package deploy import ( "sync" "testing" ) func TestLock_TryAcquire(t *testing.T) { l := NewLock() // First acquire should succeed if !l.TryAcquire("request-1") { t.Error("first TryAcquire should succeed") } // Second acquire should fail if l.TryAcquire("request-2") { t.Error("second TryAcquire should fail while lock is held") } // Verify holder if got := l.Holder(); got != "request-1" { t.Errorf("Holder() = %q, want %q", got, "request-1") } // Release and try again l.Release() if !l.TryAcquire("request-3") { t.Error("TryAcquire should succeed after Release") } if got := l.Holder(); got != "request-3" { t.Errorf("Holder() = %q, want %q", got, "request-3") } } func TestLock_IsHeld(t *testing.T) { l := NewLock() if l.IsHeld() { t.Error("new lock should not be held") } l.TryAcquire("test") if !l.IsHeld() { t.Error("lock should be held after TryAcquire") } l.Release() if l.IsHeld() { t.Error("lock should not be held after Release") } } func TestLock_Concurrent(t *testing.T) { l := NewLock() var wg sync.WaitGroup acquired := make(chan string, 100) // Try to acquire from multiple goroutines for i := range 100 { wg.Add(1) go func(id int) { defer wg.Done() holder := string(rune('A' + (id % 26))) if l.TryAcquire(holder) { acquired <- holder } }(i) } wg.Wait() close(acquired) // Only one should have succeeded count := 0 for range acquired { count++ } if count != 1 { t.Errorf("expected exactly 1 successful acquire, got %d", count) } } func TestLock_ReleaseUnheld(t *testing.T) { l := NewLock() // Releasing an unheld lock should not panic l.Release() if l.IsHeld() { t.Error("lock should not be held after Release on unheld lock") } }