Publish a merged candidate's image once; a retaken key builds only what is missing (review r1)
This commit is contained in:
@@ -595,38 +595,44 @@ func TestBuilderBuildsACandidatesFingerprintFromTheHeadMergedOntoTheTrunk(t *tes
|
||||
|
||||
// TestAnImageIsBuiltOnOneNodeAndOnlyATrunkKeyPublishes: modules.imaged (one image artifact) is built on n1, where
|
||||
// mesh-build-image runs: a trunk record's key is done with the digest and the reference, its build call carrying publish; a
|
||||
// candidate's key for the same module is done with no reference, its build call carrying no publish (ADR 0487 clause 12).
|
||||
// candidate's key for the same module is built first with no publish and no reference; when the pull request is merged and the
|
||||
// trunk's record names the candidate's fingerprint, the key is built again with publish and ends with a reference
|
||||
// (ADR 0487 clauses 5 and 12).
|
||||
func TestAnImageIsBuiltOnOneNodeAndOnlyATrunkKeyPublishes(t *testing.T) { // 1705
|
||||
b := startBed(t)
|
||||
other := "src2:" + strings.Repeat("e", 64)
|
||||
digest := b.moduleCommit(t, "imaged", "catalogue-a67f0196-imaged.module.json", "modules/imaged", nil, commit)
|
||||
// The trunk carries `other`; its key is built and published.
|
||||
trunk := func(fp2 string) {
|
||||
data, err := delivery.EncodeModule(delivery.Module{Repository: "novox/mesh-catalog", Commit: commit, FP: "src1:" + strings.Repeat("f", 64), FP2: fp2,
|
||||
Manifest: digest, Path: "modules/imaged"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := b.modules.Put(b.ctx, "imaged", data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
trunk(other)
|
||||
b.start(t, "n1", nil)
|
||||
v := b.await(t, "imaged", isState(delivery.BuildDone))
|
||||
okey, _ := delivery.BuilderBuildKey("imaged", other)
|
||||
awaitKey := func(key string, pred func(delivery.BuilderBuild) bool) delivery.BuilderBuild {
|
||||
var last delivery.BuilderBuild
|
||||
for deadline := time.Now().Add(20 * time.Second); time.Now().Before(deadline); time.Sleep(50 * time.Millisecond) {
|
||||
if e, err := b.builds.Get(b.ctx, key); err == nil {
|
||||
if last, err = delivery.DecodeBuilderBuild(e.Value()); err == nil && pred(last) {
|
||||
return last
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Fatalf("builds.%s = %+v within 20 s", key, last)
|
||||
return last
|
||||
}
|
||||
v := awaitKey(okey, isState(delivery.BuildDone))
|
||||
if len(v.Artifacts) != 1 || v.Artifacts[0].Digest != digestOf("server") || !strings.HasSuffix(v.Artifacts[0].Reference, "@"+digestOf("server")) {
|
||||
t.Fatalf("trunk build = %+v, want the digest and the reference", v)
|
||||
}
|
||||
if got := b.fake.count("mesh-build-image.build_image_build"); got != 1 {
|
||||
t.Errorf("build_image_build called %d times, want once on one node", got)
|
||||
}
|
||||
b.fake.mu.Lock()
|
||||
if len(b.fake.builds) != 1 || b.fake.builds[0]["publish"] != true {
|
||||
t.Errorf("builds = %v, want one carrying publish", b.fake.builds)
|
||||
}
|
||||
b.fake.builds = nil
|
||||
b.fake.mu.Unlock()
|
||||
|
||||
// A candidate: the trunk's record moves to another fingerprint, the candidate carries fp.
|
||||
other := "src2:" + strings.Repeat("e", 64)
|
||||
data, err := delivery.EncodeModule(delivery.Module{Repository: "novox/mesh-catalog", Commit: commit, FP: "src1:" + strings.Repeat("f", 64), FP2: other,
|
||||
Manifest: digest, Path: "modules/imaged"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b.builds.Delete(b.ctx, mustKey(t, "imaged")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := b.modules.Put(b.ctx, "imaged", data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The candidate carries fp: built, not published.
|
||||
const head = "1111111111111111111111111111111111111111"
|
||||
pulls := []delivery.CandidatePull{{Head: delivery.Head{Repository: "novox/mesh-catalog", Number: 7, Head: head}, Modules: []string{"imaged"},
|
||||
Fps: map[string]delivery.CandidateModule{"imaged": {FP2: fp, Manifest: digest}}}}
|
||||
@@ -639,26 +645,32 @@ func TestAnImageIsBuiltOnOneNodeAndOnlyATrunkKeyPublishes(t *testing.T) { // 170
|
||||
if _, err := b.candidates.Put(b.ctx, ckey, cand); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
v = b.await(t, "imaged", isState(delivery.BuildDone))
|
||||
if len(v.Artifacts) != 1 || v.Artifacts[0].Reference != "" {
|
||||
t.Fatalf("candidate build = %+v, want done with no reference", v)
|
||||
}
|
||||
b.fake.mu.Lock()
|
||||
if len(b.fake.builds) != 2 || b.fake.builds[0]["publish"] != true || b.fake.builds[1]["publish"] != nil {
|
||||
t.Errorf("builds = %v, want the trunk's with publish, then the candidate's with none", b.fake.builds)
|
||||
}
|
||||
b.fake.mu.Unlock()
|
||||
// The pull request is merged: the trunk's record names fp, and its key ends published, built once more with publish.
|
||||
trunk(fp)
|
||||
v = b.await(t, "imaged", func(v delivery.BuilderBuild) bool {
|
||||
return v.State == delivery.BuildDone && len(v.Artifacts) == 1 && v.By != ""
|
||||
return v.State == delivery.BuildDone && len(v.Artifacts) == 1 && v.Artifacts[0].Reference != ""
|
||||
})
|
||||
// The trunk's new fingerprint is built too, and published; the candidate's is built and not.
|
||||
for deadline := time.Now().Add(10 * time.Second); time.Now().Before(deadline) && b.fake.count("mesh-build-image.build_image_build") < 3; time.Sleep(50 * time.Millisecond) {
|
||||
if v.Artifacts[0].Digest != digestOf("server") {
|
||||
t.Errorf("merged build = %+v", v)
|
||||
}
|
||||
b.fake.mu.Lock()
|
||||
defer b.fake.mu.Unlock()
|
||||
if v.Artifacts[0].Reference != "" {
|
||||
t.Errorf("candidate build = %+v, want no reference", v)
|
||||
}
|
||||
published, plain := 0, 0
|
||||
published := 0
|
||||
for _, a := range b.fake.builds {
|
||||
if _, has := a["publish"]; has {
|
||||
if a["publish"] == true {
|
||||
published++
|
||||
} else {
|
||||
plain++
|
||||
}
|
||||
}
|
||||
if published != 1 || plain != 1 {
|
||||
t.Errorf("builds = %v, want one trunk call with publish and one candidate call with none", b.fake.builds)
|
||||
if len(b.fake.builds) != 3 || published != 2 {
|
||||
t.Errorf("builds = %v, want three, two of them with publish (the trunk's two fingerprints)", b.fake.builds)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user