github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/goroutine_test.go (about) 1 package f_test 2 3 import ( 4 "github.com/angenalZZZ/gofunc/f" 5 "sync" 6 "sync/atomic" 7 "testing" 8 "time" 9 ) 10 11 func BenchmarkPoolFuncJob(b *testing.B) { 12 pool := f.NewPoolsFunc(func(in interface{}) interface{} { 13 intVal := in.(int) 14 return intVal * 2 15 }) 16 defer pool.Close() 17 18 b.ResetTimer() 19 20 for i := 0; i < b.N; i++ { 21 ret := pool.Process(10) 22 if exp, act := 20, ret.(int); exp != act { 23 b.Errorf("Wrong result: %v != %v", act, exp) 24 } 25 } 26 } 27 28 func BenchmarkPoolFuncTimedJob(b *testing.B) { 29 pool := f.NewPoolsFunc(func(in interface{}) interface{} { 30 intVal := in.(int) 31 return intVal * 2 32 }) 33 defer pool.Close() 34 35 b.ResetTimer() 36 37 for i := 0; i < b.N; i++ { 38 ret, err := pool.ProcessTimed(10, 2*time.Millisecond) 39 if err != nil { 40 b.Error(err) 41 } 42 if exp, act := 20, ret.(int); exp != act { 43 b.Errorf("Wrong result: %v != %v", act, exp) 44 } 45 } 46 } 47 48 func TestPoolFuncJob(t *testing.T) { 49 pool := f.NewPoolsFunc(func(in interface{}) interface{} { 50 intVal := in.(int) 51 return intVal * 2 52 }) 53 defer pool.Close() 54 55 for i := 0; i < 1000000; i++ { 56 ret := pool.Process(10) 57 if exp, act := 20, ret.(int); exp != act { 58 t.Errorf("Wrong result: %v != %v", act, exp) 59 } 60 } 61 } 62 63 func TestPoolFuncJobTimed(t *testing.T) { 64 pool := f.NewPoolsFunc(func(in interface{}) interface{} { 65 intVal := in.(int) 66 return intVal * 2 67 }) 68 defer pool.Close() 69 70 for i := 0; i < 1000000; i++ { 71 ret, err := pool.ProcessTimed(10, 2*time.Millisecond) 72 if err != nil { 73 t.Fatalf("Failed to process: %v", err) 74 } 75 if exp, act := 20, ret.(int); exp != act { 76 t.Errorf("Wrong result: %v != %v", act, exp) 77 } 78 } 79 } 80 81 func TestPoolCallbackJob(t *testing.T) { 82 pool := f.NewPoolsCallback() 83 defer pool.Close() 84 85 var counter int32 86 for i := 0; i < 1000000; i++ { 87 ret := pool.Process(func() { 88 atomic.AddInt32(&counter, 1) 89 }) 90 if ret != nil { 91 t.Errorf("Non-nil callback response: %v", ret) 92 } 93 } 94 95 ret := pool.Process("foo") 96 if exp, act := f.ErrJobNotFunc, ret; exp != act { 97 t.Errorf("Wrong result from non-func: %v != %v", act, exp) 98 } 99 100 if exp, act := int32(1000000), counter; exp != act { 101 t.Errorf("Wrong result: %v != %v", act, exp) 102 } 103 } 104 105 func TestPoolTimeout(t *testing.T) { 106 f1 := f.NewFunc(func(in interface{}) interface{} { 107 intVal := in.(int) 108 <-time.After(time.Second) 109 return intVal * 2 110 }) 111 defer f1.Close() 112 113 _, act := f1.ProcessTimed(1, time.Microsecond) 114 if exp := f.ErrJobTimedOut; exp != act { 115 t.Errorf("Wrong error returned: %v != %v", act, exp) 116 } 117 } 118 119 func TestPoolTimedJobsAfterClose(t *testing.T) { 120 f1 := f.NewFunc(func(in interface{}) interface{} { 121 return in 122 }) 123 f1.Close() 124 125 _, act := f1.ProcessTimed(1, time.Duration(1)) 126 if exp := f.ErrPoolNotRunning; exp != act { 127 t.Errorf("Wrong error returned: %v != %v", act, exp) 128 } 129 } 130 131 func TestPoolJobsAfterClose(t *testing.T) { 132 f1 := f.NewFunc(func(in interface{}) interface{} { 133 return in 134 }) 135 f1.Close() 136 137 defer func() { 138 if r := recover(); r != f.ErrPoolNotRunning { 139 t.Errorf("Process after Stop() did not panic") 140 } 141 }() 142 143 f1.Process(1) 144 } 145 146 func TestPoolParallelJobs(t *testing.T) { 147 nWorkers := 100000 148 149 testGroup := new(sync.WaitGroup) 150 151 pool := f.NewPoolFunc(nWorkers, func(in interface{}) interface{} { 152 intVal := in.(int) 153 return intVal * 2 154 }) 155 defer pool.Close() 156 157 for j := 0; j < 1; j++ { 158 testGroup.Add(nWorkers) 159 160 for i := 0; i < nWorkers; i++ { 161 go func() { 162 ret := pool.Process(10) 163 if exp, act := 20, ret.(int); exp != act { 164 t.Errorf("Wrong result: %v != %v", act, exp) 165 } 166 testGroup.Done() 167 }() 168 } 169 170 testGroup.Wait() 171 } 172 }