Skip to content

Enable DnsResolver tests on all Unix platforms - #132216

Open
rzikm wants to merge 2 commits into
dotnet:mainfrom
rzikm:dns-resolver-unix
Open

Enable DnsResolver tests on all Unix platforms#132216
rzikm wants to merge 2 commits into
dotnet:mainfrom
rzikm:dns-resolver-unix

Conversation

@rzikm

@rzikm rzikm commented Aug 12, 2026

Copy link
Copy Markdown
Member

Follow-up to #129846, which added DnsResolver with a managed stub resolver implementation.

That implementation is compiled through the shared -unix target framework, which is a catch-all for every Unix-family TargetOS that has no explicit entry in TargetFrameworks. System.Net.NameResolution lists only windows;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 from IsWindows to "everywhere the resolver is implemented" (that is, everything except Android, Browser and WASI). Three tests that exercise genuinely DnsQueryEx-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 that DnsQueryEx rejects.
  • DnsResolverLoopbackTest: drops IsNotMobile. These tests pass an explicit Servers list 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_ReturnsCanceled now asserts ThrowsAnyAsync<OperationCanceledException>. The managed PAL cancels via CancellationToken.ThrowIfCancellationRequested(), which produces a plain OperationCanceledException, whereas the Windows PAL produces a TaskCanceledException.

Android

Android is the one Unix platform that cannot use the system-configured servers. There is no accessible /etc/resolv.conf, and IPInterfaceProperties.DnsAddresses throws PlatformNotSupportedException there for the same reason, so ResolvConf.GetNameServers() comes back empty and GetServers() falls back to 127.0.0.1:53 — every query would silently time out against an unreachable address.

Rather than fail that way, DnsResolverPal.Managed.ValidateServers now rejects the configuration up front with PlatformNotSupportedException, and the affected surface is annotated:

  • the parameterless DnsResolver() constructor
  • all 18 Dns.Resolve* statics, which route through it

DnsResolver(DnsResolverOptions) with an explicit Servers list keeps working on Android, which is why the annotation cannot go on the type. Tracked by #132212.

Browser and WASI

DnsResolver is unsupported on both — they compile DnsResolverPal.Unsupported.cs (and on Browser the whole assembly is a generated PNSE stub). Browser needs no per-member attribute because Directory.Build.props already sets UnsupportedOSPlatforms=browser, which emits an assembly-level attribute; WASI was not covered by anything, so [UnsupportedOSPlatform("wasi")] is applied to the DnsResolver type and the Dns.Resolve* statics, following the Zstandard* 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.WaitOne and blocking Socket.Send/Receive) would deadlock the only thread. Tracked by #132215.

A new test asserts the PlatformNotSupportedException contract 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 -browser and -wasi, and cross-compiles clean for TargetOS=android, osx and maccatalyst.

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.

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>
Copilot AI lite review requested due to automatic review settings August 12, 2026 16:13
@azure-pipelines

Copy link
Copy Markdown
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.

@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 commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-android

@rzikm

rzikm commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-extra-platforms

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

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.

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 DnsResolverTest network coverage on non-Android Unix platforms (and keep Browser/WASI excluded), while preserving Windows-only DnsQueryEx-specific behaviors.
  • Enable DnsResolverLoopbackTest on 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>
Copilot AI review requested due to automatic review settings August 13, 2026 07:37
@rzikm

rzikm commented Aug 13, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-android

@rzikm

rzikm commented Aug 13, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-extra-platforms

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

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.

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));
        }

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.

2 participants