package stacks import ( "os" "path/filepath" "testing" ) // R-1220: an installed app whose app.yaml cannot be read must count as INSTALLED (fail closed). Before the fix a parse // error gave a nil AppConfig, so the app looked „not installed", its live drive folder was listed as kept data — and // the household's Delete was offered on it. Red-proved against the code before the fix (the folder was listed). func TestR1220_AnUnreadableAppYamlKeepsTheFolderLive(t *testing.T) { m, drive := keptManager(t) app := filepath.Join(filepath.Dir(m.stacks["cloudapp"].ComposePath)) // An app.yaml that exists but does not parse (a half-written file, a disk error). must(t, os.WriteFile(filepath.Join(app, "app.yaml"), []byte("deployed: true\nenv: [this is: not: yaml\n"), 0o600)) must(t, m.ScanStacks()) items := m.ListKept([]string{drive}) for _, it := range items { if it.App == "cloudapp" || it.Path == filepath.Join(drive, "appdata", "cloudapp") { t.Fatalf("an app with an unreadable app.yaml had its live folder listed as kept: %+v", it) } } if _, err := m.DeleteKept([]string{drive}, filepath.Join(drive, "appdata", "cloudapp")); err == nil { t.Fatal("Delete was allowed on the folder of an app whose app.yaml cannot be read") } if _, err := os.Stat(filepath.Join(drive, "appdata/cloudapp/user1/file.txt")); err != nil { t.Fatalf("the live folder's file is gone: %v", err) } // The control: with NO app.yaml at all (a real leftover), the folder IS listed. must(t, os.Remove(filepath.Join(app, "app.yaml"))) must(t, m.ScanStacks()) if items := m.ListKept([]string{drive}); len(items) != 1 || items[0].App != "cloudapp" { t.Fatalf("a real leftover (no app.yaml) is not listed: %+v", items) } }