Skip to content
quarry Artifact [d6cd15348e]
Login

Artifact [d6cd15348e]

Artifact d6cd15348e9de9ef1a14964ef0985e1e9da20f7321751cf79f22c473ef1c8d18:


package api

import (
	"context"
	"encoding/json"
	"testing"

	"craftdesign.group/quarry/internal/ops"
)

// AN INHERITED VERDICT IS THE CHECK-IN'S OWN (RFC 0009 §inheritance).
//
// checkin.get lists it among the check-in's checks with its state and
// the pair run it came from, and the required-checks rule a deploy
// gates on reads it as it reads a run: an inherited pass is met, an
// inherited fail is unmet.
func TestAnInheritedVerdictIsTheCheckinsOwn(t *testing.T) {
	ix := redTrunkIndex(t)
	runs := runsStub{runs: []CIRun{
		{RunID: "p-quarry", InheritedFrom: "p-quarry", Checkin: redTrunkTip, Workflow: "quarry.quarry.1", Pipeline: "ci/quarry.json", Status: "completed"},
		{RunID: "p-race", InheritedFrom: "p-race", Checkin: redTrunkTip, Workflow: "quarry.race.1", Pipeline: "ci/race.json", Status: "failed"},
	}}
	r := ops.NewRegistry()
	d := Deps{Version: "v", Repos: NewRepos(map[string]*Repo{"test": {Index: ix}}), CI: runs, Checks: checksStub{required: []string{"quarry", "race"}}}
	if err := RegisterAll(r, d); err != nil {
		t.Fatal(err)
	}
	got, err := r.Invoke(context.Background(), "checkin.get", checkinGetIn{Repo: "test", Hash: redTrunkTip})
	if err != nil {
		t.Fatal(err)
	}
	b, _ := json.Marshal(got)
	var m struct {
		Checks []map[string]any `json:"checks"`
		Unmet  []string         `json:"unmet"`
	}
	if err := json.Unmarshal(b, &m); err != nil {
		t.Fatal(err)
	}
	from := map[string]any{}
	for _, c := range m.Checks {
		from[c["pipeline"].(string)] = c["inheritedFrom"]
	}
	if from["ci/quarry.json"] != "p-quarry" || from["ci/race.json"] != "p-race" {
		t.Fatalf("FAIL: checks name their sources %v; want p-quarry and p-race", from)
	}
	if len(m.Unmet) != 1 || m.Unmet[0] != "race" {
		t.Fatalf("FAIL: unmet = %v; want the inherited fail, race, and only it", m.Unmet)
	}
	t.Log("ok: inherited verdicts are listed with their source and judged as the check-in's own")
}

// pushedStub files runs under a check-in or under a pair, apart, and
// names the newest pair tested for a tip.
type pushedStub struct {
	runsStub
	tip, pair  map[string][]CIRun
	latestPair map[string]string
}

func (p pushedStub) CIRunsFor(_, c string) ([]CIRun, error)      { return p.tip[c], nil }
func (p pushedStub) CIRunsForPair(_, s string) ([]CIRun, error)  { return p.pair[s], nil }
func (p pushedStub) LatestPairFor(_, tip string) (string, error) { return p.latestPair[tip], nil }

// A BRANCH CHECK-IN'S CHECKS ARE ITS MERGE'S (RFC 0009 §once).
//
// A push to a branch is tested as its merge with the target, so the
// check-in's own runs are only what stayed on its tip; checkin.get
// lists the newest merge's runs beside them, and judges the branch's
// required checks on either.
func TestABranchCheckinShowsItsMergesChecks(t *testing.T) {
	ix := redTrunkIndex(t)
	pair := "pair:" + redTrunkTip + ":t"
	stub := pushedStub{
		tip: map[string][]CIRun{redTrunkTip: {{RunID: "d", Checkin: redTrunkTip, Workflow: "w.deploy", Pipeline: "ci/deploy.yml", Status: "completed"}}},
		pair: map[string][]CIRun{pair: {
			{RunID: "q", Checkin: pair, Pair: pair, Workflow: "w.quarry", Pipeline: "ci/quarry.json", Status: "completed"},
			{RunID: "r", Checkin: pair, Pair: pair, Workflow: "w.race", Pipeline: "ci/race.json", Status: "failed"},
		}},
		latestPair: map[string]string{redTrunkTip: pair},
	}
	r := ops.NewRegistry()
	d := Deps{Version: "v", Repos: NewRepos(map[string]*Repo{"test": {Index: ix}}), CI: stub,
		Checks: checksStub{required: []string{"deploy", "quarry", "race"}}}
	if err := RegisterAll(r, d); err != nil {
		t.Fatal(err)
	}
	got, err := r.Invoke(context.Background(), "checkin.get", checkinGetIn{Repo: "test", Hash: redTrunkTip})
	if err != nil {
		t.Fatal(err)
	}
	out := got.(checkinGetOut)
	var ids []string
	for _, c := range out.Checks {
		ids = append(ids, c.RunID)
	}
	if len(ids) != 3 {
		t.Fatalf("FAIL: checks %v; want the tip's deploy and the merge's two runs", ids)
	}
	if len(out.Unmet) != 1 || out.Unmet[0] != "race" {
		t.Fatalf("FAIL: unmet = %v; want race, failed on the merge", out.Unmet)
	}
	t.Log("ok: the merge's runs are the branch check-in's checks")
}