vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
|
70c9ad4e
Keenan Nemetz
2h ago
|
1 | package landing |
| 2 | ||
| 3 | // The gate reads one job's newest run for a commit and turns it into a gap or | |
| 4 | // nothing. Before #246 every non-success was a refusal, so a runner that could not | |
| 5 | // start the job red-flagged a commit whose tests passed. These cases pin which | |
| 6 | // statuses are the author's problem and which are the machine's. | |
| 7 | ||
| 8 | import ( | |
| 9 | "strings" | |
| 10 | "testing" | |
| 11 | ||
| 12 | "rodent.software/vole/ci" | |
| 13 | "rodent.software/vole/ci/runs" | |
| 14 | ) | |
| 15 | ||
| 16 | func TestCheckGapReadsEveryRunStatus(t *testing.T) { | |
| 17 | t.Parallel() | |
| 18 | wf := &ci.Workflow{Path: ".vole/workflows/verify.yaml", Branches: []string{"*"}} | |
| 19 | job := ci.Job{ID: "verify"} | |
| 20 | const sha = "0123456789abcdef0123456789abcdef01234567" | |
| 21 | ||
| 22 | cases := []struct { | |
| 23 | name string | |
| 24 | run *runs.Run | |
| 25 | gap bool | |
| 26 | wait bool | |
| 27 | wantHas []string | |
| 28 | }{ | |
| 29 | { | |
| 30 | name: "no run is a wait", gap: true, wait: true, | |
| 31 | wantHas: []string{"no run", "push the branch"}, | |
| 32 | }, | |
| 33 | { | |
| 34 | name: "a failed job is a refusal", wait: false, gap: true, | |
| 35 | run: &runs.Run{Status: runs.StatusFailed, ExitCode: 1}, | |
| 36 | wantHas: []string{"failed", "exit 1"}, | |
| 37 | }, | |
| 38 | { | |
| 39 | name: "a canceled job is a refusal", wait: false, gap: true, | |
| 40 | run: &runs.Run{Status: runs.StatusCanceled}, | |
| 41 | wantHas: []string{"canceled"}, | |
| 42 | }, | |
| 43 | { | |
| 44 | // The case this rule exists for: the runner could not build the image, so | |
| 45 | // nothing ran and the commit is not what stopped it. | |
| 46 | name: "a job that never started is a wait", wait: true, gap: true, | |
| 47 | run: &runs.Run{ | |
| 48 | ID: "01M6YY97B5V966TVRED4QA2643", Status: runs.StatusError, | |
| 49 | Failure: runs.FailureSetup, | |
| 50 | FailureMessage: `building image-file "verify" exited 125`, | |
| 51 | }, | |
| 52 | wantHas: []string{ | |
| 53 | "could not run", | |
| 54 | `building image-file "verify" exited 125`, | |
| 55 | "vole run rerun 01M6YY97B5V966TVRED4QA2643", | |
| 56 | }, | |
| 57 | }, | |
| 58 | { | |
| 59 | name: "a queued job is a wait", gap: true, wait: true, | |
| 60 | run: &runs.Run{Status: runs.StatusQueued}, | |
| 61 | wantHas: []string{"queued", "wait"}, | |
| 62 | }, | |
| 63 | { | |
| 64 | name: "a passing job is no gap", | |
| 65 | run: &runs.Run{Status: runs.StatusSuccess}, | |
| 66 | }, | |
| 67 | } | |
| 68 | for _, c := range cases { | |
| 69 | t.Run(c.name, func(t *testing.T) { | |
| 70 | t.Parallel() | |
| 71 | problem, wait, gap := checkGap(wf, job, sha, c.run) | |
| 72 | if gap != c.gap || wait != c.wait { | |
| 73 | t.Fatalf("checkGap = gap %v wait %v, want gap %v wait %v (%q)", | |
| 74 | gap, wait, c.gap, c.wait, problem) | |
| 75 | } | |
| 76 | for _, want := range c.wantHas { | |
| 77 | if !strings.Contains(problem, want) { | |
| 78 | t.Fatalf("the gap does not say %q: %q", want, problem) | |
| 79 | } | |
| 80 | } | |
| 81 | }) | |
| 82 | } | |
| 83 | } | |
| 84 | ||
| 85 | // A run with no recorded reason still says something a reader can act on, rather than | |
| 86 | // trailing off after the status. | |
| 87 | func TestCheckGapNamesAMissingReason(t *testing.T) { | |
| 88 | t.Parallel() | |
| 89 | wf := &ci.Workflow{Path: "verify.yaml"} | |
| 90 | run := &runs.Run{ID: "run1", Status: runs.StatusError, Failure: runs.FailureSetup} | |
| 91 | problem, wait, gap := checkGap(wf, ci.Job{ID: "verify"}, "0123456", run) | |
| 92 | if !gap || !wait { | |
| 93 | t.Fatalf("checkGap = gap %v wait %v", gap, wait) | |
| 94 | } | |
| 95 | if !strings.Contains(problem, "the runner recorded no reason") { | |
| 96 | t.Fatalf("the gap does not account for a missing reason: %q", problem) | |
| 97 | } | |
| 98 | } |