Test how a manifest and lock hashes become a module's new-form inputs (issue 1450, design 47 R4c-2)
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
package index
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// aBase is the new-form fingerprint of a base module, the one SourceFingerprint2 gives for the inputs of avahi at a tree.
|
||||
func aBase(t *testing.T) string {
|
||||
t.Helper()
|
||||
fp, none := delivery.SourceFingerprint2(delivery.SourceInputs2{Module: "mesh-tools", Tree: "basetree"})
|
||||
if none != "" {
|
||||
t.Fatal(none)
|
||||
}
|
||||
return fp
|
||||
}
|
||||
|
||||
func noBases(string) (string, string) { return "", "none are held in this test" }
|
||||
|
||||
func TestAGoModuleKeepsItsTreeAndTheHashOfItsLockFile(t *testing.T) { // 1450/AC1
|
||||
in := inputsOf("avahi", catalogueManifest(t, "avahi"), "avahitree", map[string]string{"go.sum": avahiGoSum}, noBases)
|
||||
want := &delivery.KeptInputs2{Tree: "avahitree", Locks: map[string]string{"tools": avahiGoSum}}
|
||||
if !reflect.DeepEqual(in.Kept, want) {
|
||||
t.Errorf("kept = %+v, want %+v", in.Kept, want)
|
||||
}
|
||||
if !reflect.DeepEqual(in.Languages, map[string]string{"tools": "go"}) {
|
||||
t.Errorf("languages = %v, want tools: go", in.Languages)
|
||||
}
|
||||
// Through the indexer: the merge's tree of the module's directory and the lock hashes of that directory, kept in modules.avahi.
|
||||
ix, mods, _ := manifestsIndexer(t, rec(t, "build-1", "avahi", catalogueRepo, "modules/avahi", "main", "", "2026-10-19T09:00:00Z", aInputs))
|
||||
f := withManifests(mergedMsg(catalogueRepo, map[string]string{"modules/avahi": "avahitree", "modules/other": "x"}),
|
||||
map[string]string{"modules/avahi": catalogueManifest(t, "avahi")}, map[string]map[string]string{"modules/avahi": {"go.sum": avahiGoSum}})
|
||||
if err := ix.Apply(context.Background(), f); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m, ok := moduleOf(t, mods, "avahi")
|
||||
if !ok || !reflect.DeepEqual(m.Inputs2, want) || m.Manifest != delivery.ManifestDigest([]byte(catalogueManifest(t, "avahi"))) {
|
||||
t.Errorf("module = %+v (%v), want inputs %+v and the manifest digest", m, ok, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnArtifactThatResolvesPackagesAndHasNoLockFileHasAnEmptyHash(t *testing.T) { // 1450/AC2
|
||||
in := inputsOf("avahi", catalogueManifest(t, "avahi"), "avahitree", nil, noBases)
|
||||
if in.Kept == nil || !reflect.DeepEqual(in.Kept.Locks, map[string]string{"tools": ""}) {
|
||||
t.Fatalf("kept = %+v, want Locks {tools: \"\"}", in.Kept)
|
||||
}
|
||||
// The fingerprint of such inputs is none, "no lock" (mesh-sdk SourceFingerprint2).
|
||||
if fp, none := delivery.SourceFingerprint2(in.Kept.With("avahi", nil)); fp != "" || none != "no lock" {
|
||||
t.Errorf("fingerprint = %q none %q, want none 'no lock'", fp, none)
|
||||
}
|
||||
// A TypeScript bundle's lock file is package-lock.json, not go.sum.
|
||||
ts := inputsOf("audit-logger", catalogueManifest(t, "audit-logger"), "t", map[string]string{"go.sum": "wrong", "package-lock.json": avahiGoSum}, noBases)
|
||||
if ts.Kept == nil || !reflect.DeepEqual(ts.Kept.Locks, map[string]string{"code": avahiGoSum}) || !reflect.DeepEqual(ts.Languages, map[string]string{"code": "typescript"}) {
|
||||
t.Errorf("typescript: kept %+v languages %v", ts.Kept, ts.Languages)
|
||||
}
|
||||
// netcheck has a Go and a TypeScript bundle: each takes its own language's lock file.
|
||||
both := inputsOf("netcheck", catalogueManifest(t, "netcheck"), "t", map[string]string{"go.sum": "g", "package-lock.json": "p"}, noBases)
|
||||
if both.Kept == nil || !reflect.DeepEqual(both.Kept.Locks, map[string]string{"tools-go": "g", "tools-typescript": "p"}) {
|
||||
t.Errorf("netcheck: kept %+v", both.Kept)
|
||||
}
|
||||
}
|
||||
|
||||
// aModuleWithABase is avahi's manifest (mesh-catalog a67f0196) with the one build.on entry that names a module as the
|
||||
// controller's own test has it (mesh-controller internal/builder/standing_on_test.go:22): no manifest of the sources names
|
||||
// a module as a base, only vendors' images.
|
||||
func aModuleWithABase(t *testing.T) string {
|
||||
t.Helper()
|
||||
raw := catalogueManifest(t, "avahi")
|
||||
with := strings.Replace(raw, `"build": {`, `"build": {
|
||||
"on": [{"arg": "RUNTIME_BASE", "module": "mesh-tools", "artifact": "runtime"}],`, 1)
|
||||
if with == raw {
|
||||
t.Fatal("avahi's manifest has no build")
|
||||
}
|
||||
return with
|
||||
}
|
||||
|
||||
func TestABaseEntersByTheFingerprintOfItsModuleOrNamesItsAbsence(t *testing.T) { // 1450/AC3
|
||||
fp := aBase(t)
|
||||
has := func(module string) (string, string) {
|
||||
if module != "mesh-tools" {
|
||||
t.Errorf("asked for the base %q", module)
|
||||
}
|
||||
return fp, ""
|
||||
}
|
||||
in := inputsOf("avahi", aModuleWithABase(t), "t", map[string]string{"go.sum": avahiGoSum}, has)
|
||||
if in.Kept == nil || !reflect.DeepEqual(in.Kept.Bases, []string{fp}) {
|
||||
t.Errorf("bases = %+v, want [%s]", in.Kept, fp)
|
||||
}
|
||||
none := inputsOf("avahi", aModuleWithABase(t), "t", map[string]string{"go.sum": avahiGoSum}, noBases)
|
||||
if none.Kept == nil || len(none.Kept.Bases) != 0 || !strings.Contains(none.None2, "mesh-tools") || !strings.Contains(none.None2, "base") {
|
||||
t.Errorf("kept %+v none2 %q, want no bases and none2 naming the base mesh-tools", none.Kept, none.None2)
|
||||
}
|
||||
// Through the indexer: modules.mesh-tools holds a fingerprint of the new form (a record written by a later release).
|
||||
ix, mods, _ := manifestsIndexer(t, rec(t, "build-1", "avahi", catalogueRepo, "modules/avahi", "main", "", "2026-10-19T09:00:00Z", aInputs))
|
||||
mods.put("mesh-tools", mustEncode(t, delivery.Module{Repository: catalogueRepo, Commit: merge, None: "x", FP2: fp, Manifest: strings.Repeat("a", 64)}))
|
||||
f := withManifests(mergedMsg(catalogueRepo, map[string]string{"modules/avahi": "t"}), map[string]string{"modules/avahi": aModuleWithABase(t)}, nil)
|
||||
if err := ix.Apply(context.Background(), f); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if m, _ := moduleOf(t, mods, "avahi"); m.Inputs2 == nil || !reflect.DeepEqual(m.Inputs2.Bases, []string{fp}) {
|
||||
t.Errorf("module = %+v, want the base's fingerprint", m)
|
||||
}
|
||||
}
|
||||
|
||||
func mustEncode(t *testing.T, m delivery.Module) []byte {
|
||||
t.Helper()
|
||||
b, err := delivery.EncodeModule(m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func TestAnArtifactOfNoToolchainHasNoLanguageAndNoLock(t *testing.T) { // 1450/AC4
|
||||
in := inputsOf("ca-trust", catalogueManifest(t, "ca-trust"), "t", map[string]string{"go.sum": avahiGoSum}, noBases)
|
||||
if in.Kept == nil || len(in.Kept.Locks) != 0 || len(in.Languages) != 0 {
|
||||
t.Errorf("kept %+v languages %v, want neither locks nor languages for an archive", in.Kept, in.Languages)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAManifestTheParserRefusesLeavesNoInputsAndSaysWhy(t *testing.T) { // 1450/AC5
|
||||
for name, raw := range map[string]string{
|
||||
"not json": "not json",
|
||||
"unknown field": strings.Replace(catalogueManifest(t, "avahi"), `"version": "1",`, `"version": "1", "scope": "everything",`, 1),
|
||||
} {
|
||||
in := inputsOf("avahi", raw, "t", nil, noBases)
|
||||
if in.Kept != nil || !strings.HasPrefix(in.None2, "the manifest cannot be read: ") || len(in.None2) <= len("the manifest cannot be read: ") {
|
||||
t.Errorf("%s: kept %+v none2 %q, want nil and 'the manifest cannot be read: <error>'", name, in.Kept, in.None2)
|
||||
}
|
||||
}
|
||||
if in := inputsOf("someone-else", catalogueManifest(t, "avahi"), "t", nil, noBases); in.Kept != nil || !strings.Contains(in.None2, "avahi") {
|
||||
t.Errorf("a manifest of another module: kept %+v none2 %q", in.Kept, in.None2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAContextIsNotPinned(t *testing.T) { // 1450 (the rule 1444 keeps: context not pinned, as today's form)
|
||||
// build-agent's manifest from mesh-controller at f2d7bc94 has an image artifact built from a context in another repository.
|
||||
in := inputsOf("build-agent", fixture(t, "controller-f2d7bc94-build-agent"), "t", nil, noBases)
|
||||
if in.Kept == nil || in.None2 != None2Context {
|
||||
t.Errorf("kept %+v none2 %q, want none2 %q", in.Kept, in.None2, None2Context)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user