package syncx import ( "sync" "sync/atomic" "testing" "time" "github.com/stretchr/testify/assert" "github.com/tal-tech/go-zero/core/lang" ) const limit = 10 func TestPoolGet(t *testing.T) { stack := NewPool(limit, create, destroy) ch := make(chan lang.PlaceholderType) for i := 0; i < limit; i++ { var fail AtomicBool go func() { v := stack.Get() if v.(int) != 1 { fail.Set(true) } ch <- lang.Placeholder }() select { case <-ch: case <-time.After(time.Second): t.Fail() } if fail.True() { t.Fatal("unmatch value") } } } func TestPoolPopTooMany(t *testing.T) { stack := NewPool(limit, create, destroy) ch := make(chan lang.PlaceholderType, 1) for i := 0; i < limit; i++ { var wait sync.WaitGroup wait.Add(1) go func() { stack.Get() ch <- lang.Placeholder wait.Done() }() wait.Wait() select { case <-ch: default: t.Fail() } } var waitGroup, pushWait sync.WaitGroup waitGroup.Add(1) pushWait.Add(1) go func() { pushWait.Done() stack.Get() waitGroup.Done() }() pushWait.Wait() stack.Put(1) waitGroup.Wait() } func TestPoolPopFirst(t *testing.T) { var value int32 stack := NewPool(limit, func() interface{} { return atomic.AddInt32(&value, 1) }, destroy) for i := 0; i < 100; i++ { v := stack.Get().(int32) assert.Equal(t, 1, int(v)) stack.Put(v) } } func TestPoolWithMaxAge(t *testing.T) { var value int32 stack := NewPool(limit, func() interface{} { return atomic.AddInt32(&value, 1) }, destroy, WithMaxAge(time.Millisecond)) v1 := stack.Get().(int32) // put nil should not matter stack.Put(nil) stack.Put(v1) time.Sleep(time.Millisecond * 10) v2 := stack.Get().(int32) assert.NotEqual(t, v1, v2) } func TestNewPoolPanics(t *testing.T) { assert.Panics(t, func() { NewPool(0, create, destroy) }) } func create() interface{} { return 1 } func destroy(_ interface{}) { }