github.com/matrixorigin/matrixone@v0.7.0/pkg/lockservice/waiter_test.go (about) 1 // Copyright 2023 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lockservice 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 ) 25 26 func TestAcquireWaiter(t *testing.T) { 27 w := acquireWaiter([]byte("w")) 28 defer w.close() 29 30 assert.Equal(t, 0, len(w.c)) 31 assert.Equal(t, int32(1), w.refCount.Load()) 32 assert.Equal(t, 0, w.waiters.len()) 33 } 34 35 func TestAddNewWaiter(t *testing.T) { 36 w := acquireWaiter([]byte("w")) 37 w1 := acquireWaiter([]byte("w1")) 38 defer func() { 39 ctx, cancel := context.WithCancel(context.Background()) 40 defer cancel() 41 assert.NoError(t, w1.wait(ctx)) 42 w1.close() 43 }() 44 45 w.add(w1) 46 assert.Equal(t, 1, w.waiters.len()) 47 assert.Equal(t, int32(2), w1.refCount.Load()) 48 w.close() 49 } 50 51 func TestCloseWaiter(t *testing.T) { 52 w := acquireWaiter([]byte("w")) 53 w1 := acquireWaiter([]byte("w1")) 54 w2 := acquireWaiter([]byte("w2")) 55 56 w.add(w1) 57 w.add(w2) 58 59 v := w.close() 60 assert.NotNil(t, v) 61 assert.Equal(t, 1, v.waiters.len()) 62 assert.Equal(t, w1, v) 63 64 ctx, cancel := context.WithCancel(context.Background()) 65 defer cancel() 66 assert.NoError(t, w1.wait(ctx)) 67 68 v = w1.close() 69 assert.NotNil(t, v) 70 assert.Equal(t, 0, v.waiters.len()) 71 assert.Equal(t, w2, v) 72 73 assert.NoError(t, w2.wait(ctx)) 74 assert.Nil(t, w2.close()) 75 } 76 77 func TestWait(t *testing.T) { 78 w := acquireWaiter([]byte("w")) 79 w1 := acquireWaiter([]byte("w1")) 80 defer w1.close() 81 82 w.add(w1) 83 go func() { 84 time.Sleep(time.Millisecond * 10) 85 w.close() 86 }() 87 88 assert.NoError(t, w1.wait(context.Background())) 89 } 90 91 func TestWaitWithTimeout(t *testing.T) { 92 w := acquireWaiter([]byte("w")) 93 defer w.close() 94 w1 := acquireWaiter([]byte("w1")) 95 defer w1.close() 96 97 w.add(w1) 98 99 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*100) 100 defer cancel() 101 assert.Error(t, w1.wait(ctx)) 102 } 103 104 func TestWaitAndNotifyConcurrent(t *testing.T) { 105 w := acquireWaiter([]byte("w")) 106 defer w.close() 107 108 w.beforeSwapStatusAdjustFunc = func() { 109 w.setStatus(notified) 110 w.c <- nil 111 } 112 113 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*10) 114 defer cancel() 115 assert.NoError(t, w.wait(ctx)) 116 } 117 118 func TestWaitMultiTimes(t *testing.T) { 119 w := acquireWaiter([]byte("w")) 120 w1 := acquireWaiter([]byte("w1")) 121 w2 := acquireWaiter([]byte("w2")) 122 defer w2.close() 123 124 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*100) 125 defer cancel() 126 127 w.add(w2) 128 w.close() 129 assert.NoError(t, w2.wait(ctx)) 130 w2.resetWait() 131 132 w1.add(w2) 133 w1.close() 134 assert.NoError(t, w2.wait(ctx)) 135 136 } 137 138 func TestSkipCompletedWaiters(t *testing.T) { 139 w := acquireWaiter([]byte("w")) 140 w1 := acquireWaiter([]byte("w1")) 141 defer w1.close() 142 w2 := acquireWaiter([]byte("w2")) 143 w3 := acquireWaiter([]byte("w3")) 144 defer w3.close() 145 146 w.add(w1) 147 w.add(w2) 148 w.add(w3) 149 150 // make w1 completed 151 w1.setStatus(completed) 152 153 v := w.close() 154 assert.Equal(t, w2, v) 155 156 v = w2.close() 157 assert.Equal(t, w3, v) 158 } 159 160 func TestNotifyAfterCompleted(t *testing.T) { 161 w := acquireWaiter(nil) 162 require.Equal(t, 0, len(w.c)) 163 defer w.close() 164 w.setStatus(completed) 165 assert.False(t, w.notify(nil)) 166 } 167 168 func TestNotifyAfterAlreadyNotified(t *testing.T) { 169 w := acquireWaiter(nil) 170 defer w.close() 171 assert.True(t, w.notify(nil)) 172 assert.NoError(t, w.wait(context.Background())) 173 assert.False(t, w.notify(nil)) 174 } 175 176 func TestNotifyWithStatusChanged(t *testing.T) { 177 w := acquireWaiter(nil) 178 defer w.close() 179 180 w.beforeSwapStatusAdjustFunc = func() { 181 w.setStatus(completed) 182 } 183 assert.False(t, w.notify(nil)) 184 }