Skip to content
quarry Artifact [1e3669bcc5]
Login

Artifact [1e3669bcc5]

Artifact 1e3669bcc5726912081db1247f2d13809419d2d62e4a56d89b760a45b6e234ec:


package api

import (
	"path/filepath"
	"testing"

	"craftdesign.group/quarry/internal/artifact"
	"craftdesign.group/quarry/internal/index"
	"craftdesign.group/quarry/internal/oltp"
)

const (
	redTrunkTip   = "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1"
	redFeatureTip = "f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1"
)

func redTrunkIndex(t *testing.T) *index.Index {
	t.Helper()
	ix, err := index.Open(filepath.Join(t.TempDir(), "index.db"))
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() { ix.Close() })
	if err := ix.FoldNow([]index.Parsed{
		{Hash: redTrunkTip, Art: &artifact.Artifact{Type: artifact.Manifest, Date: "2026-01-01T08:00:00", User: "ada", Comment: "trunk",
			Tags: []artifact.Tag{{Name: "*branch", Target: "*", Value: "trunk"}}}},
		{Hash: redFeatureTip, Art: &artifact.Artifact{Type: artifact.Manifest, Date: "2026-01-01T09:00:00", User: "ada", Comment: "work",
			Tags: []artifact.Tag{{Name: "*branch", Target: "*", Value: "feature"}}}},
	}); err != nil {
		t.Fatal(err)
	}
	return ix
}

// A failed run on the default branch tells the repository's owners —
// the deed holder and the default branch's owners, once each — on the
// landing family, keyed per check-in and pipeline so a re-run of the
// same pipeline on the same check-in collapses onto the first trigger.
// A failure on any other branch tells nobody.
func TestRedTrunkNotifiesTheOwnersOncePerCheckinAndPipeline(t *testing.T) {
	fn := &fakeNotify{}
	d := Deps{
		Notify: fn,
		Repos:  NewRepos(map[string]*Repo{"alpha": {Index: redTrunkIndex(t)}}),
		Owners: oneOwner("dan"),
		Protect: stubProtect{rules: []oltp.Protection{
			{Branch: "trunk", Owners: []string{"alice", "dan"}},
		}},
	}
	d.NotifyRedTrunk("alpha", redTrunkTip, "ci/race.json", "run1")
	evs := waitNotify(fn, 2)
	got := map[string]NotifyEvent{}
	for _, e := range evs {
		if e.Workflow != "quarry-landing" {
			t.Fatalf("FAIL: workflow = %q, want quarry-landing", e.Workflow)
		}
		if _, dup := got[e.To]; dup {
			t.Fatalf("FAIL: %s was told twice", e.To)
		}
		got[e.To] = e
	}
	if len(got) != 2 || got["alice"].To == "" || got["dan"].To == "" {
		t.Fatalf("FAIL: recipients = %v, want alice and dan", got)
	}
	e := got["dan"]
	if want := "ci:red:alpha:" + redTrunkTip + ":ci/race.json:dan"; e.TxnID != want {
		t.Errorf("FAIL: TxnID = %q, want %q", e.TxnID, want)
	}
	if e.Payload["repo"] != "alpha" || e.Payload["link"] != "/r/alpha/ci/run/run1" {
		t.Errorf("FAIL: payload repo/link = %v/%v", e.Payload["repo"], e.Payload["link"])
	}

	fn2 := &fakeNotify{}
	d.Notify = fn2
	d.NotifyRedTrunk("alpha", redFeatureTip, "ci/race.json", "run2")
	if evs := waitNotify(fn2, 0); len(evs) != 0 {
		t.Fatalf("FAIL: a failure off the default branch told %+v", evs)
	}
	d.NotifyRedTrunk("nope", redTrunkTip, "ci/race.json", "run3")
	if evs := waitNotify(fn2, 0); len(evs) != 0 {
		t.Fatalf("FAIL: an unknown repository told %+v", evs)
	}
	t.Log("ok: red trunk tells the owners once each; other branches tell nobody")
}