123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package asyncbuffer
- import (
- "sync"
- "testing"
- "time"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- )
- func TestNewLatch(t *testing.T) {
- latch := NewLatch()
- require.NotNil(t, latch)
- require.NotNil(t, latch.done)
- // Channel should be open (not closed) initially
- select {
- case <-latch.done:
- t.Fatal("Latch should not be released initially")
- default:
- // Expected - channel is not ready
- }
- }
- func TestLatchRelease(t *testing.T) {
- latch := NewLatch()
- // Release the latch
- latch.Release()
- // Channel should now be closed/ready
- select {
- case <-latch.done:
- // Expected - channel is ready after release
- default:
- t.Fatal("Latch should be released after Release() call")
- }
- }
- func TestLatchWait(t *testing.T) {
- latch := NewLatch()
- // Start a goroutine that will wait
- waitCompleted := make(chan bool, 1)
- go func() {
- latch.Wait()
- waitCompleted <- true
- }()
- // Give the goroutine a moment to start waiting
- time.Sleep(10 * time.Millisecond)
- // Wait should not complete yet
- select {
- case <-waitCompleted:
- t.Fatal("Wait should not complete before Release")
- default:
- // Expected
- }
- // Release the latch
- latch.Release()
- // Wait should complete now
- select {
- case <-waitCompleted:
- // Expected
- case <-time.After(100 * time.Millisecond):
- t.Fatal("Wait should complete after Release")
- }
- }
- func TestLatchMultipleWaiters(t *testing.T) {
- latch := NewLatch()
- const numWaiters = 10
- var wg sync.WaitGroup
- waitersCompleted := make(chan int, numWaiters)
- // Start multiple waiters
- for i := 0; i < numWaiters; i++ {
- wg.Add(1)
- go func(id int) {
- defer wg.Done()
- latch.Wait()
- waitersCompleted <- id
- }(i)
- }
- // Give goroutines time to start waiting
- time.Sleep(10 * time.Millisecond)
- // No waiters should complete yet
- assert.Empty(t, waitersCompleted)
- // Release the latch
- latch.Release()
- // All waiters should complete
- wg.Wait()
- close(waitersCompleted)
- // Verify all waiters completed
- completed := make([]int, 0, numWaiters)
- for id := range waitersCompleted {
- completed = append(completed, id)
- }
- assert.Len(t, completed, numWaiters)
- }
- func TestLatchMultipleReleases(t *testing.T) {
- latch := NewLatch()
- // Release multiple times should be safe
- latch.Release()
- latch.Release()
- latch.Release()
- // Should still be able to wait
- select {
- case <-latch.done:
- // Expected - channel should be ready
- default:
- t.Fatal("Latch should be released")
- }
- }
|