package apply import ( "context" "os" "testing" "github.com/novox/mesh-host/internal/store" ) // An operator-owned path the module reaches but does not own (novox/hq ADR 0051). // // The host confirms it is present and changes nothing: it does not create it, chown it or set its // mode, because the media library and the download spool are the operator's and several modules // share them. This is the opposite of a directory on every axis, and the whole reason the two are // different shapes. func TestAnAccessPresentIsConfirmedAndNothingIsChanged(t *testing.T) { dir := t.TempDir() // the operator's directory, already there d := declare(t, `{"id":"lib","type":"access","path":"`+dir+`","mode":"read-write"}`) report, _, err := Apply(context.Background(), archHost(t), d, store.State{}, store.OriginDeclared, noServices, nil, nil) if err != nil { t.Fatalf("an operator-owned path that is present was refused: %v", err) } if report.Changed() { t.Fatalf("confirming an access reported a change; the host owns nothing about it") } if _, statErr := os.Stat(dir); statErr != nil { t.Fatalf("the operator's directory was disturbed: %v", statErr) } } // Undeclaring an access never removes the path. Unassigning the module that reached the media // library must not delete the library — that is the data loss ADR 0030 exists to prevent, on a // directory the mesh never made. The record is dropped; the operator's data is left exactly as it // is. func TestAnUndeclaredAccessLeavesTheOperatorsPathAlone(t *testing.T) { lib := t.TempDir() // the operator's library keep := t.TempDir() if err := os.WriteFile(lib+"/a-real-file", []byte("the operator's data"), 0o644); err != nil { t.Fatal(err) } d := declare(t, `{"id":"lib","type":"access","path":"`+lib+`","mode":"read"}`) _, state, err := Apply(context.Background(), archHost(t), d, store.State{}, store.OriginDeclared, noServices, nil, nil) if err != nil { t.Fatal(err) } // The module is unassigned: the mesh no longer declares the access. empty := declare(t, `{"id":"unrelated","type":"directory","path":"`+keep+`"}`) report, _, err := Apply(context.Background(), archHost(t), empty, state, store.OriginDeclared, noServices, nil, nil) if err != nil { t.Fatal(err) } if _, statErr := os.Stat(lib); statErr != nil { t.Fatalf("the operator's library was removed when the module stopped reaching it: %v", statErr) } if _, statErr := os.Stat(lib + "/a-real-file"); statErr != nil { t.Fatalf("the operator's data was removed: %v", statErr) } var forgot bool for _, o := range report.Outcomes { if o.Type == "access" && o.Action == "forgotten" { forgot = true } } if !forgot { t.Errorf("dropping an access was not reported as forgotten: %+v", report.Outcomes) } }