Skip to content

[tests] Use local servers for networking tests - #12022

Merged
simonrozsival merged 10 commits into
mainfrom
android-change-networking-tests
Jul 10, 2026
Merged

[tests] Use local servers for networking tests#12022
simonrozsival merged 10 commits into
mainfrom
android-change-networking-tests

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

Summary

  • Replace httpbin.org redirect/decompression coverage with local loopback HTTP endpoints
  • Replace badssl.com self-signed/hostname-mismatch coverage with local self-signed HTTPS servers
  • Update LinkDesc HttpClient regression to post to a local HttpListener

Validation

  • make all
  • ./dotnet-local.sh build -t:Install -c Debug tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj -p:Device=R58Y30HZ65V -p:IncludeCategories=SSL
  • (cd tests/Mono.Android-Tests/Mono.Android-Tests && ../../../dotnet-local.sh test Mono.Android.NET-Tests.csproj --no-build -c Debug --report-trx --results-directory ../../../bin/TestDebug/TestResults -p:Device=R58Y30HZ65V -p:IncludeCategories=SSL) — 25 passed
  • ./dotnet-local.sh test bin/TestDebug/MSBuildDeviceIntegration/net10.0/MSBuildDeviceIntegration.dll --filter "FullyQualifiedName~InstallAndRunTests.CustomLinkDescriptionPreserve" — 4 skipped (test is currently ignored for all runtime variants)

Replace httpbin.org and badssl.com dependencies in networking tests with local loopback HTTP/HTTPS servers, including self-signed TLS coverage. Update the LinkDesc HttpClient regression to post to a local listener.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 16:42

CopilotAI 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.

Pull request overview

This PR updates networking-related tests to stop depending on external internet endpoints (httpbin.org/badssl.com) by introducing local loopback HTTP/HTTPS test servers and switching existing redirect/decompression/SSL-validation tests to use them. This improves test reliability in constrained or offline environments and reduces external flakiness.

Changes:

  • Added reusable local HTTP/HTTPS test server helpers for Mono.Android.NET-Tests.
  • Migrated AndroidMessageHandler redirect/decompression and invalid-certificate tests to use local servers instead of external hosts.
  • Updated the LinkDesc HttpClient regression app/test to POST to a local HttpListener endpoint and adjusted the manifest to allow cleartext traffic + INTERNET permission.
Show a summary per file
FileDescription
tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.csEnables cleartext + INTERNET permission for the LinkDesc regression app so it can talk to local HTTP endpoints.
tests/MSBuildDeviceIntegration/Resources/LinkDescTest/HttpClientTest.csReplaces external POST target with a local HttpListener-based loopback server.
tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/LocalTestServers.csIntroduces local HTTP and HTTPS server helpers for test scenarios (compression, redirects, self-signed certs).
tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.csSwitches decompression, redirect, and SSL callback tests to local servers.
tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidHandlerTestBase.csUpdates redirect tests to use local loopback servers.
tests/Mono.Android-Tests/Mono.Android-Tests/System.Net/SslTest.csRemoves httpbin from the external URL list to reduce dependency on that service.
tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csprojAdds the new LocalTestServers.cs to the test project build.

Copilot's findings

  • Files reviewed: 7/7 changed files
  • Comments generated: 4

Comment threadtests/MSBuildDeviceIntegration/Resources/LinkDescTest/HttpClientTest.cs Outdated
simonrozsivaland others added 8 commits July 8, 2026 22:14
Bind local HTTP listeners to loopback, dispose LinkDesc HTTP resources, backdate self-signed certificates further, and assert policy errors in the HTTPS redirect callback test.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Share local test server exception handling and shutdown logic, and add intent-level helpers for redirect and OK responses to remove repeated listener setup in networking tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add local HTTP test-server endpoint helpers for the networking tests and LinkDesc HttpClient regression. Scope the generated app's cleartext allowance to localhost via network security config instead of enabling app-wide cleartext traffic.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use declaration-style using statements in the local HTTP test helpers and redirect tests to reduce nesting. Opt the generated LinkTestLib project into C# 8 so its embedded helper can use using declarations.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the extra LocalHttpTestServer wrapper from Mono.Android networking tests. LocalTestServer now owns shared lifecycle/error handling, LocalHttpServer owns HTTP listener behavior and test endpoints, and LocalHttpsServer remains the HTTPS/self-signed transport helper.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the Mono.Android HttpListener-based LocalHttpServer with a TCP-based request parser/router shared by LocalHttpsServer. HTTPS now exposes the same /ok and /redirect-to endpoints as HTTP, with TLS layered via SslStream. Rename the generated LinkDesc helper to LinkDescHttpServer to avoid confusion with the Mono.Android helpers.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use BaseAddress with httpbin-style relative redirect endpoints in networking tests, name the HTTPS certificate host argument, and rename the generated LinkDesc helper back to LocalHttpServer with a /post endpoint.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the duplicate LinkDesc local HTTP server and compile the shared Mono.Android LocalTestServers helper into the generated LinkTestLib project. Make the shared helper netstandard2.0-compatible for the LinkDesc library while keeping HTTPS/Brotli support for the Mono.Android tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsivalsimonrozsival added flaky-tests ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). labels Jul 9, 2026
@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/review

@github-actions

github-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actionsgithub-actionsBot 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.

🤖 Code Review — ⚠️ Needs Changes

Nice cleanup. Replacing httpbin.org / badssl.com with in-process loopback servers removes a real source of external-network flakiness, and LocalTestServers.cs is well thought through:

  • Per-response Connection: close correctly forces a fresh TLS handshake, which is what keeps ServerCertificateCustomValidationCallback_Redirects asserting callbackCounter == 2.
  • Handler exceptions are captured off the accept loop and surfaced via AssertNoUnhandledExceptions(), and dispose-time IOException/ObjectDisposedException are correctly ignored once the handler completed.
  • Self-signed cert generation with SANs and the HTTPS host pinned to localhost (matching the cert) is a sensible design.

CI: ✅ All dotnet-android checks are green on bd7911c. mergeable_state: blocked reflects the pending maintainer review, not a CI failure.

Findings (see inline):

  • ⚠️ 1 warning — LinkDesc network_security_config.xml whitelists cleartext for localhost, but LocalHttpServer uses 127.0.0.1; the LinkDesc HttpClientTest will hit Cleartext ... not permitted once CustomLinkDescriptionPreserve is un-ignored.
  • 💡 2 suggestions — port-selection race in GetAvailablePort() (re-introduces a flaky window); reduced fidelity of NoServerCertificateCustomValidationCallback_ThrowsWhenThereIsCertificateHostnameMismatch.

Worth double-checking before merge: the two tests that actually exercise the loopback servers end-to-end aren't part of the green CI legs — CustomLinkDescriptionPreserve is ignored for all runtime variants (per the PR description), and the SSL-category AndroidMessageHandlerTests run on a physical device rather than the emulator legs. So the green checks above don't fully validate the new cleartext/loopback paths.

Prioritized: the network-security-config vs. server-host mismatch is the one to fix; the other two are optional.

Generated by Android PR Reviewer for #12022 · 209.6 AIC · ⌖ 27.5 AIC · ⊞ 6.8K
Comment /review to run again

Comment threadtests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs
Bind local test listeners directly to ephemeral ports and align the loopback cleartext configuration. Trust the local certificate before asserting a hostname mismatch so the test isolates name validation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9721cbaf-7e53-4fb0-b12c-6c9de7483f9d
@simonrozsival
simonrozsival enabled auto-merge (squash) July 10, 2026 07:09
@simonrozsival
simonrozsival merged commit bef2665 into mainJul 10, 2026
42 checks passed
@simonrozsival
simonrozsival deleted the android-change-networking-tests branch July 10, 2026 22:17
simonrozsival added a commit that referenced this pull request Jul 14, 2026
> Re-opened as a direct PR (supersedes #12098) so the `dotnet-android` pipeline runs automatically without `/azp run` approval.
### Context
Following up on #12022 (which migrated most on-device networking tests off live external URLs to the loopback `LocalHttpServer`/`LocalHttpsServer`) and #12058 (which handles `SslTest.HttpsShouldWork`), a few on-device tests were still reaching out to the public internet. Those requests made the tests flaky whenever the external endpoints were slow, rate-limited, or unavailable.
This migrates the remaining tests to local loopback servers.
### Tests migrated
| Test | Was hitting |
| ---- | ----------- |
| `SslTest.SslWithinTasksShouldWork` | `dotnet.microsoft.com` |
| `ProxyTest.QuoteInvalidQuoteUrlsShouldWork` | `msftconnecttest.com` |
| `AndroidMessageHandlerTests.ServerCertificateCustomValidationCallback_ApproveRequest` | `www.microsoft.com` |
| `AndroidMessageHandlerTests.ServerCertificateCustomValidationCallback_RejectRequest` | `www.microsoft.com` |
| `AndroidMessageHandlerTests.AndroidMessageHandlerSendsClientCertificate` | `corefx-net-tls.azurewebsites.net` |
| `AndroidMessageHandlerIntegrationTests.GetString_Many` | `google.com` |
| `HttpClientHandlerTestBase.Disposed` | `google.com` |
| `WebSocketTests.TestSocketConnection` | `echo.websocket.org` (was `[Ignore]`d) |
`ProxyTest` keeps its original point — an unescaped `|` in the query string (`?query&foo|bar`) — now exercised against the local `/ok` endpoint. `WebSocketTests` was previously disabled because the public echo server no longer exists; it is re-enabled against a local server.
### Test infrastructure (`LocalTestServers.cs`)
- **Client certificates (mutual TLS)**: `LocalHttpsServer.Start (requestClientCertificate: true)` now requests a client certificate during the TLS handshake, and a new `/echo-client-certificate` endpoint returns the certificate the server received (base64 DER). This replaces the external `EchoClientCertificate.ashx` endpoint.
- **`LocalWebSocketServer`**: a loopback WebSocket echo server that performs the upgrade handshake and echoes messages back (uses `WebSocket.CreateFromStream` after a manual `101 Switching Protocols` response).
### Notes
- `HttpsShouldWork` is intentionally left to #12058.
- The `http://10.255.255.1` cancellation/timeout tests deliberately use an unroutable address (not the public internet) and are unchanged.
- Cosmetic external hostnames that were never actually contacted (`CancelRequestViaProxy`'s base address behind a dead proxy, and `DisallowAutoRedirect`'s redirect target) were pointed at `localhost`.
The new server logic (HTTP, HTTPS, mutual-TLS echo, and WebSocket echo) was verified end-to-end against `HttpClient` and `ClientWebSocket` on desktop .NET.
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

flaky-testsready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@simonrozsival@jonathanpeppers