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