Skip to content

Commit a42b92d

Browse files
authored
Perf Framework (Azure#16671)
1 parent 588a8c6 commit a42b92d

34 files changed

+1396
-11
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<ProjectReference Include="..\Azure.Test.Perf\Azure.Test.Perf.csproj" />
9+
<Reference Include="System.Net.Http" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Test.Perf;
5+
using CommandLine;
6+
using System;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
10+
namespace Azure.Sample.Perf
11+
{
12+
public class DelayTest : PerfTest<DelayTest.DelayOptions>
13+
{
14+
private static int _instanceCount = 0;
15+
private TimeSpan _delay;
16+
17+
public DelayTest(DelayTest.DelayOptions options) : base(options)
18+
{
19+
var instanceCount = Interlocked.Increment(ref _instanceCount) - 1;
20+
21+
_delay = TimeSpan.FromMilliseconds(options.InitialDelayMs * Math.Pow(options.InstanceGrowthFactor, instanceCount));
22+
}
23+
24+
public override void Run(CancellationToken cancellationToken)
25+
{
26+
Thread.Sleep(_delay);
27+
_delay = TimeSpan.FromMilliseconds(_delay.TotalMilliseconds * Options.IterationGrowthFactor);
28+
}
29+
30+
public override async Task RunAsync(CancellationToken cancellationToken)
31+
{
32+
await Task.Delay(_delay, cancellationToken);
33+
_delay = TimeSpan.FromMilliseconds(_delay.TotalMilliseconds * Options.IterationGrowthFactor);
34+
}
35+
36+
public class DelayOptions : PerfOptions
37+
{
38+
[Option("initialDelayMs", Default = 1000, HelpText = "Initial delay (in milliseconds)")]
39+
public int InitialDelayMs { get; set; }
40+
41+
// Used for verifying the perf framework correctly computes average throughput across parallel tests of different speed.
42+
// Each instance of this test completes operations at a different rate, to allow for testing scenarios where
43+
// some instances are still waiting when time expires. The first instance completes in 1 second per operation,
44+
// the second instance in 2 seconds, the third instance in 4 seconds, and so on.
45+
[Option("instanceGrowthFactor", Default = 1, HelpText = "Instance growth factor. The delay of instance N will be (InitialDelayMS * (InstanceGrowthFactor ^ InstanceCount)).")]
46+
public double InstanceGrowthFactor { get; set; }
47+
48+
[Option("iterationGrowthFactor", Default = 1, HelpText = "Iteration growth factor. The delay of iteration N will be (InitialDelayMS * (IterationGrowthFactor ^ IterationCount)).")]
49+
public double IterationGrowthFactor { get; set; }
50+
}
51+
}
52+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Test.Perf;
5+
using System;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace Azure.Sample.Perf
10+
{
11+
// Used to verify framework calls DisposeAsync()
12+
public class DisposeTest : PerfTest<PerfOptions>
13+
{
14+
public DisposeTest(PerfOptions options) : base(options)
15+
{
16+
}
17+
18+
public override void Run(CancellationToken cancellationToken)
19+
{
20+
}
21+
22+
public override Task RunAsync(CancellationToken cancellationToken)
23+
{
24+
return Task.CompletedTask;
25+
}
26+
27+
public override void Dispose(bool disposing)
28+
{
29+
Console.WriteLine($"Dispose({disposing})");
30+
base.Dispose(disposing);
31+
}
32+
33+
public override ValueTask DisposeAsyncCore()
34+
{
35+
Console.WriteLine("DisposeAsyncCore()");
36+
return base.DisposeAsyncCore();
37+
}
38+
}
39+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Test.Perf;
5+
using System;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace Azure.Sample.Perf
10+
{
11+
// Measures the overhead of creating, throwing, and catching an exception (compared to NoOpTest)
12+
public class ExceptionTest : PerfTest<PerfOptions>
13+
{
14+
public ExceptionTest(PerfOptions options) : base(options)
15+
{
16+
}
17+
18+
public override void Run(CancellationToken cancellationToken)
19+
{
20+
try
21+
{
22+
throw new InvalidOperationException();
23+
}
24+
catch
25+
{
26+
}
27+
}
28+
29+
public override Task RunAsync(CancellationToken cancellationToken)
30+
{
31+
try
32+
{
33+
throw new InvalidOperationException();
34+
}
35+
catch
36+
{
37+
}
38+
39+
return Task.CompletedTask;
40+
}
41+
}
42+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Test.Perf;
5+
using CommandLine;
6+
using System.Net.Http;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
10+
namespace Azure.Sample.Perf
11+
{
12+
public class HttpClientGetTest : PerfTest<HttpClientGetTest.HttpClientGetOptions>
13+
{
14+
private static HttpClient _httpClient;
15+
16+
public HttpClientGetTest(HttpClientGetOptions options) : base(options)
17+
{
18+
}
19+
20+
public override Task GlobalSetupAsync()
21+
{
22+
if (Options.Insecure)
23+
{
24+
var httpClientHandler = new HttpClientHandler();
25+
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
26+
_httpClient = new HttpClient(httpClientHandler);
27+
}
28+
else
29+
{
30+
_httpClient = new HttpClient();
31+
}
32+
33+
return Task.CompletedTask;
34+
}
35+
36+
public override void Run(CancellationToken cancellationToken)
37+
{
38+
_httpClient.GetStringAsync(Options.Url).Wait();
39+
}
40+
41+
public override async Task RunAsync(CancellationToken cancellationToken)
42+
{
43+
await _httpClient.GetStringAsync(Options.Url);
44+
}
45+
46+
public class HttpClientGetOptions : PerfOptions
47+
{
48+
[Option('u', "url", Required = true)]
49+
public string Url { get; set; }
50+
}
51+
}
52+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Test.Perf;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace Azure.Sample.Perf
9+
{
10+
// Used for measuring the overhead of the perf framework with the fastest possible test
11+
public class NoOpTest : PerfTest<PerfOptions>
12+
{
13+
public NoOpTest(PerfOptions options) : base(options)
14+
{
15+
}
16+
17+
public override void Run(CancellationToken cancellationToken)
18+
{
19+
}
20+
21+
public override Task RunAsync(CancellationToken cancellationToken)
22+
{
23+
return Task.CompletedTask;
24+
}
25+
}
26+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Test.Perf;
5+
using System.Threading.Tasks;
6+
7+
namespace Azure.Sample.Perf
8+
{
9+
public class Program
10+
{
11+
public static async Task Main(string[] args)
12+
{
13+
await PerfProgram.Main(typeof(Program).Assembly, args);
14+
}
15+
}
16+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Test.Perf;
5+
using System;
6+
using System.Diagnostics.CodeAnalysis;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
10+
namespace Azure.Sample.Perf
11+
{
12+
public class TimerRunTest : PerfTest<PerfOptions>
13+
{
14+
private readonly SemaphoreSlim _semaphoreSlim;
15+
16+
private readonly Timer _timer;
17+
18+
public TimerRunTest(PerfOptions options) : base(options)
19+
{
20+
_semaphoreSlim = new SemaphoreSlim(0);
21+
_timer = new Timer(_ => _semaphoreSlim.Release(), state: null, dueTime: TimeSpan.FromSeconds(1), period: TimeSpan.FromSeconds(1));
22+
}
23+
24+
public override void Run(CancellationToken cancellationToken)
25+
{
26+
_semaphoreSlim.Wait();
27+
}
28+
29+
public override Task RunAsync(CancellationToken cancellationToken)
30+
{
31+
return _semaphoreSlim.WaitAsync();
32+
}
33+
}
34+
}

common/Perf/Azure.Test.Perf.sln

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.30621.155
5+
MinimumVisualStudioVersion = 15.0.26124.0
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Test.Perf", "Azure.Test.Perf\Azure.Test.Perf.csproj", "{B868679E-AD3C-4367-935A-D290F163DA20}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sample.Perf", "Azure.Sample.Perf\Azure.Sample.Perf.csproj", "{24568380-3D5D-4068-A7E9-4C5C2730D3E8}"
9+
EndProject
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template.Perf", "..\..\sdk\template\Azure.Template\perf\Azure.Template.Perf.csproj", "{4A3CADC3-8B42-462B-8135-AEBA5487BE18}"
11+
EndProject
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template", "..\..\sdk\template\Azure.Template\src\Azure.Template.csproj", "{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}"
13+
EndProject
14+
Global
15+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
16+
Debug|Any CPU = Debug|Any CPU
17+
Debug|x64 = Debug|x64
18+
Debug|x86 = Debug|x86
19+
Release|Any CPU = Release|Any CPU
20+
Release|x64 = Release|x64
21+
Release|x86 = Release|x86
22+
EndGlobalSection
23+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
24+
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25+
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|Any CPU.Build.0 = Debug|Any CPU
26+
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x64.ActiveCfg = Debug|Any CPU
27+
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x64.Build.0 = Debug|Any CPU
28+
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x86.ActiveCfg = Debug|Any CPU
29+
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x86.Build.0 = Debug|Any CPU
30+
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|Any CPU.ActiveCfg = Release|Any CPU
31+
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|Any CPU.Build.0 = Release|Any CPU
32+
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x64.ActiveCfg = Release|Any CPU
33+
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x64.Build.0 = Release|Any CPU
34+
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x86.ActiveCfg = Release|Any CPU
35+
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x86.Build.0 = Release|Any CPU
36+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
38+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x64.ActiveCfg = Debug|Any CPU
39+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x64.Build.0 = Debug|Any CPU
40+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x86.ActiveCfg = Debug|Any CPU
41+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x86.Build.0 = Debug|Any CPU
42+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|Any CPU.Build.0 = Release|Any CPU
44+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x64.ActiveCfg = Release|Any CPU
45+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x64.Build.0 = Release|Any CPU
46+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x86.ActiveCfg = Release|Any CPU
47+
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x86.Build.0 = Release|Any CPU
48+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x64.ActiveCfg = Debug|Any CPU
51+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x64.Build.0 = Debug|Any CPU
52+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x86.ActiveCfg = Debug|Any CPU
53+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x86.Build.0 = Debug|Any CPU
54+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|Any CPU.ActiveCfg = Release|Any CPU
55+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x64.ActiveCfg = Release|Any CPU
57+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x64.Build.0 = Release|Any CPU
58+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x86.ActiveCfg = Release|Any CPU
59+
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x86.Build.0 = Release|Any CPU
60+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x64.ActiveCfg = Debug|Any CPU
63+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x64.Build.0 = Debug|Any CPU
64+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x86.ActiveCfg = Debug|Any CPU
65+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x86.Build.0 = Debug|Any CPU
66+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x64.ActiveCfg = Release|Any CPU
69+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x64.Build.0 = Release|Any CPU
70+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x86.ActiveCfg = Release|Any CPU
71+
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x86.Build.0 = Release|Any CPU
72+
EndGlobalSection
73+
GlobalSection(SolutionProperties) = preSolution
74+
HideSolutionNode = FALSE
75+
EndGlobalSection
76+
GlobalSection(ExtensibilityGlobals) = postSolution
77+
SolutionGuid = {C874CFF4-58D8-4152-8B2C-36E96A07D974}
78+
EndGlobalSection
79+
EndGlobal
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<ItemGroup>
4+
<PackageReference Include="Azure.Core" />
5+
<PackageReference Include="CommandLineParser" />
6+
<PackageReference Include="System.Reflection.Emit" />
7+
<PackageReference Include="System.Threading.Channels" />
8+
<Reference Include="System.Net.Http" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
9+
</ItemGroup>
10+
11+
</Project>

0 commit comments

Comments
 (0)