[pkg-nagios-changes] [Git][nagios-team/icinga2][master] 2 commits: Update PR 10780 patch with additional changes.

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Wed Apr 29 13:32:46 BST 2026



Bas Couwenberg pushed to branch master at Debian Nagios Maintainer Group / icinga2


Commits:
0479dade by Bas Couwenberg at 2026-04-29T14:19:56+02:00
Update PR 10780 patch with additional changes.

- - - - -
2dc522d7 by Bas Couwenberg at 2026-04-29T14:19:56+02:00
Set distribution to experimental.

- - - - -


4 changed files:

- debian/changelog
- − debian/patches/perfdata-tests.patch
- + debian/patches/pr10780-parallel-tests.patch
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,13 +1,13 @@
-icinga2 (2.16.0-3~exp4) UNRELEASED; urgency=medium
+icinga2 (2.16.0-3~exp4) experimental; urgency=medium
 
   [ Bas Couwenberg ]
   * Re-enable parallel test execution, doesn't solve test failures.
-  * Disable flaky perfdata tests again.
+  * Update PR 10780 patch with additional changes.
 
   [ Luca Boccassi ]
   * Install and use sysusers.d config file.
 
- -- Bas Couwenberg <sebastic at debian.org>  Thu, 23 Apr 2026 21:08:14 +0200
+ -- Bas Couwenberg <sebastic at debian.org>  Wed, 29 Apr 2026 14:05:24 +0200
 
 icinga2 (2.16.0-3~exp3) experimental; urgency=medium
 


=====================================
debian/patches/perfdata-tests.patch deleted
=====================================
@@ -1,178 +0,0 @@
-Description: Disable flaky perfdata tests.
-Author: Bas Couwenberg <sebastic at debian.org>
-Bug: https://github.com/Icinga/icinga2/issues/10811
-
---- a/test/perfdata-elasticsearchwriter.cpp
-+++ b/test/perfdata-elasticsearchwriter.cpp
-@@ -14,7 +14,7 @@ BOOST_FIXTURE_TEST_SUITE(perfdata_elasti
- 	*boost::unit_test::label("network")
- )
- 
--BOOST_AUTO_TEST_CASE(connect)
-+BOOST_AUTO_TEST_CASE(connect, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
-@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(connect)
- 	PauseWriter();
- }
- 
--BOOST_AUTO_TEST_CASE(pause_with_pending_work)
-+BOOST_AUTO_TEST_CASE(pause_with_pending_work, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
---- a/test/perfdata-gelfwriter.cpp
-+++ b/test/perfdata-gelfwriter.cpp
-@@ -14,7 +14,7 @@ BOOST_FIXTURE_TEST_SUITE(perfdata_gelfwr
- 	*boost::unit_test::label("network")
- )
- 
--BOOST_AUTO_TEST_CASE(connect)
-+BOOST_AUTO_TEST_CASE(connect, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
-@@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE(connect)
- 	PauseWriter();
- }
- 
--BOOST_AUTO_TEST_CASE(pause_with_pending_work)
-+BOOST_AUTO_TEST_CASE(pause_with_pending_work, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
---- a/test/perfdata-graphitewriter.cpp
-+++ b/test/perfdata-graphitewriter.cpp
-@@ -15,7 +15,7 @@ BOOST_FIXTURE_TEST_SUITE(perfdata_graphi
- 	*boost::unit_test::label("network")
- )
- 
--BOOST_AUTO_TEST_CASE(connect)
-+BOOST_AUTO_TEST_CASE(connect, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
-@@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(connect)
- 	PauseWriter();
- }
- 
--BOOST_AUTO_TEST_CASE(pause_with_pending_work)
-+BOOST_AUTO_TEST_CASE(pause_with_pending_work, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
---- a/test/perfdata-influxdbwriter.cpp
-+++ b/test/perfdata-influxdbwriter.cpp
-@@ -13,7 +13,7 @@ BOOST_FIXTURE_TEST_SUITE(perfdata_influx
- 	*boost::unit_test::label("network")
- )
- 
--BOOST_AUTO_TEST_CASE(connect)
-+BOOST_AUTO_TEST_CASE(connect, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
-@@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(connect)
- 	PauseWriter();
- }
- 
--BOOST_AUTO_TEST_CASE(pause_with_pending_work)
-+BOOST_AUTO_TEST_CASE(pause_with_pending_work, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
---- a/test/perfdata-opentsdbwriter.cpp
-+++ b/test/perfdata-opentsdbwriter.cpp
-@@ -15,7 +15,7 @@ BOOST_FIXTURE_TEST_SUITE(perfdata_opents
- 	*boost::unit_test::label("network")
- )
- 
--BOOST_AUTO_TEST_CASE(connect)
-+BOOST_AUTO_TEST_CASE(connect, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
-@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE(connect)
- 	PauseWriter();
- }
- 
--BOOST_AUTO_TEST_CASE(pause_with_pending_work)
-+BOOST_AUTO_TEST_CASE(pause_with_pending_work, * boost::unit_test::disabled())
- {
- 	ResumeWriter();
- 
---- a/test/perfdata-perfdatawriterconnection.cpp
-+++ b/test/perfdata-perfdatawriterconnection.cpp
-@@ -51,7 +51,7 @@ BOOST_FIXTURE_TEST_SUITE(perfdata_connec
- 
- /* If there is no acceptor listening on the other side, connecting should fail.
-  */
--BOOST_AUTO_TEST_CASE(connection_refused)
-+BOOST_AUTO_TEST_CASE(connection_refused, * boost::unit_test::disabled())
- {
- 	std::promise<void> p;
- 	TestThread timeoutThread{[&]() {
-@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(connection_refused)
- /* The PerfdataWriterConnection connects automatically when sending the first data.
-  * In case of http we also need to support disconnecting and reconnecting.
-  */
--BOOST_AUTO_TEST_CASE(ensure_connected)
-+BOOST_AUTO_TEST_CASE(ensure_connected, * boost::unit_test::disabled())
- {
- 	std::promise<void> disconnectedPromise;
- 
-@@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(ensure_connected)
- /* Verify that data can still be sent while CancelAfterTimeout is waiting and the timeout
-  * can be aborted when all data has been sent successfully.
-  */
--BOOST_AUTO_TEST_CASE(finish_during_timeout)
-+BOOST_AUTO_TEST_CASE(finish_during_timeout, * boost::unit_test::disabled())
- {
- 	std::promise<void> p;
- 
-@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(finish_during_timeo
-  * in the kernel. But in that case the TLS handshake will be stuck, so we need to verify that a
-  * handshake can be interrupted by CancelAfterTimeout().
-  */
--BOOST_AUTO_TEST_CASE(stuck_in_handshake)
-+BOOST_AUTO_TEST_CASE(stuck_in_handshake, * boost::unit_test::disabled())
- {
- 	std::promise<void> p;
- 	TestThread timeoutThread{[&]() {
-@@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(stuck_in_handshake)
-  * No orderly TLS shutdown can be performed in this case, because the stream has been truncated.
-  * The server will need to handle this one on their own.
-  */
--BOOST_AUTO_TEST_CASE(stuck_sending)
-+BOOST_AUTO_TEST_CASE(stuck_sending, * boost::unit_test::disabled())
- {
- 	std::promise<void> shutdownPromise;
- 	std::promise<void> dataReadPromise;
-@@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(stuck_sending)
-  * in reality a server might not even do that. That case should be handled by our
-  * AsioTlsStream::GracefulDisconnect() function with an additional 10s timeout.
-  */
--BOOST_AUTO_TEST_CASE(stuck_reading_response)
-+BOOST_AUTO_TEST_CASE(stuck_reading_response, * boost::unit_test::disabled())
- {
- 	std::promise<void> shutdownPromise;
- 	std::promise<void> requestReadPromise;
-@@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(stuck_reading_respo
-  * PerfdataWriterConnection should detect the disconnect, catch the exception and attempt to
-  * reconnect without exiting Send().
-  */
--BOOST_AUTO_TEST_CASE(reconnect_failed)
-+BOOST_AUTO_TEST_CASE(reconnect_failed, * boost::unit_test::disabled())
- {
- 	TestThread mockTargetThread{[&]() {
- 		Accept();
-@@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(reconnect_failed)
-  * since on older boost versions the async_write() functions also accept non-const references, it
-  * doesn't hurt to ensure this with a test-case.
-  */
--BOOST_AUTO_TEST_CASE(http_send_retry)
-+BOOST_AUTO_TEST_CASE(http_send_retry, * boost::unit_test::disabled())
- {
- 	TestThread mockTargetThread{[&] {
- 		Accept();


=====================================
debian/patches/pr10780-parallel-tests.patch
=====================================
@@ -0,0 +1,506 @@
+Description: Enable parallel unit-test execution
+Author: Johannes Schmidt <johannes.schmidt at icinga.com>
+Origin: https://github.com/Icinga/icinga2/pull/10780
+Bug: https://github.com/Icinga/icinga2/issues/10811
+
+--- a/.github/workflows/linux.bash
++++ b/.github/workflows/linux.bash
+@@ -38,6 +38,7 @@ case "$DISTRO" in
+     )
+ 
+     ln -vs /usr/bin/cmake3 /usr/local/bin/cmake
++    ln -vs /usr/bin/ctest3 /usr/local/bin/ctest
+     ln -vs /usr/bin/ninja-build /usr/local/bin/ninja
+     CMAKE_OPTS+=(-DBOOST_{INCLUDEDIR=/boost_1_69_0,LIBRARYDIR=/boost_1_69_0/stage/lib})
+     export LD_LIBRARY_PATH=/boost_1_69_0/stage/lib
+@@ -154,6 +155,6 @@ cd /icinga2/build
+ 
+ ninja -v
+ 
+-ninja test
++ctest -j$(nproc) --output-on-failure
+ ninja install
+ icinga2 daemon -C
+--- a/Containerfile
++++ b/Containerfile
+@@ -128,8 +128,11 @@ RUN --mount=type=bind,source=.,target=/i
+         -DICINGA2_RUNDIR=/run \
+         -DICINGA2_WITH_COMPAT=OFF \
+         -DICINGA2_WITH_LIVESTATUS=OFF && \
+-    make -j$([ "$MAKE_JOBS" = auto ] && nproc || echo "$MAKE_JOBS") && \
+-    if [ "${ICINGA2_BUILD_TESTING}" = ON ]; then CTEST_OUTPUT_ON_FAILURE=1 make test; fi && \
++    JOBS=$([ "$MAKE_JOBS" = auto ] && nproc || echo "$MAKE_JOBS") && \
++    make -j"$JOBS" && \
++    if [ "${ICINGA2_BUILD_TESTING}" = ON ]; then \
++        ctest -j"$JOBS" --output-on-failure; \
++    fi && \
+     make install DESTDIR=/icinga2-install
+ 
+ RUN rm -rf /icinga2-install/etc/icinga2/features-enabled/mainlog.conf \
+--- a/test/perfdata-elasticsearchwriter.cpp
++++ b/test/perfdata-elasticsearchwriter.cpp
+@@ -45,13 +45,13 @@ BOOST_AUTO_TEST_CASE(pause_with_pending_
+ 	ResumeWriter();
+ 
+ 	// Process check-results until the writer is stuck.
+-	BOOST_REQUIRE_MESSAGE(GetWriterStuck(10s), "Failed to get Writer stuck.");
++	BOOST_REQUIRE_MESSAGE(GetWriterStuck(20s), "Failed to get Writer stuck.");
+ 
+ 	// Now try to pause.
+ 	PauseWriter();
+ 
+ 	REQUIRE_LOG_MESSAGE("Connection stopped\\.", 10s);
+-	REQUIRE_LOG_MESSAGE("'ElasticsearchWriter' paused\\.", 10s);
++	REQUIRE_LOG_MESSAGE("'ElasticsearchWriter' paused\\.", 1s);
+ }
+ 
+ BOOST_AUTO_TEST_SUITE_END()
+--- a/test/perfdata-gelfwriter.cpp
++++ b/test/perfdata-gelfwriter.cpp
+@@ -36,12 +36,12 @@ BOOST_AUTO_TEST_CASE(pause_with_pending_
+ 	ResumeWriter();
+ 
+ 	// Process check-results until the writer is stuck.
+-	BOOST_REQUIRE_MESSAGE(GetWriterStuck(10s), "Failed to get Writer stuck.");
++	BOOST_REQUIRE_MESSAGE(GetWriterStuck(20s), "Failed to get Writer stuck.");
+ 
+ 	// Now stop reading and try to pause OpenTsdbWriter.
+ 	PauseWriter();
+ 
+-	REQUIRE_LOG_MESSAGE("Connection stopped\\.", 1s);
++	REQUIRE_LOG_MESSAGE("Connection stopped\\.", 10s);
+ 	REQUIRE_LOG_MESSAGE("'GelfWriter' paused\\.", 1s);
+ }
+ 
+--- a/test/perfdata-graphitewriter.cpp
++++ b/test/perfdata-graphitewriter.cpp
+@@ -35,13 +35,13 @@ BOOST_AUTO_TEST_CASE(pause_with_pending_
+ 	ResumeWriter();
+ 
+ 	// Process check-results until the writer is stuck.
+-	BOOST_REQUIRE_MESSAGE(GetWriterStuck(10s), "Failed to get Writer stuck.");
++	BOOST_REQUIRE_MESSAGE(GetWriterStuck(20s), "Failed to get Writer stuck.");
+ 
+ 	// Now stop reading and try to pause OpenTsdbWriter.
+ 	PauseWriter();
+ 
+ 	REQUIRE_LOG_MESSAGE("Connection stopped\\.", 10s);
+-	REQUIRE_LOG_MESSAGE("'GraphiteWriter' paused\\.", 10s);
++	REQUIRE_LOG_MESSAGE("'GraphiteWriter' paused\\.", 1s);
+ }
+ 
+ BOOST_AUTO_TEST_SUITE_END()
+--- a/test/perfdata-influxdbwriter.cpp
++++ b/test/perfdata-influxdbwriter.cpp
+@@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(pause_with_pending_
+ 	ResumeWriter();
+ 
+ 	// Process check-results until the writer is stuck.
+-	BOOST_REQUIRE_MESSAGE(GetWriterStuck(10s), "Failed to get Writer stuck.");
++	BOOST_REQUIRE_MESSAGE(GetWriterStuck(20s), "Failed to get Writer stuck.");
+ 
+ 	// Now try to pause.
+ 	PauseWriter();
+--- a/test/perfdata-opentsdbwriter.cpp
++++ b/test/perfdata-opentsdbwriter.cpp
+@@ -41,13 +41,13 @@ BOOST_AUTO_TEST_CASE(pause_with_pending_
+ 	ResumeWriter();
+ 
+ 	// Process check-results until the writer is stuck.
+-	BOOST_REQUIRE_MESSAGE(GetWriterStuck(10s), "Failed to get Writer stuck.");
++	BOOST_REQUIRE_MESSAGE(GetWriterStuck(20s), "Failed to get Writer stuck.");
+ 
+ 	// Now stop reading and try to pause OpenTsdbWriter.
+ 	PauseWriter();
+ 
+ 	REQUIRE_LOG_MESSAGE("Connection stopped\\.", 10s);
+-	REQUIRE_LOG_MESSAGE("'OpenTsdbWriter' paused\\.", 10s);
++	REQUIRE_LOG_MESSAGE("'OpenTsdbWriter' paused\\.", 1s);
+ }
+ 
+ BOOST_AUTO_TEST_SUITE_END()
+--- a/test/perfdata-perfdatawriterconnection.cpp
++++ b/test/perfdata-perfdatawriterconnection.cpp
+@@ -56,14 +56,14 @@ BOOST_AUTO_TEST_CASE(connection_refused)
+ 	std::promise<void> p;
+ 	TestThread timeoutThread{[&]() {
+ 		auto f = p.get_future();
+-		GetConnection().CancelAfterTimeout(f, 50ms);
++		GetConnection().CancelAfterTimeout(f, 250ms);
+ 	}};
+ 
+ 	BOOST_REQUIRE_THROW(
+ 		GetConnection().Send(boost::asio::const_buffer{"foobar", 7}), PerfdataWriterConnection::Stopped
+ 	);
+ 
+-	REQUIRE_JOINS_WITHIN(timeoutThread, 1s);
++	REQUIRE_JOINS_WITHIN(timeoutThread, 10s);
+ }
+ 
+ /* The PerfdataWriterConnection connects automatically when sending the first data.
+@@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(ensure_connected)
+ 	BOOST_REQUIRE_NO_THROW(GetConnection().Disconnect());
+ 	disconnectedPromise.set_value();
+ 
+-	REQUIRE_JOINS_WITHIN(mockTargetThread, 1s);
++	REQUIRE_JOINS_WITHIN(mockTargetThread, 10s);
+ }
+ 
+ /* Verify that data can still be sent while CancelAfterTimeout is waiting and the timeout
+@@ -113,15 +113,15 @@ BOOST_AUTO_TEST_CASE(finish_during_timeo
+ 
+ 	TestThread timeoutThread{[&]() {
+ 		auto f = p.get_future();
+-		GetConnection().CancelAfterTimeout(f, 50ms);
++		GetConnection().CancelAfterTimeout(f, 250ms);
+ 		BOOST_REQUIRE(f.wait_for(0ms) == std::future_status::ready);
+ 		BOOST_REQUIRE(!GetConnection().IsConnected());
+ 	}};
+ 
+ 	GetConnection().Send(boost::asio::const_buffer{"foobar", 7});
+ 
+-	REQUIRE_JOINS_WITHIN(timeoutThread, 1s);
+-	REQUIRE_JOINS_WITHIN(mockTargetThread, 1s);
++	REQUIRE_JOINS_WITHIN(timeoutThread, 10s);
++	REQUIRE_JOINS_WITHIN(mockTargetThread, 10s);
+ }
+ 
+ /* For the client, even a hanging server will accept the connection immediately, since it's done
+@@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(stuck_in_handshake)
+ 	TestThread timeoutThread{[&]() {
+ 		Accept();
+ 		auto f = p.get_future();
+-		GetConnection().CancelAfterTimeout(f, 50ms);
++		GetConnection().CancelAfterTimeout(f, 250ms);
+ 		BOOST_REQUIRE(f.wait_for(0ms) == std::future_status::timeout);
+ 	}};
+ 
+@@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(stuck_in_handshake)
+ 		GetConnection().Send(boost::asio::const_buffer{"foobar", 7}), PerfdataWriterConnection::Stopped
+ 	);
+ 
+-	REQUIRE_JOINS_WITHIN(timeoutThread, 1s);
++	REQUIRE_JOINS_WITHIN(timeoutThread, 10s);
+ }
+ 
+ /* When the disconnect timeout runs out while sending something to a slow or blocking server, we
+@@ -185,8 +185,8 @@ BOOST_AUTO_TEST_CASE(stuck_sending)
+ 	BOOST_REQUIRE_THROW(GetConnection().Send(buf), PerfdataWriterConnection::Stopped);
+ 	shutdownPromise.set_value();
+ 
+-	REQUIRE_JOINS_WITHIN(timeoutThread, 1s);
+-	REQUIRE_JOINS_WITHIN(mockTargetThread, 1s);
++	REQUIRE_JOINS_WITHIN(timeoutThread, 10s);
++	REQUIRE_JOINS_WITHIN(mockTargetThread, 10s);
+ }
+ 
+ /* This simulates a server that is stuck after receiving a HTTP request and before sending their
+@@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(stuck_reading_respo
+ 		requestReadPromise.set_value();
+ 		// Do not send a response but react to the shutdown to be polite.
+ 		shutdownPromise.get_future().get();
+-		Shutdown();
++		Shutdown(true);
+ 	}};
+ 
+ 	TestThread timeoutThread{[&]() {
+@@ -226,8 +226,8 @@ BOOST_AUTO_TEST_CASE(stuck_reading_respo
+ 	BOOST_REQUIRE_THROW(GetConnection().Send(request), PerfdataWriterConnection::Stopped);
+ 	shutdownPromise.set_value();
+ 
+-	REQUIRE_JOINS_WITHIN(timeoutThread, 1s);
+-	REQUIRE_JOINS_WITHIN(mockTargetThread, 1s);
++	REQUIRE_JOINS_WITHIN(timeoutThread, 10s);
++	REQUIRE_JOINS_WITHIN(mockTargetThread, 10s);
+ }
+ 
+ /* This test simulates a server that closes the connection and reappears at a later time.
+@@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE(reconnect_failed)
+ 	BOOST_REQUIRE_NO_THROW(GetConnection().Send(boost::asio::const_buffer{randomData.data(), randomData.size()}));
+ 	BOOST_REQUIRE_NO_THROW(GetConnection().Disconnect());
+ 
+-	REQUIRE_JOINS_WITHIN(mockTargetThread, 1s);
++	REQUIRE_JOINS_WITHIN(mockTargetThread, 10s);
+ }
+ 
+ /* This tests if retrying an http send will reproducibly lead to the exact same message being
+@@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(http_send_retry)
+ 
+ 		SendResponse();
+ 
+-		Shutdown();
++		Shutdown(true);
+ 	}};
+ 
+ 	boost::beast::http::request<boost::beast::http::string_body> request{boost::beast::http::verb::post, "foo", 10};
+@@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(http_send_retry)
+ 	BOOST_REQUIRE_NO_THROW(GetConnection().Send(request));
+ 	BOOST_REQUIRE_NO_THROW(GetConnection().Disconnect());
+ 
+-	REQUIRE_JOINS_WITHIN(mockTargetThread, 1s);
++	REQUIRE_JOINS_WITHIN(mockTargetThread, 10s);
+ }
+ 
+ BOOST_AUTO_TEST_SUITE_END()
+--- a/test/base-timer.cpp
++++ b/test/base-timer.cpp
+@@ -10,7 +10,7 @@
+  * Windows needs a special handicap to keep up with the other OSs.
+  */
+ #ifdef _WIN32
+-static constexpr double timeMultiplier = 10;
++static constexpr double timeMultiplier = 5;
+ #else //_WIN32
+ static constexpr double timeMultiplier = 1;
+ #endif //_WIN32
+@@ -38,10 +38,10 @@ BOOST_AUTO_TEST_CASE(invoke)
+ 
+ 	Timer::Ptr timer = Timer::Create();
+ 	timer->OnTimerExpired.connect([&counter](const Timer* const&) { counter++; });
+-	timer->SetInterval(.1 * timeMultiplier);
++	timer->SetInterval(.2 * timeMultiplier);
+ 
+ 	timer->Start();
+-	Utility::Sleep(.55 * timeMultiplier);
++	Utility::Sleep(1.1 * timeMultiplier);
+ 	timer->Stop();
+ 
+ 	// At this point, the timer should have fired exactly 5 times (0.5 / 0.1) and the sixth time
+@@ -55,12 +55,12 @@ BOOST_AUTO_TEST_CASE(scope)
+ 
+ 	Timer::Ptr timer = Timer::Create();
+ 	timer->OnTimerExpired.connect([&counter](const Timer* const&) { counter++; });
+-	timer->SetInterval(.1 * timeMultiplier);
++	timer->SetInterval(.2 * timeMultiplier);
+ 
+ 	timer->Start();
+-	Utility::Sleep(.55 * timeMultiplier);
++	Utility::Sleep(1.1 * timeMultiplier);
+ 	timer.reset();
+-	Utility::Sleep(.1 * timeMultiplier);
++	Utility::Sleep(.2 * timeMultiplier);
+ 
+ 	// At this point, the timer should have fired exactly 5 times (0.5 / 0.1) and the sixth time
+ 	// should not have fired yet as we destroyed the timer after 0.55 seconds (0.6 would be needed),
+--- a/lib/perfdata/perfdatawriterconnection.cpp
++++ b/lib/perfdata/perfdatawriterconnection.cpp
+@@ -62,11 +62,11 @@ bool PerfdataWriterConnection::IsStopped
+ 
+ void PerfdataWriterConnection::Disconnect()
+ {
+-	if (m_Stopped.exchange(true, std::memory_order_relaxed)) {
++	if (m_Stopped.exchange(true)) {
+ 		return;
+ 	}
+ 
+-	std::promise<void> promise;
++	SyncResult<void> ret;
+ 
+ 	IoEngine::SpawnCoroutine(m_Strand, [&](boost::asio::yield_context yc) {
+ 		try {
+@@ -76,8 +76,14 @@ void PerfdataWriterConnection::Disconnec
+ 			 * completion.
+ 			 */
+ 			std::visit(
+-				[](const auto& stream) {
++				[&](const auto& stream) {
+ 					if (stream->lowest_layer().is_open()) {
++						/* In some situations a single cancel is not enough to cancel() an
++						 * async_handshake operation. Otherwise this can fail on slow targets,
++						 * like for example emulated ARM64 machines if the timing is right.
++						 */
++						stream->lowest_layer().cancel();
++						boost::asio::post(m_Strand, yc);
+ 						stream->lowest_layer().cancel();
+ 					}
+ 				},
+@@ -86,13 +92,13 @@ void PerfdataWriterConnection::Disconnec
+ 			m_ReconnectTimer.cancel();
+ 
+ 			Disconnect(std::move(yc));
+-			promise.set_value();
++			ret.SetValue();
+ 		} catch (const std::exception& ex) {
+-			promise.set_exception(std::current_exception());
++			ret.SetException(std::current_exception());
+ 		}
+ 	});
+ 
+-	promise.get_future().get();
++	ret.Get();
+ }
+ 
+ AsioTlsOrTcpStream PerfdataWriterConnection::MakeStream() const
+@@ -133,6 +139,10 @@ void PerfdataWriterConnection::EnsureCon
+ 			::Connect(stream->lowest_layer(), m_Host, m_Port, yc);
+ 
+ 			if constexpr (std::is_same_v<std::decay_t<decltype(stream)>, Shared<AsioTlsStream>::Ptr>) {
++				if (m_Stopped) {
++					BOOST_THROW_EXCEPTION(Stopped{});
++				}
++
+ 				using type = boost::asio::ssl::stream_base::handshake_type;
+ 
+ 				stream->next_layer().async_handshake(type::client, yc);
+@@ -156,7 +166,7 @@ void PerfdataWriterConnection::EnsureCon
+ 
+ void PerfdataWriterConnection::Disconnect(boost::asio::yield_context yc)
+ {
+-	if (!m_Connected.exchange(false, std::memory_order_relaxed)) {
++	if (!m_Connected.exchange(false)) {
+ 		return;
+ 	}
+ 
+--- a/test/perfdata-perfdatatargetfixture.hpp
++++ b/test/perfdata-perfdatatargetfixture.hpp
+@@ -71,11 +71,20 @@ public:
+ 		BOOST_REQUIRE(stream->next_layer().IsVerifyOK());
+ 	}
+ 
+-	void Shutdown()
++	void Shutdown(bool wait = false)
+ 	{
+ 		BOOST_REQUIRE(std::holds_alternative<Shared<AsioTlsStream>::Ptr>(m_Stream));
+ 		auto& stream = std::get<Shared<AsioTlsStream>::Ptr>(m_Stream);
+ 		try {
++			if (wait) {
++				std::array<std::byte, 128> buf{};
++				boost::asio::mutable_buffer readBuf (buf.data(), buf.size());
++				boost::system::error_code ec;
++
++				do {
++					stream->read_some(readBuf, ec);
++				} while (!ec);
++			}
+ 			stream->next_layer().shutdown();
+ 		} catch (const std::exception& ex) {
+ 			if (const auto* se = dynamic_cast<const boost::system::system_error*>(&ex);
+--- a/test/perfdata-perfdatawriterfixture.hpp
++++ b/test/perfdata-perfdatawriterfixture.hpp
+@@ -121,6 +121,7 @@ object Host "h1" {
+ 
+ 	void ResumeWriter()
+ 	{
++		Listen();
+ 		static_cast<ConfigObject::Ptr>(m_Writer)->OnConfigLoaded();
+ 		m_Writer->SetActive(true);
+ 		m_Writer->Activate();
+--- a/lib/perfdata/perfdatawriterconnection.hpp
++++ b/lib/perfdata/perfdatawriterconnection.hpp
+@@ -10,6 +10,7 @@
+ #include <boost/beast/http/message.hpp>
+ #include <boost/beast/http/string_body.hpp>
+ #include <future>
++#include <utility>
+ 
+ namespace icinga {
+ 
+@@ -21,6 +22,62 @@ class PerfdataWriterConnection final : p
+ 	static constexpr auto InitialRetryWait = 50ms;
+ 	static constexpr auto FinalRetryWait = 32s;
+ 
++	template<typename T>
++	class SyncResult
++	{
++		using ValueType = std::variant<std::monostate, std::conditional_t<std::is_void_v<T>, bool, T>, std::exception_ptr>;
++
++	public:
++		template<typename U, typename V = T, typename = std::enable_if_t<!std::is_void_v<V>>>
++		void SetValue(U&& v)
++		{
++			{
++				std::lock_guard lock(m_Mutex);
++				m_Value = std::forward<U>(v);
++			}
++			m_Cv.notify_one();
++		}
++
++		template<typename V = T, typename = std::enable_if_t<std::is_void_v<V>>>
++		void SetValue()
++		{
++			{
++				std::lock_guard lock(m_Mutex);
++				m_Value = true;
++			}
++			m_Cv.notify_one();
++		}
++
++		void SetException(std::exception_ptr ep)
++		{
++			{
++				std::lock_guard lock(m_Mutex);
++				m_Value = ValueType{ep};
++			}
++			m_Cv.notify_one();
++		}
++
++		T Get()
++		{
++			std::unique_lock l(m_Mutex);
++			m_Cv.wait(l, [&] { return !std::holds_alternative<std::monostate>(m_Value); });
++			if (std::holds_alternative<std::exception_ptr>(m_Value)) {
++				std::rethrow_exception(std::get<std::exception_ptr>(m_Value));
++			}
++
++			if constexpr (std::is_void_v<T>) {
++				return;
++			} else {
++				return std::move(std::get<T>(m_Value));
++			}
++		}
++
++	private:
++		std::mutex m_Mutex;
++		std::condition_variable m_Cv;
++		ValueType m_Value;
++	};
++
+ public:
+ 	DECLARE_PTR_TYPEDEFS(PerfdataWriterConnection);
+ 
+@@ -66,7 +123,7 @@ public:
+ 		}
+ 
+ 		using RetType = decltype(WriteMessage(std::declval<Buffer>(), std::declval<boost::asio::yield_context>()));
+-		std::promise<RetType> promise;
++		SyncResult<RetType> ret;
+ 
+ 		IoEngine::SpawnCoroutine(m_Strand, [&](boost::asio::yield_context yc) {
+ 			while (true) {
+@@ -75,16 +132,16 @@ public:
+ 
+ 					if constexpr (std::is_void_v<RetType>) {
+ 						WriteMessage(std::forward<Buffer>(buf), yc);
+-						promise.set_value();
++						ret.SetValue();
+ 					} else {
+-						promise.set_value(WriteMessage(std::forward<Buffer>(buf), yc));
++						ret.SetValue(WriteMessage(std::forward<Buffer>(buf), yc));
+ 					}
+ 
+ 					m_RetryTimeout = InitialRetryWait;
+ 					return;
+ 				} catch (const std::exception& ex) {
+ 					if (m_Stopped) {
+-						promise.set_exception(std::make_exception_ptr(Stopped{}));
++						ret.SetException(std::make_exception_ptr(Stopped{}));
+ 						return;
+ 					}
+ 
+@@ -98,14 +155,14 @@ public:
+ 					try {
+ 						BackoffWait(yc);
+ 					} catch (const std::exception&) {
+-						promise.set_exception(std::make_exception_ptr(Stopped{}));
++						ret.SetException(std::make_exception_ptr(Stopped{}));
+ 						return;
+ 					}
+ 				}
+ 			}
+ 		});
+ 
+-		return promise.get_future().get();
++		return ret.Get();
+ 	}
+ 
+ 	void Disconnect();


=====================================
debian/patches/series
=====================================
@@ -1,3 +1,3 @@
 21_config_changes
 postgres-checkcommand.patch
-perfdata-tests.patch
+pr10780-parallel-tests.patch



View it on GitLab: https://salsa.debian.org/nagios-team/icinga2/-/compare/b865568e044e5b6a8d07e743fb53e8ff2c923d0e...2dc522d7d81e7a96cc9b26e810add15a9cbe341a

-- 
View it on GitLab: https://salsa.debian.org/nagios-team/icinga2/-/compare/b865568e044e5b6a8d07e743fb53e8ff2c923d0e...2dc522d7d81e7a96cc9b26e810add15a9cbe341a
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20260429/7b9f9625/attachment-0001.htm>


More information about the pkg-nagios-changes mailing list