]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdistdist/test-dnsdistasync.cc
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #ifndef BOOST_TEST_DYN_LINK
23 #define BOOST_TEST_DYN_LINK
26 #define BOOST_TEST_NO_MAIN
28 #include <boost/test/unit_test.hpp>
30 #include "dnsdist-async.hh"
32 BOOST_AUTO_TEST_SUITE(test_dnsdistasync
)
34 class DummyQuerySender
: public TCPQuerySender
37 bool active() const override
42 void handleResponse([[maybe_unused
]] const struct timeval
& now
, [[maybe_unused
]] TCPResponse
&& response
) override
46 void handleXFRResponse([[maybe_unused
]] const struct timeval
& now
, [[maybe_unused
]] TCPResponse
&& response
) override
50 void notifyIOError([[maybe_unused
]] const struct timeval
& now
, [[maybe_unused
]] TCPResponse
&& response
) override
55 std::atomic
<bool> errorRaised
{false};
58 struct DummyCrossProtocolQuery
: public CrossProtocolQuery
60 DummyCrossProtocolQuery() :
63 d_sender
= std::make_shared
<DummyQuerySender
>();
66 std::shared_ptr
<TCPQuerySender
> getTCPQuerySender() override
71 std::shared_ptr
<DummyQuerySender
> d_sender
;
74 BOOST_AUTO_TEST_CASE(test_Basic
)
76 auto holder
= std::make_unique
<dnsdist::AsynchronousHolder
>();
77 BOOST_CHECK(holder
->empty());
80 auto query
= holder
->get(0, 0);
81 BOOST_CHECK(query
== nullptr);
86 uint16_t queryID
= 42;
88 gettimeofday(&ttd
, nullptr);
90 const timeval add
{0, 100000};
93 holder
->push(asyncID
, queryID
, ttd
, std::make_unique
<DummyCrossProtocolQuery
>());
94 BOOST_CHECK(!holder
->empty());
96 auto query
= holder
->get(0, 0);
97 BOOST_CHECK(query
== nullptr);
99 query
= holder
->get(asyncID
, queryID
);
100 BOOST_CHECK(holder
->empty());
102 query
= holder
->get(asyncID
, queryID
);
103 BOOST_CHECK(query
== nullptr);
105 // sleep for 200 ms, to be sure the main thread has
113 BOOST_AUTO_TEST_CASE(test_TimeoutFailClose
)
115 auto holder
= std::make_unique
<dnsdist::AsynchronousHolder
>(false);
116 uint16_t asyncID
= 1;
117 uint16_t queryID
= 42;
122 std::shared_ptr
<DummyQuerySender
> sender
{nullptr};
125 const timeval add
{0, 10000};
126 auto query
= std::make_unique
<DummyCrossProtocolQuery
>();
127 sender
= query
->d_sender
;
128 BOOST_REQUIRE(sender
!= nullptr);
129 gettimeofday(&ttd
, nullptr);
131 holder
->push(asyncID
, queryID
, ttd
, std::move(query
));
132 BOOST_CHECK(!holder
->empty());
135 // the event should be triggered after 10 ms, but we have seen
136 // many spurious failures on our CI, likely because the box is
137 // overloaded, so sleep for up to 100 ms to be sure
138 for (size_t counter
= 0; !holder
->empty() && counter
< 10; counter
++) {
142 BOOST_CHECK(holder
->empty());
143 BOOST_CHECK(sender
->errorRaised
.load());
148 BOOST_AUTO_TEST_CASE(test_AddingExpiredEvent
)
150 auto holder
= std::make_unique
<dnsdist::AsynchronousHolder
>(false);
151 uint16_t asyncID
= 1;
152 uint16_t queryID
= 42;
154 gettimeofday(&ttd
, nullptr);
155 // timeout was 10 ms ago, for some reason (long processing time, CPU starvation...)
156 const timeval sub
{0, 10000};
159 std::shared_ptr
<DummyQuerySender
> sender
{nullptr};
161 auto query
= std::make_unique
<DummyCrossProtocolQuery
>();
162 sender
= query
->d_sender
;
163 BOOST_REQUIRE(sender
!= nullptr);
164 holder
->push(asyncID
, queryID
, ttd
, std::move(query
));
167 // the expired event should be triggered almost immediately,
168 // but we have seen many spurious failures on our CI,
169 // likely because the box is overloaded, so sleep for up to
171 for (size_t counter
= 0; !holder
->empty() && counter
< 10; counter
++) {
175 BOOST_CHECK(holder
->empty());
176 BOOST_CHECK(sender
->errorRaised
.load());
181 BOOST_AUTO_TEST_SUITE_END();