Skip to content

[quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

Description

@github-actions

🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

Analysis Date: 2026-08-31
Focus Area: CI Timing-Assertion Robustness (custom)
Strategy Type: Custom

Executive Summary

Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

Full Analysis Report

Focus Area: CI Timing-Assertion Robustness

Current State Assessment

Metrics Collected:

MetricValueStatus
Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
Assertions with an explanatory comment about the chosen margin0 / 4
Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

Findings

Strengths

  • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
  • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

Areas for Improvement

  • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
  • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
  • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
  • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

🤖 Suggested Improvement Tasks

Task 1: Add contributor guidance for elapsed-time upper-bound assertions

Priority: Medium
Estimated Effort: Small

Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

Priority: High
Estimated Effort: Small

In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

Priority: Medium
Estimated Effort: Small

In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

Priority: Low
Estimated Effort: Small

In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

Priority: Low
Estimated Effort: Medium

Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


📊 Historical Context

Previous Focus Areas
DateFocus AreaType
2026-08-24embedded-project-packability-intent-clarityCustom
2026-08-25package-readme-content-parity-gapCustom
2026-08-26videorecorder-core-logic-test-coverage-gapCustom
2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
2026-08-28trx-report-metadata-parity-gapCustom

🎯 Recommendations

Immediate Actions (This Week)

  1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

Short-term Actions (This Month)

  1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
  2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

Add this agentic workflow to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
  • expires on Sep 2, 2026, 10:30 PM UTC

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) · Issue #10899 · microsoft/testfx · GitHub
      Skip to content

      [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

      Description

      @github-actions

      🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

      Analysis Date: 2026-08-31
      Focus Area: CI Timing-Assertion Robustness (custom)
      Strategy Type: Custom

      Executive Summary

      Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

      This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

      Full Analysis Report

      Focus Area: CI Timing-Assertion Robustness

      Current State Assessment

      Metrics Collected:

      MetricValueStatus
      Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
      Assertions with an explanatory comment about the chosen margin0 / 4
      Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
      Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

      Findings

      Strengths

      • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
      • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

      Areas for Improvement

      • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
      • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
      • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
      • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

      🤖 Suggested Improvement Tasks

      Task 1: Add contributor guidance for elapsed-time upper-bound assertions

      Priority: Medium
      Estimated Effort: Small

      Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

      Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

      Priority: High
      Estimated Effort: Small

      In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

      Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

      Priority: Medium
      Estimated Effort: Small

      In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

      Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

      Priority: Low
      Estimated Effort: Small

      In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

      Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

      Priority: Low
      Estimated Effort: Medium

      Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


      📊 Historical Context

      Previous Focus Areas
      DateFocus AreaType
      2026-08-24embedded-project-packability-intent-clarityCustom
      2026-08-25package-readme-content-parity-gapCustom
      2026-08-26videorecorder-core-logic-test-coverage-gapCustom
      2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
      2026-08-28trx-report-metadata-parity-gapCustom

      🎯 Recommendations

      Immediate Actions (This Week)

      1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

      Short-term Actions (This Month)

      1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
      2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

      Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

      🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

      Add this agentic workflow to your repo

      To install this agentic workflow, run

      gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
      
      • expires on Sep 2, 2026, 10:30 PM UTC

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) · Issue #10899 · microsoft/testfx · GitHub
          Skip to content

          [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

          Description

          @github-actions

          🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

          Analysis Date: 2026-08-31
          Focus Area: CI Timing-Assertion Robustness (custom)
          Strategy Type: Custom

          Executive Summary

          Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

          This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

          Full Analysis Report

          Focus Area: CI Timing-Assertion Robustness

          Current State Assessment

          Metrics Collected:

          MetricValueStatus
          Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
          Assertions with an explanatory comment about the chosen margin0 / 4
          Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
          Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

          Findings

          Strengths

          • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
          • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

          Areas for Improvement

          • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
          • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
          • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
          • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

          🤖 Suggested Improvement Tasks

          Task 1: Add contributor guidance for elapsed-time upper-bound assertions

          Priority: Medium
          Estimated Effort: Small

          Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

          Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

          Priority: High
          Estimated Effort: Small

          In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

          Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

          Priority: Medium
          Estimated Effort: Small

          In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

          Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

          Priority: Low
          Estimated Effort: Small

          In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

          Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

          Priority: Low
          Estimated Effort: Medium

          Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


          📊 Historical Context

          Previous Focus Areas
          DateFocus AreaType
          2026-08-24embedded-project-packability-intent-clarityCustom
          2026-08-25package-readme-content-parity-gapCustom
          2026-08-26videorecorder-core-logic-test-coverage-gapCustom
          2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
          2026-08-28trx-report-metadata-parity-gapCustom

          🎯 Recommendations

          Immediate Actions (This Week)

          1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

          Short-term Actions (This Month)

          1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
          2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

          Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

          🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

          Add this agentic workflow to your repo

          To install this agentic workflow, run

          gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
          
          • expires on Sep 2, 2026, 10:30 PM UTC

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) · Issue #10899 · microsoft/testfx · GitHub
              Skip to content

              [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

              Description

              @github-actions

              🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

              Analysis Date: 2026-08-31
              Focus Area: CI Timing-Assertion Robustness (custom)
              Strategy Type: Custom

              Executive Summary

              Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

              This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

              Full Analysis Report

              Focus Area: CI Timing-Assertion Robustness

              Current State Assessment

              Metrics Collected:

              MetricValueStatus
              Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
              Assertions with an explanatory comment about the chosen margin0 / 4
              Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
              Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

              Findings

              Strengths

              • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
              • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

              Areas for Improvement

              • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
              • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
              • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
              • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

              🤖 Suggested Improvement Tasks

              Task 1: Add contributor guidance for elapsed-time upper-bound assertions

              Priority: Medium
              Estimated Effort: Small

              Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

              Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

              Priority: High
              Estimated Effort: Small

              In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

              Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

              Priority: Medium
              Estimated Effort: Small

              In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

              Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

              Priority: Low
              Estimated Effort: Small

              In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

              Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

              Priority: Low
              Estimated Effort: Medium

              Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


              📊 Historical Context

              Previous Focus Areas
              DateFocus AreaType
              2026-08-24embedded-project-packability-intent-clarityCustom
              2026-08-25package-readme-content-parity-gapCustom
              2026-08-26videorecorder-core-logic-test-coverage-gapCustom
              2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
              2026-08-28trx-report-metadata-parity-gapCustom

              🎯 Recommendations

              Immediate Actions (This Week)

              1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

              Short-term Actions (This Month)

              1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
              2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

              Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

              🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

              Add this agentic workflow to your repo

              To install this agentic workflow, run

              gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
              
              • expires on Sep 2, 2026, 10:30 PM UTC

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) · Issue #10899 · microsoft/testfx · GitHub
                  Skip to content

                  [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

                  Description

                  @github-actions

                  🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

                  Analysis Date: 2026-08-31
                  Focus Area: CI Timing-Assertion Robustness (custom)
                  Strategy Type: Custom

                  Executive Summary

                  Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

                  This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

                  Full Analysis Report

                  Focus Area: CI Timing-Assertion Robustness

                  Current State Assessment

                  Metrics Collected:

                  MetricValueStatus
                  Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
                  Assertions with an explanatory comment about the chosen margin0 / 4
                  Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
                  Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

                  Findings

                  Strengths

                  • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
                  • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

                  Areas for Improvement

                  • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
                  • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
                  • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
                  • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

                  🤖 Suggested Improvement Tasks

                  Task 1: Add contributor guidance for elapsed-time upper-bound assertions

                  Priority: Medium
                  Estimated Effort: Small

                  Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

                  Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

                  Priority: High
                  Estimated Effort: Small

                  In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

                  Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

                  Priority: Medium
                  Estimated Effort: Small

                  In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

                  Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

                  Priority: Low
                  Estimated Effort: Small

                  In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

                  Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

                  Priority: Low
                  Estimated Effort: Medium

                  Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


                  📊 Historical Context

                  Previous Focus Areas
                  DateFocus AreaType
                  2026-08-24embedded-project-packability-intent-clarityCustom
                  2026-08-25package-readme-content-parity-gapCustom
                  2026-08-26videorecorder-core-logic-test-coverage-gapCustom
                  2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
                  2026-08-28trx-report-metadata-parity-gapCustom

                  🎯 Recommendations

                  Immediate Actions (This Week)

                  1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

                  Short-term Actions (This Month)

                  1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
                  2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

                  Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

                  🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

                  Add this agentic workflow to your repo

                  To install this agentic workflow, run

                  gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
                  
                  • expires on Sep 2, 2026, 10:30 PM UTC

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) · Issue #10899 · microsoft/testfx · GitHub
                      Skip to content

                      [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

                      Description

                      @github-actions

                      🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

                      Analysis Date: 2026-08-31
                      Focus Area: CI Timing-Assertion Robustness (custom)
                      Strategy Type: Custom

                      Executive Summary

                      Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

                      This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

                      Full Analysis Report

                      Focus Area: CI Timing-Assertion Robustness

                      Current State Assessment

                      Metrics Collected:

                      MetricValueStatus
                      Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
                      Assertions with an explanatory comment about the chosen margin0 / 4
                      Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
                      Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

                      Findings

                      Strengths

                      • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
                      • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

                      Areas for Improvement

                      • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
                      • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
                      • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
                      • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

                      🤖 Suggested Improvement Tasks

                      Task 1: Add contributor guidance for elapsed-time upper-bound assertions

                      Priority: Medium
                      Estimated Effort: Small

                      Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

                      Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

                      Priority: High
                      Estimated Effort: Small

                      In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

                      Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

                      Priority: Medium
                      Estimated Effort: Small

                      In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

                      Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

                      Priority: Low
                      Estimated Effort: Small

                      In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

                      Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

                      Priority: Low
                      Estimated Effort: Medium

                      Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


                      📊 Historical Context

                      Previous Focus Areas
                      DateFocus AreaType
                      2026-08-24embedded-project-packability-intent-clarityCustom
                      2026-08-25package-readme-content-parity-gapCustom
                      2026-08-26videorecorder-core-logic-test-coverage-gapCustom
                      2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
                      2026-08-28trx-report-metadata-parity-gapCustom

                      🎯 Recommendations

                      Immediate Actions (This Week)

                      1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

                      Short-term Actions (This Month)

                      1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
                      2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

                      Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

                      🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

                      Add this agentic workflow to your repo

                      To install this agentic workflow, run

                      gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
                      
                      • expires on Sep 2, 2026, 10:30 PM UTC

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) · Issue #10899 · microsoft/testfx · GitHub
                          Skip to content

                          [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

                          Description

                          @github-actions

                          🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

                          Analysis Date: 2026-08-31
                          Focus Area: CI Timing-Assertion Robustness (custom)
                          Strategy Type: Custom

                          Executive Summary

                          Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

                          This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

                          Full Analysis Report

                          Focus Area: CI Timing-Assertion Robustness

                          Current State Assessment

                          Metrics Collected:

                          MetricValueStatus
                          Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
                          Assertions with an explanatory comment about the chosen margin0 / 4
                          Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
                          Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

                          Findings

                          Strengths

                          • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
                          • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

                          Areas for Improvement

                          • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
                          • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
                          • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
                          • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

                          🤖 Suggested Improvement Tasks

                          Task 1: Add contributor guidance for elapsed-time upper-bound assertions

                          Priority: Medium
                          Estimated Effort: Small

                          Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

                          Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

                          Priority: High
                          Estimated Effort: Small

                          In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

                          Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

                          Priority: Medium
                          Estimated Effort: Small

                          In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

                          Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

                          Priority: Low
                          Estimated Effort: Small

                          In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

                          Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

                          Priority: Low
                          Estimated Effort: Medium

                          Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


                          📊 Historical Context

                          Previous Focus Areas
                          DateFocus AreaType
                          2026-08-24embedded-project-packability-intent-clarityCustom
                          2026-08-25package-readme-content-parity-gapCustom
                          2026-08-26videorecorder-core-logic-test-coverage-gapCustom
                          2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
                          2026-08-28trx-report-metadata-parity-gapCustom

                          🎯 Recommendations

                          Immediate Actions (This Week)

                          1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

                          Short-term Actions (This Month)

                          1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
                          2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

                          Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

                          🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

                          Add this agentic workflow to your repo

                          To install this agentic workflow, run

                          gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
                          
                          • expires on Sep 2, 2026, 10:30 PM UTC

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) · Issue #10899 · microsoft/testfx · GitHub
                              Skip to content

                              [quality-improver] Acceptance tests assert hardcoded upper bounds on wall-clock stopwatch elapsed time (CI timing flakiness risk) #10899

                              Description

                              @github-actions

                              🎯 Repository Quality Improvement Report — CI Timing-Assertion Robustness

                              Analysis Date: 2026-08-31
                              Focus Area: CI Timing-Assertion Robustness (custom)
                              Strategy Type: Custom

                              Executive Summary

                              Several acceptance tests measure the wall-clock duration of an end-to-end test-host process launch with a Stopwatch and then assert an upper bound on the elapsed seconds (e.g. Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...)). Unlike the project's own AcceptanceAssert.DurationPattern guidance — which correctly avoids hardcoding a rendered test-duration string because that format grows leading parts on slow machines — these assertions hardcode a process-launch timing budget that is not tied to any configured timeout and has no adaptive/environment-aware justification. On a loaded CI runner (macOS/Windows agents are called out in the repo's own testing guidelines as slower), simply starting a .NET test host, letting Environment.ProcessorCount * 5 data consumers register, or tearing down a TestHostControllerFinalization step can legitimately exceed a few seconds without any product regression, causing an intermittent, hard-to-reproduce CI failure that has nothing to do with the behavior under test.

                              This is distinct from the already-documented DurationPattern guidance (which is about not hardcoding the rendered(NNNms) string) — these are separate, additional hardcoded numeric ceilings on real host process wall-clock time, currently present in at least three acceptance test files. None of the four affected assertions currently carry a comment explaining the margin chosen or a fallback/inconclusive path if the timing budget is exceeded on a slow agent.

                              Full Analysis Report

                              Focus Area: CI Timing-Assertion Robustness

                              Current State Assessment

                              Metrics Collected:

                              MetricValueStatus
                              Acceptance test files asserting Assert.IsLessThan(N, stopwatch.Elapsed.TotalSeconds, ...)3 files, 4 assertion sites⚠️
                              Assertions with an explanatory comment about the chosen margin0 / 4
                              Existing repo guidance covering rendered-duration hardcoding (DurationPattern)Present and followed
                              Existing repo guidance covering stopwatch upper-bound hardcodingAbsent

                              Findings

                              Strengths

                              • The repo already has strong tooling (AcceptanceAssert.DurationPattern) and explicit contributor guidance against hardcoding rendered per-test duration strings like \(\d+ms\).
                              • Most timing-sensitive acceptance tests use rendezvous/barrier-based assertions (e.g. TestDependencyExecutionTests) instead of elapsed-time comparisons, which is the more robust pattern already used elsewhere in the same file set.

                              Areas for Improvement

                              • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.csTimeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler (line 69) and Timeout_BoundsBlockingDisposalWithoutRetryingIt (line 95) each assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) around a full process launch + a 500ms-configured timeout + a 0.5s finalization budget, leaving under an 6.5x margin that is easily consumed by CI process-start overhead alone.
                              • ⚠️test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.csMultipleDataConsumers_ShouldCompleteInReasonableTime (line 24) asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...) around registering Environment.ProcessorCount * 5 data consumers and running a full host process; the margin scales with core count in an untested way and has no comment justifying "7".
                              • ⚠️test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.csRunAndAssertAttributeTakesPrecedenceAsync (line 175) asserts Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds) against a runsettings-configured 25000ms timeout value that is baked into the same helper, i.e. the assertion and the fixture-under-test share the exact same magic number with no tolerance margin at all — a process-launch overhead of even a few hundred milliseconds beyond the configured timeout will fail the assertion.
                              • ❌ None of the four sites include a comment recording why the specific number was chosen or what margin over the "expected" duration it represents, making it hard for a future maintainer to know whether a CI failure here is a real regression or normal environment noise.

                              🤖 Suggested Improvement Tasks

                              Task 1: Add contributor guidance for elapsed-time upper-bound assertions

                              Priority: Medium
                              Estimated Effort: Small

                              Extend the existing "Testing Guidelines" documentation (the same section that already covers AcceptanceAssert.DurationPattern) with a short rule: when an acceptance test asserts an upper bound on Stopwatch.Elapsed around a real process launch, the assertion must include a comment explaining the margin relative to any configured timeout/budget in the same test, and the margin must generously exceed known slow-CI overhead (process start + JIT + host teardown), not just the nominal timeout value.

                              Task 2: Give TimeoutWhenExpiresTests.RunAndAssertAttributeTakesPrecedenceAsync a real margin over its own configured timeout

                              Priority: High
                              Estimated Effort: Small

                              In test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutWhenExpiresTests.cs, the runsettings value injected into <{runSettingsEntry}>25000</{runSettingsEntry}> and the assertion Assert.IsLessThan(25, stopwatch.Elapsed.TotalSeconds); (line 175) use the same 25-second figure, leaving zero slack for process launch/build overhead. Increase the assertion's threshold to a value that comfortably exceeds the configured timeout (e.g. 25s timeout + several seconds of host-launch margin) and add a comment stating the relationship, so the test measures "the timeout attribute value took precedence, and the host still terminated promptly after it fired" rather than a tight race against the same number.

                              Task 3: Re-examine the TestHostProcessLifetimeHandlerTests 8-second ceilings

                              Priority: Medium
                              Estimated Effort: Small

                              In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs, Timeout_BoundsBlockingFinalizationWithoutDisposingRunningHandler and Timeout_BoundsBlockingDisposalWithoutRetryingIt both assert Assert.IsLessThan(8, stopwatch.Elapsed.TotalSeconds, ...) against a --timeout 500ms configuration and TESTINGPLATFORM_TESTHOSTCONTROLLER_FINALIZATION_TIMEOUT_SECONDS=0.5. Document (in a comment) how the 8-second figure was derived (e.g., process launch overhead budget + configured 0.5s finalization timeout + safety factor) so a future flaky-test triage can tell at a glance whether an observed 8.5s run is a real regression or expected CI noise, and consider whether a larger constant is warranted given other CI slow-agent evidence already documented in the repo's testing guidelines (macOS/Windows durations growing under load).

                              Task 4: Document the DataConsumerThroughputTests 7-second budget's dependency on core count

                              Priority: Low
                              Estimated Effort: Small

                              In test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DataConsumerThroughputTests.cs, MultipleDataConsumers_ShouldCompleteInReasonableTime registers Environment.ProcessorCount * 5 data consumers and then asserts Assert.IsLessThan(7, stopwatch.Elapsed.TotalSeconds, ...). Add a comment noting that the workload scales with Environment.ProcessorCount, so the 7-second budget should be revisited if CI agents change core counts, and consider whether the assertion should scale the threshold with Environment.ProcessorCount rather than using a single flat constant.

                              Task 5: Prefer rendezvous/barrier-based assertions over elapsed-time ceilings where feasible

                              Priority: Low
                              Estimated Effort: Medium

                              Where practical, follow the pattern already used in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDependencyExecutionTests.cs (DependsOn_RunsPrerequisitesFirst_AndLetsIndependentBranchesOverlap), which asserts overlap via an in-process rendezvous/barrier signal recorded by the generated asset rather than comparing elapsed wall-clock time. This removes CI-load sensitivity entirely for cases that are really checking "did X happen concurrently/promptly" rather than "did X complete within N seconds." Not every timing assertion can be converted (e.g., the true measurement of "the process actually respects --timeout" inherently needs a wall clock), but each of the four sites above should be evaluated for whether a deterministic signal-based check could replace or tighten the loose stopwatch-based one.


                              📊 Historical Context

                              Previous Focus Areas
                              DateFocus AreaType
                              2026-08-24embedded-project-packability-intent-clarityCustom
                              2026-08-25package-readme-content-parity-gapCustom
                              2026-08-26videorecorder-core-logic-test-coverage-gapCustom
                              2026-08-28githubactions-feature-activation-logic-coverage-gapCustom
                              2026-08-28trx-report-metadata-parity-gapCustom

                              🎯 Recommendations

                              Immediate Actions (This Week)

                              1. Fix the zero-margin TimeoutWhenExpiresTests assertion (Task 2) — Priority: High

                              Short-term Actions (This Month)

                              1. Add contributor guidance and document the derivation of the other three hardcoded thresholds (Tasks 1, 3, 4) — Priority: Medium
                              2. Evaluate converting elapsed-time ceilings to deterministic rendezvous-based checks where feasible (Task 5) — Priority: Low

                              Next analysis: 2026-09-01 — Focus area selected based on diversity algorithm

                              🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · auto · 135.3 AIC · ⌖ 3.44 AIC · ⊞ 16.8K · [◷]( · )

                              Add this agentic workflow to your repo

                              To install this agentic workflow, run

                              gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
                              
                              • expires on Sep 2, 2026, 10:30 PM UTC

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions