//go:build integration package main import ( "encoding/json" "strings" "testing" "time" "github.com/novox/mesh-controller/internal/link" ) // 1145/AC1 on a store: declarationWith itself sets the module of each resource and the build of each module for a // node recorded as reading them, and for no other. Skips without a store. func TestAComposedDeclarationCarriesModulesAndBuildsOnlyForANodeThatReadsThem(t *testing.T) { open := aMesh(t) ctx := t.Context() inv := open.inventory start := time.Now().Add(-time.Hour) manifest := resticFixture(false) manifest["module"], manifest["version"] = "restic", "1" raw, _ := json.Marshal(manifest) b := link.BuildResult{ID: link.NewBuildID(start), Repository: "novox/mesh-catalog", Path: "modules/restic", On: "anchor", Module: "restic", Commit: "c1", Manifest: raw, Source: &link.SourceOnSeat{Seat: "git", Repository: "novox/mesh-catalog"}} if _, _, err := takeIn(ctx, inv, asTheOperator(t, inv, b)); err != nil { t.Fatal(err) } for _, n := range []string{"anchor", "laptop"} { if _, err := inv.Assign(ctx, n, "restic"); err != nil { t.Fatal(err) } } anchor, err := inv.NodeByName(ctx, "anchor") if err != nil { t.Fatal(err) } if err := inv.RecordReadsModules(ctx, anchor.ID, true); err != nil { t.Fatal(err) } wantBuild, err := inv.BuildOf(ctx, "restic", "c1") if err != nil || wantBuild == "" { t.Fatalf("the build of restic at c1 is %q (%v)", wantBuild, err) } declare := func(node string) sendable { t.Helper() d, err := composeSend(ctx, open, node) if err != nil { t.Fatal(err) } return d } reads := bodyKeys(t, declare("anchor")) builds, _ := reads["builds"].(map[string]any) if builds["restic"] != wantBuild { t.Errorf("1145/AC1: anchor reads modules and was sent builds %v, want restic at %s", reads["builds"], wantBuild) } owned := 0 for _, r := range reads["resources"].([]any) { r := r.(map[string]any) if strings.HasPrefix(r["id"].(string), "restic.") { owned++ if r["module"] != "restic" { t.Errorf("1145/AC1: resource %v carries module %v, want restic", r["id"], r["module"]) } } } if owned == 0 { t.Fatal("1145/AC1: no resource of restic was composed") } plain := bodyKeys(t, declare("laptop")) if _, there := plain["builds"]; there { t.Errorf("1145/AC1: laptop never said it reads modules and was sent builds %v", plain["builds"]) } for _, r := range plain["resources"].([]any) { if _, there := r.(map[string]any)["module"]; there { t.Fatalf("1145/AC1: laptop was sent a module on %v", r) } } }