github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/pkg/httputils/resumablerequestreader_test.go (about) 1 package httputils 2 3 import ( 4 "fmt" 5 "io" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "strings" 10 "testing" 11 "time" 12 ) 13 14 func TestResumableRequestHeaderSimpleErrors(t *testing.T) { 15 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 16 fmt.Fprintln(w, "Hello, world !") 17 })) 18 defer ts.Close() 19 20 client := &http.Client{} 21 22 var req *http.Request 23 req, err := http.NewRequest("GET", ts.URL, nil) 24 if err != nil { 25 t.Fatal(err) 26 } 27 28 expectedError := "client and request can't be nil\n" 29 resreq := &resumableRequestReader{} 30 _, err = resreq.Read([]byte{}) 31 if err == nil || err.Error() != expectedError { 32 t.Fatalf("Expected an error with '%s', got %v.", expectedError, err) 33 } 34 35 resreq = &resumableRequestReader{ 36 client: client, 37 request: req, 38 totalSize: -1, 39 } 40 expectedError = "failed to auto detect content length" 41 _, err = resreq.Read([]byte{}) 42 if err == nil || err.Error() != expectedError { 43 t.Fatalf("Expected an error with '%s', got %v.", expectedError, err) 44 } 45 46 } 47 48 // Not too much failures, bails out after some wait 49 func TestResumableRequestHeaderNotTooMuchFailures(t *testing.T) { 50 client := &http.Client{} 51 52 var badReq *http.Request 53 badReq, err := http.NewRequest("GET", "I'm not an url", nil) 54 if err != nil { 55 t.Fatal(err) 56 } 57 58 resreq := &resumableRequestReader{ 59 client: client, 60 request: badReq, 61 failures: 0, 62 maxFailures: 2, 63 waitDuration: 10 * time.Millisecond, 64 } 65 read, err := resreq.Read([]byte{}) 66 if err != nil || read != 0 { 67 t.Fatalf("Expected no error and no byte read, got err:%v, read:%v.", err, read) 68 } 69 } 70 71 // Too much failures, returns the error 72 func TestResumableRequestHeaderTooMuchFailures(t *testing.T) { 73 client := &http.Client{} 74 75 var badReq *http.Request 76 badReq, err := http.NewRequest("GET", "I'm not an url", nil) 77 if err != nil { 78 t.Fatal(err) 79 } 80 81 resreq := &resumableRequestReader{ 82 client: client, 83 request: badReq, 84 failures: 0, 85 maxFailures: 1, 86 } 87 defer resreq.Close() 88 89 expectedError := `Get I%27m%20not%20an%20url: unsupported protocol scheme ""` 90 read, err := resreq.Read([]byte{}) 91 if err == nil || err.Error() != expectedError || read != 0 { 92 t.Fatalf("Expected the error '%s', got err:%v, read:%v.", expectedError, err, read) 93 } 94 } 95 96 type errorReaderCloser struct{} 97 98 func (errorReaderCloser) Close() error { return nil } 99 100 func (errorReaderCloser) Read(p []byte) (n int, err error) { 101 return 0, fmt.Errorf("An error occurred") 102 } 103 104 // If an unknown error is encountered, return 0, nil and log it 105 func TestResumableRequestReaderWithReadError(t *testing.T) { 106 var req *http.Request 107 req, err := http.NewRequest("GET", "", nil) 108 if err != nil { 109 t.Fatal(err) 110 } 111 112 client := &http.Client{} 113 114 response := &http.Response{ 115 Status: "500 Internal Server", 116 StatusCode: 500, 117 ContentLength: 0, 118 Close: true, 119 Body: errorReaderCloser{}, 120 } 121 122 resreq := &resumableRequestReader{ 123 client: client, 124 request: req, 125 currentResponse: response, 126 lastRange: 1, 127 totalSize: 1, 128 } 129 defer resreq.Close() 130 131 buf := make([]byte, 1) 132 read, err := resreq.Read(buf) 133 if err != nil { 134 t.Fatal(err) 135 } 136 137 if read != 0 { 138 t.Fatalf("Expected to have read nothing, but read %v", read) 139 } 140 } 141 142 func TestResumableRequestReaderWithEOFWith416Response(t *testing.T) { 143 var req *http.Request 144 req, err := http.NewRequest("GET", "", nil) 145 if err != nil { 146 t.Fatal(err) 147 } 148 149 client := &http.Client{} 150 151 response := &http.Response{ 152 Status: "416 Requested Range Not Satisfiable", 153 StatusCode: 416, 154 ContentLength: 0, 155 Close: true, 156 Body: ioutil.NopCloser(strings.NewReader("")), 157 } 158 159 resreq := &resumableRequestReader{ 160 client: client, 161 request: req, 162 currentResponse: response, 163 lastRange: 1, 164 totalSize: 1, 165 } 166 defer resreq.Close() 167 168 buf := make([]byte, 1) 169 _, err = resreq.Read(buf) 170 if err == nil || err != io.EOF { 171 t.Fatalf("Expected an io.EOF error, got %v", err) 172 } 173 } 174 175 func TestResumableRequestReaderWithServerDoesntSupportByteRanges(t *testing.T) { 176 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 177 if r.Header.Get("Range") == "" { 178 t.Fatalf("Expected a Range HTTP header, got nothing") 179 } 180 })) 181 defer ts.Close() 182 183 var req *http.Request 184 req, err := http.NewRequest("GET", ts.URL, nil) 185 if err != nil { 186 t.Fatal(err) 187 } 188 189 client := &http.Client{} 190 191 resreq := &resumableRequestReader{ 192 client: client, 193 request: req, 194 lastRange: 1, 195 } 196 defer resreq.Close() 197 198 expectedError := "the server doesn't support byte ranges" 199 buf := make([]byte, 2) 200 _, err = resreq.Read(buf) 201 if err == nil || err.Error() != expectedError { 202 t.Fatalf("Expected an error '%s', got %v", expectedError, err) 203 } 204 } 205 206 func TestResumableRequestReaderWithZeroTotalSize(t *testing.T) { 207 208 srvtxt := "some response text data" 209 210 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 211 fmt.Fprintln(w, srvtxt) 212 })) 213 defer ts.Close() 214 215 var req *http.Request 216 req, err := http.NewRequest("GET", ts.URL, nil) 217 if err != nil { 218 t.Fatal(err) 219 } 220 221 client := &http.Client{} 222 retries := uint32(5) 223 224 resreq := ResumableRequestReader(client, req, retries, 0) 225 defer resreq.Close() 226 227 data, err := ioutil.ReadAll(resreq) 228 if err != nil { 229 t.Fatal(err) 230 } 231 232 resstr := strings.TrimSuffix(string(data), "\n") 233 234 if resstr != srvtxt { 235 t.Error("resstr != srvtxt") 236 } 237 } 238 239 func TestResumableRequestReader(t *testing.T) { 240 241 srvtxt := "some response text data" 242 243 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 244 fmt.Fprintln(w, srvtxt) 245 })) 246 defer ts.Close() 247 248 var req *http.Request 249 req, err := http.NewRequest("GET", ts.URL, nil) 250 if err != nil { 251 t.Fatal(err) 252 } 253 254 client := &http.Client{} 255 retries := uint32(5) 256 imgSize := int64(len(srvtxt)) 257 258 resreq := ResumableRequestReader(client, req, retries, imgSize) 259 defer resreq.Close() 260 261 data, err := ioutil.ReadAll(resreq) 262 if err != nil { 263 t.Fatal(err) 264 } 265 266 resstr := strings.TrimSuffix(string(data), "\n") 267 268 if resstr != srvtxt { 269 t.Error("resstr != srvtxt") 270 } 271 } 272 273 func TestResumableRequestReaderWithInitialResponse(t *testing.T) { 274 275 srvtxt := "some response text data" 276 277 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 278 fmt.Fprintln(w, srvtxt) 279 })) 280 defer ts.Close() 281 282 var req *http.Request 283 req, err := http.NewRequest("GET", ts.URL, nil) 284 if err != nil { 285 t.Fatal(err) 286 } 287 288 client := &http.Client{} 289 retries := uint32(5) 290 imgSize := int64(len(srvtxt)) 291 292 res, err := client.Do(req) 293 if err != nil { 294 t.Fatal(err) 295 } 296 297 resreq := ResumableRequestReaderWithInitialResponse(client, req, retries, imgSize, res) 298 defer resreq.Close() 299 300 data, err := ioutil.ReadAll(resreq) 301 if err != nil { 302 t.Fatal(err) 303 } 304 305 resstr := strings.TrimSuffix(string(data), "\n") 306 307 if resstr != srvtxt { 308 t.Error("resstr != srvtxt") 309 } 310 }