resolver tests: retry an answer missing the record type read (closes #218)
check / check (push) Successful in 1m20s
check / check (push) Successful in 1m20s
QueryNameserver sends one query per record type. When only the AAAA or MX query was lost, the answer still had status ok, liveQueryNameserver did not retry it, and the test found no AAAA or MX records. liveQueryNameserver now takes the record types a test reads and, through livednstest, retries an answer that holds records of none of them. The A, AAAA, MX and TXT tests name theirs. A resolver that loses a type for good still fails, after the last attempt instead of the first. Model: opus-5-5
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: a resolver test that reads one record type from a nameserver's
|
||||||
|
answer asks again when that type is missing from it (closes #218).
|
||||||
- 2026-10-02: a plain `docker build .` of a clone stamps its tag or short
|
- 2026-10-02: a plain `docker build .` of a clone stamps its tag or short
|
||||||
commit, not `dev`: the build context now carries `.git` (closes #210).
|
commit, not `dev`: the build context now carries `.git` (closes #210).
|
||||||
- 2026-10-02: a query a server refuses is not resent asking for recursion, and
|
- 2026-10-02: a query a server refuses is not resent asking for recursion, and
|
||||||
|
|||||||
@@ -226,11 +226,17 @@ func liveLookupNS(
|
|||||||
// liveQueryNameserver queries one nameserver, retrying while that
|
// liveQueryNameserver queries one nameserver, retrying while that
|
||||||
// nameserver fails to answer. NXDOMAIN and NODATA are answers and
|
// nameserver fails to answer. NXDOMAIN and NODATA are answers and
|
||||||
// are returned to the caller to assert on.
|
// are returned to the caller to assert on.
|
||||||
|
//
|
||||||
|
// QueryNameserver sends one query per record type, so one lost query
|
||||||
|
// leaves its type out of an answer that is otherwise fine. A test names
|
||||||
|
// in types the record types it reads; an answer holding records of none
|
||||||
|
// of them is retried too.
|
||||||
func liveQueryNameserver(
|
func liveQueryNameserver(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
r *resolver.Resolver,
|
r *resolver.Resolver,
|
||||||
nameserver string,
|
nameserver string,
|
||||||
hostname string,
|
hostname string,
|
||||||
|
types ...string,
|
||||||
) *resolver.NameserverResponse {
|
) *resolver.NameserverResponse {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@@ -260,6 +266,18 @@ func liveQueryNameserver(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasRecords := func(recordType string) bool {
|
||||||
|
return len(resp.Records[recordType]) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(types) > 0 && !slices.ContainsFunc(types, hasRecords) {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"%w: %s returned no %s records",
|
||||||
|
livednstest.ErrNoAnswer, nameserver,
|
||||||
|
strings.Join(types, " or "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
out = resp
|
out = resp
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ func TestQueryNameserver_BasicA(t *testing.T) {
|
|||||||
|
|
||||||
r := newTestResolver(t)
|
r := newTestResolver(t)
|
||||||
ns := findOneNSForDomain(t, r, "google.com")
|
ns := findOneNSForDomain(t, r, "google.com")
|
||||||
resp := liveQueryNameserver(t, r, ns, "www.google.com")
|
resp := liveQueryNameserver(t, r, ns, "www.google.com", "A", "CNAME")
|
||||||
|
|
||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ func TestQueryNameserver_AAAA(t *testing.T) {
|
|||||||
|
|
||||||
r := newTestResolver(t)
|
r := newTestResolver(t)
|
||||||
ns := findOneNSForDomain(t, r, "cloudflare.com")
|
ns := findOneNSForDomain(t, r, "cloudflare.com")
|
||||||
resp := liveQueryNameserver(t, r, ns, "cloudflare.com")
|
resp := liveQueryNameserver(t, r, ns, "cloudflare.com", "AAAA")
|
||||||
|
|
||||||
aaaaRecords := resp.Records["AAAA"]
|
aaaaRecords := resp.Records["AAAA"]
|
||||||
require.NotEmpty(t, aaaaRecords,
|
require.NotEmpty(t, aaaaRecords,
|
||||||
@@ -210,7 +210,7 @@ func TestQueryNameserver_MX(t *testing.T) {
|
|||||||
|
|
||||||
r := newTestResolver(t)
|
r := newTestResolver(t)
|
||||||
ns := findOneNSForDomain(t, r, "google.com")
|
ns := findOneNSForDomain(t, r, "google.com")
|
||||||
resp := liveQueryNameserver(t, r, ns, "google.com")
|
resp := liveQueryNameserver(t, r, ns, "google.com", "MX")
|
||||||
|
|
||||||
mxRecords := resp.Records["MX"]
|
mxRecords := resp.Records["MX"]
|
||||||
require.NotEmpty(t, mxRecords,
|
require.NotEmpty(t, mxRecords,
|
||||||
@@ -223,7 +223,7 @@ func TestQueryNameserver_TXT(t *testing.T) {
|
|||||||
|
|
||||||
r := newTestResolver(t)
|
r := newTestResolver(t)
|
||||||
ns := findOneNSForDomain(t, r, "google.com")
|
ns := findOneNSForDomain(t, r, "google.com")
|
||||||
resp := liveQueryNameserver(t, r, ns, "google.com")
|
resp := liveQueryNameserver(t, r, ns, "google.com", "TXT")
|
||||||
|
|
||||||
txtRecords := resp.Records["TXT"]
|
txtRecords := resp.Records["TXT"]
|
||||||
require.NotEmpty(t, txtRecords,
|
require.NotEmpty(t, txtRecords,
|
||||||
|
|||||||
Reference in New Issue
Block a user