mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-10-12 01:58:46 +02:00
test(cli): keep the indefinite recovery wait test off the host's DNS
TestNetworkShutdownCancelsIndefiniteRecoveryWait relied on an empty upstream map never recovering. Since 73db7adc an empty pool checks upstream.os instead, so the test probed the host's real OS resolver. On a host with working DNS that check succeeds, recovery completes, and it reads the upstream monitor the test never built. Recover against a loopback port nothing listens on, so the wait can never end on its own, and give the prog the upstream monitor that run always creates before network monitoring can start a recovery. The panic is test-only: production never reaches recovery without one.
This commit is contained in:
1 file changed
+13
-3
@@ -176,13 +176,23 @@ func TestNetworkShutdownCancelsIndefiniteRecoveryWait(t *testing.T) {
|
||||
oldReset, oldIntercept := recoveryResetDNSFn, dnsIntercept
|
||||
dnsIntercept = false
|
||||
defer func() { recoveryResetDNSFn, dnsIntercept = oldReset, oldIntercept }()
|
||||
p := &prog{cfg: &ctrld.Config{}}
|
||||
// The only upstream is a loopback port nothing listens on, so recovery
|
||||
// can never succeed. An empty upstream map no longer does that: recovery
|
||||
// then checks upstream.os, and on a host with working DNS that answers,
|
||||
// completes the recovery and turns the test into a probe of the host.
|
||||
dead := &ctrld.UpstreamConfig{Type: ctrld.ResolverTypeLegacy, Endpoint: deadUDPAddr(t), Timeout: 300}
|
||||
dead.Init(context.Background())
|
||||
cfg := &ctrld.Config{Upstream: map[string]*ctrld.UpstreamConfig{"0": dead}}
|
||||
p := &prog{cfg: cfg}
|
||||
p.logger.Store(mainLog.Load())
|
||||
// Recovery reads the upstream monitor, which run creates before network
|
||||
// monitoring can start any recovery.
|
||||
p.um = newUpstreamMonitor(cfg, p.logger.Load())
|
||||
entered := make(chan struct{})
|
||||
recoveryResetDNSFn = func(*prog, bool, bool) { close(entered) }
|
||||
recovered := make(chan struct{})
|
||||
// An empty upstream map can never recover. Shutdown must cancel that wait
|
||||
// without waiting on a mutex held for the recovery's entire lifetime.
|
||||
// Shutdown must cancel that wait without waiting on a mutex held for the
|
||||
// recovery's entire lifetime.
|
||||
go func() { p.handleRecovery(RecoveryReasonRegularFailure); close(recovered) }()
|
||||
waitNetworkShutdownSignal(t, entered, "recovery reset seam")
|
||||
closed := make(chan struct{})
|
||||
|
||||
Reference in new issue
Block a user