test_mpmc_q.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "includes.h"
  2. using std::chrono::milliseconds;
  3. using test_clock = std::chrono::high_resolution_clock;
  4. static milliseconds millis_from(const test_clock::time_point &tp0) {
  5. return std::chrono::duration_cast<milliseconds>(test_clock::now() - tp0);
  6. }
  7. TEST_CASE("dequeue-empty-nowait", "[mpmc_blocking_q]") {
  8. size_t q_size = 100;
  9. milliseconds tolerance_wait(20);
  10. spdlog::details::mpmc_blocking_queue<int> q(q_size);
  11. int popped_item = 0;
  12. auto start = test_clock::now();
  13. auto rv = q.dequeue_for(popped_item, milliseconds::zero());
  14. auto delta_ms = millis_from(start);
  15. REQUIRE(rv == false);
  16. INFO("Delta " << delta_ms.count() << " millis");
  17. REQUIRE(delta_ms <= tolerance_wait);
  18. }
  19. TEST_CASE("dequeue-empty-wait", "[mpmc_blocking_q]") {
  20. size_t q_size = 100;
  21. milliseconds wait_ms(250);
  22. milliseconds tolerance_wait(250);
  23. spdlog::details::mpmc_blocking_queue<int> q(q_size);
  24. int popped_item = 0;
  25. auto start = test_clock::now();
  26. auto rv = q.dequeue_for(popped_item, wait_ms);
  27. auto delta_ms = millis_from(start);
  28. REQUIRE(rv == false);
  29. INFO("Delta " << delta_ms.count() << " millis");
  30. REQUIRE(delta_ms >= wait_ms - tolerance_wait);
  31. REQUIRE(delta_ms <= wait_ms + tolerance_wait);
  32. }
  33. TEST_CASE("dequeue-full-nowait", "[mpmc_blocking_q]") {
  34. spdlog::details::mpmc_blocking_queue<int> q(1);
  35. q.enqueue(42);
  36. int item = 0;
  37. q.dequeue_for(item, milliseconds::zero());
  38. REQUIRE(item == 42);
  39. }
  40. TEST_CASE("dequeue-full-wait", "[mpmc_blocking_q]") {
  41. spdlog::details::mpmc_blocking_queue<int> q(1);
  42. q.enqueue(42);
  43. int item = 0;
  44. q.dequeue(item);
  45. REQUIRE(item == 42);
  46. }
  47. TEST_CASE("enqueue_nowait", "[mpmc_blocking_q]") {
  48. size_t q_size = 1;
  49. spdlog::details::mpmc_blocking_queue<int> q(q_size);
  50. milliseconds tolerance_wait(10);
  51. q.enqueue(1);
  52. REQUIRE(q.overrun_counter() == 0);
  53. auto start = test_clock::now();
  54. q.enqueue_nowait(2);
  55. auto delta_ms = millis_from(start);
  56. INFO("Delta " << delta_ms.count() << " millis");
  57. REQUIRE(delta_ms <= tolerance_wait);
  58. REQUIRE(q.overrun_counter() == 1);
  59. }
  60. TEST_CASE("bad_queue", "[mpmc_blocking_q]") {
  61. size_t q_size = 0;
  62. spdlog::details::mpmc_blocking_queue<int> q(q_size);
  63. q.enqueue_nowait(1);
  64. REQUIRE(q.overrun_counter() == 1);
  65. int i = 0;
  66. REQUIRE(q.dequeue_for(i, milliseconds(0)) == false);
  67. }
  68. TEST_CASE("empty_queue", "[mpmc_blocking_q]") {
  69. size_t q_size = 10;
  70. spdlog::details::mpmc_blocking_queue<int> q(q_size);
  71. int i = 0;
  72. REQUIRE(q.dequeue_for(i, milliseconds(10)) == false);
  73. }
  74. TEST_CASE("full_queue", "[mpmc_blocking_q]") {
  75. size_t q_size = 100;
  76. spdlog::details::mpmc_blocking_queue<int> q(q_size);
  77. for (int i = 0; i < static_cast<int>(q_size); i++) {
  78. q.enqueue(i + 0); // i+0 to force rvalue and avoid tidy warnings on the same time if we
  79. // std::move(i) instead
  80. }
  81. q.enqueue_nowait(123456);
  82. REQUIRE(q.overrun_counter() == 1);
  83. for (int i = 1; i < static_cast<int>(q_size); i++) {
  84. int item = -1;
  85. q.dequeue(item);
  86. REQUIRE(item == i);
  87. }
  88. // last item pushed has overridden the oldest.
  89. int item = -1;
  90. q.dequeue(item);
  91. REQUIRE(item == 123456);
  92. }