Skip to content

Commit 0845bbe

Browse files
committed
Test Timeout
1 parent 67175e0 commit 0845bbe

2 files changed

Lines changed: 152 additions & 0 deletions

File tree

test/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ set(base_test_SOURCES
6262
base-convert.cpp
6363
base-dictionary.cpp
6464
base-fifo.cpp
65+
base-io-engine.cpp
6566
base-json.cpp
6667
base-match.cpp
6768
base-netstring.cpp
@@ -128,6 +129,11 @@ add_boost_test(base
128129
base_dictionary/keys_ordered
129130
base_fifo/construct
130131
base_fifo/io
132+
base_io_engine/timeout_run
133+
base_io_engine/timeout_cancelled
134+
base_io_engine/timeout_scope
135+
base_io_engine/timeout_due_cancelled
136+
base_io_engine/timeout_due_scope
131137
base_json/encode
132138
base_json/decode
133139
base_json/invalid1

test/base-io-engine.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/* Icinga 2 | (c) 2024 Icinga GmbH | GPLv2+ */
2+
3+
#include "base/io-engine.hpp"
4+
#include "base/utility.hpp"
5+
#include <boost/asio.hpp>
6+
#include <boost/date_time/posix_time/posix_time.hpp>
7+
#include <BoostTestTargetConfig.h>
8+
9+
using namespace icinga;
10+
11+
BOOST_AUTO_TEST_SUITE(base_io_engine)
12+
13+
BOOST_AUTO_TEST_CASE(timeout_run)
14+
{
15+
boost::asio::io_context io;
16+
boost::asio::io_context::strand strand (io);
17+
int called = 0;
18+
19+
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
20+
boost::asio::deadline_timer timer (io);
21+
22+
Timeout::Ptr timeout = new Timeout(io, strand, boost::posix_time::seconds(3), [&called] { ++called; });
23+
BOOST_CHECK_EQUAL(called, 0);
24+
25+
timer.expires_from_now(boost::posix_time::seconds(2));
26+
timer.async_wait(yc);
27+
BOOST_CHECK_EQUAL(called, 0);
28+
29+
timer.expires_from_now(boost::posix_time::seconds(2));
30+
timer.async_wait(yc);
31+
});
32+
33+
io.run();
34+
BOOST_CHECK_EQUAL(called, 1);
35+
}
36+
37+
BOOST_AUTO_TEST_CASE(timeout_cancelled)
38+
{
39+
boost::asio::io_context io;
40+
boost::asio::io_context::strand strand (io);
41+
int called = 0;
42+
43+
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
44+
boost::asio::deadline_timer timer (io);
45+
Timeout::Ptr timeout = new Timeout(io, strand, boost::posix_time::seconds(3), [&called] { ++called; });
46+
47+
timer.expires_from_now(boost::posix_time::seconds(2));
48+
timer.async_wait(yc);
49+
50+
timeout->Cancel();
51+
BOOST_CHECK_EQUAL(called, 0);
52+
53+
timer.expires_from_now(boost::posix_time::seconds(2));
54+
timer.async_wait(yc);
55+
});
56+
57+
io.run();
58+
BOOST_CHECK_EQUAL(called, 0);
59+
}
60+
61+
BOOST_AUTO_TEST_CASE(timeout_scope)
62+
{
63+
boost::asio::io_context io;
64+
boost::asio::io_context::strand strand (io);
65+
int called = 0;
66+
67+
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
68+
boost::asio::deadline_timer timer (io);
69+
70+
{
71+
Timeout::Ptr timeout = new Timeout(io, strand, boost::posix_time::seconds(3), [&called] { ++called; });
72+
73+
timer.expires_from_now(boost::posix_time::seconds(2));
74+
timer.async_wait(yc);
75+
}
76+
77+
BOOST_CHECK_EQUAL(called, 0);
78+
79+
timer.expires_from_now(boost::posix_time::seconds(2));
80+
timer.async_wait(yc);
81+
});
82+
83+
io.run();
84+
BOOST_CHECK_EQUAL(called, 0);
85+
}
86+
87+
BOOST_AUTO_TEST_CASE(timeout_due_cancelled)
88+
{
89+
boost::asio::io_context io;
90+
boost::asio::io_context::strand strand (io);
91+
int called = 0;
92+
93+
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
94+
boost::asio::deadline_timer timer (io);
95+
Timeout::Ptr timeout = new Timeout(io, strand, boost::posix_time::seconds(3), [&called] { ++called; });
96+
97+
// Give the timeout enough time to become due while blocking its strand to prevent it from actually running...
98+
Utility::Sleep(4);
99+
100+
BOOST_CHECK_EQUAL(called, 0);
101+
102+
// ... so that this shall still work:
103+
timeout->Cancel();
104+
105+
BOOST_CHECK_EQUAL(called, 0);
106+
107+
timer.expires_from_now(boost::posix_time::seconds(1));
108+
timer.async_wait(yc);
109+
});
110+
111+
io.run();
112+
BOOST_CHECK_EQUAL(called, 0);
113+
}
114+
115+
BOOST_AUTO_TEST_CASE(timeout_due_scope)
116+
{
117+
boost::asio::io_context io;
118+
boost::asio::io_context::strand strand (io);
119+
int called = 0;
120+
121+
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
122+
boost::asio::deadline_timer timer (io);
123+
124+
{
125+
Timeout::Ptr timeout = new Timeout(io, strand, boost::posix_time::seconds(3), [&called] { ++called; });
126+
127+
// Give the timeout enough time to become due while blocking its strand to prevent it from actually running...
128+
Utility::Sleep(4);
129+
130+
BOOST_CHECK_EQUAL(called, 0);
131+
132+
// ... so that this shall still work:
133+
timeout.reset();
134+
}
135+
136+
BOOST_CHECK_EQUAL(called, 0);
137+
138+
timer.expires_from_now(boost::posix_time::seconds(1));
139+
timer.async_wait(yc);
140+
});
141+
142+
io.run();
143+
BOOST_CHECK_EQUAL(called, 0);
144+
}
145+
146+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)