diff --git a/tests/integration/test_compose_orchestrator.cpp b/tests/integration/test_compose_orchestrator.cpp index 2a484a1..b2f47eb 100644 --- a/tests/integration/test_compose_orchestrator.cpp +++ b/tests/integration/test_compose_orchestrator.cpp @@ -254,10 +254,18 @@ TEST_CASE("compose lifecycle: test-compose/compose.yaml up, verify, down", "[int up_args.compose_file_name = compose_path.string(); AppConfig up_config = reload_config(); int up_result = 1; + std::string up_output; { CapturedStdout capture; up_result = dispatch_command(up_args, "/nonexistent/unused-config.yaml", up_config); + up_output = capture.contents(); } + // Only surfaced if something below actually fails -- compose_up_command()'s + // own fmt::print()/spdlog output (spdlog's default sink is stdout, same + // as slocker-lite's own plain status lines) would otherwise be silently + // discarded by CapturedStdout, leaving no way to diagnose *why* a step + // failed on a run this test itself can't rerun interactively. + INFO("up output:\n" << up_output); CHECK(up_result == 0); auto containers = list_compose_containers(); @@ -298,8 +306,16 @@ TEST_CASE("compose lifecycle: test-compose/compose.yaml up, verify, down", "[int reply = tcp_request(*host_ip, 18080, 2000); return reply.has_value() && !reply->empty(); })); - REQUIRE(reply.has_value()); - CHECK(reply->find("Hello from test-worker") != std::string::npos); + CHECK(reply.has_value()); + // CHECK, not REQUIRE: a flaky port-forward reply on this specific + // run must never skip the -d/--down cleanup below -- an extern + // network's uplink relay left running would otherwise leak real + // host state (and, if this were run interactively rather than with + // output redirected to a file, hang the invoking shell -- see + // reference_device_ssh_access.md). + if (reply) { + CHECK(reply->find("Hello from test-worker") != std::string::npos); + } } ParsedArgs down_args; @@ -307,10 +323,13 @@ TEST_CASE("compose lifecycle: test-compose/compose.yaml up, verify, down", "[int down_args.compose_file_name = compose_path.string(); AppConfig down_config = reload_config(); int down_result = 1; + std::string down_output; { CapturedStdout capture; down_result = dispatch_command(down_args, "/nonexistent/unused-config.yaml", down_config); + down_output = capture.contents(); } + INFO("down output:\n" << down_output); CHECK(down_result == 0); AppConfig after_down = reload_config();