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