package ci
import (
"slices"
"testing"
)
// askedRepo records which versions its pipeline files were read at.
type askedRepo struct {
*fakeRepo
asked []string
}
func (a *askedRepo) Files(v string) ([]string, error) {
a.asked = append(a.asked, v)
return a.fakeRepo.Files(v)
}
func (a *askedRepo) Read(p, v string) ([]byte, error) {
a.asked = append(a.asked, v)
return a.fakeRepo.Read(p, v)
}
// A PAIR RUN STARTS EVERY PIPELINE ONCE, FROM THE BRANCH TIP'S
// DEFINITIONS, AND STOPS ONLY OLDER PAIR RUNS.
//
// A pair is not a check-in, so its definitions are the branch tip's.
// The landing-only pipeline runs too: a pair exists only for a proposed
// branch. Asking again starts nothing. A pair against a newer target
// supersedes the older pair's runs, and never the branch tip's own.
func TestAPairRunStartsOnceFromTheBranchTip(t *testing.T) {
srv, started, cancelled := cancellingEngine(t)
e := New(srv.URL)
st := &fakeStore{mark: map[string]string{"alpha": "old"}}
repo := &askedRepo{fakeRepo: landingRepo()}
repo.landings["feat"] = true
if err := RunMissingAt(e, st, "alpha", repo, "http://x/r/alpha", Checkin{Hash: "b1", Branch: "feat"}); err != nil {
t.Fatal(err)
}
started()
repo.asked = nil
if err := RunPairAt(e, st, "alpha", repo, "http://x/r/alpha", "feat", "b1", "t1"); err != nil {
t.Fatal(err)
}
if got := started(); !slices.Equal(got, []string{"pair:b1:t1 ci/quarry.json", "pair:b1:t1 ci/race.json"}) {
t.Errorf("FAIL: the pair started %v; want both pipelines at pair:b1:t1", got)
}
for _, v := range repo.asked {
if v != "b1" {
t.Errorf("FAIL: a pipeline file was read at %q, want the branch tip b1", v)
}
}
if got := cancelled(); len(got) != 0 {
t.Errorf("FAIL: starting a pair cancelled %v; the branch tip's runs are still its verdict", got)
}
if err := RunPairAt(e, st, "alpha", repo, "http://x/r/alpha", "feat", "b1", "t1"); err != nil {
t.Fatal(err)
}
if got := started(); len(got) != 0 {
t.Errorf("FAIL: asking for the same pair again started %v", got)
}
if err := RunPairAt(e, st, "alpha", repo, "http://x/r/alpha", "feat", "b1", "t2"); err != nil {
t.Fatal(err)
}
started()
if got := cancelled(); !slices.Equal(got, []string{"pair:b1:t1 ci/quarry.json", "pair:b1:t1 ci/race.json"}) {
t.Errorf("FAIL: a pair against a newer target cancelled %v; want the older pair's runs only", got)
}
t.Log("ok: a pair runs once, from the branch tip's definitions, and supersedes only older pairs")
}