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