v0.297.0: burn-down round 2 — 24 small rows (R-591 R-568 R-567 R-363 R-547 R-10 R-552 R-251 R-104 R-619 R-362 R-675 R-256 R-257 R-240 R-365 R-425 R-565 R-564 R-603 R-454 R-208 R-457-swept) + the banner countdown and deepCopyStack twins; MinAgent 0.131.0
gates / gates (push) Failing after 50s
gates / gates (push) Failing after 50s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/config"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
||||
)
|
||||
|
||||
// R-552: an interrupted-restore notice was cleared only by a NEW restore of the same app, so a
|
||||
// household that answered it by REMOVING the app kept a „Megszakadt visszaállítás" card about an app
|
||||
// that no longer exists — for ever, because the notice is persisted. The consequence asserted: after
|
||||
// the removal path's clear, the notice is gone from the page's list AND from the persisted record (a
|
||||
// fresh Manager loading the file sees none), while another app's notice stays.
|
||||
// COMPANION RED-PROOF: drop the clearInterruptedRestoreNotice call from removeStack → the AST check
|
||||
// fails; make ClearInterruptedRestore a no-op → the notice is still listed.
|
||||
func TestR552_RemoveClearsTheInterruptedRestoreNotice(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
cfg := &config.Config{}
|
||||
cfg.Paths.DataDir = dir
|
||||
lg := log.New(io.Discard, "", 0)
|
||||
sett, err := settings.Load(filepath.Join(dir, "settings.json"), lg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recPath := filepath.Join(dir, "restore-status.json")
|
||||
// The record two stops left behind: "otherapp" already carries a notice, "homebox" was running.
|
||||
seed := map[string]any{
|
||||
"running": true, "op": "restore", "stack": "homebox",
|
||||
"interrupted": map[string]any{"otherapp": map[string]any{"op": "restore", "stack": "otherapp", "interrupted": true}},
|
||||
}
|
||||
b, _ := json.Marshal(seed)
|
||||
if err := os.WriteFile(recPath, b, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
load := func() *backup.Manager {
|
||||
bm := backup.NewManager(cfg, sett, lg)
|
||||
bm.SetRestoreRecordPath(recPath)
|
||||
bm.LoadRestoreRecord()
|
||||
return bm
|
||||
}
|
||||
bm := load()
|
||||
if _, ok := bm.InterruptedRestore("homebox"); !ok {
|
||||
t.Fatal("setup: no interrupted notice for homebox")
|
||||
}
|
||||
|
||||
r := &Router{backupMgr: bm, logger: lg}
|
||||
r.clearInterruptedRestoreNotice("homebox")
|
||||
|
||||
if _, ok := bm.InterruptedRestore("homebox"); ok {
|
||||
t.Errorf("R-552: the removed app's interrupted-restore notice is still listed")
|
||||
}
|
||||
if _, ok := bm.InterruptedRestore("otherapp"); !ok {
|
||||
t.Errorf("another app's notice was cleared by this app's removal")
|
||||
}
|
||||
again := load()
|
||||
if _, ok := again.InterruptedRestore("homebox"); ok {
|
||||
t.Errorf("R-552: the notice comes back after a restart — the clear was not persisted")
|
||||
}
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "router.go", nil, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
called := false
|
||||
for _, d := range f.Decls {
|
||||
if fn, ok := d.(*ast.FuncDecl); ok && fn.Name.Name == "removeStack" && fn.Body != nil {
|
||||
ast.Inspect(fn.Body, func(n ast.Node) bool {
|
||||
if s, ok := n.(*ast.SelectorExpr); ok && s.Sel.Name == "clearInterruptedRestoreNotice" {
|
||||
called = true
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
if !called {
|
||||
t.Errorf("R-552: removeStack does not call clearInterruptedRestoreNotice")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user