NOTE: This test records expected text strings, but NEITHER the returned error types NOR the error texts are an API commitment subject to API stability expectations; they can change at any time for any reason.
(t *testing.T)
| 16 | // NOR the error texts are an API commitment subject to API stability expectations; |
| 17 | // they can change at any time for any reason. |
| 18 | func TestRegistryHTTPResponseToError(t *testing.T) { |
| 19 | var unwrappedUnexpectedHTTPResponseError *unexpectedHTTPResponseError |
| 20 | var unwrappedErrcodeError errcode.Error |
| 21 | for _, c := range []struct { |
| 22 | name string |
| 23 | response string |
| 24 | errorString string |
| 25 | errorType any // A value of the same type as the expected error, or nil |
| 26 | unwrappedErrorPtr any // A pointer to a value expected to be reachable using errors.As, or nil |
| 27 | errorCode *errcode.ErrorCode // A matching ErrorCode, or nil |
| 28 | fn func(t *testing.T, err error) // A more specialized test, or nil |
| 29 | }{ |
| 30 | { |
| 31 | name: "HTTP status out of registry error range", |
| 32 | response: "HTTP/1.1 333 HTTP status out of range\r\n" + |
| 33 | "Header1: Value1\r\n" + |
| 34 | "\r\n" + |
| 35 | "Body of the request\r\n", |
| 36 | errorString: "received unexpected HTTP status: 333 HTTP status out of range", |
| 37 | errorType: UnexpectedHTTPStatusError{}, |
| 38 | fn: func(t *testing.T, err error) { |
| 39 | expected := err.(UnexpectedHTTPStatusError) |
| 40 | assert.Equal(t, 333, expected.StatusCode) |
| 41 | }, |
| 42 | }, |
| 43 | { |
| 44 | name: "HTTP body not in expected format", |
| 45 | response: "HTTP/1.1 400 I don't like this request\r\n" + |
| 46 | "Header1: Value1\r\n" + |
| 47 | "\r\n" + |
| 48 | "<html><body>JSON? What JSON?</body></html>\r\n", |
| 49 | errorString: `StatusCode: 400, "<html><body>JSON? What JSON?</body></html>\r\n"`, |
| 50 | errorType: nil, |
| 51 | unwrappedErrorPtr: &unwrappedUnexpectedHTTPResponseError, |
| 52 | }, |
| 53 | { |
| 54 | name: "401 body not in expected format", |
| 55 | response: "HTTP/1.1 401 I don't like this request\r\n" + |
| 56 | "Header1: Value1\r\n" + |
| 57 | "\r\n" + |
| 58 | "<html><body>JSON? What JSON?</body></html>\r\n", |
| 59 | errorString: "authentication required", |
| 60 | errorType: nil, |
| 61 | unwrappedErrorPtr: &unwrappedErrcodeError, |
| 62 | errorCode: &errcode.ErrorCodeUnauthorized, |
| 63 | }, |
| 64 | { // docker.io when an image is not found |
| 65 | name: "GET https://registry-1.docker.io/v2/library/this-does-not-exist/manifests/latest", |
| 66 | response: "HTTP/1.1 401 Unauthorized\r\n" + |
| 67 | "Connection: close\r\n" + |
| 68 | "Content-Length: 170\r\n" + |
| 69 | "Content-Type: application/json\r\n" + |
| 70 | "Date: Thu, 12 Aug 2021 20:11:01 GMT\r\n" + |
| 71 | "Docker-Distribution-Api-Version: registry/2.0\r\n" + |
| 72 | "Strict-Transport-Security: max-age=31536000\r\n" + |
| 73 | "Www-Authenticate: Bearer realm=\"https://auth.docker.io/token\",service=\"registry.docker.io\",scope=\"repository:library/this-does-not-exist:pull\",error=\"insufficient_scope\"\r\n" + |
| 74 | "\r\n" + |
| 75 | "{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"authentication required\",\"detail\":[{\"Type\":\"repository\",\"Class\":\"\",\"Name\":\"library/this-does-not-exist\",\"Action\":\"pull\"}]}]}\n", |
nothing calls this directly
no test coverage detected
searching dependent graphs…