package cassandra import ( "context" "fmt" "strconv" "testing" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" ) // startCassandraContainer 啟動 Cassandra 測試容器 func startCassandraContainer(ctx context.Context) (string, string, func(), error) { req := testcontainers.ContainerRequest{ Image: "cassandra:4.1", ExposedPorts: []string{"9042/tcp"}, WaitingFor: wait.ForListeningPort("9042/tcp"), Env: map[string]string{ "CASSANDRA_CLUSTER_NAME": "test-cluster", }, } cassandraC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) if err != nil { return "", "", nil, fmt.Errorf("failed to start Cassandra container: %w", err) } port, err := cassandraC.MappedPort(ctx, "9042") if err != nil { cassandraC.Terminate(ctx) return "", "", nil, fmt.Errorf("failed to get mapped port: %w", err) } host, err := cassandraC.Host(ctx) if err != nil { cassandraC.Terminate(ctx) return "", "", nil, fmt.Errorf("failed to get host: %w", err) } tearDown := func() { _ = cassandraC.Terminate(ctx) } fmt.Printf("Cassandra test container started: %s:%s\n", host, port.Port()) return host, port.Port(), tearDown, nil } // setupTestDB 設置測試用的 DB 實例 func setupTestDB(t testing.TB) (*DB, func()) { ctx := context.Background() host, port, tearDown, err := startCassandraContainer(ctx) if err != nil { t.Fatalf("Failed to start Cassandra container: %v", err) } portInt, err := strconv.Atoi(port) if err != nil { tearDown() t.Fatalf("Failed to convert port to int: %v", err) } db, err := New( WithHosts(host), WithPort(portInt), WithKeyspace("test_keyspace"), ) if err != nil { tearDown() t.Fatalf("Failed to create DB: %v", err) } // 創建 keyspace createKeyspaceStmt := "CREATE KEYSPACE IF NOT EXISTS test_keyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}" if err := db.session.Query(createKeyspaceStmt, nil).Exec(); err != nil { db.Close() tearDown() t.Fatalf("Failed to create keyspace: %v", err) } cleanup := func() { db.Close() tearDown() } return db, cleanup }