blockchain/internal/lib/cassandra/client_test.go

172 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cassandra
import (
"fmt"
"testing"
"github.com/gocql/gocql"
"github.com/stretchr/testify/assert"
)
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)
})
}
}
// 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}
db, err := NewCassandraDB(
hosts,
WithPort(dbContainer.Port),
WithConsistency(gocql.One),
WithNumConns(2),
)
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}
db, err := NewCassandraDB(
hosts,
WithPort(container.Port),
WithConsistency(gocql.One),
WithNumConns(2),
)
assert.NoError(t, err)
version, err := db.getReleaseVersion()
assert.NoError(t, err)
assert.Equal(t, version, tt.want)
}
})
}
}