| 96 | std::optional<pmon::test::LogChannelManager> logManager_; |
| 97 | |
| 98 | void RunCase_(CrashKind_ kind, const char* scenarioToken) |
| 99 | { |
| 100 | ResetLogFolder_(); |
| 101 | if (!logManager_) { |
| 102 | logManager_.emplace(); |
| 103 | } |
| 104 | pmon::test::SetupTestLogging(logFolder_, "debug", {}); |
| 105 | |
| 106 | CrashClientProcess_ client{ ioctx_, jobMan_, BuildArgs_(kind) }; |
| 107 | const auto clientPid = client.GetId(); |
| 108 | const auto logPath = fs::path{ logFolder_ } / std::format("sample-client-{}.txt", clientPid); |
| 109 | |
| 110 | if (!client.WaitForExit(5s)) { |
| 111 | client.Murder(); |
| 112 | Assert::Fail(L"SampleClient did not exit after crash scenario"); |
| 113 | } |
| 114 | |
| 115 | Logger::WriteMessage(std::format("Crash test log path: {}\n", logPath.string()).c_str()); |
| 116 | const auto logReady = WaitForLogContains_(logPath, "CRASH_TEST:BEGIN", 3s); |
| 117 | Assert::IsTrue(logReady, L"Expected crash prelude entry not found in log output"); |
| 118 | |
| 119 | const auto scenarioNeedle = std::format("CRASH_TEST:SCENARIO={}", scenarioToken); |
| 120 | const auto scenarioReady = WaitForLogContains_(logPath, scenarioNeedle, 3s); |
| 121 | Assert::IsTrue(scenarioReady, L"Expected crash scenario breadcrumb not found in log output"); |
| 122 | |
| 123 | const auto exitCode = client.GetExitCode(); |
| 124 | Assert::IsTrue(exitCode != 0, L"Crash mode should terminate abnormally"); |
| 125 | } |
| 126 | |
| 127 | public: |
| 128 | TEST_METHOD_CLEANUP(Cleanup) |
no test coverage detected