33
44using System ;
55using System . Collections . Generic ;
6- using System . CommandLine ;
76using System . IO ;
87using System . IO . Compression ;
98using System . Runtime . InteropServices ;
9+ using System . Threading ;
1010using System . Threading . Tasks ;
1111
1212namespace RunTests
@@ -24,15 +24,15 @@ public TestRunner(RunTestsOptions options)
2424
2525 public bool SetupEnvironment ( )
2626 {
27- try
27+ try
2828 {
2929 // Rename default.NuGet.config to NuGet.config if there is not a custom one from the project
3030 // We use a local NuGet.config file to avoid polluting global machine state and avoid relying on global machine state
3131 if ( ! File . Exists ( "NuGet.config" ) )
3232 {
3333 File . Copy ( "default.NuGet.config" , "NuGet.config" ) ;
3434 }
35-
35+
3636 EnvironmentVariables . Add ( "PATH" , Options . Path ) ;
3737 EnvironmentVariables . Add ( "DOTNET_ROOT" , Options . DotnetRoot ) ;
3838 EnvironmentVariables . Add ( "helix" , Options . HelixQueue ) ;
@@ -68,7 +68,7 @@ public bool SetupEnvironment()
6868
6969 public void DisplayContents ( string path = "./" )
7070 {
71- try
71+ try
7272 {
7373 Console . WriteLine ( ) ;
7474 Console . WriteLine ( $ "Displaying directory contents for { path } :") ;
@@ -88,9 +88,9 @@ public void DisplayContents(string path = "./")
8888 }
8989 }
9090
91- public async Task < bool > InstallAspNetAppIfNeededAsync ( )
91+ public async Task < bool > InstallAspNetAppIfNeededAsync ( )
9292 {
93- try
93+ try
9494 {
9595 if ( File . Exists ( Options . AspNetRuntime ) )
9696 {
@@ -113,7 +113,7 @@ public async Task<bool> InstallAspNetAppIfNeededAsync()
113113 }
114114 }
115115 }
116-
116+
117117 DisplayContents ( appRuntimePath ) ;
118118
119119 Console . WriteLine ( $ "Adding current directory to nuget sources: { Options . HELIX_WORKITEM_ROOT } ") ;
@@ -152,7 +152,7 @@ await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
152152 Options . Path += $ "{ Environment . GetEnvironmentVariable ( "DOTNET_CLI_HOME" ) } /.dotnet/tools";
153153 EnvironmentVariables [ "PATH" ] = Options . Path ;
154154 }
155- else
155+ else
156156 {
157157 Console . WriteLine ( $ "No AspNetRuntime found: { Options . AspNetRuntime } , skipping...") ;
158158 }
@@ -165,19 +165,19 @@ await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
165165 }
166166 }
167167
168- public bool InstallAspNetRefIfNeeded ( )
168+ public bool InstallAspNetRefIfNeeded ( )
169169 {
170- try
170+ try
171171 {
172172 if ( File . Exists ( Options . AspNetRef ) )
173173 {
174174 var refPath = $ "Microsoft.AspNetCore.App.Ref";
175175 Console . WriteLine ( $ "Found AspNetRef: { Options . AspNetRef } , extracting to { refPath } ") ;
176176 ZipFile . ExtractToDirectory ( Options . AspNetRef , "Microsoft.AspNetCore.App.Ref" ) ;
177-
177+
178178 DisplayContents ( refPath ) ;
179179 }
180- else
180+ else
181181 {
182182 Console . WriteLine ( $ "No AspNetRef found: { Options . AspNetRef } , skipping...") ;
183183 }
@@ -189,15 +189,37 @@ public bool InstallAspNetRefIfNeeded()
189189 return false ;
190190 }
191191 }
192-
192+
193+ public async Task < bool > InstallDotnetDump ( )
194+ {
195+ try
196+ {
197+ await ProcessUtil . RunAsync ( $ "{ Options . DotnetRoot } /dotnet",
198+ $ "tool install dotnet-dump --tool-path { Options . HELIX_WORKITEM_ROOT } " +
199+ "--version 5.0.0-* --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json" ,
200+ environmentVariables : EnvironmentVariables ,
201+ outputDataReceived : Console . WriteLine ,
202+ errorDataReceived : Console . Error . WriteLine ,
203+ throwOnError : false ) ;
204+
205+ return true ;
206+ }
207+ catch ( Exception e )
208+ {
209+ Console . WriteLine ( $ "Exception in InstallDotnetDump: { e } ") ;
210+ return false ;
211+ }
212+ }
213+
193214 public async Task < bool > CheckTestDiscoveryAsync ( )
194215 {
195216 try
196217 {
197218 // Run test discovery so we know if there are tests to run
198219 var discoveryResult = await ProcessUtil . RunAsync ( $ "{ Options . DotnetRoot } /dotnet",
199220 $ "vstest { Options . Target } -lt",
200- environmentVariables : EnvironmentVariables ) ;
221+ environmentVariables : EnvironmentVariables ,
222+ cancellationToken : new CancellationTokenSource ( TimeSpan . FromMinutes ( 2 ) ) . Token ) ;
201223
202224 if ( discoveryResult . StandardOutput . Contains ( "Exception thrown" ) )
203225 {
@@ -217,8 +239,10 @@ public async Task<bool> CheckTestDiscoveryAsync()
217239 public async Task < int > RunTestsAsync ( )
218240 {
219241 var exitCode = 0 ;
220- try
242+ try
221243 {
244+ // Timeout test run 5 minutes before the Helix job would timeout
245+ var cts = new CancellationTokenSource ( Options . Timeout . Subtract ( TimeSpan . FromMinutes ( 5 ) ) ) ;
222246 var commonTestArgs = $ "vstest { Options . Target } --logger:xunit --logger:\" console;verbosity=normal\" --blame";
223247 if ( Options . Quarantined )
224248 {
@@ -230,7 +254,8 @@ public async Task<int> RunTestsAsync()
230254 environmentVariables : EnvironmentVariables ,
231255 outputDataReceived : Console . WriteLine ,
232256 errorDataReceived : Console . Error . WriteLine ,
233- throwOnError : false ) ;
257+ throwOnError : false ,
258+ cancellationToken : cts . Token ) ;
234259
235260 if ( result . ExitCode != 0 )
236261 {
@@ -247,7 +272,8 @@ public async Task<int> RunTestsAsync()
247272 environmentVariables : EnvironmentVariables ,
248273 outputDataReceived : Console . WriteLine ,
249274 errorDataReceived : Console . Error . WriteLine ,
250- throwOnError : false ) ;
275+ throwOnError : false ,
276+ cancellationToken : cts . Token ) ;
251277
252278 if ( result . ExitCode != 0 )
253279 {
0 commit comments