tests/test_offline_integration.cpp, "Integration: offline queue replayed and backend switched on network recovery", decides two outcomes of NetworkMonitor's probe thread by fixed sleeps rather than by waiting for them.
- Line 104–105:
sleep_for(80ms), then REQUIRE_FALSE(monitor.isOnline()), with probeInterval = 30ms and failureThreshold = 1. The assertion holds only if the probe thread was scheduled and ran its first probe within 80 ms.
- Line 111–117:
sleep_for(150ms), then REQUIRE(replayed.size() == 3) and REQUIRE(queue.drain().empty()). These hold only if the recovery probe, onOnline, SyncWorker::run() and switchBackend all finished within 150 ms.
On a loaded runner (ctest -j), neither bound is guaranteed.
Observed: Linux / all optional features (clang) on PR #806, head e984ebe1, failed at line 105 with REQUIRE_FALSE( monitor.isOnline() ) expanded to !true:
https://github.com/LASTRADA-Software/morph/actions/runs/36127304451/job/108046632860
The same leg passed on the previous head, and the gcc leg passed on this one. #806 does not touch include/morph/offline or this test, and NetworkMonitor runs its own std::thread/condition_variable.
Fix: the pattern #446 and #396 applied elsewhere. Wait for the state with morph::testing::waitUntil instead of sleeping for a fixed time:
REQUIRE(morph::testing::waitUntil([&] { return !monitor.isOnline(); }));
- after
networkOnline.store(true), REQUIRE(morph::testing::waitUntil([&] { std::scoped_lock lock{replayMtx}; return replayed.size() == 3; })), then the drain and execute checks as now.
The test then fails only when the monitor really does not go offline or recover, not when its thread is late.
tests/test_offline_integration.cpp, "Integration: offline queue replayed and backend switched on network recovery", decides two outcomes ofNetworkMonitor's probe thread by fixed sleeps rather than by waiting for them.sleep_for(80ms), thenREQUIRE_FALSE(monitor.isOnline()), withprobeInterval = 30msandfailureThreshold = 1. The assertion holds only if the probe thread was scheduled and ran its first probe within 80 ms.sleep_for(150ms), thenREQUIRE(replayed.size() == 3)andREQUIRE(queue.drain().empty()). These hold only if the recovery probe,onOnline,SyncWorker::run()andswitchBackendall finished within 150 ms.On a loaded runner (
ctest -j), neither bound is guaranteed.Observed: Linux / all optional features (clang) on PR #806, head
e984ebe1, failed at line 105 withREQUIRE_FALSE( monitor.isOnline() )expanded to!true:https://github.com/LASTRADA-Software/morph/actions/runs/36127304451/job/108046632860
The same leg passed on the previous head, and the gcc leg passed on this one. #806 does not touch
include/morph/offlineor this test, andNetworkMonitorruns its ownstd::thread/condition_variable.Fix: the pattern #446 and #396 applied elsewhere. Wait for the state with
morph::testing::waitUntilinstead of sleeping for a fixed time:REQUIRE(morph::testing::waitUntil([&] { return !monitor.isOnline(); }));networkOnline.store(true),REQUIRE(morph::testing::waitUntil([&] { std::scoped_lock lock{replayMtx}; return replayed.size() == 3; })), then the drain and execute checks as now.The test then fails only when the monitor really does not go offline or recover, not when its thread is late.