github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/queue/unique_queue_channel_test.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package queue 7 8 import ( 9 "sync" 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func TestChannelUniqueQueue(t *testing.T) { 17 handleChan := make(chan *testData) 18 handle := func(data ...Data) []Data { 19 for _, datum := range data { 20 testDatum := datum.(*testData) 21 handleChan <- testDatum 22 } 23 return nil 24 } 25 26 nilFn := func(_ func()) {} 27 28 queue, err := NewChannelUniqueQueue(handle, 29 ChannelQueueConfiguration{ 30 WorkerPoolConfiguration: WorkerPoolConfiguration{ 31 QueueLength: 0, 32 MaxWorkers: 10, 33 BlockTimeout: 1 * time.Second, 34 BoostTimeout: 5 * time.Minute, 35 BoostWorkers: 5, 36 Name: "TestChannelQueue", 37 }, 38 Workers: 0, 39 }, &testData{}) 40 assert.NoError(t, err) 41 42 assert.Equal(t, queue.(*ChannelUniqueQueue).WorkerPool.boostWorkers, 5) 43 44 go queue.Run(nilFn, nilFn) 45 46 test1 := testData{"A", 1} 47 go queue.Push(&test1) 48 result1 := <-handleChan 49 assert.Equal(t, test1.TestString, result1.TestString) 50 assert.Equal(t, test1.TestInt, result1.TestInt) 51 52 err = queue.Push(test1) 53 assert.Error(t, err) 54 } 55 56 func TestChannelUniqueQueue_Batch(t *testing.T) { 57 handleChan := make(chan *testData) 58 handle := func(data ...Data) []Data { 59 for _, datum := range data { 60 testDatum := datum.(*testData) 61 handleChan <- testDatum 62 } 63 return nil 64 } 65 66 nilFn := func(_ func()) {} 67 68 queue, err := NewChannelUniqueQueue(handle, 69 ChannelQueueConfiguration{ 70 WorkerPoolConfiguration: WorkerPoolConfiguration{ 71 QueueLength: 20, 72 BatchLength: 2, 73 BlockTimeout: 0, 74 BoostTimeout: 0, 75 BoostWorkers: 0, 76 MaxWorkers: 10, 77 }, 78 Workers: 1, 79 }, &testData{}) 80 assert.NoError(t, err) 81 82 go queue.Run(nilFn, nilFn) 83 84 test1 := testData{"A", 1} 85 test2 := testData{"B", 2} 86 87 queue.Push(&test1) 88 go queue.Push(&test2) 89 90 result1 := <-handleChan 91 assert.Equal(t, test1.TestString, result1.TestString) 92 assert.Equal(t, test1.TestInt, result1.TestInt) 93 94 result2 := <-handleChan 95 assert.Equal(t, test2.TestString, result2.TestString) 96 assert.Equal(t, test2.TestInt, result2.TestInt) 97 98 err = queue.Push(test1) 99 assert.Error(t, err) 100 } 101 102 func TestChannelUniqueQueue_Pause(t *testing.T) { 103 lock := sync.Mutex{} 104 var queue Queue 105 var err error 106 pushBack := false 107 handleChan := make(chan *testData) 108 handle := func(data ...Data) []Data { 109 lock.Lock() 110 if pushBack { 111 if pausable, ok := queue.(Pausable); ok { 112 pausable.Pause() 113 } 114 pushBack = false 115 lock.Unlock() 116 return data 117 } 118 lock.Unlock() 119 120 for _, datum := range data { 121 testDatum := datum.(*testData) 122 handleChan <- testDatum 123 } 124 return nil 125 } 126 nilFn := func(_ func()) {} 127 128 queue, err = NewChannelUniqueQueue(handle, 129 ChannelQueueConfiguration{ 130 WorkerPoolConfiguration: WorkerPoolConfiguration{ 131 QueueLength: 20, 132 BatchLength: 1, 133 BlockTimeout: 0, 134 BoostTimeout: 0, 135 BoostWorkers: 0, 136 MaxWorkers: 10, 137 }, 138 Workers: 1, 139 }, &testData{}) 140 assert.NoError(t, err) 141 142 go queue.Run(nilFn, nilFn) 143 144 test1 := testData{"A", 1} 145 test2 := testData{"B", 2} 146 queue.Push(&test1) 147 148 pausable, ok := queue.(Pausable) 149 if !assert.True(t, ok) { 150 return 151 } 152 result1 := <-handleChan 153 assert.Equal(t, test1.TestString, result1.TestString) 154 assert.Equal(t, test1.TestInt, result1.TestInt) 155 156 pausable.Pause() 157 158 paused, resumed := pausable.IsPausedIsResumed() 159 160 select { 161 case <-paused: 162 case <-resumed: 163 assert.Fail(t, "Queue should not be resumed") 164 return 165 default: 166 assert.Fail(t, "Queue is not paused") 167 return 168 } 169 170 queue.Push(&test2) 171 172 var result2 *testData 173 select { 174 case result2 = <-handleChan: 175 assert.Fail(t, "handler chan should be empty") 176 case <-time.After(100 * time.Millisecond): 177 } 178 179 assert.Nil(t, result2) 180 181 pausable.Resume() 182 183 select { 184 case <-resumed: 185 default: 186 assert.Fail(t, "Queue should be resumed") 187 } 188 189 select { 190 case result2 = <-handleChan: 191 case <-time.After(500 * time.Millisecond): 192 assert.Fail(t, "handler chan should contain test2") 193 } 194 195 assert.Equal(t, test2.TestString, result2.TestString) 196 assert.Equal(t, test2.TestInt, result2.TestInt) 197 198 lock.Lock() 199 pushBack = true 200 lock.Unlock() 201 202 paused, resumed = pausable.IsPausedIsResumed() 203 204 select { 205 case <-paused: 206 assert.Fail(t, "Queue should not be paused") 207 return 208 case <-resumed: 209 default: 210 assert.Fail(t, "Queue is not resumed") 211 return 212 } 213 214 queue.Push(&test1) 215 216 select { 217 case <-paused: 218 case <-handleChan: 219 assert.Fail(t, "handler chan should not contain test1") 220 return 221 case <-time.After(500 * time.Millisecond): 222 assert.Fail(t, "queue should be paused") 223 return 224 } 225 226 paused, resumed = pausable.IsPausedIsResumed() 227 228 select { 229 case <-paused: 230 case <-resumed: 231 assert.Fail(t, "Queue should not be resumed") 232 return 233 default: 234 assert.Fail(t, "Queue is not paused") 235 return 236 } 237 238 pausable.Resume() 239 240 select { 241 case <-resumed: 242 default: 243 assert.Fail(t, "Queue should be resumed") 244 } 245 246 select { 247 case result1 = <-handleChan: 248 case <-time.After(500 * time.Millisecond): 249 assert.Fail(t, "handler chan should contain test1") 250 } 251 assert.Equal(t, test1.TestString, result1.TestString) 252 assert.Equal(t, test1.TestInt, result1.TestInt) 253 }