Skip to content

Commit 7178457

Browse files
KSemenenkoclaude
andcommitted
test(site): bound isolated Node probes by caller cancellation only
Website runs 40488439737 and 40492531026 failed 52 tests at about 4m59s: SiteIsolatedFixture's projection probe re-derives every measured value from the original session archives and was killed by the fixed 300-second IsolatedProcessDeadline. Both runs used the same benchmark producer (9c30d28, run 40457815454) as the passing run 40482513353; that cohort adds a full three-node OpenSearch session, so the real work now sits at the invented limit and passes or fails by runner speed. Remove IsolatedProcessDeadline per the owner's rule against fixed test deadlines: isolated Node probes and GitHub probes now run until they exit or the test session cancels them. GitHub capture transfers keep their existing bound. No test or assertion changes. Verified locally: KeyLoad.WebsiteTests build -warnaserror and format verify. Qualification is the next Website run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 130da16 commit 7178457

5 files changed

Lines changed: 11 additions & 13 deletions

File tree

‎site/Features/BenchmarkComparisons/protocol.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ CPU, allocation and peak RSS are process observations over the lane interval; ov
4444

4545
## TUnit, builder and coverage
4646

47-
All tests are TUnit. `SessionCohortContractTests` and `SiteSessionContractCoverageTests` execute the single controlled `session-contract-probe.mjs`, which imports the actual production modules. Nine scenarios cover plan, reports, selection, environment, qualification, runtime, site-context, publication and profile-accounting. They verify positive inputs and specific identity/accounting/admission mutations; their values never enter published artifacts. Node children have bounded concurrent stdout/stderr, a deadline and joined ownership; Website children inherit the real `NODE_V8_COVERAGE`.
47+
All tests are TUnit. `SessionCohortContractTests` and `SiteSessionContractCoverageTests` execute the single controlled `session-contract-probe.mjs`, which imports the actual production modules. Nine scenarios cover plan, reports, selection, environment, qualification, runtime, site-context, publication and profile-accounting. They verify positive inputs and specific identity/accounting/admission mutations; their values never enter published artifacts. Node children have bounded concurrent stdout/stderr, caller cancellation instead of a fixed deadline, and joined ownership; Website children inherit the real `NODE_V8_COVERAGE`.
4848

4949
An independent C# oracle computes the expected per-case/lane values from authenticated originals. Real Chrome/CDP sessions load builder-emitted assets through a confined ephemeral HTTP listener and verify controls, keyboard/accessibility, raw hash rejection, cancellation and stale generations. Scene regressions and coverage converter regressions are retained.
5050

‎tests/KeyLoad.WebsiteTests/Configuration/SiteExecutionConfiguration.cs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ private static IOptions<SiteExecutionOptions> Bind()
1414
policy.BrowserStartupTimeout, policy.NavigationPollDelay, policy.NoScriptPoll,
1515
policy.SceneIdleWait, policy.SceneSettleWait, policy.ChildDeadline, policy.ChildPoll,
1616
policy.ChildQueueDeadline, policy.CleanupTimeout, policy.NodeTimeout,
17-
policy.StaticHostTimeout, policy.AdmissionDeadline, policy.GitHubDeadline,
18-
policy.IsolatedProcessDeadline];
17+
policy.StaticHostTimeout, policy.AdmissionDeadline, policy.GitHubDeadline];
1918
foreach (var duration in durations)
2019
{
2120
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(duration, TimeSpan.Zero);

‎tests/KeyLoad.WebsiteTests/Configuration/SiteExecutionOptions.cs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ internal sealed class SiteExecutionOptions
1818
public TimeSpan StaticHostTimeout { get; set; } = TimeSpan.FromSeconds(5);
1919
public TimeSpan AdmissionDeadline { get; set; } = TimeSpan.FromMinutes(20);
2020
public TimeSpan GitHubDeadline { get; set; } = TimeSpan.FromMinutes(120);
21-
public TimeSpan IsolatedProcessDeadline { get; set; } = TimeSpan.FromSeconds(300);
2221
public int BrowserSessionCapacity { get; set; } = 1;
2322
public int MaximumQueued { get; set; } = 64;
2423
public int HeavyChildCapacity { get; set; } = 2;

‎tests/KeyLoad.WebsiteTests/Processes/SiteIsolated/SiteIsolatedGitHubProcess.cs‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ public static Task<SiteProcessResult> RunAsync(ProcessStartInfo start, Cancellat
99

1010
public static Task<SiteProcessResult> RunProbeAsync(ProcessStartInfo start, CancellationToken token,
1111
SiteHeavyChildAdmission? admission = null) =>
12-
RunAsync(start, SiteExecutionConfiguration.Options.Value.IsolatedProcessDeadline, admission, token);
12+
RunAsync(start, bound: null, admission, token);
1313

14-
private static async Task<SiteProcessResult> RunAsync(ProcessStartInfo start, TimeSpan bound,
14+
private static async Task<SiteProcessResult> RunAsync(ProcessStartInfo start, TimeSpan? bound,
1515
SiteHeavyChildAdmission? admission, CancellationToken token)
1616
{
1717
using var lease = admission is null ? null : await admission.AcquireAsync(token);
@@ -23,8 +23,9 @@ private static async Task<SiteProcessResult> RunAsync(ProcessStartInfo start, Ti
2323
}
2424
lease?.MarkStarted(process);
2525

26-
using var deadlineTimeout = new CancellationTokenSource(bound, TimeProvider.System);
27-
using var deadline = CancellationTokenSource.CreateLinkedTokenSource(token, deadlineTimeout.Token);
26+
// Probes run until they exit or the caller cancels; only remote GitHub captures keep their transport bound.
27+
using var deadlineTimeout = bound is null ? null : new CancellationTokenSource(bound.Value, TimeProvider.System);
28+
using var deadline = CancellationTokenSource.CreateLinkedTokenSource(token, deadlineTimeout?.Token ?? CancellationToken.None);
2829
var stdout = SiteIsolatedGitHubProcessOutput.ReadAsync(process.StandardOutput,
2930
SiteIsolatedGitHubProcessOutput.MaximumOutputCharacters, deadline.Token);
3031
var stderr = SiteIsolatedGitHubProcessOutput.ReadAsync(process.StandardError,

‎tests/KeyLoad.WebsiteTests/Processes/SiteIsolated/SiteIsolatedNodeProcess.cs‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,12 @@ public static async Task<SiteProcessResult> RunProcessAsync(ProcessStartInfo sta
4343
}
4444
lease?.MarkStarted(process);
4545

46-
using var deadlineTimeout = new CancellationTokenSource(SiteExecutionConfiguration.Options.Value.IsolatedProcessDeadline, TimeProvider.System);
47-
using var deadline = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, deadlineTimeout.Token);
48-
var stdout = SiteProcessOutput.ReadAsync(process.StandardOutput, ProbeFailure, deadline.Token);
49-
var stderr = SiteProcessOutput.ReadAsync(process.StandardError, ProbeFailure, deadline.Token);
46+
// Real projection work is bounded by the caller's cancellation, not by an invented fixed deadline.
47+
var stdout = SiteProcessOutput.ReadAsync(process.StandardOutput, ProbeFailure, cancellationToken);
48+
var stderr = SiteProcessOutput.ReadAsync(process.StandardError, ProbeFailure, cancellationToken);
5049
try
5150
{
52-
var exit = process.WaitForExitAsync(deadline.Token);
51+
var exit = process.WaitForExitAsync(cancellationToken);
5352
var first = await Task.WhenAny(exit, stdout, stderr).ConfigureAwait(false);
5453
await first.ConfigureAwait(false);
5554
await exit.ConfigureAwait(false);

0 commit comments

Comments
 (0)