Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#if NETFRAMEWORK
Expand Down Expand Up @@ -112,15 +112,62 @@ private static void ConfigureOutputRouting(TestOutputCaptureMode mode)
Func<TestOutputCaptureMode> modeProvider = static () => MSTestSettings.CurrentSettings.OutputCaptureMode;
TextWriter originalOut = Console.Out;
TextWriter originalError = Console.Error;
TestContextImplementation.ConfigureLiveOutputWriter(originalOut);
TextWriter liveOutputWriter = CreateLiveOutputWriter(Console.OpenStandardOutput(), Console.OutputEncoding);
TestContextImplementation.ConfigureLiveOutputWriter(liveOutputWriter);
Console.SetOut(new ConsoleOutRouter(originalOut, modeProvider));
Console.SetError(new ConsoleErrorRouter(originalError, modeProvider));
Trace.Listeners.Add(new TextWriterTraceListener(new TraceTextWriter(originalOut, modeProvider)));
Trace.Listeners.Add(new TextWriterTraceListener(new TraceTextWriter(liveOutputWriter, modeProvider)));
Comment thread
Evangelink marked this conversation as resolved.

s_outputRoutingInstalled = true;
}
}

internal static TextWriter CreateLiveOutputWriter(Stream standardOutput, Encoding encoding)
{
Encoding preamblelessEncoding = encoding.GetPreamble().Length == 0
? encoding
: new PreamblelessEncoding(encoding);
var streamWriter = new StreamWriter(standardOutput, preamblelessEncoding, bufferSize: 1024, leaveOpen: true)
{
AutoFlush = true,
};

return TextWriter.Synchronized(streamWriter);
}

private sealed class PreamblelessEncoding(Encoding encoding) : Encoding
{
public override int CodePage => encoding.CodePage;

public override string EncodingName => encoding.EncodingName;

public override bool IsSingleByte => encoding.IsSingleByte;

public override string WebName => encoding.WebName;

public override Decoder GetDecoder() => encoding.GetDecoder();

public override Encoder GetEncoder() => encoding.GetEncoder();

public override int GetByteCount(char[] chars, int index, int count)
=> encoding.GetByteCount(chars, index, count);

public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
=> encoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex);

public override int GetCharCount(byte[] bytes, int index, int count)
=> encoding.GetCharCount(bytes, index, count);

public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
=> encoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex);

public override int GetMaxByteCount(int charCount) => encoding.GetMaxByteCount(charCount);

public override int GetMaxCharCount(int byteCount) => encoding.GetMaxCharCount(byteCount);

public override byte[] GetPreamble() => [];
}

#pragma warning disable CA1822 // Mark members as static
public void Cancel()
=> PlatformServiceProvider.Instance.TestRunCancellationToken?.Cancel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextIm
static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.ParameterMetadataScanCount.get -> int
static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.ResetParameterMetadataCacheForTesting() -> void
static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.SetParameterMetadataScanCallbackForTesting(System.Action? callback) -> void
static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner.CreateLiveOutputWriter(System.IO.Stream! standardOutput, System.Text.Encoding! encoding) -> System.IO.TextWriter!
static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers.RuntimeContext.IsMultiThreaded.get -> bool
static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestDiscovererHelpers.GetSettingsExceptionMessage(Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.AdapterSettingsException! ex) -> string!
static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.ConfigureLiveOutputWriter(System.IO.TextWriter! liveOutputWriter) -> void
static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetLiveOutputWriterForTesting(System.IO.TextWriter! liveOutputWriter) -> System.IDisposable!
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,24 @@ internal void Deactivate()
=> Volatile.Write(ref _isActive, 0);
}

private sealed class LiveOutputWriterScope(TextWriter? previousLiveOutputWriter) : IDisposable
{
public void Dispose()
=> Volatile.Write(ref s_liveOutputWriter, previousLiveOutputWriter);
}

// This writer is captured together with the process-wide Console routers and shares their install-once lifetime.
internal static void ConfigureLiveOutputWriter(TextWriter liveOutputWriter)
=> Volatile.Write(ref s_liveOutputWriter, liveOutputWriter);

internal static IDisposable SetLiveOutputWriterForTesting(TextWriter liveOutputWriter)
{
TextWriter? previousLiveOutputWriter = Volatile.Read(ref s_liveOutputWriter);
Volatile.Write(ref s_liveOutputWriter, liveOutputWriter);

return new LiveOutputWriterScope(previousLiveOutputWriter);
}

private void WriteLive(string? message, bool appendLine)
{
if (_liveOutputWriter is null
Expand Down
Loading
Loading