e2e/runner_scope_test.go

v1.7.0
gitbay/e2e/runner_scope_test.go history · blame · raw

60 lines · 2425 bytes

 1package e2e
 2
 3import (
 4	"os"
 5	"path/filepath"
 6	"strings"
 7	"testing"
 8)
 9
10// A runner names the repositories it will take builds for. Without that, any
11// runner claims whatever is next in the global queue, so a runner on a machine
12// that should only build one project ends up executing every repository's
13// steps — including those of a repository it has nothing to do with.
14func TestRunnerNextScopedToRepos(t *testing.T) {
15	inst := startInstance(t)
16	aliceKey := inst.newKey(t, "alice")
17	inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
18	runnerKey := inst.newKey(t, "ci")
19	inst.admin(t, "admin", "user", "create", "ci", "--key", runnerKey+".pub", "--admin")
20
21	// Two repositories, each with a build queued. "other" is pushed first, so
22	// an unscoped claim would take it.
23	for _, name := range []string{"other", "site"} {
24		if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/"+name); code != 0 {
25			t.Fatalf("repo create %s: %s", name, errOut)
26		}
27		work := t.TempDir()
28		env := inst.gitEnv(aliceKey)
29		mustGit(t, work, env, "clone", inst.sshURL("alice/"+name), "w")
30		dir := filepath.Join(work, "w")
31		os.MkdirAll(filepath.Join(dir, ".gitbay"), 0o755)
32		os.WriteFile(filepath.Join(dir, ".gitbay", "ci.yml"), []byte(
33			"jobs:\n  "+name+":\n    steps:\n      - echo hi\n"), 0o644)
34		mustGit(t, dir, env, "checkout", "-q", "-b", "main")
35		mustGit(t, dir, env, "add", ".")
36		mustGit(t, dir, env, "commit", "-q", "-m", "base")
37		mustGit(t, dir, env, "push", "-q", "origin", "main")
38	}
39
40	// Scoped to alice/site: takes the site build, not the older other build.
41	out, errOut, code := inst.ssh(t, runnerKey, "", "runner", "next", "alice/site", "--json")
42	if code != 0 {
43		t.Fatalf("runner next: %s", errOut)
44	}
45	if !strings.Contains(out, `"repo":"alice/site"`) {
46		t.Fatalf("scoped claim took the wrong repo:\n%s", out)
47	}
48
49	// That scope is now empty, though alice/other is still pending.
50	out, _, code = inst.ssh(t, runnerKey, "", "runner", "next", "alice/site", "--json")
51	if code != 0 || strings.Contains(out, `"repo":`) {
52		t.Fatalf("scoped claim took a build outside its scope:\n%s", out)
53	}
54
55	// An unscoped runner still takes it, so the default is unchanged.
56	out, _, code = inst.ssh(t, runnerKey, "", "runner", "next", "--json")
57	if code != 0 || !strings.Contains(out, `"repo":"alice/other"`) {
58		t.Fatalf("unscoped claim did not take the remaining build:\n%s", out)
59	}
60}