cloudflare/cloudflared

Public

mirrored from https://github.com/cloudflare/cloudflaredAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2018.10.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

origin/backoffhandler_test.go

148lines · modecode

1package origin
2
3import (
4 "testing"
5 "time"
6
7 "golang.org/x/net/context"
8)
9
10func immediateTimeAfter(time.Duration) <-chan time.Time {
11 c := make(chan time.Time, 1)
12 c <- time.Now()
13 return c
14}
15
16func TestBackoffRetries(t *testing.T) {
17 // make backoff return immediately
18 timeAfter = immediateTimeAfter
19 ctx := context.Background()
20 backoff := BackoffHandler{MaxRetries: 3}
21 if !backoff.Backoff(ctx) {
22 t.Fatalf("backoff failed immediately")
23 }
24 if !backoff.Backoff(ctx) {
25 t.Fatalf("backoff failed after 1 retry")
26 }
27 if !backoff.Backoff(ctx) {
28 t.Fatalf("backoff failed after 2 retry")
29 }
30 if backoff.Backoff(ctx) {
31 t.Fatalf("backoff allowed after 3 (max) retries")
32 }
33}
34
35func TestBackoffCancel(t *testing.T) {
36 // prevent backoff from returning normally
37 timeAfter = func(time.Duration) <-chan time.Time { return make(chan time.Time) }
38 ctx, cancelFunc := context.WithCancel(context.Background())
39 backoff := BackoffHandler{MaxRetries: 3}
40 cancelFunc()
41 if backoff.Backoff(ctx) {
42 t.Fatalf("backoff allowed after cancel")
43 }
44 if _, ok := backoff.GetBackoffDuration(ctx); ok {
45 t.Fatalf("backoff allowed after cancel")
46 }
47}
48
49func TestBackoffGracePeriod(t *testing.T) {
50 currentTime := time.Now()
51 // make timeNow return whatever we like
52 timeNow = func() time.Time { return currentTime }
53 // make backoff return immediately
54 timeAfter = immediateTimeAfter
55 ctx := context.Background()
56 backoff := BackoffHandler{MaxRetries: 1}
57 if !backoff.Backoff(ctx) {
58 t.Fatalf("backoff failed immediately")
59 }
60 // the next call to Backoff would fail unless it's after the grace period
61 backoff.SetGracePeriod()
62 // advance time to after the grace period (~4 seconds) and see what happens
63 currentTime = currentTime.Add(time.Second * 5)
64 if !backoff.Backoff(ctx) {
65 t.Fatalf("backoff failed after the grace period expired")
66 }
67 // confirm we ignore grace period after backoff
68 if backoff.Backoff(ctx) {
69 t.Fatalf("backoff allowed after 1 (max) retry")
70 }
71}
72
73func TestGetBackoffDurationRetries(t *testing.T) {
74 // make backoff return immediately
75 timeAfter = immediateTimeAfter
76 ctx := context.Background()
77 backoff := BackoffHandler{MaxRetries: 3}
78 if _, ok := backoff.GetBackoffDuration(ctx); !ok {
79 t.Fatalf("backoff failed immediately")
80 }
81 backoff.Backoff(ctx) // noop
82 if _, ok := backoff.GetBackoffDuration(ctx); !ok {
83 t.Fatalf("backoff failed after 1 retry")
84 }
85 backoff.Backoff(ctx) // noop
86 if _, ok := backoff.GetBackoffDuration(ctx); !ok {
87 t.Fatalf("backoff failed after 2 retry")
88 }
89 backoff.Backoff(ctx) // noop
90 if _, ok := backoff.GetBackoffDuration(ctx); ok {
91 t.Fatalf("backoff allowed after 3 (max) retries")
92 }
93 if backoff.Backoff(ctx) {
94 t.Fatalf("backoff allowed after 3 (max) retries")
95 }
96}
97
98func TestGetBackoffDuration(t *testing.T) {
99 // make backoff return immediately
100 timeAfter = immediateTimeAfter
101 ctx := context.Background()
102 backoff := BackoffHandler{MaxRetries: 3}
103 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second {
104 t.Fatalf("backoff didn't return 1 second on first retry")
105 }
106 backoff.Backoff(ctx) // noop
107 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second*2 {
108 t.Fatalf("backoff didn't return 2 seconds on second retry")
109 }
110 backoff.Backoff(ctx) // noop
111 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second*4 {
112 t.Fatalf("backoff didn't return 4 seconds on third retry")
113 }
114 backoff.Backoff(ctx) // noop
115 if duration, ok := backoff.GetBackoffDuration(ctx); ok || duration != 0 {
116 t.Fatalf("backoff didn't return 0 seconds on fourth retry (exceeding limit)")
117 }
118}
119
120func TestBackoffRetryForever(t *testing.T) {
121 // make backoff return immediately
122 timeAfter = immediateTimeAfter
123 ctx := context.Background()
124 backoff := BackoffHandler{MaxRetries: 3, RetryForever: true}
125 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second {
126 t.Fatalf("backoff didn't return 1 second on first retry")
127 }
128 backoff.Backoff(ctx) // noop
129 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second*2 {
130 t.Fatalf("backoff didn't return 2 seconds on second retry")
131 }
132 backoff.Backoff(ctx) // noop
133 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second*4 {
134 t.Fatalf("backoff didn't return 4 seconds on third retry")
135 }
136 if !backoff.Backoff(ctx) {
137 t.Fatalf("backoff refused on fourth retry despire RetryForever")
138 }
139 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second*8 {
140 t.Fatalf("backoff returned %v instead of 8 seconds on fourth retry", duration)
141 }
142 if !backoff.Backoff(ctx) {
143 t.Fatalf("backoff refused on fifth retry despire RetryForever")
144 }
145 if duration, ok := backoff.GetBackoffDuration(ctx); !ok || duration != time.Second*8 {
146 t.Fatalf("backoff returned %v instead of 8 seconds on fifth retry", duration)
147 }
148}
149