Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 28, 2026

Improve Console Output Visibility in CollectCommand Tests

This PR addresses issue #5698 by making console output visible when tests fail.

Changes completed:

  • Modified MockConsole to accept optional ITestOutputHelper parameter
  • Updated MockConsole.Write methods to multiplex output to ITestOutputHelper when provided
  • Injected ITestOutputHelper into CollectCommandFunctionalTests
  • Injected ITestOutputHelper into CollectLinuxCommandFunctionalTests
  • Injected ITestOutputHelper into ConsoleExporterTests
  • Updated all test methods to pass ITestOutputHelper to MockConsole
  • Optimized implementation to avoid unnecessary string allocations
  • Made exception handling more specific with exception message check
  • Added FlushTestLogging method to ensure buffered output is written
  • Simplified comments per code review feedback
  • Fixed case-sensitive exception filter to use OrdinalIgnoreCase comparison
  • Refactored test logging logic into BufferTestLogging helper method
  • Renamed FlushOutput to FlushTestLogging for clarity
  • Verified backward compatibility with existing tests
  • All tests pass successfully

Key features:

  • Intelligent buffering: Accumulates text until complete lines are ready to avoid fragmenting output
  • Performance optimized: Only processes buffer when incoming text contains newlines
  • Robust exception handling: Uses case-insensitive comparison to catch InvalidOperationException properly
  • Backward compatible: Optional parameter means existing tests don't need changes
  • FlushTestLogging method: Ensures any remaining buffered output is written before assertions
  • Clean separation: Test logging logic extracted into dedicated helper methods

Result:

Console output including error messages and exceptions is now visible in test output under "Standard Output Messages:", making it much easier to diagnose issues when tests fail.

Original prompt

Can you extend the CollectCommandFunctionalTests and CollectLinuxCommandFunctionalTests to increase visibility on the console output observed whenever there are failures. Currently they're swalled by MockConsole, and so we don't know what exception occurred. See #5698 for an example. There is also a suggestion to inject ITestOutputHelper,


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 5 commits January 28, 2026 02:58
… CollectCommand tests

Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
… handling

Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
…ilures

Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Copilot AI changed the title [WIP] Enhance console visibility for CollectCommand tests Add ITestOutputHelper to MockConsole for visible console output in test failures Jan 28, 2026
Copilot AI requested a review from mdh1418 January 28, 2026 03:08
Copy link
Member

@mdh1418 mdh1418 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot can we also update the ConsoleExporterTests to use the ITestOutputHelper as well

…leExporterTests

Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 28, 2026

@copilot can we also update the ConsoleExporterTests to use the ITestOutputHelper as well

Done in cf2edc3. ConsoleExporterTests now uses ITestOutputHelper with all 16 MockConsole instantiations updated.

Copilot AI requested a review from mdh1418 January 28, 2026 19:23
@mdh1418 mdh1418 marked this pull request as ready for review January 28, 2026 23:21
@mdh1418 mdh1418 requested a review from a team as a code owner January 28, 2026 23:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves diagnosability of failing tests by making MockConsole optionally mirror console output to xUnit’s ITestOutputHelper, and updates several test suites to pass the output helper into MockConsole.

Changes:

  • Added optional ITestOutputHelper plumbing to MockConsole, including line-buffering and an explicit FlushOutput() method.
  • Updated CollectCommandFunctionalTests, CollectLinuxCommandFunctionalTests, and ConsoleExporterTests to inject ITestOutputHelper and pass it to MockConsole.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/tests/Common/MockConsole.cs Adds optional xUnit output multiplexing, buffering, and flush integration in assert helpers.
src/tests/dotnet-trace/CollectCommandFunctionalTests.cs Injects ITestOutputHelper and routes console output through MockConsole.
src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs Injects ITestOutputHelper and routes console output through MockConsole across test cases.
src/tests/dotnet-counters/ConsoleExporterTests.cs Injects ITestOutputHelper and passes it to MockConsole for better failure output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 108 to 113
catch (InvalidOperationException ex) when (ex.Message.Contains("no currently active test"))
{
// ITestOutputHelper.WriteLine throws InvalidOperationException with message
// "There is no currently active test" when called after the test has completed.
// This is expected and can be safely ignored.
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception filter is case-sensitive: ex.Message.Contains("no currently active test") will NOT match the message quoted in the comment ("There is no currently active test...") due to casing. This means InvalidOperationException can still escape when writes happen after the test completes. Use a case-insensitive check (e.g., IndexOf(..., StringComparison.OrdinalIgnoreCase) >= 0) or compare against the exact expected message consistently.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 61ff689. Changed to use StringComparison.OrdinalIgnoreCase for case-insensitive matching.

_outputHelper.WriteLine(_outputBuffer.ToString());
_outputBuffer.Clear();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("no currently active test"))
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same case-sensitive exception filter issue here: ex.Message.Contains("no currently active test") won’t match "There is no currently active test" due to casing, so FlushOutput() can throw after test completion. Make the match case-insensitive or use the exact message string consistently.

Suggested change
catch (InvalidOperationException ex) when (ex.Message.Contains("no currently active test"))
catch (InvalidOperationException ex) when (ex.Message.Contains("no currently active test", StringComparison.OrdinalIgnoreCase))

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 61ff689. Changed to use StringComparison.OrdinalIgnoreCase for case-insensitive matching.

@mdh1418
Copy link
Member

mdh1418 commented Jan 28, 2026

@copilot apply changes based on the comments in this thread

@mdh1418
Copy link
Member

mdh1418 commented Jan 28, 2026

Example outputs when there are failures.

./dotnet.sh test src/tests/dotnet-trace/DotnetTrace.UnitTests.csproj

    /home/mihw/repo/diagnostics/src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs(97): error TESTERROR: 
      Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandFunctionalTests.CollectLinuxCommand_ReportsResolveProcessNameErrors (11ms): Error Message: Assert.Equal() Failure: Values differ
      Expected: 3
      Actual:   2
      Stack Trace:
         at Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandFunctionalTests.CollectLinuxCommand_ReportsResolveProcessNameErrors() in /home/mihw/repo/diagnostics/src/tests/dotnet-trace/CollectLinuxCommandFunctionalTes
      ts.cs:line 97
         at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
         at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
        Standard Output Messages:
       ==========================================================================================
       The collect-linux verb is a new preview feature and relies on an updated version of the
       .nettrace file format. The latest PerfView release supports these trace files but other
       ways of using the trace file may not work yet. For more details, see the docs at
       https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace.
       ==========================================================================================
       [ERROR] System.Exception: MIHW
          at Microsoft.Diagnostics.NETCore.Client.DiagnosticsClient.<GetPublishedProcesses>g__GetAllPublishedProcesses|33_0(String[] files)+MoveNext() in /home/mihw/repo/diagnostics/src/Microsoft.Diagnostics.NETCore.Clien
      t/DiagnosticsClient/DiagnosticsClient.cs:line 441
          at System.Linq.Enumerable.DistinctIterator`1.MoveNext()
          at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
          at Microsoft.Internal.Common.Utils.CommandUtils.FindProcessIdWithName(String name) in /home/mihw/repo/diagnostics/src/Tools/Common/CommandUtils.cs:line 20
          at Microsoft.Internal.Common.Utils.CommandUtils.ResolveProcess(Int32 processId, String name, Int32& resolvedProcessId, String& resolvedProcessName) in /home/mihw/repo/diagnostics/src/Tools/Common/CommandUtils.cs
      :line 107
          at Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandHandler.ProcessSupportsUserEventsIpcCommand(Int32 pid, String processName, Int32& resolvedPid, String& resolvedName, String& detectedRuntimeVersion) in /ho
      me/mihw/repo/diagnostics/src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs:line 304
          at Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandHandler.CollectLinux(CollectLinuxArgs args) in /home/mihw/repo/diagnostics/src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs:line 95

./test.sh

      <test name="Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandFunctionalTests.CollectLinuxCommand_Probe_CsvToConsole" type="Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandFunctionalTests" method="CollectLinuxCommand_Probe_CsvToConsole" time="0.0561657" result="Fail">
        <output><![CDATA[==========================================================================================
The collect-linux verb is a new preview feature and relies on an updated version of the
.nettrace file format. The latest PerfView release supports these trace files but other
ways of using the trace file may not work yet. For more details, see the docs at
https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace.
==========================================================================================
System.Exception: MIHW
   at Microsoft.Diagnostics.NETCore.Client.DiagnosticsClient.<GetPublishedProcesses>g__GetAllPublishedProcesses|33_0(String[] files)+MoveNext() in /home/mihw/repo/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClient.cs:line 441
   at System.Linq.Enumerable.DistinctIterator`1.MoveNext()
   at Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandHandler.SupportsCollectLinux(CollectLinuxArgs args) in /home/mihw/repo/diagnostics/src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs:line 229
]]></output>
        <failure exception-type="Xunit.Sdk.EqualException">
          <message><![CDATA[Assert.Equal() Failure: Values differ\nExpected: 0\nActual:   5]]></message>
          <stack-trace><![CDATA[   at Microsoft.Diagnostics.Tools.Trace.CollectLinuxCommandFunctionalTests.CollectLinuxCommand_Probe_CsvToConsole() in /home/mihw/repo/diagnostics/src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs:line 140
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)]]></stack-trace>
        </failure>
      </test>

Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 28, 2026

@copilot apply changes based on the comments in this thread

Applied the suggested changes in 61ff689. Both exception filters now use case-insensitive comparison with StringComparison.OrdinalIgnoreCase.

}
public override void Write(string text)
{
if (_outputHelper != null && !string.IsNullOrEmpty(text))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot - please factor this new code out into a helper function such as BufferTestLogging

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in a518e4c. Extracted the test logging buffer logic into a BufferTestLogging helper method.

/// Flushes any remaining buffered output to the ITestOutputHelper.
/// Call this at the end of a test to ensure all output is written.
/// </summary>
public void FlushOutput()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot - please rename this so its clear it refers to the test logging. For example FlushTestLogging

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in a518e4c. Renamed to FlushTestLogging to clarify it refers to test logging output.

…FlushTestLogging

Co-authored-by: noahfalk <6243776+noahfalk@users.noreply.github.com>
Copilot AI requested a review from noahfalk January 29, 2026 01:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants