[fix] Fix test output eaten by MSBuild terminal logger - #16223
Conversation
…ut=false When TestCaptureOutput=false (set in Directory.Build.props to show test output live) and the MSBuild terminal logger is active, the terminal logger buffers all MSBuild subprocess output and shows 'See log file: <path>' messages at the end. Since TestCaptureOutput=false means no log files are created, these paths point to files that don't exist, leaving developers with no test output. Fix: disable the MSBuild terminal logger in test.sh and test.cmd by default via the MSBUILDTERMINALLOGGER environment variable. Developers who prefer the terminal logger UI can override this by setting MSBUILDTERMINALLOGGER=auto before invoking the test scripts. Fixes #15509 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses missing/“eaten” test output when running via the repo’s test.sh/test.cmd in environments where TestCaptureOutput=false and the .NET SDK’s MSBuild terminal logger buffers sub-task output. The fix disables the terminal logger by default in the test entry scripts, while still allowing developers to override the setting.
Changes:
- Default
MSBUILDTERMINALLOGGERtooffintest.shto prevent terminal-logger buffering of test output. - Default
MSBUILDTERMINALLOGGERtooffintest.cmdwhen the variable isn’t already defined (allowing opt-in overrides).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test.sh | Exports MSBUILDTERMINALLOGGER (default off) before invoking the shared build/test entrypoint. |
| test.cmd | Sets MSBUILDTERMINALLOGGER=off (only if unset) before running eng\Build.ps1 -test. |
Jakub Jareš (nohwnd)
left a comment
There was a problem hiding this comment.
🧠 Reviewed by Expert Code Reviewer
Scope
This PR touches only test.cmd and test.sh — thin wrapper scripts that bootstrap scriptroot/DOTNET_ROOT and delegate to the real build engine. No production C# code is modified.
Dimensions activated (per routing table):
- Build Script & Infrastructure Hygiene — environment variable handling, exit-code propagation, pre-delegate ordering
- Source Build & Cross-Platform Compliance — bash portability, child-process propagation
Findings
No actionable issues found.
What was checked and passed:
| Check | Result |
|---|---|
if not defined VAR set VAR=off is the correct idiomatic CMD default-value pattern |
✅ |
export VAR=${VAR:-off} is correct POSIX/bash syntax, sets before delegating |
✅ |
| Env var is set before the delegated script is invoked (child process inherits it) | ✅ |
exit /b %ErrorLevel% still present in test.cmd — exit-code propagation unaffected |
✅ |
| User-override preserved on both platforms (already-set value is not overwritten) | ✅ |
CI pipelines that pre-set MSBUILDTERMINALLOGGER before calling ./test.sh are unaffected |
✅ |
Minor observation (no change needed):
The two scripts have slightly different empty-string semantics:
test.sh:${MSBUILDTERMINALLOGGER:-off}treats an empty value (="") as unset → override toofftest.cmd:if not definedtreats an empty value as defined → keeps the empty string
If a developer sets MSBUILDTERMINALLOGGER= (empty) to clear the variable, the behavior differs per platform. In practice this is irrelevant — the documented override path is MSBUILDTERMINALLOGGER=auto, not empty-string. No action needed.
PR Description Alignment
The title and description accurately describe the change. The root-cause explanation (TestCaptureOutput=false + terminal logger buffering → missing log-file paths), the fix, and the CI-impact claim all match the diff exactly. ✅
🧠 Reviewed by Expert Code Reviewer 🧠
Summary
Fixes #15509
Root Cause
When
TestCaptureOutput=falseis set inDirectory.Build.props(to allow live test output in the console) and the MSBuild terminal logger is active (default in .NET 8+ SDK), the terminal logger buffers all output from MSBuild sub-tasks — including test output. When tests complete, the terminal logger shows "See log file: (path)" messages. SinceTestCaptureOutput=falsemeans no log files are created, those paths point to files that don't exist, leaving developers with no visible test output.Fix
Disable the MSBuild terminal logger in
test.shandtest.cmdby settingMSBUILDTERMINALLOGGER=offbefore invoking the build scripts. This lets test output flow directly to the console as intended.Developers who prefer the terminal logger UI can override the default by setting
MSBUILDTERMINALLOGGER=autobefore invoking the test scripts.Testing
This is a developer-tooling change affecting only the
test.shandtest.cmdscripts. No production code is modified. The change is:test.sh: ExportsMSBUILDTERMINALLOGGER=${MSBUILDTERMINALLOGGER:-off}so the default is off but can be overridden.test.cmd: SetsMSBUILDTERMINALLOGGER=offif not already defined.CI runs (
azure-pipelines.ymlcalls./test.sh) will also have the terminal logger disabled, which is harmless — CI output is captured by the Azure DevOps agent regardless.