package build import ( "context" "git.novox.be/novox/mesh-sdk/go/delivery/buildrun" "testing" "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/delivery" ) func haveValue(t *testing.T, phase delivery.Phase, health delivery.Health) []byte { t.Helper() b, err := delivery.EncodeHave(delivery.Have{Phase: phase, Health: health}) if err != nil { t.Fatal(err) } return b } // 1. A module of an archive only: the real indexer gives an archive no language (inputs.go languagesOf), so its // fingerprint names no toolchain, and the builder builds it on the build module's nodes with no toolchain agreed. func TestAnArchiveOnlyModuleIsBuiltAlthoughItsFingerprintNamesNoToolchain(t *testing.T) { // review round 4, 1 r := newRig(t, archiveA) v := func() delivery.BuilderBuild { r.b.Module(context.Background(), "m", moduleValueWith(t, "modules/m", nil)) r.b.Wait() if _, ok := r.st.vals[r.key]; !ok { t.Fatal("no build key was written for the archive-only module") } return valueOf(t, r.st, r.key) }() if v.State != delivery.BuildDone || len(v.Artifacts) != 1 || v.Artifacts[0].Kind != "archive" || len(v.Toolchains) != 0 { t.Fatalf("build = %+v, want done with the archive and no toolchain named", v) } if n := len(r.bm.callsOf("build_go_build")); n != 1 { t.Errorf("%d go builds, want one, on one node (ADR 0478 clause 4)", n) } } func TestABundleAndAnArchiveOfOneBuildModuleStillNeedTheAgreedToolchain(t *testing.T) { // review round 4, 1 p, err := PlanOf(catalogue.Manifest{Module: "m", Build: &catalogue.Build{Artifacts: []catalogue.Artifact{goBundle, archiveA}}}) if err != nil || !p.NeedsToolchain(buildrun.GoBuildModule) { t.Errorf("a plan with a Go bundle: %v, %v", p.NeedsToolchain(buildrun.GoBuildModule), err) } p, _ = PlanOf(catalogue.Manifest{Module: "m", Build: &catalogue.Build{Artifacts: []catalogue.Artifact{archiveA}}}) if p.NeedsToolchain(buildrun.GoBuildModule) { t.Error("a plan of an archive needs a toolchain") } } func TestClaimLeavesAKeyFailedForDifferingDigestsAlone(t *testing.T) { // review round 4, 2 st := newMem() seed(t, st, delivery.BuilderBuild{State: delivery.BuildFailed, Error: buildrun.DigestsDifferPrefix + " the nodes built tool to different digests: ace x; novox y"}) writes := st.writes got, err := (Claimer{Store: st, By: "novox.a"}).Claim(context.Background(), "m", fp1, "", ClaimOptions{TakeOver: true}) if err != nil || got != nil || st.writes != writes { t.Errorf("claim = %v, %v, %d writes (was %d), want none and no write", got, err, st.writes, writes) } } // 6. A key found building is taken over, whoever holds it. func TestABuildLeftBuildingByAnyBuilderIsTakenOverAtStart(t *testing.T) { // review round 4, 6; 1607/AC3, ADR 0478 clauses 5, 6 st := newMem() seed(t, st, delivery.BuilderBuild{State: delivery.BuildBuilding, By: "novox.a"}) if got, err := (Claimer{Store: st, By: "novox.a"}).Claim(context.Background(), "m", fp1, "", ClaimOptions{}); err != nil || got == nil { t.Errorf("own building key: claim = %v, %v, want it taken again", got, err) } if got, err := (Claimer{Store: st, By: "ace.b"}).Claim(context.Background(), "m", fp1, "", ClaimOptions{TakeOver: true}); err != nil || got == nil || got.Build.By != "novox.a" { t.Errorf("another node's building key at start: claim = %v, %v, want it taken over", got, err) } if got, _ := (Claimer{Store: st, By: "ace.b"}).Claim(context.Background(), "m", fp1, "", ClaimOptions{}); got != nil { t.Errorf("another builder's building key after the start was taken: a running builder's key is its own") } } func TestABuilderFindingAKeyBuildingByAnotherNodeBuildsItOnStart(t *testing.T) { // review round 4, 6 r := newRig(t, goBundle) seed(t, r.st, delivery.BuilderBuild{State: delivery.BuildBuilding, By: "ace.builder", Manifest: manifestD}) v := r.consider(t, "modules/m") if v.State != delivery.BuildDone || v.By != "novox.builder" { t.Errorf("build = %+v, want it taken over and done by novox.builder", v) } }