github.com/safing/portbase@v0.19.5/utils/onceagain_test.go (about) 1 package utils 2 3 import ( 4 "sync" 5 "sync/atomic" 6 "testing" 7 "time" 8 9 "github.com/tevino/abool" 10 ) 11 12 func TestOnceAgain(t *testing.T) { 13 t.Parallel() 14 15 oa := OnceAgain{} 16 executed := abool.New() 17 var testWg sync.WaitGroup 18 19 // One execution should gobble up the whole batch. 20 for i := 0; i < 10; i++ { 21 testWg.Add(100) 22 for i := 0; i < 100; i++ { 23 go func() { 24 oa.Do(func() { 25 if !executed.SetToIf(false, true) { 26 t.Errorf("concurrent execution!") 27 } 28 time.Sleep(10 * time.Millisecond) 29 }) 30 testWg.Done() 31 }() 32 } 33 testWg.Wait() 34 executed.UnSet() // reset check 35 } 36 37 // Continuous use with re-execution. 38 // Choose values so that about 10 executions are expected 39 var execs uint32 40 testWg.Add(100) 41 for i := 0; i < 100; i++ { 42 go func() { 43 oa.Do(func() { 44 atomic.AddUint32(&execs, 1) 45 time.Sleep(10 * time.Millisecond) 46 }) 47 testWg.Done() 48 }() 49 50 time.Sleep(1 * time.Millisecond) 51 } 52 53 testWg.Wait() 54 if execs <= 8 { 55 t.Errorf("unexpected low exec count: %d", execs) 56 } 57 if execs >= 12 { 58 t.Errorf("unexpected high exec count: %d", execs) 59 } 60 }