github.com/safing/portbase@v0.19.5/utils/stablepool_test.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func TestStablePoolRealWorld(t *testing.T) { 13 t.Parallel() 14 // "real world" simulation 15 16 cnt := 0 17 testPool := &StablePool{ 18 New: func() interface{} { 19 cnt++ 20 return cnt 21 }, 22 } 23 var testWg sync.WaitGroup 24 var testWorkerWg sync.WaitGroup 25 26 // for i := 0; i < 100; i++ { 27 // cnt++ 28 // testPool.Put(cnt) 29 // } 30 for i := 0; i < 100; i++ { 31 // block round 32 testWg.Add(1) 33 // add workers 34 testWorkerWg.Add(100) 35 for j := 0; j < 100; j++ { 36 k := j 37 go func() { 38 // wait for round to start 39 testWg.Wait() 40 // get value 41 x := testPool.Get() 42 // fmt.Println(x) 43 // "work" 44 time.Sleep(5 * time.Microsecond) 45 // re-insert 99% 46 if k%100 > 0 { 47 testPool.Put(x) 48 } 49 // mark as finished 50 testWorkerWg.Done() 51 }() 52 } 53 // start round 54 testWg.Done() 55 // wait for round to finish 56 testWorkerWg.Wait() 57 } 58 t.Logf("real world simulation: cnt=%d p.cnt=%d p.max=%d\n", cnt, testPool.Size(), testPool.Max()) 59 assert.GreaterOrEqual(t, 200, cnt, "should not use more than 200 values") 60 assert.GreaterOrEqual(t, 100, testPool.Max(), "pool should have at most this max size") 61 62 // optimal usage test 63 64 optPool := &StablePool{} 65 for i := 0; i < 1000; i++ { 66 for j := 0; j < 100; j++ { 67 optPool.Put(j) 68 } 69 for k := 0; k < 100; k++ { 70 assert.Equal(t, k, optPool.Get(), "should match") 71 } 72 } 73 assert.Equal(t, 100, optPool.Max(), "pool should have exactly this max size") 74 } 75 76 func TestStablePoolFuzzing(t *testing.T) { 77 t.Parallel() 78 // fuzzing test 79 80 fuzzPool := &StablePool{} 81 var fuzzWg sync.WaitGroup 82 var fuzzWorkerWg sync.WaitGroup 83 // start goroutines and wait 84 fuzzWg.Add(1) 85 for i := 0; i < 1000; i++ { 86 fuzzWorkerWg.Add(2) 87 j := i 88 go func() { 89 fuzzWg.Wait() 90 fuzzPool.Put(j) 91 fuzzWorkerWg.Done() 92 }() 93 go func() { 94 fuzzWg.Wait() 95 fmt.Print(fuzzPool.Get()) 96 fuzzWorkerWg.Done() 97 }() 98 } 99 // kick off 100 fuzzWg.Done() 101 // wait for all to finish 102 fuzzWorkerWg.Wait() 103 } 104 105 func TestStablePoolBreaking(t *testing.T) { 106 t.Parallel() 107 // try to break it 108 109 breakPool := &StablePool{} 110 for i := 0; i < 10; i++ { 111 for j := 0; j < 100; j++ { 112 breakPool.Put(nil) 113 breakPool.Put(j) 114 breakPool.Put(nil) 115 } 116 for k := 0; k < 100; k++ { 117 assert.Equal(t, k, breakPool.Get(), "should match") 118 } 119 } 120 }