package backup import ( "bytes" "log" "path/filepath" "strings" "testing" "gitea.dooplex.hu/admin/felhom-controller/internal/settings" ) // Part 0.5 (F-3afix-1): the offsite restore scratch must prefer a LOCAL path — a network (squashed) // scratch would feed PlaceOffsiteRestore wrong-owner files. A network app-drive is skipped when a // local candidate exists; a network-only environment is a last resort WITH a loud WARN. func TestOffboxScratchDir_PrefersLocal(t *testing.T) { m, sett := newOffboxManager(t) prov := &offbox3aProvider{hdd: map[string]string{}, binds: map[string][]ClassifiedBind{}, has: map[string]bool{}} m.SetStackProvider(prov) nas := "/mnt/nas" local := t.TempDir() if err := sett.AddStoragePath(settings.StoragePath{Path: nas, Label: "nas", Schedulable: true, Kind: settings.StorageKindNetwork, Protocol: "nfs"}); err != nil { t.Fatal(err) } if err := sett.AddStoragePath(settings.StoragePath{Path: local, Label: "local", Schedulable: true}); err != nil { t.Fatal(err) } prov.hdd["immich"] = nas // the app lives ON the NAS _, nsRoot, err := m.offboxRestoreScratchDir("immich") if err != nil { t.Fatalf("scratchDir: %v", err) } if strings.Contains(nsRoot, "nas") { t.Errorf("network app-drive must not be the scratch — got %q, want the local drive", nsRoot) } if !strings.HasPrefix(nsRoot, filepath.Clean(local)) { t.Errorf("scratch nsRoot = %q, want under the local drive %q", nsRoot, local) } } func TestOffboxScratchDir_NetworkOnlyLastResortWarns(t *testing.T) { var buf bytes.Buffer m, sett := newOffboxManager(t) m.logger = log.New(&buf, "", 0) prov := &offbox3aProvider{hdd: map[string]string{}, binds: map[string][]ClassifiedBind{}, has: map[string]bool{}} m.SetStackProvider(prov) nas := "/mnt/nas" if err := sett.AddStoragePath(settings.StoragePath{Path: nas, Label: "nas", Schedulable: true, Kind: settings.StorageKindNetwork, Protocol: "nfs"}); err != nil { t.Fatal(err) } prov.hdd["immich"] = nas _, nsRoot, err := m.offboxRestoreScratchDir("immich") if err != nil { t.Fatalf("scratchDir: %v", err) } if !strings.Contains(nsRoot, "nas") { t.Errorf("network-only → the NAS is the last resort, got %q", nsRoot) } if !strings.Contains(buf.String(), "ownership fidelity not guaranteed") { t.Errorf("last-resort network scratch must log a loud WARN, got: %s", buf.String()) } }