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