github.com/lingyao2333/mo-zero@v1.4.1/core/syncx/pool_test.go (about)

     1  package syncx
     2  
     3  import (
     4  	"sync"
     5  	"sync/atomic"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/lingyao2333/mo-zero/core/lang"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  const limit = 10
    14  
    15  func TestPoolGet(t *testing.T) {
    16  	stack := NewPool(limit, create, destroy)
    17  	ch := make(chan lang.PlaceholderType)
    18  
    19  	for i := 0; i < limit; i++ {
    20  		var fail AtomicBool
    21  		go func() {
    22  			v := stack.Get()
    23  			if v.(int) != 1 {
    24  				fail.Set(true)
    25  			}
    26  			ch <- lang.Placeholder
    27  		}()
    28  
    29  		select {
    30  		case <-ch:
    31  		case <-time.After(time.Second):
    32  			t.Fail()
    33  		}
    34  
    35  		if fail.True() {
    36  			t.Fatal("unmatch value")
    37  		}
    38  	}
    39  }
    40  
    41  func TestPoolPopTooMany(t *testing.T) {
    42  	stack := NewPool(limit, create, destroy)
    43  	ch := make(chan lang.PlaceholderType, 1)
    44  
    45  	for i := 0; i < limit; i++ {
    46  		var wait sync.WaitGroup
    47  		wait.Add(1)
    48  		go func() {
    49  			stack.Get()
    50  			ch <- lang.Placeholder
    51  			wait.Done()
    52  		}()
    53  
    54  		wait.Wait()
    55  		select {
    56  		case <-ch:
    57  		default:
    58  			t.Fail()
    59  		}
    60  	}
    61  
    62  	var waitGroup, pushWait sync.WaitGroup
    63  	waitGroup.Add(1)
    64  	pushWait.Add(1)
    65  	go func() {
    66  		pushWait.Done()
    67  		stack.Get()
    68  		waitGroup.Done()
    69  	}()
    70  
    71  	pushWait.Wait()
    72  	stack.Put(1)
    73  	waitGroup.Wait()
    74  }
    75  
    76  func TestPoolPopFirst(t *testing.T) {
    77  	var value int32
    78  	stack := NewPool(limit, func() interface{} {
    79  		return atomic.AddInt32(&value, 1)
    80  	}, destroy)
    81  
    82  	for i := 0; i < 100; i++ {
    83  		v := stack.Get().(int32)
    84  		assert.Equal(t, 1, int(v))
    85  		stack.Put(v)
    86  	}
    87  }
    88  
    89  func TestPoolWithMaxAge(t *testing.T) {
    90  	var value int32
    91  	stack := NewPool(limit, func() interface{} {
    92  		return atomic.AddInt32(&value, 1)
    93  	}, destroy, WithMaxAge(time.Millisecond))
    94  
    95  	v1 := stack.Get().(int32)
    96  	// put nil should not matter
    97  	stack.Put(nil)
    98  	stack.Put(v1)
    99  	time.Sleep(time.Millisecond * 10)
   100  	v2 := stack.Get().(int32)
   101  	assert.NotEqual(t, v1, v2)
   102  }
   103  
   104  func TestNewPoolPanics(t *testing.T) {
   105  	assert.Panics(t, func() {
   106  		NewPool(0, create, destroy)
   107  	})
   108  }
   109  
   110  func create() interface{} {
   111  	return 1
   112  }
   113  
   114  func destroy(_ interface{}) {
   115  }