From 77e30a7632ff2350abc8ac6f9dc895164fe60831 Mon Sep 17 00:00:00 2001 From: E M <5089238+emizzle@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:55:58 +1000 Subject: [PATCH] Log tests status to stdout so it can be read into the workflow summary --- Tests/DistTestCore/DistTest.cs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Tests/DistTestCore/DistTest.cs b/Tests/DistTestCore/DistTest.cs index 8cba6af9..d33e0c7f 100644 --- a/Tests/DistTestCore/DistTest.cs +++ b/Tests/DistTestCore/DistTest.cs @@ -74,6 +74,36 @@ namespace DistTestCore fixtureLog.Error("Cleanup failed: " + ex); GlobalTestFailure.HasFailed = true; } + + // NUnit captures Console.Out for the entire test lifecycle (setup, test, + // teardown), so writes during the long WaitForCleanup period never reach + // pod stdout in real-time. Writing directly to the raw stdout stream + // bypasses that capture and flushes immediately. + // + // GKE's logging agent parses JSON lines as jsonPayload, so fields like + // jsonPayload.type and jsonPayload.fixture become queryable in Cloud Logging. + // The workflow "Generate test summary" step queries these entries to build + // the per-test summary without needing to parse NUnit runner output. + try + { + var result = GetTestResult(); + var entry = new Dictionary + { + ["type"] = "test-result", + ["runid"] = Environment.GetEnvironmentVariable("RUNID") ?? "", + ["fixture"] = NameUtils.GetRawFixtureName(), + ["testname"] = NameUtils.GetTestMethodName(), + ["status"] = result.Status, + ["success"] = result.Success, + ["duration"] = lifecycle.GetTestDuration().ToString(@"hh\:mm\:ss"), + }; + using var raw = new StreamWriter(Console.OpenStandardOutput(), leaveOpen: true) { AutoFlush = true }; + raw.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(entry)); + } + catch + { + // Best-effort; don't fail the teardown if status emission fails. + } } public CoreInterface Ci