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

barerepo / server / internal/store/webhooks_test.go
122 lines · 3.5kb · master
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
"testing"
133728e barerepo 1mo
6
)
133728e barerepo 1mo
7
133728e barerepo 1mo
8
// Chapter 23.4 disables a hook after twenty failures in a row, and "in a row" is the whole rule.
133728e barerepo 1mo
9
func TestAHookStopsAfterTwentyFailuresInARow(t *testing.T) {
133728e barerepo 1mo
10
ctx := context.Background()
133728e barerepo 1mo
11
db := open(t)
133728e barerepo 1mo
12
133728e barerepo 1mo
13
const url = "https://example.com/hook"
133728e barerepo 1mo
14
for i := range HookFailureLimit - 1 {
133728e barerepo 1mo
15
if err := db.HookFailed(ctx, "john/johnbot", url, "500 Internal Server Error"); err != nil {
133728e barerepo 1mo
16
t.Fatal(err)
133728e barerepo 1mo
17
}
133728e barerepo 1mo
18
state, err := db.HooksOf(ctx, "john/johnbot")
133728e barerepo 1mo
19
if err != nil {
133728e barerepo 1mo
20
t.Fatal(err)
133728e barerepo 1mo
21
}
133728e barerepo 1mo
22
if state[url].Disabled {
133728e barerepo 1mo
23
t.Fatalf("the hook stopped after %d failures, before the limit of %d",
133728e barerepo 1mo
24
i+1, HookFailureLimit)
133728e barerepo 1mo
25
}
133728e barerepo 1mo
26
}
133728e barerepo 1mo
27
if err := db.HookFailed(ctx, "john/johnbot", url, "500 Internal Server Error"); err != nil {
133728e barerepo 1mo
28
t.Fatal(err)
133728e barerepo 1mo
29
}
133728e barerepo 1mo
30
state, err := db.HooksOf(ctx, "john/johnbot")
133728e barerepo 1mo
31
if err != nil {
133728e barerepo 1mo
32
t.Fatal(err)
133728e barerepo 1mo
33
}
133728e barerepo 1mo
34
if !state[url].Disabled {
133728e barerepo 1mo
35
t.Errorf("the hook failed %d times and is still enabled", HookFailureLimit)
133728e barerepo 1mo
36
}
133728e barerepo 1mo
37
if state[url].LastError == "" {
133728e barerepo 1mo
38
t.Error("the config page has nothing to show about why it stopped")
133728e barerepo 1mo
39
}
133728e barerepo 1mo
40
}
133728e barerepo 1mo
41
133728e barerepo 1mo
42
// One delivery clears the count, or a hook that fails once a week eventually stops for no reason.
133728e barerepo 1mo
43
func TestOneDeliveryClearsTheFailureCount(t *testing.T) {
133728e barerepo 1mo
44
ctx := context.Background()
133728e barerepo 1mo
45
db := open(t)
133728e barerepo 1mo
46
133728e barerepo 1mo
47
const url = "https://example.com/hook"
133728e barerepo 1mo
48
for range HookFailureLimit - 1 {
133728e barerepo 1mo
49
if err := db.HookFailed(ctx, "john/johnbot", url, "timeout"); err != nil {
133728e barerepo 1mo
50
t.Fatal(err)
133728e barerepo 1mo
51
}
133728e barerepo 1mo
52
}
133728e barerepo 1mo
53
if err := db.HookDelivered(ctx, "john/johnbot", url); err != nil {
133728e barerepo 1mo
54
t.Fatal(err)
133728e barerepo 1mo
55
}
133728e barerepo 1mo
56
state, err := db.HooksOf(ctx, "john/johnbot")
133728e barerepo 1mo
57
if err != nil {
133728e barerepo 1mo
58
t.Fatal(err)
133728e barerepo 1mo
59
}
133728e barerepo 1mo
60
if state[url].Failures != 0 {
133728e barerepo 1mo
61
t.Errorf("a delivered hook still counts %d failures", state[url].Failures)
133728e barerepo 1mo
62
}
133728e barerepo 1mo
63
if state[url].LastError != "" {
133728e barerepo 1mo
64
t.Errorf("a delivered hook still shows the error %q", state[url].LastError)
133728e barerepo 1mo
65
}
133728e barerepo 1mo
66
if state[url].LastAt.IsZero() {
133728e barerepo 1mo
67
t.Error("a delivered hook has no delivery time to show")
133728e barerepo 1mo
68
}
133728e barerepo 1mo
69
}
133728e barerepo 1mo
70
133728e barerepo 1mo
71
// The cursor is what stops a restart from sending every event in the table again.
133728e barerepo 1mo
72
func TestTheCursorNeitherRepeatsNorSkips(t *testing.T) {
133728e barerepo 1mo
73
ctx := context.Background()
133728e barerepo 1mo
74
db := open(t)
133728e barerepo 1mo
75
133728e barerepo 1mo
76
for i := range 3 {
133728e barerepo 1mo
77
if err := db.Record(ctx, Event{Kind: Pushed, Actor: "john", Repo: "john/johnbot",
133728e barerepo 1mo
78
Ref: "refs/heads/master", Title: string(rune('a' + i))}); err != nil {
133728e barerepo 1mo
79
t.Fatal(err)
133728e barerepo 1mo
80
}
133728e barerepo 1mo
81
}
133728e barerepo 1mo
82
// A first start sends no backlog, because a new hook is not a request for history.
133728e barerepo 1mo
83
if err := db.StartWebhooksHere(ctx); err != nil {
133728e barerepo 1mo
84
t.Fatal(err)
133728e barerepo 1mo
85
}
133728e barerepo 1mo
86
at, err := db.WebhookCursor(ctx)
133728e barerepo 1mo
87
if err != nil {
133728e barerepo 1mo
88
t.Fatal(err)
133728e barerepo 1mo
89
}
133728e barerepo 1mo
90
pending, err := db.EventsAfter(ctx, at, 100)
133728e barerepo 1mo
91
if err != nil {
133728e barerepo 1mo
92
t.Fatal(err)
133728e barerepo 1mo
93
}
133728e barerepo 1mo
94
if len(pending) != 0 {
133728e barerepo 1mo
95
t.Fatalf("a first start would have sent %d old events", len(pending))
133728e barerepo 1mo
96
}
133728e barerepo 1mo
97
if err := db.Record(ctx, Event{Kind: ThreadOpened, Actor: "lisa",
133728e barerepo 1mo
98
Repo: "john/johnbot", Number: 4, Title: "a new one"}); err != nil {
133728e barerepo 1mo
99
t.Fatal(err)
133728e barerepo 1mo
100
}
133728e barerepo 1mo
101
pending, err = db.EventsAfter(ctx, at, 100)
133728e barerepo 1mo
102
if err != nil {
133728e barerepo 1mo
103
t.Fatal(err)
133728e barerepo 1mo
104
}
133728e barerepo 1mo
105
if len(pending) != 1 || pending[0].Title != "a new one" {
133728e barerepo 1mo
106
t.Fatalf("the event after the cursor is %v, wanted the one that just happened", pending)
133728e barerepo 1mo
107
}
133728e barerepo 1mo
108
// A second start keeps the cursor it has, or every restart replays the same events.
133728e barerepo 1mo
109
if err := db.SetWebhookCursor(ctx, pending[0].ID); err != nil {
133728e barerepo 1mo
110
t.Fatal(err)
133728e barerepo 1mo
111
}
133728e barerepo 1mo
112
if err := db.StartWebhooksHere(ctx); err != nil {
133728e barerepo 1mo
113
t.Fatal(err)
133728e barerepo 1mo
114
}
133728e barerepo 1mo
115
again, err := db.WebhookCursor(ctx)
133728e barerepo 1mo
116
if err != nil {
133728e barerepo 1mo
117
t.Fatal(err)
133728e barerepo 1mo
118
}
133728e barerepo 1mo
119
if again != pending[0].ID {
133728e barerepo 1mo
120
t.Errorf("a restart moved the cursor from %d to %d", pending[0].ID, again)
133728e barerepo 1mo
121
}
133728e barerepo 1mo
122
}
history · rawbarerepo 0.1.0