wip: tighten watcher assertions, document loopback nameservers
check / check (push) Failing after 12s
check / check (push) Failing after 12s
This commit is contained in:
+36
@@ -39,6 +39,42 @@ assertions and sensible timeouts, not from mocks.
|
||||
running at once the gates sum instead of holding, and the resolver's
|
||||
per-attempt deadlines start expiring
|
||||
|
||||
### Transport failures: loopback nameservers, not mocks
|
||||
|
||||
The resolver classifies a nameserver that stays silent as
|
||||
`StatusTimeout` and one that answers SERVFAIL as `StatusError`. The
|
||||
public network cannot be made to produce either on demand — a
|
||||
black-holed address is only black-holed on some networks, and build
|
||||
environments that transparently intercept UDP/53 answer it locally —
|
||||
so a test built on a chosen remote address asserts on the network it
|
||||
happens to run on rather than on the resolver.
|
||||
|
||||
`internal/resolver/transport_test.go` binds a real nameserver on
|
||||
`127.0.0.1` instead and points the query at it.
|
||||
`nameserverAddr` dials an address that already carries a port as
|
||||
written, so no production behaviour is bypassed to arrange this.
|
||||
|
||||
**This is permitted, and it is not a mock.** The rule above bans
|
||||
substituting `DNSClient` or any other DNS abstraction, which lets the
|
||||
code under test skip DNS and hands it a manufactured verdict. A
|
||||
loopback nameserver does the opposite: the resolver dials a real
|
||||
socket, writes a real query with the real `miekg/dns` client, and
|
||||
applies its real deadline and its real classification logic to what
|
||||
comes back. Choosing which nameserver a live query is sent to is not
|
||||
faking DNS — the resolver is aimed at a nameserver of the caller's
|
||||
choosing in production too.
|
||||
|
||||
The distinction to hold on to: **substituting the client is banned;
|
||||
choosing the server is not.** A test that reaches for a fake
|
||||
`DNSClient` to force a classification is still forbidden, no matter
|
||||
how awkward the alternative looks.
|
||||
|
||||
Such a test must stay cheap. The resolver asks for eight record
|
||||
types and retries each once, so a nameserver silent on every type
|
||||
costs sixteen query timeouts. `TestQueryNameserverIP_Timeout` is
|
||||
silent on `A` alone and answers the rest, which is all the resolver
|
||||
needs to classify the response and keeps the test to two.
|
||||
|
||||
### What NOT to do
|
||||
|
||||
- **Do not mock `DNSClient`**, the watcher's `DNSResolver` interface,
|
||||
|
||||
Reference in New Issue
Block a user