Enable DnsResolver tests on all Unix platforms - #132216
Conversation
The managed stub resolver added for Linux is already compiled for every
Unix-family target through the shared `-unix` target framework, so macOS,
the BSDs, iOS, tvOS and MacCatalyst all get a working DnsResolver without
any additional platform work. The tests, however, were still gated to
Windows only, and the loopback tests were excluded from mobile.
Widen the gating so the network tests run everywhere the resolver is
implemented and the loopback tests run on mobile as well, keeping the
handful of genuinely DnsQueryEx-specific tests on Windows and adding Unix
counterparts for them. The managed PAL surfaces cancellation as a plain
OperationCanceledException rather than TaskCanceledException, so the
pre-canceled token test now accepts any OperationCanceledException.
Android is the one Unix platform that cannot participate: it exposes no
readable resolver configuration (no accessible /etc/resolv.conf, and
IPInterfaceProperties.DnsAddresses throws PlatformNotSupportedException
for the same reason), so a resolver using the system-configured servers
would silently query an unreachable fallback address. Reject that up
front with PlatformNotSupportedException and annotate the affected
surface -- the parameterless DnsResolver constructor and the Dns.Resolve*
statics -- with [UnsupportedOSPlatform("android")].
DnsResolver is likewise unsupported on WASI, which is annotated too.
Browser needs no per-member attribute because the assembly already
carries an assembly-level [UnsupportedOSPlatform("browser")].
Follow-ups tracked by dotnet#132212 (Android) and dotnet#132215 (WASI).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @karelz, @dotnet/ncl |
|
/azp run runtime-android |
|
/azp run runtime-extra-platforms |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
1 similar comment
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Expands System.Net.NameResolution’s DnsResolver functional test coverage beyond Windows by removing overly strict platform gating, while clarifying and enforcing the unsupported/PNSE contract on platforms where the default (system-server) resolver path cannot work.
Changes:
- Enable
DnsResolverTestnetwork coverage on non-Android Unix platforms (and keep Browser/WASI excluded), while preserving Windows-onlyDnsQueryEx-specific behaviors. - Enable
DnsResolverLoopbackTeston mobile platforms by relying on explicit loopback servers (no system resolver configuration dependency). - Enforce and document platform support contracts: throw early on Android when system DNS servers can’t be discovered, and annotate APIs as unsupported on Android (default constructor +
Dns.Resolve*) and WASI (DnsResolver/Dns.Resolve*).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Net.NameResolution/tests/FunctionalTests/DnsResolverTest.cs | Broadens test gating to run on Unix platforms where DnsResolver is implemented; adds explicit unsupported-platform and Android contract tests. |
| src/libraries/System.Net.NameResolution/tests/FunctionalTests/DnsResolverLoopbackTest.cs | Removes IsNotMobile gating so loopback-based deterministic resolver tests run on mobile where applicable. |
| src/libraries/System.Net.NameResolution/src/System/Net/DnsResolverPal.Unsupported.cs | Adds clarifying comment about Browser/WASI lack of implementation and tracking issue. |
| src/libraries/System.Net.NameResolution/src/System/Net/DnsResolverPal.Managed.cs | Rejects Android default (system-server) configuration up front with a clear PlatformNotSupportedException. |
| src/libraries/System.Net.NameResolution/src/System/Net/DnsResolver.cs | Annotates DnsResolver as unsupported on WASI; marks parameterless ctor unsupported on Android and documents PNSE behavior. |
| src/libraries/System.Net.NameResolution/src/System/Net/Dns.Resolve.cs | Annotates Dns.Resolve* statics as unsupported on Android/WASI and documents PNSE contract. |
| src/libraries/System.Net.NameResolution/src/Resources/Strings.resx | Adds a dedicated SR message for “system-configured DNS servers cannot be determined”. |
| src/libraries/System.Net.NameResolution/ref/System.Net.NameResolution.cs | Updates public contract with [UnsupportedOSPlatform] attributes consistent with implementation. |
GetServers falls back to 127.0.0.1:53 when no explicit servers are configured and /etc/resolv.conf yields none. Record why: resolv.conf(5) specifies that a missing file or one without nameserver entries means the name server on the local machine is queried, so this keeps DnsResolver consistent with getaddrinfo on the same host. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run runtime-android |
|
/azp run runtime-extra-platforms |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
1 similar comment
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/libraries/System.Net.NameResolution/tests/FunctionalTests/DnsResolverTest.cs:56
- The Android-specific PNSE contract is only asserted for the synchronous Dns.ResolveAddresses path. Since the change also affects the async static APIs (they route through the same default resolver), add an assertion that ResolveAddressesAsync throws PlatformNotSupportedException as well to prevent regressions specific to the async entry point.
// Android exposes no readable resolver configuration, so a resolver that would
// have to use the system-configured servers cannot be created.
Assert.Throws<PlatformNotSupportedException>(() => new DnsResolver());
Assert.Throws<PlatformNotSupportedException>(() => Dns.ResolveAddresses(TestHost));
}
Follow-up to #129846, which added
DnsResolverwith a managed stub resolver implementation.That implementation is compiled through the shared
-unixtarget framework, which is a catch-all for every Unix-familyTargetOSthat has no explicit entry inTargetFrameworks.System.Net.NameResolutionlists onlywindows;unix;browser;wasi, so macOS, the BSDs, illumos, Haiku, iOS, tvOS, MacCatalyst and Android already compile the same managed resolver as Linux — no per-platform PAL work is needed to support them. The tests were the only thing still gated to Windows.Test gating
DnsResolverTest: the network tests move fromIsWindowsto "everywhere the resolver is implemented" (that is, everything except Android, Browser and WASI). Three tests that exercise genuinelyDnsQueryEx-specific behavior stay Windows-only, and two Unix counterparts were added for the constructor-validation ones — the managed resolver talks to each server endpoint directly, so it accepts non-standard ports and mixed IPv4/IPv6 server lists thatDnsQueryExrejects.DnsResolverLoopbackTest: dropsIsNotMobile. These tests pass an explicitServerslist and talk to an in-process loopback server, so they never touch the system resolver configuration and can run on Android and Apple mobile.DnsResolver_PreCanceledToken_ReturnsCancelednow assertsThrowsAnyAsync<OperationCanceledException>. The managed PAL cancels viaCancellationToken.ThrowIfCancellationRequested(), which produces a plainOperationCanceledException, whereas the Windows PAL produces aTaskCanceledException.Android
Android is the one Unix platform that cannot use the system-configured servers. There is no accessible
/etc/resolv.conf, andIPInterfaceProperties.DnsAddressesthrowsPlatformNotSupportedExceptionthere for the same reason, soResolvConf.GetNameServers()comes back empty andGetServers()falls back to127.0.0.1:53— every query would silently time out against an unreachable address.Rather than fail that way,
DnsResolverPal.Managed.ValidateServersnow rejects the configuration up front withPlatformNotSupportedException, and the affected surface is annotated:DnsResolver()constructorDns.Resolve*statics, which route through itDnsResolver(DnsResolverOptions)with an explicitServerslist keeps working on Android, which is why the annotation cannot go on the type. Tracked by #132212.Browser and WASI
DnsResolveris unsupported on both — they compileDnsResolverPal.Unsupported.cs(and on Browser the whole assembly is a generated PNSE stub). Browser needs no per-member attribute becauseDirectory.Build.propsalready setsUnsupportedOSPlatforms=browser, which emits an assembly-level attribute; WASI was not covered by anything, so[UnsupportedOSPlatform("wasi")]is applied to theDnsResolvertype and theDns.Resolve*statics, following theZstandard*precedent in System.IO.Compression.Reusing the managed resolver on WASI is possible in principle — WASI does have TCP and UDP sockets — but it has no resolver configuration to read and no threads, so the synchronous query path (which blocks on
IAsyncResult.AsyncWaitHandle.WaitOneand blockingSocket.Send/Receive) would deadlock the only thread. Tracked by #132215.A new test asserts the
PlatformNotSupportedExceptioncontract on each of Android, Browser and WASI. The argument-validation tests were switched to a resolver built with an explicit (never-contacted) server so that they keep running on Android instead of being skipped there.API
No new API surface. The only
ref/changes are[UnsupportedOSPlatform]attributes on API already approved and merged in #129846.Validation
Built and tested on Linux x64:
System.Net.NameResolution.Functional.Tests— 201 total, 0 failed, 6 skipped. The library builds clean (0 warnings) across all five target frameworks, including-browserand-wasi, and cross-compiles clean forTargetOS=android,osxandmaccatalyst.The mobile, macOS, Browser and WASI legs could not be exercised locally, so CI is the first execution there.
Note
This pull request was authored with GitHub Copilot.