/
client_test.go
164 lines (132 loc) · 4.04 KB
/
client_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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package http
import (
"net/http"
"net/http/httptest"
"net/url"
"testing"
)
func TestClient_QueryWhenAllAvailable(t *testing.T) {
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
defer node1.Close()
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
defer node2.Close()
httpClient := http.DefaultClient
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
client := NewClient(httpClient, []string{u1.Host, u2.Host})
res, err := client.Query(url.URL{
Path: "/",
})
defer res.Body.Close()
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if client.currentHost != 0 {
t.Errorf("expected to only forward requests to the first host")
}
if res.StatusCode != http.StatusOK {
t.Errorf("unexpected status code, expected '200' got '%d'", res.StatusCode)
}
}
func TestClient_QueryWhenSomeAreAvailable(t *testing.T) {
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
defer node2.Close()
httpClient := http.DefaultClient
// Shutting down one of the hosts making it unavailable
node1.Close()
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
client := NewClient(httpClient, []string{u1.Host, u2.Host})
res, err := client.Query(url.URL{
Path: "/",
})
defer res.Body.Close()
// If the request succeeds after changing hosts, it should be reflected in the returned error
// as HostChangedError
if err == nil {
t.Errorf("expected HostChangedError got nil instead")
}
hcerr, ok := err.(*HostChangedError)
if !ok {
t.Errorf("unexpected error occurred: %v", err)
}
if hcerr.NewHost != u2.Host {
t.Errorf("unexpected responding host")
}
if client.currentHost != 1 {
t.Errorf("expected to move on to the following host")
}
if res.StatusCode != http.StatusOK {
t.Errorf("unexpected status code, expected '200' got '%d'", res.StatusCode)
}
}
func TestClient_QueryWhenAllUnavailable(t *testing.T) {
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
httpClient := http.DefaultClient
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
// Shutting down both nodes, both of them now are unavailable
node1.Close()
node2.Close()
client := NewClient(httpClient, []string{u1.Host, u2.Host})
_, err := client.Query(url.URL{
Path: "/",
})
if err != ErrNoAvailableHost {
t.Errorf("Expected %v, got: %v", ErrNoAvailableHost, err)
}
}
func TestClient_BasicAuthIsForwarded(t *testing.T) {
mockAuth := func(request *http.Request) bool {
user, pass, ok := request.BasicAuth()
if ok {
if user == "john" && pass == "doe" {
return true
}
}
return false
}
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if mockAuth(request) {
writer.WriteHeader(http.StatusOK)
return
}
writer.WriteHeader(http.StatusUnauthorized)
}))
defer node1.Close()
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if mockAuth(request) {
writer.WriteHeader(http.StatusOK)
return
}
writer.WriteHeader(http.StatusUnauthorized)
}))
defer node2.Close()
httpClient := http.DefaultClient
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
client := NewClient(httpClient, []string{u1.Host, u2.Host}, WithBasicAuth("john:wrongpassword"))
res, err := client.Query(url.URL{
Path: "/",
})
if err != nil {
t.Errorf("unexpected error")
}
if res.StatusCode != http.StatusUnauthorized {
t.Errorf("expected unauthorized status")
}
}