watcher: a stop during the first scan sends no startup notification (closes #271)
check / check (push) Waiting to run
check / check (push) Waiting to run
Run sent the startup notification right after the first scan without checking the context. RunOnce returns as usual when shutdown cuts the scan short, so a stop during the first scan sent "has started and completed its initial scan" to every endpoint as the process shut down. Run now sends it only when the context was not cancelled. The new test cancels the context before Run starts, so the scan never sends its lookup; a stop part way through a scan follows the same path. 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-13: a stop before the first scan completes sends no startup
|
||||||
|
notification; a scan that ran to the end still sends it (closes #271).
|
||||||
- 2026-10-13: a nameserver leaving a domain's delegation sends only NS Change;
|
- 2026-10-13: a nameserver leaving a domain's delegation sends only NS Change;
|
||||||
one leaving a hostname's zone sends NS Change, not NS Failure (closes #262).
|
one leaving a hostname's zone sends NS Change, not NS Failure (closes #262).
|
||||||
- 2026-10-13: `DNSWATCHER_METRICS_USERNAME` set without
|
- 2026-10-13: `DNSWATCHER_METRICS_USERNAME` set without
|
||||||
|
|||||||
@@ -83,6 +83,30 @@ func TestCancelledCheckSavesNothing(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestStopBeforeFirstScanSendsNoStartupNotification runs a watcher with
|
||||||
|
// the startup notification on and its context already cancelled, so the
|
||||||
|
// first scan is cut short before its lookup is sent. The scan did not
|
||||||
|
// complete, so no startup notification may be sent.
|
||||||
|
func TestStopBeforeFirstScanSendsNoStartupNotification(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := defaultTestConfig(t)
|
||||||
|
cfg.Hostnames = []string{testHost}
|
||||||
|
cfg.SendTestNotification = true
|
||||||
|
|
||||||
|
w, deps := newTestWatcher(t, cfg)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(t.Context())
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
w.Run(ctx)
|
||||||
|
|
||||||
|
notifications := deps.notifier.getNotifications()
|
||||||
|
if len(notifications) != 0 {
|
||||||
|
t.Errorf("sent %v, want no notifications", notifications)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// newLoggingWatcher returns a watcher for a domain and a hostname, with
|
// newLoggingWatcher returns a watcher for a domain and a hostname, with
|
||||||
// the real resolver, that writes what it logs at warning level or above
|
// the real resolver, that writes what it logs at warning level or above
|
||||||
// into the returned buffer.
|
// into the returned buffer.
|
||||||
|
|||||||
@@ -133,7 +133,12 @@ func (w *Watcher) Run(ctx context.Context) {
|
|||||||
|
|
||||||
w.cleanupRemovedTargets()
|
w.cleanupRemovedTargets()
|
||||||
w.RunOnce(ctx)
|
w.RunOnce(ctx)
|
||||||
w.maybeSendTestNotification(ctx)
|
|
||||||
|
// RunOnce returns as usual when shutdown cuts the scan short, and
|
||||||
|
// the startup notification says the scan completed.
|
||||||
|
if ctx.Err() == nil {
|
||||||
|
w.maybeSendTestNotification(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
dnsTicker := time.NewTicker(w.config.DNSInterval)
|
dnsTicker := time.NewTicker(w.config.DNSInterval)
|
||||||
tlsTicker := time.NewTicker(w.config.TLSInterval)
|
tlsTicker := time.NewTicker(w.config.TLSInterval)
|
||||||
|
|||||||
Reference in New Issue
Block a user