Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: benchmarks

on:
push:
branches:
- master
schedule:
# Run weekly on Sundays at 04:00 UTC
- cron: '0 4 * * 0'
workflow_dispatch:

jobs:
benchmarks:
name: Benchmarks (${{ matrix.display-name }})
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
dotnet-version: ['8.0', '9.0', '10.0']
include:
- dotnet-version: '8.0'
display-name: '.NET 8.0'
framework: 'net8.0'
install-version: '8.0.x'
- dotnet-version: '9.0'
display-name: '.NET 9.0'
framework: 'net9.0'
install-version: '9.0.x'
- dotnet-version: '10.0'
display-name: '.NET 10.0'
framework: 'net10.0'
install-version: '10.0.x'
steps:
- uses: actions/checkout@v4

- name: Setup .NET 8.0
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
dotnet-quality: 'ga'

- name: Setup .NET 9.0
uses: actions/setup-dotnet@v3
with:
dotnet-version: '9.0.x'
dotnet-quality: 'ga'

- name: Setup .NET 10.0
uses: actions/setup-dotnet@v3
with:
dotnet-version: '10.0.x'
dotnet-quality: 'ga'

- name: Restore dependencies
run: dotnet restore

- name: Build
run: dotnet build --configuration Release --no-restore

- name: Run Benchmarks
run: |
dotnet run \
--project test/Dapr.Benchmarks/Dapr.Benchmarks.csproj \
--configuration Release \
--framework ${{ matrix.framework }} \
--no-build \
-- \
--filter '*' \
--artifacts "${{ github.workspace }}/BenchmarkResults"

- name: Upload benchmark results
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-results-${{ matrix.framework }}
path: ${{ github.workspace }}/BenchmarkResults
retention-days: 90
15 changes: 15 additions & 0 deletions all.sln
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.IntegrationTest.Crypto
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.IntegrationTest.Actors", "test\Dapr.IntegrationTest.Actors\Dapr.IntegrationTest.Actors.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Benchmarks", "test\Dapr.Benchmarks\Dapr.Benchmarks.csproj", "{175AEE22-9DE6-462E-A31B-671E7BA88E4B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.IntegrationTest.Examples", "test\Dapr.IntegrationTest.Examples\Dapr.IntegrationTest.Examples.csproj", "{8777EAD2-419B-4683-826A-82B7C1F4F69F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.IntegrationTest.Actors.Generators", "test\Dapr.IntegrationTest.Actors.Generators\Dapr.IntegrationTest.Actors.Generators.csproj", "{C6948155-C70C-4C03-A733-0624402AEC97}"
Expand Down Expand Up @@ -1494,6 +1496,18 @@ Global
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x64.Build.0 = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x86.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x86.Build.0 = Release|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Debug|x64.ActiveCfg = Debug|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Debug|x64.Build.0 = Debug|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Debug|x86.ActiveCfg = Debug|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Debug|x86.Build.0 = Debug|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Release|Any CPU.Build.0 = Release|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Release|x64.ActiveCfg = Release|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Release|x64.Build.0 = Release|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Release|x86.ActiveCfg = Release|Any CPU
{175AEE22-9DE6-462E-A31B-671E7BA88E4B}.Release|x86.Build.0 = Release|Any CPU
{8777EAD2-419B-4683-826A-82B7C1F4F69F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8777EAD2-419B-4683-826A-82B7C1F4F69F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8777EAD2-419B-4683-826A-82B7C1F4F69F}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -1653,6 +1667,7 @@ Global
{01A20A89-53A1-4D5B-B563-89E157718474} = {8462B106-175A-423A-BA94-BE0D39D0BD8E}
{7B14879F-156B-417E-ACA3-0B5A69CC2F39} = {8462B106-175A-423A-BA94-BE0D39D0BD8E}
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890} = {8462B106-175A-423A-BA94-BE0D39D0BD8E}
{175AEE22-9DE6-462E-A31B-671E7BA88E4B} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{8777EAD2-419B-4683-826A-82B7C1F4F69F} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{C6948155-C70C-4C03-A733-0624402AEC97} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{6C77A2C4-0A96-4B90-AFEA-16E86A906259} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
Expand Down
29 changes: 29 additions & 0 deletions test/Dapr.Benchmarks/Dapr.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<!--
Benchmarks are not test projects — suppress the test-related defaults
inherited from test/Directory.Build.props so BenchmarkDotNet's console
runner is the only entry-point.
-->
<IsTestProject>false</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Dapr.Client\Dapr.Client.csproj" />
<ProjectReference Include="..\..\src\Dapr.AspNetCore\Dapr.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\Dapr.Messaging\Dapr.Messaging.csproj" />
<ProjectReference Include="..\..\src\Dapr.Workflow\Dapr.Workflow.csproj" />
<ProjectReference Include="..\..\src\Dapr.Testcontainers\Dapr.Testcontainers.csproj" />
</ItemGroup>

</Project>
102 changes: 102 additions & 0 deletions test/Dapr.Benchmarks/Infrastructure/DaprBenchmarkBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// ------------------------------------------------------------------------
// Copyright 2025 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------

using Dapr.Testcontainers.Common;
using Dapr.Testcontainers.Common.Options;
using Dapr.Testcontainers.Common.Testing;
using Dapr.Testcontainers.Harnesses;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Dapr.Benchmarks.Infrastructure;

/// <summary>
/// Base class that manages the lifecycle of a Dapr Testcontainers environment
/// for BenchmarkDotNet [GlobalSetup] / [GlobalCleanup].
/// </summary>
public abstract class DaprBenchmarkBase : IDisposable
{
private DaprTestEnvironment? environment;
private DaprTestApplication? testApp;
private bool disposed;

/// <summary>
/// Gets the service scope created from the test application.
/// </summary>
protected IServiceScope? Scope { get; private set; }

/// <summary>
/// Creates the Dapr test environment and starts the application.
/// </summary>
protected async Task SetupEnvironmentAsync(
Func<DaprHarnessBuilder, BaseHarness> buildHarness,
Action<WebApplicationBuilder>? configureServices = null,
Action<WebApplication>? configureApp = null,
bool needsActorState = false)
{
var componentsDir = TestDirectoryManager.CreateTestDirectory($"bench-{Guid.NewGuid():N}");

environment = await DaprTestEnvironment.CreateWithPooledNetworkAsync(
needsActorState: needsActorState);
await environment.StartAsync();

var harness = buildHarness(new DaprHarnessBuilder(componentsDir).WithEnvironment(environment));

var appBuilder = DaprHarnessBuilder.ForHarness(harness);

if (configureServices is not null)
{
appBuilder.ConfigureServices(configureServices);
}

if (configureApp is not null)
{
appBuilder.ConfigureApp(configureApp);
}

testApp = await appBuilder.BuildAndStartAsync();
Scope = testApp.CreateScope();
}

/// <summary>
/// Tears down the Dapr test environment and disposes resources.
/// </summary>
protected async Task TeardownEnvironmentAsync()
{
Scope?.Dispose();
Scope = null;

if (testApp is not null)
{
await testApp.DisposeAsync();
testApp = null;
}

if (environment is not null)
{
await environment.DisposeAsync();
environment = null;
}
}

/// <inheritdoc />
public void Dispose()
{
if (disposed) return;
disposed = true;

TeardownEnvironmentAsync().GetAwaiter().GetResult();

GC.SuppressFinalize(this);
}
}
16 changes: 16 additions & 0 deletions test/Dapr.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// ------------------------------------------------------------------------
// Copyright 2025 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------

using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
Loading
Loading