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