Skip to content
quarry Artifact [cb98cc3ca8]
Login

Artifact [cb98cc3ca8]

Artifact cb98cc3ca84cf6792acd918abb219edfb0088052cba2b0a006a150fb70dc86aa:


package ci

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
	"sync"
	"testing"
)

// A RUN'S START IS RECORDED: ITS EVENT, ITS STARTER, EACH JOB'S
// DECLARATION (RFC 0021 §runs). The engine never sees permissions:.
func TestARunRecordsItsEventStarterAndJobs(t *testing.T) {
	var mu sync.Mutex
	var specs []string
	n := 0
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		mu.Lock()
		defer mu.Unlock()
		switch {
		case r.URL.Path == "/v1/ci/compile":
			var body struct{ Name, Spec string }
			json.NewDecoder(r.Body).Decode(&body)
			specs = append(specs, body.Spec)
			fmt.Fprintf(w, `{"workflow":{"name":%q},"registered":true,"on":{"tag":{},"workflow_dispatch":{}}}`, body.Name)
		case r.URL.Path == "/runs" && r.Method == http.MethodPost:
			n++
			w.WriteHeader(http.StatusCreated)
			fmt.Fprintf(w, `{"run_id":"r%d"}`, n)
		case r.URL.Path == "/runs":
			fmt.Fprint(w, `[]`)
		}
	}))
	defer srv.Close()
	e := New(srv.URL)
	release := []byte("on:\n  tag: {}\n  workflow_dispatch: {}\npermissions:\n  uv: write\njobs:\n  publish:\n    environment: release\n    steps:\n      - run: ./publish\n")
	st := &fakeStore{mark: map[string]string{"alpha": "t1"}, pushedBy: map[string]string{"s0": "tagger"}}
	repo := &fakeRepo{
		files: []string{"ci/release.yml"},
		blobs: map[string][]byte{"ci/release.yml": release},
		news:  []Checkin{{Hash: "t1", Branch: "trunk", User: "author"}},
	}
	key := TagKey{Src: "s0", Target: "t1", Name: "version-0.1.0"}
	repo.tags = nil
	if err := TriggerTags(e, st, "alpha", repo, "u"); err != nil { // first sight
		t.Fatal(err)
	}
	repo.tags = []Tagged{{TagKey: key, At: Checkin{Hash: "t1", Branch: "trunk", User: "author"}}}
	if err := TriggerTags(e, st, "alpha", repo, "u"); err != nil {
		t.Fatal(err)
	}
	want := RunStart{Event: "tag", Starter: "tagger", Jobs: map[string]JobGrant{"publish": {Environment: "release", Letters: "y"}}}
	if got := st.starts["r1"]; got.Event != want.Event || got.Starter != want.Starter || got.Jobs["publish"] != want.Jobs["publish"] || len(got.Jobs) != 1 {
		t.Errorf("FAIL: the tag run recorded %+v; want %+v", got, want)
	}
	if err := RunAt(e, st, "alpha", repo, "u", "t1", "clicker"); err != nil {
		t.Fatal(err)
	}
	if got := st.starts["r2"]; got.Event != "workflow_dispatch" || got.Starter != "clicker" {
		t.Errorf("FAIL: the dispatched run recorded %+v; want workflow_dispatch by clicker", got)
	}
	for _, s := range specs {
		if strings.Contains(s, "permissions") || strings.Contains(s, "uv: write") {
			t.Errorf("FAIL: the engine was handed permissions:\n%s", s)
		}
	}
	t.Log("ok: tag and dispatch runs record their event, starter and job grants; the engine never sees permissions:")
}