Browse code

Update httputils tests

- Make sure we use httptest instead of depending on network
- Update resumablerequestreader tests

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2015/09/09 21:59:25
Showing 2 changed files
... ...
@@ -1,25 +1,65 @@
1 1
 package httputils
2 2
 
3
-import "testing"
3
+import (
4
+	"fmt"
5
+	"io/ioutil"
6
+	"net/http"
7
+	"net/http/httptest"
8
+	"strings"
9
+	"testing"
10
+)
4 11
 
5 12
 func TestDownload(t *testing.T) {
6
-	_, err := Download("http://docker.com")
7
-
13
+	expected := "Hello, docker !"
14
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15
+		fmt.Fprintf(w, expected)
16
+	}))
17
+	defer ts.Close()
18
+	response, err := Download(ts.URL)
8 19
 	if err != nil {
9
-		t.Fatalf("Expected error to not exist when Download(http://docker.com)")
20
+		t.Fatal(err)
21
+	}
22
+
23
+	actual, err := ioutil.ReadAll(response.Body)
24
+	response.Body.Close()
25
+
26
+	if err != nil || string(actual) != expected {
27
+		t.Fatalf("Expected the response %q, got err:%v, response:%v, actual:%s", expected, err, response, string(actual))
28
+	}
29
+}
30
+
31
+func TestDownload400Errors(t *testing.T) {
32
+	expectedError := "Got HTTP status code >= 400: 403 Forbidden"
33
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
34
+		// 403
35
+		http.Error(w, "something failed (forbidden)", http.StatusForbidden)
36
+	}))
37
+	defer ts.Close()
38
+	// Expected status code = 403
39
+	if _, err := Download(ts.URL); err == nil || err.Error() != expectedError {
40
+		t.Fatalf("Expected the the error %q, got %v", expectedError, err)
10 41
 	}
42
+}
11 43
 
12
-	// Expected status code = 404
13
-	if _, err = Download("http://docker.com/abc1234567"); err == nil {
14
-		t.Fatalf("Expected error to exist when Download(http://docker.com/abc1234567)")
44
+func TestDownloadOtherErrors(t *testing.T) {
45
+	if _, err := Download("I'm not an url.."); err == nil || !strings.Contains(err.Error(), "unsupported protocol scheme") {
46
+		t.Fatalf("Expected an error with 'unsupported protocol scheme', got %v", err)
15 47
 	}
16 48
 }
17 49
 
18 50
 func TestNewHTTPRequestError(t *testing.T) {
19 51
 	errorMessage := "Some error message"
20
-	httpResponse, _ := Download("http://docker.com")
52
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
53
+		// 403
54
+		http.Error(w, errorMessage, http.StatusForbidden)
55
+	}))
56
+	defer ts.Close()
57
+	httpResponse, err := http.Get(ts.URL)
58
+	if err != nil {
59
+		t.Fatal(err)
60
+	}
21 61
 	if err := NewHTTPRequestError(errorMessage, httpResponse); err.Error() != errorMessage {
22
-		t.Fatalf("Expected err to equal error Message")
62
+		t.Fatalf("Expected err to be %q, got %v", errorMessage, err)
23 63
 	}
24 64
 }
25 65
 
... ...
@@ -2,6 +2,7 @@ package httputils
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"io"
5 6
 	"io/ioutil"
6 7
 	"net/http"
7 8
 	"net/http/httptest"
... ...
@@ -9,6 +10,229 @@ import (
9 9
 	"testing"
10 10
 )
11 11
 
12
+func TestResumableRequestHeaderSimpleErrors(t *testing.T) {
13
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
14
+		fmt.Fprintln(w, "Hello, world !")
15
+	}))
16
+	defer ts.Close()
17
+
18
+	client := &http.Client{}
19
+
20
+	var req *http.Request
21
+	req, err := http.NewRequest("GET", ts.URL, nil)
22
+	if err != nil {
23
+		t.Fatal(err)
24
+	}
25
+
26
+	expectedError := "client and request can't be nil\n"
27
+	resreq := &resumableRequestReader{}
28
+	_, err = resreq.Read([]byte{})
29
+	if err == nil || err.Error() != expectedError {
30
+		t.Fatalf("Expected an error with '%s', got %v.", expectedError, err)
31
+	}
32
+
33
+	resreq = &resumableRequestReader{
34
+		client:    client,
35
+		request:   req,
36
+		totalSize: -1,
37
+	}
38
+	expectedError = "failed to auto detect content length"
39
+	_, err = resreq.Read([]byte{})
40
+	if err == nil || err.Error() != expectedError {
41
+		t.Fatalf("Expected an error with '%s', got %v.", expectedError, err)
42
+	}
43
+
44
+}
45
+
46
+// Not too much failures, bails out after some wait
47
+func TestResumableRequestHeaderNotTooMuchFailures(t *testing.T) {
48
+	client := &http.Client{}
49
+
50
+	var badReq *http.Request
51
+	badReq, err := http.NewRequest("GET", "I'm not an url", nil)
52
+	if err != nil {
53
+		t.Fatal(err)
54
+	}
55
+
56
+	resreq := &resumableRequestReader{
57
+		client:      client,
58
+		request:     badReq,
59
+		failures:    0,
60
+		maxFailures: 2,
61
+	}
62
+	read, err := resreq.Read([]byte{})
63
+	if err != nil || read != 0 {
64
+		t.Fatalf("Expected no error and no byte read, got err:%v, read:%v.", err, read)
65
+	}
66
+}
67
+
68
+// Too much failures, returns the error
69
+func TestResumableRequestHeaderTooMuchFailures(t *testing.T) {
70
+	client := &http.Client{}
71
+
72
+	var badReq *http.Request
73
+	badReq, err := http.NewRequest("GET", "I'm not an url", nil)
74
+	if err != nil {
75
+		t.Fatal(err)
76
+	}
77
+
78
+	resreq := &resumableRequestReader{
79
+		client:      client,
80
+		request:     badReq,
81
+		failures:    0,
82
+		maxFailures: 1,
83
+	}
84
+	defer resreq.Close()
85
+
86
+	expectedError := `Get I%27m%20not%20an%20url: unsupported protocol scheme ""`
87
+	read, err := resreq.Read([]byte{})
88
+	if err == nil || err.Error() != expectedError || read != 0 {
89
+		t.Fatalf("Expected the error '%s', got err:%v, read:%v.", expectedError, err, read)
90
+	}
91
+}
92
+
93
+type errorReaderCloser struct{}
94
+
95
+func (errorReaderCloser) Close() error { return nil }
96
+
97
+func (errorReaderCloser) Read(p []byte) (n int, err error) {
98
+	return 0, fmt.Errorf("A error occured")
99
+}
100
+
101
+// If a an unknown error is encountered, return 0, nil and log it
102
+func TestResumableRequestReaderWithReadError(t *testing.T) {
103
+	var req *http.Request
104
+	req, err := http.NewRequest("GET", "", nil)
105
+	if err != nil {
106
+		t.Fatal(err)
107
+	}
108
+
109
+	client := &http.Client{}
110
+
111
+	response := &http.Response{
112
+		Status:        "500 Internal Server",
113
+		StatusCode:    500,
114
+		ContentLength: 0,
115
+		Close:         true,
116
+		Body:          errorReaderCloser{},
117
+	}
118
+
119
+	resreq := &resumableRequestReader{
120
+		client:          client,
121
+		request:         req,
122
+		currentResponse: response,
123
+		lastRange:       1,
124
+		totalSize:       1,
125
+	}
126
+	defer resreq.Close()
127
+
128
+	buf := make([]byte, 1)
129
+	read, err := resreq.Read(buf)
130
+	if err != nil {
131
+		t.Fatal(err)
132
+	}
133
+
134
+	if read != 0 {
135
+		t.Fatalf("Expected to have read nothing, but read %v", read)
136
+	}
137
+}
138
+
139
+func TestResumableRequestReaderWithEOFWith416Response(t *testing.T) {
140
+	var req *http.Request
141
+	req, err := http.NewRequest("GET", "", nil)
142
+	if err != nil {
143
+		t.Fatal(err)
144
+	}
145
+
146
+	client := &http.Client{}
147
+
148
+	response := &http.Response{
149
+		Status:        "416 Requested Range Not Satisfiable",
150
+		StatusCode:    416,
151
+		ContentLength: 0,
152
+		Close:         true,
153
+		Body:          ioutil.NopCloser(strings.NewReader("")),
154
+	}
155
+
156
+	resreq := &resumableRequestReader{
157
+		client:          client,
158
+		request:         req,
159
+		currentResponse: response,
160
+		lastRange:       1,
161
+		totalSize:       1,
162
+	}
163
+	defer resreq.Close()
164
+
165
+	buf := make([]byte, 1)
166
+	_, err = resreq.Read(buf)
167
+	if err == nil || err != io.EOF {
168
+		t.Fatalf("Expected an io.EOF error, got %v", err)
169
+	}
170
+}
171
+
172
+func TestResumableRequestReaderWithServerDoesntSupportByteRanges(t *testing.T) {
173
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
174
+		if r.Header.Get("Range") == "" {
175
+			t.Fatalf("Expected a Range HTTP header, got nothing")
176
+		}
177
+	}))
178
+	defer ts.Close()
179
+
180
+	var req *http.Request
181
+	req, err := http.NewRequest("GET", ts.URL, nil)
182
+	if err != nil {
183
+		t.Fatal(err)
184
+	}
185
+
186
+	client := &http.Client{}
187
+
188
+	resreq := &resumableRequestReader{
189
+		client:    client,
190
+		request:   req,
191
+		lastRange: 1,
192
+	}
193
+	defer resreq.Close()
194
+
195
+	buf := make([]byte, 2)
196
+	_, err = resreq.Read(buf)
197
+	if err == nil || err.Error() != "the server doesn't support byte ranges" {
198
+		t.Fatalf("Expected an error 'the server doesn't support byte ranges', got %v", err)
199
+	}
200
+}
201
+
202
+func TestResumableRequestReaderWithZeroTotalSize(t *testing.T) {
203
+
204
+	srvtxt := "some response text data"
205
+
206
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
207
+		fmt.Fprintln(w, srvtxt)
208
+	}))
209
+	defer ts.Close()
210
+
211
+	var req *http.Request
212
+	req, err := http.NewRequest("GET", ts.URL, nil)
213
+	if err != nil {
214
+		t.Fatal(err)
215
+	}
216
+
217
+	client := &http.Client{}
218
+	retries := uint32(5)
219
+
220
+	resreq := ResumableRequestReader(client, req, retries, 0)
221
+	defer resreq.Close()
222
+
223
+	data, err := ioutil.ReadAll(resreq)
224
+	if err != nil {
225
+		t.Fatal(err)
226
+	}
227
+
228
+	resstr := strings.TrimSuffix(string(data), "\n")
229
+
230
+	if resstr != srvtxt {
231
+		t.Errorf("resstr != srvtxt")
232
+	}
233
+}
234
+
12 235
 func TestResumableRequestReader(t *testing.T) {
13 236
 
14 237
 	srvtxt := "some response text data"