github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/xsync/once_test.go (about) 1 package xsync 2 3 import ( 4 "context" 5 "errors" 6 "sync" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest" 12 ) 13 14 func TestOnceFunc(t *testing.T) { 15 var ( 16 ctx = xtest.Context(t) 17 cnt = 0 18 ) 19 f := OnceFunc(func(ctx context.Context) error { 20 cnt++ 21 22 return nil 23 }) 24 require.Equal(t, 0, cnt) 25 require.NoError(t, f(ctx)) 26 require.Equal(t, 1, cnt) 27 require.NoError(t, f(ctx)) 28 require.Equal(t, 1, cnt) 29 } 30 31 type testCloser struct { 32 value int 33 inited bool 34 closed bool 35 closeErr error 36 } 37 38 func (c *testCloser) Close(ctx context.Context) error { 39 c.closed = true 40 41 return c.closeErr 42 } 43 44 func TestOnceValue(t *testing.T) { 45 ctx := xtest.Context(t) 46 t.Run("Race", func(t *testing.T) { 47 counter := 0 48 once := OnceValue(func() (*testCloser, error) { 49 counter++ 50 51 return &testCloser{value: counter}, nil 52 }) 53 var wg sync.WaitGroup 54 wg.Add(1000) 55 for range make([]struct{}, 1000) { 56 go func() { 57 defer wg.Done() 58 v, err := once.Get() 59 require.NoError(t, err) 60 require.Equal(t, 1, v.value) 61 }() 62 } 63 wg.Wait() 64 }) 65 t.Run("GetBeforeClose", func(t *testing.T) { 66 constCloseErr := errors.New("") 67 once := OnceValue(func() (*testCloser, error) { 68 return &testCloser{ 69 inited: true, 70 closeErr: constCloseErr, 71 }, nil 72 }) 73 require.NotPanics(t, func() { 74 v := once.Must() 75 require.True(t, v.inited) 76 require.False(t, v.closed) 77 err := once.Close(ctx) 78 require.ErrorIs(t, err, constCloseErr) 79 require.True(t, v.inited) 80 require.True(t, v.closed) 81 }) 82 }) 83 t.Run("CloseBeforeGet", func(t *testing.T) { 84 constCloseErr := errors.New("") 85 once := OnceValue(func() (*testCloser, error) { 86 return &testCloser{ 87 inited: true, 88 closeErr: constCloseErr, 89 }, nil 90 }) 91 err := once.Close(ctx) 92 require.NoError(t, err) 93 v, err := once.Get() 94 require.NoError(t, err) 95 require.Nil(t, v) 96 }) 97 }