The indexer needs a module's manifest, lock hashes and toolchain to compute its new-form fingerprint, and has none of them (ADR 0465 clauses 1, 2, 5): the forge messages now carry the first two, a module keeps its inputs so it can be computed again when a toolchain is reported, and the build modules' toolchain keys have a layout and an agreement rule.
91 lines
2.9 KiB
Go
91 lines
2.9 KiB
Go
package delivery
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func tcEntry(node, lang, version, recipe string) NodeToolchain {
|
|
return NodeToolchain{Node: node, Toolchain: Toolchain{Language: lang, Version: version, Recipe: recipe, At: time.Unix(100, 0).UTC()}}
|
|
}
|
|
|
|
// 1443/AC1
|
|
func TestToolchainKeyAndValue(t *testing.T) {
|
|
key, err := ToolchainKey("ace", "go")
|
|
if err != nil || key != "ace.go" {
|
|
t.Fatalf("%q %v", key, err)
|
|
}
|
|
node, lang, err := ParseToolchainKey(key)
|
|
if err != nil || node != "ace" || lang != "go" {
|
|
t.Errorf("%q %q %v", node, lang, err)
|
|
}
|
|
for _, bad := range []string{"", "ace", "ace.rust", ".go", "a.b.go", "ace."} {
|
|
if _, _, err := ParseToolchainKey(bad); err == nil {
|
|
t.Errorf("ParseToolchainKey(%q) passed", bad)
|
|
}
|
|
}
|
|
if _, err := ToolchainKey("ace", "python"); err == nil {
|
|
t.Error("language python keyed")
|
|
}
|
|
want := Toolchain{Language: "go", Version: "1.26.1", Recipe: "3", At: time.Unix(100, 0).UTC()}
|
|
data, err := EncodeToolchain(want)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := DecodeToolchain(data)
|
|
want.V = Version
|
|
if err != nil || got != want {
|
|
t.Errorf("%+v %v", got, err)
|
|
}
|
|
for name, bad := range map[string]Toolchain{
|
|
"python": {Language: "python", Version: "3", Recipe: "1"},
|
|
"no version": {Language: "go", Recipe: "1"},
|
|
"no recipe": {Language: "typescript", Version: "5"},
|
|
} {
|
|
if _, err := EncodeToolchain(bad); err == nil {
|
|
t.Errorf("%s was encoded", name)
|
|
}
|
|
if _, err := DecodeToolchain([]byte(`{"v":1,"language":"` + bad.Language + `","version":"` + bad.Version + `","recipe":"` + bad.Recipe + `"}`)); err == nil {
|
|
t.Errorf("%s was decoded", name)
|
|
}
|
|
}
|
|
if ToolchainsBucket("go-build") != "go-build_toolchains" {
|
|
t.Error(ToolchainsBucket("go-build"))
|
|
}
|
|
}
|
|
|
|
// 1443/AC2
|
|
func TestAgreedToolchain(t *testing.T) {
|
|
tc, none := AgreedToolchain([]NodeToolchain{tcEntry("ace", "go", "1.26.1", "3"), tcEntry("novox", "go", "1.26.1", "3")})
|
|
if tc != (Toolchain2{Language: "go", Version: "1.26.1", Recipe: "3"}) || none != "" {
|
|
t.Errorf("%+v %q", tc, none)
|
|
}
|
|
}
|
|
|
|
// 1443/AC3
|
|
func TestAgreedToolchainNoReport(t *testing.T) {
|
|
tc, none := AgreedToolchain(nil)
|
|
if tc != (Toolchain2{}) || none != "toolchain not yet reported" {
|
|
t.Errorf("%+v %q", tc, none)
|
|
}
|
|
}
|
|
|
|
// 1443/AC4
|
|
func TestAgreedToolchainDisagree(t *testing.T) {
|
|
a, b, c := tcEntry("ace", "go", "1.26.1", "3"), tcEntry("novox", "go", "1.26.2", "3"), tcEntry("g14", "go", "1.26.1", "4")
|
|
_, first := AgreedToolchain([]NodeToolchain{a, b, c})
|
|
_, second := AgreedToolchain([]NodeToolchain{c, b, a})
|
|
if first == "" || first != second {
|
|
t.Errorf("order changed the answer: %q vs %q", first, second)
|
|
}
|
|
for _, want := range []string{"builders disagree", "1.26.1", "1.26.2", "ace", "novox", "g14"} {
|
|
if !strings.Contains(first, want) {
|
|
t.Errorf("%q does not name %q", first, want)
|
|
}
|
|
}
|
|
if tc, _ := AgreedToolchain([]NodeToolchain{a, b}); tc != (Toolchain2{}) {
|
|
t.Errorf("a disagreement gave %+v", tc)
|
|
}
|
|
}
|