From 6758b529344f5c1f045c4eedfb328281d92469f3 Mon Sep 17 00:00:00 2001 From: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> Date: Thu, 6 Aug 2026 19:01:47 -0700 Subject: [PATCH] Update System.CommandLine to 2.0.10 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: e3b1c2bf-8a48-4f24-a7ad-dfb5cb3b0644 --- eng/Versions.props | 1 + .../CommandService.cs | 49 +++++------- src/Tools/Common/Commands/ProcessStatus.cs | 2 +- src/Tools/Common/ProcessTerminationHandler.cs | 16 ++-- src/Tools/dotnet-dump/Program.cs | 4 +- src/Tools/dotnet-sos/Program.cs | 8 +- src/Tools/dotnet-stack/ReportCommand.cs | 4 +- src/Tools/dotnet-stack/Symbolicate.cs | 4 +- .../CommandLine/Commands/CollectCommand.cs | 4 +- .../CommandLine/Commands/ConvertCommand.cs | 4 +- .../EventPipeStress/Common/Common.csproj | 2 +- src/tests/EventPipeStress/Common/Options.cs | 79 ++++++++++--------- .../Orchestrator/CommandLine.cs | 76 ++++++++++-------- .../Orchestrator/Orchestrator.csproj | 2 +- .../EventPipeStress/Orchestrator/Program.cs | 59 ++++++-------- src/tests/EventPipeStress/Stress/Program.cs | 29 ++++--- .../EventPipeStress/Stress/Stress.csproj | 2 +- src/tests/dotnet-stack/StackTests.cs | 13 +-- .../CollectCommandFunctionalTests.cs | 2 +- 19 files changed, 176 insertions(+), 184 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 5c41747bbf..4b38da1e33 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -45,6 +45,7 @@ 8.0.0 9.0.11 + 2.0.10 9.0.8 17.10.0-beta1.24272.1 3.1.23 diff --git a/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs b/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs index 2cb40fb2eb..bfbed5d32a 100644 --- a/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs +++ b/src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs @@ -276,7 +276,6 @@ private sealed class CommandGroup { private Command _rootCommand; private readonly Dictionary _commandHandlers = new(); - private readonly ParseResult _emptyParseResult; /// /// Create an instance of the command processor; @@ -285,10 +284,6 @@ private sealed class CommandGroup public CommandGroup(string commandPrompt = null) { _rootCommand = new Command(commandPrompt); - - // The actual ParseResult.Empty() has a bug in it where it tries to get the executable name - // and nothing is returned under lldb on Linux causing an index out of range exception. - _emptyParseResult = _rootCommand.Parse(Array.Empty()); } /// @@ -300,15 +295,7 @@ public CommandGroup(string commandPrompt = null) /// parsing error internal bool Execute(IReadOnlyList commandLine, IServiceProvider services) { - IConsoleService consoleService = services.GetService(); - CommandLineConfiguration configuration = new(_rootCommand) - { - Output = new ConsoleServiceWrapper(consoleService.Write), - Error = new ConsoleServiceWrapper(consoleService.WriteError) - }; - - // Parse the command line and invoke the command - ParseResult parseResult = configuration.Parse(commandLine); + ParseResult parseResult = _rootCommand.Parse(commandLine); if (parseResult.Errors.Count > 0) { @@ -437,10 +424,26 @@ internal string GetDetailedHelp(Command command, IServiceProvider services, int { StringWriter console = new(); - // Get the command help - HelpBuilder helpBuilder = new(maxWidth: windowWidth); - HelpContext helpContext = new(helpBuilder, command, console, _emptyParseResult); - helpBuilder.Write(helpContext); + HelpOption helpOption = new() + { + Hidden = true, + Action = new HelpAction + { + MaxWidth = windowWidth + } + }; + command.Options.Add(helpOption); + try + { + command.Parse(["--help"]).Invoke(new InvocationConfiguration + { + Output = console + }); + } + finally + { + command.Options.Remove(helpOption); + } // Get the detailed help if any if (TryGetCommandHandler(command.Name, out CommandHandler handler)) @@ -725,15 +728,5 @@ private void SetProperties(ParseResult contextParseResult, Command parser, objec } } - internal sealed class ConsoleServiceWrapper : TextWriter - { - private Action _write; - - public ConsoleServiceWrapper(Action write) => _write = write; - - public override void Write(string value) => _write.Invoke(value); - - public override Encoding Encoding => throw new NotImplementedException(); - } } } diff --git a/src/Tools/Common/Commands/ProcessStatus.cs b/src/Tools/Common/Commands/ProcessStatus.cs index e5fa27cd97..c3d0608ebd 100644 --- a/src/Tools/Common/Commands/ProcessStatus.cs +++ b/src/Tools/Common/Commands/ProcessStatus.cs @@ -23,7 +23,7 @@ public class ProcessStatusCommandHandler public static Command ProcessStatusCommand(string description) { Command statusCommand = new(name: "ps", description); - statusCommand.SetAction((parseResult, ct) => Task.FromResult(ProcessStatus(parseResult.Configuration.Output, parseResult.Configuration.Error))); + statusCommand.SetAction((parseResult, ct) => Task.FromResult(ProcessStatus(parseResult.InvocationConfiguration.Output, parseResult.InvocationConfiguration.Error))); return statusCommand; } diff --git a/src/Tools/Common/ProcessTerminationHandler.cs b/src/Tools/Common/ProcessTerminationHandler.cs index b5eb515f74..0e9b30d6cb 100644 --- a/src/Tools/Common/ProcessTerminationHandler.cs +++ b/src/Tools/Common/ProcessTerminationHandler.cs @@ -24,15 +24,13 @@ internal sealed class ProcessTerminationHandler : IDisposable internal static async Task InvokeAsync(ParseResult parseResult, string blockedSignals = "") { - using ProcessTerminationHandler terminationHandler = ConfigureTerminationHandler(parseResult, blockedSignals); - return await parseResult.InvokeAsync(terminationHandler.GetToken).ConfigureAwait(false); - } - - private static ProcessTerminationHandler ConfigureTerminationHandler(ParseResult parseResult, string blockedSignals) - { - // Use custom process terminate handler for the command line tool parse result. - parseResult.Configuration.ProcessTerminationTimeout = null; - return new ProcessTerminationHandler(blockedSignals); + using ProcessTerminationHandler terminationHandler = new(blockedSignals); + return await parseResult.InvokeAsync( + configuration: new InvocationConfiguration + { + ProcessTerminationTimeout = null + }, + cancellationToken: terminationHandler.GetToken).ConfigureAwait(false); } private ProcessTerminationHandler(string blockedSignals) diff --git a/src/Tools/dotnet-dump/Program.cs b/src/Tools/dotnet-dump/Program.cs index 6e5d18cca7..9e8fdc7b92 100644 --- a/src/Tools/dotnet-dump/Program.cs +++ b/src/Tools/dotnet-dump/Program.cs @@ -32,8 +32,8 @@ private static Command CollectCommand() }; command.SetAction((parseResult) => new Dumper().Collect( - stdOutput: parseResult.Configuration.Output, - stdError: parseResult.Configuration.Error, + stdOutput: parseResult.InvocationConfiguration.Output, + stdError: parseResult.InvocationConfiguration.Error, processId: parseResult.GetValue(ProcessIdOption), output: parseResult.GetValue(OutputOption), diag: parseResult.GetValue(DiagnosticLoggingOption), diff --git a/src/Tools/dotnet-sos/Program.cs b/src/Tools/dotnet-sos/Program.cs index 89a9e3ffc4..d3ab7cfb60 100644 --- a/src/Tools/dotnet-sos/Program.cs +++ b/src/Tools/dotnet-sos/Program.cs @@ -32,8 +32,8 @@ private static Command InstallCommand() }; installCommand.SetAction(parseResult => Invoke( - parseResult.Configuration.Output, - parseResult.Configuration.Error, + parseResult.InvocationConfiguration.Output, + parseResult.InvocationConfiguration.Error, architecture: parseResult.GetValue(ArchitectureOption), install: true)); @@ -53,8 +53,8 @@ private static Command UninstallCommand() description: "Uninstalls SOS and reverts any configuration changes to LLDB."); uninstallCommand.SetAction(parseResult => Invoke( - parseResult.Configuration.Output, - parseResult.Configuration.Error, + parseResult.InvocationConfiguration.Output, + parseResult.InvocationConfiguration.Error, architecture: null, install: false)); diff --git a/src/Tools/dotnet-stack/ReportCommand.cs b/src/Tools/dotnet-stack/ReportCommand.cs index 21e73f2d7e..a32fb5ae41 100644 --- a/src/Tools/dotnet-stack/ReportCommand.cs +++ b/src/Tools/dotnet-stack/ReportCommand.cs @@ -174,8 +174,8 @@ public static Command ReportCommand() }; reportCommand.SetAction((parseResult, ct) => Report(ct, - stdOutput: parseResult.Configuration.Output, - stdError: parseResult.Configuration.Error, + stdOutput: parseResult.InvocationConfiguration.Output, + stdError: parseResult.InvocationConfiguration.Error, processId: parseResult.GetValue(ProcessIdOption), name: parseResult.GetValue(NameOption), duration: parseResult.GetValue(DurationOption))); diff --git a/src/Tools/dotnet-stack/Symbolicate.cs b/src/Tools/dotnet-stack/Symbolicate.cs index ce8b10e59b..7b8081d0c8 100644 --- a/src/Tools/dotnet-stack/Symbolicate.cs +++ b/src/Tools/dotnet-stack/Symbolicate.cs @@ -306,8 +306,8 @@ public static Command SymbolicateCommand() }; symbolicateCommand.SetAction((parseResult, ct) => Task.FromResult(Symbolicate( - stdOutput: parseResult.Configuration.Output, - stdError: parseResult.Configuration.Error, + stdOutput: parseResult.InvocationConfiguration.Output, + stdError: parseResult.InvocationConfiguration.Error, inputPath: parseResult.GetValue(InputFileArgument), searchDir: parseResult.GetValue(SearchDirectoryOption), output: parseResult.GetValue(OutputFileOption), diff --git a/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs b/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs index d86b3f537b..a251651731 100644 --- a/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs +++ b/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs @@ -65,7 +65,7 @@ private void ConsoleWriteLine(string str = "") /// Collect rundown events. /// The session buffering mode; Block requests non-lossy collection (requires a .NET 11+ target). /// - internal async Task Collect(CancellationToken ct, CommandLineConfiguration cliConfig, int processId, FileInfo output, uint buffersize, string[] providers, string[] profile, TraceFileFormat format, TimeSpan duration, string clrevents, string clreventlevel, string name, string diagnosticPort, bool showchildio, bool resumeRuntime, string stoppingEventProviderName, string stoppingEventEventName, string stoppingEventPayloadFilter, bool? rundown, string dsrouter, EventPipeBufferingMode bufferingMode) + internal async Task Collect(CancellationToken ct, InvocationConfiguration cliConfig, int processId, FileInfo output, uint buffersize, string[] providers, string[] profile, TraceFileFormat format, TimeSpan duration, string clrevents, string clreventlevel, string name, string diagnosticPort, bool showchildio, bool resumeRuntime, string stoppingEventProviderName, string stoppingEventEventName, string stoppingEventPayloadFilter, bool? rundown, string dsrouter, EventPipeBufferingMode bufferingMode) { bool collectionStopped = false; bool cancelOnEnter = true; @@ -572,7 +572,7 @@ public static Command CollectCommand() string profileValue = parseResult.GetValue(CommonOptions.ProfileOption) ?? string.Empty; return handler.Collect(ct, - cliConfig: parseResult.Configuration, + cliConfig: parseResult.InvocationConfiguration, processId: parseResult.GetValue(CommonOptions.ProcessIdOption), output: parseResult.GetValue(CommonOptions.OutputPathOption), buffersize: parseResult.GetValue(CircularBufferOption), diff --git a/src/Tools/dotnet-trace/CommandLine/Commands/ConvertCommand.cs b/src/Tools/dotnet-trace/CommandLine/Commands/ConvertCommand.cs index 606c195901..0f2ab89112 100644 --- a/src/Tools/dotnet-trace/CommandLine/Commands/ConvertCommand.cs +++ b/src/Tools/dotnet-trace/CommandLine/Commands/ConvertCommand.cs @@ -104,8 +104,8 @@ public static Command ConvertCommand() }; convertCommand.SetAction((parseResult, ct) => Task.FromResult(ConvertFile( - stdOut: parseResult.Configuration.Output, - stdError: parseResult.Configuration.Error, + stdOut: parseResult.InvocationConfiguration.Output, + stdError: parseResult.InvocationConfiguration.Error, inputFilename: parseResult.GetValue(InputFileArgument), format: parseResult.GetValue(CommonOptions.ConvertFormatOption), output: parseResult.GetValue(OutputOption diff --git a/src/tests/EventPipeStress/Common/Common.csproj b/src/tests/EventPipeStress/Common/Common.csproj index 6147636936..14f3c4b2f9 100644 --- a/src/tests/EventPipeStress/Common/Common.csproj +++ b/src/tests/EventPipeStress/Common/Common.csproj @@ -5,7 +5,7 @@ - + \ No newline at end of file diff --git a/src/tests/EventPipeStress/Common/Options.cs b/src/tests/EventPipeStress/Common/Options.cs index aa2c257560..54121c7524 100644 --- a/src/tests/EventPipeStress/Common/Options.cs +++ b/src/tests/EventPipeStress/Common/Options.cs @@ -6,26 +6,23 @@ namespace Common { public static class CommandLineOptions { - static public ValidateSymbol GreaterThanZeroValidator = (OptionResult result) => + static public Action GreaterThanZeroValidator = (OptionResult result) => { if (result.GetValueOrDefault() <= 0) - return $"{result.Option.Name} must be greater than or equal to 0"; - return null; + result.AddError($"{result.Option.Name} must be greater than or equal to 0"); }; - static public ValidateSymbol GreaterThanOrEqualZeroValidator = (OptionResult result) => + static public Action GreaterThanOrEqualZeroValidator = (OptionResult result) => { if (result.GetValueOrDefault() < 0) - return $"{result.Option.Name} must be greater than 0"; - return null; + result.AddError($"{result.Option.Name} must be greater than 0"); }; - static public ValidateSymbol MustBeNegOneOrPositiveValidator = (OptionResult result) => + static public Action MustBeNegOneOrPositiveValidator = (OptionResult result) => { int val = result.GetValueOrDefault(); if (val < -1 || val == 0) - return $"{result.Option.Name} must be -1 or greater than 0"; - return null; + result.AddError($"{result.Option.Name} must be -1 or greater than 0"); }; static private Option _eventSizeOption = null; @@ -36,11 +33,12 @@ static public Option EventSizeOption if (_eventSizeOption != null) return _eventSizeOption; - _eventSizeOption = new Option( - alias: "--event-size", - getDefaultValue: () => 100, - description: "The size of the event payload. The payload is a string, so the actual size will be eventSize * sizeof(char) where sizeof(char) is 2 Bytes due to Unicode in C#."); - _eventSizeOption.AddValidator(GreaterThanZeroValidator); + _eventSizeOption = new Option("--event-size") + { + DefaultValueFactory = _ => 100, + Description = "The size of the event payload. The payload is a string, so the actual size will be eventSize * sizeof(char) where sizeof(char) is 2 Bytes due to Unicode in C#." + }; + _eventSizeOption.Validators.Add(GreaterThanZeroValidator); return _eventSizeOption; } private set {} @@ -54,21 +52,23 @@ static public Option EventRateOption if (_eventRateOption != null) return _eventRateOption; - _eventRateOption = new Option( - alias: "--event-rate", - getDefaultValue: () => -1, - description: "The rate of events in events/sec. -1 means 'as fast as possible'."); - _eventRateOption.AddValidator(MustBeNegOneOrPositiveValidator); + _eventRateOption = new Option("--event-rate") + { + DefaultValueFactory = _ => -1, + Description = "The rate of events in events/sec. -1 means 'as fast as possible'." + }; + _eventRateOption.Validators.Add(MustBeNegOneOrPositiveValidator); return _eventRateOption; } private set {} } static public Option BurstPatternOption = - new Option( - alias: "--burst-pattern", - getDefaultValue: () => BurstPattern.NONE, - description: "The burst pattern to send events in."); + new Option("--burst-pattern") + { + DefaultValueFactory = _ => BurstPattern.NONE, + Description = "The burst pattern to send events in." + }; static private Option _durationOption = null; static public Option DurationOption @@ -78,11 +78,12 @@ static public Option DurationOption if (_durationOption != null) return _durationOption; - _durationOption = new Option( - alias: "--duration", - getDefaultValue: () => 60, - description: "The number of seconds to send events for."); - _durationOption.AddValidator(GreaterThanZeroValidator); + _durationOption = new Option("--duration") + { + DefaultValueFactory = _ => 60, + Description = "The number of seconds to send events for." + }; + _durationOption.Validators.Add(GreaterThanZeroValidator); return _durationOption; } private set {} @@ -97,11 +98,12 @@ static public Option ThreadsOption if (_threadsOption != null) return _threadsOption; - _threadsOption = new Option( - alias: "--threads", - getDefaultValue: () => 1, - description: "The number of threads writing events."); - _threadsOption.AddValidator(GreaterThanZeroValidator); + _threadsOption = new Option("--threads") + { + DefaultValueFactory = _ => 1, + Description = "The number of threads writing events." + }; + _threadsOption.Validators.Add(GreaterThanZeroValidator); return _threadsOption; } private set {} @@ -116,11 +118,12 @@ static public Option EventCountOption if (_eventCountOption != null) return _eventCountOption; - _eventCountOption = new Option( - alias: "--event-count", - getDefaultValue: () => -1, - description: "The total number of events to write per thread. -1 means no limit"); - _eventCountOption.AddValidator(MustBeNegOneOrPositiveValidator); + _eventCountOption = new Option("--event-count") + { + DefaultValueFactory = _ => -1, + Description = "The total number of events to write per thread. -1 means no limit" + }; + _eventCountOption.Validators.Add(MustBeNegOneOrPositiveValidator); return _eventCountOption; } private set {} diff --git a/src/tests/EventPipeStress/Orchestrator/CommandLine.cs b/src/tests/EventPipeStress/Orchestrator/CommandLine.cs index 994977066f..614bdbd1b7 100644 --- a/src/tests/EventPipeStress/Orchestrator/CommandLine.cs +++ b/src/tests/EventPipeStress/Orchestrator/CommandLine.cs @@ -8,22 +8,25 @@ namespace Orchestrator public static class OrchestrateCommandLine { static public Option ReaderTypeOption = - new Option( - alias: "--reader-type", - getDefaultValue: () => ReaderType.Stream, - description: "The method to read the stream of events."); + new Option("--reader-type") + { + DefaultValueFactory = _ => ReaderType.Stream, + Description = "The method to read the stream of events." + }; static public Option PauseOption = - new Option( - alias: "--pause", - getDefaultValue: () => false, - description: "Should the orchestrator pause before starting each test phase for a debugger to attach?"); + new Option("--pause") + { + DefaultValueFactory = _ => false, + Description = "Should the orchestrator pause before starting each test phase for a debugger to attach?" + }; static public Option RundownOption = - new Option( - alias: "--rundown", - getDefaultValue: () => true, - description: "Should the EventPipe session request rundown events?"); + new Option("--rundown") + { + DefaultValueFactory = _ => true, + Description = "Should the EventPipe session request rundown events?" + }; static private Option _bufferSizeOption = null; static public Option BufferSizeOption @@ -33,11 +36,12 @@ static public Option BufferSizeOption if (_bufferSizeOption != null) return _bufferSizeOption; - _bufferSizeOption = new Option( - alias: "--buffer-size", - getDefaultValue: () => 256, - description: "The size of the buffer requested in the EventPipe session"); - _bufferSizeOption.AddValidator(CommandLineOptions.GreaterThanZeroValidator); + _bufferSizeOption = new Option("--buffer-size") + { + DefaultValueFactory = _ => 256, + Description = "The size of the buffer requested in the EventPipe session" + }; + _bufferSizeOption.Validators.Add(CommandLineOptions.GreaterThanZeroValidator); return _bufferSizeOption; } private set {} @@ -51,11 +55,12 @@ static public Option SlowReaderOption if (_slowReaderOption != null) return _slowReaderOption; - _slowReaderOption = new Option( - alias: "--slow-reader", - getDefaultValue: () => 0, - description: " Delay every read by this many milliseconds."); - _slowReaderOption.AddValidator(CommandLineOptions.GreaterThanOrEqualZeroValidator); + _slowReaderOption = new Option("--slow-reader") + { + DefaultValueFactory = _ => 0, + Description = " Delay every read by this many milliseconds." + }; + _slowReaderOption.Validators.Add(CommandLineOptions.GreaterThanOrEqualZeroValidator); return _slowReaderOption; } private set {} @@ -69,11 +74,12 @@ static public Option CoresOption if (_coresOption != null) return _coresOption; - _coresOption = new Option( - alias: "--cores", - getDefaultValue: () => Environment.ProcessorCount, - description: "The number of logical cores to restrict the writing process to."); - _coresOption.AddValidator(CoreValueMustBeFeasibleValidator); + _coresOption = new Option("--cores") + { + DefaultValueFactory = _ => Environment.ProcessorCount, + Description = "The number of logical cores to restrict the writing process to." + }; + _coresOption.Validators.Add(CoreValueMustBeFeasibleValidator); return _coresOption; } private set {} @@ -87,22 +93,22 @@ static public Option IterationsOption if (_iterationsOption != null) return _iterationsOption; - _iterationsOption = new Option( - alias: "--iterations", - getDefaultValue: () => 1, - description: "The number of times to run the test."); - _iterationsOption.AddValidator(CommandLineOptions.GreaterThanZeroValidator); + _iterationsOption = new Option("--iterations") + { + DefaultValueFactory = _ => 1, + Description = "The number of times to run the test." + }; + _iterationsOption.Validators.Add(CommandLineOptions.GreaterThanZeroValidator); return _iterationsOption; } private set {} } - static public ValidateSymbol CoreValueMustBeFeasibleValidator = (OptionResult result) => + static public Action CoreValueMustBeFeasibleValidator = (OptionResult result) => { int val = result.GetValueOrDefault(); if (val < 1 || val > Environment.ProcessorCount) - return $"Core count must be between 1 and {Environment.ProcessorCount}"; - return null; + result.AddError($"Core count must be between 1 and {Environment.ProcessorCount}"); }; } } \ No newline at end of file diff --git a/src/tests/EventPipeStress/Orchestrator/Orchestrator.csproj b/src/tests/EventPipeStress/Orchestrator/Orchestrator.csproj index 30aa2379a1..ceafecc19a 100644 --- a/src/tests/EventPipeStress/Orchestrator/Orchestrator.csproj +++ b/src/tests/EventPipeStress/Orchestrator/Orchestrator.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/tests/EventPipeStress/Orchestrator/Program.cs b/src/tests/EventPipeStress/Orchestrator/Program.cs index 50c20606f0..c7f31ce919 100644 --- a/src/tests/EventPipeStress/Orchestrator/Program.cs +++ b/src/tests/EventPipeStress/Orchestrator/Program.cs @@ -7,9 +7,6 @@ using System.Threading.Tasks; using System.Runtime.InteropServices; using System.CommandLine; -using System.CommandLine.Invocation; -using System.CommandLine.Builder; -using System.CommandLine.Parsing; using Common; using Microsoft.Diagnostics.NETCore.Client; @@ -28,24 +25,6 @@ public enum ReaderType class Program { - delegate Task RootCommandHandler( - IConsole console, - CancellationToken ct, - FileInfo stressPath, - int eventSize, - int eventRate, - BurstPattern burstPattern, - ReaderType readerType, - int slowReader, - int duration, - int cores, - int threads, - int eventCount, - bool rundown, - int bufferSize, - int iterations, - bool pause); - // TODO: Collect CPU % of reader and writer while running test and add to stats // TODO: Standardize and clean up logging from orchestrator and corescaletest // TODO: Improve error handling @@ -69,20 +48,18 @@ static async Task Main(string[] args) } } - return await BuildCommandLine() - .UseDefaults() - .Build() - .InvokeAsync(args); + return await BuildCommandLine().Parse(args).InvokeAsync(); } - static CommandLineBuilder BuildCommandLine() + static RootCommand BuildCommandLine() { - var rootCommand = new RootCommand("EventPipe Stress Tester - Orchestrator") + Argument stressPathArgument = new("stress-path") + { + Description = "The location of the Stress executable." + }; + RootCommand rootCommand = new("EventPipe Stress Tester - Orchestrator") { - new Argument( - name: "stress-path", - description: "The location of the Stress executable." - ), + stressPathArgument, CommandLineOptions.EventSizeOption, CommandLineOptions.EventRateOption, CommandLineOptions.BurstPatternOption, @@ -99,8 +76,23 @@ static CommandLineBuilder BuildCommandLine() }; - rootCommand.Handler = CommandHandler.Create((RootCommandHandler)Orchestrate); - return new CommandLineBuilder(rootCommand); + rootCommand.SetAction((parseResult, ct) => Orchestrate( + ct, + parseResult.GetValue(stressPathArgument), + parseResult.GetValue(CommandLineOptions.EventSizeOption), + parseResult.GetValue(CommandLineOptions.EventRateOption), + parseResult.GetValue(CommandLineOptions.BurstPatternOption), + parseResult.GetValue(OrchestrateCommandLine.ReaderTypeOption), + parseResult.GetValue(OrchestrateCommandLine.SlowReaderOption), + parseResult.GetValue(CommandLineOptions.DurationOption), + parseResult.GetValue(OrchestrateCommandLine.CoresOption), + parseResult.GetValue(CommandLineOptions.ThreadsOption), + parseResult.GetValue(CommandLineOptions.EventCountOption), + parseResult.GetValue(OrchestrateCommandLine.RundownOption), + parseResult.GetValue(OrchestrateCommandLine.BufferSizeOption), + parseResult.GetValue(OrchestrateCommandLine.IterationsOption), + parseResult.GetValue(OrchestrateCommandLine.PauseOption))); + return rootCommand; } private static EventPipeSession GetSession(int pid, bool rundown, int bufferSize) @@ -197,7 +189,6 @@ static Func UseFS(bool rundown, int bufferSize) static bool IsWindowsOrLinux => OperatingSystem.IsLinux() || OperatingSystem.IsWindows(); static async Task Orchestrate( - IConsole console, CancellationToken ct, FileInfo stressPath, int eventSize, diff --git a/src/tests/EventPipeStress/Stress/Program.cs b/src/tests/EventPipeStress/Stress/Program.cs index d5289f0160..912ef9bd14 100644 --- a/src/tests/EventPipeStress/Stress/Program.cs +++ b/src/tests/EventPipeStress/Stress/Program.cs @@ -1,8 +1,5 @@ -using System; +using System; using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.Invocation; -using System.CommandLine.Parsing; using System.Diagnostics.Tracing; using System.Linq; using System.Threading; @@ -44,11 +41,9 @@ private static Action makeThreadProc(int eventCount) return () => { while (!finished) { burst(); } }; } - private delegate Task RootCommandHandler(IConsole console, CancellationToken ct, int eventSize, int eventRate, BurstPattern burstPattern, int threads, int duration, int eventCount); - - private static CommandLineBuilder BuildCommandLine() + private static RootCommand BuildCommandLine() { - var rootCommand = new RootCommand("EventPipe Stress Tester - Stress") + RootCommand rootCommand = new("EventPipe Stress Tester - Stress") { CommandLineOptions.EventSizeOption, CommandLineOptions.EventRateOption, @@ -59,19 +54,23 @@ private static CommandLineBuilder BuildCommandLine() }; - rootCommand.Handler = CommandHandler.Create((RootCommandHandler)Run); - return new CommandLineBuilder(rootCommand); + rootCommand.SetAction((parseResult, ct) => Run( + ct, + parseResult.GetValue(CommandLineOptions.EventSizeOption), + parseResult.GetValue(CommandLineOptions.EventRateOption), + parseResult.GetValue(CommandLineOptions.BurstPatternOption), + parseResult.GetValue(CommandLineOptions.ThreadsOption), + parseResult.GetValue(CommandLineOptions.DurationOption), + parseResult.GetValue(CommandLineOptions.EventCountOption))); + return rootCommand; } static async Task Main(string[] args) { - return await BuildCommandLine() - .UseDefaults() - .Build() - .InvokeAsync(args); + return await BuildCommandLine().Parse(args).InvokeAsync(); } - private static async Task Run(IConsole console, CancellationToken ct, int eventSize, int eventRate, BurstPattern burstPattern, int threads, int duration, int eventCount) + private static async Task Run(CancellationToken ct, int eventSize, int eventRate, BurstPattern burstPattern, int threads, int duration, int eventCount) { TimeSpan durationTimeSpan = TimeSpan.FromSeconds(duration); diff --git a/src/tests/EventPipeStress/Stress/Stress.csproj b/src/tests/EventPipeStress/Stress/Stress.csproj index 3277f12440..1022b87c1d 100644 --- a/src/tests/EventPipeStress/Stress/Stress.csproj +++ b/src/tests/EventPipeStress/Stress/Stress.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/tests/dotnet-stack/StackTests.cs b/src/tests/dotnet-stack/StackTests.cs index c689e5a5ba..4969c5008a 100644 --- a/src/tests/dotnet-stack/StackTests.cs +++ b/src/tests/dotnet-stack/StackTests.cs @@ -4,8 +4,7 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.IO; -using System.CommandLine.Parsing; +using System.IO; using System.Threading.Tasks; using Microsoft.Diagnostics.TestHelpers; using Xunit; @@ -61,8 +60,7 @@ public async Task ReportsStacksCorrectly(TestConfiguration config) { Command reportCommand = ReportCommandHandler.ReportCommand(); - TestConsole console = new(); - Parser parser = new(reportCommand); + StringWriter stdOut = new(); await using TestRunner runner = await TestRunner.Create(config, _output, "StackTracee", usePipe: false); await runner.Start(); @@ -70,9 +68,12 @@ public async Task ReportsStacksCorrectly(TestConfiguration config) // Wait for tracee to get to readkey call await Task.Delay(TimeSpan.FromSeconds(1)); - await parser.InvokeAsync($"report -p {runner.Pid}", console); + await reportCommand.Parse(["-p", runner.Pid.ToString()]).InvokeAsync(new InvocationConfiguration + { + Output = stdOut + }); - string report = console.Out.ToString(); + string report = stdOut.ToString(); runner.WriteLine($"REPORT_START\n{report}REPORT_END"); Assert.True(!string.IsNullOrEmpty(report)); diff --git a/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs b/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs index c59802287e..85c9a772bb 100644 --- a/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs +++ b/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs @@ -30,7 +30,7 @@ public CollectCommandFunctionalTests(ITestOutputHelper outputHelper) public sealed record CollectArgs( CancellationToken ct = default, - CommandLineConfiguration cliConfig = null, + InvocationConfiguration cliConfig = null, int processId = -1, uint buffersize = 1, string[] providers = null,