resolver: the refused-query test asks several operators, one query each (closes #251)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The test asked one operator's recursive resolver for eight record types at each of its two addresses, and passed only when all eight were refused within one attempt; when that operator stopped answering, next went red. It is now TestQueryServers_RecursiveResolverRefused: through the existing QueryServers test export it sends one A query to public resolvers of four operators in turn, inside livednstest.Retry, moving on when one gives no reply. Each refuses a query not asking for recursion and answers one that does, so putting the resend asking for recursion back still fails the test at once. Model: opus-5-5
This commit was merged in pull request #252.
This commit is contained in:
@@ -19,6 +19,8 @@ trial run of the finished image: https://git.eeqj.de/sneak/dnswatcher/issues/149
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-02: the refused-query test sends one query to four operators' public
|
||||||
|
resolvers in turn until one replies, not eight to one operator (closes #251).
|
||||||
- 2026-10-02: a name removed from `DNSWATCHER_TARGETS` leaves the state, and so
|
- 2026-10-02: a name removed from `DNSWATCHER_TARGETS` leaves the state, and so
|
||||||
the dashboard and API, at startup, before the first check (closes #223).
|
the dashboard and API, at startup, before the first check (closes #223).
|
||||||
- 2026-10-02: a record type whose query to a nameserver fails keeps its previous
|
- 2026-10-02: a record type whose query to a nameserver fails keeps its previous
|
||||||
|
|||||||
@@ -442,48 +442,45 @@ func TestQueryNameserver_Refused(t *testing.T) {
|
|||||||
assert.Equal(t, "server returned REFUSED", resp.Error)
|
assert.Equal(t, "server returned REFUSED", resp.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestQueryNameserverIP_RecursiveResolverRefused asks Quad9, a public
|
// TestQueryServers_RecursiveResolverRefused passes a public recursive
|
||||||
// recursive resolver, about google.com at both of its addresses. Quad9
|
// resolver to QueryServers as the server of google.com. These resolvers
|
||||||
// refuses a query that does not ask for recursion and answers one that
|
// refuse a query that does not ask for recursion and answer one that
|
||||||
// does. The resolver never asks for recursion, so it must be reported
|
// does. The resolver never asks for recursion, so the query must be
|
||||||
// as refusing, never as answering.
|
// reported as refused, never answered. Each resolver is run by a
|
||||||
func TestQueryNameserverIP_RecursiveResolverRefused(t *testing.T) {
|
// different operator, and they are asked in turn until one replies, so
|
||||||
|
// one operator not answering does not fail the test.
|
||||||
|
func TestQueryServers_RecursiveResolverRefused(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
r := newTestResolver(t)
|
r := newTestResolver(t)
|
||||||
|
resolvers := []string{
|
||||||
for _, ip := range []string{"9.9.9.9", "149.112.112.112"} {
|
"64.6.64.6", "185.222.222.222", "4.2.2.1", "9.9.9.9",
|
||||||
var resp *resolver.NameserverResponse
|
|
||||||
|
|
||||||
livednstest.Retry(
|
|
||||||
t,
|
|
||||||
"QueryNameserverIP("+ip+", google.com)",
|
|
||||||
func(ctx context.Context) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
resp, err = r.QueryNameserverIP(
|
|
||||||
ctx, ip, ip, "google.com",
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// A timeout or a network error is no reply at all.
|
|
||||||
if resp.Status == resolver.StatusTimeout ||
|
|
||||||
strings.HasPrefix(resp.Error, "network error") {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"%w: %s: %s",
|
|
||||||
livednstest.ErrNoAnswer, ip, resp.Error,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert.Equal(t, resolver.StatusError, resp.Status, ip)
|
|
||||||
assert.Equal(t, "server returned REFUSED", resp.Error, ip)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
livednstest.Retry(
|
||||||
|
t,
|
||||||
|
"QueryServers(public recursive resolvers, google.com)",
|
||||||
|
func(ctx context.Context) error {
|
||||||
|
for _, ip := range resolvers {
|
||||||
|
_, err = r.QueryServers(
|
||||||
|
ctx, []string{ip}, "google.com.", "google.com.",
|
||||||
|
dns.TypeA,
|
||||||
|
)
|
||||||
|
|
||||||
|
// A refusal or an answer is a reply; anything else may
|
||||||
|
// be no reply at all, so the next resolver is asked.
|
||||||
|
if err == nil || errors.Is(err, resolver.ErrRefused) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("%w: %w", livednstest.ErrNoAnswer, err)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
require.ErrorIs(t, err, resolver.ErrRefused)
|
||||||
}
|
}
|
||||||
|
|
||||||
// googleNameserverIPv4s returns the IPv4 addresses of google.com's
|
// googleNameserverIPv4s returns the IPv4 addresses of google.com's
|
||||||
|
|||||||
Reference in New Issue
Block a user