github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zpool/pool_test.go (about)

     1  /*
     2  go test -race ./zpool -v
     3  */
     4  package zpool_test
     5  
     6  import (
     7  	"runtime"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/sohaha/zlsgo"
    13  	"github.com/sohaha/zlsgo/zerror"
    14  	"github.com/sohaha/zlsgo/zfile"
    15  	"github.com/sohaha/zlsgo/zlog"
    16  	"github.com/sohaha/zlsgo/zpool"
    17  	"github.com/sohaha/zlsgo/zutil"
    18  )
    19  
    20  func TestBase(t *testing.T) {
    21  	tt := zlsgo.NewTest(t)
    22  	workerNum := 5
    23  	p := zpool.New(workerNum)
    24  	p.PanicFunc(func(err error) {
    25  		zlog.Printf("panic: %v", err)
    26  	})
    27  	for i := 0; i < workerNum*2; i++ {
    28  		ii := i
    29  		err := p.Do(func() {
    30  			t.Log("run", ii)
    31  			time.Sleep(time.Millisecond * 300)
    32  			t.Log("done", ii)
    33  		})
    34  		tt.EqualNil(err)
    35  	}
    36  
    37  	p.Wait()
    38  }
    39  
    40  func TestPool(t *testing.T) {
    41  	tt := zlsgo.NewTest(t)
    42  
    43  	count := 10000
    44  	workerNum := 160
    45  	var curMem uint64
    46  	for i := 0; i < 10; i++ {
    47  		var g sync.WaitGroup
    48  		var now time.Time
    49  		runtime.GC()
    50  		now = time.Now()
    51  		_, curMem = zutil.WithRunContext(func() {
    52  			now = time.Now()
    53  			for i := 0; i < count; i++ {
    54  				ii := i
    55  				g.Add(1)
    56  				go func() {
    57  					_ = ii
    58  					time.Sleep(time.Millisecond * 10)
    59  					g.Done()
    60  				}()
    61  			}
    62  			g.Wait()
    63  		})
    64  		t.Logf("NoPool memory:%v goroutines:%v time:%v \n", zfile.SizeFormat(curMem), count, time.Since(now))
    65  		runtime.GC()
    66  		p := zpool.New(workerNum)
    67  		now = time.Now()
    68  		_, curMem = zutil.WithRunContext(func() {
    69  			for i := 0; i < count; i++ {
    70  				ii := i
    71  				g.Add(1)
    72  				err := p.Do(func() {
    73  					_ = ii
    74  					time.Sleep(time.Millisecond)
    75  					g.Done()
    76  				})
    77  				tt.EqualNil(err)
    78  			}
    79  			g.Wait()
    80  		})
    81  		t.Logf("Pool   memory:%v goroutines:%v time:%v \n", zfile.SizeFormat(curMem), p.Cap(), time.Since(now))
    82  		p.Close()
    83  	}
    84  
    85  	p := zpool.New(workerNum)
    86  	_ = p.PreInit()
    87  	tt.EqualExit(uint(workerNum), p.Cap())
    88  	p.Close()
    89  
    90  	err := p.PreInit()
    91  	tt.EqualExit(true, err != nil)
    92  
    93  	p.Close()
    94  	c := p.IsClosed()
    95  	tt.EqualExit(true, c)
    96  
    97  	err = p.Do(func() {})
    98  	tt.EqualExit(true, err != nil)
    99  }
   100  
   101  func TestPoolCap(t *testing.T) {
   102  	tt := zlsgo.NewTest(t)
   103  	p := zpool.New(0)
   104  	g := sync.WaitGroup{}
   105  	g.Add(1)
   106  	err := p.Do(func() {
   107  		time.Sleep(time.Second / 100)
   108  		g.Done()
   109  	})
   110  	tt.EqualNil(err)
   111  	tt.EqualExit(uint(1), p.Cap())
   112  	g.Wait()
   113  
   114  	maxsize := 10
   115  	p = zpool.New(1, maxsize)
   116  	g = sync.WaitGroup{}
   117  	g.Add(1)
   118  	err = p.Do(func() {
   119  		time.Sleep(time.Second / 100)
   120  		g.Done()
   121  	})
   122  	tt.EqualNil(err)
   123  	tt.EqualExit(uint(1), p.Cap())
   124  	g.Wait()
   125  	p.Pause()
   126  	tt.EqualExit(uint(0), p.Cap())
   127  
   128  	newSize := 5
   129  	p.Continue(newSize)
   130  	tt.EqualExit(uint(newSize), p.Cap())
   131  
   132  	restarSum := 7
   133  	g.Add(restarSum)
   134  
   135  	for i := 0; i < restarSum; i++ {
   136  		ii := i
   137  		go func() {
   138  			now := time.Now()
   139  			err := p.Do(func() {
   140  				time.Sleep(time.Second / 100)
   141  				t.Log("continue", ii, time.Since(now))
   142  				g.Done()
   143  			})
   144  			tt.EqualNil(err)
   145  		}()
   146  	}
   147  	g.Wait()
   148  	tt.EqualExit(uint(restarSum), p.Cap())
   149  
   150  	p.Continue(1000)
   151  	tt.EqualExit(uint(maxsize), p.Cap())
   152  
   153  	p.Close()
   154  	tt.EqualExit(uint(0), p.Cap())
   155  }
   156  
   157  func TestPoolPanicFunc(t *testing.T) {
   158  	tt := zlsgo.NewTest(t)
   159  	p := zpool.New(1)
   160  	defErr := zerror.New(0, "test panic")
   161  	var g sync.WaitGroup
   162  	p.PanicFunc(func(err error) {
   163  		g.Done()
   164  		tt.Equal(err, defErr)
   165  		t.Log(err)
   166  	})
   167  	i := 0
   168  
   169  	g.Add(1)
   170  	_ = p.Do(func() {
   171  		zerror.Panic(defErr)
   172  		i++
   173  	})
   174  	g.Wait()
   175  	tt.EqualExit(0, i)
   176  
   177  	g.Add(1)
   178  	_ = p.Do(func() {
   179  		i++
   180  		zerror.Panic(defErr)
   181  		i++
   182  	})
   183  	g.Wait()
   184  	tt.EqualExit(1, i)
   185  
   186  	g.Add(1)
   187  	_ = p.Do(func() {
   188  		i++
   189  		g.Done()
   190  	})
   191  
   192  	g.Wait()
   193  	tt.EqualExit(2, i)
   194  
   195  	p.Pause()
   196  	p.PanicFunc(func(err error) {
   197  		t.Log("send again")
   198  		defer g.Done()
   199  	})
   200  	p.Continue()
   201  	g.Add(1)
   202  	_ = p.Do(func() {
   203  		i++
   204  		zerror.Panic(defErr)
   205  		i++
   206  	})
   207  	g.Wait()
   208  	tt.EqualExit(3, i)
   209  }
   210  
   211  func TestPoolTimeout(t *testing.T) {
   212  	tt := zlsgo.NewTest(t)
   213  	p := zpool.New(1)
   214  	for i := 0; i < 3; i++ {
   215  		v := i
   216  		err := p.DoWithTimeout(func() {
   217  			t.Log(v)
   218  			time.Sleep(time.Second)
   219  		}, time.Second/3)
   220  		t.Log(err)
   221  		if v > 0 {
   222  			tt.Equal(err, zpool.ErrWaitTimeout)
   223  		}
   224  		if err == zpool.ErrWaitTimeout {
   225  			t.Log(v)
   226  		}
   227  	}
   228  	p.Wait()
   229  }
   230  
   231  func TestPoolAuto(t *testing.T) {
   232  	tt := zlsgo.NewTest(t)
   233  	var g sync.WaitGroup
   234  	p := zpool.New(1, 2)
   235  	for i := 0; i < 4; i++ {
   236  		g.Add(1)
   237  		v := i
   238  		err := p.DoWithTimeout(func() {
   239  			time.Sleep(time.Second)
   240  			t.Log("ok", v)
   241  			g.Done()
   242  		}, time.Second/6)
   243  		t.Log(v, err)
   244  		if v > 1 {
   245  			tt.EqualTrue(err == zpool.ErrWaitTimeout)
   246  		}
   247  		if err == zpool.ErrWaitTimeout {
   248  			go func() {
   249  				time.Sleep(time.Second)
   250  				t.Log("err", v)
   251  				g.Done()
   252  			}()
   253  		}
   254  	}
   255  	g.Wait()
   256  	tt.Log("done", p.Cap())
   257  }