2487681396
gofmt -w across the controller tree (46 files) so gofmt -l is empty — disarms the
formatting landmine where a targeted edit + accidental gofmt -w swept ~46 unrelated
files. Pure formatting: whitespace + gofmt's optional-semicolon removal in reflowed
inline closures. One doc comment reworded ('' -> 'the empty string') to avoid gofmt's
Go-1.19 doc-comment typographic substitition ('' -> curly quote) muddying its meaning.
No build/vet/test behavior change.
70 lines
3.0 KiB
Go
70 lines
3.0 KiB
Go
package stacks
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// T1: the deploy belt SKIPS ensure when an EXTERNAL drive root is not a live mountpoint (drive absent).
|
|
// Creating ${USERDATA_PATH}/... then would land app data on the rootfs, shadowed when the drive returns.
|
|
// Companion red-proof: removing the gate in ensureUserdataMounts makes the dir get created → this fails.
|
|
func TestEnsureUserdataMounts_SkipsAbsentExternalDrive(t *testing.T) {
|
|
m := newMigManager(t, "") // sysDataPath = /mnt/sys_drive
|
|
m.isMountPoint = func(string) bool { return false } // external drive is NOT mounted
|
|
stackDir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(stackDir, "docker-compose.yml"), []byte(beltCompose), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ud := filepath.Join(t.TempDir(), "userdata")
|
|
env := []string{"HDD_PATH=/mnt/felhom-drives/flash", "USERDATA_PATH=" + ud} // external, != sysDataPath
|
|
|
|
m.ensureUserdataMounts(stackDir, env)
|
|
|
|
if _, err := os.Stat(filepath.Join(ud, "media", "movies")); err == nil {
|
|
t.Fatal("belt MUST NOT create userdata dirs when the external drive is absent (rootfs-shadow hazard)")
|
|
}
|
|
if _, err := os.Stat(filepath.Join(ud, "downloads")); err == nil {
|
|
t.Fatal("belt MUST NOT create userdata dirs when the external drive is absent")
|
|
}
|
|
}
|
|
|
|
// T2: the belt ENSURES the bind-source dirs when the external drive IS a live mountpoint.
|
|
func TestEnsureUserdataMounts_EnsuresWhenMounted(t *testing.T) {
|
|
m := newMigManager(t, "")
|
|
m.isMountPoint = func(string) bool { return true } // drive mounted
|
|
stackDir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(stackDir, "docker-compose.yml"), []byte(beltCompose), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ud := filepath.Join(t.TempDir(), "userdata")
|
|
env := []string{"HDD_PATH=/mnt/felhom-drives/flash", "USERDATA_PATH=" + ud}
|
|
|
|
m.ensureUserdataMounts(stackDir, env)
|
|
|
|
for _, p := range []string{filepath.Join(ud, "media", "movies"), filepath.Join(ud, "downloads")} {
|
|
if fi, err := os.Stat(p); err != nil || !fi.IsDir() {
|
|
t.Errorf("belt should create %s when the drive is mounted (%v)", p, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// T3: the SYSTEM/local path (HDD_PATH == sysDataPath) is NEVER gated — the SSD path is legitimately not
|
|
// a mountpoint, so ensure must always run there (must-not-over-gate).
|
|
func TestEnsureUserdataMounts_SystemPathNeverSkipped(t *testing.T) {
|
|
m := newMigManager(t, "") // sysDataPath = /mnt/sys_drive
|
|
m.isMountPoint = func(string) bool { return false } // SSD path is not a mountpoint — but must not gate
|
|
stackDir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(stackDir, "docker-compose.yml"), []byte(beltCompose), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ud := filepath.Join(t.TempDir(), "userdata")
|
|
env := []string{"HDD_PATH=" + m.sysDataPath, "USERDATA_PATH=" + ud} // system path
|
|
|
|
m.ensureUserdataMounts(stackDir, env)
|
|
|
|
if fi, err := os.Stat(filepath.Join(ud, "media", "movies")); err != nil || !fi.IsDir() {
|
|
t.Errorf("belt must ALWAYS ensure on the system/local path (not a mountpoint, but never gated): %v", err)
|
|
}
|
|
}
|