//go:build integration package main import ( "encoding/json" "reflect" "strings" "testing" "git.novox.be/novox/mesh-sdk/go/catalogue" ) func aMeshWithTheWordsInItsLayers(t *testing.T) (*stores, wordedMesh) { t.Helper() open := aMesh(t) ctx := t.Context() inv := open.inventory w := theWordedMesh(t) image := "registry.invalid:5000/library@sha256:" + strings.Repeat("a", 64) register(t, open, catalogue.Manifest{Module: "proxy", Version: "1", Provides: catalogue.FromAnywhere("route"), Receives: map[string]string{"route": "/var/lib/proxy/routes.json"}}) for _, text := range w.Modules { m, err := catalogue.ParseManifest([]byte(strings.ReplaceAll(string(text), "IMAGE", image))) if err != nil { t.Fatal(err) } register(t, open, m) } on := map[string][]string{"anchor": {"proxy"}, "laptop": {"proxy"}} for _, l := range w.Layers { settings, err := json.Marshal(l.Settings) if err != nil { t.Fatal(err) } inv.ExecForTest(t, `insert into settings (node, module, values) select id, $2, $3 from node where name = $1`, l.Node, l.Module, string(settings)) if l.Placement != nil { placement, err := json.Marshal(l.Placement) if err != nil { t.Fatal(err) } inv.ExecForTest(t, `insert into placement (node, module, values) select id, $2, $3 from node where name = $1`, l.Node, l.Module, string(placement)) } on[l.Node] = append(on[l.Node], l.Module) } for _, node := range []string{"anchor", "laptop"} { if err := inv.SetPublicDomain(ctx, node, node+".example.test"); err != nil { t.Fatal(err) } if _, err := assign(ctx, open, node, on[node]...); err != nil { t.Fatalf("assign %s %v: %v", node, on[node], err) } } return open, w } func TestADeclarationIsTheSameWhileTheWordsAreStillInTheLayers(t *testing.T) { open, _ := aMeshWithTheWordsInItsLayers(t) sameAsTheGolden(t, open, "before the move") } func TestADeclarationIsTheSameAfterTheMoveOfPlacement(t *testing.T) { open, w := aMeshWithTheWordsInItsLayers(t) ctx := t.Context() inv := open.inventory asked, err := runMovePlacement(ctx, inv, false) if err != nil || !asked.DryRun || len(asked.Moved) != len(w.Layers) { t.Fatalf("the move, not confirmed, says %+v (%v); %d layers hold the words", asked, err, len(w.Layers)) } if held := inv.QueryForTest(t, `select module from settings where values ?| $1`, catalogue.PlacementKeys()); len(held) != len(w.Layers) { t.Fatalf("the move, not confirmed, moved something: %d layers still hold the words", len(held)) } sameAsTheGolden(t, open, "after the move was asked without confirming") moved, err := runMovePlacement(ctx, inv, true) if err != nil || moved.DryRun || !reflect.DeepEqual(moved.Moved, asked.Moved) { t.Fatalf("the move says %+v (%v), it said it would move %+v", moved, err, asked.Moved) } if held := inv.QueryForTest(t, `select module from settings where values ?| $1`, catalogue.PlacementKeys()); len(held) != 0 { t.Fatalf("a settings layer still holds a placement key: %v", held) } sameAsTheGolden(t, open, "after the move") if again, err := runMovePlacement(ctx, inv, true); err != nil || len(again.Moved) != 0 { t.Fatalf("asked again, the move moved %+v (%v)", again, err) } if said := describeMovePlacement(movePlacementAnswer{}); !strings.Contains(said, "nothing to move") { t.Fatalf("an empty move says %q", said) } }