Skip to content

Commit

Permalink
Perf Framework (Azure#16671)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeharder authored Nov 7, 2020
1 parent 588a8c6 commit a42b92d
Show file tree
Hide file tree
Showing 34 changed files with 1,396 additions and 11 deletions.
12 changes: 12 additions & 0 deletions common/Perf/Azure.Sample.Perf/Azure.Sample.Perf.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Azure.Test.Perf\Azure.Test.Perf.csproj" />
<Reference Include="System.Net.Http" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
</ItemGroup>

</Project>
52 changes: 52 additions & 0 deletions common/Perf/Azure.Sample.Perf/DelayTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Test.Perf;
using CommandLine;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Azure.Sample.Perf
{
public class DelayTest : PerfTest<DelayTest.DelayOptions>
{
private static int _instanceCount = 0;
private TimeSpan _delay;

public DelayTest(DelayTest.DelayOptions options) : base(options)
{
var instanceCount = Interlocked.Increment(ref _instanceCount) - 1;

_delay = TimeSpan.FromMilliseconds(options.InitialDelayMs * Math.Pow(options.InstanceGrowthFactor, instanceCount));
}

public override void Run(CancellationToken cancellationToken)
{
Thread.Sleep(_delay);
_delay = TimeSpan.FromMilliseconds(_delay.TotalMilliseconds * Options.IterationGrowthFactor);
}

public override async Task RunAsync(CancellationToken cancellationToken)
{
await Task.Delay(_delay, cancellationToken);
_delay = TimeSpan.FromMilliseconds(_delay.TotalMilliseconds * Options.IterationGrowthFactor);
}

public class DelayOptions : PerfOptions
{
[Option("initialDelayMs", Default = 1000, HelpText = "Initial delay (in milliseconds)")]
public int InitialDelayMs { get; set; }

// Used for verifying the perf framework correctly computes average throughput across parallel tests of different speed.
// Each instance of this test completes operations at a different rate, to allow for testing scenarios where
// some instances are still waiting when time expires. The first instance completes in 1 second per operation,
// the second instance in 2 seconds, the third instance in 4 seconds, and so on.
[Option("instanceGrowthFactor", Default = 1, HelpText = "Instance growth factor. The delay of instance N will be (InitialDelayMS * (InstanceGrowthFactor ^ InstanceCount)).")]
public double InstanceGrowthFactor { get; set; }

[Option("iterationGrowthFactor", Default = 1, HelpText = "Iteration growth factor. The delay of iteration N will be (InitialDelayMS * (IterationGrowthFactor ^ IterationCount)).")]
public double IterationGrowthFactor { get; set; }
}
}
}
39 changes: 39 additions & 0 deletions common/Perf/Azure.Sample.Perf/DisposeTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Test.Perf;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Azure.Sample.Perf
{
// Used to verify framework calls DisposeAsync()
public class DisposeTest : PerfTest<PerfOptions>
{
public DisposeTest(PerfOptions options) : base(options)
{
}

public override void Run(CancellationToken cancellationToken)
{
}

public override Task RunAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public override void Dispose(bool disposing)
{
Console.WriteLine($"Dispose({disposing})");
base.Dispose(disposing);
}

public override ValueTask DisposeAsyncCore()
{
Console.WriteLine("DisposeAsyncCore()");
return base.DisposeAsyncCore();
}
}
}
42 changes: 42 additions & 0 deletions common/Perf/Azure.Sample.Perf/ExceptionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Test.Perf;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Azure.Sample.Perf
{
// Measures the overhead of creating, throwing, and catching an exception (compared to NoOpTest)
public class ExceptionTest : PerfTest<PerfOptions>
{
public ExceptionTest(PerfOptions options) : base(options)
{
}

public override void Run(CancellationToken cancellationToken)
{
try
{
throw new InvalidOperationException();
}
catch
{
}
}

public override Task RunAsync(CancellationToken cancellationToken)
{
try
{
throw new InvalidOperationException();
}
catch
{
}

return Task.CompletedTask;
}
}
}
52 changes: 52 additions & 0 deletions common/Perf/Azure.Sample.Perf/HttpClientGetTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Test.Perf;
using CommandLine;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Azure.Sample.Perf
{
public class HttpClientGetTest : PerfTest<HttpClientGetTest.HttpClientGetOptions>
{
private static HttpClient _httpClient;

public HttpClientGetTest(HttpClientGetOptions options) : base(options)
{
}

public override Task GlobalSetupAsync()
{
if (Options.Insecure)
{
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
_httpClient = new HttpClient(httpClientHandler);
}
else
{
_httpClient = new HttpClient();
}

return Task.CompletedTask;
}

public override void Run(CancellationToken cancellationToken)
{
_httpClient.GetStringAsync(Options.Url).Wait();
}

public override async Task RunAsync(CancellationToken cancellationToken)
{
await _httpClient.GetStringAsync(Options.Url);
}

public class HttpClientGetOptions : PerfOptions
{
[Option('u', "url", Required = true)]
public string Url { get; set; }
}
}
}
26 changes: 26 additions & 0 deletions common/Perf/Azure.Sample.Perf/NoOpTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Test.Perf;
using System.Threading;
using System.Threading.Tasks;

namespace Azure.Sample.Perf
{
// Used for measuring the overhead of the perf framework with the fastest possible test
public class NoOpTest : PerfTest<PerfOptions>
{
public NoOpTest(PerfOptions options) : base(options)
{
}

public override void Run(CancellationToken cancellationToken)
{
}

public override Task RunAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}
16 changes: 16 additions & 0 deletions common/Perf/Azure.Sample.Perf/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Test.Perf;
using System.Threading.Tasks;

namespace Azure.Sample.Perf
{
public class Program
{
public static async Task Main(string[] args)
{
await PerfProgram.Main(typeof(Program).Assembly, args);
}
}
}
34 changes: 34 additions & 0 deletions common/Perf/Azure.Sample.Perf/TimerRunTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Test.Perf;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;

namespace Azure.Sample.Perf
{
public class TimerRunTest : PerfTest<PerfOptions>
{
private readonly SemaphoreSlim _semaphoreSlim;

private readonly Timer _timer;

public TimerRunTest(PerfOptions options) : base(options)
{
_semaphoreSlim = new SemaphoreSlim(0);
_timer = new Timer(_ => _semaphoreSlim.Release(), state: null, dueTime: TimeSpan.FromSeconds(1), period: TimeSpan.FromSeconds(1));
}

public override void Run(CancellationToken cancellationToken)
{
_semaphoreSlim.Wait();
}

public override Task RunAsync(CancellationToken cancellationToken)
{
return _semaphoreSlim.WaitAsync();
}
}
}
79 changes: 79 additions & 0 deletions common/Perf/Azure.Test.Perf.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30621.155
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Test.Perf", "Azure.Test.Perf\Azure.Test.Perf.csproj", "{B868679E-AD3C-4367-935A-D290F163DA20}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sample.Perf", "Azure.Sample.Perf\Azure.Sample.Perf.csproj", "{24568380-3D5D-4068-A7E9-4C5C2730D3E8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template.Perf", "..\..\sdk\template\Azure.Template\perf\Azure.Template.Perf.csproj", "{4A3CADC3-8B42-462B-8135-AEBA5487BE18}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template", "..\..\sdk\template\Azure.Template\src\Azure.Template.csproj", "{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x64.ActiveCfg = Debug|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x64.Build.0 = Debug|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x86.ActiveCfg = Debug|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Debug|x86.Build.0 = Debug|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|Any CPU.Build.0 = Release|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x64.ActiveCfg = Release|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x64.Build.0 = Release|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x86.ActiveCfg = Release|Any CPU
{B868679E-AD3C-4367-935A-D290F163DA20}.Release|x86.Build.0 = Release|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x64.ActiveCfg = Debug|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x64.Build.0 = Debug|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x86.ActiveCfg = Debug|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Debug|x86.Build.0 = Debug|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|Any CPU.Build.0 = Release|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x64.ActiveCfg = Release|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x64.Build.0 = Release|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x86.ActiveCfg = Release|Any CPU
{24568380-3D5D-4068-A7E9-4C5C2730D3E8}.Release|x86.Build.0 = Release|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x64.ActiveCfg = Debug|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x64.Build.0 = Debug|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x86.ActiveCfg = Debug|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Debug|x86.Build.0 = Debug|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|Any CPU.Build.0 = Release|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x64.ActiveCfg = Release|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x64.Build.0 = Release|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x86.ActiveCfg = Release|Any CPU
{4A3CADC3-8B42-462B-8135-AEBA5487BE18}.Release|x86.Build.0 = Release|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x64.ActiveCfg = Debug|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x64.Build.0 = Debug|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x86.ActiveCfg = Debug|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Debug|x86.Build.0 = Debug|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|Any CPU.Build.0 = Release|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x64.ActiveCfg = Release|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x64.Build.0 = Release|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x86.ActiveCfg = Release|Any CPU
{02BFED5E-F4AE-471F-8B02-764E3D5FF5DC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C874CFF4-58D8-4152-8B2C-36E96A07D974}
EndGlobalSection
EndGlobal
11 changes: 11 additions & 0 deletions common/Perf/Azure.Test.Perf/Azure.Test.Perf.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="Azure.Core" />
<PackageReference Include="CommandLineParser" />
<PackageReference Include="System.Reflection.Emit" />
<PackageReference Include="System.Threading.Channels" />
<Reference Include="System.Net.Http" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions common/Perf/Azure.Test.Perf/BenchmarkMeasurement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.Test.Perf
{
internal class BenchmarkMeasurement
{
public DateTime Timestamp { get; internal set; }
public string Name { get; internal set; }
public object Value { get; internal set; }
}
}
Loading

0 comments on commit a42b92d

Please sign in to comment.