github.com/better-concurrent/guc@v0.0.0-20190520022744-eb29266403a1/priorityblockingqueue_test.go (about) 1 package guc 2 3 import ( 4 "container/list" 5 "testing" 6 "time" 7 ) 8 9 func TestNewPriorityBlockingQueue(t *testing.T) { 10 p := NewPriorityBlockingQueue() 11 if !p.IsEmpty() { 12 t.Fatal("queue should be empty") 13 } 14 } 15 16 type sampleBlockingItem struct { 17 Value int 18 } 19 20 func (this *sampleBlockingItem) Equals(i interface{}) bool { 21 dst, ok := i.(*sampleBlockingItem) 22 if !ok { 23 return false 24 } 25 return this.Value == dst.Value 26 } 27 28 func (this *sampleBlockingItem) CompareTo(i interface{}) int { 29 return this.Value - i.(*sampleBlockingItem).Value 30 } 31 32 func newSampleBlockingItem(value int) *sampleBlockingItem { 33 return &sampleBlockingItem{ 34 Value: value, 35 } 36 } 37 38 func newPreparedPriorityBlockingQueue() *PriorityBlockingQueue { 39 p := NewPriorityBlockingQueue() 40 p.Add(newSampleBlockingItem(6)) 41 p.Add(newSampleBlockingItem(8)) 42 p.Add(newSampleBlockingItem(3)) 43 p.Add(newSampleBlockingItem(6)) 44 p.Add(newSampleBlockingItem(33)) 45 p.Add(newSampleBlockingItem(7)) 46 p.Add(newSampleBlockingItem(2)) 47 return p 48 } 49 50 func TestPriorityBlockingQueue_Add(t *testing.T) { 51 p := newPreparedPriorityBlockingQueue() 52 if p.IsEmpty() { 53 t.Fatal("queue should not be empty") 54 } 55 if p.priorityQueue.data.data[0].(*sampleBlockingItem).Value != 2 { 56 t.Fatal("first should be value 2") 57 } 58 if p.Size() != 7 { 59 t.Fatal("queue size should be 7") 60 } 61 } 62 63 func TestPriorityBlockingQueue_Contains(t *testing.T) { 64 p := newPreparedPriorityBlockingQueue() 65 if p.Contains(newSampleBlockingItem(100)) { 66 t.Fatal("queue should not contains value 100") 67 } 68 if !p.Contains(newSampleBlockingItem(6)) { 69 t.Fatal("queue should contains value 6") 70 } 71 if !p.Contains(newSampleBlockingItem(3)) { 72 t.Fatal("queue should contains value 3") 73 } 74 } 75 76 func TestPriorityBlockingQueue_ForEach(t *testing.T) { 77 p := newPreparedPriorityBlockingQueue() 78 79 l := list.New() 80 p.ForEach(func(i interface{}) { 81 l.PushBack(i) 82 }) 83 if l.Len() != 7 { 84 t.Fatal("total number of foreach items are not 7") 85 } 86 } 87 88 func TestPriorityBlockingQueue_ToArray(t *testing.T) { 89 p := newPreparedPriorityBlockingQueue() 90 91 arr := p.ToArray() 92 if len(arr) != 7 { 93 t.Fatal("array size must be 7") 94 } 95 matched := false 96 for _, v := range arr { 97 if v.(*sampleBlockingItem).Value == 6 { 98 matched = true 99 break 100 } 101 } 102 if !matched { 103 t.Fatal("must have value 6 in array") 104 } 105 } 106 107 func TestPriorityBlockingQueue_FillArray(t *testing.T) { 108 p := newPreparedPriorityBlockingQueue() 109 110 arr := p.FillArray(make([]interface{}, 0)) 111 if len(arr) != 7 { 112 t.Fatal("array size must be 7") 113 } 114 matched := false 115 for _, v := range arr { 116 if v.(*sampleBlockingItem).Value == 6 { 117 matched = true 118 break 119 } 120 } 121 if !matched { 122 t.Fatal("must have value 6 in array") 123 } 124 125 newArr := make([]interface{}, 7) 126 p.FillArray(newArr) 127 matched = false 128 for _, v := range newArr { 129 if v.(*sampleBlockingItem).Value == 6 { 130 matched = true 131 break 132 } 133 } 134 if !matched { 135 t.Fatal("must have value 6 in array") 136 } 137 } 138 139 func TestPriorityBlockingQueue_Remove(t *testing.T) { 140 p := newPreparedPriorityBlockingQueue() 141 142 b := p.Remove(newSampleBlockingItem(100)) 143 if b { 144 t.Fatal("should return false") 145 } 146 if p.Size() != 7 { 147 t.Fatal("size should be 7") 148 } 149 150 b = p.Remove(newSampleBlockingItem(3)) 151 if !b { 152 t.Fatal("should return true") 153 } 154 if p.Size() != 6 { 155 t.Fatal("size should be 6") 156 } 157 158 b = p.Remove(newSampleBlockingItem(6)) 159 if !b { 160 t.Fatal("should return true") 161 } 162 if p.Size() != 5 { 163 t.Fatal("size should be 5") 164 } 165 } 166 167 func TestPriorityBlockingQueue_ContainsAll(t *testing.T) { 168 p := newPreparedPriorityBlockingQueue() 169 170 c := NewPriorityBlockingQueue() 171 c.Add(newSampleBlockingItem(6)) 172 c.Add(newSampleBlockingItem(2)) 173 if !p.ContainsAll(c) { 174 t.Fatal("should contains all") 175 } 176 177 c = NewPriorityBlockingQueue() 178 c.Add(newSampleBlockingItem(6)) 179 c.Add(newSampleBlockingItem(100)) 180 if p.ContainsAll(c) { 181 t.Fatal("should not contains all - 1") 182 } 183 184 c = NewPriorityBlockingQueue() 185 c.Add(newSampleBlockingItem(200)) 186 c.Add(newSampleBlockingItem(100)) 187 if p.ContainsAll(c) { 188 t.Fatal("should not contains all - 2") 189 } 190 } 191 192 func TestPriorityBlockingQueue_AddAll(t *testing.T) { 193 p := newPreparedPriorityBlockingQueue() 194 if p.Size() != 7 { 195 t.Fatal("queue size must be 7") 196 } 197 198 c := NewPriorityBlockingQueue() 199 c.Add(newSampleBlockingItem(200)) 200 c.Add(newSampleBlockingItem(100)) 201 if !p.AddAll(c) { 202 t.Fatal("add result should be true") 203 } 204 205 if !p.Contains(newSampleBlockingItem(100)) { 206 t.Fatal("queue should contains value 100") 207 } 208 if !p.Contains(newSampleBlockingItem(200)) { 209 t.Fatal("queue should contains value 200") 210 } 211 if p.Size() != 9 { 212 t.Fatal("queue size should be 9") 213 } 214 } 215 216 func TestPriorityBlockingQueue_RemoveAll(t *testing.T) { 217 p := newPreparedPriorityBlockingQueue() 218 if p.Size() != 7 { 219 t.Fatal("queue size must be 7") 220 } 221 222 c := NewPriorityBlockingQueue() 223 c.Add(newSampleBlockingItem(200)) 224 c.Add(newSampleBlockingItem(100)) 225 if p.RemoveAll(c) { 226 t.Fatal("remove all should return false") 227 } 228 if p.Size() != 7 { 229 t.Fatal("queue size should be 7") 230 } 231 232 c = NewPriorityBlockingQueue() 233 c.Add(newSampleBlockingItem(3)) 234 c.Add(newSampleBlockingItem(100)) 235 if !p.RemoveAll(c) { 236 t.Fatal("remove all should return true") 237 } 238 if p.Size() != 6 { 239 t.Fatal("queue size should be 6") 240 } 241 242 c = NewPriorityBlockingQueue() 243 c.Add(newSampleBlockingItem(8)) 244 c.Add(newSampleBlockingItem(2)) 245 if !p.RemoveAll(c) { 246 t.Fatal("remove all should return true") 247 } 248 if p.Size() != 4 { 249 t.Fatal("queue size should be 4") 250 } 251 } 252 253 func TestPriorityBlockingQueue_RemoveIf(t *testing.T) { 254 p := newPreparedPriorityBlockingQueue() 255 if p.Size() != 7 { 256 t.Fatal("queue size not match") 257 } 258 259 b := p.RemoveIf(func(i interface{}) bool { 260 return i.(*sampleBlockingItem).Value == 6 261 }) 262 if !b { 263 t.Fatal("remove result should be true") 264 } 265 if p.Size() != 6 { 266 t.Fatal("queue size should be 6") 267 } 268 269 b = p.RemoveIf(func(i interface{}) bool { 270 return i.(*sampleBlockingItem).Value == 100 271 }) 272 if b { 273 t.Fatal("remove result should be false") 274 } 275 if p.Size() != 6 { 276 t.Fatal("queue size should be 6") 277 } 278 } 279 280 func TestPriorityBlockingQueue_RetainAll(t *testing.T) { 281 { 282 p := newPreparedPriorityBlockingQueue() 283 c := NewPriorityBlockingQueue() 284 c.Add(newSampleBlockingItem(200)) 285 c.Add(newSampleBlockingItem(100)) 286 if !p.RetainAll(c) { 287 t.Fatal("remove all should return true") 288 } 289 if p.Size() != 0 { 290 t.Fatal("queue size should be 0") 291 } 292 } 293 { 294 p := newPreparedPriorityBlockingQueue() 295 c := NewPriorityBlockingQueue() 296 c.Add(newSampleBlockingItem(3)) 297 c.Add(newSampleBlockingItem(100)) 298 if !p.RetainAll(c) { 299 t.Fatal("remove all should return true") 300 } 301 if p.Size() != 1 { 302 t.Fatal("queue size should be 1") 303 } 304 } 305 { 306 p := newPreparedPriorityBlockingQueue() 307 c := NewPriorityBlockingQueue() 308 c.Add(newSampleBlockingItem(8)) 309 c.Add(newSampleBlockingItem(2)) 310 if !p.RetainAll(c) { 311 t.Fatal("remove all should return true") 312 } 313 if p.Size() != 2 { 314 t.Fatal("queue size should be 2") 315 } 316 } 317 } 318 319 func TestPriorityBlockingQueue_Clear(t *testing.T) { 320 p := newPreparedPriorityBlockingQueue() 321 if p.Size() != 7 { 322 t.Fatal("queue size not match") 323 } 324 p.Clear() 325 if p.Size() != 0 { 326 t.Fatal("queue size should be 0") 327 } 328 if !p.IsEmpty() { 329 t.Fatal("queue should be empty") 330 } 331 } 332 333 func TestPriorityBlockingQueue_Equals(t *testing.T) { 334 p := newPreparedPriorityBlockingQueue() 335 if !p.Equals(p) { 336 t.Fatal("queue should be equals to itself") 337 } 338 if p.Equals(newPreparedPriorityBlockingQueue()) { 339 t.Fatal("queue should not be equals to a new one") 340 } 341 if p.Equals(struct{}{}) { 342 t.Fatal("queue should not be equals to another object of other type") 343 } 344 } 345 346 func TestPriorityBlockingQueue_HashCode(t *testing.T) { 347 p := newPreparedPriorityBlockingQueue() 348 if p.HashCode() != p.HashCode() { 349 t.Fatal("hashcode must same") 350 } 351 } 352 353 func TestPriorityBlockingQueue_RemoveHead(t *testing.T) { 354 p := newPreparedPriorityBlockingQueue() 355 h := p.RemoveHead().(*sampleBlockingItem) 356 if h.Value != 2 { 357 t.Fatal("remove head must value 2") 358 } 359 if p.Size() != 6 { 360 t.Fatal("queue size must be 6") 361 } 362 363 emptyQueue := NewPriorityBlockingQueue() 364 r := func(p *PriorityBlockingQueue) (result bool) { 365 result = false 366 defer func() { 367 err := recover() 368 if err != nil { 369 result = true 370 } 371 }() 372 p.RemoveHead() 373 return 374 }(emptyQueue) 375 if !r { 376 t.Fatal("should panic when RemoveHead of an empty queue") 377 } 378 } 379 380 func TestPriorityBlockingQueue_Poll(t *testing.T) { 381 p := newPreparedPriorityBlockingQueue() 382 if p.Size() != 7 { 383 t.Fatal("queue size not match") 384 } 385 386 prev := -1 387 for i := 0; i < 7; i++ { 388 s := p.Poll().(*sampleBlockingItem) 389 if prev == -1 { 390 prev = s.Value 391 continue 392 } 393 if prev > s.Value { 394 t.Fatal("prev value:", prev, "should be <= current value:", s.Value) 395 } 396 prev = s.Value 397 } 398 } 399 400 func TestPriorityBlockingQueue_Peek(t *testing.T) { 401 p := newPreparedPriorityBlockingQueue() 402 h := p.Peek().(*sampleBlockingItem) 403 if h.Value != 2 { 404 t.Fatal("remove head must value 2") 405 } 406 407 emptyQueue := NewPriorityBlockingQueue() 408 r := emptyQueue.Peek() 409 if r != nil { 410 t.Fatal("peek of empty queue should be nil") 411 } 412 } 413 414 func TestPriorityBlockingQueue_Element(t *testing.T) { 415 p := newPreparedPriorityBlockingQueue() 416 h := p.Element().(*sampleBlockingItem) 417 if h.Value != 2 { 418 t.Fatal("element() must value 2") 419 } 420 421 emptyQueue := NewPriorityBlockingQueue() 422 r := func(p *PriorityBlockingQueue) (result bool) { 423 result = false 424 defer func() { 425 err := recover() 426 if err != nil { 427 result = true 428 } 429 }() 430 p.Element() 431 return 432 }(emptyQueue) 433 if !r { 434 t.Fatal("should panic when element() of an empty queue") 435 } 436 } 437 438 func TestPriorityBlockingQueue_Put(t *testing.T) { 439 p := newPreparedPriorityBlockingQueue() 440 p.Put(newSampleBlockingItem(100)) 441 if p.Size() != 8 { 442 t.Fatal("queue size must be 8") 443 } 444 if !p.Contains(newSampleBlockingItem(100)) { 445 t.Fatal("queue must contains value 100") 446 } 447 } 448 449 func TestPriorityBlockingQueue_Offer(t *testing.T) { 450 p := newPreparedPriorityBlockingQueue() 451 p.Offer(newSampleBlockingItem(100)) 452 if p.Size() != 8 { 453 t.Fatal("queue size must be 8") 454 } 455 if !p.Contains(newSampleBlockingItem(100)) { 456 t.Fatal("queue must contains value 100") 457 } 458 } 459 460 func TestPriorityBlockingQueue_OfferWithTimeout(t *testing.T) { 461 p := newPreparedPriorityBlockingQueue() 462 p.OfferWithTimeout(newSampleBlockingItem(100), 1*time.Hour) 463 if p.Size() != 8 { 464 t.Fatal("queue size must be 8") 465 } 466 if !p.Contains(newSampleBlockingItem(100)) { 467 t.Fatal("queue must contains value 100") 468 } 469 } 470 471 func TestPriorityBlockingQueue_Take(t *testing.T) { 472 { 473 p := newPreparedPriorityBlockingQueue() 474 i := p.Take() 475 if i == nil { 476 t.Fatal("take from queue should return a value") 477 } 478 } 479 { 480 p := NewPriorityBlockingQueue() 481 ch := make(chan struct{}, 1) 482 go func() { 483 <-ch 484 time.Sleep(50 * time.Millisecond) 485 p.Offer(newSampleBlockingItem(1)) 486 }() 487 ch <- struct{}{} 488 i := p.Take() 489 if i.(*sampleBlockingItem).Value != 1 { 490 t.Fatal("shoudl have value 1") 491 } 492 } 493 } 494 495 func TestPriorityBlockingQueue_PollWithTimeout(t *testing.T) { 496 { 497 p := newPreparedPriorityBlockingQueue() 498 i := p.PollWithTimeout(1 * time.Second) 499 if i == nil { 500 t.Fatal("take from queue should return a value") 501 } 502 } 503 { 504 p := NewPriorityBlockingQueue() 505 ch := make(chan struct{}, 1) 506 go func() { 507 <-ch 508 time.Sleep(50 * time.Millisecond) 509 p.Offer(newSampleBlockingItem(1)) 510 }() 511 ch <- struct{}{} 512 i := p.PollWithTimeout(1 * time.Second) 513 if i.(*sampleBlockingItem).Value != 1 { 514 t.Fatal("shoudl have value 1") 515 } 516 } 517 } 518 519 func TestPriorityBlockingQueue_RemainingCapacity(t *testing.T) { 520 p := newPreparedPriorityBlockingQueue() 521 if p.RemainingCapacity() <= 0 { 522 t.Fatal("remaining capacity should greater than 0") 523 } 524 p = NewPriorityBlockingQueue() 525 if p.RemainingCapacity() <= 0 { 526 t.Fatal("remaining capacity should greater than 0") 527 } 528 } 529 530 func TestPriorityBlockingQueue_DrainTo(t *testing.T) { 531 p := newPreparedPriorityBlockingQueue() 532 d := NewPriorityBlockingQueue() 533 if p.DrainTo(d) != 7 { 534 t.Fatal("drain result should be 7") 535 } 536 if d.Size() != 7 { 537 t.Fatal("dest size should be 7") 538 } 539 if !d.Contains(newSampleBlockingItem(6)) { 540 t.Fatal("dest should contain value 7") 541 } 542 if !d.Contains(newSampleBlockingItem(33)) { 543 t.Fatal("dest should contain value 33") 544 } 545 if !d.Contains(newSampleBlockingItem(3)) { 546 t.Fatal("dest should contain value 3") 547 } 548 if d.Contains(newSampleBlockingItem(0)) { 549 t.Fatal("dest should not contain value 0") 550 } 551 } 552 553 func TestPriorityBlockingQueue_DrainToWithLimit(t *testing.T) { 554 p := newPreparedPriorityBlockingQueue() 555 d := NewPriorityBlockingQueue() 556 if p.DrainToWithLimit(d, 2) != 2 { 557 t.Fatal("drain result should be 2") 558 } 559 if d.Size() != 2 { 560 t.Fatal("dest size should be 2") 561 } 562 } 563 564 func TestPriorityBlockingQueue_Iterator(t *testing.T) { 565 p := newPreparedPriorityBlockingQueue() 566 cnt := 0 567 matched := false 568 iter := p.Iterator() 569 if iter == nil { 570 t.Fatal("iter should not be nil") 571 } 572 for iter.HasNext() { 573 cnt++ 574 if iter.Next().(*sampleBlockingItem).Value == 6 { 575 matched = true 576 } 577 } 578 if cnt != 7 { 579 t.Fatal("iter count should be 7") 580 } 581 if !matched { 582 t.Fatal("should contains value 6") 583 } 584 } 585 586 func TestPriorityBlockingQueueIter_ForEachRemaining(t *testing.T) { 587 p := newPreparedPriorityBlockingQueue() 588 iter := p.Iterator() 589 590 l := list.New() 591 iter.ForEachRemaining(func(i interface{}) { 592 l.PushBack(i) 593 }) 594 if l.Len() != 7 { 595 t.Fatal("total number of foreach items are not 7") 596 } 597 } 598 599 func TestPriorityBlockingQueueIter_Remove(t *testing.T) { 600 p := newPreparedPriorityBlockingQueue() 601 iter := p.Iterator() 602 iter.HasNext() 603 iter.Remove() 604 iterImpl := iter.(*priorityBlockingQueueIter) 605 if len(iterImpl.data) != 7 { 606 t.Fatal("iter size should be 7") 607 } 608 if p.Size() != 6 { 609 t.Fatal("iter size should be 6") 610 } 611 }