diff --git a/common/Perf/Azure.Test.Perf/PerfOptions.cs b/common/Perf/Azure.Test.Perf/PerfOptions.cs index dae55b1b3523..34994cd64880 100644 --- a/common/Perf/Azure.Test.Perf/PerfOptions.cs +++ b/common/Perf/Azure.Test.Perf/PerfOptions.cs @@ -3,6 +3,7 @@ using CommandLine; using System; +using System.Collections.Generic; namespace Azure.Test.Perf { @@ -50,8 +51,8 @@ public class PerfOptions [Option("sync", HelpText = "Runs sync version of test")] public bool Sync { get; set; } - [Option('x', "test-proxy", HelpText = "URI of TestProxy Server")] - public Uri TestProxy { get; set; } + [Option('x', "test-proxies", Separator = ';', HelpText = "URIs of TestProxy Servers (separated by ';')")] + public IEnumerable TestProxies { get; set; } [Option('w', "warmup", Default = 5, HelpText = "Duration of warmup in seconds")] public int Warmup { get; set; } diff --git a/common/Perf/Azure.Test.Perf/PerfProgram.cs b/common/Perf/Azure.Test.Perf/PerfProgram.cs index d04e3aca352f..1433830c2618 100644 --- a/common/Perf/Azure.Test.Perf/PerfProgram.cs +++ b/common/Perf/Azure.Test.Perf/PerfProgram.cs @@ -113,7 +113,7 @@ private static async Task Run(Type testType, PerfOptions options) setupStatusCts.Cancel(); setupStatusThread.Join(); - if (options.TestProxy != null) + if (options.TestProxies != null && options.TestProxies.Any()) { using var recordStatusCts = new CancellationTokenSource(); var recordStatusThread = PerfStressUtilities.PrintStatus("=== Record and Start Playback ===", () => ".", newLine: false, recordStatusCts.Token); diff --git a/common/Perf/Azure.Test.Perf/PerfTest.cs b/common/Perf/Azure.Test.Perf/PerfTest.cs index 0fe2f603952b..6376189019cc 100644 --- a/common/Perf/Azure.Test.Perf/PerfTest.cs +++ b/common/Perf/Azure.Test.Perf/PerfTest.cs @@ -17,15 +17,20 @@ public abstract class PerfTest : IPerfTest where TOptions : PerfOption private readonly HttpPipelineTransport _insecureTransport; private readonly HttpClient _recordPlaybackHttpClient; + private readonly Uri _testProxy; private readonly TestProxyPolicy _testProxyPolicy; private string _recordingId; protected TOptions Options { get; private set; } + private static int _globalParallelIndex; + protected int ParallelIndex { get; } + public PerfTest(TOptions options) { Options = options; + ParallelIndex = Interlocked.Increment(ref _globalParallelIndex) - 1; if (Options.Insecure) { @@ -48,7 +53,7 @@ public PerfTest(TOptions options) } } - if (Options.TestProxy != null) + if (Options.TestProxies != null && Options.TestProxies.Any()) { if (Options.Insecure) { @@ -62,7 +67,8 @@ public PerfTest(TOptions options) _recordPlaybackHttpClient = new HttpClient(); } - _testProxyPolicy = new TestProxyPolicy(Options.TestProxy); + _testProxy = Options.TestProxies.ElementAt(ParallelIndex % Options.TestProxies.Count()); + _testProxyPolicy = new TestProxyPolicy(_testProxy); } } @@ -125,7 +131,7 @@ public async Task RecordAndStartPlayback() public async Task StopPlayback() { - var message = new HttpRequestMessage(HttpMethod.Post, new Uri(Options.TestProxy, "/playback/stop")); + var message = new HttpRequestMessage(HttpMethod.Post, new Uri(_testProxy, "/playback/stop")); message.Headers.Add("x-recording-id", _recordingId); message.Headers.Add("x-purge-inmemory-recording", bool.TrueString); @@ -182,7 +188,7 @@ protected static string GetEnvironmentVariable(string name) private async Task StartRecording() { - var message = new HttpRequestMessage(HttpMethod.Post, new Uri(Options.TestProxy, "/record/start")); + var message = new HttpRequestMessage(HttpMethod.Post, new Uri(_testProxy, "/record/start")); var response = await _recordPlaybackHttpClient.SendAsync(message); _recordingId = response.Headers.GetValues("x-recording-id").Single(); @@ -190,7 +196,7 @@ private async Task StartRecording() private async Task StopRecording() { - var message = new HttpRequestMessage(HttpMethod.Post, new Uri(Options.TestProxy, "/record/stop")); + var message = new HttpRequestMessage(HttpMethod.Post, new Uri(_testProxy, "/record/stop")); message.Headers.Add("x-recording-id", _recordingId); await _recordPlaybackHttpClient.SendAsync(message); @@ -198,7 +204,7 @@ private async Task StopRecording() private async Task StartPlayback() { - var message = new HttpRequestMessage(HttpMethod.Post, new Uri(Options.TestProxy, "/playback/start")); + var message = new HttpRequestMessage(HttpMethod.Post, new Uri(_testProxy, "/playback/start")); message.Headers.Add("x-recording-id", _recordingId); var response = await _recordPlaybackHttpClient.SendAsync(message);