github.com/LazyboyChen7/engine@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  }