Files
mesh-host/internal/apply/module_scope_test.go
T

114 lines
4.4 KiB
Go

package apply
import (
"context"
"path/filepath"
"testing"
"git.novox.be/novox/mesh-sdk/go/declaration"
"github.com/novox/mesh-host/internal/store"
)
// R6-A AC3: given two modules declaring one path, when one module's want changes, the shared path is neither removed
// nor taken from the other module (novox/hq ADR 0539 §9).
func TestASharedPathIsNeitherRemovedNorTakenFromTheOtherModule(t *testing.T) {
dir := t.TempDir()
shared := filepath.Join(dir, "shared.conf")
own := filepath.Join(dir, "a-own.conf")
a := declare(t, `{"id":"a.shared","type":"file","path":"`+shared+`","content":"x\n","module":"a"},
{"id":"a.own","type":"file","path":"`+own+`","content":"a\n","module":"a"}`)
b := declare(t, `{"id":"b.shared","type":"file","path":"`+shared+`","content":"x\n","module":"b"}`)
state := store.State{}
var err error
_, state, err = ApplyModule(context.Background(), archHost(t), a, Scope{Module: "a", Others: b.Resources},
state, store.OriginDeclared, noServices, nil, nil, nil, nil)
if err != nil {
t.Fatal(err)
}
_, state, err = ApplyModule(context.Background(), archHost(t), b, Scope{Module: "b", Others: a.Resources},
state, store.OriginDeclared, noServices, nil, nil, nil, nil)
if err != nil {
t.Fatal(err)
}
// A's want changes: it no longer declares the shared path, and b still does.
a2 := declare(t, `{"id":"a.own","type":"file","path":"`+own+`","content":"a\n","module":"a"}`)
report, state, err := ApplyModule(context.Background(), archHost(t), a2, Scope{Module: "a", Others: b.Resources},
state, store.OriginDeclared, noServices, nil, nil, nil, nil)
if err != nil {
t.Fatal(err)
}
if !exists(shared) {
t.Fatal("the path another module still declares was removed")
}
if _, still := state.Find("b.shared"); !still {
t.Fatal("the other module's record was taken away")
}
if _, still := state.Find("a.shared"); still {
t.Fatal("the module's own record of the shared path was kept")
}
if o := outcomeOf(report, "a.shared"); o.Action != "forgotten" {
t.Fatalf("the shared path: %+v", o)
}
}
// R6-A AC4: given modules A and B on a node, when A's want is removed, only A's resources are removed and B is
// untouched.
func TestARemovedModuleTakesOnlyItsOwnResources(t *testing.T) {
dir := t.TempDir()
fa, fb := filepath.Join(dir, "a.conf"), filepath.Join(dir, "b.conf")
d := declare(t, `{"id":"a.conf","type":"file","path":"`+fa+`","content":"a\n","module":"a"},
{"id":"b.conf","type":"file","path":"`+fb+`","content":"b\n","module":"b"}`)
_, state, err := Apply(context.Background(), archHost(t), d, store.State{}, store.OriginDeclared, noServices, nil, nil)
if err != nil {
t.Fatal(err)
}
if rec, _ := state.Find("a.conf"); rec.Module != "a" {
t.Fatalf("the owner was not recorded: %+v", rec)
}
gone := &declaration.Declaration{}
b := declare(t, `{"id":"b.conf","type":"file","path":"`+fb+`","content":"b\n","module":"b"}`)
report, state, err := ApplyModule(context.Background(), archHost(t), gone, Scope{Module: "a", Others: b.Resources},
state, store.OriginDeclared, noServices, nil, nil, nil, nil)
if err != nil {
t.Fatal(err)
}
if exists(fa) || !exists(fb) {
t.Fatalf("a's file exists %v, b's file exists %v", exists(fa), exists(fb))
}
if o := outcomeOf(report, "a.conf"); o.Action != "removed" {
t.Fatalf("a's file: %+v", o)
}
if _, still := state.Find("b.conf"); !still {
t.Fatal("b's record was removed")
}
if _, still := state.Find("a.conf"); still {
t.Fatal("a's record is still there")
}
}
// A record from before the owner was kept is read by its id, so the first removal after the switch is the module's too.
func TestARecordWithoutAnOwnerBelongsToTheModuleItsIdNames(t *testing.T) {
dir := t.TempDir()
fa, fb := filepath.Join(dir, "a.conf"), filepath.Join(dir, "b.conf")
d := declare(t, `{"id":"a.conf","type":"file","path":"`+fa+`","content":"a\n"},
{"id":"b.conf","type":"file","path":"`+fb+`","content":"b\n"}`)
_, state, err := Apply(context.Background(), archHost(t), d, store.State{}, store.OriginDeclared, noServices, nil, nil)
if err != nil {
t.Fatal(err)
}
for i := range state.Resources {
state.Resources[i].Module = ""
}
_, state, err = ApplyModule(context.Background(), archHost(t), &declaration.Declaration{}, Scope{Module: "a"},
state, store.OriginDeclared, noServices, nil, nil, nil, nil)
if err != nil {
t.Fatal(err)
}
if exists(fa) || !exists(fb) {
t.Fatalf("a's file exists %v, b's file exists %v", exists(fa), exists(fb))
}
}