]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/test-mplexer.cc
8a7412fea6a87403a0091c8d2b885b7f8e000584
2 #define BOOST_TEST_DYN_LINK
3 #define BOOST_TEST_NO_MAIN
6 #include <boost/test/unit_test.hpp>
11 BOOST_AUTO_TEST_SUITE(mplexer
)
13 BOOST_AUTO_TEST_CASE(test_MPlexer
) {
14 auto mplexer
= std::unique_ptr
<FDMultiplexer
>(FDMultiplexer::getMultiplexerSilent());
15 BOOST_REQUIRE(mplexer
!= nullptr);
18 int ready
= mplexer
->run(&now
, 100);
19 BOOST_CHECK_EQUAL(ready
, 0);
21 std::vector
<int> readyFDs
;
22 mplexer
->getAvailableFDs(readyFDs
, 0);
23 BOOST_CHECK_EQUAL(readyFDs
.size(), 0);
25 auto timeouts
= mplexer
->getTimeouts(now
);
26 BOOST_CHECK_EQUAL(timeouts
.size(), 0);
29 int res
= pipe(pipes
);
30 BOOST_REQUIRE_EQUAL(res
, 0);
31 BOOST_REQUIRE_EQUAL(setNonBlocking(pipes
[0]), true);
32 BOOST_REQUIRE_EQUAL(setNonBlocking(pipes
[1]), true);
34 /* let's declare a TTD that expired 5s ago */
35 struct timeval ttd
= now
;
38 bool writeCBCalled
= false;
39 auto writeCB
= [](int fd
, FDMultiplexer::funcparam_t param
) {
40 auto calledPtr
= boost::any_cast
<bool*>(param
);
41 BOOST_REQUIRE(calledPtr
!= nullptr);
44 mplexer
->addWriteFD(pipes
[1],
48 /* we can't add it twice */
49 BOOST_CHECK_THROW(mplexer
->addWriteFD(pipes
[1],
53 FDMultiplexerException
);
56 mplexer
->getAvailableFDs(readyFDs
, 0);
57 BOOST_REQUIRE_EQUAL(readyFDs
.size(), 1);
58 BOOST_CHECK_EQUAL(readyFDs
.at(0), pipes
[1]);
60 ready
= mplexer
->run(&now
, 100);
61 BOOST_CHECK_EQUAL(ready
, 1);
62 BOOST_CHECK_EQUAL(writeCBCalled
, true);
64 /* no read timeouts */
65 timeouts
= mplexer
->getTimeouts(now
, false);
66 BOOST_CHECK_EQUAL(timeouts
.size(), 0);
67 /* but we should have a write one */
68 timeouts
= mplexer
->getTimeouts(now
, true);
69 BOOST_REQUIRE_EQUAL(timeouts
.size(), 1);
70 BOOST_CHECK_EQUAL(timeouts
.at(0).first
, pipes
[1]);
72 /* can't remove from the wrong type of FD */
73 BOOST_CHECK_THROW(mplexer
->removeReadFD(pipes
[1]), FDMultiplexerException
);
74 mplexer
->removeWriteFD(pipes
[1]);
75 /* can't remove a non-existing FD */
76 BOOST_CHECK_THROW(mplexer
->removeWriteFD(pipes
[0]), FDMultiplexerException
);
77 BOOST_CHECK_THROW(mplexer
->removeWriteFD(pipes
[1]), FDMultiplexerException
);
80 mplexer
->getAvailableFDs(readyFDs
, 0);
81 BOOST_REQUIRE_EQUAL(readyFDs
.size(), 0);
83 ready
= mplexer
->run(&now
, 100);
84 BOOST_CHECK_EQUAL(ready
, 0);
86 bool readCBCalled
= false;
87 auto readCB
= [](int fd
, FDMultiplexer::funcparam_t param
) {
88 auto calledPtr
= boost::any_cast
<bool*>(param
);
89 BOOST_REQUIRE(calledPtr
!= nullptr);
92 mplexer
->addReadFD(pipes
[0],
97 /* not ready for reading yet */
99 mplexer
->getAvailableFDs(readyFDs
, 0);
100 BOOST_REQUIRE_EQUAL(readyFDs
.size(), 0);
102 ready
= mplexer
->run(&now
, 100);
103 BOOST_CHECK_EQUAL(ready
, 0);
104 BOOST_CHECK_EQUAL(readCBCalled
, false);
106 /* let's make the pipe readable */
107 BOOST_REQUIRE_EQUAL(write(pipes
[1], "0", 1), 1);
110 mplexer
->getAvailableFDs(readyFDs
, 0);
111 BOOST_REQUIRE_EQUAL(readyFDs
.size(), 1);
112 BOOST_CHECK_EQUAL(readyFDs
.at(0), pipes
[0]);
114 ready
= mplexer
->run(&now
, 100);
115 BOOST_CHECK_EQUAL(ready
, 1);
116 BOOST_CHECK_EQUAL(readCBCalled
, true);
118 /* add back the write FD */
119 mplexer
->addWriteFD(pipes
[1],
124 /* both should be available */
126 mplexer
->getAvailableFDs(readyFDs
, 0);
127 BOOST_REQUIRE_EQUAL(readyFDs
.size(), 2);
129 readCBCalled
= false;
130 writeCBCalled
= false;
131 ready
= mplexer
->run(&now
, 100);
132 BOOST_CHECK_EQUAL(ready
, 2);
133 BOOST_CHECK_EQUAL(readCBCalled
, true);
134 BOOST_CHECK_EQUAL(writeCBCalled
, true);
136 /* both the read and write FD should be reported */
137 timeouts
= mplexer
->getTimeouts(now
, false);
138 BOOST_REQUIRE_EQUAL(timeouts
.size(), 1);
139 BOOST_CHECK_EQUAL(timeouts
.at(0).first
, pipes
[0]);
140 timeouts
= mplexer
->getTimeouts(now
, true);
141 BOOST_REQUIRE_EQUAL(timeouts
.size(), 1);
142 BOOST_CHECK_EQUAL(timeouts
.at(0).first
, pipes
[1]);
144 struct timeval past
= ttd
;
145 /* so five seconds before the actual TTD */
148 /* no read timeouts */
149 timeouts
= mplexer
->getTimeouts(past
, false);
150 BOOST_CHECK_EQUAL(timeouts
.size(), 0);
151 /* and we should not have a write one either */
152 timeouts
= mplexer
->getTimeouts(past
, true);
153 BOOST_CHECK_EQUAL(timeouts
.size(), 0);
155 /* update the timeouts to now, they should not be reported anymore */
156 mplexer
->setReadTTD(pipes
[0], now
, 0);
157 mplexer
->setWriteTTD(pipes
[1], now
, 0);
158 timeouts
= mplexer
->getTimeouts(now
, false);
159 BOOST_REQUIRE_EQUAL(timeouts
.size(), 0);
160 timeouts
= mplexer
->getTimeouts(now
, true);
161 BOOST_REQUIRE_EQUAL(timeouts
.size(), 0);
163 /* put it back into the past */
164 mplexer
->setReadTTD(pipes
[0], now
, -5);
165 mplexer
->setWriteTTD(pipes
[1], now
, -5);
166 timeouts
= mplexer
->getTimeouts(now
, false);
167 BOOST_REQUIRE_EQUAL(timeouts
.size(), 1);
168 BOOST_CHECK_EQUAL(timeouts
.at(0).first
, pipes
[0]);
169 timeouts
= mplexer
->getTimeouts(now
, true);
170 BOOST_REQUIRE_EQUAL(timeouts
.size(), 1);
171 BOOST_CHECK_EQUAL(timeouts
.at(0).first
, pipes
[1]);
173 mplexer
->removeReadFD(pipes
[0]);
174 mplexer
->removeWriteFD(pipes
[1]);
182 BOOST_AUTO_TEST_SUITE_END()