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

barerepo / server / internal/store/search_test.go
159 lines · 5.1kb · 133728eaa05486504991b230f9d4c7e986b7defc
log files threads runs releases config jump to file t
133728e barerepo 1mo
1
package store
133728e barerepo 1mo
2
133728e barerepo 1mo
3
import (
133728e barerepo 1mo
4
"context"
133728e barerepo 1mo
5
133728e barerepo 1mo
6
"github.com/barerepo/server/internal/token"
133728e barerepo 1mo
7
"strings"
133728e barerepo 1mo
8
"testing"
133728e barerepo 1mo
9
)
133728e barerepo 1mo
10
133728e barerepo 1mo
11
func indexed(t *testing.T, db *DB, repo, kind, path, title, body string, public bool, readers string) {
133728e barerepo 1mo
12
t.Helper()
133728e barerepo 1mo
13
if err := db.PutDoc(context.Background(),
133728e barerepo 1mo
14
Doc{Repo: repo, Kind: kind, Path: path, Title: title, Body: body}, public, readers); err != nil {
133728e barerepo 1mo
15
t.Fatal(err)
133728e barerepo 1mo
16
}
133728e barerepo 1mo
17
}
133728e barerepo 1mo
18
133728e barerepo 1mo
19
// A query is text, not syntax, so LIKE's own wildcards must not reach the database as wildcards.
133728e barerepo 1mo
20
func TestAQueryWithAWildcardInItIsText(t *testing.T) {
133728e barerepo 1mo
21
ctx := context.Background()
133728e barerepo 1mo
22
db := open(t)
133728e barerepo 1mo
23
indexed(t, db, "john/johnbot", Code, "a.go", "", "cover 100% of the branches", true, "")
133728e barerepo 1mo
24
indexed(t, db, "john/johnbot", Code, "b.go", "", "nothing to do with coverage", true, "")
133728e barerepo 1mo
25
133728e barerepo 1mo
26
// Unescaped, a percent stands for anything, so this query would reach b.go through "coverage".
133728e barerepo 1mo
27
docs, err := db.FindDocs(ctx, "", "c%e", 10)
133728e barerepo 1mo
28
if err != nil {
133728e barerepo 1mo
29
t.Fatal(err)
133728e barerepo 1mo
30
}
133728e barerepo 1mo
31
if len(docs) != 0 {
133728e barerepo 1mo
32
t.Errorf("c%%e matched %d documents, and it is a string that appears in neither", len(docs))
133728e barerepo 1mo
33
}
133728e barerepo 1mo
34
if docs, err := db.FindDocs(ctx, "", "100%", 10); err != nil || len(docs) != 1 {
133728e barerepo 1mo
35
t.Errorf("the literal 100%% found %d documents, wanted a.go alone: %v", len(docs), err)
133728e barerepo 1mo
36
}
133728e barerepo 1mo
37
133728e barerepo 1mo
38
// An underscore is LIKE's single character wildcard, and here it is a character.
133728e barerepo 1mo
39
indexed(t, db, "john/johnbot", Code, "c.go", "", "func readXall() error", true, "")
133728e barerepo 1mo
40
docs, err = db.FindDocs(ctx, "", "read_all", 10)
133728e barerepo 1mo
41
if err != nil {
133728e barerepo 1mo
42
t.Fatal(err)
133728e barerepo 1mo
43
}
133728e barerepo 1mo
44
if len(docs) != 0 {
133728e barerepo 1mo
45
t.Errorf("read_all matched readXall, so the underscore reached the database as a wildcard")
133728e barerepo 1mo
46
}
133728e barerepo 1mo
47
}
133728e barerepo 1mo
48
133728e barerepo 1mo
49
// The read set is a string of names between pipes, so one name must never match inside another.
133728e barerepo 1mo
50
func TestOneReaderNameNeverMatchesInsideAnother(t *testing.T) {
133728e barerepo 1mo
51
ctx := context.Background()
133728e barerepo 1mo
52
db := open(t)
133728e barerepo 1mo
53
indexed(t, db, "johnson/vault", Code, "s.go", "", "const launchCode = 1", false, Readers("johnson", nil))
133728e barerepo 1mo
54
133728e barerepo 1mo
55
if docs, err := db.FindDocs(ctx, "johnson", "launchCode", 10); err != nil || len(docs) != 1 {
133728e barerepo 1mo
56
t.Errorf("johnson cannot read her own repository: %d, %v", len(docs), err)
133728e barerepo 1mo
57
}
133728e barerepo 1mo
58
for _, who := range []string{"", "lisa", "ami", "a"} {
133728e barerepo 1mo
59
docs, err := db.FindDocs(ctx, who, "launchCode", 10)
133728e barerepo 1mo
60
if err != nil {
133728e barerepo 1mo
61
t.Fatal(err)
133728e barerepo 1mo
62
}
133728e barerepo 1mo
63
if len(docs) != 0 {
133728e barerepo 1mo
64
t.Errorf("%q read a private repository they have no part in", who)
133728e barerepo 1mo
65
}
133728e barerepo 1mo
66
}
133728e barerepo 1mo
67
}
133728e barerepo 1mo
68
133728e barerepo 1mo
69
// Chapter 18 grants read to [access] push as well as the owner, and the index carries both.
133728e barerepo 1mo
70
func TestTheReadSetCarriesTheOwnerAndThePushList(t *testing.T) {
133728e barerepo 1mo
71
got := Readers("john", []string{"lisa", "mark", "john"})
133728e barerepo 1mo
72
if !strings.HasPrefix(got, "|john|") {
133728e barerepo 1mo
73
t.Errorf("the owner is not first in %q", got)
133728e barerepo 1mo
74
}
133728e barerepo 1mo
75
if strings.Count(got, "|john|") != 1 {
133728e barerepo 1mo
76
t.Errorf("the owner is listed twice in %q", got)
133728e barerepo 1mo
77
}
133728e barerepo 1mo
78
for _, name := range []string{"lisa", "mark"} {
133728e barerepo 1mo
79
if !strings.Contains(got, "|"+name+"|") {
133728e barerepo 1mo
80
t.Errorf("%s is missing from %q", name, got)
133728e barerepo 1mo
81
}
133728e barerepo 1mo
82
}
133728e barerepo 1mo
83
}
133728e barerepo 1mo
84
133728e barerepo 1mo
85
// Ranking is code, then threads, then repositories, per chapter 17.
133728e barerepo 1mo
86
func TestCodeRanksAboveThreadsAboveRepositories(t *testing.T) {
133728e barerepo 1mo
87
ctx := context.Background()
133728e barerepo 1mo
88
db := open(t)
133728e barerepo 1mo
89
indexed(t, db, "john/johnbot", Repository, "", "john/johnbot", "a backoff bot", true, "")
133728e barerepo 1mo
90
indexed(t, db, "john/johnbot", Thread, "44", "backoff is wrong", "it spins", true, "")
133728e barerepo 1mo
91
indexed(t, db, "john/johnbot", Code, "retry.go", "", "func backoff() {}", true, "")
133728e barerepo 1mo
92
133728e barerepo 1mo
93
docs, err := db.FindDocs(ctx, "", "backoff", 10)
133728e barerepo 1mo
94
if err != nil {
133728e barerepo 1mo
95
t.Fatal(err)
133728e barerepo 1mo
96
}
133728e barerepo 1mo
97
var order []string
133728e barerepo 1mo
98
for _, d := range docs {
133728e barerepo 1mo
99
order = append(order, d.Kind)
133728e barerepo 1mo
100
}
133728e barerepo 1mo
101
want := []string{Code, Thread, Repository}
133728e barerepo 1mo
102
if len(order) != len(want) {
133728e barerepo 1mo
103
t.Fatalf("got %v, wanted %v", order, want)
133728e barerepo 1mo
104
}
133728e barerepo 1mo
105
for i := range want {
133728e barerepo 1mo
106
if order[i] != want[i] {
133728e barerepo 1mo
107
t.Fatalf("got %v, wanted %v", order, want)
133728e barerepo 1mo
108
}
133728e barerepo 1mo
109
}
133728e barerepo 1mo
110
}
133728e barerepo 1mo
111
133728e barerepo 1mo
112
// Chapter 24 puts a run count and a status on every runner row, and both come from the jobs table.
133728e barerepo 1mo
113
func TestWorkOfCountsRunsAndFindsTheBusyMachine(t *testing.T) {
133728e barerepo 1mo
114
ctx := context.Background()
133728e barerepo 1mo
115
db := open(t)
133728e barerepo 1mo
116
if _, err := db.CreateAccount(ctx, "john", keyA, false); err != nil {
133728e barerepo 1mo
117
t.Fatal(err)
133728e barerepo 1mo
118
}
133728e barerepo 1mo
119
_, tok, err := db.CreateToken(ctx, token.Runner, "john", "john/johnbot", "a runner")
133728e barerepo 1mo
120
if err != nil {
133728e barerepo 1mo
121
t.Fatal(err)
133728e barerepo 1mo
122
}
133728e barerepo 1mo
123
runner, err := db.AttachRunner(ctx, tok.ID, "john/johnbot", "uproar.local", "linux", "amd64", nil)
133728e barerepo 1mo
124
if err != nil {
133728e barerepo 1mo
125
t.Fatal(err)
133728e barerepo 1mo
126
}
133728e barerepo 1mo
127
133728e barerepo 1mo
128
if work, err := db.WorkOf(ctx, "john/johnbot"); err != nil || len(work) != 0 {
133728e barerepo 1mo
129
t.Errorf("a machine that has run nothing counted %d, %v", len(work), err)
133728e barerepo 1mo
130
}
133728e barerepo 1mo
131
133728e barerepo 1mo
132
for i := 0; i < 3; i++ {
133728e barerepo 1mo
133
if _, err := db.QueueJob(ctx, "john/johnbot", "refs/heads/master", "abc", "go test", ""); err != nil {
133728e barerepo 1mo
134
t.Fatal(err)
133728e barerepo 1mo
135
}
133728e barerepo 1mo
136
job, err := db.TakeJob(ctx, "john/johnbot", *runner)
133728e barerepo 1mo
137
if err != nil || job == nil {
133728e barerepo 1mo
138
t.Fatalf("the runner could not take a job: %v", err)
133728e barerepo 1mo
139
}
133728e barerepo 1mo
140
// Two of the three finish, so the third leaves the machine busy.
133728e barerepo 1mo
141
if i < 2 {
133728e barerepo 1mo
142
if _, err := db.FinishJob(ctx, job.ID, runner.ID); err != nil {
133728e barerepo 1mo
143
t.Fatal(err)
133728e barerepo 1mo
144
}
133728e barerepo 1mo
145
}
133728e barerepo 1mo
146
}
133728e barerepo 1mo
147
133728e barerepo 1mo
148
work, err := db.WorkOf(ctx, "john/johnbot")
133728e barerepo 1mo
149
if err != nil {
133728e barerepo 1mo
150
t.Fatal(err)
133728e barerepo 1mo
151
}
133728e barerepo 1mo
152
got := work[runner.ID]
133728e barerepo 1mo
153
if got.Runs != 3 {
133728e barerepo 1mo
154
t.Errorf("the machine counted %d runs, wanted 3", got.Runs)
133728e barerepo 1mo
155
}
133728e barerepo 1mo
156
if !got.Busy {
133728e barerepo 1mo
157
t.Error("a machine holding a running job did not read as busy")
133728e barerepo 1mo
158
}
133728e barerepo 1mo
159
}
history · rawbarerepo 0.1.0