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