Skip to content

Commit ce8def5

Browse files
committed
Separate benchmark contracts from functional Build and Tests
1 parent 75aa7d0 commit ce8def5

369 files changed

Lines changed: 315 additions & 121 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/AGENTS.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# GitHub Actions workflows
22

3+
## Build and Tests scope, owner correction 2026-10-06
4+
5+
- Build and Tests executes only solution builds, repository checks and KeyLoad functional tests. Benchmark/comparison cases and their progress, entry, counter and image-preparation checks belong exclusively to Benchmarks. Keep benchmark contracts in KeyLoad.ComparisonTests, not KeyLoad.UnitTests; retain their assertions and execution in Benchmarks. RF3 functional qualification builds only the KeyLoad server image, never a benchmark load-generator image. This explicit owner correction supersedes earlier benchmark-correctness placement in ordinary CI.
6+
37
## Purpose and entry points
48
- Owns repository CI qualification and GitHub Pages publication workflows.
59
- Canonical workflows: `ci.yml` (restore, Release build, TUnit unit/integration/recovery suites and comparison artifact production) and `pages.yml` (verified artifact download, site checks/build and Pages deployment).

‎.github/workflows/Features/BenchmarkComparisons/QualifySite/AGENTS.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,7 @@
3333
- The current four workflows are Build and Tests (`build-and-tests.yml`), Benchmarks (`benchmarks.yml`), Website (`website.yml`) and prepared manual Release (`release.yml`). Only Website builds, qualifies and publishes the site on trusted main push/manual; Benchmarks ends with a bounded Website dispatch and Website has no `workflow_run` executor subscription. These explicit owner corrections supersede every earlier three-workflow, filename, executor, placement and completion-subscription clause; every unrelated suite, permission and qualification rule remains mandatory.
3434
- The sole measured producer contract is the current 1,386-worker/2,530-input cohort in ADR-076. Its executed dependency manifest contains exactly 80 current source paths. Remove old-plan readers, schemas, event-file parsers and their exclusive fixtures or inventory entries under the root owner-only migration/legacy super rule. This supersedes earlier 270/277 and old-reader requirements only; retain bounded authenticated REST producer/artifact provenance, exact current source and input hashes, failed/null accounting, strict selected-evidence rejection, freshness and unchanged 80/70/90 coverage thresholds.
3535
- When no current authenticated producer is ready, qualify the complete content-only site without figures. Real native TUnit/Node/Chrome operations, no skips in each applicable suite, source/coverage inventories and needs-gated least-privilege Pages remain required. Local tests enter the same Aspire-owned AppHost and are development evidence; genuine exact-source Linux/provider proof closes delivery. Controlled rejection inputs cannot become published measurements.
36+
37+
## Test project separation, owner correction 2026-10-06
38+
39+
- Website startup/optional-selection checks moved with the benchmark infrastructure contracts to KeyLoad.ComparisonTests. Build that project and select only those two gates through the Aspire comparison suite. Preserve their complete assertions, TRX and Website executor checks; this does not execute database benchmark workloads. Ordinary Build and Tests must not execute them.

‎.github/workflows/Features/BenchmarkComparisons/QualifySite/action.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ runs:
123123
pwsh --version > "$EVIDENCE_DIR/powershell-version.txt"
124124
dotnet restore KeyLoad.slnx
125125
dotnet build src/KeyLoad.AppHost/KeyLoad.AppHost.csproj --no-restore --configuration Release
126-
dotnet build tests/KeyLoad.UnitTests/KeyLoad.UnitTests.csproj --no-restore --configuration Release
127-
dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/SiteQualificationStartupTests/*' --KeyLoadTests:ReportTrx=true "--KeyLoadTests:ResultsDirectory=$EVIDENCE_DIR/startup-tests"
128-
dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/SiteOptionalBenchmarkSelectionTests/*' --KeyLoadTests:ReportTrx=true "--KeyLoadTests:ResultsDirectory=$EVIDENCE_DIR/selection-tests"
126+
dotnet build tests/KeyLoad.ComparisonTests/KeyLoad.ComparisonTests.csproj --no-restore --configuration Release
127+
dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/SiteQualificationStartupTests/*' --KeyLoadTests:ReportTrx=true "--KeyLoadTests:ResultsDirectory=$EVIDENCE_DIR/startup-tests"
128+
dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/SiteOptionalBenchmarkSelectionTests/*' --KeyLoadTests:ReportTrx=true "--KeyLoadTests:ResultsDirectory=$EVIDENCE_DIR/selection-tests"
129129
dotnet build tests/KeyLoad.Analyzers.Tests/KeyLoad.Analyzers.Tests.csproj --no-restore --configuration Release
130130
mkdir -p "$EVIDENCE_DIR/analyzer-coverage"
131131
cp scripts/Features/CodeQuality/site-analyzer-coverage.settings.xml "$EVIDENCE_DIR/analyzer-coverage/coverage.config.xml"

‎.github/workflows/benchmarks.yml‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
comparison-build:
1212
name: Build and check KeyLoad
1313
runs-on: ubuntu-latest
14-
timeout-minutes: 30
14+
timeout-minutes: 120
1515
steps:
1616
- name: Download source code
1717
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -27,6 +27,21 @@ jobs:
2727
run: dotnet format KeyLoad.slnx --verify-no-changes --no-restore
2828
- name: Check repository rules
2929
run: node scripts/Features/RepositoryGovernance/verify.mjs
30+
- name: Test benchmark contracts
31+
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/KeyLoad.UnitTests*/*/*' --KeyLoadTests:ResultsDirectory=TestResults/benchmark-contracts --KeyLoadTests:ReportTrx=true
32+
- name: Test benchmark contracts without CPU intrinsics
33+
env:
34+
DOTNET_EnableHWIntrinsic: '0'
35+
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/KeyLoad.UnitTests*/*/*' --KeyLoadTests:ResultsDirectory=TestResults/benchmark-contracts-scalar --KeyLoadTests:ReportTrx=true
36+
- name: Test prompt termination on Aspire resource failures
37+
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/AspireFailure*/*' --KeyLoadTests:ResultsDirectory=TestResults/aspire-failure --KeyLoadTests:ReportTrx=true
38+
- name: Save benchmark contract test results
39+
if: always()
40+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
41+
with:
42+
name: benchmark-contract-tests
43+
path: TestResults/**
44+
if-no-files-found: error
3045
- name: Save build diagnostics
3146
if: always()
3247
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -84,10 +99,8 @@ jobs:
8499
- name: Build benchmark tests
85100
id: benchmark-build
86101
run: dotnet build tests/KeyLoad.ComparisonTests --no-restore --configuration Release
87-
- name: Build benchmark preparation unit tests
88-
run: dotnet build tests/KeyLoad.UnitTests --no-restore --configuration Release
89102
- name: Check bounded Docker registry readiness
90-
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/ImageRegistryReadinessTests/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/registry-readiness
103+
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/ImageRegistryReadinessTests/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/registry-readiness
91104
- name: Build KeyLoad server and benchmark Docker images
92105
id: images
93106
run: node scripts/Features/BenchmarkComparisons/prepare-images.mjs
@@ -141,9 +154,9 @@ jobs:
141154
- name: Test live benchmark progress capture
142155
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/ComparisonProgress*/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/live-progress
143156
- name: Test live benchmark process entry
144-
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/NativeBenchmarkProgressEntryTests/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/live-entry
157+
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/NativeBenchmarkProgressEntryTests/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/live-entry
145158
- name: Test benchmark phase and attempt counters
146-
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/ComparisonLiveProgress*/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/live-counters
159+
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/ComparisonLiveProgress*/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/live-counters
147160
- name: Test KeyLoad replay admission
148161
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/IsolatedKeyLoadReplayAdmissionTests/*' --KeyLoadTests:ResultsDirectory=TestResults/comparison-images/replay-admission
149162
- name: Test Redis replica error reporting

‎.github/workflows/build-and-tests.yml‎

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,6 @@ jobs:
144144
run: node scripts/Features/RepositoryGovernance/verify.mjs
145145
- name: Test code analyzers
146146
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=analyzers --KeyLoadTests:ReportTrx=true
147-
- name: Test prompt termination on Aspire resource failures
148-
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/AspireFailure*/*' --KeyLoadTests:ResultsDirectory=TestResults/aspire-failure --KeyLoadTests:ReportTrx=true
149-
- name: Test live benchmark progress capture
150-
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=comparison '--KeyLoadTests:Filter=/*/*/ComparisonProgress*/*' --KeyLoadTests:ResultsDirectory=TestResults/live-benchmark-progress --KeyLoadTests:ReportTrx=true
151-
- name: Test live benchmark process entry
152-
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/NativeBenchmarkProgressEntryTests/*' --KeyLoadTests:ResultsDirectory=TestResults/live-benchmark-entry --KeyLoadTests:ReportTrx=true
153-
- name: Test benchmark phase and attempt counters
154-
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/ComparisonLiveProgress*/*' --KeyLoadTests:ResultsDirectory=TestResults/live-benchmark-counters --KeyLoadTests:ReportTrx=true
155147
- name: Test native coverage source ownership
156148
id: source-ownership
157149
run: dotnet run --project src/KeyLoad.AppHost --no-build --no-restore --configuration Release -- --KeyLoadTests:Suite=unit '--KeyLoadTests:Filter=/*/*/(NativePathMapCompilerTests)|(ProductionSourceManifestSettlementTests)|(NativeSourceManifestChildSettlementTests)|(ProductionSourceManifestOperationTests)/*' --KeyLoadTests:ResultsDirectory=TestResults/native-source-ownership --KeyLoadTests:ReportTrx=true
@@ -212,17 +204,16 @@ jobs:
212204
global-json-file: global.json
213205
- name: Check Docker
214206
run: docker version
215-
- name: Build KeyLoad server and benchmark Docker images
207+
- name: Build KeyLoad server Docker image
216208
id: images
217-
run: node scripts/Features/BenchmarkComparisons/prepare-images.mjs
209+
run: node scripts/Features/BenchmarkComparisons/prepare-images.mjs --server-only
218210
- name: Configure Docker image references
219211
shell: bash
220212
env:
221213
KEYLOAD_SERVER_IMAGE: ${{ steps.images.outputs.server-image }}
222-
KEYLOAD_RUNNER_IMAGE: ${{ steps.images.outputs.load-generator-image }}
223214
run: |
224-
test -n "$KEYLOAD_SERVER_IMAGE" && test -n "$KEYLOAD_RUNNER_IMAGE"
225-
printf 'KeyLoad__ContainerImages__Server=%s\nBenchmarks__ContainerImages__LoadGenerator=%s\nKEYLOAD_IMAGE_RECEIPT=%s\n' "$KEYLOAD_SERVER_IMAGE" "$KEYLOAD_RUNNER_IMAGE" "$RUNNER_TEMP/keyload-images/image-receipt.json" >> "$GITHUB_ENV"
215+
test -n "$KEYLOAD_SERVER_IMAGE"
216+
printf 'KeyLoad__ContainerImages__Server=%s\nKEYLOAD_IMAGE_RECEIPT=%s\n' "$KEYLOAD_SERVER_IMAGE" "$RUNNER_TEMP/keyload-images/image-receipt.json" >> "$GITHUB_ENV"
226217
- name: Find Chrome for admin tests
227218
shell: bash
228219
run: |

‎AGENTS.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,3 +537,7 @@ A bounded website qualification candidate contains the20-project historical runt
537537
## Build and Tests workflow filename, owner direction 2026-10-06
538538

539539
- The canonical Build and Tests workflow is `.github/workflows/build-and-tests.yml`, renamed from `ci.yml`. Dispatch with `gh workflow run build-and-tests.yml --repo managedcode/KeyLoad --ref main`. This supersedes earlier active filename/dispatch references only; preserve all build/test gates, stable job IDs, permissions and historical evidence.
540+
541+
## Build and Tests scope, owner correction 2026-10-06
542+
543+
- Build and Tests MUST execute only solution builds, repository checks and KeyLoad functional tests, including analyzer, unit/scalar, process recovery and Aspire RF3 SDK/MCP tests. Benchmark/comparison tests, progress/entry/counter checks, load generators and comparison-image preparation MUST NOT execute there, even when stored in the unit-test project. Run them exclusively in the separate Benchmarks workflow; preserve their checks there. This explicit correction supersedes earlier placement of benchmark correctness checks in ordinary CI. Compiling the complete solution remains mandatory.

‎benchmarks/KeyLoad.BenchmarkScenarios/KeyLoad.BenchmarkScenarios.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
<PackageReference Include="BenchmarkDotNet" />
1111
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
1212
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" />
13-
<InternalsVisibleTo Include="KeyLoad.UnitTests" />
13+
<InternalsVisibleTo Include="KeyLoad.ComparisonTests" />
1414
</ItemGroup>
1515
</Project>

‎benchmarks/KeyLoad.ComparisonHost/Features/BenchmarkComparisons/Hosting/ComparisonHostTestFriend.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ namespace KeyLoad.ComparisonHost.Features.BenchmarkComparisons;
66

77
internal static class ComparisonHostTestFriend
88
{
9-
internal const string AssemblyName = "KeyLoad.UnitTests";
9+
internal const string AssemblyName = "KeyLoad.ComparisonTests";
1010
}

‎docs/ADR/ADR-074-aspire-owned-test-entry.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ minutes after original run37349838022 cancelled recovery at the old job limit.
1616
Keep unit, scalar and recovery sequential, every suite's native deadline and all
1717
required source/runtime/artifact gates. No timeout or failed suite becomes green.
1818

19+
## Build and Tests boundary, owner correction 2026-10-06
20+
21+
REQ/AC-TEST-PIPELINE-001 requires only functional KeyLoad suites in Build and
22+
Tests. Benchmark contract cases and exclusive helpers move from UnitTests to
23+
ComparisonTests/Features/BenchmarkComparisons/UnitContracts, preserving
24+
namespaces/assertions. Benchmarks owns their normal/scalar Aspire comparison
25+
execution and original TRX artifacts. Shared pure infrastructure retains one
26+
source compiled by both executables. Root owns TASK-TEST-PIPELINE-001..003 and
27+
integration. RF3 selects `prepare-images.mjs --server-only`: build/push/hash only
28+
the server image, with the same source-bound receipt/manifest and scoped registry
29+
cleanup. Benchmarks keeps both server and load-generator preparation. No database
30+
API or server-record receipt format changes. Verify native image-mode selection
31+
and rejection, transferred discovery inventory, solution build, formatter,
32+
governance and Aspire functional suites. Failed gates remain open; reverting
33+
this boundary requires owner direction.
34+
1935
## Decision and boundaries
2036

2137
`KeyLoad.AppHost --KeyLoadTests:Suite=<suite>` composes one actual Aspire

‎docs/ADR/ADR-085-live-benchmark-progress.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ timeout would hide slow execution and cannot qualify the workload.
3131
4. Root owns the process relay scripts, workflow/test integration and docs. Retain
3232
canonical dotnet/AppHost invocation, original exit and signal handling. No
3333
independent database startup or global process termination is permitted.
34-
CI runs focused native progress capture regressions independently of the
35-
complete Benchmarks matrix; these do not qualify a database workload.
34+
Benchmarks runs focused native progress capture regressions independently of
35+
its complete measurement matrix; these do not qualify a database workload.
3636
5. Root reviews every diff, builds, runs real focused Aspire/TUnit checks, format
3737
and governance; commits only this repair and pushes under standing authority.
3838
Actual Linux CI/native workload/cancellation artifacts supply delivered proof.

0 commit comments

Comments
 (0)