Skip to content

Correct HTTP/2 stream window cap test expectations - #133942

Merged
rzikm merged 1 commit into
dotnet:mainfrom
rzikm:rzikm/http2-flow-control-fix
Sep 15, 2026
Merged

rzikm merged 1 commit into
dotnet:mainfrom
rzikm:rzikm/http2-flow-control-fix

Conversation

@rzikm

@rzikm rzikm commented Sep 15, 2026 •

Copy link
Copy Markdown
Member

Fixes failure in System.Net.Http.Functional.Tests.SocketsHttpHandler_Http2FlowControl_Test.MaxStreamWindowSize_WhenSet_WindowDoesNotScaleAboveMaximum observed e.g. in

https://helixr18s23ayyejvk1x8qcc.blob.core.windows.net/dotnet-runtime-refs-heads-main-599d096511a54659b1/System.Net.Http.Functional.Tests/1/console.a3d71edc.log?helixlogtype=result

(no tracking issue yet)

Summary

Remove the stale expectation in TestClientWindowScalingAsync that RTT PINGs stop once observed stream credit exceeds 90% of its maximum. RTT estimation belongs to the connection, not an individual stream. The original implementation explicitly removed this optimization because it ignored other streams (author explanation). No product PING behavior changes are included.

The current assertion fails in the remote child before maxCredit <= MaxWindow is evaluated; examples include Windows and macOS in main build 1590723. These failures do not establish a receive-window overflow.

Retain the existing maximum-credit, payload-length, unexpected-frame and PING-flood checks. Add a focused theory that sends exactly one update threshold of nonfinal DATA, stops sending, then checks the target stream's WINDOW_UPDATE restores credit to exactly 654321. Initial windows 327161 and 654321 cover one-byte-over-cap doubling and replenishment at the cap. A zero scaling multiplier removes dependence on bandwidth; the complete response bytes are also verified.

Validation

Windows x64, CoreCLR Release and libraries/tests Debug, using a short subst path:

  • build.cmd clr+libs -rc release: succeeded, zero warnings/errors.
  • Full SocketsHttpHandler_Http2FlowControl_Test class with /p:Outerloop=true: 11 passed, 0 failed, 0 skipped, after restoring all diagnostic changes.
  • New exact-credit theory repeated ten times: 20 passed, 0 failed, 0 skipped.
  • Controlled stale-assertion reproduction: temporarily start the original helper at the cap. The old heuristic fails with the CI child Assert.Null signature; the corrected helper passes the identical setup. This diagnostic setup is not included in the commit.
  • Broken-cap negative control: temporarily remove Math.Min and its adjacent product Debug.Assert (so the assertion does not preempt the test oracle). The new growth case fails with expected 654321, actual 654322; the at-cap case passes. Both product changes were restored, the product rebuilt, and the full class rerun successfully.

Targeted command from the repository root:

.\.dotnet\dotnet.exe build src\libraries\System.Net.Http\tests\FunctionalTests\System.Net.Http.Functional.Tests.csproj /t:Test /p:RuntimeConfiguration=Release /p:Outerloop=true '/p:XUnitOptions=-class System.Net.Http.Functional.Tests.SocketsHttpHandler_Http2FlowControl_Test'

The unchanged original test passed once locally; its CI failure is intermittent. macOS execution and the broader HTTP functional suite were not run locally. No CI reruns or test disabling were used.

Note

This PR and its description were generated with GitHub Copilot.

Remove the stale expectation that connection RTT PINGs stop when a stream reaches its cap. Preserve flow-control safety checks and add exact WINDOW_UPDATE coverage for clamping and replenishment at the maximum.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 15, 2026 11:38
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @karelz, @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@rzikm
rzikm requested a review from a team September 15, 2026 11:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The test-only changes are focused and fully validated.

Pull request overview

Updates HTTP/2 flow-control tests without changing product behavior.

Changes:

  • Removes the obsolete RTT PING expectation.
  • Adds exact stream-window cap and replenishment coverage.
  • Preserves existing payload, frame, and PING-flood checks.
File summaries
File Description
src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2FlowControl.cs Updates flow-control expectations and adds exact-cap tests.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

@rzikm

rzikm commented Sep 15, 2026

Copy link
Copy Markdown
Member Author

/ba-g Build failure is unrelated

@rzikm
rzikm merged commit 99b0c18 into dotnet:main Sep 15, 2026
80 of 84 checks passed
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Sep 16, 2026
@rzikm

rzikm commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@rzikm

rzikm commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

/backport to release/11.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0 (link to workflow run)

svick pushed a commit that referenced this pull request Sep 17, 2026
…34038)

Backport of #133942 to release/11.0

/cc @rzikm
Test-only change to clean up CI

Co-authored-by: Radek Zikmund <32671551+rzikm@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jtschuster pushed a commit to jtschuster/runtime that referenced this pull request Sep 18, 2026
Fixes failure in
System.Net.Http.Functional.Tests.SocketsHttpHandler_Http2FlowControl_Test.MaxStreamWindowSize_WhenSet_WindowDoesNotScaleAboveMaximum
observed e.g. in


https://helixr18s23ayyejvk1x8qcc.blob.core.windows.net/dotnet-runtime-refs-heads-main-599d096511a54659b1/System.Net.Http.Functional.Tests/1/console.a3d71edc.log?helixlogtype=result

(no tracking issue yet)

## Summary

Remove the stale expectation in `TestClientWindowScalingAsync` that RTT
PINGs stop once observed stream credit exceeds 90% of its maximum. RTT
estimation belongs to the connection, not an individual stream. The
original implementation explicitly removed this optimization because it
ignored other streams ([author
explanation](dotnet#54755 (comment))).
No product PING behavior changes are included.

The current assertion fails in the remote child before `maxCredit <=
MaxWindow` is evaluated; examples include
[Windows](https://helixr18s23ayyejvk1x8qcc.blob.core.windows.net/dotnet-runtime-refs-heads-main-599d096511a54659b1/System.Net.Http.Functional.Tests/1/console.a3d71edc.log?helixlogtype=result)
and
[macOS](https://helixr1107v0xdeko0k025g8.blob.core.windows.net/dotnet-runtime-refs-heads-main-be1a20d5b78e45c39c/System.Net.Http.Functional.Tests/1/console.7bbcc8f9.log?helixlogtype=result)
in main build 1590723. These failures do not establish a receive-window
overflow.

Retain the existing maximum-credit, payload-length, unexpected-frame and
PING-flood checks. Add a focused theory that sends exactly one update
threshold of nonfinal DATA, stops sending, then checks the target
stream's WINDOW_UPDATE restores credit to exactly 654321. Initial
windows 327161 and 654321 cover one-byte-over-cap doubling and
replenishment at the cap. A zero scaling multiplier removes dependence
on bandwidth; the complete response bytes are also verified.

## Validation

Windows x64, CoreCLR Release and libraries/tests Debug, using a short
`subst` path:

- `build.cmd clr+libs -rc release`: succeeded, zero warnings/errors.
- Full `SocketsHttpHandler_Http2FlowControl_Test` class with
`/p:Outerloop=true`: **11 passed, 0 failed, 0 skipped**, after restoring
all diagnostic changes.
- New exact-credit theory repeated ten times: **20 passed, 0 failed, 0
skipped**.
- Controlled stale-assertion reproduction: temporarily start the
original helper at the cap. The old heuristic fails with the CI child
`Assert.Null` signature; the corrected helper passes the identical
setup. This diagnostic setup is not included in the commit.
- Broken-cap negative control: temporarily remove `Math.Min` and its
adjacent product `Debug.Assert` (so the assertion does not preempt the
test oracle). The new growth case fails with **expected 654321, actual
654322**; the at-cap case passes. Both product changes were restored,
the product rebuilt, and the full class rerun successfully.

Targeted command from the repository root:

```powershell
.\.dotnet\dotnet.exe build src\libraries\System.Net.Http\tests\FunctionalTests\System.Net.Http.Functional.Tests.csproj /t:Test /p:RuntimeConfiguration=Release /p:Outerloop=true '/p:XUnitOptions=-class System.Net.Http.Functional.Tests.SocketsHttpHandler_Http2FlowControl_Test'
```

The unchanged original test passed once locally; its CI failure is
intermittent. macOS execution and the broader HTTP functional suite were
not run locally. No CI reruns or test disabling were used.

> [!NOTE]
> This PR and its description were generated with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants