Skip to content

Add representative workflow benchmark suite#70

Merged
woutervanranst merged 10 commits into
masterfrom
benchmark2
Apr 28, 2026
Merged

Add representative workflow benchmark suite#70
woutervanranst merged 10 commits into
masterfrom
benchmark2

Conversation

@woutervanranst

@woutervanranst woutervanranst commented Apr 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a BenchmarkDotNet suite for the canonical representative workflow on Azurite
  • Append autoresearch-friendly benchmark tail rows with runtime, GC, allocation, and threading metrics
  • Store benchmark tail and raw output under src/Arius.Benchmarks

Validation

  • dotnet build src/Arius.Benchmarks/Arius.Benchmarks.csproj -c Release --no-restore
  • dotnet run -c Release --project src/Arius.Benchmarks
  • dotnet test --project src/Arius.E2E.Tests/Arius.E2E.Tests.csproj --treenode-filter "///RepresentativeArchiveRestoreTests/*"
  • slopwatch analyze --fail-on warning

Summary by CodeRabbit

  • New Features

    • Added an integrated benchmarking suite to run and record representative workflow performance, producing timing, memory, GC and run metadata, and saving raw artifacts.
  • Documentation

    • Added a Benchmarks section with instructions to run benchmarks in Release mode; results are stored under a raw output folder and each run appends a tail-log entry.
  • CI

    • Added a workflow job to run benchmarks on push and persist updated outputs.
  • Chores

    • Included benchmarks in the solution, added central package version for benchmarking, adjusted ignore rules to track outputs, and updated access for tooling integration.

woutervanranst and others added 3 commits April 28, 2026 05:57
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3bd56d69-ed13-41da-bd20-32b7096419be

📥 Commits

Reviewing files that changed from the base of the PR and between ab34bf1 and d00828e.

📒 Files selected for processing (1)
  • codecov.yml

📝 Walkthrough

Walkthrough

Adds a new BenchmarkDotNet-based project (Arius.Benchmarks) including CLI parsing, git-head resolution, tail-log appending, a representative Azurite workflow benchmark, sample raw reports, solution/package updates, an InternalsVisibleTo entry, and a CI job to run and optionally commit benchmark outputs.

Changes

Cohort / File(s) Summary
Repo & docs
/.gitignore, README.md
Allow tracking src/Arius.Benchmarks/benchmark-tail.log and src/Arius.Benchmarks/raw/**; add README Benchmarks section describing how to run the benchmark and where raw results/logs are stored.
Solution & packages
src/Arius.slnx, src/Directory.Packages.props
Add Arius.Benchmarks to solution and pin BenchmarkDotNet version to 0.15.8.
Benchmarks project
src/Arius.Benchmarks/Arius.Benchmarks.csproj
New .NET 10 SDK console project referencing Arius.E2E.Tests and BenchmarkDotNet.
CLI & run options
src/Arius.Benchmarks/BenchmarkRunOptions.cs
Add record to locate repo root, compute default raw/tail paths, parse --raw-output/--tail-log/--help, and expose iteration count constant.
Tail log writer
src/Arius.Benchmarks/BenchmarkTailLog.cs
Add pipe-delimited tail-log appender that writes header when missing and extracts summary fields (Mean/Error/StdDev, GC counts, allocations, etc.) from BenchmarkDotNet Summary.
Git helper
src/Arius.Benchmarks/GitHeadResolver.cs
Add utility that runs git -C <root> rev-parse HEAD and returns the commit hash or "unknown".
Runner & config
src/Arius.Benchmarks/Program.cs
Program entry that parses options, creates run dir, configures ManualConfig/Job and StreamLogger, executes BenchmarkDotNet, and appends a tail-log entry.
Benchmarks implementation
src/Arius.Benchmarks/RepresentativeWorkflowBenchmarks.cs
Benchmark class that manages AzuriteE2EBackendFixture lifecycle and runs the canonical representative workflow as an async BenchmarkDotNet benchmark with setup/cleanup.
Sample results
src/Arius.Benchmarks/raw/.../results/*
Add generated BenchmarkDotNet report files (HTML and GitHub-flavored Markdown) for sample runs.
Test internals & constants
src/Arius.E2E.Tests/AssemblyMarker.cs, src/Arius.E2E.Tests/Datasets/SyntheticRepositoryDefinitionFactory.cs
Expose internals to benchmarks via InternalsVisibleTo("Arius.Benchmarks") and make RepresentativeScaleDivisor public.
CI workflow
.github/workflows/ci.yml
Add benchmark job (runs on push) that executes the benchmark and conditionally commits/pushes updated tail log and raw outputs.
Codecov
codecov.yml
Ignore coverage for src/Arius.Tests.Shared/** in addition to existing rules.

Sequence Diagram(s)

sequenceDiagram
    participant Program as Program (Runner)
    participant Git as GitHeadResolver
    participant BDN as BenchmarkDotNet
    participant RepBench as RepresentativeWorkflowBenchmarks
    participant Fixture as AzuriteE2EBackendFixture
    participant Workflow as RepresentativeWorkflowRunner
    participant TailLog as BenchmarkTailLog

    Program->>Program: Parse CLI args, locate repo, create run dir
    Program->>Git: Resolve(repo root)
    Git-->>Program: commit hash or "unknown"
    Program->>BDN: Run benchmarks with ManualConfig & StreamLogger
    BDN->>RepBench: [GlobalSetup] SetupAsync
    RepBench->>Fixture: Create & InitializeAsync
    Fixture-->>RepBench: Ready
    loop iterations
        BDN->>RepBench: Invoke benchmark method
        RepBench->>Workflow: RunAsync representative workflow
        Workflow-->>RepBench: Result
        RepBench->>RepBench: Validate result (skip/archive checks)
    end
    BDN->>RepBench: [GlobalCleanup] CleanupAsync
    RepBench->>Fixture: DisposeAsync
    Program->>TailLog: Append(run metadata, summary, raw path)
    TailLog-->>TailLog: Write header if missing and append pipe-delimited row
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Add representative workflow benchmark suite' directly and clearly summarizes the main change: introducing a benchmarking suite for the representative workflow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch benchmark2

Comment @coderabbitai help to get the list of available commands and usage tips.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
README.md (1)

155-155: Trim implementation-heavy wording in the benchmark section.

Line 155 is a bit too internal-path/tooling heavy for README flow; consider keeping this section focused on how to run and where to look next, with less implementation detail.

✍️ Suggested wording
-The benchmark runs the canonical representative workflow with BenchmarkDotNet. Raw BenchmarkDotNet output is written under `src/Arius.Benchmarks/raw/`, and each run appends one line to `src/Arius.Benchmarks/benchmark-tail.log` for autoresearch-style tailing.
+This runs the canonical representative workflow benchmark. Results are saved under `src/Arius.Benchmarks/raw/`, and a summary line is appended to `src/Arius.Benchmarks/benchmark-tail.log`.

As per coding guidelines: README.md should stay high signal and accessible, and should not be cluttered with implementation details.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 155, Replace the implementation-heavy sentence about
BenchmarkDotNet output with a concise, user-focused line: remove internal paths
and tooling specifics and instead state how to run the benchmark and where to
inspect results (e.g., “Run the benchmark with BenchmarkDotNet; raw output and
logs are available in the benchmarks folder”); update the README's benchmark
section to be high-level and actionable, keeping phrasing similar to the
existing sentence but omitting `src/Arius.Benchmarks/raw/` and
`src/Arius.Benchmarks/benchmark-tail.log` details.
src/Arius.E2E.Tests/AssemblyMarker.cs (1)

3-3: Move SyntheticRepositoryDefinitionFactory, E2E fixtures, and workflows to Arius.Tests.Shared to eliminate this broad InternalsVisibleTo grant.

Arius.Benchmarks currently imports Arius.E2E.Tests.Datasets, Arius.E2E.Tests.Fixtures, and Arius.E2E.Tests.Workflows as internal dependencies. Extract the synthetic repository generation and fixture infrastructure into src/Arius.Tests.Shared/, keeping Arius.E2E.Tests reserved for actual end-to-end behavior coverage. This removes the need for the friend-assembly grant and consolidates reusable test infrastructure per architectural guidelines.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Arius.E2E.Tests/AssemblyMarker.cs` at line 3, The project currently
exposes internals to Arius.Benchmarks via the AssemblyMarker InternalsVisibleTo
attribute; move SyntheticRepositoryDefinitionFactory, all E2E fixtures
(Arius.E2E.Tests.Fixtures) and workflows (Arius.E2E.Tests.Workflows) into a new
shared test library Arius.Tests.Shared and update their namespaces so they are
compiled into that project, then remove the
InternalsVisibleTo("Arius.Benchmarks") attribute from AssemblyMarker.cs and
update any references in Arius.Benchmarks to depend on Arius.Tests.Shared
instead; specifically, extract the implementation of
SyntheticRepositoryDefinitionFactory and the fixture/workflow classes into
src/Arius.Tests.Shared, make them public if needed, add a project reference from
Arius.Benchmarks to Arius.Tests.Shared, and remove the InternalsVisibleTo
attribute to eliminate the broad friend-assembly grant.
src/Arius.Benchmarks/Arius.Benchmarks.csproj (1)

16-18: Decouple benchmark runtime code from Arius.E2E.Tests assembly.

Arius.Benchmarks currently depends on the E2E test assembly directly. Consider moving reusable workflow/fixture primitives into src/Arius.Tests.Shared/ and referencing that shared project from both benchmarks and E2E tests to avoid cross-assembly test coupling.

Based on learnings: Reusable Azurite and repository-fixture wiring belongs in src/Arius.Tests.Shared/, not in another test project assembly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Arius.Benchmarks/Arius.Benchmarks.csproj` around lines 16 - 18,
Arius.Benchmarks currently references the test assembly Arius.E2E.Tests; extract
the reusable fixture/workflow primitives (e.g., Azurite wiring, repository
fixtures) into a new or existing shared project src/Arius.Tests.Shared and
update usages to the shared namespace, then remove the ProjectReference to
..\Arius.E2E.Tests\Arius.E2E.Tests.csproj from Arius.Benchmarks.csproj and add a
ProjectReference to the new src/Arius.Tests.Shared project; also update
Arius.E2E.Tests to reference Arius.Tests.Shared so both benchmarks and E2E tests
consume the same shared primitives without cross-assembling coupling.
src/Arius.Benchmarks/BenchmarkTailLog.cs (1)

78-105: Split extra top-level types into dedicated files.

BenchmarkTailLogEntry and BenchmarkSummaryValues should be moved out of BenchmarkTailLog.cs so each top-level type has a matching file.

As per coding guidelines: "Prefer one top-level class per file, with the filename matching the class name."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Arius.Benchmarks/BenchmarkTailLog.cs` around lines 78 - 105, Move the two
top-level types out of BenchmarkTailLog.cs into their own files: create a file
that declares the internal sealed record BenchmarkTailLogEntry with the same
signature and accessibility, and another file that declares the internal sealed
class BenchmarkSummaryValues with the same constructor, Get method, Normalize
helper and accessibility; keep their namespace and any required using
directives, remove these type declarations from BenchmarkTailLog.cs, and ensure
any references to BenchmarkTailLogEntry or BenchmarkSummaryValues compile
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Arius.Benchmarks/GitHeadResolver.cs`:
- Around line 9-25: The current GitHeadResolver logic can throw when
Process.Start fails, block indefinitely on process.WaitForExit(), and never
consumes StandardError; update the method that creates the Process (using
ProcessStartInfo and the local variable process) to wrap Process.Start in a
try/catch and immediately return "unknown" on exception, set a bounded wait via
process.WaitForExit(timeoutMs) (e.g. 5s), on timeout call process.Kill() and
return "unknown", and always read both process.StandardOutput and
process.StandardError (or drain StandardError) before checking process.ExitCode
to avoid deadlocks; ensure the process is disposed in a finally block so
repositoryRoot resolution always fails closed to "unknown".

In
`@src/Arius.Benchmarks/raw/20260428T040505.928Z/results/Arius.Benchmarks.RepresentativeWorkflowBenchmarks-report-github.md`:
- Around line 1-15: Add a fenced language to the opening code fence (change the
initial ``` to ```text) and ensure there is a blank line before the markdown
table header row ("| Method ...") and a blank line after the table end, so the
initial code block is properly language-marked (fixes MD040) and the table is
separated by surrounding blank lines (fixes MD058); update the file's opening
``` and the area around the table header/footer accordingly.

In `@src/Arius.Benchmarks/RepresentativeWorkflowBenchmarks.cs`:
- Line 9: The class RepresentativeWorkflowBenchmarks is declared public but
doesn't require cross-assembly access; change its declaration to internal to
narrow visibility. Update the type declaration for
RepresentativeWorkflowBenchmarks from public to internal (keeping the class name
and members unchanged) so it follows the guideline to make non-test classes
internal unless needed externally.

---

Nitpick comments:
In `@README.md`:
- Line 155: Replace the implementation-heavy sentence about BenchmarkDotNet
output with a concise, user-focused line: remove internal paths and tooling
specifics and instead state how to run the benchmark and where to inspect
results (e.g., “Run the benchmark with BenchmarkDotNet; raw output and logs are
available in the benchmarks folder”); update the README's benchmark section to
be high-level and actionable, keeping phrasing similar to the existing sentence
but omitting `src/Arius.Benchmarks/raw/` and
`src/Arius.Benchmarks/benchmark-tail.log` details.

In `@src/Arius.Benchmarks/Arius.Benchmarks.csproj`:
- Around line 16-18: Arius.Benchmarks currently references the test assembly
Arius.E2E.Tests; extract the reusable fixture/workflow primitives (e.g., Azurite
wiring, repository fixtures) into a new or existing shared project
src/Arius.Tests.Shared and update usages to the shared namespace, then remove
the ProjectReference to ..\Arius.E2E.Tests\Arius.E2E.Tests.csproj from
Arius.Benchmarks.csproj and add a ProjectReference to the new
src/Arius.Tests.Shared project; also update Arius.E2E.Tests to reference
Arius.Tests.Shared so both benchmarks and E2E tests consume the same shared
primitives without cross-assembling coupling.

In `@src/Arius.Benchmarks/BenchmarkTailLog.cs`:
- Around line 78-105: Move the two top-level types out of BenchmarkTailLog.cs
into their own files: create a file that declares the internal sealed record
BenchmarkTailLogEntry with the same signature and accessibility, and another
file that declares the internal sealed class BenchmarkSummaryValues with the
same constructor, Get method, Normalize helper and accessibility; keep their
namespace and any required using directives, remove these type declarations from
BenchmarkTailLog.cs, and ensure any references to BenchmarkTailLogEntry or
BenchmarkSummaryValues compile unchanged.

In `@src/Arius.E2E.Tests/AssemblyMarker.cs`:
- Line 3: The project currently exposes internals to Arius.Benchmarks via the
AssemblyMarker InternalsVisibleTo attribute; move
SyntheticRepositoryDefinitionFactory, all E2E fixtures
(Arius.E2E.Tests.Fixtures) and workflows (Arius.E2E.Tests.Workflows) into a new
shared test library Arius.Tests.Shared and update their namespaces so they are
compiled into that project, then remove the
InternalsVisibleTo("Arius.Benchmarks") attribute from AssemblyMarker.cs and
update any references in Arius.Benchmarks to depend on Arius.Tests.Shared
instead; specifically, extract the implementation of
SyntheticRepositoryDefinitionFactory and the fixture/workflow classes into
src/Arius.Tests.Shared, make them public if needed, add a project reference from
Arius.Benchmarks to Arius.Tests.Shared, and remove the InternalsVisibleTo
attribute to eliminate the broad friend-assembly grant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5ed0149e-5aa0-455f-b88e-ce0aa1debb3f

📥 Commits

Reviewing files that changed from the base of the PR and between 8c5e5e3 and e9c2556.

⛔ Files ignored due to path filters (4)
  • src/Arius.Benchmarks/benchmark-tail.log is excluded by !**/*.log
  • src/Arius.Benchmarks/raw/20260428T040505.928Z/Arius.Benchmarks.RepresentativeWorkflowBenchmarks-20260428-060506.log is excluded by !**/*.log
  • src/Arius.Benchmarks/raw/20260428T040505.928Z/benchmark-output.log is excluded by !**/*.log
  • src/Arius.Benchmarks/raw/20260428T040505.928Z/results/Arius.Benchmarks.RepresentativeWorkflowBenchmarks-report.csv is excluded by !**/*.csv
📒 Files selected for processing (14)
  • .gitignore
  • README.md
  • src/Arius.Benchmarks/Arius.Benchmarks.csproj
  • src/Arius.Benchmarks/BenchmarkRunOptions.cs
  • src/Arius.Benchmarks/BenchmarkTailLog.cs
  • src/Arius.Benchmarks/GitHeadResolver.cs
  • src/Arius.Benchmarks/Program.cs
  • src/Arius.Benchmarks/RepresentativeWorkflowBenchmarks.cs
  • src/Arius.Benchmarks/raw/20260428T040505.928Z/results/Arius.Benchmarks.RepresentativeWorkflowBenchmarks-report-github.md
  • src/Arius.Benchmarks/raw/20260428T040505.928Z/results/Arius.Benchmarks.RepresentativeWorkflowBenchmarks-report.html
  • src/Arius.E2E.Tests/AssemblyMarker.cs
  • src/Arius.E2E.Tests/Datasets/SyntheticRepositoryDefinitionFactory.cs
  • src/Arius.slnx
  • src/Directory.Packages.props

Comment thread src/Arius.Benchmarks/GitHeadResolver.cs
Comment thread src/Arius.Benchmarks/RepresentativeWorkflowBenchmarks.cs
woutervanranst and others added 3 commits April 28, 2026 06:20
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codecov

codecov Bot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.85%. Comparing base (8c5e5e3) to head (d00828e).
⚠️ Report is 12 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #70      +/-   ##
==========================================
- Coverage   79.20%   78.85%   -0.36%     
==========================================
  Files          69       66       -3     
  Lines        4986     4842     -144     
  Branches      671      656      -15     
==========================================
- Hits         3949     3818     -131     
+ Misses        881      872       -9     
+ Partials      156      152       -4     
Flag Coverage Δ
linux 82.12% <ø> (-0.05%) ⬇️
windows 76.47% <ø> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@woutervanranst woutervanranst merged commit ba08605 into master Apr 28, 2026
11 checks passed
@woutervanranst woutervanranst deleted the benchmark2 branch April 28, 2026 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant