github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/integration-cli/docker_api_build_test.go (about)

     1  package main
     2  
     3  import (
     4  	"archive/tar"
     5  	"bytes"
     6  	"net/http"
     7  	"regexp"
     8  	"strings"
     9  
    10  	"github.com/docker/docker/pkg/integration/checker"
    11  	"github.com/go-check/check"
    12  )
    13  
    14  func (s *DockerSuite) TestBuildAPIDockerFileRemote(c *check.C) {
    15  	testRequires(c, NotUserNamespace)
    16  	var testD string
    17  	if daemonPlatform == "windows" {
    18  		testD = `FROM busybox
    19  COPY * /tmp/
    20  RUN find / -name ba*
    21  RUN find /tmp/`
    22  	} else {
    23  		// -xdev is required because sysfs can cause EPERM
    24  		testD = `FROM busybox
    25  COPY * /tmp/
    26  RUN find / -xdev -name ba*
    27  RUN find /tmp/`
    28  	}
    29  	server, err := fakeStorage(map[string]string{"testD": testD})
    30  	c.Assert(err, checker.IsNil)
    31  	defer server.Close()
    32  
    33  	res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json")
    34  	c.Assert(err, checker.IsNil)
    35  	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
    36  
    37  	buf, err := readBody(body)
    38  	c.Assert(err, checker.IsNil)
    39  
    40  	// Make sure Dockerfile exists.
    41  	// Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL
    42  	out := string(buf)
    43  	c.Assert(out, checker.Contains, "/tmp/Dockerfile")
    44  	c.Assert(out, checker.Not(checker.Contains), "baz")
    45  }
    46  
    47  func (s *DockerSuite) TestBuildAPIRemoteTarballContext(c *check.C) {
    48  	buffer := new(bytes.Buffer)
    49  	tw := tar.NewWriter(buffer)
    50  	defer tw.Close()
    51  
    52  	dockerfile := []byte("FROM busybox")
    53  	err := tw.WriteHeader(&tar.Header{
    54  		Name: "Dockerfile",
    55  		Size: int64(len(dockerfile)),
    56  	})
    57  	// failed to write tar file header
    58  	c.Assert(err, checker.IsNil)
    59  
    60  	_, err = tw.Write(dockerfile)
    61  	// failed to write tar file content
    62  	c.Assert(err, checker.IsNil)
    63  
    64  	// failed to close tar archive
    65  	c.Assert(tw.Close(), checker.IsNil)
    66  
    67  	server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
    68  		"testT.tar": buffer,
    69  	})
    70  	c.Assert(err, checker.IsNil)
    71  
    72  	defer server.Close()
    73  
    74  	res, b, err := sockRequestRaw("POST", "/build?remote="+server.URL()+"/testT.tar", nil, "application/tar")
    75  	c.Assert(err, checker.IsNil)
    76  	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
    77  	b.Close()
    78  }
    79  
    80  func (s *DockerSuite) TestBuildAPIRemoteTarballContextWithCustomDockerfile(c *check.C) {
    81  	buffer := new(bytes.Buffer)
    82  	tw := tar.NewWriter(buffer)
    83  	defer tw.Close()
    84  
    85  	dockerfile := []byte(`FROM busybox
    86  RUN echo 'wrong'`)
    87  	err := tw.WriteHeader(&tar.Header{
    88  		Name: "Dockerfile",
    89  		Size: int64(len(dockerfile)),
    90  	})
    91  	// failed to write tar file header
    92  	c.Assert(err, checker.IsNil)
    93  
    94  	_, err = tw.Write(dockerfile)
    95  	// failed to write tar file content
    96  	c.Assert(err, checker.IsNil)
    97  
    98  	custom := []byte(`FROM busybox
    99  RUN echo 'right'
   100  `)
   101  	err = tw.WriteHeader(&tar.Header{
   102  		Name: "custom",
   103  		Size: int64(len(custom)),
   104  	})
   105  
   106  	// failed to write tar file header
   107  	c.Assert(err, checker.IsNil)
   108  
   109  	_, err = tw.Write(custom)
   110  	// failed to write tar file content
   111  	c.Assert(err, checker.IsNil)
   112  
   113  	// failed to close tar archive
   114  	c.Assert(tw.Close(), checker.IsNil)
   115  
   116  	server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
   117  		"testT.tar": buffer,
   118  	})
   119  	c.Assert(err, checker.IsNil)
   120  
   121  	defer server.Close()
   122  	url := "/build?dockerfile=custom&remote=" + server.URL() + "/testT.tar"
   123  	res, body, err := sockRequestRaw("POST", url, nil, "application/tar")
   124  	c.Assert(err, checker.IsNil)
   125  	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
   126  
   127  	defer body.Close()
   128  	content, err := readBody(body)
   129  	c.Assert(err, checker.IsNil)
   130  
   131  	// Build used the wrong dockerfile.
   132  	c.Assert(string(content), checker.Not(checker.Contains), "wrong")
   133  }
   134  
   135  func (s *DockerSuite) TestBuildAPILowerDockerfile(c *check.C) {
   136  	git, err := newFakeGit("repo", map[string]string{
   137  		"dockerfile": `FROM busybox
   138  RUN echo from dockerfile`,
   139  	}, false)
   140  	c.Assert(err, checker.IsNil)
   141  	defer git.Close()
   142  
   143  	res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
   144  	c.Assert(err, checker.IsNil)
   145  	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
   146  
   147  	buf, err := readBody(body)
   148  	c.Assert(err, checker.IsNil)
   149  
   150  	out := string(buf)
   151  	c.Assert(out, checker.Contains, "from dockerfile")
   152  }
   153  
   154  func (s *DockerSuite) TestBuildAPIBuildGitWithF(c *check.C) {
   155  	git, err := newFakeGit("repo", map[string]string{
   156  		"baz": `FROM busybox
   157  RUN echo from baz`,
   158  		"Dockerfile": `FROM busybox
   159  RUN echo from Dockerfile`,
   160  	}, false)
   161  	c.Assert(err, checker.IsNil)
   162  	defer git.Close()
   163  
   164  	// Make sure it tries to 'dockerfile' query param value
   165  	res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json")
   166  	c.Assert(err, checker.IsNil)
   167  	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
   168  
   169  	buf, err := readBody(body)
   170  	c.Assert(err, checker.IsNil)
   171  
   172  	out := string(buf)
   173  	c.Assert(out, checker.Contains, "from baz")
   174  }
   175  
   176  func (s *DockerSuite) TestBuildAPIDoubleDockerfile(c *check.C) {
   177  	testRequires(c, UnixCli) // dockerfile overwrites Dockerfile on Windows
   178  	git, err := newFakeGit("repo", map[string]string{
   179  		"Dockerfile": `FROM busybox
   180  RUN echo from Dockerfile`,
   181  		"dockerfile": `FROM busybox
   182  RUN echo from dockerfile`,
   183  	}, false)
   184  	c.Assert(err, checker.IsNil)
   185  	defer git.Close()
   186  
   187  	// Make sure it tries to 'dockerfile' query param value
   188  	res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
   189  	c.Assert(err, checker.IsNil)
   190  	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
   191  
   192  	buf, err := readBody(body)
   193  	c.Assert(err, checker.IsNil)
   194  
   195  	out := string(buf)
   196  	c.Assert(out, checker.Contains, "from Dockerfile")
   197  }
   198  
   199  func (s *DockerSuite) TestBuildAPIUnnormalizedTarPaths(c *check.C) {
   200  	// Make sure that build context tars with entries of the form
   201  	// x/./y don't cause caching false positives.
   202  
   203  	buildFromTarContext := func(fileContents []byte) string {
   204  		buffer := new(bytes.Buffer)
   205  		tw := tar.NewWriter(buffer)
   206  		defer tw.Close()
   207  
   208  		dockerfile := []byte(`FROM busybox
   209  	COPY dir /dir/`)
   210  		err := tw.WriteHeader(&tar.Header{
   211  			Name: "Dockerfile",
   212  			Size: int64(len(dockerfile)),
   213  		})
   214  		//failed to write tar file header
   215  		c.Assert(err, checker.IsNil)
   216  
   217  		_, err = tw.Write(dockerfile)
   218  		// failed to write Dockerfile in tar file content
   219  		c.Assert(err, checker.IsNil)
   220  
   221  		err = tw.WriteHeader(&tar.Header{
   222  			Name: "dir/./file",
   223  			Size: int64(len(fileContents)),
   224  		})
   225  		//failed to write tar file header
   226  		c.Assert(err, checker.IsNil)
   227  
   228  		_, err = tw.Write(fileContents)
   229  		// failed to write file contents in tar file content
   230  		c.Assert(err, checker.IsNil)
   231  
   232  		// failed to close tar archive
   233  		c.Assert(tw.Close(), checker.IsNil)
   234  
   235  		res, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
   236  		c.Assert(err, checker.IsNil)
   237  		c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
   238  
   239  		out, err := readBody(body)
   240  		c.Assert(err, checker.IsNil)
   241  		lines := strings.Split(string(out), "\n")
   242  		c.Assert(len(lines), checker.GreaterThan, 1)
   243  		c.Assert(lines[len(lines)-2], checker.Matches, ".*Successfully built [0-9a-f]{12}.*")
   244  
   245  		re := regexp.MustCompile("Successfully built ([0-9a-f]{12})")
   246  		matches := re.FindStringSubmatch(lines[len(lines)-2])
   247  		return matches[1]
   248  	}
   249  
   250  	imageA := buildFromTarContext([]byte("abc"))
   251  	imageB := buildFromTarContext([]byte("def"))
   252  
   253  	c.Assert(imageA, checker.Not(checker.Equals), imageB)
   254  }