github.com/wfusion/gofusion@v1.1.14/test/routine/cases/candy_test.go (about) 1 package cases 2 3 import ( 4 "context" 5 "errors" 6 "sync" 7 "testing" 8 "time" 9 10 "github.com/spf13/cast" 11 "github.com/stretchr/testify/suite" 12 "go.uber.org/atomic" 13 14 "github.com/wfusion/gofusion/log" 15 "github.com/wfusion/gofusion/routine" 16 17 testRoutine "github.com/wfusion/gofusion/test/routine" 18 ) 19 20 func TestCandy(t *testing.T) { 21 testingSuite := &Candy{Test: new(testRoutine.Test)} 22 testingSuite.Init(testingSuite) 23 suite.Run(t, testingSuite) 24 } 25 26 type Candy struct { 27 *testRoutine.Test 28 } 29 30 func (t *Candy) BeforeTest(suiteName, testName string) { 31 t.Catch(func() { 32 log.Info(context.Background(), "right before %s %s", suiteName, testName) 33 }) 34 } 35 36 func (t *Candy) AfterTest(suiteName, testName string) { 37 t.Catch(func() { 38 log.Info(context.Background(), "right after %s %s", suiteName, testName) 39 }) 40 } 41 42 func (t *Candy) TestGo() { 43 t.Catch(func() { 44 wg := new(sync.WaitGroup) 45 i := 0 46 wg.Add(1) 47 routine.Go(func() { 48 i += 1 49 }, routine.WaitGroup(wg), routine.AppName(t.AppName())) 50 wg.Wait() 51 t.EqualValues(1, i) 52 }) 53 } 54 55 func (t *Candy) TestGoWithArgs() { 56 t.Catch(func() { 57 wg := new(sync.WaitGroup) 58 i := 0 59 wg.Add(1) 60 routine.Go( 61 func(args ...any) { 62 i += args[0].(int) 63 }, 64 routine.Args(2, 3, 4, 5), 65 routine.WaitGroup(wg), 66 routine.AppName(t.AppName()), 67 ) 68 wg.Wait() 69 t.EqualValues(2, i) 70 }) 71 } 72 73 func (t *Candy) TestGoWithType() { 74 t.Catch(func() { 75 wg := new(sync.WaitGroup) 76 i := 0 77 wg.Add(1) 78 routine.Go( 79 func(arg int) { i += arg }, 80 routine.Args(2), 81 routine.WaitGroup(wg), 82 routine.AppName(t.AppName()), 83 ) 84 wg.Wait() 85 t.EqualValues(2, i) 86 }) 87 } 88 89 func (t *Candy) TestGoWithVariableArgs() { 90 t.Catch(func() { 91 wg := new(sync.WaitGroup) 92 i := 0 93 wg.Add(1) 94 routine.Go( 95 func(num int, str string, args ...uint) { 96 i += int(args[0]) 97 }, 98 routine.Args(2, "this is a string", 4, 5, 6), 99 routine.WaitGroup(wg), 100 routine.AppName(t.AppName()), 101 ) 102 wg.Wait() 103 t.EqualValues(4, i) 104 }) 105 } 106 107 func (t *Candy) TestGoWithError() { 108 t.Catch(func() { 109 wg := new(sync.WaitGroup) 110 i := 0 111 wg.Add(1) 112 routine.Go( 113 func(num int, str string, args ...uint) error { 114 i += int(args[0]) 115 return errors.New("no") 116 }, 117 routine.Args(2, "this is a string", 4, 5, 6), 118 routine.WaitGroup(wg), 119 routine.AppName(t.AppName()), 120 ) 121 wg.Wait() 122 t.EqualValues(4, i) 123 }) 124 } 125 126 func (t *Candy) TestGoWithResultAndError() { 127 t.Catch(func() { 128 wg := new(sync.WaitGroup) 129 i := 0 130 wg.Add(1) 131 routine.Go( 132 func(num int, str string, args ...uint) (any, error) { 133 i += int(args[0]) 134 return i, nil 135 }, 136 routine.Args(2, "this is a string", 4, 5, 6), 137 routine.WaitGroup(wg), 138 routine.AppName(t.AppName()), 139 ) 140 wg.Wait() 141 t.EqualValues(4, i) 142 }) 143 } 144 145 func (t *Candy) TestGocWithResultAndError() { 146 t.Catch(func() { 147 wg := new(sync.WaitGroup) 148 i := 0 149 wg.Add(1) 150 routine.Goc( 151 context.Background(), 152 func(num int, str string, args ...uint) (any, error) { 153 i += int(args[0]) 154 return i, errors.New("get an error") 155 }, 156 routine.Args(2, "this is a string", 4, 5, 6), 157 routine.WaitGroup(wg), 158 routine.AppName(t.AppName()), 159 ) 160 wg.Wait() 161 t.EqualValues(4, i) 162 }) 163 } 164 165 func (t *Candy) TestGoWithChannel() { 166 t.Catch(func() { 167 ch := make(chan any, 1) 168 wg := new(sync.WaitGroup) 169 i := 0 170 wg.Add(1) 171 routine.Go( 172 func(args ...any) { 173 i += args[0].(int) 174 }, 175 routine.Args(2, 3, 4, 5), 176 routine.WaitGroup(wg), 177 routine.Channel(ch), 178 routine.AppName(t.AppName()), 179 ) 180 wg.Wait() 181 t.EqualValues(2, i) 182 select { 183 case v := <-ch: 184 log.Info(context.Background(), "get channel result: %+v", v) 185 } 186 }) 187 } 188 189 func (t *Candy) TestGoWithChannelResult() { 190 t.Catch(func() { 191 ch := make(chan any, 1) 192 wg := new(sync.WaitGroup) 193 i := 0 194 wg.Add(1) 195 routine.Go( 196 func(args ...any) (any, error) { 197 i += args[0].(int) 198 return i, nil 199 }, 200 routine.Args(2, 3, 4, 5), 201 routine.WaitGroup(wg), 202 routine.Channel(ch), 203 routine.AppName(t.AppName()), 204 ) 205 wg.Wait() 206 t.EqualValues(2, i) 207 select { 208 case v := <-ch: 209 log.Info(context.Background(), "get channel result: %+v", v) 210 } 211 }) 212 } 213 214 func (t *Candy) TestGoWithChannelError() { 215 t.Catch(func() { 216 ch := make(chan any, 1) 217 wg := new(sync.WaitGroup) 218 i := 0 219 wg.Add(1) 220 routine.Go( 221 func(args ...any) (any, error) { 222 i += args[0].(int) 223 return i, errors.New("channel error") 224 }, 225 routine.Args(2, 3, 4, 5), 226 routine.WaitGroup(wg), 227 routine.Channel(ch), 228 routine.AppName(t.AppName()), 229 ) 230 wg.Wait() 231 t.EqualValues(2, i) 232 select { 233 case v := <-ch: 234 log.Info(context.Background(), "get channel result: %+v", v) 235 } 236 }) 237 } 238 239 func (t *Candy) TestLoop() { 240 t.Catch(func() { 241 i := 0 242 expected := 10 243 wg := new(sync.WaitGroup) 244 wg.Add(1) 245 routine.Loop(func() { 246 for i = 0; i < expected; i++ { 247 } 248 }, routine.WaitGroup(wg), routine.AppName(t.AppName())) 249 wg.Wait() 250 t.EqualValues(expected, i) 251 }) 252 } 253 254 func (t *Candy) TestLoopWithArgs() { 255 t.Catch(func() { 256 i := 0 257 expected := 10 258 wg := new(sync.WaitGroup) 259 wg.Add(1) 260 routine.Loop(func(args ...any) { 261 for i := args[0].(*int); *i < expected; *i++ { 262 } 263 }, routine.Args(&i), routine.WaitGroup(wg), routine.AppName(t.AppName())) 264 wg.Wait() 265 t.Equal(expected, i) 266 }) 267 } 268 269 func (t *Candy) TestWhenAllWithFuture() { 270 t.Catch(func() { 271 sum, expected := atomic.NewInt64(0), 10 272 futures := make([]any, 0, 10) 273 for i := 0; i < expected; i++ { 274 future := routine.Promise( 275 func(args ...any) { 276 sum.Add(cast.ToInt64(args[0])) 277 }, 278 true, 279 routine.Args(2, 3, 4, 5), 280 routine.AppName(t.AppName()), 281 ) 282 283 futures = append(futures, future) 284 } 285 286 futures = append(futures, routine.AppName(t.AppName())) 287 _, timeout, err := routine.WhenAll(futures...).GetOrTimeout(time.Second) 288 t.False(timeout) 289 t.NoError(err) 290 t.EqualValues(expected*2, sum.Load()) 291 }) 292 } 293 294 func (t *Candy) TestReachMax() { 295 t.Catch(func() { 296 futureList := make([]any, 0, 100) 297 for i := 0; i < 100; i++ { 298 futureList = append(futureList, routine.Promise(func(idx int) { 299 ctx := context.Background() 300 log.Info(ctx, "goroutine %d start", idx) 301 defer log.Info(ctx, "goroutine %d end", idx) 302 303 <-time.After(50 * time.Millisecond) 304 }, true, routine.Args(i), routine.AppName(t.AppName()))) 305 } 306 307 _, _ = routine.WhenAll(append(futureList, routine.AppName(t.AppName()))...).Get() 308 }) 309 }