Files
felhom-controller/controller/internal/stacks/delete_r1027_test.go
T

73 lines
3.0 KiB
Go

package stacks
import (
"path/filepath"
"testing"
)
// R-1027 — „delete my data too" must never delete a read-only bind or the shared media library. MEASURED 2026-10-14
// on Tester 1: removing a throwaway Plex (a READER, `:ro`) with „delete data" deleted drive A's whole
// `userdata/media`. The test asserts the EFFECT on a real tree: the library's files are still there, the app's own
// folder is gone.
//
// COMPANION RED-PROOF (2026-10-15): make keepOnRemoval return "" → this test fails (the library and the :ro folder are
// deleted). Restored.
func TestRemoveStack_R1027_NeverDeletesSharedOrReadOnly(t *testing.T) {
drive := t.TempDir()
compose := "services:\n" +
" app:\n" +
" image: nginx:1.27\n" +
" volumes:\n" +
" - ${HDD_PATH}/appdata/app:/data\n" +
" - " + drive + "/userdata/media:" + drive + "/userdata/media\n" + // a literal, rw, shared library (the drill shape)
" - " + drive + "/userdata/documents/scans:/scans:ro\n" + // someone else's folder, read only
" - app_cfg:/config\n" +
"volumes:\n" +
" app_cfg:\n"
m, _, _ := newR442Manager(t, "app", compose, driveAppYAML(drive), drive)
own := filepath.Join(drive, "appdata", "app", "state.db")
film := filepath.Join(drive, "userdata", "media", "movies", "Nosferatu (1922)", "Nosferatu.mkv")
scan := filepath.Join(drive, "userdata", "documents", "scans", "letter.pdf")
plantFile(t, own)
plantFile(t, film)
plantFile(t, scan)
resp, err := m.RemoveStack("app", true, nil)
if err != nil {
t.Fatalf("remove: %v", err)
}
if exists(own) {
t.Errorf("the app's OWN folder must be deleted with delete-my-data: %s still exists", own)
}
if !exists(film) {
t.Fatalf("the shared media library was DELETED by an app's removal (R-1027): %s is gone; resp=%+v", film, resp)
}
if !exists(scan) {
t.Fatalf("a read-only bind was DELETED by an app's removal (R-1027): %s is gone", scan)
}
}
// R-1032 — the safety list knows the userdata layout: the userdata root, the media library and its folders, the
// download folders. COMPANION RED-PROOF: remove the R-1032 block from ProtectedHDDPaths → this test fails. Restored.
func TestProtectedHDDPaths_R1032_UserdataLayout(t *testing.T) {
p := ProtectedHDDPaths("/mnt/felhom-drives/hdd_1")
for _, want := range []string{
"/mnt/felhom-drives/hdd_1/userdata",
"/mnt/felhom-drives/hdd_1/userdata/media",
"/mnt/felhom-drives/hdd_1/userdata/media/tv",
"/mnt/felhom-drives/hdd_1/userdata/media/movies",
"/mnt/felhom-drives/hdd_1/userdata/media/torrents",
"/mnt/felhom-drives/hdd_1/userdata/media/transmission",
"/mnt/felhom-drives/hdd_1/userdata/documents",
"/mnt/felhom-drives/hdd_1/userdata/downloads",
"/mnt/felhom-drives/hdd_1/media", // the old layout stays protected too
} {
if !p[want] {
t.Errorf("ProtectedHDDPaths does not protect %s", want)
}
}
if p["/mnt/felhom-drives/hdd_1/userdata/media/movies/Some Film"] {
t.Error("a single film folder is not a top-level folder — the list must stay a list of roots")
}
}