Uh oh!
There was an error while loading. Please reload this page.
[tests] Use local servers for remaining networking tests - #12098
[tests] Use local servers for remaining networking tests#12098simonrozsival wants to merge 2 commits into
Conversation
PR #12022 migrated most on-device networking tests off live external URLs to the loopback `LocalHttpServer`/`LocalHttpsServer`, and #12058 handles `SslTest.HttpsShouldWork`. This migrates the remaining tests that still reached out to the public internet, which made them flaky when those endpoints were slow or unavailable: - `SslTest.SslWithinTasksShouldWork` (dotnet.microsoft.com) - `ProxyTest.QuoteInvalidQuoteUrlsShouldWork` (msftconnecttest.com) - keeps the `?query&foo|bar` unescaped-pipe scenario against `/ok`. - `AndroidMessageHandlerTests.ServerCertificateCustomValidationCallback_ApproveRequest` and `_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 because the echo server no longer exists; re-enabled against a local server. To support these, `LocalTestServers.cs` gains: - Opt-in client-certificate (mutual TLS) support on `LocalHttpsServer` plus an `/echo-client-certificate` endpoint that returns the client certificate the server received. - A new loopback `LocalWebSocketServer` that performs the WebSocket upgrade handshake and echoes messages back. Also cleaned up cosmetic external hostnames in `CancelRequestViaProxy` (request never connects; goes through a dead proxy) and the `DisallowAutoRedirect` redirect target (never followed). The `http://10.255.255.1` cancellation/timeout tests intentionally use an unroutable address and are left unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 289a099a-278f-432b-b2b4-aac036e6e2dc
There was a problem hiding this comment.
Pull request overview
This PR completes the migration of remaining on-device networking tests away from public internet dependencies by extending the loopback test-server infrastructure (HTTP/HTTPS, mutual-TLS, and WebSocket) and updating tests to use those local endpoints. This reduces flakiness from external endpoint availability, latency, and rate limiting.
Changes:
- Extend
LocalHttpsServerto optionally request a client certificate and add an/echo-client-certificateendpoint. - Add a loopback
LocalWebSocketServerecho implementation forClientWebSocket-based tests. - Update remaining tests to target local loopback servers instead of public hostnames, re-enabling the WebSocket test.
Show a summary per file
| File | Description |
|---|---|
| tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/LocalTestServers.cs | Adds mutual-TLS client-certificate echo endpoint and introduces a local WebSocket echo server. |
| tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs | Switches cert-validation and client-cert tests to use LocalHttpsServer loopback endpoints. |
| tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerIntegrationTests.cs | Replaces remaining external google.com usage with LocalHttpServer in concurrent request test and adjusts cosmetic host strings. |
| tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidHandlerTestBase.cs | Updates disposed-handler test to use LocalHttpServer instead of an external URL. |
| tests/Mono.Android-Tests/Mono.Android-Tests/System.Net/WebSocketTests.cs | Re-enables WebSocket coverage by using the new loopback LocalWebSocketServer. |
| tests/Mono.Android-Tests/Mono.Android-Tests/System.Net/SslTest.cs | Updates SslWithinTasksShouldWork to use LocalHttpsServer loopback endpoint. |
| tests/Mono.Android-Tests/Mono.Android-Tests/System.Net/ProxyTest.cs | Updates the proxy quoting test to use LocalHttpServer loopback endpoint. |
Copilot's findings
Comments suppressed due to low confidence (1)
tests/Mono.Android-Tests/Mono.Android-Tests/System.Net/SslTest.cs:39
ServicePointManager.ServerCertificateValidationCallbackis a process-wide/static setting. If anything throws between setting it and resetting it, subsequent tests can be affected. Wrapping the body in a try/finally ensures the original callback is always restored.
var cb = ServicePointManager.ServerCertificateValidationCallback;
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, policy) => {
Console.WriteLine ("# ServerCertificateValidationCallback");
return true;
};
- Files reviewed: 7/7 changed files
- Comments generated: 3
| var t = ConnectIgnoreFailure (() => c.GetAsync (server.OkUri), out bool connectionFailed); | ||
| if (connectionFailed) | ||
| return; |
| } catch (WebException ex) when ( | ||
| ex.Status == WebExceptionStatus.ConnectFailure || | ||
| ex.Status == WebExceptionStatus.NameResolutionFailure || | ||
| ex.Status == WebExceptionStatus.Timeout) { | ||
| Assert.Ignore ($"Ignoring network failure: {ex.Message}"); |
| Assert.IsTrue (callbackHasBeenCalled, "custom validation callback hasn't been called"); | ||
| } |
The local WebSocket test server computes the Sec-WebSocket-Accept value using SHA-1, as mandated by the WebSocket handshake (RFC 6455 §1.3). This is a protocol requirement, not a security-sensitive choice, but CA5350 (treated as an error in the test build) flagged it and broke the Mono.Android.NET-Tests APK build. Suppress CA5350 around the SHA-1 usage with a justification. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 528dc903-4f7c-4a75-b74b-da0fbfe23f01
simonrozsival
commented
Jul 14, 2026
Superseded by #12099, re-opened as a direct PR (branch pushed to dotnet/android) so the |
> 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.
Context
Following up on #12022 (which migrated most on-device networking tests off live external URLs to the loopback
LocalHttpServer/LocalHttpsServer) and #12058 (which handlesSslTest.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
SslTest.SslWithinTasksShouldWorkdotnet.microsoft.comProxyTest.QuoteInvalidQuoteUrlsShouldWorkmsftconnecttest.comAndroidMessageHandlerTests.ServerCertificateCustomValidationCallback_ApproveRequestwww.microsoft.comAndroidMessageHandlerTests.ServerCertificateCustomValidationCallback_RejectRequestwww.microsoft.comAndroidMessageHandlerTests.AndroidMessageHandlerSendsClientCertificatecorefx-net-tls.azurewebsites.netAndroidMessageHandlerIntegrationTests.GetString_Manygoogle.comHttpClientHandlerTestBase.Disposedgoogle.comWebSocketTests.TestSocketConnectionecho.websocket.org(was[Ignore]d)ProxyTestkeeps its original point — an unescaped|in the query string (?query&foo|bar) — now exercised against the local/okendpoint.WebSocketTestswas previously disabled because the public echo server no longer exists; it is re-enabled against a local server.Test infrastructure (
LocalTestServers.cs)LocalHttpsServer.Start (requestClientCertificate: true)now requests a client certificate during the TLS handshake, and a new/echo-client-certificateendpoint returns the certificate the server received (base64 DER). This replaces the externalEchoClientCertificate.ashxendpoint.LocalWebSocketServer: a loopback WebSocket echo server that performs the upgrade handshake and echoes messages back (usesWebSocket.CreateFromStreamafter a manual101 Switching Protocolsresponse).Notes
HttpsShouldWorkis intentionally left to Use a local HTTPS server inSslTest.HttpsShouldWork#12058.http://10.255.255.1cancellation/timeout tests deliberately use an unroutable address (not the public internet) and are unchanged.CancelRequestViaProxy's base address behind a dead proxy, andDisallowAutoRedirect's redirect target) were pointed atlocalhost.The new server logic (HTTP, HTTPS, mutual-TLS echo, and WebSocket echo) was verified end-to-end against
HttpClientandClientWebSocketon desktop .NET.