github.com/adxhyt/docker@v1.4.2-0.20150117221845-467b7c821390/integration-cli/docker_cli_build_test.go (about)

     1  package main
     2  
     3  import (
     4  	"archive/tar"
     5  	"bytes"
     6  	"encoding/json"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"os/exec"
    11  	"path"
    12  	"path/filepath"
    13  	"reflect"
    14  	"regexp"
    15  	"strconv"
    16  	"strings"
    17  	"syscall"
    18  	"testing"
    19  	"text/template"
    20  	"time"
    21  
    22  	"github.com/docker/docker/pkg/archive"
    23  )
    24  
    25  func TestBuildJSONEmptyRun(t *testing.T) {
    26  	name := "testbuildjsonemptyrun"
    27  	defer deleteImages(name)
    28  
    29  	_, err := buildImage(
    30  		name,
    31  		`
    32      FROM busybox
    33      RUN []
    34      `,
    35  		true)
    36  
    37  	if err != nil {
    38  		t.Fatal("error when dealing with a RUN statement with empty JSON array")
    39  	}
    40  
    41  	logDone("build - RUN with an empty array should not panic")
    42  }
    43  
    44  func TestBuildEmptyWhitespace(t *testing.T) {
    45  	name := "testbuildemptywhitespace"
    46  	defer deleteImages(name)
    47  
    48  	_, err := buildImage(
    49  		name,
    50  		`
    51      FROM busybox
    52      RUN 
    53        quux \
    54        bar
    55      `,
    56  		true)
    57  
    58  	if err == nil {
    59  		t.Fatal("no error when dealing with a RUN statement with no content on the same line")
    60  	}
    61  
    62  	logDone("build - statements with whitespace and no content should generate a parse error")
    63  }
    64  
    65  func TestBuildShCmdJSONEntrypoint(t *testing.T) {
    66  	name := "testbuildshcmdjsonentrypoint"
    67  	defer deleteImages(name)
    68  
    69  	_, err := buildImage(
    70  		name,
    71  		`
    72      FROM busybox
    73      ENTRYPOINT ["/bin/echo"]
    74      CMD echo test
    75      `,
    76  		true)
    77  
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  
    82  	out, _, err := runCommandWithOutput(
    83  		exec.Command(
    84  			dockerBinary,
    85  			"run",
    86  			"--rm",
    87  			name))
    88  
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  
    93  	if strings.TrimSpace(out) != "/bin/sh -c echo test" {
    94  		t.Fatal("CMD did not contain /bin/sh -c")
    95  	}
    96  
    97  	logDone("build - CMD should always contain /bin/sh -c when specified without JSON")
    98  }
    99  
   100  func TestBuildEnvironmentReplacementUser(t *testing.T) {
   101  	name := "testbuildenvironmentreplacement"
   102  	defer deleteImages(name)
   103  
   104  	_, err := buildImage(name, `
   105    FROM scratch
   106    ENV user foo
   107    USER ${user}
   108    `, true)
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  
   113  	res, err := inspectFieldJSON(name, "Config.User")
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  
   118  	if res != `"foo"` {
   119  		t.Fatal("User foo from environment not in Config.User on image")
   120  	}
   121  
   122  	logDone("build - user environment replacement")
   123  }
   124  
   125  func TestBuildEnvironmentReplacementVolume(t *testing.T) {
   126  	name := "testbuildenvironmentreplacement"
   127  	defer deleteImages(name)
   128  
   129  	_, err := buildImage(name, `
   130    FROM scratch
   131    ENV volume /quux
   132    VOLUME ${volume}
   133    `, true)
   134  	if err != nil {
   135  		t.Fatal(err)
   136  	}
   137  
   138  	res, err := inspectFieldJSON(name, "Config.Volumes")
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  
   143  	var volumes map[string]interface{}
   144  
   145  	if err := json.Unmarshal([]byte(res), &volumes); err != nil {
   146  		t.Fatal(err)
   147  	}
   148  
   149  	if _, ok := volumes["/quux"]; !ok {
   150  		t.Fatal("Volume /quux from environment not in Config.Volumes on image")
   151  	}
   152  
   153  	logDone("build - volume environment replacement")
   154  }
   155  
   156  func TestBuildEnvironmentReplacementExpose(t *testing.T) {
   157  	name := "testbuildenvironmentreplacement"
   158  	defer deleteImages(name)
   159  
   160  	_, err := buildImage(name, `
   161    FROM scratch
   162    ENV port 80
   163    EXPOSE ${port}
   164    `, true)
   165  	if err != nil {
   166  		t.Fatal(err)
   167  	}
   168  
   169  	res, err := inspectFieldJSON(name, "Config.ExposedPorts")
   170  	if err != nil {
   171  		t.Fatal(err)
   172  	}
   173  
   174  	var exposedPorts map[string]interface{}
   175  
   176  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
   177  		t.Fatal(err)
   178  	}
   179  
   180  	if _, ok := exposedPorts["80/tcp"]; !ok {
   181  		t.Fatal("Exposed port 80 from environment not in Config.ExposedPorts on image")
   182  	}
   183  
   184  	logDone("build - expose environment replacement")
   185  }
   186  
   187  func TestBuildEnvironmentReplacementWorkdir(t *testing.T) {
   188  	name := "testbuildenvironmentreplacement"
   189  	defer deleteImages(name)
   190  
   191  	_, err := buildImage(name, `
   192    FROM busybox
   193    ENV MYWORKDIR /work
   194    RUN mkdir ${MYWORKDIR}
   195    WORKDIR ${MYWORKDIR}
   196    `, true)
   197  
   198  	if err != nil {
   199  		t.Fatal(err)
   200  	}
   201  
   202  	logDone("build - workdir environment replacement")
   203  }
   204  
   205  func TestBuildEnvironmentReplacementAddCopy(t *testing.T) {
   206  	name := "testbuildenvironmentreplacement"
   207  	defer deleteImages(name)
   208  
   209  	ctx, err := fakeContext(`
   210    FROM scratch
   211    ENV baz foo
   212    ENV quux bar
   213    ENV dot .
   214  
   215    ADD ${baz} ${dot}
   216    COPY ${quux} ${dot}
   217    `,
   218  		map[string]string{
   219  			"foo": "test1",
   220  			"bar": "test2",
   221  		})
   222  
   223  	if err != nil {
   224  		t.Fatal(err)
   225  	}
   226  	defer ctx.Close()
   227  
   228  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   229  		t.Fatal(err)
   230  	}
   231  
   232  	logDone("build - add/copy environment replacement")
   233  }
   234  
   235  func TestBuildEnvironmentReplacementEnv(t *testing.T) {
   236  	name := "testbuildenvironmentreplacement"
   237  
   238  	defer deleteImages(name)
   239  
   240  	_, err := buildImage(name,
   241  		`
   242    FROM scratch
   243    ENV foo foo
   244    ENV bar ${foo}
   245    `, true)
   246  
   247  	if err != nil {
   248  		t.Fatal(err)
   249  	}
   250  
   251  	res, err := inspectFieldJSON(name, "Config.Env")
   252  	if err != nil {
   253  		t.Fatal(err)
   254  	}
   255  
   256  	envResult := []string{}
   257  
   258  	if err = unmarshalJSON([]byte(res), &envResult); err != nil {
   259  		t.Fatal(err)
   260  	}
   261  
   262  	found := false
   263  
   264  	for _, env := range envResult {
   265  		parts := strings.SplitN(env, "=", 2)
   266  		if parts[0] == "bar" {
   267  			found = true
   268  			if parts[1] != "foo" {
   269  				t.Fatalf("Could not find replaced var for env `bar`: got %q instead of `foo`", parts[1])
   270  			}
   271  		}
   272  	}
   273  
   274  	if !found {
   275  		t.Fatal("Never found the `bar` env variable")
   276  	}
   277  
   278  	logDone("build - env environment replacement")
   279  }
   280  
   281  func TestBuildHandleEscapes(t *testing.T) {
   282  	name := "testbuildhandleescapes"
   283  
   284  	defer deleteImages(name)
   285  
   286  	_, err := buildImage(name,
   287  		`
   288    FROM scratch
   289    ENV FOO bar
   290    VOLUME ${FOO}
   291    `, true)
   292  
   293  	if err != nil {
   294  		t.Fatal(err)
   295  	}
   296  
   297  	var result map[string]map[string]struct{}
   298  
   299  	res, err := inspectFieldJSON(name, "Config.Volumes")
   300  	if err != nil {
   301  		t.Fatal(err)
   302  	}
   303  
   304  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   305  		t.Fatal(err)
   306  	}
   307  
   308  	if _, ok := result["bar"]; !ok {
   309  		t.Fatal("Could not find volume bar set from env foo in volumes table")
   310  	}
   311  
   312  	deleteImages(name)
   313  
   314  	_, err = buildImage(name,
   315  		`
   316    FROM scratch
   317    ENV FOO bar
   318    VOLUME \${FOO}
   319    `, true)
   320  
   321  	if err != nil {
   322  		t.Fatal(err)
   323  	}
   324  
   325  	res, err = inspectFieldJSON(name, "Config.Volumes")
   326  	if err != nil {
   327  		t.Fatal(err)
   328  	}
   329  
   330  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   331  		t.Fatal(err)
   332  	}
   333  
   334  	if _, ok := result["${FOO}"]; !ok {
   335  		t.Fatal("Could not find volume ${FOO} set from env foo in volumes table")
   336  	}
   337  
   338  	deleteImages(name)
   339  
   340  	// this test in particular provides *7* backslashes and expects 6 to come back.
   341  	// Like above, the first escape is swallowed and the rest are treated as
   342  	// literals, this one is just less obvious because of all the character noise.
   343  
   344  	_, err = buildImage(name,
   345  		`
   346    FROM scratch
   347    ENV FOO bar
   348    VOLUME \\\\\\\${FOO}
   349    `, true)
   350  
   351  	if err != nil {
   352  		t.Fatal(err)
   353  	}
   354  
   355  	res, err = inspectFieldJSON(name, "Config.Volumes")
   356  	if err != nil {
   357  		t.Fatal(err)
   358  	}
   359  
   360  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   361  		t.Fatal(err)
   362  	}
   363  
   364  	if _, ok := result[`\\\\\\${FOO}`]; !ok {
   365  		t.Fatal(`Could not find volume \\\\\\${FOO} set from env foo in volumes table`)
   366  	}
   367  
   368  	logDone("build - handle escapes")
   369  }
   370  
   371  func TestBuildOnBuildLowercase(t *testing.T) {
   372  	name := "testbuildonbuildlowercase"
   373  	name2 := "testbuildonbuildlowercase2"
   374  
   375  	defer deleteImages(name, name2)
   376  
   377  	_, err := buildImage(name,
   378  		`
   379    FROM busybox
   380    onbuild run echo quux
   381    `, true)
   382  
   383  	if err != nil {
   384  		t.Fatal(err)
   385  	}
   386  
   387  	_, out, err := buildImageWithOut(name2, fmt.Sprintf(`
   388    FROM %s
   389    `, name), true)
   390  
   391  	if err != nil {
   392  		t.Fatal(err)
   393  	}
   394  
   395  	if !strings.Contains(out, "quux") {
   396  		t.Fatalf("Did not receive the expected echo text, got %s", out)
   397  	}
   398  
   399  	if strings.Contains(out, "ONBUILD ONBUILD") {
   400  		t.Fatalf("Got an ONBUILD ONBUILD error with no error: got %s", out)
   401  	}
   402  
   403  	logDone("build - handle case-insensitive onbuild statement")
   404  }
   405  
   406  func TestBuildEnvEscapes(t *testing.T) {
   407  	name := "testbuildenvescapes"
   408  	defer deleteImages(name)
   409  	defer deleteAllContainers()
   410  	_, err := buildImage(name,
   411  		`
   412      FROM busybox
   413      ENV TEST foo
   414      CMD echo \$
   415      `,
   416  		true)
   417  
   418  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name))
   419  
   420  	if err != nil {
   421  		t.Fatal(err)
   422  	}
   423  
   424  	if strings.TrimSpace(out) != "$" {
   425  		t.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
   426  	}
   427  
   428  	logDone("build - env should handle \\$ properly")
   429  }
   430  
   431  func TestBuildEnvOverwrite(t *testing.T) {
   432  	name := "testbuildenvoverwrite"
   433  	defer deleteImages(name)
   434  	defer deleteAllContainers()
   435  
   436  	_, err := buildImage(name,
   437  		`
   438      FROM busybox
   439      ENV TEST foo
   440      CMD echo ${TEST}
   441      `,
   442  		true)
   443  
   444  	if err != nil {
   445  		t.Fatal(err)
   446  	}
   447  
   448  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-e", "TEST=bar", "-t", name))
   449  
   450  	if err != nil {
   451  		t.Fatal(err)
   452  	}
   453  
   454  	if strings.TrimSpace(out) != "bar" {
   455  		t.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
   456  	}
   457  
   458  	logDone("build - env should overwrite builder ENV during run")
   459  }
   460  
   461  func TestBuildOnBuildForbiddenMaintainerInSourceImage(t *testing.T) {
   462  	name := "testbuildonbuildforbiddenmaintainerinsourceimage"
   463  	defer deleteImages("onbuild")
   464  	defer deleteImages(name)
   465  	defer deleteAllContainers()
   466  
   467  	createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
   468  	out, _, _, err := runCommandWithStdoutStderr(createCmd)
   469  	if err != nil {
   470  		t.Fatal(out, err)
   471  	}
   472  
   473  	cleanedContainerID := stripTrailingCharacters(out)
   474  
   475  	commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"MAINTAINER docker.io\"]}", cleanedContainerID, "onbuild")
   476  
   477  	if _, err := runCommand(commitCmd); err != nil {
   478  		t.Fatal(err)
   479  	}
   480  
   481  	_, err = buildImage(name,
   482  		`FROM onbuild`,
   483  		true)
   484  	if err != nil {
   485  		if !strings.Contains(err.Error(), "maintainer isn't allowed as an ONBUILD trigger") {
   486  			t.Fatalf("Wrong error %v, must be about MAINTAINER and ONBUILD in source image", err)
   487  		}
   488  	} else {
   489  		t.Fatal("Error must not be nil")
   490  	}
   491  	logDone("build - onbuild forbidden maintainer in source image")
   492  
   493  }
   494  
   495  func TestBuildOnBuildForbiddenFromInSourceImage(t *testing.T) {
   496  	name := "testbuildonbuildforbiddenfrominsourceimage"
   497  	defer deleteImages("onbuild")
   498  	defer deleteImages(name)
   499  	defer deleteAllContainers()
   500  
   501  	createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
   502  	out, _, _, err := runCommandWithStdoutStderr(createCmd)
   503  	if err != nil {
   504  		t.Fatal(out, err)
   505  	}
   506  
   507  	cleanedContainerID := stripTrailingCharacters(out)
   508  
   509  	commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"FROM busybox\"]}", cleanedContainerID, "onbuild")
   510  
   511  	if _, err := runCommand(commitCmd); err != nil {
   512  		t.Fatal(err)
   513  	}
   514  
   515  	_, err = buildImage(name,
   516  		`FROM onbuild`,
   517  		true)
   518  	if err != nil {
   519  		if !strings.Contains(err.Error(), "from isn't allowed as an ONBUILD trigger") {
   520  			t.Fatalf("Wrong error %v, must be about FROM and ONBUILD in source image", err)
   521  		}
   522  	} else {
   523  		t.Fatal("Error must not be nil")
   524  	}
   525  	logDone("build - onbuild forbidden from in source image")
   526  
   527  }
   528  
   529  func TestBuildOnBuildForbiddenChainedInSourceImage(t *testing.T) {
   530  	name := "testbuildonbuildforbiddenchainedinsourceimage"
   531  	defer deleteImages("onbuild")
   532  	defer deleteImages(name)
   533  	defer deleteAllContainers()
   534  
   535  	createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
   536  	out, _, _, err := runCommandWithStdoutStderr(createCmd)
   537  	if err != nil {
   538  		t.Fatal(out, err)
   539  	}
   540  
   541  	cleanedContainerID := stripTrailingCharacters(out)
   542  
   543  	commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"ONBUILD RUN ls\"]}", cleanedContainerID, "onbuild")
   544  
   545  	if _, err := runCommand(commitCmd); err != nil {
   546  		t.Fatal(err)
   547  	}
   548  
   549  	_, err = buildImage(name,
   550  		`FROM onbuild`,
   551  		true)
   552  	if err != nil {
   553  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
   554  			t.Fatalf("Wrong error %v, must be about chaining ONBUILD in source image", err)
   555  		}
   556  	} else {
   557  		t.Fatal("Error must not be nil")
   558  	}
   559  	logDone("build - onbuild forbidden chained in source image")
   560  
   561  }
   562  
   563  func TestBuildOnBuildCmdEntrypointJSON(t *testing.T) {
   564  	name1 := "onbuildcmd"
   565  	name2 := "onbuildgenerated"
   566  
   567  	defer deleteImages(name2)
   568  	defer deleteImages(name1)
   569  	defer deleteAllContainers()
   570  
   571  	_, err := buildImage(name1, `
   572  FROM busybox
   573  ONBUILD CMD ["hello world"]
   574  ONBUILD ENTRYPOINT ["echo"]
   575  ONBUILD RUN ["true"]`,
   576  		false)
   577  
   578  	if err != nil {
   579  		t.Fatal(err)
   580  	}
   581  
   582  	_, err = buildImage(name2, fmt.Sprintf(`FROM %s`, name1), false)
   583  
   584  	if err != nil {
   585  		t.Fatal(err)
   586  	}
   587  
   588  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
   589  	if err != nil {
   590  		t.Fatal(err)
   591  	}
   592  
   593  	if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
   594  		t.Fatal("did not get echo output from onbuild", out)
   595  	}
   596  
   597  	logDone("build - onbuild with json entrypoint/cmd")
   598  }
   599  
   600  func TestBuildOnBuildEntrypointJSON(t *testing.T) {
   601  	name1 := "onbuildcmd"
   602  	name2 := "onbuildgenerated"
   603  
   604  	defer deleteImages(name2)
   605  	defer deleteImages(name1)
   606  	defer deleteAllContainers()
   607  
   608  	_, err := buildImage(name1, `
   609  FROM busybox
   610  ONBUILD ENTRYPOINT ["echo"]`,
   611  		false)
   612  
   613  	if err != nil {
   614  		t.Fatal(err)
   615  	}
   616  
   617  	_, err = buildImage(name2, fmt.Sprintf("FROM %s\nCMD [\"hello world\"]\n", name1), false)
   618  
   619  	if err != nil {
   620  		t.Fatal(err)
   621  	}
   622  
   623  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
   624  	if err != nil {
   625  		t.Fatal(err)
   626  	}
   627  
   628  	if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
   629  		t.Fatal("got malformed output from onbuild", out)
   630  	}
   631  
   632  	logDone("build - onbuild with json entrypoint")
   633  }
   634  
   635  func TestBuildCacheADD(t *testing.T) {
   636  	name := "testbuildtwoimageswithadd"
   637  	defer deleteImages(name)
   638  	server, err := fakeStorage(map[string]string{
   639  		"robots.txt": "hello",
   640  		"index.html": "world",
   641  	})
   642  	if err != nil {
   643  		t.Fatal(err)
   644  	}
   645  	defer server.Close()
   646  	if _, err := buildImage(name,
   647  		fmt.Sprintf(`FROM scratch
   648  		ADD %s/robots.txt /`, server.URL),
   649  		true); err != nil {
   650  		t.Fatal(err)
   651  	}
   652  	if err != nil {
   653  		t.Fatal(err)
   654  	}
   655  	deleteImages(name)
   656  	_, out, err := buildImageWithOut(name,
   657  		fmt.Sprintf(`FROM scratch
   658  		ADD %s/index.html /`, server.URL),
   659  		true)
   660  	if err != nil {
   661  		t.Fatal(err)
   662  	}
   663  	if strings.Contains(out, "Using cache") {
   664  		t.Fatal("2nd build used cache on ADD, it shouldn't")
   665  	}
   666  
   667  	logDone("build - build two images with remote ADD")
   668  }
   669  
   670  func TestBuildSixtySteps(t *testing.T) {
   671  	name := "foobuildsixtysteps"
   672  	defer deleteImages(name)
   673  	ctx, err := fakeContext("FROM scratch\n"+strings.Repeat("ADD foo /\n", 60),
   674  		map[string]string{
   675  			"foo": "test1",
   676  		})
   677  	if err != nil {
   678  		t.Fatal(err)
   679  	}
   680  	defer ctx.Close()
   681  
   682  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   683  		t.Fatal(err)
   684  	}
   685  	logDone("build - build an image with sixty build steps")
   686  }
   687  
   688  func TestBuildAddSingleFileToRoot(t *testing.T) {
   689  	name := "testaddimg"
   690  	defer deleteImages(name)
   691  	ctx, err := fakeContext(`FROM busybox
   692  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   693  RUN echo 'dockerio:x:1001:' >> /etc/group
   694  RUN touch /exists
   695  RUN chown dockerio.dockerio /exists
   696  ADD test_file /
   697  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
   698  RUN [ $(ls -l /test_file | awk '{print $1}') = '-rw-r--r--' ]
   699  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
   700  		map[string]string{
   701  			"test_file": "test1",
   702  		})
   703  	if err != nil {
   704  		t.Fatal(err)
   705  	}
   706  	defer ctx.Close()
   707  
   708  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   709  		t.Fatal(err)
   710  	}
   711  	logDone("build - add single file to root")
   712  }
   713  
   714  // Issue #3960: "ADD src ." hangs
   715  func TestBuildAddSingleFileToWorkdir(t *testing.T) {
   716  	name := "testaddsinglefiletoworkdir"
   717  	defer deleteImages(name)
   718  	ctx, err := fakeContext(`FROM busybox
   719  ADD test_file .`,
   720  		map[string]string{
   721  			"test_file": "test1",
   722  		})
   723  	if err != nil {
   724  		t.Fatal(err)
   725  	}
   726  	defer ctx.Close()
   727  
   728  	done := make(chan struct{})
   729  	go func() {
   730  		if _, err := buildImageFromContext(name, ctx, true); err != nil {
   731  			t.Fatal(err)
   732  		}
   733  		close(done)
   734  	}()
   735  	select {
   736  	case <-time.After(5 * time.Second):
   737  		t.Fatal("Build with adding to workdir timed out")
   738  	case <-done:
   739  	}
   740  	logDone("build - add single file to workdir")
   741  }
   742  
   743  func TestBuildAddSingleFileToExistDir(t *testing.T) {
   744  	name := "testaddsinglefiletoexistdir"
   745  	defer deleteImages(name)
   746  	ctx, err := fakeContext(`FROM busybox
   747  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   748  RUN echo 'dockerio:x:1001:' >> /etc/group
   749  RUN mkdir /exists
   750  RUN touch /exists/exists_file
   751  RUN chown -R dockerio.dockerio /exists
   752  ADD test_file /exists/
   753  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   754  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
   755  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
   756  		map[string]string{
   757  			"test_file": "test1",
   758  		})
   759  	if err != nil {
   760  		t.Fatal(err)
   761  	}
   762  	defer ctx.Close()
   763  
   764  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   765  		t.Fatal(err)
   766  	}
   767  	logDone("build - add single file to existing dir")
   768  }
   769  
   770  func TestBuildCopyAddMultipleFiles(t *testing.T) {
   771  	name := "testcopymultiplefilestofile"
   772  	defer deleteImages(name)
   773  	ctx, err := fakeContext(`FROM busybox
   774  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   775  RUN echo 'dockerio:x:1001:' >> /etc/group
   776  RUN mkdir /exists
   777  RUN touch /exists/exists_file
   778  RUN chown -R dockerio.dockerio /exists
   779  COPY test_file1 test_file2 /exists/
   780  ADD test_file3 test_file4 https://dockerproject.com/robots.txt /exists/
   781  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   782  RUN [ $(ls -l /exists/test_file1 | awk '{print $3":"$4}') = 'root:root' ]
   783  RUN [ $(ls -l /exists/test_file2 | awk '{print $3":"$4}') = 'root:root' ]
   784  
   785  RUN [ $(ls -l /exists/test_file3 | awk '{print $3":"$4}') = 'root:root' ]
   786  RUN [ $(ls -l /exists/test_file4 | awk '{print $3":"$4}') = 'root:root' ]
   787  RUN [ $(ls -l /exists/robots.txt | awk '{print $3":"$4}') = 'root:root' ]
   788  
   789  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   790  `,
   791  		map[string]string{
   792  			"test_file1": "test1",
   793  			"test_file2": "test2",
   794  			"test_file3": "test3",
   795  			"test_file4": "test4",
   796  		})
   797  	defer ctx.Close()
   798  	if err != nil {
   799  		t.Fatal(err)
   800  	}
   801  
   802  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   803  		t.Fatal(err)
   804  	}
   805  	logDone("build - mulitple file copy/add tests")
   806  }
   807  
   808  func TestBuildAddMultipleFilesToFile(t *testing.T) {
   809  	name := "testaddmultiplefilestofile"
   810  	defer deleteImages(name)
   811  	ctx, err := fakeContext(`FROM scratch
   812  	ADD file1.txt file2.txt test
   813          `,
   814  		map[string]string{
   815  			"file1.txt": "test1",
   816  			"file2.txt": "test1",
   817  		})
   818  	defer ctx.Close()
   819  	if err != nil {
   820  		t.Fatal(err)
   821  	}
   822  
   823  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   824  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   825  		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
   826  	}
   827  
   828  	logDone("build - multiple add files to file")
   829  }
   830  
   831  func TestBuildAddMultipleFilesToFileWild(t *testing.T) {
   832  	name := "testaddmultiplefilestofilewild"
   833  	defer deleteImages(name)
   834  	ctx, err := fakeContext(`FROM scratch
   835  	ADD file*.txt test
   836          `,
   837  		map[string]string{
   838  			"file1.txt": "test1",
   839  			"file2.txt": "test1",
   840  		})
   841  	defer ctx.Close()
   842  	if err != nil {
   843  		t.Fatal(err)
   844  	}
   845  
   846  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   847  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   848  		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
   849  	}
   850  
   851  	logDone("build - multiple add files to file wild")
   852  }
   853  
   854  func TestBuildCopyMultipleFilesToFile(t *testing.T) {
   855  	name := "testcopymultiplefilestofile"
   856  	defer deleteImages(name)
   857  	ctx, err := fakeContext(`FROM scratch
   858  	COPY file1.txt file2.txt test
   859          `,
   860  		map[string]string{
   861  			"file1.txt": "test1",
   862  			"file2.txt": "test1",
   863  		})
   864  	defer ctx.Close()
   865  	if err != nil {
   866  		t.Fatal(err)
   867  	}
   868  
   869  	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
   870  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   871  		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
   872  	}
   873  
   874  	logDone("build - multiple copy files to file")
   875  }
   876  
   877  func TestBuildCopyWildcard(t *testing.T) {
   878  	name := "testcopywildcard"
   879  	defer deleteImages(name)
   880  	server, err := fakeStorage(map[string]string{
   881  		"robots.txt": "hello",
   882  		"index.html": "world",
   883  	})
   884  	if err != nil {
   885  		t.Fatal(err)
   886  	}
   887  	defer server.Close()
   888  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
   889  	COPY file*.txt /tmp/
   890  	RUN ls /tmp/file1.txt /tmp/file2.txt
   891  	RUN mkdir /tmp1
   892  	COPY dir* /tmp1/
   893  	RUN ls /tmp1/dirt /tmp1/nested_file /tmp1/nested_dir/nest_nest_file
   894  	RUN mkdir /tmp2
   895          ADD dir/*dir %s/robots.txt /tmp2/
   896  	RUN ls /tmp2/nest_nest_file /tmp2/robots.txt
   897  	`, server.URL),
   898  		map[string]string{
   899  			"file1.txt":                     "test1",
   900  			"file2.txt":                     "test2",
   901  			"dir/nested_file":               "nested file",
   902  			"dir/nested_dir/nest_nest_file": "2 times nested",
   903  			"dirt": "dirty",
   904  		})
   905  	defer ctx.Close()
   906  	if err != nil {
   907  		t.Fatal(err)
   908  	}
   909  
   910  	id1, err := buildImageFromContext(name, ctx, true)
   911  	if err != nil {
   912  		t.Fatal(err)
   913  	}
   914  
   915  	// Now make sure we use a cache the 2nd time
   916  	id2, err := buildImageFromContext(name, ctx, true)
   917  	if err != nil {
   918  		t.Fatal(err)
   919  	}
   920  
   921  	if id1 != id2 {
   922  		t.Fatal("didn't use the cache")
   923  	}
   924  
   925  	logDone("build - copy wild card")
   926  }
   927  
   928  func TestBuildCopyWildcardNoFind(t *testing.T) {
   929  	name := "testcopywildcardnofind"
   930  	defer deleteImages(name)
   931  	ctx, err := fakeContext(`FROM busybox
   932  	COPY file*.txt /tmp/
   933  	`, nil)
   934  	defer ctx.Close()
   935  	if err != nil {
   936  		t.Fatal(err)
   937  	}
   938  
   939  	_, err = buildImageFromContext(name, ctx, true)
   940  	if err == nil {
   941  		t.Fatal("should have failed to find a file")
   942  	}
   943  	if !strings.Contains(err.Error(), "No source files were specified") {
   944  		t.Fatalf("Wrong error %v, must be about no source files", err)
   945  	}
   946  
   947  	logDone("build - copy wild card no find")
   948  }
   949  
   950  func TestBuildCopyWildcardCache(t *testing.T) {
   951  	name := "testcopywildcardcache"
   952  	defer deleteImages(name)
   953  	ctx, err := fakeContext(`FROM busybox
   954  	COPY file1.txt /tmp/`,
   955  		map[string]string{
   956  			"file1.txt": "test1",
   957  		})
   958  	defer ctx.Close()
   959  	if err != nil {
   960  		t.Fatal(err)
   961  	}
   962  
   963  	id1, err := buildImageFromContext(name, ctx, true)
   964  	if err != nil {
   965  		t.Fatal(err)
   966  	}
   967  
   968  	// Now make sure we use a cache the 2nd time even with wild cards.
   969  	// Use the same context so the file is the same and the checksum will match
   970  	ctx.Add("Dockerfile", `FROM busybox
   971  	COPY file*.txt /tmp/`)
   972  
   973  	id2, err := buildImageFromContext(name, ctx, true)
   974  	if err != nil {
   975  		t.Fatal(err)
   976  	}
   977  
   978  	if id1 != id2 {
   979  		t.Fatal("didn't use the cache")
   980  	}
   981  
   982  	logDone("build - copy wild card cache")
   983  }
   984  
   985  func TestBuildAddSingleFileToNonExistingDir(t *testing.T) {
   986  	name := "testaddsinglefiletononexistingdir"
   987  	defer deleteImages(name)
   988  	ctx, err := fakeContext(`FROM busybox
   989  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   990  RUN echo 'dockerio:x:1001:' >> /etc/group
   991  RUN touch /exists
   992  RUN chown dockerio.dockerio /exists
   993  ADD test_file /test_dir/
   994  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
   995  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
   996  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
   997  		map[string]string{
   998  			"test_file": "test1",
   999  		})
  1000  	if err != nil {
  1001  		t.Fatal(err)
  1002  	}
  1003  	defer ctx.Close()
  1004  
  1005  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1006  		t.Fatal(err)
  1007  	}
  1008  
  1009  	logDone("build - add single file to non-existing dir")
  1010  }
  1011  
  1012  func TestBuildAddDirContentToRoot(t *testing.T) {
  1013  	name := "testadddircontenttoroot"
  1014  	defer deleteImages(name)
  1015  	ctx, err := fakeContext(`FROM busybox
  1016  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1017  RUN echo 'dockerio:x:1001:' >> /etc/group
  1018  RUN touch /exists
  1019  RUN chown dockerio.dockerio exists
  1020  ADD test_dir /
  1021  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1022  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1023  		map[string]string{
  1024  			"test_dir/test_file": "test1",
  1025  		})
  1026  	if err != nil {
  1027  		t.Fatal(err)
  1028  	}
  1029  	defer ctx.Close()
  1030  
  1031  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1032  		t.Fatal(err)
  1033  	}
  1034  	logDone("build - add directory contents to root")
  1035  }
  1036  
  1037  func TestBuildAddDirContentToExistingDir(t *testing.T) {
  1038  	name := "testadddircontenttoexistingdir"
  1039  	defer deleteImages(name)
  1040  	ctx, err := fakeContext(`FROM busybox
  1041  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1042  RUN echo 'dockerio:x:1001:' >> /etc/group
  1043  RUN mkdir /exists
  1044  RUN touch /exists/exists_file
  1045  RUN chown -R dockerio.dockerio /exists
  1046  ADD test_dir/ /exists/
  1047  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1048  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1049  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1050  		map[string]string{
  1051  			"test_dir/test_file": "test1",
  1052  		})
  1053  	if err != nil {
  1054  		t.Fatal(err)
  1055  	}
  1056  	defer ctx.Close()
  1057  
  1058  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1059  		t.Fatal(err)
  1060  	}
  1061  	logDone("build - add directory contents to existing dir")
  1062  }
  1063  
  1064  func TestBuildAddWholeDirToRoot(t *testing.T) {
  1065  	name := "testaddwholedirtoroot"
  1066  	defer deleteImages(name)
  1067  	ctx, err := fakeContext(`FROM busybox
  1068  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1069  RUN echo 'dockerio:x:1001:' >> /etc/group
  1070  RUN touch /exists
  1071  RUN chown dockerio.dockerio exists
  1072  ADD test_dir /test_dir
  1073  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1074  RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1075  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1076  RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '-rw-r--r--' ]
  1077  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1078  		map[string]string{
  1079  			"test_dir/test_file": "test1",
  1080  		})
  1081  	if err != nil {
  1082  		t.Fatal(err)
  1083  	}
  1084  	defer ctx.Close()
  1085  
  1086  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1087  		t.Fatal(err)
  1088  	}
  1089  	logDone("build - add whole directory to root")
  1090  }
  1091  
  1092  // Testing #5941
  1093  func TestBuildAddEtcToRoot(t *testing.T) {
  1094  	name := "testaddetctoroot"
  1095  	defer deleteImages(name)
  1096  	ctx, err := fakeContext(`FROM scratch
  1097  ADD . /`,
  1098  		map[string]string{
  1099  			"etc/test_file": "test1",
  1100  		})
  1101  	if err != nil {
  1102  		t.Fatal(err)
  1103  	}
  1104  	defer ctx.Close()
  1105  
  1106  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1107  		t.Fatal(err)
  1108  	}
  1109  	logDone("build - add etc directory to root")
  1110  }
  1111  
  1112  // Testing #9401
  1113  func TestBuildAddPreservesFilesSpecialBits(t *testing.T) {
  1114  	name := "testaddpreservesfilesspecialbits"
  1115  	defer deleteImages(name)
  1116  	ctx, err := fakeContext(`FROM busybox
  1117  ADD suidbin /usr/bin/suidbin
  1118  RUN chmod 4755 /usr/bin/suidbin
  1119  RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]
  1120  ADD ./data/ /
  1121  RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]`,
  1122  		map[string]string{
  1123  			"suidbin":             "suidbin",
  1124  			"/data/usr/test_file": "test1",
  1125  		})
  1126  	if err != nil {
  1127  		t.Fatal(err)
  1128  	}
  1129  	defer ctx.Close()
  1130  
  1131  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1132  		t.Fatal(err)
  1133  	}
  1134  	logDone("build - add preserves files special bits")
  1135  }
  1136  
  1137  func TestBuildCopySingleFileToRoot(t *testing.T) {
  1138  	name := "testcopysinglefiletoroot"
  1139  	defer deleteImages(name)
  1140  	ctx, err := fakeContext(`FROM busybox
  1141  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1142  RUN echo 'dockerio:x:1001:' >> /etc/group
  1143  RUN touch /exists
  1144  RUN chown dockerio.dockerio /exists
  1145  COPY test_file /
  1146  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1147  RUN [ $(ls -l /test_file | awk '{print $1}') = '-rw-r--r--' ]
  1148  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1149  		map[string]string{
  1150  			"test_file": "test1",
  1151  		})
  1152  	if err != nil {
  1153  		t.Fatal(err)
  1154  	}
  1155  	defer ctx.Close()
  1156  
  1157  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1158  		t.Fatal(err)
  1159  	}
  1160  	logDone("build - copy single file to root")
  1161  }
  1162  
  1163  // Issue #3960: "ADD src ." hangs - adapted for COPY
  1164  func TestBuildCopySingleFileToWorkdir(t *testing.T) {
  1165  	name := "testcopysinglefiletoworkdir"
  1166  	defer deleteImages(name)
  1167  	ctx, err := fakeContext(`FROM busybox
  1168  COPY test_file .`,
  1169  		map[string]string{
  1170  			"test_file": "test1",
  1171  		})
  1172  	if err != nil {
  1173  		t.Fatal(err)
  1174  	}
  1175  	defer ctx.Close()
  1176  
  1177  	done := make(chan struct{})
  1178  	go func() {
  1179  		if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1180  			t.Fatal(err)
  1181  		}
  1182  		close(done)
  1183  	}()
  1184  	select {
  1185  	case <-time.After(5 * time.Second):
  1186  		t.Fatal("Build with adding to workdir timed out")
  1187  	case <-done:
  1188  	}
  1189  	logDone("build - copy single file to workdir")
  1190  }
  1191  
  1192  func TestBuildCopySingleFileToExistDir(t *testing.T) {
  1193  	name := "testcopysinglefiletoexistdir"
  1194  	defer deleteImages(name)
  1195  	ctx, err := fakeContext(`FROM busybox
  1196  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1197  RUN echo 'dockerio:x:1001:' >> /etc/group
  1198  RUN mkdir /exists
  1199  RUN touch /exists/exists_file
  1200  RUN chown -R dockerio.dockerio /exists
  1201  COPY test_file /exists/
  1202  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1203  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1204  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1205  		map[string]string{
  1206  			"test_file": "test1",
  1207  		})
  1208  	if err != nil {
  1209  		t.Fatal(err)
  1210  	}
  1211  	defer ctx.Close()
  1212  
  1213  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1214  		t.Fatal(err)
  1215  	}
  1216  	logDone("build - copy single file to existing dir")
  1217  }
  1218  
  1219  func TestBuildCopySingleFileToNonExistDir(t *testing.T) {
  1220  	name := "testcopysinglefiletononexistdir"
  1221  	defer deleteImages(name)
  1222  	ctx, err := fakeContext(`FROM busybox
  1223  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1224  RUN echo 'dockerio:x:1001:' >> /etc/group
  1225  RUN touch /exists
  1226  RUN chown dockerio.dockerio /exists
  1227  COPY test_file /test_dir/
  1228  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1229  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1230  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1231  		map[string]string{
  1232  			"test_file": "test1",
  1233  		})
  1234  	if err != nil {
  1235  		t.Fatal(err)
  1236  	}
  1237  	defer ctx.Close()
  1238  
  1239  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1240  		t.Fatal(err)
  1241  	}
  1242  	logDone("build - copy single file to non-existing dir")
  1243  }
  1244  
  1245  func TestBuildCopyDirContentToRoot(t *testing.T) {
  1246  	name := "testcopydircontenttoroot"
  1247  	defer deleteImages(name)
  1248  	ctx, err := fakeContext(`FROM busybox
  1249  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1250  RUN echo 'dockerio:x:1001:' >> /etc/group
  1251  RUN touch /exists
  1252  RUN chown dockerio.dockerio exists
  1253  COPY test_dir /
  1254  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1255  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1256  		map[string]string{
  1257  			"test_dir/test_file": "test1",
  1258  		})
  1259  	if err != nil {
  1260  		t.Fatal(err)
  1261  	}
  1262  	defer ctx.Close()
  1263  
  1264  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1265  		t.Fatal(err)
  1266  	}
  1267  	logDone("build - copy directory contents to root")
  1268  }
  1269  
  1270  func TestBuildCopyDirContentToExistDir(t *testing.T) {
  1271  	name := "testcopydircontenttoexistdir"
  1272  	defer deleteImages(name)
  1273  	ctx, err := fakeContext(`FROM busybox
  1274  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1275  RUN echo 'dockerio:x:1001:' >> /etc/group
  1276  RUN mkdir /exists
  1277  RUN touch /exists/exists_file
  1278  RUN chown -R dockerio.dockerio /exists
  1279  COPY test_dir/ /exists/
  1280  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1281  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1282  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1283  		map[string]string{
  1284  			"test_dir/test_file": "test1",
  1285  		})
  1286  	if err != nil {
  1287  		t.Fatal(err)
  1288  	}
  1289  	defer ctx.Close()
  1290  
  1291  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1292  		t.Fatal(err)
  1293  	}
  1294  	logDone("build - copy directory contents to existing dir")
  1295  }
  1296  
  1297  func TestBuildCopyWholeDirToRoot(t *testing.T) {
  1298  	name := "testcopywholedirtoroot"
  1299  	defer deleteImages(name)
  1300  	ctx, err := fakeContext(`FROM busybox
  1301  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1302  RUN echo 'dockerio:x:1001:' >> /etc/group
  1303  RUN touch /exists
  1304  RUN chown dockerio.dockerio exists
  1305  COPY test_dir /test_dir
  1306  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1307  RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1308  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1309  RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '-rw-r--r--' ]
  1310  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1311  		map[string]string{
  1312  			"test_dir/test_file": "test1",
  1313  		})
  1314  	if err != nil {
  1315  		t.Fatal(err)
  1316  	}
  1317  	defer ctx.Close()
  1318  
  1319  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1320  		t.Fatal(err)
  1321  	}
  1322  	logDone("build - copy whole directory to root")
  1323  }
  1324  
  1325  func TestBuildCopyEtcToRoot(t *testing.T) {
  1326  	name := "testcopyetctoroot"
  1327  	defer deleteImages(name)
  1328  	ctx, err := fakeContext(`FROM scratch
  1329  COPY . /`,
  1330  		map[string]string{
  1331  			"etc/test_file": "test1",
  1332  		})
  1333  	if err != nil {
  1334  		t.Fatal(err)
  1335  	}
  1336  	defer ctx.Close()
  1337  
  1338  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1339  		t.Fatal(err)
  1340  	}
  1341  	logDone("build - copy etc directory to root")
  1342  }
  1343  
  1344  func TestBuildCopyDisallowRemote(t *testing.T) {
  1345  	name := "testcopydisallowremote"
  1346  	defer deleteImages(name)
  1347  	_, out, err := buildImageWithOut(name, `FROM scratch
  1348  COPY https://index.docker.io/robots.txt /`,
  1349  		true)
  1350  	if err == nil || !strings.Contains(out, "Source can't be a URL for COPY") {
  1351  		t.Fatalf("Error should be about disallowed remote source, got err: %s, out: %q", err, out)
  1352  	}
  1353  	logDone("build - copy - disallow copy from remote")
  1354  }
  1355  
  1356  func TestBuildAddBadLinks(t *testing.T) {
  1357  	const (
  1358  		dockerfile = `
  1359  			FROM scratch
  1360  			ADD links.tar /
  1361  			ADD foo.txt /symlink/
  1362  			`
  1363  		targetFile = "foo.txt"
  1364  	)
  1365  	var (
  1366  		name = "test-link-absolute"
  1367  	)
  1368  	defer deleteImages(name)
  1369  	ctx, err := fakeContext(dockerfile, nil)
  1370  	if err != nil {
  1371  		t.Fatal(err)
  1372  	}
  1373  	defer ctx.Close()
  1374  
  1375  	tempDir, err := ioutil.TempDir("", "test-link-absolute-temp-")
  1376  	if err != nil {
  1377  		t.Fatalf("failed to create temporary directory: %s", tempDir)
  1378  	}
  1379  	defer os.RemoveAll(tempDir)
  1380  
  1381  	symlinkTarget := fmt.Sprintf("/../../../../../../../../../../../..%s", tempDir)
  1382  	tarPath := filepath.Join(ctx.Dir, "links.tar")
  1383  	nonExistingFile := filepath.Join(tempDir, targetFile)
  1384  	fooPath := filepath.Join(ctx.Dir, targetFile)
  1385  
  1386  	tarOut, err := os.Create(tarPath)
  1387  	if err != nil {
  1388  		t.Fatal(err)
  1389  	}
  1390  
  1391  	tarWriter := tar.NewWriter(tarOut)
  1392  
  1393  	header := &tar.Header{
  1394  		Name:     "symlink",
  1395  		Typeflag: tar.TypeSymlink,
  1396  		Linkname: symlinkTarget,
  1397  		Mode:     0755,
  1398  		Uid:      0,
  1399  		Gid:      0,
  1400  	}
  1401  
  1402  	err = tarWriter.WriteHeader(header)
  1403  	if err != nil {
  1404  		t.Fatal(err)
  1405  	}
  1406  
  1407  	tarWriter.Close()
  1408  	tarOut.Close()
  1409  
  1410  	foo, err := os.Create(fooPath)
  1411  	if err != nil {
  1412  		t.Fatal(err)
  1413  	}
  1414  	defer foo.Close()
  1415  
  1416  	if _, err := foo.WriteString("test"); err != nil {
  1417  		t.Fatal(err)
  1418  	}
  1419  
  1420  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1421  		t.Fatal(err)
  1422  	}
  1423  
  1424  	if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1425  		t.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1426  	}
  1427  
  1428  	logDone("build - ADD must add files in container")
  1429  }
  1430  
  1431  func TestBuildAddBadLinksVolume(t *testing.T) {
  1432  	const (
  1433  		dockerfileTemplate = `
  1434  		FROM busybox
  1435  		RUN ln -s /../../../../../../../../%s /x
  1436  		VOLUME /x
  1437  		ADD foo.txt /x/`
  1438  		targetFile = "foo.txt"
  1439  	)
  1440  	var (
  1441  		name       = "test-link-absolute-volume"
  1442  		dockerfile = ""
  1443  	)
  1444  	defer deleteImages(name)
  1445  
  1446  	tempDir, err := ioutil.TempDir("", "test-link-absolute-volume-temp-")
  1447  	if err != nil {
  1448  		t.Fatalf("failed to create temporary directory: %s", tempDir)
  1449  	}
  1450  	defer os.RemoveAll(tempDir)
  1451  
  1452  	dockerfile = fmt.Sprintf(dockerfileTemplate, tempDir)
  1453  	nonExistingFile := filepath.Join(tempDir, targetFile)
  1454  
  1455  	ctx, err := fakeContext(dockerfile, nil)
  1456  	if err != nil {
  1457  		t.Fatal(err)
  1458  	}
  1459  	defer ctx.Close()
  1460  	fooPath := filepath.Join(ctx.Dir, targetFile)
  1461  
  1462  	foo, err := os.Create(fooPath)
  1463  	if err != nil {
  1464  		t.Fatal(err)
  1465  	}
  1466  	defer foo.Close()
  1467  
  1468  	if _, err := foo.WriteString("test"); err != nil {
  1469  		t.Fatal(err)
  1470  	}
  1471  
  1472  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1473  		t.Fatal(err)
  1474  	}
  1475  
  1476  	if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1477  		t.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1478  	}
  1479  
  1480  	logDone("build - ADD should add files in volume")
  1481  }
  1482  
  1483  // Issue #5270 - ensure we throw a better error than "unexpected EOF"
  1484  // when we can't access files in the context.
  1485  func TestBuildWithInaccessibleFilesInContext(t *testing.T) {
  1486  	{
  1487  		name := "testbuildinaccessiblefiles"
  1488  		defer deleteImages(name)
  1489  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"fileWithoutReadAccess": "foo"})
  1490  		if err != nil {
  1491  			t.Fatal(err)
  1492  		}
  1493  		defer ctx.Close()
  1494  		// This is used to ensure we detect inaccessible files early during build in the cli client
  1495  		pathToFileWithoutReadAccess := filepath.Join(ctx.Dir, "fileWithoutReadAccess")
  1496  
  1497  		if err = os.Chown(pathToFileWithoutReadAccess, 0, 0); err != nil {
  1498  			t.Fatalf("failed to chown file to root: %s", err)
  1499  		}
  1500  		if err = os.Chmod(pathToFileWithoutReadAccess, 0700); err != nil {
  1501  			t.Fatalf("failed to chmod file to 700: %s", err)
  1502  		}
  1503  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1504  		buildCmd.Dir = ctx.Dir
  1505  		out, _, err := runCommandWithOutput(buildCmd)
  1506  		if err == nil {
  1507  			t.Fatalf("build should have failed: %s %s", err, out)
  1508  		}
  1509  
  1510  		// check if we've detected the failure before we started building
  1511  		if !strings.Contains(out, "no permission to read from ") {
  1512  			t.Fatalf("output should've contained the string: no permission to read from but contained: %s", out)
  1513  		}
  1514  
  1515  		if !strings.Contains(out, "Error checking context is accessible") {
  1516  			t.Fatalf("output should've contained the string: Error checking context is accessible")
  1517  		}
  1518  	}
  1519  	{
  1520  		name := "testbuildinaccessibledirectory"
  1521  		defer deleteImages(name)
  1522  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"directoryWeCantStat/bar": "foo"})
  1523  		if err != nil {
  1524  			t.Fatal(err)
  1525  		}
  1526  		defer ctx.Close()
  1527  		// This is used to ensure we detect inaccessible directories early during build in the cli client
  1528  		pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1529  		pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1530  
  1531  		if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1532  			t.Fatalf("failed to chown directory to root: %s", err)
  1533  		}
  1534  		if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1535  			t.Fatalf("failed to chmod directory to 755: %s", err)
  1536  		}
  1537  		if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1538  			t.Fatalf("failed to chmod file to 444: %s", err)
  1539  		}
  1540  
  1541  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1542  		buildCmd.Dir = ctx.Dir
  1543  		out, _, err := runCommandWithOutput(buildCmd)
  1544  		if err == nil {
  1545  			t.Fatalf("build should have failed: %s %s", err, out)
  1546  		}
  1547  
  1548  		// check if we've detected the failure before we started building
  1549  		if !strings.Contains(out, "can't stat") {
  1550  			t.Fatalf("output should've contained the string: can't access %s", out)
  1551  		}
  1552  
  1553  		if !strings.Contains(out, "Error checking context is accessible") {
  1554  			t.Fatalf("output should've contained the string: Error checking context is accessible")
  1555  		}
  1556  
  1557  	}
  1558  	{
  1559  		name := "testlinksok"
  1560  		defer deleteImages(name)
  1561  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", nil)
  1562  		if err != nil {
  1563  			t.Fatal(err)
  1564  		}
  1565  		defer ctx.Close()
  1566  
  1567  		target := "../../../../../../../../../../../../../../../../../../../azA"
  1568  		if err := os.Symlink(filepath.Join(ctx.Dir, "g"), target); err != nil {
  1569  			t.Fatal(err)
  1570  		}
  1571  		defer os.Remove(target)
  1572  		// This is used to ensure we don't follow links when checking if everything in the context is accessible
  1573  		// This test doesn't require that we run commands as an unprivileged user
  1574  		if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1575  			t.Fatal(err)
  1576  		}
  1577  	}
  1578  	{
  1579  		name := "testbuildignoredinaccessible"
  1580  		defer deleteImages(name)
  1581  		ctx, err := fakeContext("FROM scratch\nADD . /foo/",
  1582  			map[string]string{
  1583  				"directoryWeCantStat/bar": "foo",
  1584  				".dockerignore":           "directoryWeCantStat",
  1585  			})
  1586  		if err != nil {
  1587  			t.Fatal(err)
  1588  		}
  1589  		defer ctx.Close()
  1590  		// This is used to ensure we don't try to add inaccessible files when they are ignored by a .dockerignore pattern
  1591  		pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1592  		pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1593  		if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1594  			t.Fatalf("failed to chown directory to root: %s", err)
  1595  		}
  1596  		if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1597  			t.Fatalf("failed to chmod directory to 755: %s", err)
  1598  		}
  1599  		if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1600  			t.Fatalf("failed to chmod file to 444: %s", err)
  1601  		}
  1602  
  1603  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1604  		buildCmd.Dir = ctx.Dir
  1605  		if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  1606  			t.Fatalf("build should have worked: %s %s", err, out)
  1607  		}
  1608  
  1609  	}
  1610  	logDone("build - ADD from context with inaccessible files must fail")
  1611  	logDone("build - ADD from context with accessible links must work")
  1612  	logDone("build - ADD from context with ignored inaccessible files must work")
  1613  }
  1614  
  1615  func TestBuildForceRm(t *testing.T) {
  1616  	containerCountBefore, err := getContainerCount()
  1617  	if err != nil {
  1618  		t.Fatalf("failed to get the container count: %s", err)
  1619  	}
  1620  	name := "testbuildforcerm"
  1621  	defer deleteImages(name)
  1622  	ctx, err := fakeContext("FROM scratch\nRUN true\nRUN thiswillfail", nil)
  1623  	if err != nil {
  1624  		t.Fatal(err)
  1625  	}
  1626  	defer ctx.Close()
  1627  
  1628  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, "--force-rm", ".")
  1629  	buildCmd.Dir = ctx.Dir
  1630  	if out, _, err := runCommandWithOutput(buildCmd); err == nil {
  1631  		t.Fatalf("failed to build the image: %s, %v", out, err)
  1632  	}
  1633  
  1634  	containerCountAfter, err := getContainerCount()
  1635  	if err != nil {
  1636  		t.Fatalf("failed to get the container count: %s", err)
  1637  	}
  1638  
  1639  	if containerCountBefore != containerCountAfter {
  1640  		t.Fatalf("--force-rm shouldn't have left containers behind")
  1641  	}
  1642  
  1643  	logDone("build - ensure --force-rm doesn't leave containers behind")
  1644  }
  1645  
  1646  func TestBuildRm(t *testing.T) {
  1647  	name := "testbuildrm"
  1648  	defer deleteImages(name)
  1649  	ctx, err := fakeContext("FROM scratch\nADD foo /\nADD foo /", map[string]string{"foo": "bar"})
  1650  	if err != nil {
  1651  		t.Fatal(err)
  1652  	}
  1653  	defer ctx.Close()
  1654  	{
  1655  		containerCountBefore, err := getContainerCount()
  1656  		if err != nil {
  1657  			t.Fatalf("failed to get the container count: %s", err)
  1658  		}
  1659  
  1660  		out, _, err := dockerCmdInDir(t, ctx.Dir, "build", "--rm", "-t", name, ".")
  1661  
  1662  		if err != nil {
  1663  			t.Fatal("failed to build the image", out)
  1664  		}
  1665  
  1666  		containerCountAfter, err := getContainerCount()
  1667  		if err != nil {
  1668  			t.Fatalf("failed to get the container count: %s", err)
  1669  		}
  1670  
  1671  		if containerCountBefore != containerCountAfter {
  1672  			t.Fatalf("-rm shouldn't have left containers behind")
  1673  		}
  1674  		deleteImages(name)
  1675  	}
  1676  
  1677  	{
  1678  		containerCountBefore, err := getContainerCount()
  1679  		if err != nil {
  1680  			t.Fatalf("failed to get the container count: %s", err)
  1681  		}
  1682  
  1683  		out, _, err := dockerCmdInDir(t, ctx.Dir, "build", "-t", name, ".")
  1684  
  1685  		if err != nil {
  1686  			t.Fatal("failed to build the image", out)
  1687  		}
  1688  
  1689  		containerCountAfter, err := getContainerCount()
  1690  		if err != nil {
  1691  			t.Fatalf("failed to get the container count: %s", err)
  1692  		}
  1693  
  1694  		if containerCountBefore != containerCountAfter {
  1695  			t.Fatalf("--rm shouldn't have left containers behind")
  1696  		}
  1697  		deleteImages(name)
  1698  	}
  1699  
  1700  	{
  1701  		containerCountBefore, err := getContainerCount()
  1702  		if err != nil {
  1703  			t.Fatalf("failed to get the container count: %s", err)
  1704  		}
  1705  
  1706  		out, _, err := dockerCmdInDir(t, ctx.Dir, "build", "--rm=false", "-t", name, ".")
  1707  
  1708  		if err != nil {
  1709  			t.Fatal("failed to build the image", out)
  1710  		}
  1711  
  1712  		containerCountAfter, err := getContainerCount()
  1713  		if err != nil {
  1714  			t.Fatalf("failed to get the container count: %s", err)
  1715  		}
  1716  
  1717  		if containerCountBefore == containerCountAfter {
  1718  			t.Fatalf("--rm=false should have left containers behind")
  1719  		}
  1720  		deleteAllContainers()
  1721  		deleteImages(name)
  1722  
  1723  	}
  1724  
  1725  	logDone("build - ensure --rm doesn't leave containers behind and that --rm=true is the default")
  1726  	logDone("build - ensure --rm=false overrides the default")
  1727  }
  1728  
  1729  func TestBuildWithVolumes(t *testing.T) {
  1730  	var (
  1731  		result   map[string]map[string]struct{}
  1732  		name     = "testbuildvolumes"
  1733  		emptyMap = make(map[string]struct{})
  1734  		expected = map[string]map[string]struct{}{
  1735  			"/test1":  emptyMap,
  1736  			"/test2":  emptyMap,
  1737  			"/test3":  emptyMap,
  1738  			"/test4":  emptyMap,
  1739  			"/test5":  emptyMap,
  1740  			"/test6":  emptyMap,
  1741  			"[/test7": emptyMap,
  1742  			"/test8]": emptyMap,
  1743  		}
  1744  	)
  1745  	defer deleteImages(name)
  1746  	_, err := buildImage(name,
  1747  		`FROM scratch
  1748  		VOLUME /test1
  1749  		VOLUME /test2
  1750      VOLUME /test3 /test4
  1751      VOLUME ["/test5", "/test6"]
  1752      VOLUME [/test7 /test8]
  1753      `,
  1754  		true)
  1755  	if err != nil {
  1756  		t.Fatal(err)
  1757  	}
  1758  	res, err := inspectFieldJSON(name, "Config.Volumes")
  1759  	if err != nil {
  1760  		t.Fatal(err)
  1761  	}
  1762  
  1763  	err = unmarshalJSON([]byte(res), &result)
  1764  	if err != nil {
  1765  		t.Fatal(err)
  1766  	}
  1767  
  1768  	equal := reflect.DeepEqual(&result, &expected)
  1769  
  1770  	if !equal {
  1771  		t.Fatalf("Volumes %s, expected %s", result, expected)
  1772  	}
  1773  
  1774  	logDone("build - with volumes")
  1775  }
  1776  
  1777  func TestBuildMaintainer(t *testing.T) {
  1778  	name := "testbuildmaintainer"
  1779  	expected := "dockerio"
  1780  	defer deleteImages(name)
  1781  	_, err := buildImage(name,
  1782  		`FROM scratch
  1783          MAINTAINER dockerio`,
  1784  		true)
  1785  	if err != nil {
  1786  		t.Fatal(err)
  1787  	}
  1788  	res, err := inspectField(name, "Author")
  1789  	if err != nil {
  1790  		t.Fatal(err)
  1791  	}
  1792  	if res != expected {
  1793  		t.Fatalf("Maintainer %s, expected %s", res, expected)
  1794  	}
  1795  	logDone("build - maintainer")
  1796  }
  1797  
  1798  func TestBuildUser(t *testing.T) {
  1799  	name := "testbuilduser"
  1800  	expected := "dockerio"
  1801  	defer deleteImages(name)
  1802  	_, err := buildImage(name,
  1803  		`FROM busybox
  1804  		RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1805  		USER dockerio
  1806  		RUN [ $(whoami) = 'dockerio' ]`,
  1807  		true)
  1808  	if err != nil {
  1809  		t.Fatal(err)
  1810  	}
  1811  	res, err := inspectField(name, "Config.User")
  1812  	if err != nil {
  1813  		t.Fatal(err)
  1814  	}
  1815  	if res != expected {
  1816  		t.Fatalf("User %s, expected %s", res, expected)
  1817  	}
  1818  	logDone("build - user")
  1819  }
  1820  
  1821  func TestBuildRelativeWorkdir(t *testing.T) {
  1822  	name := "testbuildrelativeworkdir"
  1823  	expected := "/test2/test3"
  1824  	defer deleteImages(name)
  1825  	_, err := buildImage(name,
  1826  		`FROM busybox
  1827  		RUN [ "$PWD" = '/' ]
  1828  		WORKDIR test1
  1829  		RUN [ "$PWD" = '/test1' ]
  1830  		WORKDIR /test2
  1831  		RUN [ "$PWD" = '/test2' ]
  1832  		WORKDIR test3
  1833  		RUN [ "$PWD" = '/test2/test3' ]`,
  1834  		true)
  1835  	if err != nil {
  1836  		t.Fatal(err)
  1837  	}
  1838  	res, err := inspectField(name, "Config.WorkingDir")
  1839  	if err != nil {
  1840  		t.Fatal(err)
  1841  	}
  1842  	if res != expected {
  1843  		t.Fatalf("Workdir %s, expected %s", res, expected)
  1844  	}
  1845  	logDone("build - relative workdir")
  1846  }
  1847  
  1848  func TestBuildWorkdirWithEnvVariables(t *testing.T) {
  1849  	name := "testbuildworkdirwithenvvariables"
  1850  	expected := "/test1/test2/$MISSING_VAR"
  1851  	defer deleteImages(name)
  1852  	_, err := buildImage(name,
  1853  		`FROM busybox
  1854  		ENV DIRPATH /test1
  1855  		ENV SUBDIRNAME test2
  1856  		WORKDIR $DIRPATH
  1857  		WORKDIR $SUBDIRNAME/$MISSING_VAR`,
  1858  		true)
  1859  	if err != nil {
  1860  		t.Fatal(err)
  1861  	}
  1862  	res, err := inspectField(name, "Config.WorkingDir")
  1863  	if err != nil {
  1864  		t.Fatal(err)
  1865  	}
  1866  	if res != expected {
  1867  		t.Fatalf("Workdir %s, expected %s", res, expected)
  1868  	}
  1869  	logDone("build - workdir with env variables")
  1870  }
  1871  
  1872  func TestBuildRelativeCopy(t *testing.T) {
  1873  	name := "testbuildrelativecopy"
  1874  	defer deleteImages(name)
  1875  	dockerfile := `
  1876  		FROM busybox
  1877  			WORKDIR /test1
  1878  			WORKDIR test2
  1879  			RUN [ "$PWD" = '/test1/test2' ]
  1880  			COPY foo ./
  1881  			RUN [ "$(cat /test1/test2/foo)" = 'hello' ]
  1882  			ADD foo ./bar/baz
  1883  			RUN [ "$(cat /test1/test2/bar/baz)" = 'hello' ]
  1884  			COPY foo ./bar/baz2
  1885  			RUN [ "$(cat /test1/test2/bar/baz2)" = 'hello' ]
  1886  			WORKDIR ..
  1887  			COPY foo ./
  1888  			RUN [ "$(cat /test1/foo)" = 'hello' ]
  1889  			COPY foo /test3/
  1890  			RUN [ "$(cat /test3/foo)" = 'hello' ]
  1891  			WORKDIR /test4
  1892  			COPY . .
  1893  			RUN [ "$(cat /test4/foo)" = 'hello' ]
  1894  			WORKDIR /test5/test6
  1895  			COPY foo ../
  1896  			RUN [ "$(cat /test5/foo)" = 'hello' ]
  1897  			`
  1898  	ctx, err := fakeContext(dockerfile, map[string]string{
  1899  		"foo": "hello",
  1900  	})
  1901  	defer ctx.Close()
  1902  	if err != nil {
  1903  		t.Fatal(err)
  1904  	}
  1905  	_, err = buildImageFromContext(name, ctx, false)
  1906  	if err != nil {
  1907  		t.Fatal(err)
  1908  	}
  1909  	logDone("build - relative copy/add")
  1910  }
  1911  
  1912  func TestBuildEnv(t *testing.T) {
  1913  	name := "testbuildenv"
  1914  	expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  1915  	defer deleteImages(name)
  1916  	_, err := buildImage(name,
  1917  		`FROM busybox
  1918  		ENV PATH /test:$PATH
  1919          ENV PORT 2375
  1920  		RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  1921  		true)
  1922  	if err != nil {
  1923  		t.Fatal(err)
  1924  	}
  1925  	res, err := inspectField(name, "Config.Env")
  1926  	if err != nil {
  1927  		t.Fatal(err)
  1928  	}
  1929  	if res != expected {
  1930  		t.Fatalf("Env %s, expected %s", res, expected)
  1931  	}
  1932  	logDone("build - env")
  1933  }
  1934  
  1935  func TestBuildContextCleanup(t *testing.T) {
  1936  	name := "testbuildcontextcleanup"
  1937  	defer deleteImages(name)
  1938  	entries, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1939  	if err != nil {
  1940  		t.Fatalf("failed to list contents of tmp dir: %s", err)
  1941  	}
  1942  	_, err = buildImage(name,
  1943  		`FROM scratch
  1944          ENTRYPOINT ["/bin/echo"]`,
  1945  		true)
  1946  	if err != nil {
  1947  		t.Fatal(err)
  1948  	}
  1949  	entriesFinal, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1950  	if err != nil {
  1951  		t.Fatalf("failed to list contents of tmp dir: %s", err)
  1952  	}
  1953  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  1954  		t.Fatalf("context should have been deleted, but wasn't")
  1955  	}
  1956  
  1957  	logDone("build - verify context cleanup works properly")
  1958  }
  1959  
  1960  func TestBuildContextCleanupFailedBuild(t *testing.T) {
  1961  	name := "testbuildcontextcleanup"
  1962  	defer deleteImages(name)
  1963  	defer deleteAllContainers()
  1964  	entries, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1965  	if err != nil {
  1966  		t.Fatalf("failed to list contents of tmp dir: %s", err)
  1967  	}
  1968  	_, err = buildImage(name,
  1969  		`FROM scratch
  1970  	RUN /non/existing/command`,
  1971  		true)
  1972  	if err == nil {
  1973  		t.Fatalf("expected build to fail, but it didn't")
  1974  	}
  1975  	entriesFinal, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1976  	if err != nil {
  1977  		t.Fatalf("failed to list contents of tmp dir: %s", err)
  1978  	}
  1979  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  1980  		t.Fatalf("context should have been deleted, but wasn't")
  1981  	}
  1982  
  1983  	logDone("build - verify context cleanup works properly after a failed build")
  1984  }
  1985  
  1986  func TestBuildCmd(t *testing.T) {
  1987  	name := "testbuildcmd"
  1988  	expected := "[/bin/echo Hello World]"
  1989  	defer deleteImages(name)
  1990  	_, err := buildImage(name,
  1991  		`FROM scratch
  1992          CMD ["/bin/echo", "Hello World"]`,
  1993  		true)
  1994  	if err != nil {
  1995  		t.Fatal(err)
  1996  	}
  1997  	res, err := inspectField(name, "Config.Cmd")
  1998  	if err != nil {
  1999  		t.Fatal(err)
  2000  	}
  2001  	if res != expected {
  2002  		t.Fatalf("Cmd %s, expected %s", res, expected)
  2003  	}
  2004  	logDone("build - cmd")
  2005  }
  2006  
  2007  func TestBuildExpose(t *testing.T) {
  2008  	name := "testbuildexpose"
  2009  	expected := "map[2375/tcp:map[]]"
  2010  	defer deleteImages(name)
  2011  	_, err := buildImage(name,
  2012  		`FROM scratch
  2013          EXPOSE 2375`,
  2014  		true)
  2015  	if err != nil {
  2016  		t.Fatal(err)
  2017  	}
  2018  	res, err := inspectField(name, "Config.ExposedPorts")
  2019  	if err != nil {
  2020  		t.Fatal(err)
  2021  	}
  2022  	if res != expected {
  2023  		t.Fatalf("Exposed ports %s, expected %s", res, expected)
  2024  	}
  2025  	logDone("build - expose")
  2026  }
  2027  
  2028  func TestBuildExposeMorePorts(t *testing.T) {
  2029  	// start building docker file with a large number of ports
  2030  	portList := make([]string, 50)
  2031  	line := make([]string, 100)
  2032  	expectedPorts := make([]int, len(portList)*len(line))
  2033  	for i := 0; i < len(portList); i++ {
  2034  		for j := 0; j < len(line); j++ {
  2035  			p := i*len(line) + j + 1
  2036  			line[j] = strconv.Itoa(p)
  2037  			expectedPorts[p-1] = p
  2038  		}
  2039  		if i == len(portList)-1 {
  2040  			portList[i] = strings.Join(line, " ")
  2041  		} else {
  2042  			portList[i] = strings.Join(line, " ") + ` \`
  2043  		}
  2044  	}
  2045  
  2046  	dockerfile := `FROM scratch
  2047  	EXPOSE {{range .}} {{.}}
  2048  	{{end}}`
  2049  	tmpl := template.Must(template.New("dockerfile").Parse(dockerfile))
  2050  	buf := bytes.NewBuffer(nil)
  2051  	tmpl.Execute(buf, portList)
  2052  
  2053  	name := "testbuildexpose"
  2054  	defer deleteImages(name)
  2055  	_, err := buildImage(name, buf.String(), true)
  2056  	if err != nil {
  2057  		t.Fatal(err)
  2058  	}
  2059  
  2060  	// check if all the ports are saved inside Config.ExposedPorts
  2061  	res, err := inspectFieldJSON(name, "Config.ExposedPorts")
  2062  	if err != nil {
  2063  		t.Fatal(err)
  2064  	}
  2065  	var exposedPorts map[string]interface{}
  2066  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  2067  		t.Fatal(err)
  2068  	}
  2069  
  2070  	for _, p := range expectedPorts {
  2071  		ep := fmt.Sprintf("%d/tcp", p)
  2072  		if _, ok := exposedPorts[ep]; !ok {
  2073  			t.Errorf("Port(%s) is not exposed", ep)
  2074  		} else {
  2075  			delete(exposedPorts, ep)
  2076  		}
  2077  	}
  2078  	if len(exposedPorts) != 0 {
  2079  		t.Errorf("Unexpected extra exposed ports %v", exposedPorts)
  2080  	}
  2081  	logDone("build - expose large number of ports")
  2082  }
  2083  
  2084  func TestBuildExposeOrder(t *testing.T) {
  2085  	buildID := func(name, exposed string) string {
  2086  		_, err := buildImage(name, fmt.Sprintf(`FROM scratch
  2087  		EXPOSE %s`, exposed), true)
  2088  		if err != nil {
  2089  			t.Fatal(err)
  2090  		}
  2091  		id, err := inspectField(name, "Id")
  2092  		if err != nil {
  2093  			t.Fatal(err)
  2094  		}
  2095  		return id
  2096  	}
  2097  
  2098  	id1 := buildID("testbuildexpose1", "80 2375")
  2099  	id2 := buildID("testbuildexpose2", "2375 80")
  2100  	defer deleteImages("testbuildexpose1", "testbuildexpose2")
  2101  	if id1 != id2 {
  2102  		t.Errorf("EXPOSE should invalidate the cache only when ports actually changed")
  2103  	}
  2104  	logDone("build - expose order")
  2105  }
  2106  
  2107  func TestBuildEmptyEntrypointInheritance(t *testing.T) {
  2108  	name := "testbuildentrypointinheritance"
  2109  	name2 := "testbuildentrypointinheritance2"
  2110  	defer deleteImages(name, name2)
  2111  
  2112  	_, err := buildImage(name,
  2113  		`FROM busybox
  2114          ENTRYPOINT ["/bin/echo"]`,
  2115  		true)
  2116  	if err != nil {
  2117  		t.Fatal(err)
  2118  	}
  2119  	res, err := inspectField(name, "Config.Entrypoint")
  2120  	if err != nil {
  2121  		t.Fatal(err)
  2122  	}
  2123  
  2124  	expected := "[/bin/echo]"
  2125  	if res != expected {
  2126  		t.Fatalf("Entrypoint %s, expected %s", res, expected)
  2127  	}
  2128  
  2129  	_, err = buildImage(name2,
  2130  		fmt.Sprintf(`FROM %s
  2131          ENTRYPOINT []`, name),
  2132  		true)
  2133  	if err != nil {
  2134  		t.Fatal(err)
  2135  	}
  2136  	res, err = inspectField(name2, "Config.Entrypoint")
  2137  	if err != nil {
  2138  		t.Fatal(err)
  2139  	}
  2140  
  2141  	expected = "[]"
  2142  
  2143  	if res != expected {
  2144  		t.Fatalf("Entrypoint %s, expected %s", res, expected)
  2145  	}
  2146  
  2147  	logDone("build - empty entrypoint inheritance")
  2148  }
  2149  
  2150  func TestBuildEmptyEntrypoint(t *testing.T) {
  2151  	name := "testbuildentrypoint"
  2152  	defer deleteImages(name)
  2153  	expected := "[]"
  2154  
  2155  	_, err := buildImage(name,
  2156  		`FROM busybox
  2157          ENTRYPOINT []`,
  2158  		true)
  2159  	if err != nil {
  2160  		t.Fatal(err)
  2161  	}
  2162  	res, err := inspectField(name, "Config.Entrypoint")
  2163  	if err != nil {
  2164  		t.Fatal(err)
  2165  	}
  2166  	if res != expected {
  2167  		t.Fatalf("Entrypoint %s, expected %s", res, expected)
  2168  	}
  2169  
  2170  	logDone("build - empty entrypoint")
  2171  }
  2172  
  2173  func TestBuildEntrypoint(t *testing.T) {
  2174  	name := "testbuildentrypoint"
  2175  	expected := "[/bin/echo]"
  2176  	defer deleteImages(name)
  2177  	_, err := buildImage(name,
  2178  		`FROM scratch
  2179          ENTRYPOINT ["/bin/echo"]`,
  2180  		true)
  2181  	if err != nil {
  2182  		t.Fatal(err)
  2183  	}
  2184  	res, err := inspectField(name, "Config.Entrypoint")
  2185  	if err != nil {
  2186  		t.Fatal(err)
  2187  	}
  2188  	if res != expected {
  2189  		t.Fatalf("Entrypoint %s, expected %s", res, expected)
  2190  	}
  2191  
  2192  	logDone("build - entrypoint")
  2193  }
  2194  
  2195  // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2196  func TestBuildOnBuildLimitedInheritence(t *testing.T) {
  2197  	var (
  2198  		out2, out3 string
  2199  	)
  2200  	{
  2201  		name1 := "testonbuildtrigger1"
  2202  		dockerfile1 := `
  2203  		FROM busybox
  2204  		RUN echo "GRANDPARENT"
  2205  		ONBUILD RUN echo "ONBUILD PARENT"
  2206  		`
  2207  		ctx, err := fakeContext(dockerfile1, nil)
  2208  		if err != nil {
  2209  			t.Fatal(err)
  2210  		}
  2211  		defer ctx.Close()
  2212  
  2213  		out1, _, err := dockerCmdInDir(t, ctx.Dir, "build", "-t", name1, ".")
  2214  		if err != nil {
  2215  			t.Fatalf("build failed to complete: %s, %v", out1, err)
  2216  		}
  2217  		defer deleteImages(name1)
  2218  	}
  2219  	{
  2220  		name2 := "testonbuildtrigger2"
  2221  		dockerfile2 := `
  2222  		FROM testonbuildtrigger1
  2223  		`
  2224  		ctx, err := fakeContext(dockerfile2, nil)
  2225  		if err != nil {
  2226  			t.Fatal(err)
  2227  		}
  2228  		defer ctx.Close()
  2229  
  2230  		out2, _, err = dockerCmdInDir(t, ctx.Dir, "build", "-t", name2, ".")
  2231  		if err != nil {
  2232  			t.Fatalf("build failed to complete: %s, %v", out2, err)
  2233  		}
  2234  		defer deleteImages(name2)
  2235  	}
  2236  	{
  2237  		name3 := "testonbuildtrigger3"
  2238  		dockerfile3 := `
  2239  		FROM testonbuildtrigger2
  2240  		`
  2241  		ctx, err := fakeContext(dockerfile3, nil)
  2242  		if err != nil {
  2243  			t.Fatal(err)
  2244  		}
  2245  		defer ctx.Close()
  2246  
  2247  		out3, _, err = dockerCmdInDir(t, ctx.Dir, "build", "-t", name3, ".")
  2248  		if err != nil {
  2249  			t.Fatalf("build failed to complete: %s, %v", out3, err)
  2250  		}
  2251  
  2252  		defer deleteImages(name3)
  2253  	}
  2254  
  2255  	// ONBUILD should be run in second build.
  2256  	if !strings.Contains(out2, "ONBUILD PARENT") {
  2257  		t.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2258  	}
  2259  
  2260  	// ONBUILD should *not* be run in third build.
  2261  	if strings.Contains(out3, "ONBUILD PARENT") {
  2262  		t.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2263  	}
  2264  
  2265  	logDone("build - onbuild")
  2266  }
  2267  
  2268  func TestBuildWithCache(t *testing.T) {
  2269  	name := "testbuildwithcache"
  2270  	defer deleteImages(name)
  2271  	id1, err := buildImage(name,
  2272  		`FROM scratch
  2273  		MAINTAINER dockerio
  2274  		EXPOSE 5432
  2275          ENTRYPOINT ["/bin/echo"]`,
  2276  		true)
  2277  	if err != nil {
  2278  		t.Fatal(err)
  2279  	}
  2280  	id2, err := buildImage(name,
  2281  		`FROM scratch
  2282  		MAINTAINER dockerio
  2283  		EXPOSE 5432
  2284          ENTRYPOINT ["/bin/echo"]`,
  2285  		true)
  2286  	if err != nil {
  2287  		t.Fatal(err)
  2288  	}
  2289  	if id1 != id2 {
  2290  		t.Fatal("The cache should have been used but hasn't.")
  2291  	}
  2292  	logDone("build - with cache")
  2293  }
  2294  
  2295  func TestBuildWithoutCache(t *testing.T) {
  2296  	name := "testbuildwithoutcache"
  2297  	name2 := "testbuildwithoutcache2"
  2298  	defer deleteImages(name, name2)
  2299  	id1, err := buildImage(name,
  2300  		`FROM scratch
  2301  		MAINTAINER dockerio
  2302  		EXPOSE 5432
  2303          ENTRYPOINT ["/bin/echo"]`,
  2304  		true)
  2305  	if err != nil {
  2306  		t.Fatal(err)
  2307  	}
  2308  
  2309  	id2, err := buildImage(name2,
  2310  		`FROM scratch
  2311  		MAINTAINER dockerio
  2312  		EXPOSE 5432
  2313          ENTRYPOINT ["/bin/echo"]`,
  2314  		false)
  2315  	if err != nil {
  2316  		t.Fatal(err)
  2317  	}
  2318  	if id1 == id2 {
  2319  		t.Fatal("The cache should have been invalided but hasn't.")
  2320  	}
  2321  	logDone("build - without cache")
  2322  }
  2323  
  2324  func TestBuildConditionalCache(t *testing.T) {
  2325  	name := "testbuildconditionalcache"
  2326  	name2 := "testbuildconditionalcache2"
  2327  	defer deleteImages(name, name2)
  2328  
  2329  	dockerfile := `
  2330  		FROM busybox
  2331          ADD foo /tmp/`
  2332  	ctx, err := fakeContext(dockerfile, map[string]string{
  2333  		"foo": "hello",
  2334  	})
  2335  
  2336  	id1, err := buildImageFromContext(name, ctx, true)
  2337  	if err != nil {
  2338  		t.Fatalf("Error building #1: %s", err)
  2339  	}
  2340  
  2341  	if err := ctx.Add("foo", "bye"); err != nil {
  2342  		t.Fatalf("Error modifying foo: %s", err)
  2343  	}
  2344  
  2345  	id2, err := buildImageFromContext(name, ctx, false)
  2346  	if err != nil {
  2347  		t.Fatalf("Error building #2: %s", err)
  2348  	}
  2349  	if id2 == id1 {
  2350  		t.Fatal("Should not have used the cache")
  2351  	}
  2352  
  2353  	id3, err := buildImageFromContext(name, ctx, true)
  2354  	if err != nil {
  2355  		t.Fatalf("Error building #3: %s", err)
  2356  	}
  2357  	if id3 != id2 {
  2358  		t.Fatal("Should have used the cache")
  2359  	}
  2360  
  2361  	logDone("build - conditional cache")
  2362  }
  2363  
  2364  func TestBuildADDLocalFileWithCache(t *testing.T) {
  2365  	name := "testbuildaddlocalfilewithcache"
  2366  	name2 := "testbuildaddlocalfilewithcache2"
  2367  	defer deleteImages(name, name2)
  2368  	dockerfile := `
  2369  		FROM busybox
  2370          MAINTAINER dockerio
  2371          ADD foo /usr/lib/bla/bar
  2372  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2373  	ctx, err := fakeContext(dockerfile, map[string]string{
  2374  		"foo": "hello",
  2375  	})
  2376  	defer ctx.Close()
  2377  	if err != nil {
  2378  		t.Fatal(err)
  2379  	}
  2380  	id1, err := buildImageFromContext(name, ctx, true)
  2381  	if err != nil {
  2382  		t.Fatal(err)
  2383  	}
  2384  	id2, err := buildImageFromContext(name2, ctx, true)
  2385  	if err != nil {
  2386  		t.Fatal(err)
  2387  	}
  2388  	if id1 != id2 {
  2389  		t.Fatal("The cache should have been used but hasn't.")
  2390  	}
  2391  	logDone("build - add local file with cache")
  2392  }
  2393  
  2394  func TestBuildADDMultipleLocalFileWithCache(t *testing.T) {
  2395  	name := "testbuildaddmultiplelocalfilewithcache"
  2396  	name2 := "testbuildaddmultiplelocalfilewithcache2"
  2397  	defer deleteImages(name, name2)
  2398  	dockerfile := `
  2399  		FROM busybox
  2400          MAINTAINER dockerio
  2401          ADD foo Dockerfile /usr/lib/bla/
  2402  		RUN [ "$(cat /usr/lib/bla/foo)" = "hello" ]`
  2403  	ctx, err := fakeContext(dockerfile, map[string]string{
  2404  		"foo": "hello",
  2405  	})
  2406  	defer ctx.Close()
  2407  	if err != nil {
  2408  		t.Fatal(err)
  2409  	}
  2410  	id1, err := buildImageFromContext(name, ctx, true)
  2411  	if err != nil {
  2412  		t.Fatal(err)
  2413  	}
  2414  	id2, err := buildImageFromContext(name2, ctx, true)
  2415  	if err != nil {
  2416  		t.Fatal(err)
  2417  	}
  2418  	if id1 != id2 {
  2419  		t.Fatal("The cache should have been used but hasn't.")
  2420  	}
  2421  	logDone("build - add multiple local files with cache")
  2422  }
  2423  
  2424  func TestBuildADDLocalFileWithoutCache(t *testing.T) {
  2425  	name := "testbuildaddlocalfilewithoutcache"
  2426  	name2 := "testbuildaddlocalfilewithoutcache2"
  2427  	defer deleteImages(name, name2)
  2428  	dockerfile := `
  2429  		FROM busybox
  2430          MAINTAINER dockerio
  2431          ADD foo /usr/lib/bla/bar
  2432  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2433  	ctx, err := fakeContext(dockerfile, map[string]string{
  2434  		"foo": "hello",
  2435  	})
  2436  	defer ctx.Close()
  2437  	if err != nil {
  2438  		t.Fatal(err)
  2439  	}
  2440  	id1, err := buildImageFromContext(name, ctx, true)
  2441  	if err != nil {
  2442  		t.Fatal(err)
  2443  	}
  2444  	id2, err := buildImageFromContext(name2, ctx, false)
  2445  	if err != nil {
  2446  		t.Fatal(err)
  2447  	}
  2448  	if id1 == id2 {
  2449  		t.Fatal("The cache should have been invalided but hasn't.")
  2450  	}
  2451  	logDone("build - add local file without cache")
  2452  }
  2453  
  2454  func TestBuildCopyDirButNotFile(t *testing.T) {
  2455  	name := "testbuildcopydirbutnotfile"
  2456  	name2 := "testbuildcopydirbutnotfile2"
  2457  	defer deleteImages(name, name2)
  2458  	dockerfile := `
  2459          FROM scratch
  2460          COPY dir /tmp/`
  2461  	ctx, err := fakeContext(dockerfile, map[string]string{
  2462  		"dir/foo": "hello",
  2463  	})
  2464  	defer ctx.Close()
  2465  	if err != nil {
  2466  		t.Fatal(err)
  2467  	}
  2468  	id1, err := buildImageFromContext(name, ctx, true)
  2469  	if err != nil {
  2470  		t.Fatal(err)
  2471  	}
  2472  	// Check that adding file with similar name doesn't mess with cache
  2473  	if err := ctx.Add("dir_file", "hello2"); err != nil {
  2474  		t.Fatal(err)
  2475  	}
  2476  	id2, err := buildImageFromContext(name2, ctx, true)
  2477  	if err != nil {
  2478  		t.Fatal(err)
  2479  	}
  2480  	if id1 != id2 {
  2481  		t.Fatal("The cache should have been used but wasn't")
  2482  	}
  2483  	logDone("build - add current directory but not file")
  2484  }
  2485  
  2486  func TestBuildADDCurrentDirWithCache(t *testing.T) {
  2487  	name := "testbuildaddcurrentdirwithcache"
  2488  	name2 := name + "2"
  2489  	name3 := name + "3"
  2490  	name4 := name + "4"
  2491  	name5 := name + "5"
  2492  	defer deleteImages(name, name2, name3, name4, name5)
  2493  	dockerfile := `
  2494          FROM scratch
  2495          MAINTAINER dockerio
  2496          ADD . /usr/lib/bla`
  2497  	ctx, err := fakeContext(dockerfile, map[string]string{
  2498  		"foo": "hello",
  2499  	})
  2500  	defer ctx.Close()
  2501  	if err != nil {
  2502  		t.Fatal(err)
  2503  	}
  2504  	id1, err := buildImageFromContext(name, ctx, true)
  2505  	if err != nil {
  2506  		t.Fatal(err)
  2507  	}
  2508  	// Check that adding file invalidate cache of "ADD ."
  2509  	if err := ctx.Add("bar", "hello2"); err != nil {
  2510  		t.Fatal(err)
  2511  	}
  2512  	id2, err := buildImageFromContext(name2, ctx, true)
  2513  	if err != nil {
  2514  		t.Fatal(err)
  2515  	}
  2516  	if id1 == id2 {
  2517  		t.Fatal("The cache should have been invalided but hasn't.")
  2518  	}
  2519  	// Check that changing file invalidate cache of "ADD ."
  2520  	if err := ctx.Add("foo", "hello1"); err != nil {
  2521  		t.Fatal(err)
  2522  	}
  2523  	id3, err := buildImageFromContext(name3, ctx, true)
  2524  	if err != nil {
  2525  		t.Fatal(err)
  2526  	}
  2527  	if id2 == id3 {
  2528  		t.Fatal("The cache should have been invalided but hasn't.")
  2529  	}
  2530  	// Check that changing file to same content invalidate cache of "ADD ."
  2531  	time.Sleep(1 * time.Second) // wait second because of mtime precision
  2532  	if err := ctx.Add("foo", "hello1"); err != nil {
  2533  		t.Fatal(err)
  2534  	}
  2535  	id4, err := buildImageFromContext(name4, ctx, true)
  2536  	if err != nil {
  2537  		t.Fatal(err)
  2538  	}
  2539  	if id3 == id4 {
  2540  		t.Fatal("The cache should have been invalided but hasn't.")
  2541  	}
  2542  	id5, err := buildImageFromContext(name5, ctx, true)
  2543  	if err != nil {
  2544  		t.Fatal(err)
  2545  	}
  2546  	if id4 != id5 {
  2547  		t.Fatal("The cache should have been used but hasn't.")
  2548  	}
  2549  	logDone("build - add current directory with cache")
  2550  }
  2551  
  2552  func TestBuildADDCurrentDirWithoutCache(t *testing.T) {
  2553  	name := "testbuildaddcurrentdirwithoutcache"
  2554  	name2 := "testbuildaddcurrentdirwithoutcache2"
  2555  	defer deleteImages(name, name2)
  2556  	dockerfile := `
  2557          FROM scratch
  2558          MAINTAINER dockerio
  2559          ADD . /usr/lib/bla`
  2560  	ctx, err := fakeContext(dockerfile, map[string]string{
  2561  		"foo": "hello",
  2562  	})
  2563  	defer ctx.Close()
  2564  	if err != nil {
  2565  		t.Fatal(err)
  2566  	}
  2567  	id1, err := buildImageFromContext(name, ctx, true)
  2568  	if err != nil {
  2569  		t.Fatal(err)
  2570  	}
  2571  	id2, err := buildImageFromContext(name2, ctx, false)
  2572  	if err != nil {
  2573  		t.Fatal(err)
  2574  	}
  2575  	if id1 == id2 {
  2576  		t.Fatal("The cache should have been invalided but hasn't.")
  2577  	}
  2578  	logDone("build - add current directory without cache")
  2579  }
  2580  
  2581  func TestBuildADDRemoteFileWithCache(t *testing.T) {
  2582  	name := "testbuildaddremotefilewithcache"
  2583  	defer deleteImages(name)
  2584  	server, err := fakeStorage(map[string]string{
  2585  		"baz": "hello",
  2586  	})
  2587  	if err != nil {
  2588  		t.Fatal(err)
  2589  	}
  2590  	defer server.Close()
  2591  	id1, err := buildImage(name,
  2592  		fmt.Sprintf(`FROM scratch
  2593          MAINTAINER dockerio
  2594          ADD %s/baz /usr/lib/baz/quux`, server.URL),
  2595  		true)
  2596  	if err != nil {
  2597  		t.Fatal(err)
  2598  	}
  2599  	id2, err := buildImage(name,
  2600  		fmt.Sprintf(`FROM scratch
  2601          MAINTAINER dockerio
  2602          ADD %s/baz /usr/lib/baz/quux`, server.URL),
  2603  		true)
  2604  	if err != nil {
  2605  		t.Fatal(err)
  2606  	}
  2607  	if id1 != id2 {
  2608  		t.Fatal("The cache should have been used but hasn't.")
  2609  	}
  2610  	logDone("build - add remote file with cache")
  2611  }
  2612  
  2613  func TestBuildADDRemoteFileWithoutCache(t *testing.T) {
  2614  	name := "testbuildaddremotefilewithoutcache"
  2615  	name2 := "testbuildaddremotefilewithoutcache2"
  2616  	defer deleteImages(name, name2)
  2617  	server, err := fakeStorage(map[string]string{
  2618  		"baz": "hello",
  2619  	})
  2620  	if err != nil {
  2621  		t.Fatal(err)
  2622  	}
  2623  	defer server.Close()
  2624  	id1, err := buildImage(name,
  2625  		fmt.Sprintf(`FROM scratch
  2626          MAINTAINER dockerio
  2627          ADD %s/baz /usr/lib/baz/quux`, server.URL),
  2628  		true)
  2629  	if err != nil {
  2630  		t.Fatal(err)
  2631  	}
  2632  	id2, err := buildImage(name2,
  2633  		fmt.Sprintf(`FROM scratch
  2634          MAINTAINER dockerio
  2635          ADD %s/baz /usr/lib/baz/quux`, server.URL),
  2636  		false)
  2637  	if err != nil {
  2638  		t.Fatal(err)
  2639  	}
  2640  	if id1 == id2 {
  2641  		t.Fatal("The cache should have been invalided but hasn't.")
  2642  	}
  2643  	logDone("build - add remote file without cache")
  2644  }
  2645  
  2646  func TestBuildADDRemoteFileMTime(t *testing.T) {
  2647  	name := "testbuildaddremotefilemtime"
  2648  	name2 := name + "2"
  2649  	name3 := name + "3"
  2650  	name4 := name + "4"
  2651  
  2652  	defer deleteImages(name, name2, name3, name4)
  2653  
  2654  	server, err := fakeStorage(map[string]string{"baz": "hello"})
  2655  	if err != nil {
  2656  		t.Fatal(err)
  2657  	}
  2658  	defer server.Close()
  2659  
  2660  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2661          MAINTAINER dockerio
  2662          ADD %s/baz /usr/lib/baz/quux`, server.URL), nil)
  2663  	if err != nil {
  2664  		t.Fatal(err)
  2665  	}
  2666  	defer ctx.Close()
  2667  
  2668  	id1, err := buildImageFromContext(name, ctx, true)
  2669  	if err != nil {
  2670  		t.Fatal(err)
  2671  	}
  2672  
  2673  	id2, err := buildImageFromContext(name2, ctx, true)
  2674  	if err != nil {
  2675  		t.Fatal(err)
  2676  	}
  2677  	if id1 != id2 {
  2678  		t.Fatal("The cache should have been used but wasn't - #1")
  2679  	}
  2680  
  2681  	// Now set baz's times to anything else and redo the build
  2682  	// This time the cache should not be used
  2683  	bazPath := path.Join(server.FakeContext.Dir, "baz")
  2684  	err = syscall.UtimesNano(bazPath, make([]syscall.Timespec, 2))
  2685  	if err != nil {
  2686  		t.Fatalf("Error setting mtime on %q: %v", bazPath, err)
  2687  	}
  2688  
  2689  	id3, err := buildImageFromContext(name3, ctx, true)
  2690  	if err != nil {
  2691  		t.Fatal(err)
  2692  	}
  2693  	if id1 == id3 {
  2694  		t.Fatal("The cache should not have been used but was")
  2695  	}
  2696  
  2697  	// And for good measure do it again and make sure cache is used this time
  2698  	id4, err := buildImageFromContext(name4, ctx, true)
  2699  	if err != nil {
  2700  		t.Fatal(err)
  2701  	}
  2702  	if id3 != id4 {
  2703  		t.Fatal("The cache should have been used but wasn't - #2")
  2704  	}
  2705  	logDone("build - add remote file testing mtime")
  2706  }
  2707  
  2708  func TestBuildADDLocalAndRemoteFilesWithCache(t *testing.T) {
  2709  	name := "testbuildaddlocalandremotefilewithcache"
  2710  	defer deleteImages(name)
  2711  	server, err := fakeStorage(map[string]string{
  2712  		"baz": "hello",
  2713  	})
  2714  	if err != nil {
  2715  		t.Fatal(err)
  2716  	}
  2717  	defer server.Close()
  2718  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2719          MAINTAINER dockerio
  2720          ADD foo /usr/lib/bla/bar
  2721          ADD %s/baz /usr/lib/baz/quux`, server.URL),
  2722  		map[string]string{
  2723  			"foo": "hello world",
  2724  		})
  2725  	if err != nil {
  2726  		t.Fatal(err)
  2727  	}
  2728  	defer ctx.Close()
  2729  	id1, err := buildImageFromContext(name, ctx, true)
  2730  	if err != nil {
  2731  		t.Fatal(err)
  2732  	}
  2733  	id2, err := buildImageFromContext(name, ctx, true)
  2734  	if err != nil {
  2735  		t.Fatal(err)
  2736  	}
  2737  	if id1 != id2 {
  2738  		t.Fatal("The cache should have been used but hasn't.")
  2739  	}
  2740  	logDone("build - add local and remote file with cache")
  2741  }
  2742  
  2743  func testContextTar(t *testing.T, compression archive.Compression) {
  2744  	ctx, err := fakeContext(
  2745  		`FROM busybox
  2746  ADD foo /foo
  2747  CMD ["cat", "/foo"]`,
  2748  		map[string]string{
  2749  			"foo": "bar",
  2750  		},
  2751  	)
  2752  	defer ctx.Close()
  2753  	if err != nil {
  2754  		t.Fatal(err)
  2755  	}
  2756  	context, err := archive.Tar(ctx.Dir, compression)
  2757  	if err != nil {
  2758  		t.Fatalf("failed to build context tar: %v", err)
  2759  	}
  2760  	name := "contexttar"
  2761  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
  2762  	defer deleteImages(name)
  2763  	buildCmd.Stdin = context
  2764  
  2765  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2766  		t.Fatalf("build failed to complete: %v %v", out, err)
  2767  	}
  2768  	logDone(fmt.Sprintf("build - build an image with a context tar, compression: %v", compression))
  2769  }
  2770  
  2771  func TestBuildContextTarGzip(t *testing.T) {
  2772  	testContextTar(t, archive.Gzip)
  2773  }
  2774  
  2775  func TestBuildContextTarNoCompression(t *testing.T) {
  2776  	testContextTar(t, archive.Uncompressed)
  2777  }
  2778  
  2779  func TestBuildNoContext(t *testing.T) {
  2780  	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  2781  	buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  2782  
  2783  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2784  		t.Fatalf("build failed to complete: %v %v", out, err)
  2785  	}
  2786  
  2787  	if out, _, err := dockerCmd(t, "run", "--rm", "nocontext"); out != "ok\n" || err != nil {
  2788  		t.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  2789  	}
  2790  
  2791  	deleteImages("nocontext")
  2792  	logDone("build - build an image with no context")
  2793  }
  2794  
  2795  // TODO: TestCaching
  2796  func TestBuildADDLocalAndRemoteFilesWithoutCache(t *testing.T) {
  2797  	name := "testbuildaddlocalandremotefilewithoutcache"
  2798  	name2 := "testbuildaddlocalandremotefilewithoutcache2"
  2799  	defer deleteImages(name, name2)
  2800  	server, err := fakeStorage(map[string]string{
  2801  		"baz": "hello",
  2802  	})
  2803  	if err != nil {
  2804  		t.Fatal(err)
  2805  	}
  2806  	defer server.Close()
  2807  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2808          MAINTAINER dockerio
  2809          ADD foo /usr/lib/bla/bar
  2810          ADD %s/baz /usr/lib/baz/quux`, server.URL),
  2811  		map[string]string{
  2812  			"foo": "hello world",
  2813  		})
  2814  	if err != nil {
  2815  		t.Fatal(err)
  2816  	}
  2817  	defer ctx.Close()
  2818  	id1, err := buildImageFromContext(name, ctx, true)
  2819  	if err != nil {
  2820  		t.Fatal(err)
  2821  	}
  2822  	id2, err := buildImageFromContext(name2, ctx, false)
  2823  	if err != nil {
  2824  		t.Fatal(err)
  2825  	}
  2826  	if id1 == id2 {
  2827  		t.Fatal("The cache should have been invalided but hasn't.")
  2828  	}
  2829  	logDone("build - add local and remote file without cache")
  2830  }
  2831  
  2832  func TestBuildWithVolumeOwnership(t *testing.T) {
  2833  	name := "testbuildimg"
  2834  	defer deleteImages(name)
  2835  
  2836  	_, err := buildImage(name,
  2837  		`FROM busybox:latest
  2838          RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  2839          VOLUME /test`,
  2840  		true)
  2841  
  2842  	if err != nil {
  2843  		t.Fatal(err)
  2844  	}
  2845  
  2846  	cmd := exec.Command(dockerBinary, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  2847  	out, _, err := runCommandWithOutput(cmd)
  2848  	if err != nil {
  2849  		t.Fatal(out, err)
  2850  	}
  2851  
  2852  	if expected := "drw-------"; !strings.Contains(out, expected) {
  2853  		t.Fatalf("expected %s received %s", expected, out)
  2854  	}
  2855  
  2856  	if expected := "daemon   daemon"; !strings.Contains(out, expected) {
  2857  		t.Fatalf("expected %s received %s", expected, out)
  2858  	}
  2859  
  2860  	logDone("build - volume ownership")
  2861  }
  2862  
  2863  // testing #1405 - config.Cmd does not get cleaned up if
  2864  // utilizing cache
  2865  func TestBuildEntrypointRunCleanup(t *testing.T) {
  2866  	name := "testbuildcmdcleanup"
  2867  	defer deleteImages(name)
  2868  	if _, err := buildImage(name,
  2869  		`FROM busybox
  2870          RUN echo "hello"`,
  2871  		true); err != nil {
  2872  		t.Fatal(err)
  2873  	}
  2874  
  2875  	ctx, err := fakeContext(`FROM busybox
  2876          RUN echo "hello"
  2877          ADD foo /foo
  2878          ENTRYPOINT ["/bin/echo"]`,
  2879  		map[string]string{
  2880  			"foo": "hello",
  2881  		})
  2882  	defer ctx.Close()
  2883  	if err != nil {
  2884  		t.Fatal(err)
  2885  	}
  2886  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2887  		t.Fatal(err)
  2888  	}
  2889  	res, err := inspectField(name, "Config.Cmd")
  2890  	if err != nil {
  2891  		t.Fatal(err)
  2892  	}
  2893  	// Cmd must be cleaned up
  2894  	if expected := "<no value>"; res != expected {
  2895  		t.Fatalf("Cmd %s, expected %s", res, expected)
  2896  	}
  2897  	logDone("build - cleanup cmd after RUN")
  2898  }
  2899  
  2900  func TestBuildForbiddenContextPath(t *testing.T) {
  2901  	name := "testbuildforbidpath"
  2902  	defer deleteImages(name)
  2903  	ctx, err := fakeContext(`FROM scratch
  2904          ADD ../../ test/
  2905          `,
  2906  		map[string]string{
  2907  			"test.txt":  "test1",
  2908  			"other.txt": "other",
  2909  		})
  2910  	defer ctx.Close()
  2911  	if err != nil {
  2912  		t.Fatal(err)
  2913  	}
  2914  
  2915  	expected := "Forbidden path outside the build context: ../../ "
  2916  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  2917  		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
  2918  	}
  2919  
  2920  	logDone("build - forbidden context path")
  2921  }
  2922  
  2923  func TestBuildADDFileNotFound(t *testing.T) {
  2924  	name := "testbuildaddnotfound"
  2925  	defer deleteImages(name)
  2926  	ctx, err := fakeContext(`FROM scratch
  2927          ADD foo /usr/local/bar`,
  2928  		map[string]string{"bar": "hello"})
  2929  	defer ctx.Close()
  2930  	if err != nil {
  2931  		t.Fatal(err)
  2932  	}
  2933  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2934  		if !strings.Contains(err.Error(), "foo: no such file or directory") {
  2935  			t.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  2936  		}
  2937  	} else {
  2938  		t.Fatal("Error must not be nil")
  2939  	}
  2940  	logDone("build - add file not found")
  2941  }
  2942  
  2943  func TestBuildInheritance(t *testing.T) {
  2944  	name := "testbuildinheritance"
  2945  	defer deleteImages(name)
  2946  
  2947  	_, err := buildImage(name,
  2948  		`FROM scratch
  2949  		EXPOSE 2375`,
  2950  		true)
  2951  	if err != nil {
  2952  		t.Fatal(err)
  2953  	}
  2954  	ports1, err := inspectField(name, "Config.ExposedPorts")
  2955  	if err != nil {
  2956  		t.Fatal(err)
  2957  	}
  2958  
  2959  	_, err = buildImage(name,
  2960  		fmt.Sprintf(`FROM %s
  2961  		ENTRYPOINT ["/bin/echo"]`, name),
  2962  		true)
  2963  	if err != nil {
  2964  		t.Fatal(err)
  2965  	}
  2966  
  2967  	res, err := inspectField(name, "Config.Entrypoint")
  2968  	if err != nil {
  2969  		t.Fatal(err)
  2970  	}
  2971  	if expected := "[/bin/echo]"; res != expected {
  2972  		t.Fatalf("Entrypoint %s, expected %s", res, expected)
  2973  	}
  2974  	ports2, err := inspectField(name, "Config.ExposedPorts")
  2975  	if err != nil {
  2976  		t.Fatal(err)
  2977  	}
  2978  	if ports1 != ports2 {
  2979  		t.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  2980  	}
  2981  	logDone("build - inheritance")
  2982  }
  2983  
  2984  func TestBuildFails(t *testing.T) {
  2985  	name := "testbuildfails"
  2986  	defer deleteImages(name)
  2987  	defer deleteAllContainers()
  2988  	_, err := buildImage(name,
  2989  		`FROM busybox
  2990  		RUN sh -c "exit 23"`,
  2991  		true)
  2992  	if err != nil {
  2993  		if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  2994  			t.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  2995  		}
  2996  	} else {
  2997  		t.Fatal("Error must not be nil")
  2998  	}
  2999  	logDone("build - fails")
  3000  }
  3001  
  3002  func TestBuildFailsDockerfileEmpty(t *testing.T) {
  3003  	name := "testbuildfails"
  3004  	defer deleteImages(name)
  3005  	_, err := buildImage(name, ``, true)
  3006  	if err != nil {
  3007  		if !strings.Contains(err.Error(), "Dockerfile cannot be empty") {
  3008  			t.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  3009  		}
  3010  	} else {
  3011  		t.Fatal("Error must not be nil")
  3012  	}
  3013  	logDone("build - fails with empty dockerfile")
  3014  }
  3015  
  3016  func TestBuildOnBuild(t *testing.T) {
  3017  	name := "testbuildonbuild"
  3018  	defer deleteImages(name)
  3019  	_, err := buildImage(name,
  3020  		`FROM busybox
  3021  		ONBUILD RUN touch foobar`,
  3022  		true)
  3023  	if err != nil {
  3024  		t.Fatal(err)
  3025  	}
  3026  	_, err = buildImage(name,
  3027  		fmt.Sprintf(`FROM %s
  3028  		RUN [ -f foobar ]`, name),
  3029  		true)
  3030  	if err != nil {
  3031  		t.Fatal(err)
  3032  	}
  3033  	logDone("build - onbuild")
  3034  }
  3035  
  3036  func TestBuildOnBuildForbiddenChained(t *testing.T) {
  3037  	name := "testbuildonbuildforbiddenchained"
  3038  	defer deleteImages(name)
  3039  	_, err := buildImage(name,
  3040  		`FROM busybox
  3041  		ONBUILD ONBUILD RUN touch foobar`,
  3042  		true)
  3043  	if err != nil {
  3044  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  3045  			t.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  3046  		}
  3047  	} else {
  3048  		t.Fatal("Error must not be nil")
  3049  	}
  3050  	logDone("build - onbuild forbidden chained")
  3051  }
  3052  
  3053  func TestBuildOnBuildForbiddenFrom(t *testing.T) {
  3054  	name := "testbuildonbuildforbiddenfrom"
  3055  	defer deleteImages(name)
  3056  	_, err := buildImage(name,
  3057  		`FROM busybox
  3058  		ONBUILD FROM scratch`,
  3059  		true)
  3060  	if err != nil {
  3061  		if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  3062  			t.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  3063  		}
  3064  	} else {
  3065  		t.Fatal("Error must not be nil")
  3066  	}
  3067  	logDone("build - onbuild forbidden from")
  3068  }
  3069  
  3070  func TestBuildOnBuildForbiddenMaintainer(t *testing.T) {
  3071  	name := "testbuildonbuildforbiddenmaintainer"
  3072  	defer deleteImages(name)
  3073  	_, err := buildImage(name,
  3074  		`FROM busybox
  3075  		ONBUILD MAINTAINER docker.io`,
  3076  		true)
  3077  	if err != nil {
  3078  		if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  3079  			t.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  3080  		}
  3081  	} else {
  3082  		t.Fatal("Error must not be nil")
  3083  	}
  3084  	logDone("build - onbuild forbidden maintainer")
  3085  }
  3086  
  3087  // gh #2446
  3088  func TestBuildAddToSymlinkDest(t *testing.T) {
  3089  	name := "testbuildaddtosymlinkdest"
  3090  	defer deleteImages(name)
  3091  	ctx, err := fakeContext(`FROM busybox
  3092          RUN mkdir /foo
  3093          RUN ln -s /foo /bar
  3094          ADD foo /bar/
  3095          RUN [ -f /bar/foo ]
  3096          RUN [ -f /foo/foo ]`,
  3097  		map[string]string{
  3098  			"foo": "hello",
  3099  		})
  3100  	if err != nil {
  3101  		t.Fatal(err)
  3102  	}
  3103  	defer ctx.Close()
  3104  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3105  		t.Fatal(err)
  3106  	}
  3107  	logDone("build - add to symlink destination")
  3108  }
  3109  
  3110  func TestBuildEscapeWhitespace(t *testing.T) {
  3111  	name := "testbuildescaping"
  3112  	defer deleteImages(name)
  3113  
  3114  	_, err := buildImage(name, `
  3115    FROM busybox
  3116    MAINTAINER "Docker \
  3117  IO <io@\
  3118  docker.com>"
  3119    `, true)
  3120  
  3121  	res, err := inspectField(name, "Author")
  3122  
  3123  	if err != nil {
  3124  		t.Fatal(err)
  3125  	}
  3126  
  3127  	if res != "\"Docker IO <io@docker.com>\"" {
  3128  		t.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  3129  	}
  3130  
  3131  	logDone("build - validate escaping whitespace")
  3132  }
  3133  
  3134  func TestBuildVerifyIntString(t *testing.T) {
  3135  	// Verify that strings that look like ints are still passed as strings
  3136  	name := "testbuildstringing"
  3137  	defer deleteImages(name)
  3138  
  3139  	_, err := buildImage(name, `
  3140    FROM busybox
  3141    MAINTAINER 123
  3142    `, true)
  3143  
  3144  	out, rc, err := runCommandWithOutput(exec.Command(dockerBinary, "inspect", name))
  3145  	if rc != 0 || err != nil {
  3146  		t.Fatalf("Unexcepted error from inspect: rc: %v  err: %v", rc, err)
  3147  	}
  3148  
  3149  	if !strings.Contains(out, "\"123\"") {
  3150  		t.Fatalf("Output does not contain the int as a string:\n%s", out)
  3151  	}
  3152  
  3153  	logDone("build - verify int/strings as strings")
  3154  }
  3155  
  3156  func TestBuildDockerignore(t *testing.T) {
  3157  	name := "testbuilddockerignore"
  3158  	defer deleteImages(name)
  3159  	dockerfile := `
  3160          FROM busybox
  3161          ADD . /bla
  3162  		RUN [[ -f /bla/src/x.go ]]
  3163  		RUN [[ -f /bla/Makefile ]]
  3164  		RUN [[ ! -e /bla/src/_vendor ]]
  3165  		RUN [[ ! -e /bla/.gitignore ]]
  3166  		RUN [[ ! -e /bla/README.md ]]
  3167  		RUN [[ ! -e /bla/.git ]]`
  3168  	ctx, err := fakeContext(dockerfile, map[string]string{
  3169  		"Makefile":         "all:",
  3170  		".git/HEAD":        "ref: foo",
  3171  		"src/x.go":         "package main",
  3172  		"src/_vendor/v.go": "package main",
  3173  		".gitignore":       "",
  3174  		"README.md":        "readme",
  3175  		".dockerignore":    ".git\npkg\n.gitignore\nsrc/_vendor\n*.md",
  3176  	})
  3177  	defer ctx.Close()
  3178  	if err != nil {
  3179  		t.Fatal(err)
  3180  	}
  3181  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3182  		t.Fatal(err)
  3183  	}
  3184  	logDone("build - test .dockerignore")
  3185  }
  3186  
  3187  func TestBuildDockerignoreCleanPaths(t *testing.T) {
  3188  	name := "testbuilddockerignorecleanpaths"
  3189  	defer deleteImages(name)
  3190  	dockerfile := `
  3191          FROM busybox
  3192          ADD . /tmp/
  3193          RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)`
  3194  	ctx, err := fakeContext(dockerfile, map[string]string{
  3195  		"foo":           "foo",
  3196  		"foo2":          "foo2",
  3197  		"dir1/foo":      "foo in dir1",
  3198  		".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  3199  	})
  3200  	if err != nil {
  3201  		t.Fatal(err)
  3202  	}
  3203  	defer ctx.Close()
  3204  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3205  		t.Fatal(err)
  3206  	}
  3207  	logDone("build - test .dockerignore with clean paths")
  3208  }
  3209  
  3210  func TestBuildDockerignoringDockerfile(t *testing.T) {
  3211  	name := "testbuilddockerignoredockerfile"
  3212  	defer deleteImages(name)
  3213  	dockerfile := `
  3214          FROM busybox
  3215  		ADD . /tmp/
  3216  		RUN ! ls /tmp/Dockerfile
  3217  		RUN ls /tmp/.dockerignore`
  3218  	ctx, err := fakeContext(dockerfile, map[string]string{
  3219  		"Dockerfile":    dockerfile,
  3220  		".dockerignore": "Dockerfile\n",
  3221  	})
  3222  	if err != nil {
  3223  		t.Fatal(err)
  3224  	}
  3225  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3226  		t.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3227  	}
  3228  
  3229  	// now try it with ./Dockerfile
  3230  	ctx.Add(".dockerignore", "./Dockerfile\n")
  3231  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3232  		t.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3233  	}
  3234  
  3235  	logDone("build - test .dockerignore of Dockerfile")
  3236  }
  3237  
  3238  func TestBuildDockerignoringRenamedDockerfile(t *testing.T) {
  3239  	name := "testbuilddockerignoredockerfile"
  3240  	defer deleteImages(name)
  3241  	dockerfile := `
  3242          FROM busybox
  3243  		ADD . /tmp/
  3244  		RUN ls /tmp/Dockerfile
  3245  		RUN ! ls /tmp/MyDockerfile
  3246  		RUN ls /tmp/.dockerignore`
  3247  	ctx, err := fakeContext(dockerfile, map[string]string{
  3248  		"Dockerfile":    "Should not use me",
  3249  		"MyDockerfile":  dockerfile,
  3250  		".dockerignore": "MyDockerfile\n",
  3251  	})
  3252  	if err != nil {
  3253  		t.Fatal(err)
  3254  	}
  3255  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3256  		t.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3257  	}
  3258  
  3259  	// now try it with ./MyDockerfile
  3260  	ctx.Add(".dockerignore", "./MyDockerfile\n")
  3261  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3262  		t.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3263  	}
  3264  
  3265  	logDone("build - test .dockerignore of renamed Dockerfile")
  3266  }
  3267  
  3268  func TestBuildDockerignoringDockerignore(t *testing.T) {
  3269  	name := "testbuilddockerignoredockerignore"
  3270  	defer deleteImages(name)
  3271  	dockerfile := `
  3272          FROM busybox
  3273  		ADD . /tmp/
  3274  		RUN ! ls /tmp/.dockerignore
  3275  		RUN ls /tmp/Dockerfile`
  3276  	ctx, err := fakeContext(dockerfile, map[string]string{
  3277  		"Dockerfile":    dockerfile,
  3278  		".dockerignore": ".dockerignore\n",
  3279  	})
  3280  	defer ctx.Close()
  3281  	if err != nil {
  3282  		t.Fatal(err)
  3283  	}
  3284  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3285  		t.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3286  	}
  3287  	logDone("build - test .dockerignore of .dockerignore")
  3288  }
  3289  
  3290  func TestBuildDockerignoreTouchDockerfile(t *testing.T) {
  3291  	var id1 string
  3292  	var id2 string
  3293  
  3294  	name := "testbuilddockerignoretouchdockerfile"
  3295  	defer deleteImages(name)
  3296  	dockerfile := `
  3297          FROM busybox
  3298  		ADD . /tmp/`
  3299  	ctx, err := fakeContext(dockerfile, map[string]string{
  3300  		"Dockerfile":    dockerfile,
  3301  		".dockerignore": "Dockerfile\n",
  3302  	})
  3303  	defer ctx.Close()
  3304  	if err != nil {
  3305  		t.Fatal(err)
  3306  	}
  3307  
  3308  	if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3309  		t.Fatalf("Didn't build it correctly:%s", err)
  3310  	}
  3311  
  3312  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3313  		t.Fatalf("Didn't build it correctly:%s", err)
  3314  	}
  3315  	if id1 != id2 {
  3316  		t.Fatalf("Didn't use the cache - 1")
  3317  	}
  3318  
  3319  	// Now make sure touching Dockerfile doesn't invalidate the cache
  3320  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3321  		t.Fatalf("Didn't add Dockerfile: %s", err)
  3322  	}
  3323  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3324  		t.Fatalf("Didn't build it correctly:%s", err)
  3325  	}
  3326  	if id1 != id2 {
  3327  		t.Fatalf("Didn't use the cache - 2")
  3328  	}
  3329  
  3330  	// One more time but just 'touch' it instead of changing the content
  3331  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3332  		t.Fatalf("Didn't add Dockerfile: %s", err)
  3333  	}
  3334  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3335  		t.Fatalf("Didn't build it correctly:%s", err)
  3336  	}
  3337  	if id1 != id2 {
  3338  		t.Fatalf("Didn't use the cache - 3")
  3339  	}
  3340  
  3341  	logDone("build - test .dockerignore touch dockerfile")
  3342  }
  3343  
  3344  func TestBuildDockerignoringWholeDir(t *testing.T) {
  3345  	name := "testbuilddockerignorewholedir"
  3346  	defer deleteImages(name)
  3347  	dockerfile := `
  3348          FROM busybox
  3349  		COPY . /
  3350  		RUN [[ ! -e /.gitignore ]]
  3351  		RUN [[ -f /Makefile ]]`
  3352  	ctx, err := fakeContext(dockerfile, map[string]string{
  3353  		"Dockerfile":    "FROM scratch",
  3354  		"Makefile":      "all:",
  3355  		".dockerignore": ".*\n",
  3356  	})
  3357  	defer ctx.Close()
  3358  	if err != nil {
  3359  		t.Fatal(err)
  3360  	}
  3361  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3362  		t.Fatal(err)
  3363  	}
  3364  	logDone("build - test .dockerignore whole dir with .*")
  3365  }
  3366  
  3367  func TestBuildLineBreak(t *testing.T) {
  3368  	name := "testbuildlinebreak"
  3369  	defer deleteImages(name)
  3370  	_, err := buildImage(name,
  3371  		`FROM  busybox
  3372  RUN    sh -c 'echo root:testpass \
  3373  	> /tmp/passwd'
  3374  RUN    mkdir -p /var/run/sshd
  3375  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3376  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3377  		true)
  3378  	if err != nil {
  3379  		t.Fatal(err)
  3380  	}
  3381  	logDone("build - line break with \\")
  3382  }
  3383  
  3384  func TestBuildEOLInLine(t *testing.T) {
  3385  	name := "testbuildeolinline"
  3386  	defer deleteImages(name)
  3387  	_, err := buildImage(name,
  3388  		`FROM   busybox
  3389  RUN    sh -c 'echo root:testpass > /tmp/passwd'
  3390  RUN    echo "foo \n bar"; echo "baz"
  3391  RUN    mkdir -p /var/run/sshd
  3392  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3393  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3394  		true)
  3395  	if err != nil {
  3396  		t.Fatal(err)
  3397  	}
  3398  	logDone("build - end of line in dockerfile instruction")
  3399  }
  3400  
  3401  func TestBuildCommentsShebangs(t *testing.T) {
  3402  	name := "testbuildcomments"
  3403  	defer deleteImages(name)
  3404  	_, err := buildImage(name,
  3405  		`FROM busybox
  3406  # This is an ordinary comment.
  3407  RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3408  RUN [ ! -x /hello.sh ]
  3409  # comment with line break \
  3410  RUN chmod +x /hello.sh
  3411  RUN [ -x /hello.sh ]
  3412  RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3413  RUN [ "$(/hello.sh)" = "hello world" ]`,
  3414  		true)
  3415  	if err != nil {
  3416  		t.Fatal(err)
  3417  	}
  3418  	logDone("build - comments and shebangs")
  3419  }
  3420  
  3421  func TestBuildUsersAndGroups(t *testing.T) {
  3422  	name := "testbuildusers"
  3423  	defer deleteImages(name)
  3424  	_, err := buildImage(name,
  3425  		`FROM busybox
  3426  
  3427  # Make sure our defaults work
  3428  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3429  
  3430  # TODO decide if "args.user = strconv.Itoa(syscall.Getuid())" is acceptable behavior for changeUser in sysvinit instead of "return nil" when "USER" isn't specified (so that we get the proper group list even if that is the empty list, even in the default case of not supplying an explicit USER to run as, which implies USER 0)
  3431  USER root
  3432  RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3433  
  3434  # Setup dockerio user and group
  3435  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  3436  RUN echo 'dockerio:x:1001:' >> /etc/group
  3437  
  3438  # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3439  USER dockerio
  3440  RUN id -G
  3441  RUN id -Gn
  3442  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3443  
  3444  # Switch back to root and double check that worked exactly as we might expect it to
  3445  USER root
  3446  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ]
  3447  
  3448  # Add a "supplementary" group for our dockerio user
  3449  RUN echo 'supplementary:x:1002:dockerio' >> /etc/group
  3450  
  3451  # ... and then go verify that we get it like we expect
  3452  USER dockerio
  3453  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3454  USER 1001
  3455  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3456  
  3457  # super test the new "user:group" syntax
  3458  USER dockerio:dockerio
  3459  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3460  USER 1001:dockerio
  3461  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3462  USER dockerio:1001
  3463  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3464  USER 1001:1001
  3465  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3466  USER dockerio:supplementary
  3467  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3468  USER dockerio:1002
  3469  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3470  USER 1001:supplementary
  3471  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3472  USER 1001:1002
  3473  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3474  
  3475  # make sure unknown uid/gid still works properly
  3476  USER 1042:1043
  3477  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3478  		true)
  3479  	if err != nil {
  3480  		t.Fatal(err)
  3481  	}
  3482  	logDone("build - users and groups")
  3483  }
  3484  
  3485  func TestBuildEnvUsage(t *testing.T) {
  3486  	name := "testbuildenvusage"
  3487  	defer deleteImages(name)
  3488  	dockerfile := `FROM busybox
  3489  ENV    HOME /root
  3490  ENV    PATH $HOME/bin:$PATH
  3491  ENV    PATH /tmp:$PATH
  3492  RUN    [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  3493  ENV    FOO /foo/baz
  3494  ENV    BAR /bar
  3495  ENV    BAZ $BAR
  3496  ENV    FOOPATH $PATH:$FOO
  3497  RUN    [ "$BAR" = "$BAZ" ]
  3498  RUN    [ "$FOOPATH" = "$PATH:/foo/baz" ]
  3499  ENV	   FROM hello/docker/world
  3500  ENV    TO /docker/world/hello
  3501  ADD    $FROM $TO
  3502  RUN    [ "$(cat $TO)" = "hello" ]
  3503  `
  3504  	ctx, err := fakeContext(dockerfile, map[string]string{
  3505  		"hello/docker/world": "hello",
  3506  	})
  3507  	if err != nil {
  3508  		t.Fatal(err)
  3509  	}
  3510  	defer ctx.Close()
  3511  
  3512  	_, err = buildImageFromContext(name, ctx, true)
  3513  	if err != nil {
  3514  		t.Fatal(err)
  3515  	}
  3516  	logDone("build - environment variables usage")
  3517  }
  3518  
  3519  func TestBuildEnvUsage2(t *testing.T) {
  3520  	name := "testbuildenvusage2"
  3521  	defer deleteImages(name)
  3522  	dockerfile := `FROM busybox
  3523  ENV    abc=def
  3524  RUN    [ "$abc" = "def" ]
  3525  ENV    def="hello world"
  3526  RUN    [ "$def" = "hello world" ]
  3527  ENV    def=hello\ world
  3528  RUN    [ "$def" = "hello world" ]
  3529  ENV    v1=abc v2="hi there"
  3530  RUN    [ "$v1" = "abc" ]
  3531  RUN    [ "$v2" = "hi there" ]
  3532  ENV    v3='boogie nights' v4="with'quotes too"
  3533  RUN    [ "$v3" = "boogie nights" ]
  3534  RUN    [ "$v4" = "with'quotes too" ]
  3535  ENV    abc=zzz FROM=hello/docker/world
  3536  ENV    abc=zzz TO=/docker/world/hello
  3537  ADD    $FROM $TO
  3538  RUN    [ "$(cat $TO)" = "hello" ]
  3539  ENV    abc "zzz"
  3540  RUN    [ $abc = \"zzz\" ]
  3541  ENV    abc 'yyy'
  3542  RUN    [ $abc = \'yyy\' ]
  3543  ENV    abc=
  3544  RUN    [ "$abc" = "" ]
  3545  `
  3546  	ctx, err := fakeContext(dockerfile, map[string]string{
  3547  		"hello/docker/world": "hello",
  3548  	})
  3549  	if err != nil {
  3550  		t.Fatal(err)
  3551  	}
  3552  	_, err = buildImageFromContext(name, ctx, true)
  3553  	if err != nil {
  3554  		t.Fatal(err)
  3555  	}
  3556  	logDone("build - environment variables usage2")
  3557  }
  3558  
  3559  func TestBuildAddScript(t *testing.T) {
  3560  	name := "testbuildaddscript"
  3561  	defer deleteImages(name)
  3562  	dockerfile := `
  3563  FROM busybox
  3564  ADD test /test
  3565  RUN ["chmod","+x","/test"]
  3566  RUN ["/test"]
  3567  RUN [ "$(cat /testfile)" = 'test!' ]`
  3568  	ctx, err := fakeContext(dockerfile, map[string]string{
  3569  		"test": "#!/bin/sh\necho 'test!' > /testfile",
  3570  	})
  3571  	if err != nil {
  3572  		t.Fatal(err)
  3573  	}
  3574  	defer ctx.Close()
  3575  
  3576  	_, err = buildImageFromContext(name, ctx, true)
  3577  	if err != nil {
  3578  		t.Fatal(err)
  3579  	}
  3580  	logDone("build - add and run script")
  3581  }
  3582  
  3583  func TestBuildAddTar(t *testing.T) {
  3584  	name := "testbuildaddtar"
  3585  	defer deleteImages(name)
  3586  
  3587  	ctx := func() *FakeContext {
  3588  		dockerfile := `
  3589  FROM busybox
  3590  ADD test.tar /
  3591  RUN cat /test/foo | grep Hi
  3592  ADD test.tar /test.tar
  3593  RUN cat /test.tar/test/foo | grep Hi
  3594  ADD test.tar /unlikely-to-exist
  3595  RUN cat /unlikely-to-exist/test/foo | grep Hi
  3596  ADD test.tar /unlikely-to-exist-trailing-slash/
  3597  RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  3598  RUN mkdir /existing-directory
  3599  ADD test.tar /existing-directory
  3600  RUN cat /existing-directory/test/foo | grep Hi
  3601  ADD test.tar /existing-directory-trailing-slash/
  3602  RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  3603  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3604  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3605  		if err != nil {
  3606  			t.Fatalf("failed to create test.tar archive: %v", err)
  3607  		}
  3608  		defer testTar.Close()
  3609  
  3610  		tw := tar.NewWriter(testTar)
  3611  
  3612  		if err := tw.WriteHeader(&tar.Header{
  3613  			Name: "test/foo",
  3614  			Size: 2,
  3615  		}); err != nil {
  3616  			t.Fatalf("failed to write tar file header: %v", err)
  3617  		}
  3618  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3619  			t.Fatalf("failed to write tar file content: %v", err)
  3620  		}
  3621  		if err := tw.Close(); err != nil {
  3622  			t.Fatalf("failed to close tar archive: %v", err)
  3623  		}
  3624  
  3625  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3626  			t.Fatalf("failed to open destination dockerfile: %v", err)
  3627  		}
  3628  		return &FakeContext{Dir: tmpDir}
  3629  	}()
  3630  	defer ctx.Close()
  3631  
  3632  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3633  		t.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  3634  	}
  3635  
  3636  	logDone("build - ADD tar")
  3637  }
  3638  
  3639  func TestBuildAddTarXz(t *testing.T) {
  3640  	name := "testbuildaddtarxz"
  3641  	defer deleteImages(name)
  3642  
  3643  	ctx := func() *FakeContext {
  3644  		dockerfile := `
  3645  			FROM busybox
  3646  			ADD test.tar.xz /
  3647  			RUN cat /test/foo | grep Hi`
  3648  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3649  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3650  		if err != nil {
  3651  			t.Fatalf("failed to create test.tar archive: %v", err)
  3652  		}
  3653  		defer testTar.Close()
  3654  
  3655  		tw := tar.NewWriter(testTar)
  3656  
  3657  		if err := tw.WriteHeader(&tar.Header{
  3658  			Name: "test/foo",
  3659  			Size: 2,
  3660  		}); err != nil {
  3661  			t.Fatalf("failed to write tar file header: %v", err)
  3662  		}
  3663  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3664  			t.Fatalf("failed to write tar file content: %v", err)
  3665  		}
  3666  		if err := tw.Close(); err != nil {
  3667  			t.Fatalf("failed to close tar archive: %v", err)
  3668  		}
  3669  		xzCompressCmd := exec.Command("xz", "test.tar")
  3670  		xzCompressCmd.Dir = tmpDir
  3671  		out, _, err := runCommandWithOutput(xzCompressCmd)
  3672  		if err != nil {
  3673  			t.Fatal(err, out)
  3674  		}
  3675  
  3676  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3677  			t.Fatalf("failed to open destination dockerfile: %v", err)
  3678  		}
  3679  		return &FakeContext{Dir: tmpDir}
  3680  	}()
  3681  
  3682  	defer ctx.Close()
  3683  
  3684  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3685  		t.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  3686  	}
  3687  
  3688  	logDone("build - ADD tar.xz")
  3689  }
  3690  
  3691  func TestBuildAddTarXzGz(t *testing.T) {
  3692  	name := "testbuildaddtarxzgz"
  3693  	defer deleteImages(name)
  3694  
  3695  	ctx := func() *FakeContext {
  3696  		dockerfile := `
  3697  			FROM busybox
  3698  			ADD test.tar.xz.gz /
  3699  			RUN ls /test.tar.xz.gz`
  3700  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3701  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3702  		if err != nil {
  3703  			t.Fatalf("failed to create test.tar archive: %v", err)
  3704  		}
  3705  		defer testTar.Close()
  3706  
  3707  		tw := tar.NewWriter(testTar)
  3708  
  3709  		if err := tw.WriteHeader(&tar.Header{
  3710  			Name: "test/foo",
  3711  			Size: 2,
  3712  		}); err != nil {
  3713  			t.Fatalf("failed to write tar file header: %v", err)
  3714  		}
  3715  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3716  			t.Fatalf("failed to write tar file content: %v", err)
  3717  		}
  3718  		if err := tw.Close(); err != nil {
  3719  			t.Fatalf("failed to close tar archive: %v", err)
  3720  		}
  3721  
  3722  		xzCompressCmd := exec.Command("xz", "test.tar")
  3723  		xzCompressCmd.Dir = tmpDir
  3724  		out, _, err := runCommandWithOutput(xzCompressCmd)
  3725  		if err != nil {
  3726  			t.Fatal(err, out)
  3727  		}
  3728  
  3729  		gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  3730  		gzipCompressCmd.Dir = tmpDir
  3731  		out, _, err = runCommandWithOutput(gzipCompressCmd)
  3732  		if err != nil {
  3733  			t.Fatal(err, out)
  3734  		}
  3735  
  3736  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3737  			t.Fatalf("failed to open destination dockerfile: %v", err)
  3738  		}
  3739  		return &FakeContext{Dir: tmpDir}
  3740  	}()
  3741  
  3742  	defer ctx.Close()
  3743  
  3744  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3745  		t.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  3746  	}
  3747  
  3748  	logDone("build - ADD tar.xz.gz")
  3749  }
  3750  
  3751  func TestBuildFromGIT(t *testing.T) {
  3752  	name := "testbuildfromgit"
  3753  	defer deleteImages(name)
  3754  	git, err := fakeGIT("repo", map[string]string{
  3755  		"Dockerfile": `FROM busybox
  3756  					ADD first /first
  3757  					RUN [ -f /first ]
  3758  					MAINTAINER docker`,
  3759  		"first": "test git data",
  3760  	})
  3761  	if err != nil {
  3762  		t.Fatal(err)
  3763  	}
  3764  	defer git.Close()
  3765  
  3766  	_, err = buildImageFromPath(name, git.RepoURL, true)
  3767  	if err != nil {
  3768  		t.Fatal(err)
  3769  	}
  3770  	res, err := inspectField(name, "Author")
  3771  	if err != nil {
  3772  		t.Fatal(err)
  3773  	}
  3774  	if res != "docker" {
  3775  		t.Fatalf("Maintainer should be docker, got %s", res)
  3776  	}
  3777  	logDone("build - build from GIT")
  3778  }
  3779  
  3780  func TestBuildCleanupCmdOnEntrypoint(t *testing.T) {
  3781  	name := "testbuildcmdcleanuponentrypoint"
  3782  	defer deleteImages(name)
  3783  	if _, err := buildImage(name,
  3784  		`FROM scratch
  3785          CMD ["test"]
  3786  		ENTRYPOINT ["echo"]`,
  3787  		true); err != nil {
  3788  		t.Fatal(err)
  3789  	}
  3790  	if _, err := buildImage(name,
  3791  		fmt.Sprintf(`FROM %s
  3792  		ENTRYPOINT ["cat"]`, name),
  3793  		true); err != nil {
  3794  		t.Fatal(err)
  3795  	}
  3796  	res, err := inspectField(name, "Config.Cmd")
  3797  	if err != nil {
  3798  		t.Fatal(err)
  3799  	}
  3800  	if expected := "<no value>"; res != expected {
  3801  		t.Fatalf("Cmd %s, expected %s", res, expected)
  3802  	}
  3803  	res, err = inspectField(name, "Config.Entrypoint")
  3804  	if err != nil {
  3805  		t.Fatal(err)
  3806  	}
  3807  	if expected := "[cat]"; res != expected {
  3808  		t.Fatalf("Entrypoint %s, expected %s", res, expected)
  3809  	}
  3810  	logDone("build - cleanup cmd on ENTRYPOINT")
  3811  }
  3812  
  3813  func TestBuildClearCmd(t *testing.T) {
  3814  	name := "testbuildclearcmd"
  3815  	defer deleteImages(name)
  3816  	_, err := buildImage(name,
  3817  		`From scratch
  3818     ENTRYPOINT ["/bin/bash"]
  3819     CMD []`,
  3820  		true)
  3821  	if err != nil {
  3822  		t.Fatal(err)
  3823  	}
  3824  	res, err := inspectFieldJSON(name, "Config.Cmd")
  3825  	if err != nil {
  3826  		t.Fatal(err)
  3827  	}
  3828  	if res != "[]" {
  3829  		t.Fatalf("Cmd %s, expected %s", res, "[]")
  3830  	}
  3831  	logDone("build - clearcmd")
  3832  }
  3833  
  3834  func TestBuildEmptyCmd(t *testing.T) {
  3835  	name := "testbuildemptycmd"
  3836  	defer deleteImages(name)
  3837  	if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil {
  3838  		t.Fatal(err)
  3839  	}
  3840  	res, err := inspectFieldJSON(name, "Config.Cmd")
  3841  	if err != nil {
  3842  		t.Fatal(err)
  3843  	}
  3844  	if res != "null" {
  3845  		t.Fatalf("Cmd %s, expected %s", res, "null")
  3846  	}
  3847  	logDone("build - empty cmd")
  3848  }
  3849  
  3850  func TestBuildOnBuildOutput(t *testing.T) {
  3851  	name := "testbuildonbuildparent"
  3852  	defer deleteImages(name)
  3853  	if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  3854  		t.Fatal(err)
  3855  	}
  3856  
  3857  	childname := "testbuildonbuildchild"
  3858  	defer deleteImages(childname)
  3859  
  3860  	_, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  3861  	if err != nil {
  3862  		t.Fatal(err)
  3863  	}
  3864  
  3865  	if !strings.Contains(out, "Trigger 0, RUN echo foo") {
  3866  		t.Fatal("failed to find the ONBUILD output", out)
  3867  	}
  3868  
  3869  	logDone("build - onbuild output")
  3870  }
  3871  
  3872  func TestBuildInvalidTag(t *testing.T) {
  3873  	name := "abcd:" + makeRandomString(200)
  3874  	defer deleteImages(name)
  3875  	_, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true)
  3876  	// if the error doesnt check for illegal tag name, or the image is built
  3877  	// then this should fail
  3878  	if !strings.Contains(out, "Illegal tag name") || strings.Contains(out, "Sending build context to Docker daemon") {
  3879  		t.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  3880  	}
  3881  	logDone("build - invalid tag")
  3882  }
  3883  
  3884  func TestBuildCmdShDashC(t *testing.T) {
  3885  	name := "testbuildcmdshc"
  3886  	defer deleteImages(name)
  3887  	if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  3888  		t.Fatal(err)
  3889  	}
  3890  
  3891  	res, err := inspectFieldJSON(name, "Config.Cmd")
  3892  	if err != nil {
  3893  		t.Fatal(err, res)
  3894  	}
  3895  
  3896  	expected := `["/bin/sh","-c","echo cmd"]`
  3897  
  3898  	if res != expected {
  3899  		t.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  3900  	}
  3901  
  3902  	logDone("build - cmd should have sh -c for non-json")
  3903  }
  3904  
  3905  func TestBuildCmdJSONNoShDashC(t *testing.T) {
  3906  	name := "testbuildcmdjson"
  3907  	defer deleteImages(name)
  3908  	if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  3909  		t.Fatal(err)
  3910  	}
  3911  
  3912  	res, err := inspectFieldJSON(name, "Config.Cmd")
  3913  	if err != nil {
  3914  		t.Fatal(err, res)
  3915  	}
  3916  
  3917  	expected := `["echo","cmd"]`
  3918  
  3919  	if res != expected {
  3920  		t.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  3921  	}
  3922  
  3923  	logDone("build - cmd should not have /bin/sh -c for json")
  3924  }
  3925  
  3926  func TestBuildIgnoreInvalidInstruction(t *testing.T) {
  3927  	name := "testbuildignoreinvalidinstruction"
  3928  	defer deleteImages(name)
  3929  
  3930  	out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true)
  3931  	if err != nil {
  3932  		t.Fatal(err, out)
  3933  	}
  3934  
  3935  	logDone("build - ignore invalid Dockerfile instruction")
  3936  }
  3937  
  3938  func TestBuildEntrypointInheritance(t *testing.T) {
  3939  	defer deleteImages("parent", "child")
  3940  	defer deleteAllContainers()
  3941  
  3942  	if _, err := buildImage("parent", `
  3943      FROM busybox
  3944      ENTRYPOINT exit 130
  3945      `, true); err != nil {
  3946  		t.Fatal(err)
  3947  	}
  3948  
  3949  	status, _ := runCommand(exec.Command(dockerBinary, "run", "parent"))
  3950  
  3951  	if status != 130 {
  3952  		t.Fatalf("expected exit code 130 but received %d", status)
  3953  	}
  3954  
  3955  	if _, err := buildImage("child", `
  3956      FROM parent
  3957      ENTRYPOINT exit 5
  3958      `, true); err != nil {
  3959  		t.Fatal(err)
  3960  	}
  3961  
  3962  	status, _ = runCommand(exec.Command(dockerBinary, "run", "child"))
  3963  
  3964  	if status != 5 {
  3965  		t.Fatalf("expected exit code 5 but received %d", status)
  3966  	}
  3967  
  3968  	logDone("build - clear entrypoint")
  3969  }
  3970  
  3971  func TestBuildEntrypointInheritanceInspect(t *testing.T) {
  3972  	var (
  3973  		name     = "testbuildepinherit"
  3974  		name2    = "testbuildepinherit2"
  3975  		expected = `["/bin/sh","-c","echo quux"]`
  3976  	)
  3977  
  3978  	defer deleteImages(name, name2)
  3979  	defer deleteAllContainers()
  3980  
  3981  	if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  3982  		t.Fatal(err)
  3983  	}
  3984  
  3985  	if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  3986  		t.Fatal(err)
  3987  	}
  3988  
  3989  	res, err := inspectFieldJSON(name2, "Config.Entrypoint")
  3990  	if err != nil {
  3991  		t.Fatal(err, res)
  3992  	}
  3993  
  3994  	if res != expected {
  3995  		t.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  3996  	}
  3997  
  3998  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
  3999  	if err != nil {
  4000  		t.Fatal(err, out)
  4001  	}
  4002  
  4003  	expected = "quux"
  4004  
  4005  	if strings.TrimSpace(out) != expected {
  4006  		t.Fatalf("Expected output is %s, got %s", expected, out)
  4007  	}
  4008  
  4009  	logDone("build - entrypoint override inheritance properly")
  4010  }
  4011  
  4012  func TestBuildRunShEntrypoint(t *testing.T) {
  4013  	name := "testbuildentrypoint"
  4014  	defer deleteImages(name)
  4015  	_, err := buildImage(name,
  4016  		`FROM busybox
  4017                                  ENTRYPOINT /bin/echo`,
  4018  		true)
  4019  	if err != nil {
  4020  		t.Fatal(err)
  4021  	}
  4022  
  4023  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4024  
  4025  	if err != nil {
  4026  		t.Fatal(err, out)
  4027  	}
  4028  
  4029  	logDone("build - entrypoint with /bin/echo running successfully")
  4030  }
  4031  
  4032  func TestBuildExoticShellInterpolation(t *testing.T) {
  4033  	name := "testbuildexoticshellinterpolation"
  4034  	defer deleteImages(name)
  4035  
  4036  	_, err := buildImage(name, `
  4037  		FROM busybox
  4038  		
  4039  		ENV SOME_VAR a.b.c
  4040  
  4041  		RUN [ "$SOME_VAR"       = 'a.b.c' ]
  4042  		RUN [ "${SOME_VAR}"     = 'a.b.c' ]
  4043  		RUN [ "${SOME_VAR%.*}"  = 'a.b'   ]
  4044  		RUN [ "${SOME_VAR%%.*}" = 'a'     ]
  4045  		RUN [ "${SOME_VAR#*.}"  = 'b.c'   ]
  4046  		RUN [ "${SOME_VAR##*.}" = 'c'     ]
  4047  		RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  4048  		RUN [ "${#SOME_VAR}"    = '5'     ]
  4049  
  4050  		RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  4051  		RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  4052  		RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  4053  		RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  4054  	`, false)
  4055  	if err != nil {
  4056  		t.Fatal(err)
  4057  	}
  4058  
  4059  	logDone("build - exotic shell interpolation")
  4060  }
  4061  
  4062  func TestBuildVerifySingleQuoteFails(t *testing.T) {
  4063  	// This testcase is supposed to generate an error because the
  4064  	// JSON array we're passing in on the CMD uses single quotes instead
  4065  	// of double quotes (per the JSON spec). This means we interpret it
  4066  	// as a "string" insead of "JSON array" and pass it on to "sh -c" and
  4067  	// it should barf on it.
  4068  	name := "testbuildsinglequotefails"
  4069  	defer deleteImages(name)
  4070  	defer deleteAllContainers()
  4071  
  4072  	_, err := buildImage(name,
  4073  		`FROM busybox
  4074  		CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  4075  		true)
  4076  	_, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4077  
  4078  	if err == nil {
  4079  		t.Fatal("The image was not supposed to be able to run")
  4080  	}
  4081  
  4082  	logDone("build - verify single quotes fail")
  4083  }
  4084  
  4085  func TestBuildVerboseOut(t *testing.T) {
  4086  	name := "testbuildverboseout"
  4087  	defer deleteImages(name)
  4088  
  4089  	_, out, err := buildImageWithOut(name,
  4090  		`FROM busybox
  4091  RUN echo 123`,
  4092  		false)
  4093  
  4094  	if err != nil {
  4095  		t.Fatal(err)
  4096  	}
  4097  	if !strings.Contains(out, "\n123\n") {
  4098  		t.Fatalf("Output should contain %q: %q", "123", out)
  4099  	}
  4100  
  4101  	logDone("build - verbose output from commands")
  4102  }
  4103  
  4104  func TestBuildWithTabs(t *testing.T) {
  4105  	name := "testbuildwithtabs"
  4106  	defer deleteImages(name)
  4107  	_, err := buildImage(name,
  4108  		"FROM busybox\nRUN echo\tone\t\ttwo", true)
  4109  	if err != nil {
  4110  		t.Fatal(err)
  4111  	}
  4112  	res, err := inspectFieldJSON(name, "ContainerConfig.Cmd")
  4113  	if err != nil {
  4114  		t.Fatal(err)
  4115  	}
  4116  	expected := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  4117  	if res != expected {
  4118  		t.Fatalf("Missing tabs.\nGot:%s\nExp:%s", res, expected)
  4119  	}
  4120  	logDone("build - with tabs")
  4121  }
  4122  
  4123  func TestBuildStderr(t *testing.T) {
  4124  	// This test just makes sure that no non-error output goes
  4125  	// to stderr
  4126  	name := "testbuildstderr"
  4127  	defer deleteImages(name)
  4128  	_, _, stderr, err := buildImageWithStdoutStderr(name,
  4129  		"FROM busybox\nRUN echo one", true)
  4130  	if err != nil {
  4131  		t.Fatal(err)
  4132  	}
  4133  	if stderr != "" {
  4134  		t.Fatalf("Stderr should have been empty, instead its: %q", stderr)
  4135  	}
  4136  	logDone("build - testing stderr")
  4137  }
  4138  
  4139  func TestBuildChownSingleFile(t *testing.T) {
  4140  	name := "testbuildchownsinglefile"
  4141  	defer deleteImages(name)
  4142  
  4143  	ctx, err := fakeContext(`
  4144  FROM busybox
  4145  COPY test /
  4146  RUN ls -l /test
  4147  RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  4148  `, map[string]string{
  4149  		"test": "test",
  4150  	})
  4151  	if err != nil {
  4152  		t.Fatal(err)
  4153  	}
  4154  	defer ctx.Close()
  4155  
  4156  	if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  4157  		t.Fatal(err)
  4158  	}
  4159  
  4160  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4161  		t.Fatal(err)
  4162  	}
  4163  
  4164  	logDone("build - change permission on single file")
  4165  }
  4166  
  4167  func TestBuildSymlinkBreakout(t *testing.T) {
  4168  	name := "testbuildsymlinkbreakout"
  4169  	tmpdir, err := ioutil.TempDir("", name)
  4170  	if err != nil {
  4171  		t.Fatal(err)
  4172  	}
  4173  	defer os.RemoveAll(tmpdir)
  4174  	ctx := filepath.Join(tmpdir, "context")
  4175  	if err := os.MkdirAll(ctx, 0755); err != nil {
  4176  		t.Fatal(err)
  4177  	}
  4178  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  4179  	from busybox
  4180  	add symlink.tar /
  4181  	add inject /symlink/
  4182  	`), 0644); err != nil {
  4183  		t.Fatal(err)
  4184  	}
  4185  	inject := filepath.Join(ctx, "inject")
  4186  	if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  4187  		t.Fatal(err)
  4188  	}
  4189  	f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  4190  	if err != nil {
  4191  		t.Fatal(err)
  4192  	}
  4193  	w := tar.NewWriter(f)
  4194  	w.WriteHeader(&tar.Header{
  4195  		Name:     "symlink2",
  4196  		Typeflag: tar.TypeSymlink,
  4197  		Linkname: "/../../../../../../../../../../../../../../",
  4198  		Uid:      os.Getuid(),
  4199  		Gid:      os.Getgid(),
  4200  	})
  4201  	w.WriteHeader(&tar.Header{
  4202  		Name:     "symlink",
  4203  		Typeflag: tar.TypeSymlink,
  4204  		Linkname: filepath.Join("symlink2", tmpdir),
  4205  		Uid:      os.Getuid(),
  4206  		Gid:      os.Getgid(),
  4207  	})
  4208  	w.Close()
  4209  	f.Close()
  4210  	if _, err := buildImageFromContext(name, &FakeContext{Dir: ctx}, false); err != nil {
  4211  		t.Fatal(err)
  4212  	}
  4213  	if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  4214  		t.Fatal("symlink breakout - inject")
  4215  	} else if !os.IsNotExist(err) {
  4216  		t.Fatalf("unexpected error: %v", err)
  4217  	}
  4218  	logDone("build - symlink breakout")
  4219  }
  4220  
  4221  func TestBuildXZHost(t *testing.T) {
  4222  	name := "testbuildxzhost"
  4223  	defer deleteImages(name)
  4224  
  4225  	ctx, err := fakeContext(`
  4226  FROM busybox
  4227  ADD xz /usr/local/sbin/
  4228  RUN chmod 755 /usr/local/sbin/xz
  4229  ADD test.xz /
  4230  RUN [ ! -e /injected ]`,
  4231  		map[string]string{
  4232  			"test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  4233  				"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  4234  				"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  4235  			"xz": "#!/bin/sh\ntouch /injected",
  4236  		})
  4237  
  4238  	if err != nil {
  4239  		t.Fatal(err)
  4240  	}
  4241  	defer ctx.Close()
  4242  
  4243  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4244  		t.Fatal(err)
  4245  	}
  4246  
  4247  	logDone("build - xz host is being used")
  4248  }
  4249  
  4250  func TestBuildVolumesRetainContents(t *testing.T) {
  4251  	var (
  4252  		name     = "testbuildvolumescontent"
  4253  		expected = "some text"
  4254  	)
  4255  	defer deleteImages(name)
  4256  	ctx, err := fakeContext(`
  4257  FROM busybox
  4258  COPY content /foo/file
  4259  VOLUME /foo
  4260  CMD cat /foo/file`,
  4261  		map[string]string{
  4262  			"content": expected,
  4263  		})
  4264  	if err != nil {
  4265  		t.Fatal(err)
  4266  	}
  4267  	defer ctx.Close()
  4268  
  4269  	if _, err := buildImageFromContext(name, ctx, false); err != nil {
  4270  		t.Fatal(err)
  4271  	}
  4272  
  4273  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4274  	if err != nil {
  4275  		t.Fatal(err)
  4276  	}
  4277  	if out != expected {
  4278  		t.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  4279  	}
  4280  
  4281  	logDone("build - volumes retain contents in build")
  4282  }
  4283  
  4284  func TestBuildRenamedDockerfile(t *testing.T) {
  4285  	defer deleteAllContainers()
  4286  
  4287  	ctx, err := fakeContext(`FROM busybox
  4288  	RUN echo from Dockerfile`,
  4289  		map[string]string{
  4290  			"Dockerfile":       "FROM busybox\nRUN echo from Dockerfile",
  4291  			"files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  4292  			"files/dFile":      "FROM busybox\nRUN echo from files/dFile",
  4293  			"dFile":            "FROM busybox\nRUN echo from dFile",
  4294  		})
  4295  	defer ctx.Close()
  4296  	if err != nil {
  4297  		t.Fatal(err)
  4298  	}
  4299  
  4300  	out, _, err := dockerCmdInDir(t, ctx.Dir, "build", "-t", "test1", ".")
  4301  
  4302  	if err != nil {
  4303  		t.Fatalf("Failed to build: %s\n%s", out, err)
  4304  	}
  4305  	if !strings.Contains(out, "from Dockerfile") {
  4306  		t.Fatalf("Should have used Dockerfile, output:%s", out)
  4307  	}
  4308  
  4309  	out, _, err = dockerCmdInDir(t, ctx.Dir, "build", "-f", "files/Dockerfile", "-t", "test2", ".")
  4310  
  4311  	if err != nil {
  4312  		t.Fatal(err)
  4313  	}
  4314  	if !strings.Contains(out, "from files/Dockerfile") {
  4315  		t.Fatalf("Should have used files/Dockerfile, output:%s", out)
  4316  	}
  4317  
  4318  	out, _, err = dockerCmdInDir(t, ctx.Dir, "build", "--file=files/dFile", "-t", "test3", ".")
  4319  
  4320  	if err != nil {
  4321  		t.Fatal(err)
  4322  	}
  4323  	if !strings.Contains(out, "from files/dFile") {
  4324  		t.Fatalf("Should have used files/dFile, output:%s", out)
  4325  	}
  4326  
  4327  	out, _, err = dockerCmdInDir(t, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  4328  
  4329  	if err != nil {
  4330  		t.Fatal(err)
  4331  	}
  4332  	if !strings.Contains(out, "from dFile") {
  4333  		t.Fatalf("Should have used dFile, output:%s", out)
  4334  	}
  4335  
  4336  	out, _, err = dockerCmdInDir(t, ctx.Dir, "build", "--file=/etc/passwd", "-t", "test5", ".")
  4337  
  4338  	if err == nil {
  4339  		t.Fatalf("Was supposed to fail to find passwd")
  4340  	}
  4341  
  4342  	if !strings.Contains(out, "The Dockerfile (/etc/passwd) must be within the build context (.)") {
  4343  		t.Fatalf("Wrong error message for passwd:%v", out)
  4344  	}
  4345  
  4346  	out, _, err = dockerCmdInDir(t, ctx.Dir+"/files", "build", "-f", "../Dockerfile", "-t", "test5", "..")
  4347  
  4348  	if err != nil {
  4349  		t.Fatal(err)
  4350  	}
  4351  
  4352  	if !strings.Contains(out, "from Dockerfile") {
  4353  		t.Fatalf("Should have used root Dockerfile, output:%s", out)
  4354  	}
  4355  
  4356  	out, _, err = dockerCmdInDir(t, ctx.Dir+"/files", "build", "-f", ctx.Dir+"/files/Dockerfile", "-t", "test6", "..")
  4357  
  4358  	if err != nil {
  4359  		t.Fatal(err)
  4360  	}
  4361  
  4362  	if !strings.Contains(out, "from files/Dockerfile") {
  4363  		t.Fatalf("Should have used files Dockerfile - 2, output:%s", out)
  4364  	}
  4365  
  4366  	out, _, err = dockerCmdInDir(t, ctx.Dir+"/files", "build", "-f", "../Dockerfile", "-t", "test7", ".")
  4367  
  4368  	if err == nil || !strings.Contains(out, "must be within the build context") {
  4369  		t.Fatalf("Should have failed with Dockerfile out of context")
  4370  	}
  4371  
  4372  	out, _, err = dockerCmdInDir(t, "/tmp", "build", "-t", "test6", ctx.Dir)
  4373  
  4374  	if err != nil {
  4375  		t.Fatal(err)
  4376  	}
  4377  
  4378  	if !strings.Contains(out, "from Dockerfile") {
  4379  		t.Fatalf("Should have used root Dockerfile, output:%s", out)
  4380  	}
  4381  
  4382  	logDone("build - rename dockerfile")
  4383  }
  4384  
  4385  func TestBuildFromOfficialNames(t *testing.T) {
  4386  	name := "testbuildfromofficial"
  4387  	fromNames := []string{
  4388  		"busybox",
  4389  		"docker.io/busybox",
  4390  		"index.docker.io/busybox",
  4391  		"library/busybox",
  4392  		"docker.io/library/busybox",
  4393  		"index.docker.io/library/busybox",
  4394  	}
  4395  	for idx, fromName := range fromNames {
  4396  		imgName := fmt.Sprintf("%s%d", name, idx)
  4397  		_, err := buildImage(imgName, "FROM "+fromName, true)
  4398  		if err != nil {
  4399  			t.Errorf("Build failed using FROM %s: %s", fromName, err)
  4400  		}
  4401  		deleteImages(imgName)
  4402  	}
  4403  	logDone("build - from official names")
  4404  }