63 lines
2.3 KiB
Go
63 lines
2.3 KiB
Go
package web
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/parser"
|
|
"go/token"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// R-1251 (review round 2, HUNT-1 H1): the two web paths that START a drive-backed app when its drive is there — the
|
|
// boot recreate and the drive-return restart — must pour a waiting put-back back FIRST (resumePutBack), before
|
|
// appHeld and before StartStack; and the drive-return branch must run the sweep for held apps it did not stop. A
|
|
// source pin: the decision is tested in internal/backup (r1251_putback_waits_test.go); this pins the WIRING.
|
|
// COMPANION RED-PROOF (2026-10-24): drop `!s.resumePutBack(...) ||` from either path, or the sweep from the Return
|
|
// branch → this fails.
|
|
func TestR1251_DriveStartPathsPutBackBeforeTheyStart(t *testing.T) {
|
|
src, err := os.ReadFile("intermediary.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
fset := token.NewFileSet()
|
|
f, err := parser.ParseFile(fset, "intermediary.go", src, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
body := map[string]string{}
|
|
for _, d := range f.Decls {
|
|
if fn, ok := d.(*ast.FuncDecl); ok && fn.Body != nil {
|
|
body[fn.Name.Name] = string(src[fset.Position(fn.Body.Pos()).Offset:fset.Position(fn.Body.End()).Offset])
|
|
}
|
|
}
|
|
order := func(fn, first, then string) {
|
|
t.Helper()
|
|
b, ok := body[fn]
|
|
if !ok {
|
|
t.Fatalf("function %s not found in intermediary.go — the pin is stale", fn)
|
|
}
|
|
i, j := strings.Index(b, first), strings.Index(b, then)
|
|
if i < 0 || j < 0 || i > j {
|
|
t.Errorf("%s: %q must come before %q (found at %d, %d) — the app would start on the cut restore's data", fn, first, then, i, j)
|
|
}
|
|
}
|
|
order("restartStacks", "!s.resumePutBack(name)", "s.stackMgr.StartStack(name)")
|
|
order("restartStacks", "!s.resumePutBack(name)", "s.appHeld(name)")
|
|
// the boot recreate is a closure inside the boot-id handler; find the function that holds it
|
|
var recreateFn string
|
|
for name, b := range body {
|
|
if strings.Contains(b, "live bind confirmed — recreating drive-backed app") {
|
|
recreateFn = name
|
|
}
|
|
}
|
|
if recreateFn == "" {
|
|
t.Fatal("the boot recreate closure was not found — the pin is stale")
|
|
}
|
|
order(recreateFn, "!s.resumePutBack(bs.name)", "s.stackMgr.StartStack(bs.name)")
|
|
order("ReconcileDriveGates", "s.restartStacks(stopped)", "ResumeWaitingPutBacks()")
|
|
if !strings.Contains(body["resumePutBack"], "ResumePutBack(name)") {
|
|
t.Error("resumePutBack no longer asks the app-stop guard")
|
|
}
|
|
}
|