package resolution import ( "strings" "testing" mcat "git.novox.be/novox/mesh-sdk/go/catalogue" ) var digest = "sha256:" + strings.Repeat("d", 64) // **The address is composed into a declaration, and the record never carries it.** func TestAnImageTheMeshBuiltIsRoutedThroughTheStoreWhenDeclared(t *testing.T) { m := mcat.Manifest{Module: "gitea", Version: "1", Resources: []map[string]any{ {"id": "server", "type": "container", "name": "mesh-gitea", "artifact": "server"}, {"id": "config", "type": "archive", "path": "/etc/gitea", "artifact": "config"}, {"id": "cache", "type": "container", "name": "mesh-gitea-cache", "image": "valkey/valkey@" + digest}, }, Build: &mcat.Build{Artifacts: []mcat.Artifact{ {Name: "server", Kind: mcat.ArtifactImage, From: "Dockerfile"}, {Name: "config", Kind: mcat.ArtifactArchive, From: "config"}, }}} resolved, err := m.Resolve([]mcat.Built{ {Name: "server", Kind: mcat.ArtifactImage, Reference: mcat.ArtifactStoreScheme + "gitea/server@" + digest}, {Name: "config", Kind: mcat.ArtifactArchive, Reference: mcat.ArtifactStoreScheme + "gitea/config/blobs/" + digest, Digest: digest}, }) if err != nil { t.Fatal(err) } r := mcat.Resolution{Node: "anchor", Modules: []mcat.Manifest{resolved}} out, err := Declaration(r, mcat.Rendering{ArtifactStore: "anchor.internal:5101"}) if err != nil { t.Fatal(err) } if got := fileNamed(out, "gitea.server")["image"]; got != "anchor.internal:5101/gitea/server@"+digest { t.Errorf("the image the mesh built is fetched as %v", got) } if got := fileNamed(out, "gitea.config")["source"]; got != "http://anchor.internal:5101/v2/gitea/config/blobs/"+digest { t.Errorf("the archive the mesh built is fetched from %v", got) } if got := fileNamed(out, "gitea.cache")["image"]; got != "valkey/valkey@"+digest { t.Errorf("an image from a public registry was routed through the store: %v", got) } // The manifest the mesh holds still says what it is, not where it was fetched from. if got := resolved.Resources[0]["image"]; got != mcat.ArtifactStoreScheme+"gitea/server@"+digest { t.Errorf("composing wrote the address into the catalogue's copy: %v", got) } // And the store moves: the same record, another address, without a rebuild. out, err = Declaration(r, mcat.Rendering{ArtifactStore: "laptop.internal:5000"}) if err != nil { t.Fatal(err) } if got := fileNamed(out, "gitea.server")["image"]; got != "laptop.internal:5000/gitea/server@"+digest { t.Errorf("after the store moved, the image is still fetched as %v", got) } } func TestAnImageInTheStoreWithNoStoreToFetchItFromIsRefused(t *testing.T) { m := mcat.Manifest{Module: "gitea", Version: "1", Resources: []map[string]any{ {"id": "server", "type": "container", "name": "mesh-gitea", "image": mcat.ArtifactStoreScheme + "gitea/server@" + digest}, }} _, err := Declaration(mcat.Resolution{Node: "anchor", Modules: []mcat.Manifest{m}}, mcat.Rendering{}) if err == nil || !strings.Contains(err.Error(), "no artifact store") { t.Fatalf("a reference nothing can fetch was sent to a machine: %v", err) } } // **A reference recorded with an address before this follows the store too** — when the mesh // built it. A module running an image straight from a public registry under its own name is left // exactly where it says: `quay.io/keycloak/keycloak` is not the mesh's, whatever it is called. func TestAReferenceRecordedWithAnAddressFollowsTheStoreWhenTheMeshBuiltIt(t *testing.T) { m := mcat.Manifest{Module: "keycloak", Version: "1", Resources: []map[string]any{ {"id": "server", "type": "container", "name": "mesh-keycloak", "image": "anchor.internal:5100/keycloak/server@" + digest}, {"id": "upstream", "type": "container", "name": "mesh-keycloak-upstream", "image": "quay.io/keycloak/keycloak@" + digest}, }} r := mcat.Resolution{Node: "anchor", Modules: []mcat.Manifest{m}} out, err := Declaration(r, mcat.Rendering{ ArtifactStore: "anchor.internal:5101", Built: map[string]bool{"keycloak/server": true}, }) if err != nil { t.Fatal(err) } if got := fileNamed(out, "keycloak.server")["image"]; got != "anchor.internal:5101/keycloak/server@"+digest { t.Errorf("an image the mesh built, recorded with the old address, is fetched as %v", got) } if got := fileNamed(out, "keycloak.upstream")["image"]; got != "quay.io/keycloak/keycloak@"+digest { t.Errorf("a public image was re-routed through the store: %v", got) } // Nothing known to be built: nothing re-routed, nothing refused. out, err = Declaration(r, mcat.Rendering{ArtifactStore: "anchor.internal:5101"}) if err != nil { t.Fatal(err) } if got := fileNamed(out, "keycloak.server")["image"]; got != "anchor.internal:5100/keycloak/server@"+digest { t.Errorf("with no build record, a reference was rewritten: %v", got) } }