diff --git a/src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs b/src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs index 32fec2755d..fec9826e6d 100644 --- a/src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs +++ b/src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs @@ -23,6 +23,8 @@ internal partial class CollectLinuxCommandHandler private LineRewriter rewriter; private long statusUpdateTimestamp; private Version minRuntimeSupportingUserEventsIPCCommand = new(10, 0, 0); + private readonly bool cancelOnEnter; + private readonly bool printStatusOverTime; internal sealed record CollectLinuxArgs( CancellationToken Ct, @@ -41,6 +43,8 @@ public CollectLinuxCommandHandler(IConsole console = null) { Console = console ?? new DefaultConsole(); rewriter = new LineRewriter(Console); + cancelOnEnter = !Console.IsInputRedirected; + printStatusOverTime = !Console.IsOutputRedirected; } internal static bool IsSupported() @@ -491,12 +495,12 @@ private int OutputHandler(uint type, IntPtr data, UIntPtr dataLen) } } - if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Enter) + if (cancelOnEnter && Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Enter) { stopTracing = true; } - if (ot == OutputType.Progress) + if (printStatusOverTime && ot == OutputType.Progress) { long currentTimestamp = Stopwatch.GetTimestamp(); if (statusUpdateTimestamp != 0 && currentTimestamp < statusUpdateTimestamp) diff --git a/src/tests/Common/MockConsole.cs b/src/tests/Common/MockConsole.cs index 7046b473b9..a8f2307d1e 100644 --- a/src/tests/Common/MockConsole.cs +++ b/src/tests/Common/MockConsole.cs @@ -47,9 +47,9 @@ public MockConsole(int width, int height, ITestOutputHelper outputHelper = null) public bool IsOutputRedirected { get; set; } - public bool IsInputRedirected { get; private set; } + public bool IsInputRedirected { get; set; } - public bool KeyAvailable { get; private set; } + public bool KeyAvailable { get; set; } public TextWriter Out => this; @@ -186,9 +186,11 @@ public void FlushTestLogging() public string GetLineText(int row) => new string(_chars[row]).TrimEnd(); - public ConsoleKeyInfo ReadKey() => Console.ReadKey(); + public ConsoleKeyInfo NextKeyInfo { get; set; } = new ConsoleKeyInfo('\0', ConsoleKey.Enter, false, false, false); - public ConsoleKeyInfo ReadKey(bool intercept) => Console.ReadKey(intercept); + public ConsoleKeyInfo ReadKey() => NextKeyInfo; + + public ConsoleKeyInfo ReadKey(bool intercept) => NextKeyInfo; public string[] Lines { diff --git a/src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs b/src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs index 8d0a6639aa..80741796b4 100644 --- a/src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs +++ b/src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs @@ -23,7 +23,7 @@ public class CollectLinuxCommandFunctionalTests { public static bool IsCollectLinuxSupported => CollectLinuxCommandHandler.IsSupported(); public static bool IsCollectLinuxNotSupported => !CollectLinuxCommandHandler.IsSupported(); - + private readonly ITestOutputHelper _outputHelper; public CollectLinuxCommandFunctionalTests(ITestOutputHelper outputHelper) @@ -269,6 +269,57 @@ public void CollectLinuxCommand_DoesNotChangeCursorVisibility_WhenOutputIsRedire Assert.Equal(initialCursorVisible, console.CursorVisible); } + [ConditionalFact(nameof(IsCollectLinuxSupported))] + public void CollectLinuxCommand_DoesNotPrintStatusUpdates_WhenOutputIsRedirected() + { + MockConsole console = new(200, 30, _outputHelper); + console.IsOutputRedirected = true; + + var handler = new CollectLinuxCommandHandler(console); + handler.RecordTraceInvoker = (cmd, len, cb) => { + // Send progress output type. + cb((uint)3, IntPtr.Zero, UIntPtr.Zero); + return 0; + }; + + int exitCode = handler.CollectLinux(TestArgs()); + Assert.Equal((int)ReturnCode.Ok, exitCode); + + string[] lines = console.Lines; + Assert.DoesNotContain(lines, l => l.Contains("Recording trace", StringComparison.OrdinalIgnoreCase)); + Assert.DoesNotContain(lines, l => l.Contains("Press ", StringComparison.OrdinalIgnoreCase)); + } + + [ConditionalFact(nameof(IsCollectLinuxSupported))] + public void CollectLinuxCommand_DoesNotReadKey_WhenInputIsRedirected() + { + MockConsole console = new(200, 30, _outputHelper); + console.IsInputRedirected = true; + console.KeyAvailable = true; + console.NextKeyInfo = new ConsoleKeyInfo('\r', ConsoleKey.Enter, false, false, false); + + var handler = new CollectLinuxCommandHandler(console); + bool callbackInvoked = false; + handler.RecordTraceInvoker = (cmd, len, cb) => { + // Send progress output type. + int result = cb((uint)3, IntPtr.Zero, UIntPtr.Zero); + + // It should return 0, i.e., continue tracing, even though + // enter was pressed. + Assert.Equal(0, result); + + callbackInvoked = true; + + return 0; + }; + + int exitCode = handler.CollectLinux(TestArgs()); + Assert.Equal((int)ReturnCode.Ok, exitCode); + + // The important assertion is in the callback so make sure it was called. + Assert.True(callbackInvoked); + } + private static int Run(object args, MockConsole console) { var handler = new CollectLinuxCommandHandler(console);