Compare commits

..
1 Commits
Author SHA1 Message Date
clawbot 48275d598e tests: remove the DNS stand-ins from the watcher and resolver tests (closes #159)
check / check (push) Successful in 1m17s
The watcher tests used a stand-in resolver and the resolver timeout test
a stand-in DNS client, against the rule that DNS is never mocked. The
watcher tests now run the real resolver against live DNS. A change is
tested by saving values live DNS never returns (names under .invalid,
192.0.2.1) in the state a check starts from, or by marking a real
nameserver failed. The timeout test queries 192.0.2.1, where nothing
answers. The live-DNS retry and concurrency limit moved from the
resolver tests to internal/livedns, so both packages share them.
NewFromLoggerWithClient had no other use and is gone. TESTING.md and
the DNSClient comment now state the README's rule.

Model: opus-5-5
2026-09-29 03:28:13 +00:00
2 changed files with 17 additions and 11 deletions
+7 -5
View File
@@ -16,10 +16,12 @@
// operations are in flight at once in one test binary. // operations are in flight at once in one test binary.
// //
// 2. Retry with exponential backoff. Each live operation gets several // 2. Retry with exponential backoff. Each live operation gets several
// attempts with its own timeout. The retry condition is strictly // attempts with its own timeout. An attempt is retried when it
// transport-level — "did a nameserver answer at all" — never the // obtained nothing to check, never because of what the test
// assertion the test is making. Code that answers incorrectly // asserts about the result, so a wrong result still fails on the
// still fails on the first attempt. // first attempt. A fault in the code under test that leaves
// nothing to check looks the same as live DNS not answering, and
// fails only after the last attempt.
package livedns package livedns
import ( import (
@@ -113,7 +115,7 @@ func Retry(
} }
t.Fatalf( t.Fatalf(
"%s: no answer after %d live attempts: %v", "%s: all %d live attempts failed: %v",
what, attempts, last, what, attempts, last,
) )
} }
+10 -6
View File
@@ -171,11 +171,11 @@ func defaultTestConfig(t *testing.T) *config.Config {
} }
} }
// checkOnce runs the watcher's checks once and returns // checkOnce runs the watcher's checks once and returns an error when a
// livedns.ErrNoAnswer when live DNS did not answer for a configured // configured name has no hostname state saved by this check, or that
// name. The watcher saves a name's hostname state only when all of the // state holds no address. The watcher saves a name's hostname state
// name's lookups succeed, so live DNS answered for a name when this // only when all of the name's lookups succeed, so this means either
// check saved its hostname state and that state holds an address. // live DNS did not answer or the watcher did not save what it got.
func checkOnce( func checkOnce(
ctx context.Context, ctx context.Context,
w *watcher.Watcher, w *watcher.Watcher,
@@ -191,7 +191,11 @@ func checkOnce(
hs, ok := deps.state.GetHostnameState(name) hs, ok := deps.state.GetHostnameState(name)
if !ok || hs.LastChecked.Before(started) || if !ok || hs.LastChecked.Before(started) ||
len(addresses(hs)) == 0 { len(addresses(hs)) == 0 {
return fmt.Errorf("%w: %s", livedns.ErrNoAnswer, name) return fmt.Errorf(
"%s: %w, or the watcher saved no fresh "+
"result for it",
name, livedns.ErrNoAnswer,
)
} }
} }