]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/test-channel.cc
pkcs11signers: Use emplace_back for attributes
[thirdparty/pdns.git] / pdns / test-channel.cc
1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
3
4 #include <boost/test/unit_test.hpp>
5
6 #include "channel.hh"
7
8 struct MyObject
9 {
10 uint64_t a{0};
11 };
12
13 BOOST_AUTO_TEST_SUITE(test_channel)
14
15 BOOST_AUTO_TEST_CASE(test_object_queue)
16 {
17 auto [sender, receiver] = pdns::channel::createObjectQueue<MyObject>();
18
19 BOOST_CHECK(receiver.getDescriptor() != -1);
20 BOOST_CHECK_EQUAL(receiver.isClosed(), false);
21
22 auto got = receiver.receive();
23 BOOST_CHECK(!got);
24
25 auto obj = std::make_unique<MyObject>();
26 obj->a = 42U;
27 BOOST_CHECK_EQUAL(sender.send(std::move(obj)), true);
28 BOOST_CHECK(!obj);
29 got = receiver.receive();
30 BOOST_CHECK(got != std::nullopt && *got);
31 BOOST_CHECK_EQUAL((*got)->a, 42U);
32 }
33
34 BOOST_AUTO_TEST_CASE(test_object_queue_full)
35 {
36 auto [sender, receiver] = pdns::channel::createObjectQueue<MyObject>();
37
38 {
39 auto got = receiver.receive();
40 BOOST_CHECK(!got);
41 }
42
43 /* add objects to the queue until it becomes full */
44 bool blocked = false;
45 size_t queued = 0;
46 while (!blocked) {
47 auto obj = std::make_unique<MyObject>();
48 obj->a = 42U;
49 blocked = !sender.send(std::move(obj));
50 if (blocked) {
51 BOOST_CHECK(obj);
52 }
53 else {
54 BOOST_CHECK(!obj);
55 ++queued;
56 }
57 }
58
59 BOOST_CHECK_GT(queued, 1U);
60
61 /* clear the queue */
62 blocked = false;
63 size_t received = 0;
64 while (!blocked) {
65 auto got = receiver.receive();
66 if (got) {
67 ++received;
68 }
69 else {
70 blocked = true;
71 }
72 }
73
74 BOOST_CHECK_EQUAL(queued, received);
75
76 /* we should be able to write again */
77 auto obj = std::make_unique<MyObject>();
78 obj->a = 42U;
79 BOOST_CHECK(sender.send(std::move(obj)));
80 }
81
82 BOOST_AUTO_TEST_CASE(test_object_queue_throw_on_eof)
83 {
84 auto [sender, receiver] = pdns::channel::createObjectQueue<MyObject>();
85 sender.close();
86 BOOST_CHECK_THROW(receiver.receive(), std::runtime_error);
87 BOOST_CHECK_EQUAL(receiver.isClosed(), true);
88 }
89
90 BOOST_AUTO_TEST_CASE(test_object_queue_do_not_throw_on_eof)
91 {
92 auto [sender, receiver] = pdns::channel::createObjectQueue<MyObject>(true, true, 0U, false);
93 sender.close();
94 auto got = receiver.receive();
95 BOOST_CHECK(got == std::nullopt);
96 BOOST_CHECK_EQUAL(receiver.isClosed(), true);
97 }
98
99 BOOST_AUTO_TEST_CASE(test_notification_queue_full)
100 {
101 auto [notifier, waiter] = pdns::channel::createNotificationQueue();
102
103 BOOST_CHECK(waiter.getDescriptor() != -1);
104 BOOST_CHECK_EQUAL(waiter.isClosed(), false);
105 waiter.clear();
106
107 /* add notifications until the queue becomes full */
108 bool blocked = false;
109 while (!blocked) {
110 blocked = notifier.notify();
111 }
112
113 /* clear the queue */
114 waiter.clear();
115
116 /* we should be able to write again */
117 BOOST_CHECK(notifier.notify());
118 }
119
120 BOOST_AUTO_TEST_CASE(test_notification_queue_throw_on_eof)
121 {
122 auto [notifier, waiter] = pdns::channel::createNotificationQueue();
123
124 BOOST_CHECK(waiter.getDescriptor() != -1);
125 BOOST_CHECK_EQUAL(waiter.isClosed(), false);
126
127 BOOST_CHECK_EQUAL(notifier.notify(), true);
128 waiter.clear();
129
130 notifier = pdns::channel::Notifier();
131 BOOST_CHECK_THROW(waiter.clear(), std::runtime_error);
132 }
133
134 BOOST_AUTO_TEST_CASE(test_notification_queue_do_not_throw_on_eof)
135 {
136 auto [notifier, waiter] = pdns::channel::createNotificationQueue(true, 0, false);
137
138 BOOST_CHECK(waiter.getDescriptor() != -1);
139 BOOST_CHECK_EQUAL(waiter.isClosed(), false);
140
141 BOOST_CHECK_EQUAL(notifier.notify(), true);
142 waiter.clear();
143
144 notifier = pdns::channel::Notifier();
145 waiter.clear();
146 BOOST_CHECK_EQUAL(waiter.isClosed(), true);
147 }
148
149 BOOST_AUTO_TEST_SUITE_END()