mesh/merge-gate head a39661aa36f3 merged into trunk 34392e74916c — pass, with a note: builds mesh-sdk (+41 dependent(s)) → ace, g14, novox, shanks; no bus …
mesh/repo-check head a39661aa36f3 merged into trunk 34392e74916c — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript)…
mesh/delivery delivered
179 lines
6.5 KiB
Go
179 lines
6.5 KiB
Go
package delivery
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func inputs() SourceInputs {
|
|
return SourceInputs{
|
|
Module: "mesh-mail", Tree: "t-module",
|
|
Bases: []string{"registry.example/base@sha256:aaa", "registry.example/other@sha256:bbb"},
|
|
Contexts: map[string]string{"mail": "t-root", "tool": "t-root2"},
|
|
Toolchains: map[string]string{"mail": "go sha256:ccc 0123456789abcdef", "tool": "go sha256:ccc fedcba9876543210"},
|
|
}
|
|
}
|
|
|
|
func mustFP(t *testing.T, in SourceInputs) string {
|
|
t.Helper()
|
|
fp, none := SourceFingerprint(in)
|
|
if fp == "" || none != "" {
|
|
t.Fatalf("fingerprint = %q, none = %q", fp, none)
|
|
}
|
|
return fp
|
|
}
|
|
|
|
func TestFingerprintForm(t *testing.T) {
|
|
fp := mustFP(t, inputs())
|
|
hex := strings.TrimPrefix(fp, SourcePrefix)
|
|
if SourcePrefix != "src1:" || hex == fp || len(hex) != 64 || strings.Trim(hex, "0123456789abcdef") != "" {
|
|
t.Errorf("fingerprint %q is not src1: and 64 hex digits", fp)
|
|
}
|
|
}
|
|
|
|
func TestFingerprintOrderAndDuplicates(t *testing.T) { // 1203/AC2
|
|
want := mustFP(t, inputs())
|
|
in := inputs()
|
|
in.Bases = []string{in.Bases[1], in.Bases[0]}
|
|
if got := mustFP(t, in); got != want {
|
|
t.Errorf("the order of bases changes it: %s", got)
|
|
}
|
|
in = inputs()
|
|
in.Bases = append(in.Bases, in.Bases[0])
|
|
if got := mustFP(t, in); got != want {
|
|
t.Errorf("a base given twice changes it: %s", got)
|
|
}
|
|
in = inputs()
|
|
in.Bases = append(in.Bases, "other.registry.example/base@sha256:aaa")
|
|
if got := mustFP(t, in); got != want {
|
|
t.Errorf("two references to one digest change it: %s", got)
|
|
}
|
|
// Maps have no order, but build them in many insertion orders anyway.
|
|
for i := 0; i < 20; i++ {
|
|
in = inputs()
|
|
in.Contexts = map[string]string{}
|
|
in.Toolchains = map[string]string{}
|
|
for _, k := range []string{"tool", "mail"} {
|
|
in.Contexts[k] = inputs().Contexts[k]
|
|
in.Toolchains[k] = inputs().Toolchains[k]
|
|
}
|
|
if got := mustFP(t, in); got != want {
|
|
t.Fatalf("map order changes it: %s", got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFingerprintChanges(t *testing.T) { // 1203/AC3
|
|
want := mustFP(t, inputs())
|
|
for name, f := range map[string]func(*SourceInputs){
|
|
"module": func(in *SourceInputs) { in.Module = "other" },
|
|
"tree": func(in *SourceInputs) { in.Tree = "t-other" },
|
|
"base": func(in *SourceInputs) { in.Bases[0] = "registry.example/base@sha256:zzz" },
|
|
"a base added": func(in *SourceInputs) { in.Bases = append(in.Bases, "x@sha256:new") },
|
|
"context": func(in *SourceInputs) { in.Contexts["mail"] = "t-changed" },
|
|
"context artifact": func(in *SourceInputs) { in.Contexts["extra"] = "t-root" },
|
|
"toolchain": func(in *SourceInputs) { in.Toolchains["tool"] = "go sha256:ccc changed" },
|
|
} {
|
|
in := inputs()
|
|
f(&in)
|
|
if got := mustFP(t, in); got == want {
|
|
t.Errorf("a changed %s keeps the fingerprint", name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFingerprintNone(t *testing.T) { // 1203/AC4
|
|
in := inputs()
|
|
in.Unpinned = "the build resolves packages when built"
|
|
fp, none := SourceFingerprint(in)
|
|
if fp != "" || none != in.Unpinned {
|
|
t.Errorf("unpinned: fp = %q, none = %q", fp, none)
|
|
}
|
|
in = inputs()
|
|
in.Tree = ""
|
|
fp, none = SourceFingerprint(in)
|
|
if fp != "" || none != "no tree" {
|
|
t.Errorf("no tree: fp = %q, none = %q", fp, none)
|
|
}
|
|
in = inputs()
|
|
in.Tree, in.Unpinned = "", "the build resolves packages when built"
|
|
if _, none = SourceFingerprint(in); none != in.Unpinned {
|
|
t.Errorf("the reason for unpinned stands over no tree: %q", none)
|
|
}
|
|
}
|
|
|
|
func TestReferenceDigest(t *testing.T) {
|
|
for in, want := range map[string]string{
|
|
"registry.example/base@sha256:aaa": "sha256:aaa",
|
|
"registry.example/base": "registry.example/base",
|
|
"registry.example/base@": "registry.example/base@",
|
|
"": "",
|
|
} {
|
|
if got := ReferenceDigest(in); got != want {
|
|
t.Errorf("ReferenceDigest(%q) = %q, want %q", in, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 1203/AC1: three builds the live builder recorded a source fingerprint for. Each value is captured, never written
|
|
// by hand: the recorded fingerprint was read with mesh-controller.builds (after issues 1204 and 1208 were
|
|
// delivered); each tree is `git rev-parse <commit>:<dir>` in the repository's clone; the bases are from the
|
|
// build's `[bases]` log lines; the toolchain lines are mesh-controller's toolchainOf over its toolchains values.
|
|
func TestFingerprintLiveBuilds(t *testing.T) {
|
|
const ts = "typescript sha256:4b81682df5665c1f461d3f720a3a0fd7593f4aa71e4fc272dbfdc4bbd235b489 20125bd590041690"
|
|
for _, c := range []struct {
|
|
name string
|
|
in SourceInputs
|
|
recorded string
|
|
}{
|
|
{
|
|
// mailu, build-1792391134620131370: mesh-catalog at b4527d9091e972f28cb365623d9280045e7741a3, dir modules/mailu.
|
|
name: "mailu",
|
|
in: SourceInputs{
|
|
Module: "mailu",
|
|
Tree: "cfc6fa8ff5fc1e220132e51ade653b9d3f387b3e",
|
|
Bases: []string{"sha256:25f3cfeaceca14921366af4d1240b56457ef46273bdb508c7b0e8f469f6fd228"},
|
|
Toolchains: map[string]string{"code": ts},
|
|
},
|
|
recorded: "src1:539f2e64000d436c572ef53b40e524012455945f8c5a1c6bb173ee0707e88ef4",
|
|
},
|
|
{
|
|
// radarr, build-1792391147149753355: mesh-media-catalog at 197abb061d9b77d67c7f11e9e567528ea7a85436,
|
|
// dir modules/radarr; no bases.
|
|
name: "radarr",
|
|
in: SourceInputs{
|
|
Module: "radarr",
|
|
Tree: "42b9c918b5af75cba2bbc75845012e7f64e16df9",
|
|
Toolchains: map[string]string{
|
|
"code": ts,
|
|
"tools-go": "go sha256:2054591ca034b68323d87ec887ba34f56819cb3364034360c0777da4b314dd54 0995d85edc9a6a23",
|
|
},
|
|
},
|
|
recorded: "src1:b3c150d39c395b99dd68974a48490e9a42467aa5d486d0c604d6ef1e8e9c910a",
|
|
},
|
|
{
|
|
// build-agent, build-1792395447088936520: mesh-controller at 7a74cee83f88e6585a5511c3cc53bdf0f5303d20,
|
|
// dir modules/build-agent; the context is narrowTree's hash of the 185 paths GoBuildSource gave for
|
|
// cmd/mesh-builder at 7a74cee8.
|
|
name: "build-agent",
|
|
in: SourceInputs{
|
|
Module: "build-agent",
|
|
Tree: "11c0b4f90cae0d6e4ef9cc48cbfdf9f6dbe52bca",
|
|
Bases: []string{
|
|
"sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc",
|
|
"sha256:8ac98ca534ac3f51e1f420a1dd2c15e74c75cfa0f23f3ad27eb5d7236c349a0c",
|
|
},
|
|
Contexts: map[string]string{"server": "narrow:d51ca744fd11af59d616c858f76c27b3e58e16e11fbdc0c720eb9d7d19d55fac"},
|
|
},
|
|
recorded: "src1:e846efe73716b78e80860baaac96153de2cb76551325753838ca245d2160a3d7",
|
|
},
|
|
} {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
fp, none := SourceFingerprint(c.in)
|
|
if none != "" || fp != c.recorded {
|
|
t.Errorf("fingerprint = %q (none %q), the live builder recorded %q", fp, none, c.recorded)
|
|
}
|
|
})
|
|
}
|
|
}
|