From 24f898c54d7c6547555a4402543b6a3cd7ced7f6 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 24 Jul 2026 13:21:08 +0200 Subject: [PATCH] fix(diag): identify the binary measured by soak reports --- .../ConnectedR6SoakContractTests.cs | 29 ++++++++++++ tools/run-connected-r6-soak.ps1 | 44 +++++++++++++++++-- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/tests/AcDream.App.Tests/Diagnostics/ConnectedR6SoakContractTests.cs b/tests/AcDream.App.Tests/Diagnostics/ConnectedR6SoakContractTests.cs index 81597771..60130c5e 100644 --- a/tests/AcDream.App.Tests/Diagnostics/ConnectedR6SoakContractTests.cs +++ b/tests/AcDream.App.Tests/Diagnostics/ConnectedR6SoakContractTests.cs @@ -289,6 +289,35 @@ public sealed class ConnectedR6SoakContractTests Assert.Contains("$env:ACDREAM_DUMP_MOVE_TRUTH = '1'", source, StringComparison.Ordinal); } + [Fact] + public void BaselineIdentityComesFromTheMeasuredBinaryRatherThanOnlyTheCheckout() + { + string source = File.ReadAllText(Path.Combine( + FindRepoRoot(), + "tools", + "run-connected-r6-soak.ps1")); + + AssertAppearsInOrder( + source, + "$sourceCommit = (& git -C $Repository rev-parse HEAD).Trim()", + "[Diagnostics.FileVersionInfo]::GetVersionInfo($exe).ProductVersion", + "$binaryCommitMatch = [regex]::Match(", + "$commit = if ($null -ne $binaryCommit) { $binaryCommit } else { $sourceCommit }", + "$binaryMatchesSource = $null -ne $binaryCommit -and $binaryCommit -eq $sourceCommit"); + Assert.Contains( + "status --short --untracked-files=no", + source, + StringComparison.Ordinal); + Assert.Contains("BinaryProductVersion = $binaryProductVersion", source); + Assert.Contains("BinaryCommit = $binaryCommit", source); + Assert.Contains("BinaryMatchesSource = $binaryMatchesSource", source); + Assert.Contains("TrackedSourceStatus = @($sourceStatus)", source); + Assert.Contains( + "measured binary commit $binaryCommit differs from checked-out source commit $sourceCommit", + source, + StringComparison.Ordinal); + } + [Fact] public void SoakExportsAndSummarizesFrameHistory() { diff --git a/tools/run-connected-r6-soak.ps1 b/tools/run-connected-r6-soak.ps1 index 774c4496..9111a48f 100644 --- a/tools/run-connected-r6-soak.ps1 +++ b/tools/run-connected-r6-soak.ps1 @@ -625,8 +625,35 @@ if (-not $SkipBuild) { if (-not (Test-Path -LiteralPath $exe)) { throw "client executable not found: $exe" } if (-not (Test-Path -LiteralPath $cliDll)) { throw "CLI assembly not found: $cliDll" } -$commit = (& git -C $Repository rev-parse HEAD).Trim() -$sourceStatus = @(& git -C $Repository status --short) +$sourceCommit = (& git -C $Repository rev-parse HEAD).Trim() +# -SkipBuild is intentionally supported, so the checked-out source commit is +# not necessarily the binary being measured. Read the SDK-stamped +# AssemblyInformationalVersion from the executable and make the BINARY commit +# the baseline identity. Otherwise a docs-only commit after a build can +# silently mislabel every performance artifact. +$binaryProductVersion = [Diagnostics.FileVersionInfo]::GetVersionInfo($exe).ProductVersion +$binaryCommitMatch = [regex]::Match( + [string]$binaryProductVersion, + '\+([0-9a-fA-F]{40})(?:\.|$)') +$binaryCommit = if ($binaryCommitMatch.Success) { + $binaryCommitMatch.Groups[1].Value.ToLowerInvariant() +} +else { + $null +} +$commit = if ($null -ne $binaryCommit) { $binaryCommit } else { $sourceCommit } +$binaryMatchesSource = $null -ne $binaryCommit -and $binaryCommit -eq $sourceCommit +# Generated logs and artifacts may be untracked beside a clean source tree. +# The reproducibility contract is about tracked source modifications. +$sourceStatus = @(& git -C $Repository status --short --untracked-files=no) +if ($null -eq $binaryCommit) { + $failures.Add( + "client binary ProductVersion '$binaryProductVersion' does not identify a 40-character source commit") +} +elseif (-not $binaryMatchesSource) { + $warnings.Add( + "measured binary commit $binaryCommit differs from checked-out source commit $sourceCommit") +} $videoControllers = @(Get-CimInstance Win32_VideoController -ErrorAction SilentlyContinue | ForEach-Object { [pscustomobject]@{ Name = $_.Name; DriverVersion = $_.DriverVersion; AdapterRam = $_.AdapterRAM } }) @@ -670,6 +697,11 @@ $acdreamEnvVars = Get-ChildItem Env: | Where-Object { $_.Name -like 'ACDREAM_*' $envDisclosure = [pscustomobject][ordered]@{ Script = 'run-connected-r6-soak.ps1' GeneratedUtc = [DateTime]::UtcNow.ToString('O') + SourceCommit = $sourceCommit + BinaryProductVersion = $binaryProductVersion + BinaryCommit = $binaryCommit + BinaryMatchesSource = $binaryMatchesSource + TrackedSourceStatus = @($sourceStatus) Uncapped = [bool]$Uncapped DenseTown = [bool]$DenseTown CaptureContention = [bool]$CaptureContention @@ -683,7 +715,9 @@ $envDisclosure | ConvertTo-Json -Depth 4 | try { $process = Start-Process -FilePath $exe -WorkingDirectory $Repository ` -RedirectStandardOutput $stdoutLog -RedirectStandardError $stderrLog -PassThru - Write-Marker "launch pid=$($process.Id) commit=$commit session='$env:SESSIONNAME'" + Write-Marker ( + "launch pid=$($process.Id) binaryCommit=$commit sourceCommit=$sourceCommit " + + "binaryMatchesSource=$binaryMatchesSource session='$env:SESSIONNAME'") $null = Wait-ForLogPattern $process $stdoutLog 'live: in world' 1 $LoginTimeoutSeconds # Attach EventPipe observers only after normal CLR/client startup. Starting @@ -866,6 +900,10 @@ finally { FinishedUtc = [DateTime]::UtcNow.ToString('O') ElapsedSeconds = [Math]::Round($stopwatch.Elapsed.TotalSeconds, 3) Commit = $commit + SourceCommit = $sourceCommit + BinaryProductVersion = $binaryProductVersion + BinaryCommit = $binaryCommit + BinaryMatchesSource = $binaryMatchesSource SessionName = $env:SESSIONNAME ExitCode = $exitCode GracefulExit = $gracefulExit