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:
@@ -1380,10 +1380,10 @@ func TestQueryNameserverIP_Timeout(t *testing.T) {
|
||||
r := newTestResolver(t)
|
||||
|
||||
// Nothing answers at 192.0.2.1, a documentation address. The
|
||||
// resolver tries each query twice, and the first try gives up
|
||||
// after two seconds. A deadline that ends during the first try
|
||||
// makes the status vary from run to run between error and
|
||||
// timeout, so the deadline must outlast the first try.
|
||||
// resolver tries each query twice, and each try gives up after two
|
||||
// seconds. This deadline ends during the second try of the first
|
||||
// record type; TestQueryNameserverIP_DeadlineDuringFirstTry covers
|
||||
// one that ends during the first.
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(), 3*time.Second,
|
||||
)
|
||||
@@ -1399,6 +1399,31 @@ func TestQueryNameserverIP_Timeout(t *testing.T) {
|
||||
assert.NotEmpty(t, resp.Error)
|
||||
}
|
||||
|
||||
// TestQueryNameserverIP_DeadlineDuringFirstTry gives a query to
|
||||
// 192.0.2.1, where nothing answers, a deadline that ends during its
|
||||
// first try. That try ends at the deadline as a timeout, so the
|
||||
// nameserver is reported as timed out, not as answering.
|
||||
func TestQueryNameserverIP_DeadlineDuringFirstTry(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := newTestResolver(t)
|
||||
|
||||
// Well under the two seconds one try waits.
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(), 500*time.Millisecond,
|
||||
)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
resp, err := r.QueryNameserverIP(
|
||||
ctx, "unreachable.test.", "192.0.2.1",
|
||||
"example.com",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, resolver.StatusTimeout, resp.Status)
|
||||
assert.NotEmpty(t, resp.Error)
|
||||
}
|
||||
|
||||
// TestQueryNameserverIP_CancelledLogsNothing cancels the context while
|
||||
// a query to 192.0.2.1, where nothing answers, is waiting for a reply,
|
||||
// as shutdown does. The query was cut short, not failed, so nothing is
|
||||
|
||||
Reference in New Issue
Block a user