-
Notifications
You must be signed in to change notification settings - Fork 500
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Client encryption]: Add baseline benchmarks for `Microsoft.Azure.Cos…
…mos.Encryption.Custom` (#4679) # Pull Request Template ## Description Adding a `Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests` with `Encrypt`/`Decrypt` benchmarks for different document size. Attaching also initial baseline report with the current memory allocations. ## Type of change Please delete options that are not relevant. - [x] New feature (non-breaking change which adds functionality) ## Closing issues Contributes to #4678 --------- Co-authored-by: Santosh Kulkarni <[email protected]> Co-authored-by: Kiran Kumar Kolli <[email protected]>
- Loading branch information
1 parent
c6d907c
commit a883414
Showing
10 changed files
with
266 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
...m/tests/Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests/EncryptionBenchmark.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
namespace Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests | ||
{ | ||
using System.IO; | ||
using BenchmarkDotNet.Attributes; | ||
using Microsoft.Data.Encryption.Cryptography; | ||
using Moq; | ||
|
||
[RPlotExporter] | ||
public partial class EncryptionBenchmark | ||
{ | ||
private static readonly byte[] DekData = Enumerable.Repeat((byte)0, 32).ToArray(); | ||
private static readonly DataEncryptionKeyProperties DekProperties = new( | ||
"id", | ||
CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, | ||
DekData, | ||
new EncryptionKeyWrapMetadata("name", "value"), DateTime.UtcNow); | ||
private static readonly Mock<EncryptionKeyStoreProvider> StoreProvider = new(); | ||
|
||
private CosmosEncryptor? encryptor; | ||
|
||
private EncryptionOptions? encryptionOptions; | ||
private byte[]? encryptedData; | ||
private byte[]? plaintext; | ||
|
||
[Params(1, 10, 100)] | ||
public int DocumentSizeInKb { get; set; } | ||
|
||
[GlobalSetup] | ||
public async Task Setup() | ||
{ | ||
StoreProvider | ||
.Setup(x => x.UnwrapKey(It.IsAny<string>(), It.IsAny<KeyEncryptionKeyAlgorithm>(), It.IsAny<byte[]>())) | ||
.Returns(DekData); | ||
|
||
Mock<DataEncryptionKeyProvider> keyProvider = new(); | ||
keyProvider | ||
.Setup(x => x.FetchDataEncryptionKeyWithoutRawKeyAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(() => new MdeEncryptionAlgorithm(DekProperties, EncryptionType.Randomized, StoreProvider.Object, cacheTimeToLive: TimeSpan.MaxValue)); | ||
|
||
this.encryptor = new(keyProvider.Object); | ||
this.encryptionOptions = CreateEncryptionOptions(); | ||
this.plaintext = this.LoadTestDoc(); | ||
|
||
Stream encryptedStream = await EncryptionProcessor.EncryptAsync( | ||
new MemoryStream(this.plaintext), | ||
this.encryptor, | ||
this.encryptionOptions, | ||
new CosmosDiagnosticsContext(), | ||
CancellationToken.None); | ||
|
||
using MemoryStream memoryStream = new MemoryStream(); | ||
encryptedStream.CopyTo(memoryStream); | ||
this.encryptedData = memoryStream.ToArray(); | ||
} | ||
|
||
[Benchmark] | ||
public async Task Encrypt() | ||
{ | ||
await EncryptionProcessor.EncryptAsync( | ||
new MemoryStream(this.plaintext!), | ||
this.encryptor, | ||
this.encryptionOptions, | ||
new CosmosDiagnosticsContext(), | ||
CancellationToken.None); | ||
} | ||
|
||
[Benchmark] | ||
public async Task Decrypt() | ||
{ | ||
await EncryptionProcessor.DecryptAsync( | ||
new MemoryStream(this.encryptedData!), | ||
this.encryptor, | ||
new CosmosDiagnosticsContext(), | ||
CancellationToken.None); | ||
} | ||
|
||
private static EncryptionOptions CreateEncryptionOptions() | ||
{ | ||
EncryptionOptions options = new() | ||
{ | ||
DataEncryptionKeyId = "dekId", | ||
EncryptionAlgorithm = CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, | ||
PathsToEncrypt = TestDoc.PathsToEncrypt | ||
}; | ||
|
||
return options; | ||
} | ||
|
||
private byte[] LoadTestDoc() | ||
{ | ||
string name = $"Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests.sampledata.testdoc-{this.DocumentSizeInKb}kb.json"; | ||
using Stream resourceStream = typeof(EncryptionBenchmark).Assembly.GetManifestResourceStream(name)!; | ||
|
||
byte[] buffer = new byte[resourceStream!.Length]; | ||
resourceStream.Read(buffer, 0, buffer.Length); | ||
|
||
return buffer; | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...ustom.Performance.Tests/Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<AssemblyName>Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests</AssemblyName> | ||
<OutputType>Exe</OutputType> | ||
<TargetFrameworks>net6</TargetFrameworks> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<EmbeddedResource Include="sampledata\testdoc-100kb.json" /> | ||
<EmbeddedResource Include="sampledata\testdoc-10kb.json" /> | ||
<EmbeddedResource Include="sampledata\testdoc-1kb.json" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="BenchmarkDotNet" Version="0.13.3" /> | ||
<PackageReference Include="Moq" Version="4.13.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Microsoft.Azure.Cosmos.Encryption.Custom.csproj" /> | ||
</ItemGroup> | ||
|
||
<PropertyGroup> | ||
<SignAssembly>true</SignAssembly> | ||
<DelaySign>true</DelaySign> | ||
<AssemblyOriginatorKeyFile>..\..\..\testkey.snk</AssemblyOriginatorKeyFile> | ||
</PropertyGroup> | ||
|
||
</Project> |
21 changes: 21 additions & 0 deletions
21
...yption.Custom/tests/Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests | ||
{ | ||
using BenchmarkDotNet.Configs; | ||
using BenchmarkDotNet.Diagnosers; | ||
using BenchmarkDotNet.Jobs; | ||
using BenchmarkDotNet.Running; | ||
using BenchmarkDotNet.Toolchains.InProcess.Emit; | ||
|
||
internal class Program | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
ManualConfig dontRequireSlnToRunBenchmarks = ManualConfig | ||
.Create(DefaultConfig.Instance) | ||
.AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance)) | ||
.AddDiagnoser(MemoryDiagnoser.Default); | ||
|
||
BenchmarkRunner.Run<EncryptionBenchmark>(dontRequireSlnToRunBenchmarks, args); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...stom/tests/Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests/Readme.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
``` ini | ||
|
||
BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22631.4169) | ||
11th Gen Intel Core i9-11950H 2.60GHz, 1 CPU, 16 logical and 8 physical cores | ||
.NET SDK=9.0.100-rc.1.24452.12 | ||
[Host] : .NET 6.0.33 (6.0.3324.36610), X64 RyuJIT AVX2 | ||
|
||
Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15 | ||
LaunchCount=2 WarmupCount=10 | ||
|
||
``` | ||
| Method | DocumentSizeInKb | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | | ||
|-------- |----------------- |------------:|-----------:|-----------:|---------:|---------:|---------:|-----------:| | ||
| **Encrypt** | **1** | **61.45 μs** | **1.676 μs** | **2.457 μs** | **4.9438** | **1.2207** | **-** | **61.25 KB** | | ||
| Decrypt | 1 | 77.89 μs | 1.959 μs | 2.933 μs | 5.7373 | 1.4648 | - | 71.22 KB | | ||
| **Encrypt** | **10** | **171.64 μs** | **3.341 μs** | **4.791 μs** | **21.2402** | **3.6621** | **-** | **260.97 KB** | | ||
| Decrypt | 10 | 255.57 μs | 7.833 μs | 11.724 μs | 29.2969 | 4.3945 | - | 363.84 KB | | ||
| **Encrypt** | **100** | **2,601.33 μs** | **215.481 μs** | **322.522 μs** | **199.2188** | **125.0000** | **123.0469** | **2464.88 KB** | | ||
| Decrypt | 100 | 3,156.06 μs | 321.419 μs | 481.084 μs | 355.4688 | 300.7813 | 261.7188 | 3413.05 KB | |
62 changes: 62 additions & 0 deletions
62
...yption.Custom/tests/Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests/TestDoc.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
namespace Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests | ||
{ | ||
using System.Text; | ||
using Newtonsoft.Json; | ||
|
||
public partial class EncryptionBenchmark | ||
{ | ||
internal class TestDoc | ||
{ | ||
public static List<string> PathsToEncrypt { get; } = new List<string>() { "/SensitiveStr", "/SensitiveInt", "/SensitiveDict" }; | ||
|
||
[JsonProperty("id")] | ||
public string Id { get; set; } | ||
|
||
public string NonSensitive { get; set; } | ||
|
||
public string SensitiveStr { get; set; } | ||
|
||
public int SensitiveInt { get; set; } | ||
|
||
public Dictionary<string, string> SensitiveDict { get; set; } | ||
|
||
public TestDoc() | ||
{ | ||
} | ||
|
||
public static TestDoc Create(int approximateSize = -1) | ||
{ | ||
return new TestDoc() | ||
{ | ||
Id = Guid.NewGuid().ToString(), | ||
NonSensitive = Guid.NewGuid().ToString(), | ||
SensitiveStr = Guid.NewGuid().ToString(), | ||
SensitiveInt = new Random().Next(), | ||
SensitiveDict = GenerateBigDictionary(approximateSize), | ||
}; | ||
} | ||
|
||
private static Dictionary<string, string> GenerateBigDictionary(int approximateSize) | ||
{ | ||
const int stringSize = 100; | ||
int items = Math.Max(1, approximateSize / stringSize); | ||
|
||
return Enumerable.Range(1, items).ToDictionary(x => x.ToString(), y => GenerateRandomString(stringSize)); | ||
} | ||
|
||
private static string GenerateRandomString(int size) | ||
{ | ||
Random rnd = new Random(); | ||
const string characters = "abcdefghijklmnopqrstuvwxyz0123456789"; | ||
|
||
StringBuilder sb = new(); | ||
for (int i = 0; i < size; i++) | ||
{ | ||
sb.Append(characters[rnd.Next(0, characters.Length)]); | ||
} | ||
return sb.ToString(); | ||
} | ||
} | ||
|
||
} | ||
} |
1 change: 1 addition & 0 deletions
1
.../Microsoft.Azure.Cosmos.Encryption.Custom.Performance.Tests/sampledata/testdoc-100kb.json
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.