60 lines
2.9 KiB
Go
60 lines
2.9 KiB
Go
package backup
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// R-488 — the package's ONE test clock for the post-restore health wait.
|
|
//
|
|
// Before this, every restore fixture slept waitForHealthy's 3 s settle for real, and every fixture
|
|
// whose fake provider never reports "running" waited out the full 90 s timeout: measured 2026-10-05,
|
|
// 51 of 599 tests took ≥ 1 s and together held 442 of the package's 444 s, two of them alone 279 s.
|
|
// The production values are captured here BEFORE they are shortened, so the pin below reads what a
|
|
// box runs, not what the tests run.
|
|
var prodHealthSettle, prodHealthInterval, prodHealthTimeout = healthSettle, healthInterval, healthTimeout
|
|
var prodStableWindow, prodStablePoll, prodStableWatch = stableStartWindow, stableStartPoll, stableReleaseWatch
|
|
|
|
func TestMain(m *testing.M) {
|
|
healthSettle = 0
|
|
healthInterval = 2 * time.Millisecond
|
|
healthTimeout = 50 * time.Millisecond
|
|
// D48 / R-650: no test in this package reaches Docker for the restore's pre-pull — every image is present unless a
|
|
// test says otherwise (m.imagePresentFn / m.imagePullFn).
|
|
imagePresentDefault = func(string) bool { return true }
|
|
// fix A (R-1270 follow-up): the stable-start window, shortened for the package the way the health wait is.
|
|
stableStartWindow, stableStartPoll, stableReleaseWatch = 30*time.Millisecond, 2*time.Millisecond, 2*time.Second
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
// The shortening is a TEST seam only: a box must still give a restored stack 3 s to settle, poll
|
|
// every 5 s, and wait 90 s before calling the restore unhealthy.
|
|
func TestR488_HealthWaitDefaultsAreProduction(t *testing.T) {
|
|
if prodHealthSettle != 3*time.Second || prodHealthInterval != 5*time.Second || prodHealthTimeout != 90*time.Second {
|
|
t.Fatalf("production health wait changed: settle=%v interval=%v timeout=%v (want 3s/5s/1m30s) — "+
|
|
"a restored app now gets a different grace on every box", prodHealthSettle, prodHealthInterval, prodHealthTimeout)
|
|
}
|
|
if prodStableWindow != 3*time.Minute || prodStablePoll != 10*time.Second || prodStableWatch != 30*time.Minute {
|
|
t.Fatalf("production stable-start rule changed: window=%v poll=%v watch=%v (want 3m/10s/30m)", prodStableWindow, prodStablePoll, prodStableWatch)
|
|
}
|
|
}
|
|
|
|
// The consequence the seam must not break: a stack that never comes up is still reported as a
|
|
// failure (only sooner), and one that is up is accepted.
|
|
func TestR488_WaitForHealthyStillJudges(t *testing.T) {
|
|
m := &Manager{}
|
|
m.stackProvider = &fakeRecoveryProvider{running: false}
|
|
start := time.Now()
|
|
if err := m.waitForHealthy("app", healthTimeout); err == nil {
|
|
t.Fatal("a stack that never reaches running must fail the health wait")
|
|
}
|
|
if d := time.Since(start); d > 5*time.Second {
|
|
t.Fatalf("the shortened clock is not in force: the wait took %v", d)
|
|
}
|
|
m.stackProvider = &fakeRecoveryProvider{running: true}
|
|
if err := m.waitForHealthy("app", healthTimeout); err != nil {
|
|
t.Fatalf("a running stack must pass: %v", err)
|
|
}
|
|
}
|