Files
mesh-delivery/sdk/buildstep/toolchains_test.go
T

74 lines
2.7 KiB
Go

package buildstep
import (
"strings"
"testing"
)
func tcEntry(node, lang, version, recipe string) NodeToolchain {
return NodeToolchain{Node: node, Toolchain: Toolchain{Language: lang, Version: version, Recipe: recipe}}
}
// 1443/AC2-4, ADR 0584: the agreed toolchain is the strict majority's; a minority node sits out; a tie waits.
func TestToolchainAgreement(t *testing.T) {
e := tcEntry
for _, c := range []struct {
name string
in []NodeToolchain
version string
out []SittingOut
wait []string // "" wait means agreed
}{
{"all agree", []NodeToolchain{e("ace", "go", "1.26.1", "3"), e("novox", "go", "1.26.1", "3")}, "1.26.1", nil, nil},
{"three against one", []NodeToolchain{e("ace", "typescript", "26.12.1", "3"), e("g14", "typescript", "26.13.0", "3"), e("novox", "typescript", "26.13.0", "3"), e("shanks", "typescript", "26.13.0", "3")},
"26.13.0", []SittingOut{{"ace", "26.12.1", "3"}}, nil},
{"two against two", []NodeToolchain{e("ace", "go", "1.26.1", "3"), e("novox", "go", "1.26.2", "3"), e("g14", "go", "1.26.1", "3"), e("shanks", "go", "1.26.2", "3")},
"", nil, []string{"builders disagree", "1.26.1 recipe 3 on ace, g14", "1.26.2 recipe 3 on novox, shanks"}},
{"one node alone", []NodeToolchain{e("ace", "go", "1.26.1", "3")}, "1.26.1", nil, nil},
{"no report", nil, "", nil, []string{ToolchainNoReport}},
} {
a := ToolchainAgreement(c.in)
rev := make([]NodeToolchain, len(c.in))
for i, x := range c.in {
rev[len(c.in)-1-i] = x
}
if b := ToolchainAgreement(rev); b.Wait != a.Wait || b.Toolchain != a.Toolchain {
t.Errorf("%s: order changed the answer: %+v vs %+v", c.name, a, b)
}
if a.Toolchain.Version != c.version || len(a.SittingOut) != len(c.out) {
t.Errorf("%s: %+v", c.name, a)
}
for i := range c.out {
if a.SittingOut[i] != c.out[i] {
t.Errorf("%s: sitting out %+v, want %+v", c.name, a.SittingOut, c.out)
}
}
if (len(c.wait) == 0) != (a.Wait == "") {
t.Errorf("%s: wait %q", c.name, a.Wait)
}
for _, w := range c.wait {
if !strings.Contains(a.Wait, w) {
t.Errorf("%s: %q does not name %q", c.name, a.Wait, w)
}
}
if tc, none := AgreedToolchain(c.in); tc != a.Toolchain || none != a.Wait {
t.Errorf("%s: AgreedToolchain %+v %q", c.name, tc, none)
}
}
}
func TestToolchainKeyParsesBack(t *testing.T) {
key, err := ToolchainKey("ace", "go")
if err != nil {
t.Fatal(err)
}
if node, lang, err := ParseToolchainKey(key); err != nil || node != "ace" || lang != "go" {
t.Errorf("%q parsed to %q %q %v", key, node, lang, err)
}
for _, bad := range []string{"ace", "ace.rust", ".go", "a.b.go"} {
if _, _, err := ParseToolchainKey(bad); err == nil {
t.Errorf("%q parsed", bad)
}
}
}