blockchain/internal/lib/cassandra/client_test.go

172 lines
4.3 KiB
Go
Raw Normal View History

2025-08-05 23:41:29 +00:00
package cassandra
import (
"fmt"
2025-08-06 07:08:32 +00:00
"testing"
2025-08-05 23:41:29 +00:00
"github.com/gocql/gocql"
"github.com/stretchr/testify/assert"
)
2025-08-06 07:08:32 +00:00
func TestIsSAISupported(t *testing.T) {
tests := []struct {
version string
expected bool
}{
{"5.0.0", true}, // 5.x 支援
{"5.1.2", true}, // 5.x 支援
{"6.0.0", true}, // 6.x 理論上也支援
{"4.0.8", false}, // 4.0.8 不支援
{"4.0.9", true}, // 4.0.9 支援
{"4.1.0", true}, // 4.1.0 支援
{"4.2.2", true}, // 4.2.2 支援
{"3.11.10", false}, // 3.x 不支援
{"3.0.0", false},
{"", false}, // 空字串,不支援
{"unknown", false}, // 無效格式
{"4", false}, // 缺 patch不支援
{"4.0", false}, // 缺 patch不支援
{"5", false}, // 缺 minor
{"5.0", true}, // 5.0 預設支援
}
for _, tt := range tests {
t.Run(tt.version, func(t *testing.T) {
result := isSAISupported(tt.version)
assert.Equal(t, tt.expected, result, "version: %s", tt.version)
})
}
}
2025-08-05 23:41:29 +00:00
// TestCassandraDB_Integration_TableDriven 使用 table-driven 方式整合測試
func TestCassandraDB_Integration_TableDriven(t *testing.T) {
// 啟動 Cassandra container
dbContainer, err := initCassandraContainer("5.0.4")
defer func() {
_ = dbContainer.Container.Terminate(dbContainer.Ctx)
fmt.Println("[TEST] Container terminated")
}()
// 建立 CassandraDB 連線
hosts := []string{dbContainer.Host}
2025-08-06 07:08:32 +00:00
db, err := NewCassandraDB(
2025-08-05 23:41:29 +00:00
hosts,
WithPort(dbContainer.Port),
WithConsistency(gocql.One),
2025-08-06 07:08:32 +00:00
WithNumConns(2),
2025-08-05 23:41:29 +00:00
)
assert.NoError(t, err, "should success create CassandraDB")
assert.NotNil(t, db, "db should not be nil")
assert.NotNil(t, db.GetSession(), "get Session should not be nil")
err = db.EnsureTable("CREATE KEYSPACE my_keyspace\nWITH replication = {\n 'class': 'SimpleStrategy',\n 'replication_factor': 1\n};\n")
assert.NoError(t, err, "should success ensure table")
// 注意:由於 Close 會關閉 session因此請把測試 Close 的子案例放在所有使用 session 的子案例之後
tests := []struct {
name string
action func() error
wantErr bool
}{
{
name: "ok",
action: func() error {
// 建立一個合法的資料表 (使用 IF NOT EXISTS 避免重複建立錯誤)
schema := "CREATE TABLE IF NOT EXISTS my_keyspace.test (id uuid PRIMARY KEY, name text)"
return db.EnsureTable(schema)
},
wantErr: false,
},
{
name: "failed to ensure table since wrong schema",
action: func() error {
// 傳入無效的 CQL 語法,預期應回傳錯誤
schema := "CREATE TABLE invalid schema"
return db.EnsureTable(schema)
},
wantErr: true,
},
{
name: "GetSession 返回有效 Session",
action: func() error {
if db.GetSession().Session == nil {
return fmt.Errorf("session is nil")
}
return nil
},
wantErr: false,
},
{
name: "Close close Session",
action: func() error {
db.Close()
// 無法直接驗證內部是否已關閉,但可避免再次使用 session 產生 panic
return nil
},
wantErr: false,
},
}
// 依序執行各子案例
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := tc.action()
if (err != nil) != tc.wantErr {
t.Errorf("%s havs error = %v, wantErr %v", tc.name, err, tc.wantErr)
}
})
}
}
func TestCassandraDB_getReleaseVersion(t *testing.T) {
type fields struct {
Version string
}
tests := []struct {
name string
fields fields
want string
wantError bool
}{
{
name: "3",
fields: fields{Version: "3.11"},
want: "3.11.19",
wantError: false,
},
{
name: "5",
fields: fields{Version: "5.0.4"},
want: "5.0.4",
wantError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
container, err := initCassandraContainer(tt.fields.Version)
defer func() {
_ = container.Container.Terminate(container.Ctx)
fmt.Println("[TEST] Container terminated")
}()
if !tt.wantError {
assert.NoError(t, err)
// 建立 CassandraDB 連線
hosts := []string{container.Host}
2025-08-06 07:08:32 +00:00
db, err := NewCassandraDB(
2025-08-05 23:41:29 +00:00
hosts,
WithPort(container.Port),
WithConsistency(gocql.One),
2025-08-06 07:08:32 +00:00
WithNumConns(2),
2025-08-05 23:41:29 +00:00
)
assert.NoError(t, err)
version, err := db.getReleaseVersion()
assert.NoError(t, err)
assert.Equal(t, version, tt.want)
}
})
}
}