diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs
index 6d02c40f79..1c97503247 100644
--- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs
@@ -29,7 +29,21 @@ public class BenchmarkConfig
[Option('k', Required = true, HelpText = "Cosmos account master key")]
[JsonIgnore]
- public string Key { get; set; }
+ public string Key { get; set; }
+
+ [Option("isthinclientenabled", Required = false, HelpText = "ThinClient enabled")]
+ public string IsThinClientEnabledRaw { get; set; }
+ public bool IsThinClientEnabled => string.Equals(this.IsThinClientEnabledRaw, "true", StringComparison.OrdinalIgnoreCase);
+
+ [Option("isgatewaymodeenabled", Required = false, HelpText = "Gateway mode enabled")]
+ public string IsGatewayModeEnabledRaw { get; set; }
+ public bool IsGatewayModeEnabled => string.Equals(this.IsGatewayModeEnabledRaw, "true", StringComparison.OrdinalIgnoreCase);
+
+ [Option("isdirectmodeenabled", Required = false, HelpText = "Direct mode enabled")]
+ public string IsDirectModeEnabledRaw { get; set; }
+ public bool IsDirectModeEnabled => string.Equals(this.IsDirectModeEnabledRaw, "true", StringComparison.OrdinalIgnoreCase);
+
+
[Option(Required = false, HelpText = "Workload Name, it will override the workloadType value in published results")]
public string WorkloadName { get; set; }
@@ -209,7 +223,7 @@ private string GetUserAgentPrefix()
return this.WorkloadName ?? this.WorkloadType ?? BenchmarkConfig.UserAgentSuffix;
}
- internal Microsoft.Azure.Cosmos.CosmosClient CreateCosmosClient(string accountKey)
+ internal Microsoft.Azure.Cosmos.CosmosClient CreateCosmosClient()
{
// Overwrite the default timespan if configured
if(this.TelemetryScheduleInSec > 0)
@@ -222,7 +236,8 @@ internal Microsoft.Azure.Cosmos.CosmosClient CreateCosmosClient(string accountKe
ApplicationName = this.GetUserAgentPrefix(),
MaxRetryAttemptsOnRateLimitedRequests = 0,
MaxRequestsPerTcpConnection = this.MaxRequestsPerTcpConnection,
- MaxTcpConnectionsPerEndpoint = this.MaxTcpConnectionsPerEndpoint,
+ MaxTcpConnectionsPerEndpoint = this.MaxTcpConnectionsPerEndpoint,
+ ConnectionMode = (this.IsThinClientEnabled || this.IsGatewayModeEnabled) ? Microsoft.Azure.Cosmos.ConnectionMode.Gateway: Microsoft.Azure.Cosmos.ConnectionMode.Direct,
CosmosClientTelemetryOptions = new Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions()
{
DisableSendingMetricsToService = !this.EnableTelemetry,
@@ -239,11 +254,11 @@ internal Microsoft.Azure.Cosmos.CosmosClient CreateCosmosClient(string accountKe
if (!string.IsNullOrWhiteSpace(this.ConsistencyLevel))
{
clientOptions.ConsistencyLevel = (Microsoft.Azure.Cosmos.ConsistencyLevel)Enum.Parse(typeof(Microsoft.Azure.Cosmos.ConsistencyLevel), this.ConsistencyLevel, ignoreCase: true);
- }
+ }
return new Microsoft.Azure.Cosmos.CosmosClient(
this.EndPoint,
- accountKey,
+ this.Key,
clientOptions);
}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs
index fde9d5cd2c..598b12a071 100644
--- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs
@@ -34,7 +34,9 @@ public static async Task Main(string[] args)
{
try
{
- BenchmarkConfig config = BenchmarkConfig.From(args);
+ BenchmarkConfig config = BenchmarkConfig.From(args);
+ Environment.SetEnvironmentVariable("AZURE_COSMOS_THIN_CLIENT_ENABLED", config.IsThinClientEnabled.ToString());
+
await AddAzureInfoToRunSummary();
MeterProvider meterProvider = BuildMeterProvider(config);
@@ -70,7 +72,9 @@ public static async Task Main(string[] args)
Utility.TeeTraceInformation("Exception ocured:" + e.ToString());
}
finally
- {
+ {
+ Environment.SetEnvironmentVariable("AZURE_COSMOS_THIN_CLIENT_ENABLED", "False");
+
Utility.TeeTraceInformation($"{nameof(CosmosBenchmark)} completed successfully.");
if (Debugger.IsAttached)
{
@@ -142,9 +146,10 @@ private static async Task AddAzureInfoToRunSummary()
///
/// a Task object.
private async Task ExecuteAsync(BenchmarkConfig config)
- {
- // V3 SDK client initialization
- using (CosmosClient cosmosClient = config.CreateCosmosClient(config.Key))
+ {
+ // V3 SDK client initialization
+
+ using (CosmosClient cosmosClient = config.CreateCosmosClient())
{
Microsoft.Azure.Cosmos.Database database = cosmosClient.GetDatabase(config.Database);
if (config.CleanupOnStart)
@@ -219,8 +224,8 @@ private async Task ExecuteAsync(BenchmarkConfig config)
Utility.TeeTraceInformation("Publishing results");
runSummary.Diagnostics = CosmosDiagnosticsLogger.GetDiagnostics();
await this.PublishResults(
- config,
- runSummary,
+ config,
+ runSummary,
cosmosClient);
}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/RunSummary.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/RunSummary.cs
index 4f84322554..cf799cb97b 100644
--- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/RunSummary.cs
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/RunSummary.cs
@@ -28,7 +28,6 @@ public RunSummary(
public string Commit => this.BenchmarkConfig.CommitId;
public string CommitDate => this.BenchmarkConfig.CommitDate;
public string CommitTime => this.BenchmarkConfig.CommitTime;
-
public string Remarks { get; set; }
public string Date { get; }
public string Time { get; }
@@ -59,8 +58,7 @@ public RunSummary(
[JsonProperty]
public static string Location { get; set; }
[JsonProperty]
- public static JObject AzureVmInfo { get; set; }
-
+ public static JObject AzureVmInfo { get; set; }
public double Top10PercentAverageRps { get; set; }
public double Top20PercentAverageRps { get; set; }
public double Top30PercentAverageRps { get; set; }
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh
index 11ff4ebf8a..1dd0b1ae35 100644
--- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh
@@ -8,7 +8,7 @@ export PL=18
export ACCOUNT_ENDPOINT=
export ACCOUNT_KEY=
-#Loop forever
+# Loop forever
i=0
while :
do
@@ -16,6 +16,25 @@ do
pkill -f run.sh
git pull origin master
+ # Distribute workload between modes
+ mode=$((i % 3))
+ if [ $mode -eq 0 ]; then
+ echo "Running in THINCLIENT mode"
+ export THINCLIENT_ENABLED=true
+ export GATEWAYMODE_ENABLED=false
+ export DIRECTMODE_ENABLED=false
+ elif [ $mode -eq 1 ]; then
+ echo "Running in GATEWAY mode"
+ export THINCLIENT_ENABLED=false
+ export GATEWAYMODE_ENABLED=true
+ export DIRECTMODE_ENABLED=false
+ else
+ echo "Running in DIRECT mode"
+ export THINCLIENT_ENABLED=false
+ export GATEWAYMODE_ENABLED=false
+ export DIRECTMODE_ENABLED=true
+ fi
+
# Query operations take a long time
# Only run them once every 10 runs
if [ $(($i % 10)) -eq 0 ]; then
@@ -30,5 +49,5 @@ do
echo "====== Waiting for 10Sec ================="
sleep 10 #Wait for 10sec
-
+
done
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/run.sh b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/run.sh
index 81cafc4a4a..0d6e001743 100644
--- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/run.sh
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/run.sh
@@ -1,5 +1,6 @@
#!/bin/bash
+
if [ -z "$ACCOUNT_ENDPOINT" ]
then
echo "Missing ACCOUNT_ENDPOINT"
@@ -24,12 +25,6 @@ then
exit -1
fi
-if [ -z "$TELEMETRY_ENDPOINT" ]
-then
- echo "Missing TELEMETRY_ENDPOINT"
- exit -1
-fi
-
if [ -z "$INCLUDE_QUERY" ]
then
echo "Missing INCLUDE_QUERY"
@@ -46,37 +41,78 @@ echo $COMMIT_DATE
echo $COMMIT_TIME
echo $BRANCH_NAME
-# Client telemetry disabled ReadStreamExistsV3
-dotnet run -c Release -- -n 2000000 -w ReadStreamExistsV3 --tcp 10 --pl $PL -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
-sleep 10 #Wait
+MODE_FLAGS="--isthinclientenabled=${THINCLIENT_ENABLED:-false} \
+--isgatewaymodeenabled=${GATEWAYMODE_ENABLED:-false} \
+--isdirectmodeenabled=${DIRECTMODE_ENABLED:-false}"
-# Client telemetry enabled ReadStreamExistsV3. This is needed to see the impact of client telemetry.
-dotnet run -c Release -- -n 2000000 -w ReadStreamExistsV3 --WorkloadName ReadStreamExistsV3WithTelemetry --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 10 --pl $PL -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
-sleep 10 #Wait
+ # ---------- 1) ALWAYS RUN THESE 10 WORKLOADS ----------
+for WORKLOAD_NAME in \
+ CreateItemV3BenchmarkOperation \
+ InsertV3BenchmarkOperation \
+ ReadItemV3BenchmarkOperation \
+ ReadStreamExistsV3BenchmarkOperation \
+ ReplaceItemV3BenchmarkOperation \
+ ReplaceItemStreamV3BenchmarkOperation \
+ UpsertItemV3BenchmarkOperation \
+ UpsertItemStreamV3BenchmarkOperation \
+ DeleteItemV3BenchmarkOperation \
+ DeleteItemStreamV3BenchmarkOperation
+do
+ dotnet run -c Release \
+ -- -n 2000000 \
+ -w $WORKLOAD_NAME \
+ $MODE_FLAGS \
+ --pl $PL \
+ -e $ACCOUNT_ENDPOINT \
+ -k $ACCOUNT_KEY \
+ --enablelatencypercentiles \
+ --disablecoresdklogging \
+ --publishresults \
+ --resultspartitionkeyvalue $RESULTS_PK \
+ --commitid $COMMIT_ID \
+ --commitdate $COMMIT_DATE \
+ --committime $COMMIT_TIME \
+ --branchname $BRANCH_NAME \
+ --database testdb \
+ --container testcol \
+ --partitionkeypath /pk
+ sleep 10
+done
-# Open telemetry enabled ReadStreamExistsV3. This is needed to see the impact of distributed tracing (without listener)
-dotnet run -c Release -- -n 2000000 -w ReadStreamExistsV3 --WorkloadName ReadStreamExistsV3WithDistributedTracingWOListener --enableDistributedTracing --tcp 10 --pl $PL -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
-sleep 10 #Wait
+# ---------- 2) ADDITIONAL SCENARIOS DIRECT-ONLY ----------
+if [ "${DIRECTMODE_ENABLED:-false}" = true ]; then
+ # Client telemetry disabled ReadStreamExistsV3
+ dotnet run -c Release -- -n 2000000 -w ReadStreamExistsV3 $MODE_FLAGS --tcp 10 --pl $PL -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
+ sleep 10 #Wait
-#Point read operations
-for WORKLOAD_NAME in ReadNotExistsV3 ReadTExistsV3 ReadStreamExistsWithDiagnosticsV3
-do
- dotnet run -c Release -- -n 2000000 -w $WORKLOAD_NAME --pl $PL --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 10 -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
+ # Client telemetry enabled ReadStreamExistsV3. This is needed to see the impact of client telemetry.
+ dotnet run -c Release -- -n 2000000 -w ReadStreamExistsV3 $MODE_FLAGS --WorkloadName ReadStreamExistsV3WithTelemetry --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 10 --pl $PL -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
sleep 10 #Wait
-done
-#Insert operation
-dotnet run -c Release -- -n 2000000 -w InsertV3 --pl 30 --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 1 -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
-sleep 45 #Wait
+ # Open telemetry enabled ReadStreamExistsV3. This is needed to see the impact of distributed tracing (without listener)
+ dotnet run -c Release -- -n 2000000 -w ReadStreamExistsV3 $MODE_FLAGS --WorkloadName ReadStreamExistsV3WithDistributedTracingWOListener --enableDistributedTracing --tcp 10 --pl $PL -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
+ sleep 10 #Wait
-if [ "$INCLUDE_QUERY" = true ]
-then
- #Query operations
- # n value is lowered to 200000 because queries are significantly slower. This prevents the runs from taking to long.
- # pl is 16 because 18 was casuing a small amount of thorrtles.
- for WORKLOAD_NAME in ReadFeedStreamV3 QueryTSinglePkV3 QueryTSinglePkOrderByWithPaginationV3 QueryTSinglePkOrderByFullDrainV3 QueryTCrossPkV3 QueryTCrossPkOrderByWithPaginationV3 QueryTCrossPkOrderByFullDrainV3 QueryStreamSinglePkV3 QueryStreamSinglePkOrderByWithPaginationV3 QueryStreamSinglePkOrderByFullDrainV3 QueryStreamCrossPkV3 QueryStreamCrossPkOrderByWithPaginationV3 QueryStreamCrossPkOrderByFullDrainV3
+ #Point read operations
+ for WORKLOAD_NAME in ReadNotExistsV3 ReadTExistsV3 ReadStreamExistsWithDiagnosticsV3
do
- dotnet run -c Release -- -n 200000 -w $WORKLOAD_NAME --pl 16 --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 10 -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
+ dotnet run -c Release -- -n 2000000 -w $WORKLOAD_NAME $MODE_FLAGS --pl $PL --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 10 -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
sleep 10 #Wait
done
+
+ #Insert operation
+ dotnet run -c Release -- -n 2000000 -w InsertV3 $MODE_FLAGS --pl 30 --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 1 -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
+ sleep 45 #Wait
+
+ if [ "$INCLUDE_QUERY" = true ]
+ then
+ #Query operations
+ # n value is lowered to 200000 because queries are significantly slower. This prevents the runs from taking to long.
+ # pl is 16 because 18 was casuing a small amount of thorrtles.
+ for WORKLOAD_NAME in ReadFeedStreamV3 QueryTSinglePkV3 QueryTSinglePkOrderByWithPaginationV3 QueryTSinglePkOrderByFullDrainV3 QueryTCrossPkV3 QueryTCrossPkOrderByWithPaginationV3 QueryTCrossPkOrderByFullDrainV3 QueryStreamSinglePkV3 QueryStreamSinglePkOrderByWithPaginationV3 QueryStreamSinglePkOrderByFullDrainV3 QueryStreamCrossPkV3 QueryStreamCrossPkOrderByWithPaginationV3 QueryStreamCrossPkOrderByFullDrainV3
+ do
+ dotnet run -c Release -- -n 200000 -w $WORKLOAD_NAME $MODE_FLAGS --pl 16 --enableTelemetry --telemetryScheduleInSec 60 --telemetryEndpoint $TELEMETRY_ENDPOINT --tcp 10 -e $ACCOUNT_ENDPOINT -k $ACCOUNT_KEY --enablelatencypercentiles --disablecoresdklogging --publishresults --resultspartitionkeyvalue $RESULTS_PK --commitid $COMMIT_ID --commitdate $COMMIT_DATE --committime $COMMIT_TIME --branchname $BRANCH_NAME --database testdb --container testcol --partitionkeypath /pk
+ sleep 10 #Wait
+ done
+ fi
fi
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/CreateItemV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/CreateItemV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..950e4a4be3
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/CreateItemV3BenchmarkOperation.cs
@@ -0,0 +1,60 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class CreateItemV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+
+ public CreateItemV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Insert;
+
+ public Task PrepareAsync()
+ {
+ this.sampleJObject["id"] = Guid.NewGuid().ToString();
+ this.sampleJObject[this.partitionKeyPath] = Guid.NewGuid().ToString();
+ return Task.CompletedTask;
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ PartitionKey partitionKey = new PartitionKey(this.sampleJObject[this.partitionKeyPath].ToString());
+ ItemResponse> response = await this.container.CreateItemAsync(this.sampleJObject, partitionKey: partitionKey);
+
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/DeleteItemStreamV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/DeleteItemStreamV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..7ee5322656
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/DeleteItemStreamV3BenchmarkOperation.cs
@@ -0,0 +1,66 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class DeleteItemStreamV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+ private string itemId;
+ private string itemPk;
+
+ public DeleteItemStreamV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Read;
+
+ public async Task PrepareAsync()
+ {
+ this.itemId = Guid.NewGuid().ToString();
+ this.itemPk = Guid.NewGuid().ToString();
+ this.sampleJObject["id"] = this.itemId;
+ this.sampleJObject[this.partitionKeyPath] = this.itemPk;
+
+ using (MemoryStream input = JsonHelper.ToStream(this.sampleJObject))
+ {
+ ResponseMessage itemResponse = await this.container.CreateItemStreamAsync(input, new PartitionKey(this.itemPk));
+ System.Buffers.ArrayPool.Shared.Return(input.GetBuffer());
+ }
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ ResponseMessage response = await this.container.DeleteItemStreamAsync(this.itemId, new PartitionKey(this.itemPk));
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.Headers.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/DeleteItemV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/DeleteItemV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..c2baaa1609
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/DeleteItemV3BenchmarkOperation.cs
@@ -0,0 +1,66 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class DeleteItemV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+ private string itemId;
+ private string itemPk;
+
+ public DeleteItemV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Read;
+
+ public async Task PrepareAsync()
+ {
+ this.itemId = Guid.NewGuid().ToString();
+ this.itemPk = Guid.NewGuid().ToString();
+ this.sampleJObject["id"] = this.itemId;
+ this.sampleJObject[this.partitionKeyPath] = this.itemPk;
+
+ using (MemoryStream input = JsonHelper.ToStream(this.sampleJObject))
+ {
+ ResponseMessage itemResponse = await this.container.CreateItemStreamAsync(input, new PartitionKey(this.itemPk));
+ System.Buffers.ArrayPool.Shared.Return(input.GetBuffer());
+ }
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ ItemResponse> response = await this.container.DeleteItemAsync>(this.itemId, new PartitionKey(this.itemPk));
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadItemV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadItemV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..f8ad218508
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadItemV3BenchmarkOperation.cs
@@ -0,0 +1,66 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class ReadItemV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+ private string itemId;
+ private string itemPk;
+
+ public ReadItemV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Read;
+
+ public async Task PrepareAsync()
+ {
+ this.itemId = Guid.NewGuid().ToString();
+ this.itemPk = Guid.NewGuid().ToString();
+ this.sampleJObject["id"] = this.itemId;
+ this.sampleJObject[this.partitionKeyPath] = this.itemPk;
+
+ using (MemoryStream input = JsonHelper.ToStream(this.sampleJObject))
+ {
+ ResponseMessage itemResponse = await this.container.CreateItemStreamAsync(input, new PartitionKey(this.itemPk));
+ System.Buffers.ArrayPool.Shared.Return(input.GetBuffer());
+ }
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ ItemResponse> response = await this.container.ReadItemAsync>(this.itemId, new PartitionKey(this.itemPk));
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReplaceItemStreamV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReplaceItemStreamV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..03ca79cbe1
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReplaceItemStreamV3BenchmarkOperation.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class ReplaceItemStreamV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+ private string itemId;
+ private string itemPk;
+
+ public ReplaceItemStreamV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Read;
+
+ public async Task PrepareAsync()
+ {
+ this.itemId = Guid.NewGuid().ToString();
+ this.itemPk = Guid.NewGuid().ToString();
+ this.sampleJObject["id"] = this.itemId;
+ this.sampleJObject[this.partitionKeyPath] = this.itemPk;
+ this.sampleJObject["other"] = "Original";
+
+ using (MemoryStream input = JsonHelper.ToStream(this.sampleJObject))
+ {
+ ResponseMessage itemResponse = await this.container.CreateItemStreamAsync(input, new PartitionKey(this.itemPk));
+ System.Buffers.ArrayPool.Shared.Return(input.GetBuffer());
+ }
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ this.sampleJObject["other"] = "Updated Stream Other";
+ using (MemoryStream input = JsonHelper.ToStream(this.sampleJObject))
+ {
+ ResponseMessage response = await this.container.ReplaceItemStreamAsync(input, this.itemId, new PartitionKey(this.itemPk));
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.Headers.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReplaceItemV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReplaceItemV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..de4f2677cc
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReplaceItemV3BenchmarkOperation.cs
@@ -0,0 +1,68 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class ReplaceItemV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+ private string itemId;
+ private string itemPk;
+
+ public ReplaceItemV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Read;
+
+ public async Task PrepareAsync()
+ {
+ this.itemId = Guid.NewGuid().ToString();
+ this.itemPk = Guid.NewGuid().ToString();
+ this.sampleJObject["id"] = this.itemId;
+ this.sampleJObject[this.partitionKeyPath] = this.itemPk;
+ this.sampleJObject["other"] = "Original";
+
+ using (MemoryStream input = JsonHelper.ToStream(this.sampleJObject))
+ {
+ ResponseMessage itemResponse = await this.container.CreateItemStreamAsync(input, new PartitionKey(this.itemPk));
+ System.Buffers.ArrayPool.Shared.Return(input.GetBuffer());
+ }
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ this.sampleJObject["other"] = "Updated Other";
+ ItemResponse> response = await this.container.ReplaceItemAsync(this.sampleJObject, this.itemId, new PartitionKey(this.itemPk));
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/UpsertItemStreamV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/UpsertItemStreamV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..611c9a8a65
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/UpsertItemStreamV3BenchmarkOperation.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class UpsertItemStreamV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+
+ public UpsertItemStreamV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Read;
+
+ public Task PrepareAsync()
+ {
+ this.sampleJObject["id"] = Guid.NewGuid().ToString();
+ this.sampleJObject[this.partitionKeyPath] = Guid.NewGuid().ToString();
+ this.sampleJObject["other"] = "Upserted Stream";
+ return Task.CompletedTask;
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ PartitionKey partitionKey = new PartitionKey(this.sampleJObject[this.partitionKeyPath].ToString());
+ using (MemoryStream input = JsonHelper.ToStream(this.sampleJObject))
+ {
+ ResponseMessage response = await this.container.UpsertItemStreamAsync(input, partitionKey);
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.Headers.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/UpsertItemV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/UpsertItemV3BenchmarkOperation.cs
new file mode 100644
index 0000000000..151876b758
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/UpsertItemV3BenchmarkOperation.cs
@@ -0,0 +1,59 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace CosmosBenchmark
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+
+ internal class UpsertItemV3BenchmarkOperation : IBenchmarkOperation
+ {
+ private readonly Container container;
+ private readonly string partitionKeyPath;
+ private readonly Dictionary sampleJObject;
+ private readonly string databaseName;
+ private readonly string containerName;
+
+ public UpsertItemV3BenchmarkOperation(
+ CosmosClient cosmosClient,
+ string dbName,
+ string containerName,
+ string partitionKeyPath,
+ string sampleJson)
+ {
+ this.databaseName = dbName;
+ this.containerName = containerName;
+ this.container = cosmosClient.GetContainer(this.databaseName, this.containerName);
+ this.partitionKeyPath = partitionKeyPath.Replace("/", "");
+ this.sampleJObject = JsonHelper.Deserialize>(sampleJson);
+ }
+
+ public BenchmarkOperationType OperationType => BenchmarkOperationType.Read;
+
+ public Task PrepareAsync()
+ {
+ this.sampleJObject["id"] = Guid.NewGuid().ToString();
+ this.sampleJObject[this.partitionKeyPath] = Guid.NewGuid().ToString();
+ this.sampleJObject["other"] = "Upserted";
+ return Task.CompletedTask;
+ }
+
+ public async Task ExecuteOnceAsync()
+ {
+ PartitionKey partitionKey = new PartitionKey(this.sampleJObject[this.partitionKeyPath].ToString());
+ ItemResponse> response = await this.container.UpsertItemAsync(this.sampleJObject, partitionKey: partitionKey);
+ return new OperationResult
+ {
+ DatabseName = this.databaseName,
+ ContainerName = this.containerName,
+ OperationType = this.OperationType,
+ RuCharges = response.RequestCharge,
+ CosmosDiagnostics = response.Diagnostics,
+ LazyDiagnostics = () => response.Diagnostics.ToString(),
+ };
+ }
+ }
+}