check / check (push) Waiting to run
The health check answered ok while every DNS lookup failed, as on a network that intercepts DNS queries. A lookup whose root servers give no usable reply now fails with ErrNoRootServerAnswered. At the end of each round of DNS checks that shutdown did not cut short, the watcher records whether every lookup failed with it or with ErrIntercepted; the health check then gives status error, and /.well-known/healthcheck and /health answer 503. Until the first round finishes it stays ok. The health check now depends on the watcher, so fx starts the watcher before the HTTP server and stops the server first. NewWithRootServers lets tests start a resolver's walks at real servers that are not root servers. Model: opus-5-5
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
package watcher_test
|
|
|
|
import (
|
|
"log/slog"
|
|
"testing"
|
|
|
|
"sneak.berlin/go/dnswatcher/internal/resolver"
|
|
"sneak.berlin/go/dnswatcher/internal/watcher"
|
|
)
|
|
|
|
// TestDNSUnreachableWhenNoRootServerGivesUsableReply runs one round of
|
|
// checks of a domain and a hostname with every walk starting at real
|
|
// servers that are not root servers. At 192.0.2.1, a documentation
|
|
// address, nothing answers, as when no root server answers. Public
|
|
// recursive resolvers of four operators mark their replies recursion
|
|
// available, as on a network that intercepts DNS queries; one that gives
|
|
// no reply is passed over for the next, and if none replies, no root
|
|
// server answered. Either way every lookup failed because no root server
|
|
// gave a usable reply, so the round could not reach the DNS.
|
|
// TestFirstRunBaseline and TestDomainThatDoesNotExist check rounds in
|
|
// which the root servers gave a usable reply.
|
|
func TestDNSUnreachableWhenNoRootServerGivesUsableReply(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
servers []string
|
|
}{
|
|
{"no root server answers", []string{"192.0.2.1"}},
|
|
{
|
|
"the network intercepts DNS queries",
|
|
[]string{"1.1.1.1", "8.8.8.8", "9.9.9.9", "208.67.222.222"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg := defaultTestConfig(t)
|
|
cfg.Domains = []string{testSmallDomain}
|
|
cfg.Hostnames = []string{testHost}
|
|
|
|
deps := newTestDeps(t, cfg)
|
|
w := watcher.NewForTest(
|
|
cfg,
|
|
deps.state,
|
|
resolver.NewWithRootServers(slog.Default(), tt.servers),
|
|
deps.portChecker,
|
|
deps.tlsChecker,
|
|
deps.notifier,
|
|
)
|
|
|
|
if w.DNSUnreachable() {
|
|
t.Error("DNSUnreachable is true before the first round")
|
|
}
|
|
|
|
w.RunOnce(t.Context())
|
|
|
|
if !w.DNSUnreachable() {
|
|
t.Error("DNSUnreachable is false after a round in " +
|
|
"which no root server gave a usable reply")
|
|
}
|
|
})
|
|
}
|
|
}
|