package cassandra import ( "fmt" "testing" "time" "github.com/stretchr/testify/assert" ) type LockTest struct { ID string `db:"id" partition_key:"true"` Holder string `db:"holder"` } func (l *LockTest) TableName() string { return "lock_test" } func TestTryLockAndUnLock(t *testing.T) { container, db := setupForTest(t) defer func() { _ = container.Container.Terminate(container.Ctx) fmt.Println("[TEST] Container terminated") }() assert.NoError(t, db.EnsureTable(` CREATE TABLE IF NOT EXISTS my_keyspace.lock_test ( id TEXT PRIMARY KEY, holder TEXT ); `)) lockID := "lock-123" holder := "daniel" lockDoc := &LockTest{ID: lockID, Holder: holder} t.Run("acquire lock - success", func(t *testing.T) { err := db.TryLock(container.Ctx, lockDoc, "my_keyspace") assert.NoError(t, err, "TryLock 應該成功") }) t.Run("acquire lock again - fail", func(t *testing.T) { err := db.TryLock(container.Ctx, lockDoc, "my_keyspace") assert.Error(t, err, "重複上鎖應該失敗") }) t.Run("unlock", func(t *testing.T) { err := db.UnLock(container.Ctx, lockDoc, "my_keyspace") assert.NoError(t, err, "UnLock 應該成功") }) t.Run("lock with TTL", func(t *testing.T) { lockWithTTL := &LockTest{ID: "lock-ttl", Holder: "jack"} err := db.TryLock(container.Ctx, lockWithTTL, "my_keyspace", WithLockTTL(2*time.Second)) assert.NoError(t, err) // 兩秒後嘗試再次上鎖應該成功(TTL 過期) time.Sleep(3 * time.Second) err = db.TryLock(container.Ctx, lockWithTTL, "my_keyspace") assert.NoError(t, err) _ = db.UnLock(container.Ctx, lockWithTTL, "my_keyspace") }) t.Run("unlock not exist", func(t *testing.T) { nonExist := &LockTest{ID: "not-exist", Holder: "nobody"} err := db.UnLock(container.Ctx, nonExist, "my_keyspace") assert.Error(t, err, "unlock 不存在的鎖應該失敗") }) }