Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

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.

Blame · forge/landing/candidate_test.go

Line attribution on main · 117 line(s)

e5478085
Keenan Nemetz
11d ago
1 package landing
2
3 // The combined result has one identity: the ref name carries the request and the
4 // two tips, so asking twice reuses the commit and a moved base makes the old one
5 // stale without any bookkeeping.
6
7 import (
8 "strings"
9 "testing"
10
d37d301f
Keenan Nemetz
16h ago
11 "rodent.software/vole/metadata"
e5478085
Keenan Nemetz
11d ago
12 )
13
14 func TestCandidateIsPublishedAndReused(t *testing.T) {
15 t.Parallel()
16 f := newFixture(t)
17 base := f.commit("", "a.md", "one\n", "base")
18 if err := f.g.UpdateRef("refs/heads/main", base); err != nil {
19 t.Fatal(err)
20 }
21 head := f.commit(base, "b.md", "feature\n", "head")
22 moved := f.commit(base, "c.md", "other\n", "base moved")
23 if err := f.g.UpdateRef("refs/heads/main", moved); err != nil {
24 t.Fatal(err)
25 }
26 id := f.review("keenan", head, "reviewer")
27 req, err := metadata.GetRequest(f.g, id)
28 if err != nil {
29 t.Fatal(err)
30 }
31
32 c, conflicts, err := EnsureCandidate(f.g, req, moved, head)
33 if err != nil {
34 t.Fatalf("ensure: %v", err)
35 }
36 if len(conflicts) > 0 {
37 t.Fatalf("conflicts = %v", conflicts)
38 }
39 if c.Ref != CandidateRef(req, moved, head) || !strings.HasPrefix(c.Ref, CandidateRoot) {
40 t.Fatalf("ref = %q, want the candidate namespace", c.Ref)
41 }
42 tip, err := f.g.RevParseRaw(c.Ref)
43 if err != nil || tip != c.SHA {
44 t.Fatalf("ref tip = %q, %v; want %s", tip, err, c.SHA)
45 }
46 parents, err := f.g.CommitParents(c.SHA)
47 if err != nil {
48 t.Fatal(err)
49 }
50 if len(parents) != 2 || parents[0] != moved || parents[1] != head {
51 t.Fatalf("parents = %v, want [%s %s]", parents, moved, head)
52 }
53
54 // The same question has one answer, not a new commit every time.
55 again, _, err := EnsureCandidate(f.g, req, moved, head)
56 if err != nil || again.SHA != c.SHA {
57 t.Fatalf("ensure twice = %v, %v; want the same commit %s", again, err, c.SHA)
58 }
59 found, ok, err := LookupCandidateAt(f.g, req, moved, head)
60 if err != nil || !ok || found.SHA != c.SHA {
61 t.Fatalf("lookup = %+v, %v, %v; want %s", found, ok, err, c.SHA)
62 }
63
64 // A further base move is a different landing, so the old result is not it.
65 movedAgain := f.commit(moved, "d.md", "third\n", "base moved again")
66 if err := f.g.UpdateRef("refs/heads/main", movedAgain); err != nil {
67 t.Fatal(err)
68 }
69 if _, ok, err := LookupCandidateAt(f.g, req, movedAgain, head); err != nil || ok {
70 t.Fatalf("the old result matched a new base: ok=%t err=%v", ok, err)
71 }
72 next, conflicts, err := EnsureCandidate(f.g, req, movedAgain, head)
73 if err != nil || len(conflicts) > 0 {
74 t.Fatalf("ensure for the new base: %v %v", err, conflicts)
75 }
76 if next.SHA == c.SHA {
77 t.Fatal("a new base reused the old combined result")
78 }
79 parents, err = f.g.CommitParents(next.SHA)
80 if err != nil {
81 t.Fatal(err)
82 }
83 if len(parents) != 2 || parents[0] != movedAgain || parents[1] != head {
84 t.Fatalf("new parents = %v, want [%s %s]", parents, movedAgain, head)
85 }
86 }
87
88 func TestCandidateConflictPublishesNothing(t *testing.T) {
89 t.Parallel()
90 f := newFixture(t)
91 base := f.commit("", "a.md", "one\n", "base")
92 if err := f.g.UpdateRef("refs/heads/main", base); err != nil {
93 t.Fatal(err)
94 }
95 head := f.commit(base, "a.md", "branch\n", "branch edit")
96 moved := f.commit(base, "a.md", "base edit\n", "base edit")
97 if err := f.g.UpdateRef("refs/heads/main", moved); err != nil {
98 t.Fatal(err)
99 }
100 id := f.review("keenan", head, "reviewer")
101 req, err := metadata.GetRequest(f.g, id)
102 if err != nil {
103 t.Fatal(err)
104 }
105 c, conflicts, err := EnsureCandidate(f.g, req, moved, head)
106 if err != nil {
107 t.Fatalf("ensure: %v", err)
108 }
109 if c != nil || len(conflicts) == 0 {
110 t.Fatalf("conflicting merge = %+v, %v; want conflicts and no candidate", c, conflicts)
111 }
112 if refs, err := CandidateRefs(f.g, req.ID); err != nil {
113 t.Fatal(err)
114 } else if len(refs) != 0 {
115 t.Fatalf("a conflict published refs: %v", refs)
116 }
117 }