2
2
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
3
4
4
using System ;
5
- using System . Collections . Generic ;
6
5
using System . IO ;
7
- using System . IO . Compression ;
8
6
using System . Linq ;
9
7
using System . Reflection ;
10
8
using System . Runtime . ExceptionServices ;
@@ -23,52 +21,70 @@ namespace Wasm.Performance.Driver
23
21
{
24
22
public class Program
25
23
{
26
- static readonly TimeSpan Timeout = TimeSpan . FromMinutes ( 3 ) ;
27
- static TaskCompletionSource < BenchmarkResult > benchmarkResult = new TaskCompletionSource < BenchmarkResult > ( ) ;
24
+ internal static TaskCompletionSource < BenchmarkResult > BenchmarkResultTask ;
28
25
29
26
public static async Task < int > Main ( string [ ] args )
30
27
{
31
- var seleniumPort = 4444 ;
28
+ // This cancellation token manages the timeout for the stress run.
29
+ // By default the driver executes and reports a single Benchmark run. For stress runs,
30
+ // we'll pass in the duration to execute the runs in milliseconds. This will cause this driver
31
+ // to repeat executions for the duration specified.
32
+ var stressRunCancellation = new CancellationToken ( canceled : true ) ;
32
33
if ( args . Length > 0 )
33
34
{
34
- if ( ! int . TryParse ( args [ 0 ] , out seleniumPort ) )
35
+ if ( ! int . TryParse ( args [ 0 ] , out var stressRunSeconds ) )
35
36
{
36
- Console . Error . WriteLine ( "Usage Driver <selenium-port >" ) ;
37
+ Console . Error . WriteLine ( "Usage Driver <stress-run-duration >" ) ;
37
38
return 1 ;
38
39
}
40
+
41
+ if ( stressRunSeconds > 0 )
42
+ {
43
+ var stressRunDuration = TimeSpan . FromSeconds ( stressRunSeconds ) ;
44
+ Console . WriteLine ( $ "Stress run duration: { stressRunDuration } .") ;
45
+ stressRunCancellation = new CancellationTokenSource ( stressRunDuration ) . Token ;
46
+ }
39
47
}
40
48
41
49
// This write is required for the benchmarking infrastructure.
42
50
Console . WriteLine ( "Application started." ) ;
43
51
44
- var cancellationToken = new CancellationTokenSource ( Timeout ) ;
45
- cancellationToken . Token . Register ( ( ) => benchmarkResult . TrySetException ( new TimeoutException ( $ "Timed out after { Timeout } ") ) ) ;
46
-
47
- using var browser = await Selenium . CreateBrowser ( seleniumPort , cancellationToken . Token ) ;
52
+ using var browser = await Selenium . CreateBrowser ( default ) ;
48
53
using var testApp = StartTestApp ( ) ;
49
54
using var benchmarkReceiver = StartBenchmarkResultReceiver ( ) ;
50
-
51
55
var testAppUrl = GetListeningUrl ( testApp ) ;
52
56
var receiverUrl = GetListeningUrl ( benchmarkReceiver ) ;
53
-
54
57
Console . WriteLine ( $ "Test app listening at { testAppUrl } .") ;
55
58
56
- var launchUrl = $ "{ testAppUrl } ?resultsUrl={ UrlEncoder . Default . Encode ( receiverUrl ) } #automated";
57
- browser . Url = launchUrl ;
58
- browser . Navigate ( ) ;
59
+ var first = true ;
60
+ do
61
+ {
62
+ BenchmarkResultTask = new TaskCompletionSource < BenchmarkResult > ( ) ;
63
+ var timeForEachRun = TimeSpan . FromMinutes ( 3 ) ;
64
+ using var runCancellationToken = new CancellationTokenSource ( timeForEachRun ) ;
65
+ runCancellationToken . Token . Register ( ( ) => BenchmarkResultTask . TrySetException ( new TimeoutException ( $ "Timed out after { timeForEachRun } ") ) ) ;
66
+
67
+ if ( first )
68
+ {
69
+ first = false ;
70
+ var launchUrl = $ "{ testAppUrl } ?resultsUrl={ UrlEncoder . Default . Encode ( receiverUrl ) } #automated";
71
+ browser . Url = launchUrl ;
72
+ browser . Navigate ( ) ;
73
+ }
74
+ else
75
+ {
76
+ browser . FindElementById ( "runAll" ) . Click ( ) ;
77
+ }
59
78
60
- FormatAsBenchmarksOutput ( benchmarkResult . Task . Result ) ;
79
+ var results = await BenchmarkResultTask . Task ;
80
+ FormatAsBenchmarksOutput ( results , includeStressRunDelimiter : ! stressRunCancellation . IsCancellationRequested ) ;
81
+ } while ( ! stressRunCancellation . IsCancellationRequested ) ;
61
82
62
83
Console . WriteLine ( "Done executing benchmark" ) ;
63
84
return 0 ;
64
85
}
65
86
66
- internal static void SetBenchmarkResult ( BenchmarkResult result )
67
- {
68
- benchmarkResult . TrySetResult ( result ) ;
69
- }
70
-
71
- private static void FormatAsBenchmarksOutput ( BenchmarkResult benchmarkResult )
87
+ private static void FormatAsBenchmarksOutput ( BenchmarkResult benchmarkResult , bool includeStressRunDelimiter )
72
88
{
73
89
// Sample of the the format: https://github.com/aspnet/Benchmarks/blob/e55f9e0312a7dd019d1268c1a547d1863f0c7237/src/Benchmarks/Program.cs#L51-L67
74
90
var output = new BenchmarkOutput ( ) ;
@@ -126,6 +142,15 @@ private static void FormatAsBenchmarksOutput(BenchmarkResult benchmarkResult)
126
142
} ) ;
127
143
}
128
144
145
+ if ( includeStressRunDelimiter )
146
+ {
147
+ output . Measurements . Add ( new BenchmarkMeasurement
148
+ {
149
+ Timestamp = DateTime . UtcNow ,
150
+ Name = "$$Delimiter$$" ,
151
+ } ) ;
152
+ }
153
+
129
154
Console . WriteLine ( "#StartJobStatistics" ) ;
130
155
Console . WriteLine ( JsonSerializer . Serialize ( output ) ) ;
131
156
Console . WriteLine ( "#EndJobStatistics" ) ;
@@ -184,9 +209,9 @@ static void RunInBackgroundThread(Action action)
184
209
isDone . Set ( ) ;
185
210
} ) ;
186
211
187
- if ( ! isDone . WaitOne ( Timeout ) )
212
+ if ( ! isDone . WaitOne ( TimeSpan . FromSeconds ( 30 ) ) )
188
213
{
189
- throw new TimeoutException ( "Timed out waiting for: " + action ) ;
214
+ throw new TimeoutException ( "Timed out waiting to start the host" ) ;
190
215
}
191
216
192
217
if ( edi != null )
0 commit comments