Skip to content
Open
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
Expand Up @@ -82,6 +82,8 @@ internal int CollectLinux(CollectLinuxArgs args)

int ret = (int)ReturnCode.TracingError;
string scriptPath = null;
bool cursorVisibilityChanged = false;
bool originalCursorVisible = false;
try
{
if (args.Probe)
Expand All @@ -101,7 +103,15 @@ internal int CollectLinux(CollectLinuxArgs args)
}

args.Ct.Register(() => stopTracing = true);
Console.CursorVisible = false;

// Only hide cursor if output is not redirected
if (!Console.IsOutputRedirected)
{
originalCursorVisible = Console.CursorVisible;
Console.CursorVisible = false;
cursorVisibilityChanged = true;
}

byte[] command = BuildRecordTraceArgs(args, out scriptPath);

if (args.Duration != default)
Expand Down Expand Up @@ -135,6 +145,12 @@ internal int CollectLinux(CollectLinuxArgs args)
}
finally
{
// Restore cursor visibility to its original state if we changed it
if (cursorVisibilityChanged)
{
Console.CursorVisible = originalCursorVisible;
}

if (!string.IsNullOrEmpty(scriptPath))
{
try
Expand Down
47 changes: 47 additions & 0 deletions src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,53 @@ public void CollectLinuxCommand_NotSupported_OnNonLinux()
});
}

[ConditionalFact(nameof(IsCollectLinuxSupported))]
public void CollectLinuxCommand_RestoresCursorVisibility_OnSuccess()
{
MockConsole console = new(200, 30, _outputHelper);
console.CursorVisible = true;

int exitCode = Run(TestArgs(), console);

// Cursor should be restored to visible after command completes
Assert.True(console.CursorVisible, "Cursor should be visible after command completes");
}

[ConditionalFact(nameof(IsCollectLinuxSupported))]
public void CollectLinuxCommand_RestoresCursorVisibility_OnError()
{
MockConsole console = new(200, 30, _outputHelper);
console.CursorVisible = true;

var handler = new CollectLinuxCommandHandler(console);
// Simulate an error by throwing an exception in the RecordTraceInvoker
handler.RecordTraceInvoker = (cmd, len, cb) => {
throw new InvalidOperationException("Simulated error");
};

int exitCode = handler.CollectLinux(TestArgs());

// Cursor should be restored to visible even when an error occurs
Assert.True(console.CursorVisible, "Cursor should be visible after error");
Assert.Equal((int)ReturnCode.TracingError, exitCode);
}

[ConditionalTheory(nameof(IsCollectLinuxSupported))]
[InlineData(true)]
[InlineData(false)]
public void CollectLinuxCommand_DoesNotChangeCursorVisibility_WhenOutputIsRedirected(bool initialCursorVisible)
{
MockConsole console = new(200, 30, _outputHelper);
console.CursorVisible = initialCursorVisible;
console.IsOutputRedirected = true;

int exitCode = Run(TestArgs(), console);

// When output is redirected, the command should not change cursor visibility,
// so the cursor should remain in its original state.
Assert.Equal(initialCursorVisible, console.CursorVisible);
}

private static int Run(object args, MockConsole console)
{
var handler = new CollectLinuxCommandHandler(console);
Expand Down
Loading