1111using System . Linq ;
1212using Microsoft . Diagnostics . Tests . Common ;
1313using Microsoft . Diagnostics . Tools . Trace ;
14+ using Microsoft . Internal . Common . Utils ;
1415using Xunit ;
1516
1617namespace Microsoft . Diagnostics . Tools . Trace
@@ -23,7 +24,7 @@ private static CollectLinuxCommandHandler.CollectLinuxArgs TestArgs(
2324 string clrEventLevel = "" ,
2425 string clrEvents = "" ,
2526 string [ ] perfEvents = null ,
26- string [ ] profiles = null ,
27+ string [ ] profile = null ,
2728 FileInfo output = null ,
2829 TimeSpan duration = default )
2930 {
@@ -32,7 +33,7 @@ private static CollectLinuxCommandHandler.CollectLinuxArgs TestArgs(
3233 clrEventLevel ,
3334 clrEvents ,
3435 perfEvents ?? Array . Empty < string > ( ) ,
35- profiles ?? Array . Empty < string > ( ) ,
36+ profile ?? Array . Empty < string > ( ) ,
3637 output ?? new FileInfo ( CommonOptions . DefaultTraceName ) ,
3738 duration ) ;
3839 }
@@ -42,23 +43,49 @@ private static CollectLinuxCommandHandler.CollectLinuxArgs TestArgs(
4243 public void CollectLinuxCommandProviderConfigurationConsolidation ( object testArgs , string [ ] expectedLines )
4344 {
4445 MockConsole console = new ( 200 , 30 ) ;
45- var handler = new CollectLinuxCommandHandler ( console ) ;
46- handler . RecordTraceInvoker = ( cmd , len , cb ) => 0 ;
47- int exit = handler . CollectLinux ( ( CollectLinuxCommandHandler . CollectLinuxArgs ) testArgs ) ;
46+ int exitCode = Run ( testArgs , console ) ;
4847 if ( OperatingSystem . IsLinux ( ) )
4948 {
50- Assert . Equal ( 0 , exit ) ;
51- console . AssertSanitizedLinesEqual ( null , expectedLines ) ;
49+ Assert . Equal ( ( int ) ReturnCode . Ok , exitCode ) ;
50+ console . AssertSanitizedLinesEqual ( null , expectedLines : expectedLines ) ;
5251 }
5352 else
5453 {
55- Assert . Equal ( 3 , exit ) ;
56- console . AssertSanitizedLinesEqual ( null , new string [ ] {
54+ Assert . Equal ( ( int ) ReturnCode . PlatformNotSupportedError , exitCode ) ;
55+ console . AssertSanitizedLinesEqual ( null , expectedLines : new string [ ] {
5756 "The collect-linux command is only supported on Linux." ,
5857 } ) ;
5958 }
6059 }
6160
61+ [ Theory ]
62+ [ MemberData ( nameof ( InvalidProviders ) ) ]
63+ public void CollectLinuxCommandProviderConfigurationConsolidation_Throws ( object testArgs , string [ ] expectedException )
64+ {
65+ MockConsole console = new ( 200 , 30 ) ;
66+ int exitCode = Run ( testArgs , console ) ;
67+ if ( OperatingSystem . IsLinux ( ) )
68+ {
69+ Assert . Equal ( ( int ) ReturnCode . TracingError , exitCode ) ;
70+ console . AssertSanitizedLinesEqual ( null , true , expectedLines : expectedException ) ;
71+ }
72+ else
73+ {
74+ Assert . Equal ( ( int ) ReturnCode . PlatformNotSupportedError , exitCode ) ;
75+ console . AssertSanitizedLinesEqual ( null , expectedLines : new string [ ] {
76+ "The collect-linux command is only supported on Linux." ,
77+ } ) ;
78+ }
79+ }
80+
81+ private static int Run ( object args , MockConsole console )
82+ {
83+ var handler = new CollectLinuxCommandHandler ( console ) ;
84+ handler . RecordTraceInvoker = ( cmd , len , cb ) => 0 ;
85+ return handler . CollectLinux ( ( CollectLinuxCommandHandler . CollectLinuxArgs ) args ) ;
86+ }
87+
88+
6289 public static IEnumerable < object [ ] > BasicCases ( )
6390 {
6491 yield return new object [ ] {
@@ -98,7 +125,7 @@ public static IEnumerable<object[]> BasicCases()
98125 }
99126 } ;
100127 yield return new object [ ] {
101- TestArgs ( profiles : new [ ] { "cpu-sampling" } ) ,
128+ TestArgs ( profile : new [ ] { "cpu-sampling" } ) ,
102129 new string [ ] {
103130 "No .NET providers were configured." ,
104131 "" ,
@@ -108,7 +135,7 @@ public static IEnumerable<object[]> BasicCases()
108135 }
109136 } ;
110137 yield return new object [ ] {
111- TestArgs ( providers : new [ ] { "Foo:0x1:4" } , profiles : new [ ] { "cpu-sampling" } ) ,
138+ TestArgs ( providers : new [ ] { "Foo:0x1:4" } , profile : new [ ] { "cpu-sampling" } ) ,
112139 new string [ ] {
113140 "" ,
114141 ProviderHeader ,
@@ -120,7 +147,7 @@ public static IEnumerable<object[]> BasicCases()
120147 }
121148 } ;
122149 yield return new object [ ] {
123- TestArgs ( clrEvents : "gc" , profiles : new [ ] { "cpu-sampling" } ) ,
150+ TestArgs ( clrEvents : "gc" , profile : new [ ] { "cpu-sampling" } ) ,
124151 new string [ ] {
125152 "" ,
126153 ProviderHeader ,
@@ -132,7 +159,7 @@ public static IEnumerable<object[]> BasicCases()
132159 }
133160 } ;
134161 yield return new object [ ] {
135- TestArgs ( providers : new [ ] { "Microsoft-Windows-DotNETRuntime:0x1:4" } , profiles : new [ ] { "cpu-sampling" } ) ,
162+ TestArgs ( providers : new [ ] { "Microsoft-Windows-DotNETRuntime:0x1:4" } , profile : new [ ] { "cpu-sampling" } ) ,
136163 new string [ ] {
137164 "" ,
138165 ProviderHeader ,
@@ -189,6 +216,39 @@ public static IEnumerable<object[]> BasicCases()
189216 } ;
190217 }
191218
219+ public static IEnumerable < object [ ] > InvalidProviders ( )
220+ {
221+ yield return new object [ ]
222+ {
223+ TestArgs ( profile : new [ ] { "dotnet-sampled-thread-time" } ) ,
224+ new [ ] { FormatException ( "The specified profile 'dotnet-sampled-thread-time' does not apply to `dotnet-trace collect-linux`." , "System.ArgumentException" ) }
225+ } ;
226+
227+ yield return new object [ ]
228+ {
229+ TestArgs ( profile : new [ ] { "unknown" } ) ,
230+ new [ ] { FormatException ( "Invalid profile name: unknown" , "System.ArgumentException" ) }
231+ } ;
232+
233+ yield return new object [ ]
234+ {
235+ TestArgs ( providers : new [ ] { "Foo:::Bar=0" , "Foo:::Bar=1" } ) ,
236+ new [ ] { FormatException ( $ "Provider \" Foo\" is declared multiple times with filter arguments.", "System.ArgumentException" ) }
237+ } ;
238+
239+ yield return new object [ ]
240+ {
241+ TestArgs ( clrEvents : "unknown" ) ,
242+ new [ ] { FormatException ( "unknown is not a valid CLR event keyword" , "System.ArgumentException" ) }
243+ } ;
244+
245+ yield return new object [ ]
246+ {
247+ TestArgs ( clrEvents : "gc" , clrEventLevel : "unknown" ) ,
248+ new [ ] { FormatException ( "Unknown EventLevel: unknown" , "System.ArgumentException" ) }
249+ } ;
250+ }
251+
192252 private const string ProviderHeader = "Provider Name Keywords Level Enabled By" ;
193253 private static string LinuxHeader => $ "{ "Linux Events" , - 80 } Enabled By";
194254 private static string LinuxProfile ( string name ) => $ "{ name , - 80 } --profile";
@@ -200,5 +260,6 @@ private static string FormatProvider(string name, string keywordsHex, string lev
200260 string . Format ( "{0, -8}" , $ "{ levelName } ({ levelValue } )") ;
201261 return string . Format ( "{0, -80}" , display ) + enabledBy ;
202262 }
263+ private static string FormatException ( string message , string exceptionType ) => $ "[ERROR] { exceptionType } : { message } ";
203264 }
204265}
0 commit comments