gitlab.com/ignitionrobotics/web/ign-go@v1.0.0-rc4/queue_test.go (about) 1 package ign 2 3 import ( 4 "fmt" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/suite" 10 ) 11 12 type QueueTestSuite struct { 13 suite.Suite 14 queue *Queue 15 } 16 17 const ( 18 testValue = "test value" 19 ) 20 21 func (suite *QueueTestSuite) SetupTest() { 22 suite.queue = NewQueue() 23 } 24 25 // *************************************************************************************** 26 // ** Queue initialization 27 // *************************************************************************************** 28 29 // no elements at initialization 30 func (suite *QueueTestSuite) TestNoElementsAtInitialization() { 31 length := suite.queue.GetLen() 32 suite.Equalf(0, length, "No elements expected at initialization, currently: %v", length) 33 } 34 35 // *************************************************************************************** 36 // ** Enqueue && GetLen 37 // *************************************************************************************** 38 39 // single enqueue (1 element, 1 goroutine) 40 func (suite *QueueTestSuite) TestEnqueueLenSingleGR() { 41 suite.queue.Enqueue(testValue) 42 length := suite.queue.GetLen() 43 suite.Equalf(1, length, "Expected number of elements in queue: 1, currently: %v", length) 44 45 suite.queue.Enqueue(5) 46 length = suite.queue.GetLen() 47 suite.Equalf(2, length, "Expected number of elements in queue: 2, currently: %v", length) 48 } 49 50 // single enqueue and wait for next element 51 func (suite *QueueTestSuite) TestEnqueueWaitForNextElementSingleGR() { 52 waitForNextElement := make(chan interface{}) 53 // add the listener manually (ONLY for testings purposes) 54 suite.queue.waitForNextElementChan <- waitForNextElement 55 56 value := 100 57 // enqueue from a different GR to avoid blocking the listener channel 58 go suite.queue.Enqueue(value) 59 // wait for the enqueued element 60 result := <-waitForNextElement 61 62 suite.Equal(value, result) 63 } 64 65 // TestEnqueueLenMultipleGR enqueues elements concurrently 66 // 67 // Detailed steps: 68 // 1 - Enqueue totalGRs concurrently (from totalGRs different GRs) 69 // 2 - Verifies the len, it should be equal to totalGRs 70 // 3 - Verifies that all elements from 0 to totalGRs were enqueued 71 func (suite *QueueTestSuite) TestEnqueueLenMultipleGR() { 72 var ( 73 totalGRs = 500 74 wg sync.WaitGroup 75 ) 76 77 // concurrent enqueueing 78 // multiple GRs concurrently enqueueing consecutive integers from 0 to (totalGRs - 1) 79 for i := 0; i < totalGRs; i++ { 80 wg.Add(1) 81 go func(value int) { 82 defer wg.Done() 83 suite.queue.Enqueue(value) 84 }(i) 85 } 86 wg.Wait() 87 88 // check that there are totalGRs elements enqueued 89 totalElements := suite.queue.GetLen() 90 suite.Equalf(totalGRs, totalElements, "Total enqueued elements should be %v, currently: %v", totalGRs, totalElements) 91 92 // checking that the expected elements (1, 2, 3, ... totalGRs-1 ) were enqueued 93 var ( 94 tmpVal interface{} 95 val int 96 err *ErrMsg 97 totalElementsVerified int 98 ) 99 // slice to check every element 100 sl2check := make([]bool, totalGRs) 101 102 for i := 0; i < totalElements; i++ { 103 tmpVal, err = suite.queue.GetElement(i) 104 suite.Nil(err, "No error should be returned trying to get an existent element") 105 106 val = tmpVal.(int) 107 if !sl2check[val] { 108 totalElementsVerified++ 109 sl2check[val] = true 110 } else { 111 suite.Failf("Duplicated element", "Unexpected duplicated value: %v", val) 112 } 113 } 114 suite.True(totalElementsVerified == totalGRs, "Enqueued elements are missing") 115 } 116 117 // call GetLen concurrently 118 func (suite *QueueTestSuite) TestGetLenMultipleGRs() { 119 var ( 120 totalGRs = 100 121 totalElementsToEnqueue = 10 122 wg sync.WaitGroup 123 ) 124 125 for i := 0; i < totalElementsToEnqueue; i++ { 126 suite.queue.Enqueue(i) 127 } 128 129 for i := 0; i < totalGRs; i++ { 130 wg.Add(1) 131 go func() { 132 defer wg.Done() 133 134 total := suite.queue.GetLen() 135 suite.Equalf(totalElementsToEnqueue, total, "Expected len: %v", totalElementsToEnqueue) 136 }() 137 } 138 wg.Wait() 139 } 140 141 // *************************************************************************************** 142 // ** GetCap 143 // *************************************************************************************** 144 145 // single GR getCapacity 146 func (suite *QueueTestSuite) TestGetCapSingleGR() { 147 // initial capacity 148 suite.Equal(cap(suite.queue.slice), suite.queue.GetCap(), "unexpected capacity") 149 150 // checking after adding 2 items 151 suite.queue.Enqueue(1) 152 suite.queue.Enqueue(2) 153 suite.Equal(cap(suite.queue.slice), suite.queue.GetCap(), "unexpected capacity") 154 } 155 156 // *************************************************************************************** 157 // ** Get 158 // *************************************************************************************** 159 160 // get a valid element 161 func (suite *QueueTestSuite) TestGetSingleGR() { 162 suite.queue.Enqueue(testValue) 163 val, err := suite.queue.GetElement(0) 164 165 // verify error (should be nil) 166 suite.Nil(err, "No error should be enqueueing an element") 167 168 // verify element's value 169 suite.Equalf(testValue, val, "Different element returned: %v", val) 170 } 171 172 // get a invalid element 173 func (suite *QueueTestSuite) TestGetInvalidElementSingleGR() { 174 suite.queue.Enqueue(testValue) 175 val, err := suite.queue.GetElement(1) 176 177 // verify error 178 suite.Equal(ErrorQueueIndexOutOfBounds, err.ErrCode, "An error should be returned after ask for a no existent element") 179 180 // verify element's value 181 suite.Equalf(val, nil, "Nil should be returned, currently returned: %v", val) 182 } 183 184 // call Get concurrently 185 func (suite *QueueTestSuite) TestGetMultipleGRs() { 186 var ( 187 totalGRs = 100 188 totalElementsToEnqueue = 10 189 wg sync.WaitGroup 190 ) 191 192 for i := 0; i < totalElementsToEnqueue; i++ { 193 suite.queue.Enqueue(i) 194 } 195 196 for i := 0; i < totalGRs; i++ { 197 wg.Add(1) 198 go func() { 199 defer wg.Done() 200 val, err := suite.queue.GetElement(5) 201 202 suite.Nil(err, "No error should be returned trying to get an existent element") 203 suite.Equal(5, val.(int), "Expected element's value: 5") 204 }() 205 } 206 wg.Wait() 207 208 total := suite.queue.GetLen() 209 suite.Equalf(totalElementsToEnqueue, total, "Expected len: %v", totalElementsToEnqueue) 210 } 211 212 // *************************************************************************************** 213 // ** Remove 214 // *************************************************************************************** 215 216 // remove elements 217 func (suite *QueueTestSuite) TestRemoveSingleGR() { 218 suite.queue.Enqueue(testValue) 219 suite.queue.Enqueue(5) 220 221 // removing first element 222 err := suite.queue.Remove(testValue) 223 suite.Nil(err, "Unexpected error") 224 225 // get element at index 0 226 val, err2 := suite.queue.GetElement(0) 227 suite.Nil(err2, "Unexpected error") 228 suite.Equal(5, val, "Queue returned the wrong element") 229 } 230 231 func (suite *QueueTestSuite) TestRemoveNotFound() { 232 suite.queue.Enqueue(testValue) 233 234 err := suite.queue.Remove("anotherValue") 235 236 suite.Equal(ErrorIDNotFound, err.ErrCode) 237 } 238 239 // TestRemoveMultipleGRs removes elements concurrently. 240 // 241 // Detailed steps: 242 // 1 - Enqueues totalElementsToEnqueue consecutive elements (0, 1, 2, 3, ... totalElementsToEnqueue - 1) 243 // 2 - Hits queue.Remove(1) concurrently from totalElementsToRemove different GRs 244 // 3 - Verifies the final len == totalElementsToEnqueue - totalElementsToRemove 245 // 4 - Verifies that final 2nd element == (1 + totalElementsToRemove) 246 func (suite *QueueTestSuite) TestRemoveMultipleGRs() { 247 var ( 248 wg sync.WaitGroup 249 totalElementsToEnqueue = 100 250 totalElementsToRemove = 90 251 ) 252 253 for i := 0; i < totalElementsToEnqueue; i++ { 254 suite.queue.Enqueue(testValue) 255 } 256 257 for i := 0; i < totalElementsToRemove; i++ { 258 wg.Add(1) 259 go func() { 260 defer wg.Done() 261 err := suite.queue.Remove(testValue) 262 suite.Nil(err, "Unexpected error during concurrent Remove(n)") 263 }() 264 } 265 wg.Wait() 266 267 // check len, should be == totalElementsToEnqueue - totalElementsToRemove 268 totalElementsAfterRemove := suite.queue.GetLen() 269 suite.Equal(totalElementsToEnqueue-totalElementsToRemove, totalElementsAfterRemove, "Total elements on list does not match with expected number") 270 271 // check current 2nd element (index 1) on the queue 272 _, err := suite.queue.GetElement(1) 273 suite.Nil(err, "No error should be returned when getting an existent element") 274 } 275 276 // *************************************************************************************** 277 // ** Dequeue 278 // *************************************************************************************** 279 280 // dequeue an empty queue 281 func (suite *QueueTestSuite) TestDequeueEmptyQueueSingleGR() { 282 val, err := suite.queue.Dequeue() 283 284 // error expected 285 suite.Equal(ErrorQueueEmpty, err.ErrCode, "Can't dequeue an empty queue") 286 287 // no value expected 288 suite.Equal(nil, val, "Can't get a value different than nil from an empty queue") 289 } 290 291 // dequeue all elements 292 func (suite *QueueTestSuite) TestDequeueSingleGR() { 293 suite.queue.Enqueue(testValue) 294 suite.queue.Enqueue(5) 295 296 // get the first element 297 val, err := suite.queue.Dequeue() 298 suite.Nil(err, "Unexpected error") 299 suite.Equal(testValue, val, "Wrong element's value") 300 length := suite.queue.GetLen() 301 suite.Equal(1, length, "Incorrect number of queue elements") 302 303 // get the second element 304 val, err = suite.queue.Dequeue() 305 suite.Nil(err, "Unexpected error") 306 suite.Equal(5, val, "Wrong element's value") 307 length = suite.queue.GetLen() 308 suite.Equal(0, length, "Incorrect number of queue elements") 309 310 } 311 312 // TestDequeueMultipleGRs dequeues elements concurrently 313 // 314 // Detailed steps: 315 // 1 - Enqueues totalElementsToEnqueue consecutive integers 316 // 2 - Dequeues totalElementsToDequeue concurrently from totalElementsToDequeue GRs 317 // 3 - Verifies the final len, should be equal to totalElementsToEnqueue - totalElementsToDequeue 318 // 4 - Verifies that the next dequeued element's value is equal to totalElementsToDequeue 319 func (suite *QueueTestSuite) TestDequeueMultipleGRs() { 320 var ( 321 wg sync.WaitGroup 322 totalElementsToEnqueue = 100 323 totalElementsToDequeue = 90 324 ) 325 326 for i := 0; i < totalElementsToEnqueue; i++ { 327 suite.queue.Enqueue(i) 328 } 329 330 for i := 0; i < totalElementsToDequeue; i++ { 331 wg.Add(1) 332 go func() { 333 defer wg.Done() 334 _, err := suite.queue.Dequeue() 335 suite.Nil(err, "Unexpected error during concurrent Dequeue()") 336 }() 337 } 338 wg.Wait() 339 340 // check len, should be == totalElementsToEnqueue - totalElementsToDequeue 341 totalElementsAfterDequeue := suite.queue.GetLen() 342 suite.Equal(totalElementsToEnqueue-totalElementsToDequeue, totalElementsAfterDequeue, "Total elements on queue (after Dequeue) does not match with expected number") 343 344 // check current first element 345 val, err := suite.queue.Dequeue() 346 suite.Nil(err, "No error should be returned when dequeuing an existent element") 347 suite.Equalf(totalElementsToDequeue, val, "The expected last element's value should be: %v", totalElementsToEnqueue-totalElementsToDequeue) 348 } 349 350 // *************************************************************************************** 351 // ** DequeueOrWaitForNextElement 352 // *************************************************************************************** 353 354 // single GR DequeueOrWaitForNextElement with a previous enqueued element 355 func (suite *QueueTestSuite) TestDequeueOrWaitForNextElementWithEnqueuedElementSingleGR() { 356 value := 100 357 length := suite.queue.GetLen() 358 suite.queue.Enqueue(value) 359 360 result, err := suite.queue.DequeueOrWaitForNextElement() 361 362 suite.Nil(err) 363 suite.Equal(value, result) 364 // length must be exactly the same as it was before 365 suite.Equal(length, suite.queue.GetLen()) 366 } 367 368 // single GR DequeueOrWaitForNextElement 1 element 369 func (suite *QueueTestSuite) TestDequeueOrWaitForNextElementWithEmptyQueue() { 370 var ( 371 value = 100 372 result interface{} 373 err *ErrMsg 374 done = make(chan struct{}) 375 ) 376 377 // waiting for next enqueued element 378 go func() { 379 result, err = suite.queue.DequeueOrWaitForNextElement() 380 done <- struct{}{} 381 }() 382 383 // enqueue an element 384 go func() { 385 suite.queue.Enqueue(value) 386 }() 387 388 select { 389 // wait for the dequeued element 390 case <-done: 391 suite.Nil(err) 392 suite.Equal(value, result) 393 394 // the following comes first if more time than expected happened while waiting for the dequeued element 395 case <-time.After(2 * time.Second): 396 suite.Fail("too much time waiting for the enqueued element") 397 398 } 399 } 400 401 // single GR calling DequeueOrWaitForNextElement (WaitForNextElementChanCapacity + 1) times, last one should return error 402 func (suite *QueueTestSuite) TestDequeueOrWaitForNextElementWithFullWaitingChannel() { 403 // enqueue WaitForNextElementChanCapacity listeners to future enqueued elements 404 for i := 0; i < WaitForNextElementChanCapacity; i++ { 405 suite.queue.waitForNextElementChan <- make(chan interface{}) 406 } 407 408 result, err := suite.queue.DequeueOrWaitForNextElement() 409 suite.Nil(result) 410 suite.Equal(ErrorQueueTooManyListeners, err.ErrCode) 411 } 412 413 // multiple GRs, calling DequeueOrWaitForNextElement from different GRs and enqueuing the expected values later 414 func (suite *QueueTestSuite) TestDequeueOrWaitForNextElementMultiGR() { 415 var ( 416 wg sync.WaitGroup 417 // channel to enqueue dequeued values 418 dequeuedValues = make(chan int, WaitForNextElementChanCapacity) 419 // map[dequeued_value] = times dequeued 420 mp = make(map[int]int) 421 ) 422 423 for i := 0; i < WaitForNextElementChanCapacity; i++ { 424 go func() { 425 // wait for the next enqueued element 426 result, err := suite.queue.DequeueOrWaitForNextElement() 427 // no error && no nil result 428 suite.Nil(err) 429 suite.NotNil(result) 430 431 // send each dequeued element into the dequeuedValues channel 432 resultInt, _ := result.(int) 433 dequeuedValues <- resultInt 434 435 // let the wg.Wait() know that this GR is done 436 wg.Done() 437 }() 438 } 439 440 // enqueue all needed elements 441 for i := 0; i < WaitForNextElementChanCapacity; i++ { 442 wg.Add(1) 443 suite.queue.Enqueue(i) 444 // save the enqueued value as index 445 mp[i] = 0 446 } 447 448 // wait until all GRs dequeue the elements 449 wg.Wait() 450 // close dequeuedValues channel in order to only read the previous enqueued values (from the channel) 451 close(dequeuedValues) 452 453 // verify that all enqueued values were dequeued 454 for v := range dequeuedValues { 455 val, ok := mp[v] 456 suite.Truef(ok, "element dequeued but never enqueued: %v", val) 457 // increment the m[p] value meaning the value p was dequeued 458 mp[v] = val + 1 459 } 460 // verify that there are no duplicates 461 for k, v := range mp { 462 suite.Equalf(1, v, "%v was dequeued %v times", k, v) 463 } 464 } 465 466 // multiple GRs, calling DequeueOrWaitForNextElement from different GRs and enqueuing the expected values later 467 func (suite *QueueTestSuite) TestDequeueOrWaitForNextElementMultiGR2() { 468 var ( 469 done = make(chan int, 10) 470 total = 2000 471 results = make(map[int]struct{}) 472 totalOk = 0 473 totalError = 0 474 ) 475 476 go func(queue *Queue, done chan int, total int) { 477 for i := 0; i < total; i++ { 478 go func(queue *Queue, done chan int) { 479 rawValue, err := queue.DequeueOrWaitForNextElement() 480 if err != nil { 481 fmt.Println(err) 482 // error 483 done <- -1 484 } else { 485 val, _ := rawValue.(int) 486 done <- val 487 } 488 }(queue, done) 489 490 go func(queue *Queue, value int) { 491 queue.Enqueue(value) 492 }(queue, i) 493 } 494 }(suite.queue, done, total) 495 496 i := 0 497 for { 498 v := <-done 499 if v != -1 { 500 totalOk++ 501 _, ok := results[v] 502 suite.Falsef(ok, "duplicated value %v", v) 503 504 results[v] = struct{}{} 505 } else { 506 totalError++ 507 } 508 509 i++ 510 if i == total { 511 break 512 } 513 } 514 515 suite.Equal(total, totalError+totalOk) 516 } 517 518 // call DequeueOrWaitForNextElement(), wait some time and enqueue an item 519 func (suite *QueueTestSuite) TestDequeueOrWaitForNextElementGapSingleGR() { 520 var ( 521 expectedValue = 50 522 done = make(chan struct{}, 3) 523 ) 524 525 // DequeueOrWaitForNextElement() 526 go func(queue *Queue, done chan struct{}) { 527 val, err := queue.DequeueOrWaitForNextElement() 528 suite.Nil(err) 529 suite.Equal(expectedValue, val) 530 done <- struct{}{} 531 }(suite.queue, done) 532 533 // wait and Enqueue function 534 go func(queue *Queue, done chan struct{}) { 535 time.Sleep(time.Millisecond * dequeueOrWaitForNextElementInvokeGapTime * dequeueOrWaitForNextElementInvokeGapTime) 536 queue.Enqueue(expectedValue) 537 done <- struct{}{} 538 }(suite.queue, done) 539 540 for i := 0; i < 2; i++ { 541 select { 542 case <-done: 543 case <-time.After(2 * time.Millisecond * dequeueOrWaitForNextElementInvokeGapTime * dequeueOrWaitForNextElementInvokeGapTime): 544 suite.FailNow("Too much time waiting for the value") 545 } 546 } 547 } 548 549 // *************************************************************************************** 550 // ** Swap 551 // *************************************************************************************** 552 func (suite *QueueTestSuite) TestSwapEmptyQueue() { 553 const ( 554 a = 4 555 b = 4 556 ) 557 558 err := suite.queue.Swap(a, b) 559 suite.Equal(ErrorQueueEmpty, err.ErrCode) 560 } 561 562 func (suite *QueueTestSuite) TestSwapIndexesNotFound() { 563 const ( 564 size = 2 565 a = 4 566 b = 3 567 ) 568 569 for i := 0; i < size; i++ { 570 suite.queue.Enqueue(i) 571 } 572 573 err := suite.queue.Swap(a, b) 574 575 suite.Equal(ErrorIDNotFound, err.ErrCode) 576 } 577 578 func (suite *QueueTestSuite) TestSwapSameIndex() { 579 const ( 580 size = 10 581 a = 4 582 b = 4 583 ) 584 585 for i := 0; i < size; i++ { 586 suite.queue.Enqueue(i) 587 } 588 589 err := suite.queue.Swap(a, b) 590 591 suite.Equal(ErrorQueueSwapIndexesMatch, err.ErrCode) 592 } 593 594 func (suite *QueueTestSuite) TestSwapElements() { 595 596 const ( 597 size = 10 598 a = 3 599 b = 4 600 ) 601 602 for i := 0; i < size; i++ { 603 suite.queue.Enqueue(i) 604 } 605 606 oldValueFromA, _ := suite.queue.GetElement(a) 607 oldValueFromB, _ := suite.queue.GetElement(b) 608 609 suite.queue.Swap(a, b) 610 611 newValueFromA, _ := suite.queue.GetElement(a) 612 newValueFromB, _ := suite.queue.GetElement(b) 613 614 suite.Equal(oldValueFromA, newValueFromB) 615 suite.Equal(oldValueFromB, newValueFromA) 616 } 617 618 // *************************************************************************************** 619 // ** Move elements inside an empty queue 620 // *************************************************************************************** 621 func (suite *QueueTestSuite) TestMoveToFrontEmptyQueue() { 622 const ( 623 front = 10 624 ) 625 626 suite.Equal(ErrorQueueEmpty, suite.queue.MoveToFront(front).ErrCode) 627 } 628 629 func (suite *QueueTestSuite) TestMoveToBackEmptyQueue() { 630 const ( 631 back = 1 632 ) 633 634 suite.Equal(ErrorQueueEmpty, suite.queue.MoveToBack(back).ErrCode) 635 } 636 637 // *************************************************************************************** 638 // ** Move elements to the front 639 // *************************************************************************************** 640 func (suite *QueueTestSuite) TestMoveToFront() { 641 const ( 642 size = 10 643 front = 5 644 ) 645 646 for i := 0; i < size; i++ { 647 suite.queue.Enqueue(i + 1) 648 } 649 650 result := []interface{}{5, 1, 2, 3, 4, 6, 7, 8, 9, 10} 651 652 suite.Nil(suite.queue.MoveToFront(front)) 653 suite.Equal(result, suite.queue.slice) 654 } 655 656 func (suite *QueueTestSuite) TestMoveToFrontAlreadyInFront() { 657 const ( 658 size = 10 659 front = "sim-1" 660 ) 661 662 for i := 1; i < size; i++ { 663 item := fmt.Sprintf("sim-%d", i) 664 suite.queue.Enqueue(item) 665 } 666 667 suite.Equal(ErrorQueueMoveIndexFrontPosition, suite.queue.MoveToFront(front).ErrCode) 668 } 669 670 func (suite *QueueTestSuite) TestMoveToFrontNotFound() { 671 suite.queue.Enqueue(testValue) 672 673 err := suite.queue.MoveToFront("anotherValue") 674 675 suite.Equal(ErrorIDNotFound, err.ErrCode) 676 } 677 678 // *************************************************************************************** 679 // ** Move elements to the back 680 // *************************************************************************************** 681 func (suite *QueueTestSuite) TestMoveToBack() { 682 const ( 683 size = 10 684 back = 5 685 ) 686 687 for i := 0; i < size; i++ { 688 suite.queue.Enqueue(i + 1) 689 } 690 691 result := []interface{}{1, 2, 3, 4, 6, 7, 8, 9, 10, 5} 692 693 suite.Nil(suite.queue.MoveToBack(back)) 694 suite.Equal(result, suite.queue.slice) 695 } 696 697 func (suite *QueueTestSuite) TestMoveToBackAlreadyInBack() { 698 const ( 699 size = 10 700 back = "sim-9" 701 ) 702 703 for i := 1; i < size; i++ { 704 item := fmt.Sprintf("sim-%d", i) 705 suite.queue.Enqueue(item) 706 } 707 708 suite.Equal(ErrorQueueMoveIndexBackPosition, suite.queue.MoveToBack(back).ErrCode) 709 } 710 711 func (suite *QueueTestSuite) TestMoveToBackNotFound() { 712 suite.queue.Enqueue(testValue) 713 714 err := suite.queue.MoveToBack("anotherValue") 715 716 suite.Equal(ErrorIDNotFound, err.ErrCode) 717 } 718 719 // *************************************************************************************** 720 // ** Get all elements 721 // *************************************************************************************** 722 func (suite *QueueTestSuite) TestGetAll() { 723 const ( 724 size = 10 725 ) 726 var slice []interface{} 727 728 for i := 0; i < size; i++ { 729 suite.queue.Enqueue(i) 730 slice = append(slice, i) 731 } 732 733 result, err := suite.queue.GetElements() 734 suite.Nil(err) 735 suite.Equal(slice, result) 736 } 737 738 func (suite *QueueTestSuite) TestGetAllFiltered() { 739 const ( 740 size = 10 741 ) 742 var ( 743 offset = 4 744 limit = 2 745 ) 746 var slice []interface{} 747 for i := 1; i < size; i++ { 748 suite.queue.Enqueue(i) 749 slice = append(slice, i) 750 } 751 752 expected := []interface{}{5, 6} 753 754 result, err := suite.queue.GetFilteredElements(offset, limit) 755 suite.Nil(err) 756 suite.Equal(slice, suite.queue.slice) 757 suite.Equal(expected, result) 758 } 759 760 func (suite *QueueTestSuite) TestGetAllFilteredOutOfBounds() { 761 const ( 762 size = 10 763 ) 764 var ( 765 limit = 2 766 offset = 10 767 ) 768 var slice []interface{} 769 for i := 0; i < size; i++ { 770 suite.queue.Enqueue(i) 771 slice = append(slice, i) 772 } 773 774 _, err := suite.queue.GetFilteredElements(offset, limit) 775 suite.Equal(ErrorQueueIndexOutOfBounds, err.ErrCode) 776 suite.Equal(slice, suite.queue.slice) 777 } 778 779 func (suite *QueueTestSuite) TestGetAllFilteredWrongRange() { 780 const ( 781 size = 10 782 ) 783 var ( 784 limit = -5 785 offset = -3 786 ) 787 var slice []interface{} 788 for i := 0; i < size; i++ { 789 suite.queue.Enqueue(i) 790 slice = append(slice, i) 791 } 792 793 _, err := suite.queue.GetFilteredElements(offset, limit) 794 suite.Equal(err.ErrCode, ErrorQueueIndexOutOfBounds) 795 suite.Equal(slice, suite.queue.slice) 796 } 797 798 func (suite *QueueTestSuite) TestGetAllFilteredLimitOutOfBounds() { 799 const ( 800 size = 10 801 ) 802 var ( 803 limit = 50 804 offset = 5 805 ) 806 807 for i := 1; i < size; i++ { 808 suite.queue.Enqueue(i) 809 } 810 811 expected := []interface{}{6, 7, 8, 9} 812 813 result, err := suite.queue.GetFilteredElements(offset, limit) 814 suite.Nil(err) 815 suite.Equal(expected, result) 816 } 817 818 // *************************************************************************************** 819 // ** Find by criteria 820 // *************************************************************************************** 821 func (suite *QueueTestSuite) TestQueueFindNotFound() { 822 const ( 823 size = 10 824 ) 825 826 for i := 1; i < size; i++ { 827 item := fmt.Sprintf("sim-%d", i) 828 suite.queue.Enqueue(item) 829 } 830 831 results := suite.queue.Find(func(element interface{}) bool { 832 return element == "sim-11" 833 }) 834 835 suite.Empty(results) 836 } 837 838 func (suite *QueueTestSuite) TestQueueFind() { 839 const ( 840 size = 10 841 ) 842 843 for i := 1; i < size; i++ { 844 item := fmt.Sprintf("sim-%d", i) 845 suite.queue.Enqueue(item) 846 } 847 848 expected := []int{7, 8} 849 results := suite.queue.Find(func(element interface{}) bool { 850 return element == "sim-8" || element == "sim-9" 851 }) 852 853 suite.NotEmpty(results) 854 suite.Equal(expected, results) 855 } 856 857 // *************************************************************************************** 858 // ** Find one by target 859 // *************************************************************************************** 860 func (suite *QueueTestSuite) TestQueueFindOneNotFound() { 861 const ( 862 size = 10 863 ) 864 865 for i := 1; i < size; i++ { 866 item := fmt.Sprintf("sim-%d", i) 867 suite.queue.Enqueue(item) 868 } 869 870 result := suite.queue.FindOne("sim-11") 871 suite.Equal(-1, result) 872 } 873 874 func (suite *QueueTestSuite) TestQueueFindOne() { 875 const ( 876 size = 10 877 ) 878 879 for i := 1; i < size; i++ { 880 item := fmt.Sprintf("sim-%d", i) 881 suite.queue.Enqueue(item) 882 } 883 884 result := suite.queue.FindOne("sim-9") 885 suite.Equal(8, result) 886 } 887 888 // *************************************************************************************** 889 // ** Find by IDS 890 // *************************************************************************************** 891 func (suite *QueueTestSuite) TestQueueFindByIDsNotFound() { 892 const ( 893 size = 10 894 ) 895 896 for i := 1; i < size; i++ { 897 item := fmt.Sprintf("sim-%d", i) 898 suite.queue.Enqueue(item) 899 } 900 901 ids := []int{10, 11} 902 results := suite.queue.FindByIDs(ids) 903 904 suite.Empty(results) 905 } 906 907 func (suite *QueueTestSuite) TestQueueFindByIDs() { 908 const ( 909 size = 10 910 ) 911 912 for i := 1; i < size; i++ { 913 item := fmt.Sprintf("sim-%d", i) 914 suite.queue.Enqueue(item) 915 } 916 917 ids := []int{7, 8} 918 expected := []interface{}{"sim-8", "sim-9"} 919 920 results := suite.queue.FindByIDs(ids) 921 922 suite.NotEmpty(results) 923 suite.Equal(expected, results) 924 } 925 926 func TestQueueTestSuite(t *testing.T) { 927 suite.Run(t, new(QueueTestSuite)) 928 }