Skip to content

Commit ccabaed

Browse files
committed
Allow BlazorWasm benchmark driver to perform stress runs
Adds an option that allows running the driver in a loop until timeout expires
1 parent 63e8089 commit ccabaed

File tree

6 files changed

+59
-30
lines changed

6 files changed

+59
-30
lines changed

src/Components/benchmarkapps/Wasm.Performance/Driver/BenchmarkResultsStartup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void Configure(IApplicationBuilder app)
2929
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
3030
});
3131
await context.Response.WriteAsync("OK");
32-
Program.SetBenchmarkResult(result);
32+
Program.BenchmarkResultTask.TrySetResult(result);
3333
});
3434
}
3535
}

src/Components/benchmarkapps/Wasm.Performance/Driver/Program.cs

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.IO;
7-
using System.IO.Compression;
86
using System.Linq;
97
using System.Reflection;
108
using System.Runtime.ExceptionServices;
@@ -23,52 +21,70 @@ namespace Wasm.Performance.Driver
2321
{
2422
public class Program
2523
{
26-
static readonly TimeSpan Timeout = TimeSpan.FromMinutes(3);
27-
static TaskCompletionSource<BenchmarkResult> benchmarkResult = new TaskCompletionSource<BenchmarkResult>();
24+
internal static TaskCompletionSource<BenchmarkResult> BenchmarkResultTask;
2825

2926
public static async Task<int> Main(string[] args)
3027
{
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);
3233
if (args.Length > 0)
3334
{
34-
if (!int.TryParse(args[0], out seleniumPort))
35+
if (!int.TryParse(args[0], out var stressRunSeconds))
3536
{
36-
Console.Error.WriteLine("Usage Driver <selenium-port>");
37+
Console.Error.WriteLine("Usage Driver <stress-run-duration>");
3738
return 1;
3839
}
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+
}
3947
}
4048

4149
// This write is required for the benchmarking infrastructure.
4250
Console.WriteLine("Application started.");
4351

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);
4853
using var testApp = StartTestApp();
4954
using var benchmarkReceiver = StartBenchmarkResultReceiver();
50-
5155
var testAppUrl = GetListeningUrl(testApp);
5256
var receiverUrl = GetListeningUrl(benchmarkReceiver);
53-
5457
Console.WriteLine($"Test app listening at {testAppUrl}.");
5558

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+
}
5978

60-
FormatAsBenchmarksOutput(benchmarkResult.Task.Result);
79+
var results = await BenchmarkResultTask.Task;
80+
FormatAsBenchmarksOutput(results, includeStressRunDelimiter: !stressRunCancellation.IsCancellationRequested);
81+
} while (!stressRunCancellation.IsCancellationRequested);
6182

6283
Console.WriteLine("Done executing benchmark");
6384
return 0;
6485
}
6586

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)
7288
{
7389
// Sample of the the format: https://github.com/aspnet/Benchmarks/blob/e55f9e0312a7dd019d1268c1a547d1863f0c7237/src/Benchmarks/Program.cs#L51-L67
7490
var output = new BenchmarkOutput();
@@ -126,6 +142,15 @@ private static void FormatAsBenchmarksOutput(BenchmarkResult benchmarkResult)
126142
});
127143
}
128144

145+
if (includeStressRunDelimiter)
146+
{
147+
output.Measurements.Add(new BenchmarkMeasurement
148+
{
149+
Timestamp = DateTime.UtcNow,
150+
Name = "$$Delimiter$$",
151+
});
152+
}
153+
129154
Console.WriteLine("#StartJobStatistics");
130155
Console.WriteLine(JsonSerializer.Serialize(output));
131156
Console.WriteLine("#EndJobStatistics");
@@ -184,9 +209,9 @@ static void RunInBackgroundThread(Action action)
184209
isDone.Set();
185210
});
186211

187-
if (!isDone.WaitOne(Timeout))
212+
if (!isDone.WaitOne(TimeSpan.FromSeconds(30)))
188213
{
189-
throw new TimeoutException("Timed out waiting for: " + action);
214+
throw new TimeoutException("Timed out waiting to start the host");
190215
}
191216

192217
if (edi != null)

src/Components/benchmarkapps/Wasm.Performance/Driver/Selenium.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -15,6 +15,7 @@ namespace Wasm.Performance.Driver
1515
{
1616
class Selenium
1717
{
18+
const int SeleniumPort = 4444;
1819
static bool RunHeadlessBrowser = true;
1920
static bool PoolForBrowserLogs = true;
2021

@@ -55,9 +56,9 @@ private static async ValueTask<Uri> WaitForServerAsync(int port, CancellationTok
5556
throw new Exception($"Unable to connect to selenium-server at {uri}");
5657
}
5758

58-
public static async Task<RemoteWebDriver> CreateBrowser(int port, CancellationToken cancellationToken)
59+
public static async Task<RemoteWebDriver> CreateBrowser(CancellationToken cancellationToken)
5960
{
60-
var uri = await WaitForServerAsync(port, cancellationToken);
61+
var uri = await WaitForServerAsync(SeleniumPort, cancellationToken);
6162

6263
var options = new ChromeOptions();
6364

src/Components/benchmarkapps/Wasm.Performance/dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
22

3+
ENV StressRunDuration=0
34
ARG DEBIAN_FRONTEND=noninteractive
45

56
# Setup for nodejs
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
22

33
/opt/bin/start-selenium-standalone.sh&
4-
./Wasm.Performance.Driver
4+
./Wasm.Performance.Driver $StressRunDuration
55

src/Components/benchmarkapps/Wasm.Performance/local.dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
FROM selenium/standalone-chrome:3.141.59-mercury as final
22

3+
ENV StressRunDuration=0
4+
35
WORKDIR /app
46
COPY ./Driver/bin/Release/netcoreapp3.1/linux-x64/publish ./
57
COPY ./exec.sh ./

0 commit comments

Comments
 (0)