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  }