File view with blame information shown in the left gutter beside each line.

barerepo / server / e2e/matrix_test.go
124 lines · 5.3kb · 133728eaa05486504991b230f9d4c7e986b7defc
log files threads runs releases config jump to file t
133728e barerepo 1mo
1
package e2e
133728e barerepo 1mo
2
133728e barerepo 1mo
3
import (
133728e barerepo 1mo
4
"fmt"
133728e barerepo 1mo
5
"os/exec"
133728e barerepo 1mo
6
"strings"
133728e barerepo 1mo
7
"testing"
133728e barerepo 1mo
8
)
133728e barerepo 1mo
9
133728e barerepo 1mo
10
// Chapter 18 calls itself the complete matrix, so every cell of it is a row here.
133728e barerepo 1mo
11
func TestTheAccessMatrixIsTheWholeMatrix(t *testing.T) {
133728e barerepo 1mo
12
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
13
t.Skip("git is not installed")
133728e barerepo 1mo
14
}
133728e barerepo 1mo
15
in := newInstance(t)
133728e barerepo 1mo
16
john := in.account("john")
133728e barerepo 1mo
17
lisa := in.account("lisa")
133728e barerepo 1mo
18
mark := in.account("mark")
133728e barerepo 1mo
19
dave := in.account("dave")
133728e barerepo 1mo
20
133728e barerepo 1mo
21
// john owns it, lisa has push, mark and dave have neither.
133728e barerepo 1mo
22
work := t.TempDir()
133728e barerepo 1mo
23
run(t, work, "git", "init", "-q", "-b", "master", work)
133728e barerepo 1mo
24
write(t, work, "config.go", "package main\n")
133728e barerepo 1mo
25
write(t, work, ".barerepo/config", "[repo]\nvisibility = \"public\"\n\n[access]\npush = [\"lisa\"]\n")
133728e barerepo 1mo
26
run(t, work, "git", "add", "-A")
133728e barerepo 1mo
27
run(t, work, "git", "commit", "-qm", "first")
133728e barerepo 1mo
28
run(t, work, "git", "push", "-q", in.url(john, "/john/johnbot"), "master")
133728e barerepo 1mo
29
133728e barerepo 1mo
30
// mark opens a proposal, which makes him its author for the row that says so.
133728e barerepo 1mo
31
mine := clone(t, in, mark, "/john/johnbot")
133728e barerepo 1mo
32
commit(t, mine, "package main\n\nfunc main() {}\n", "mark proposes")
133728e barerepo 1mo
33
run(t, mine, "git", "push", "-q", in.url(mark, "/john/johnbot"), "HEAD:refs/proposals/new")
133728e barerepo 1mo
34
133728e barerepo 1mo
35
cases := []struct {
133728e barerepo 1mo
36
row string
133728e barerepo 1mo
37
actor string
133728e barerepo 1mo
38
token string
133728e barerepo 1mo
39
ref string
133728e barerepo 1mo
40
allowed bool
133728e barerepo 1mo
41
}{
133728e barerepo 1mo
42
{"refs/heads/*", "the owner", john, "refs/heads/topic", true},
133728e barerepo 1mo
43
{"refs/heads/*", "someone with push", lisa, "refs/heads/lisa-topic", true},
133728e barerepo 1mo
44
{"refs/heads/*", "a stranger", mark, "refs/heads/mark-topic", false},
133728e barerepo 1mo
45
{"refs/tags/*", "the owner", john, "refs/tags/v1.0.0", true},
133728e barerepo 1mo
46
{"refs/tags/*", "someone with push", lisa, "refs/tags/v1.0.1", true},
133728e barerepo 1mo
47
{"refs/tags/*", "a stranger", mark, "refs/tags/v9.9.9", false},
133728e barerepo 1mo
48
{"refs/proposals/new", "a stranger", dave, "refs/proposals/new", true},
133728e barerepo 1mo
49
{"refs/proposals/<n>", "its author", mark, "refs/proposals/1", true},
133728e barerepo 1mo
50
{"refs/proposals/<n>", "someone with push", lisa, "refs/proposals/1", true},
133728e barerepo 1mo
51
{"refs/proposals/<n>", "another stranger", dave, "refs/proposals/1", false},
133728e barerepo 1mo
52
{"refs/notes/runs", "a stranger", mark, "refs/notes/runs", false},
133728e barerepo 1mo
53
{"refs/notes/runs", "the owner restoring", john, "refs/notes/runs", true},
133728e barerepo 1mo
54
{"refs/meta/*", "a stranger", mark, "refs/meta/counter", false},
133728e barerepo 1mo
55
{"refs/meta/*", "the owner restoring", john, "refs/meta/counter", true},
133728e barerepo 1mo
56
{"everything else", "the owner restoring", john, "refs/wat/anything", true},
133728e barerepo 1mo
57
{"everything else", "a stranger", mark, "refs/wat/anything", false},
133728e barerepo 1mo
58
}
133728e barerepo 1mo
59
133728e barerepo 1mo
60
// Each case pushes its own commit, or git answers "everything up-to-date" and the hook never runs.
133728e barerepo 1mo
61
shas := make([]string, len(cases))
133728e barerepo 1mo
62
for i := range cases {
133728e barerepo 1mo
63
commit(t, mine, fmt.Sprintf("package main\n\nvar n = %d\n", i), fmt.Sprintf("case %d", i))
133728e barerepo 1mo
64
shas[i] = strings.TrimSpace(run(t, mine, "git", "rev-parse", "HEAD"))
133728e barerepo 1mo
65
}
133728e barerepo 1mo
66
133728e barerepo 1mo
67
for i, c := range cases {
133728e barerepo 1mo
68
out, err := try(t, mine, "git", "push", "-f", in.url(c.token, "/john/johnbot"),
133728e barerepo 1mo
69
shas[i]+":"+c.ref)
133728e barerepo 1mo
70
if strings.Contains(out, "up-to-date") {
133728e barerepo 1mo
71
t.Errorf("%s: %s pushed nothing, so the hook never judged it", c.row, c.actor)
133728e barerepo 1mo
72
continue
133728e barerepo 1mo
73
}
133728e barerepo 1mo
74
switch {
133728e barerepo 1mo
75
case c.allowed && err != nil:
133728e barerepo 1mo
76
t.Errorf("%s: %s was refused and chapter 18 allows it:\n%s", c.row, c.actor, out)
133728e barerepo 1mo
77
case !c.allowed && err == nil:
133728e barerepo 1mo
78
t.Errorf("%s: %s wrote it and chapter 18 does not allow that:\n%s", c.row, c.actor, out)
133728e barerepo 1mo
79
}
133728e barerepo 1mo
80
}
133728e barerepo 1mo
81
}
133728e barerepo 1mo
82
133728e barerepo 1mo
83
// Chapter 18 lets anyone who may read write refs/notes/threads/*, and chapter 13 makes that a reply.
133728e barerepo 1mo
84
func TestAnyoneWhoMayReadMayReplyAndNobodyMayWipeAThread(t *testing.T) {
133728e barerepo 1mo
85
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
86
t.Skip("git is not installed")
133728e barerepo 1mo
87
}
133728e barerepo 1mo
88
in := newInstance(t)
133728e barerepo 1mo
89
john := in.account("john")
133728e barerepo 1mo
90
dave := in.account("dave")
133728e barerepo 1mo
91
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
92
133728e barerepo 1mo
93
mine := clone(t, in, john, "/john/johnbot")
133728e barerepo 1mo
94
commit(t, mine, "package main\n\nfunc main() {}\n", "john proposes")
133728e barerepo 1mo
95
run(t, mine, "git", "push", "-q", in.url(john, "/john/johnbot"), "HEAD:refs/proposals/new")
133728e barerepo 1mo
96
133728e barerepo 1mo
97
daves := clone(t, in, dave, "/john/johnbot")
133728e barerepo 1mo
98
ref := "refs/notes/threads/1"
133728e barerepo 1mo
99
run(t, daves, "git", "fetch", "-q", in.url(dave, "/john/johnbot"), ref+":"+ref)
133728e barerepo 1mo
100
run(t, daves, "git", "fetch", "-q", in.url(dave, "/john/johnbot"), "refs/proposals/1:refs/proposals/1")
133728e barerepo 1mo
101
run(t, daves, "git", "notes", "--ref=threads/1", "append", "-m", "dave may read, so dave may reply")
133728e barerepo 1mo
102
if out, err := try(t, daves, "git", "push", in.url(dave, "/john/johnbot"), ref+":"+ref); err != nil {
133728e barerepo 1mo
103
t.Errorf("a reader was refused a reply and chapter 18 allows it:\n%s", out)
133728e barerepo 1mo
104
}
133728e barerepo 1mo
105
133728e barerepo 1mo
106
// The same ref, the same reader, and a push that keeps nothing. Chapter 13 refuses this one.
133728e barerepo 1mo
107
wipe := strings.TrimSpace(run(t, daves, "git", "rev-parse", "HEAD"))
133728e barerepo 1mo
108
if out, err := try(t, daves, "git", "push", "-f", in.url(dave, "/john/johnbot"), wipe+":"+ref); err == nil {
133728e barerepo 1mo
109
t.Errorf("a reader wiped a thread and chapter 13 forbids that:\n%s", out)
133728e barerepo 1mo
110
}
133728e barerepo 1mo
111
133728e barerepo 1mo
112
// The meta blob survives this one, so only the guard that counts records can refuse it.
133728e barerepo 1mo
113
run(t, daves, "git", "fetch", "-q", "-f", in.url(dave, "/john/johnbot"), ref+":"+ref)
133728e barerepo 1mo
114
listed := run(t, daves, "git", "notes", "--ref=threads/1", "list")
133728e barerepo 1mo
115
fields := strings.Fields(listed)
133728e barerepo 1mo
116
if len(fields) < 2 {
133728e barerepo 1mo
117
t.Fatalf("thread 1 holds no note to overwrite: %s", listed)
133728e barerepo 1mo
118
}
133728e barerepo 1mo
119
on := fields[1]
133728e barerepo 1mo
120
run(t, daves, "git", "notes", "--ref=threads/1", "add", "-f", "-m", "mine alone now", on)
133728e barerepo 1mo
121
if out, err := try(t, daves, "git", "push", "-f", in.url(dave, "/john/johnbot"), ref+":"+ref); err == nil {
133728e barerepo 1mo
122
t.Errorf("a reader overwrote a comment and chapter 13 forbids that:\n%s", out)
133728e barerepo 1mo
123
}
133728e barerepo 1mo
124
}
history · rawbarerepo 0.1.0