resolver: a query cut short by the caller's context records no reason (closes #298)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
When the caller's context ends, the next query returns ErrContextCanceled before anything is sent. querySingleType recorded that as a network error, which outranks a timeout, so a nameserver that had only timed out could be reported as "network error: context canceled". It now records no reason for it. A try the context's deadline cuts short ends as a timeout. When the context has ended before a further try, tryExchange now returns that try's error instead of ErrContextCanceled, so such a nameserver is reported as timed out, not as answering. Model: opus-5-5
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"testing"
|
||||
@@ -132,3 +134,33 @@ func TestReadReply(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestQuerySingleType_ContextEnded asks a nameserver about one record
|
||||
// type with a context that has already ended, so no query is sent. A
|
||||
// query the context ended before it was sent says nothing about the
|
||||
// nameserver and records no reason: a nameserver whose earlier query
|
||||
// timed out is still reported as timed out, not as a network error.
|
||||
func TestQuerySingleType_ContextEnded(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := NewFromLogger(slog.New(slog.DiscardHandler))
|
||||
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
cancel()
|
||||
|
||||
resp := &NameserverResponse{Records: map[string][]string{}, Status: StatusOK}
|
||||
|
||||
// The query for an earlier record type timed out.
|
||||
state := queryState{gotTimeout: true}
|
||||
|
||||
_, err := r.querySingleType(
|
||||
ctx, []string{"192.0.2.1"}, "example.com.", dns.TypeA, resp, &state,
|
||||
)
|
||||
require.ErrorIs(t, err, ErrContextCanceled)
|
||||
assert.Equal(t, queryState{gotTimeout: true}, state)
|
||||
|
||||
classifyResponse(resp, state)
|
||||
|
||||
assert.Equal(t, StatusTimeout, resp.Status)
|
||||
assert.Equal(t, "all queries timed out", resp.Error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user