Skip to content
quarry Artifact [84dda4dddc]
Login

Artifact [84dda4dddc]

Artifact 84dda4dddcdde9dc3fa37de8924bfbb54ae35548c1cdd9b9d38c13ef936d53be:


package ci

import (
	"slices"
	"testing"
)

// A PUSH OF SEVERAL CHECK-INS ON ONE BRANCH LAUNCHES ITS TIP, IN EITHER
// ARRIVAL ORDER, AND THE TIP'S RUN IS NEVER CANCELLED BY ITS PARENT.
//
// The trigger takes a round's check-ins by arrival (#314), and one push
// can deliver the tip before its parent. The parent launching second
// used to supersede every running build on the branch, the tip's
// included, leaving the branch's verdict on an old check-in and none on
// its tip (e0a264f69bc8, cancelled by 16e797279bf8's launch).
func TestAPushOfSeveralCheckinsLaunchesTheTipAndKeepsIt(t *testing.T) {
	for _, order := range [][]string{{"b4", "b5"}, {"b5", "b4"}} {
		srv, started, cancelled := cancellingEngine(t)
		e := New(srv.URL)
		st := &fakeStore{mark: map[string]string{"alpha": "old"}}
		repo := landingRepo()
		repo.parents = map[string][]string{"b5": {"b4"}}
		for _, h := range order {
			repo.news = append(repo.news, Checkin{Hash: h, Branch: "feat"})
		}
		if err := Trigger(e, st, "alpha", repo, "http://x/r/alpha"); err != nil {
			t.Fatal(err)
		}
		if got := started(); !slices.Equal(got, []string{"b5 ci/quarry.json"}) {
			t.Errorf("FAIL: arrival %v started %v; want the tip's run only", order, got)
		}
		if got := cancelled(); len(got) != 0 {
			t.Errorf("FAIL: arrival %v cancelled %v; want nothing", order, got)
		}
	}
	t.Log("ok: the tip runs and stays running whichever check-in arrived first")
}

// AN OLDER CHECK-IN ARRIVING AFTER THE TIP DOES NOT CANCEL THE TIP'S
// RUN; A DESCENDANT STILL SUPERSEDES ITS ANCESTOR'S.
func TestSupersedeStopsOnlyAncestors(t *testing.T) {
	srv, started, cancelled := cancellingEngine(t)
	e := New(srv.URL)
	st := &fakeStore{mark: map[string]string{"alpha": "old"}}
	repo := landingRepo()
	repo.parents = map[string][]string{"b5": {"b4"}, "b6": {"b5"}}
	round := func(news ...Checkin) {
		repo.news = news
		if err := Trigger(e, st, "alpha", repo, "http://x/r/alpha"); err != nil {
			t.Fatal(err)
		}
	}
	round(Checkin{Hash: "b5", Branch: "feat"})
	round(Checkin{Hash: "b4", Branch: "feat"}) // the parent, arriving late
	if got := started(); !slices.Equal(got, []string{"b4 ci/quarry.json", "b5 ci/quarry.json"}) {
		t.Fatalf("FAIL: started %v", got)
	}
	if got := cancelled(); len(got) != 0 {
		t.Fatalf("FAIL: the late parent cancelled %v; want the tip's run left alone", got)
	}
	round(Checkin{Hash: "b6", Branch: "feat"})
	started()
	if got := cancelled(); !slices.Equal(got, []string{"b4 ci/quarry.json", "b5 ci/quarry.json"}) {
		t.Fatalf("FAIL: the new tip cancelled %v; want both its ancestors' runs", got)
	}
	t.Log("ok: supersede reaches back, never forward")
}