forked from alphagov/cdn-acceptance-tests
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cdn_serve_stale_test.go
128 lines (109 loc) · 3.57 KB
/
cdn_serve_stale_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"fmt"
"io/ioutil"
"net/http"
"testing"
"time"
)
// Should serve stale object and not hit any other backends, if origin
// is down and object is beyond TTL but still in cache.
func TestServeStaleOriginDown(t *testing.T) {
ResetBackends(backendsByPriority)
const expectedBody = "going off like stilton"
const respTTL = time.Duration(2 * time.Second)
const respTTLWithBuffer = 5 * respTTL
headerValue := fmt.Sprintf("max-age=%.0f", respTTL.Seconds())
// All backends except origin.
for _, backend := range backendsByPriority[1:] {
backend.SwitchHandler(func(w http.ResponseWriter, r *http.Request) {
t.Errorf("Server %s received request and it shouldn't have", backend.Name)
w.Write([]byte(backend.Name))
})
}
req := NewUniqueEdgeGET(t)
for requestCount := 1; requestCount < 6; requestCount++ {
switch requestCount {
case 1: // Request 1 populates cache.
originServer.SwitchHandler(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", headerValue)
w.Write([]byte(expectedBody))
})
case 2: // Request 2+ from stale.
time.Sleep(respTTLWithBuffer)
originServer.Stop()
}
resp := RoundTripCheckError(t, req)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
if bodyStr := string(body); bodyStr != expectedBody {
t.Errorf(
"Request %d received incorrect response body. Expected %q, got %q",
requestCount,
expectedBody,
bodyStr,
)
}
}
}
// Should serve stale object and not hit any other backends, if origin
// returns a 5xx response and object is beyond TTL but still in cache.
func TestServeStaleOrigin5xx(t *testing.T) {
ResetBackends(backendsByPriority)
const expectedResponseStale = "going off like stilton"
const expectedResponseFresh = "as fresh as daisies"
const respTTL = time.Duration(2 * time.Second)
const respTTLWithBuffer = 5 * respTTL
// Allow varnish's beresp.saintmode to expire.
const waitSaintMode = time.Duration(5 * time.Second)
headerValue := fmt.Sprintf("max-age=%.0f", respTTL.Seconds())
// All backends except origin.
for _, backend := range backendsByPriority[1:] {
backend.SwitchHandler(func(w http.ResponseWriter, r *http.Request) {
t.Errorf("Server %s received request and it shouldn't have", backend.Name)
w.Write([]byte(backend.Name))
})
}
req := NewUniqueEdgeGET(t)
var expectedBody string
for requestCount := 1; requestCount < 6; requestCount++ {
switch requestCount {
case 1: // Request 1 populates cache.
expectedBody = expectedResponseStale
originServer.SwitchHandler(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", headerValue)
w.Write([]byte(expectedBody))
})
case 2: // Requests 2,3,4 come from stale.
time.Sleep(respTTLWithBuffer)
expectedBody = expectedResponseStale
originServer.SwitchHandler(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(originServer.Name))
})
case 5: // Last request comes directly from origin again.
time.Sleep(waitSaintMode)
expectedBody = expectedResponseFresh
originServer.SwitchHandler(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(expectedBody))
})
}
resp := RoundTripCheckError(t, req)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
if bodyStr := string(body); bodyStr != expectedBody {
t.Errorf(
"Request %d received incorrect response body. Expected %q, got %q",
requestCount,
expectedBody,
bodyStr,
)
}
}
}