github.com/sams1990/dockerrepo@v17.12.1-ce-rc2+incompatible/builder/remotecontext/remote_test.go (about) 1 package remotecontext 2 3 import ( 4 "bytes" 5 "io" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "net/url" 10 "testing" 11 12 "github.com/docker/docker/builder" 13 "github.com/docker/docker/internal/testutil" 14 "github.com/gotestyourself/gotestyourself/fs" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 var binaryContext = []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00} //xz magic 20 21 func TestSelectAcceptableMIME(t *testing.T) { 22 validMimeStrings := []string{ 23 "application/x-bzip2", 24 "application/bzip2", 25 "application/gzip", 26 "application/x-gzip", 27 "application/x-xz", 28 "application/xz", 29 "application/tar", 30 "application/x-tar", 31 "application/octet-stream", 32 "text/plain", 33 } 34 35 invalidMimeStrings := []string{ 36 "", 37 "application/octet", 38 "application/json", 39 } 40 41 for _, m := range invalidMimeStrings { 42 if len(selectAcceptableMIME(m)) > 0 { 43 t.Fatalf("Should not have accepted %q", m) 44 } 45 } 46 47 for _, m := range validMimeStrings { 48 if str := selectAcceptableMIME(m); str == "" { 49 t.Fatalf("Should have accepted %q", m) 50 } 51 } 52 } 53 54 func TestInspectEmptyResponse(t *testing.T) { 55 ct := "application/octet-stream" 56 br := ioutil.NopCloser(bytes.NewReader([]byte(""))) 57 contentType, bReader, err := inspectResponse(ct, br, 0) 58 if err == nil { 59 t.Fatal("Should have generated an error for an empty response") 60 } 61 if contentType != "application/octet-stream" { 62 t.Fatalf("Content type should be 'application/octet-stream' but is %q", contentType) 63 } 64 body, err := ioutil.ReadAll(bReader) 65 if err != nil { 66 t.Fatal(err) 67 } 68 if len(body) != 0 { 69 t.Fatal("response body should remain empty") 70 } 71 } 72 73 func TestInspectResponseBinary(t *testing.T) { 74 ct := "application/octet-stream" 75 br := ioutil.NopCloser(bytes.NewReader(binaryContext)) 76 contentType, bReader, err := inspectResponse(ct, br, int64(len(binaryContext))) 77 if err != nil { 78 t.Fatal(err) 79 } 80 if contentType != "application/octet-stream" { 81 t.Fatalf("Content type should be 'application/octet-stream' but is %q", contentType) 82 } 83 body, err := ioutil.ReadAll(bReader) 84 if err != nil { 85 t.Fatal(err) 86 } 87 if len(body) != len(binaryContext) { 88 t.Fatalf("Wrong response size %d, should be == len(binaryContext)", len(body)) 89 } 90 for i := range body { 91 if body[i] != binaryContext[i] { 92 t.Fatalf("Corrupted response body at byte index %d", i) 93 } 94 } 95 } 96 97 func TestResponseUnsupportedContentType(t *testing.T) { 98 content := []byte(dockerfileContents) 99 ct := "application/json" 100 br := ioutil.NopCloser(bytes.NewReader(content)) 101 contentType, bReader, err := inspectResponse(ct, br, int64(len(dockerfileContents))) 102 103 if err == nil { 104 t.Fatal("Should have returned an error on content-type 'application/json'") 105 } 106 if contentType != ct { 107 t.Fatalf("Should not have altered content-type: orig: %s, altered: %s", ct, contentType) 108 } 109 body, err := ioutil.ReadAll(bReader) 110 if err != nil { 111 t.Fatal(err) 112 } 113 if string(body) != dockerfileContents { 114 t.Fatalf("Corrupted response body %s", body) 115 } 116 } 117 118 func TestInspectResponseTextSimple(t *testing.T) { 119 content := []byte(dockerfileContents) 120 ct := "text/plain" 121 br := ioutil.NopCloser(bytes.NewReader(content)) 122 contentType, bReader, err := inspectResponse(ct, br, int64(len(content))) 123 if err != nil { 124 t.Fatal(err) 125 } 126 if contentType != "text/plain" { 127 t.Fatalf("Content type should be 'text/plain' but is %q", contentType) 128 } 129 body, err := ioutil.ReadAll(bReader) 130 if err != nil { 131 t.Fatal(err) 132 } 133 if string(body) != dockerfileContents { 134 t.Fatalf("Corrupted response body %s", body) 135 } 136 } 137 138 func TestInspectResponseEmptyContentType(t *testing.T) { 139 content := []byte(dockerfileContents) 140 br := ioutil.NopCloser(bytes.NewReader(content)) 141 contentType, bodyReader, err := inspectResponse("", br, int64(len(content))) 142 if err != nil { 143 t.Fatal(err) 144 } 145 if contentType != "text/plain" { 146 t.Fatalf("Content type should be 'text/plain' but is %q", contentType) 147 } 148 body, err := ioutil.ReadAll(bodyReader) 149 if err != nil { 150 t.Fatal(err) 151 } 152 if string(body) != dockerfileContents { 153 t.Fatalf("Corrupted response body %s", body) 154 } 155 } 156 157 func TestUnknownContentLength(t *testing.T) { 158 content := []byte(dockerfileContents) 159 ct := "text/plain" 160 br := ioutil.NopCloser(bytes.NewReader(content)) 161 contentType, bReader, err := inspectResponse(ct, br, -1) 162 if err != nil { 163 t.Fatal(err) 164 } 165 if contentType != "text/plain" { 166 t.Fatalf("Content type should be 'text/plain' but is %q", contentType) 167 } 168 body, err := ioutil.ReadAll(bReader) 169 if err != nil { 170 t.Fatal(err) 171 } 172 if string(body) != dockerfileContents { 173 t.Fatalf("Corrupted response body %s", body) 174 } 175 } 176 177 func TestDownloadRemote(t *testing.T) { 178 contextDir := fs.NewDir(t, "test-builder-download-remote", 179 fs.WithFile(builder.DefaultDockerfileName, dockerfileContents)) 180 defer contextDir.Remove() 181 182 mux := http.NewServeMux() 183 server := httptest.NewServer(mux) 184 serverURL, _ := url.Parse(server.URL) 185 186 serverURL.Path = "/" + builder.DefaultDockerfileName 187 remoteURL := serverURL.String() 188 189 mux.Handle("/", http.FileServer(http.Dir(contextDir.Path()))) 190 191 contentType, content, err := downloadRemote(remoteURL) 192 require.NoError(t, err) 193 194 assert.Equal(t, mimeTypes.TextPlain, contentType) 195 raw, err := ioutil.ReadAll(content) 196 require.NoError(t, err) 197 assert.Equal(t, dockerfileContents, string(raw)) 198 } 199 200 func TestGetWithStatusError(t *testing.T) { 201 var testcases = []struct { 202 err error 203 statusCode int 204 expectedErr string 205 expectedBody string 206 }{ 207 { 208 statusCode: 200, 209 expectedBody: "THE BODY", 210 }, 211 { 212 statusCode: 400, 213 expectedErr: "with status 400 Bad Request: broke", 214 expectedBody: "broke", 215 }, 216 } 217 for _, testcase := range testcases { 218 ts := httptest.NewServer( 219 http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 220 buffer := bytes.NewBufferString(testcase.expectedBody) 221 w.WriteHeader(testcase.statusCode) 222 w.Write(buffer.Bytes()) 223 }), 224 ) 225 defer ts.Close() 226 response, err := GetWithStatusError(ts.URL) 227 228 if testcase.expectedErr == "" { 229 require.NoError(t, err) 230 231 body, err := readBody(response.Body) 232 require.NoError(t, err) 233 assert.Contains(t, string(body), testcase.expectedBody) 234 } else { 235 testutil.ErrorContains(t, err, testcase.expectedErr) 236 } 237 } 238 } 239 240 func readBody(b io.ReadCloser) ([]byte, error) { 241 defer b.Close() 242 return ioutil.ReadAll(b) 243 }