diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index dbec07fab9..0a698308bc 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" "os/exec" "path/filepath" @@ -10,25 +11,6 @@ import ( "time" ) -func checkSimpleBuild(t *testing.T, dockerfile, name, inspectFormat, expected string) { - buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-") - buildCmd.Stdin = strings.NewReader(dockerfile) - out, exitCode, err := runCommandWithOutput(buildCmd) - errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err)) - if err != nil || exitCode != 0 { - t.Fatal("failed to build the image") - } - inspectCmd := exec.Command(dockerBinary, "inspect", "-f", inspectFormat, name) - out, exitCode, err = runCommandWithOutput(inspectCmd) - if err != nil || exitCode != 0 { - t.Fatalf("failed to inspect the image: %s", out) - } - out = strings.TrimSpace(out) - if out != expected { - t.Fatalf("From format %s expected %s, got %s", inspectFormat, expected, out) - } -} - func TestBuildCacheADD(t *testing.T) { buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildCacheADD", "1") buildCmd := exec.Command(dockerBinary, "build", "-t", "testcacheadd1", ".") @@ -606,129 +588,516 @@ func TestBuildRm(t *testing.T) { logDone("build - ensure --rm doesn't leave containers behind and that --rm=true is the default") logDone("build - ensure --rm=false overrides the default") } - -func TestBuildWithVolume(t *testing.T) { - checkSimpleBuild(t, - ` - FROM scratch - VOLUME /test - `, - "testbuildimg", - "{{json .Config.Volumes}}", - `{"/test":{}}`) - - deleteImages("testbuildimg") - logDone("build - with volume") +func TestBuildWithVolumes(t *testing.T) { + name := "testbuildvolumes" + expected := "map[/test1:map[] /test2:map[]]" + defer deleteImages(name) + _, err := buildImage(name, + `FROM scratch + VOLUME /test1 + VOLUME /test2`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Config.Volumes") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("Volumes %s, expected %s", res, expected) + } + logDone("build - with volumes") } func TestBuildMaintainer(t *testing.T) { - checkSimpleBuild(t, - ` - FROM scratch - MAINTAINER dockerio - `, - "testbuildimg", - "{{json .Author}}", - `"dockerio"`) - - deleteImages("testbuildimg") + name := "testbuildmaintainer" + expected := "dockerio" + defer deleteImages(name) + _, err := buildImage(name, + `FROM scratch + MAINTAINER dockerio`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Author") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("Maintainer %s, expected %s", res, expected) + } logDone("build - maintainer") } func TestBuildUser(t *testing.T) { - checkSimpleBuild(t, - ` - FROM busybox + name := "testbuilduser" + expected := "dockerio" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd USER dockerio - RUN [ $(whoami) = 'dockerio' ] - `, - "testbuildimg", - "{{json .Config.User}}", - `"dockerio"`) - - deleteImages("testbuildimg") + RUN [ $(whoami) = 'dockerio' ]`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Config.User") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("User %s, expected %s", res, expected) + } logDone("build - user") } func TestBuildRelativeWorkdir(t *testing.T) { - checkSimpleBuild(t, - ` - FROM busybox + name := "testbuildrelativeworkdir" + expected := "/test2/test3" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox RUN [ "$PWD" = '/' ] WORKDIR test1 RUN [ "$PWD" = '/test1' ] WORKDIR /test2 RUN [ "$PWD" = '/test2' ] WORKDIR test3 - RUN [ "$PWD" = '/test2/test3' ] - `, - "testbuildimg", - "{{json .Config.WorkingDir}}", - `"/test2/test3"`) - - deleteImages("testbuildimg") + RUN [ "$PWD" = '/test2/test3' ]`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Config.WorkingDir") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("Workdir %s, expected %s", res, expected) + } logDone("build - relative workdir") } func TestBuildEnv(t *testing.T) { - checkSimpleBuild(t, - ` - FROM busybox + name := "testbuildenv" + expected := "[HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=4243]" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox ENV PORT 4243 - RUN [ $(env | grep PORT) = 'PORT=4243' ] - `, - "testbuildimg", - "{{json .Config.Env}}", - `["HOME=/","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","PORT=4243"]`) - - deleteImages("testbuildimg") + RUN [ $(env | grep PORT) = 'PORT=4243' ]`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Config.Env") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("Env %s, expected %s", res, expected) + } logDone("build - env") } func TestBuildCmd(t *testing.T) { - checkSimpleBuild(t, - ` - FROM scratch - CMD ["/bin/echo", "Hello World"] - `, - "testbuildimg", - "{{json .Config.Cmd}}", - `["/bin/echo","Hello World"]`) - - deleteImages("testbuildimg") + name := "testbuildcmd" + expected := "[/bin/echo Hello World]" + defer deleteImages(name) + _, err := buildImage(name, + `FROM scratch + CMD ["/bin/echo", "Hello World"]`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Config.Cmd") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("Cmd %s, expected %s", res, expected) + } logDone("build - cmd") } func TestBuildExpose(t *testing.T) { - checkSimpleBuild(t, - ` - FROM scratch - EXPOSE 4243 - `, - - "testbuildimg", - "{{json .Config.ExposedPorts}}", - `{"4243/tcp":{}}`) - - deleteImages("testbuildimg") + name := "testbuildexpose" + expected := "map[4243/tcp:map[]]" + defer deleteImages(name) + _, err := buildImage(name, + `FROM scratch + EXPOSE 4243`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Config.ExposedPorts") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("Exposed ports %s, expected %s", res, expected) + } logDone("build - expose") } func TestBuildEntrypoint(t *testing.T) { - checkSimpleBuild(t, - ` - FROM scratch - ENTRYPOINT ["/bin/echo"] - `, - "testbuildimg", - "{{json .Config.Entrypoint}}", - `["/bin/echo"]`) - - deleteImages("testbuildimg") + name := "testbuildentrypoint" + expected := "[/bin/echo]" + defer deleteImages(name) + _, err := buildImage(name, + `FROM scratch + ENTRYPOINT ["/bin/echo"]`, + true) + if err != nil { + t.Fatal(err) + } + res, err := inspectField(name, "Config.Entrypoint") + if err != nil { + t.Fatal(err) + } + if res != expected { + t.Fatalf("Entrypoint %s, expected %s", res, expected) + } logDone("build - entrypoint") } -// TODO: TestCaching +func TestBuildWithCache(t *testing.T) { + name := "testbuildwithcache" + defer deleteImages(name) + id1, err := buildImage(name, + `FROM scratch + MAINTAINER dockerio + EXPOSE 5432 + ENTRYPOINT ["/bin/echo"]`, + true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImage(name, + `FROM scratch + MAINTAINER dockerio + EXPOSE 5432 + ENTRYPOINT ["/bin/echo"]`, + true) + if err != nil { + t.Fatal(err) + } + if id1 != id2 { + t.Fatal("The cache should have been used but hasn't.") + } + logDone("build - with cache") +} -// TODO: TestADDCacheInvalidation +func TestBuildWithoutCache(t *testing.T) { + name := "testbuildwithoutcache" + defer deleteImages(name) + id1, err := buildImage(name, + `FROM scratch + MAINTAINER dockerio + EXPOSE 5432 + ENTRYPOINT ["/bin/echo"]`, + true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImage(name, + `FROM scratch + MAINTAINER dockerio + EXPOSE 5432 + ENTRYPOINT ["/bin/echo"]`, + false) + if err != nil { + t.Fatal(err) + } + if id1 == id2 { + t.Fatal("The cache should have been invalided but hasn't.") + } + logDone("build - without cache") +} + +func TestBuildADDLocalFileWithCache(t *testing.T) { + name := "testbuildaddlocalfilewithcache" + defer deleteImages(name) + dockerfile := ` + FROM busybox + MAINTAINER dockerio + ADD foo /usr/lib/bla/bar + RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]` + ctx, err := fakeContext(dockerfile, map[string]string{ + "foo": "hello", + }) + defer ctx.Close() + if err != nil { + t.Fatal(err) + } + id1, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + if id1 != id2 { + t.Fatal("The cache should have been used but hasn't.") + } + logDone("build - add local file with cache") +} + +func TestBuildADDLocalFileWithoutCache(t *testing.T) { + name := "testbuildaddlocalfilewithoutcache" + defer deleteImages(name) + dockerfile := ` + FROM busybox + MAINTAINER dockerio + ADD foo /usr/lib/bla/bar + RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]` + ctx, err := fakeContext(dockerfile, map[string]string{ + "foo": "hello", + }) + defer ctx.Close() + if err != nil { + t.Fatal(err) + } + id1, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImageFromContext(name, ctx, false) + if err != nil { + t.Fatal(err) + } + if id1 == id2 { + t.Fatal("The cache should have been invalided but hasn't.") + } + logDone("build - add local file without cache") +} + +func TestBuildADDCurrentDirWithCache(t *testing.T) { + name := "testbuildaddcurrentdirwithcache" + defer deleteImages(name) + dockerfile := ` + FROM scratch + MAINTAINER dockerio + ADD . /usr/lib/bla` + ctx, err := fakeContext(dockerfile, map[string]string{ + "foo": "hello", + }) + defer ctx.Close() + if err != nil { + t.Fatal(err) + } + id1, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + // Check that adding file invalidate cache of "ADD ." + if err := ctx.Add("bar", "hello2"); err != nil { + t.Fatal(err) + } + id2, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + if id1 == id2 { + t.Fatal("The cache should have been invalided but hasn't.") + } + // Check that changing file invalidate cache of "ADD ." + if err := ctx.Add("foo", "hello1"); err != nil { + t.Fatal(err) + } + id3, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + if id2 == id3 { + t.Fatal("The cache should have been invalided but hasn't.") + } + // Check that changing file to same content invalidate cache of "ADD ." + time.Sleep(1 * time.Second) // wait second because of mtime precision + if err := ctx.Add("foo", "hello1"); err != nil { + t.Fatal(err) + } + id4, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + if id3 == id4 { + t.Fatal("The cache should have been invalided but hasn't.") + } + id5, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + if id4 != id5 { + t.Fatal("The cache should have been used but hasn't.") + } + logDone("build - add current directory with cache") +} + +func TestBuildADDCurrentDirWithoutCache(t *testing.T) { + name := "testbuildaddcurrentdirwithoutcache" + defer deleteImages(name) + dockerfile := ` + FROM scratch + MAINTAINER dockerio + ADD . /usr/lib/bla` + ctx, err := fakeContext(dockerfile, map[string]string{ + "foo": "hello", + }) + defer ctx.Close() + if err != nil { + t.Fatal(err) + } + id1, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImageFromContext(name, ctx, false) + if err != nil { + t.Fatal(err) + } + if id1 == id2 { + t.Fatal("The cache should have been invalided but hasn't.") + } + logDone("build - add current directory without cache") +} + +func TestBuildADDRemoteFileWithCache(t *testing.T) { + name := "testbuildaddremotefilewithcache" + defer deleteImages(name) + server, err := fakeStorage(map[string]string{ + "baz": "hello", + }) + if err != nil { + t.Fatal(err) + } + defer server.Close() + id1, err := buildImage(name, + fmt.Sprintf(`FROM scratch + MAINTAINER dockerio + ADD %s/baz /usr/lib/baz/quux`, server.URL), + true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImage(name, + fmt.Sprintf(`FROM scratch + MAINTAINER dockerio + ADD %s/baz /usr/lib/baz/quux`, server.URL), + true) + if err != nil { + t.Fatal(err) + } + if id1 != id2 { + t.Fatal("The cache should have been used but hasn't.") + } + logDone("build - add remote file with cache") +} + +func TestBuildADDRemoteFileWithoutCache(t *testing.T) { + name := "testbuildaddremotefilewithoutcache" + defer deleteImages(name) + server, err := fakeStorage(map[string]string{ + "baz": "hello", + }) + if err != nil { + t.Fatal(err) + } + defer server.Close() + id1, err := buildImage(name, + fmt.Sprintf(`FROM scratch + MAINTAINER dockerio + ADD %s/baz /usr/lib/baz/quux`, server.URL), + true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImage(name, + fmt.Sprintf(`FROM scratch + MAINTAINER dockerio + ADD %s/baz /usr/lib/baz/quux`, server.URL), + false) + if err != nil { + t.Fatal(err) + } + if id1 == id2 { + t.Fatal("The cache should have been invalided but hasn't.") + } + logDone("build - add remote file without cache") +} + +func TestBuildADDLocalAndRemoteFilesWithCache(t *testing.T) { + name := "testbuildaddlocalandremotefilewithcache" + defer deleteImages(name) + server, err := fakeStorage(map[string]string{ + "baz": "hello", + }) + if err != nil { + t.Fatal(err) + } + defer server.Close() + ctx, err := fakeContext(fmt.Sprintf(`FROM scratch + MAINTAINER dockerio + ADD foo /usr/lib/bla/bar + ADD %s/baz /usr/lib/baz/quux`, server.URL), + map[string]string{ + "foo": "hello world", + }) + if err != nil { + t.Fatal(err) + } + defer ctx.Close() + id1, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + if id1 != id2 { + t.Fatal("The cache should have been used but hasn't.") + } + logDone("build - add local and remote file with cache") +} + +func TestBuildADDLocalAndRemoteFilesWithoutCache(t *testing.T) { + name := "testbuildaddlocalandremotefilewithoutcache" + defer deleteImages(name) + server, err := fakeStorage(map[string]string{ + "baz": "hello", + }) + if err != nil { + t.Fatal(err) + } + defer server.Close() + ctx, err := fakeContext(fmt.Sprintf(`FROM scratch + MAINTAINER dockerio + ADD foo /usr/lib/bla/bar + ADD %s/baz /usr/lib/baz/quux`, server.URL), + map[string]string{ + "foo": "hello world", + }) + if err != nil { + t.Fatal(err) + } + defer ctx.Close() + id1, err := buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + id2, err := buildImageFromContext(name, ctx, false) + if err != nil { + t.Fatal(err) + } + if id1 == id2 { + t.Fatal("The cache should have been invalided but hasn't.") + } + logDone("build - add local and remote file without cache") +} diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 660d509e76..c1e306f2ee 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -2,7 +2,12 @@ package main import ( "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "os" "os/exec" + "path" "strconv" "strings" "testing" @@ -97,3 +102,120 @@ func getContainerCount() (int, error) { } return 0, fmt.Errorf("couldn't find the Container count in the output") } + +type FakeContext struct { + Dir string +} + +func (f *FakeContext) Add(file, content string) error { + filepath := path.Join(f.Dir, file) + dirpath := path.Dir(filepath) + if dirpath != "." { + if err := os.MkdirAll(dirpath, 0755); err != nil { + return err + } + } + return ioutil.WriteFile(filepath, []byte(content), 0644) +} + +func (f *FakeContext) Delete(file string) error { + filepath := path.Join(f.Dir, file) + return os.RemoveAll(filepath) +} + +func (f *FakeContext) Close() error { + return os.RemoveAll(f.Dir) +} + +func fakeContext(dockerfile string, files map[string]string) (*FakeContext, error) { + tmp, err := ioutil.TempDir("", "fake-context") + if err != nil { + return nil, err + } + ctx := &FakeContext{tmp} + for file, content := range files { + if err := ctx.Add(file, content); err != nil { + ctx.Close() + return nil, err + } + } + if err := ctx.Add("Dockerfile", dockerfile); err != nil { + ctx.Close() + return nil, err + } + return ctx, nil +} + +type FakeStorage struct { + *FakeContext + *httptest.Server +} + +func (f *FakeStorage) Close() error { + f.Server.Close() + return f.FakeContext.Close() +} + +func fakeStorage(files map[string]string) (*FakeStorage, error) { + tmp, err := ioutil.TempDir("", "fake-storage") + if err != nil { + return nil, err + } + ctx := &FakeContext{tmp} + for file, content := range files { + if err := ctx.Add(file, content); err != nil { + ctx.Close() + return nil, err + } + } + handler := http.FileServer(http.Dir(ctx.Dir)) + server := httptest.NewServer(handler) + return &FakeStorage{ + FakeContext: ctx, + Server: server, + }, nil +} + +func inspectField(name, field string) (string, error) { + format := fmt.Sprintf("{{.%s}}", field) + inspectCmd := exec.Command(dockerBinary, "inspect", "-f", format, name) + out, exitCode, err := runCommandWithOutput(inspectCmd) + if err != nil || exitCode != 0 { + return "", fmt.Errorf("failed to inspect %s: %s", name, out) + } + return strings.TrimSpace(out), nil +} + +func getIDByName(name string) (string, error) { + return inspectField(name, "Id") +} + +func buildImage(name, dockerfile string, useCache bool) (string, error) { + args := []string{"build", "-t", name} + if !useCache { + args = append(args, "--no-cache") + } + args = append(args, "-") + buildCmd := exec.Command(dockerBinary, args...) + buildCmd.Stdin = strings.NewReader(dockerfile) + out, exitCode, err := runCommandWithOutput(buildCmd) + if err != nil || exitCode != 0 { + return "", fmt.Errorf("failed to build the image: %s", out) + } + return getIDByName(name) +} + +func buildImageFromContext(name string, ctx *FakeContext, useCache bool) (string, error) { + args := []string{"build", "-t", name} + if !useCache { + args = append(args, "--no-cache") + } + args = append(args, ".") + buildCmd := exec.Command(dockerBinary, args...) + buildCmd.Dir = ctx.Dir + out, exitCode, err := runCommandWithOutput(buildCmd) + if err != nil || exitCode != 0 { + return "", fmt.Errorf("failed to build the image: %s", out) + } + return getIDByName(name) +} diff --git a/integration/buildfile_test.go b/integration/buildfile_test.go index c60bb64c7f..f91d5c2a69 100644 --- a/integration/buildfile_test.go +++ b/integration/buildfile_test.go @@ -445,226 +445,6 @@ func TestBuildEntrypointRunCleanup(t *testing.T) { } } -func checkCacheBehavior(t *testing.T, template testContextTemplate, expectHit bool) (imageId string) { - eng := NewTestEngine(t) - defer nuke(mkDaemonFromEngine(eng, t)) - - img, err := buildImage(template, t, eng, true) - if err != nil { - t.Fatal(err) - } - - imageId = img.ID - - img, err = buildImage(template, t, eng, expectHit) - if err != nil { - t.Fatal(err) - } - - if hit := imageId == img.ID; hit != expectHit { - t.Fatalf("Cache misbehavior, got hit=%t, expected hit=%t: (first: %s, second %s)", hit, expectHit, imageId, img.ID) - } - return -} - -func checkCacheBehaviorFromEngime(t *testing.T, template testContextTemplate, expectHit bool, eng *engine.Engine) (imageId string) { - img, err := buildImage(template, t, eng, true) - if err != nil { - t.Fatal(err) - } - - imageId = img.ID - - img, err = buildImage(template, t, eng, expectHit) - if err != nil { - t.Fatal(err) - } - - if hit := imageId == img.ID; hit != expectHit { - t.Fatalf("Cache misbehavior, got hit=%t, expected hit=%t: (first: %s, second %s)", hit, expectHit, imageId, img.ID) - } - return -} - -func TestBuildImageWithCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - `, - nil, nil} - checkCacheBehavior(t, template, true) -} - -func TestBuildExposeWithCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - expose 80 - run echo hello - `, - nil, nil} - checkCacheBehavior(t, template, true) -} - -func TestBuildImageWithoutCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - `, - nil, nil} - checkCacheBehavior(t, template, false) -} - -func TestBuildADDLocalFileWithCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - run echo "first" - add foo /usr/lib/bla/bar - run [ "$(cat /usr/lib/bla/bar)" = "hello" ] - run echo "second" - add . /src/ - run [ "$(cat /src/foo)" = "hello" ] - `, - [][2]string{ - {"foo", "hello"}, - }, - nil} - eng := NewTestEngine(t) - defer nuke(mkDaemonFromEngine(eng, t)) - - id1 := checkCacheBehaviorFromEngime(t, template, true, eng) - template.files = append(template.files, [2]string{"bar", "hello2"}) - id2 := checkCacheBehaviorFromEngime(t, template, true, eng) - if id1 == id2 { - t.Fatal("The cache should have been invalided but hasn't.") - } - id3 := checkCacheBehaviorFromEngime(t, template, true, eng) - if id2 != id3 { - t.Fatal("The cache should have been used but hasn't.") - } - template.files[1][1] = "hello3" - id4 := checkCacheBehaviorFromEngime(t, template, true, eng) - if id3 == id4 { - t.Fatal("The cache should have been invalided but hasn't.") - } - template.dockerfile += ` - add ./bar /src2/ - run ls /src2/bar - ` - id5 := checkCacheBehaviorFromEngime(t, template, true, eng) - if id4 == id5 { - t.Fatal("The cache should have been invalided but hasn't.") - } - template.files[1][1] = "hello4" - id6 := checkCacheBehaviorFromEngime(t, template, true, eng) - if id5 == id6 { - t.Fatal("The cache should have been invalided but hasn't.") - } - - template.dockerfile += ` - add bar /src2/bar2 - add /bar /src2/bar3 - run ls /src2/bar2 /src2/bar3 - ` - id7 := checkCacheBehaviorFromEngime(t, template, true, eng) - if id6 == id7 { - t.Fatal("The cache should have been invalided but hasn't.") - } - template.files[1][1] = "hello5" - id8 := checkCacheBehaviorFromEngime(t, template, true, eng) - if id7 == id8 { - t.Fatal("The cache should have been invalided but hasn't.") - } -} - -func TestBuildADDLocalFileWithoutCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - run echo "first" - add foo /usr/lib/bla/bar - run echo "second" - `, - [][2]string{{"foo", "hello"}}, - nil} - checkCacheBehavior(t, template, false) -} - -func TestBuildADDCurrentDirectoryWithCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - add . /usr/lib/bla - `, - nil, nil} - checkCacheBehavior(t, template, true) -} - -func TestBuildADDCurrentDirectoryWithoutCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - add . /usr/lib/bla - `, - nil, nil} - checkCacheBehavior(t, template, false) -} - -func TestBuildADDRemoteFileWithCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - run echo "first" - add http://{SERVERADDR}/baz /usr/lib/baz/quux - run echo "second" - `, - nil, - [][2]string{{"/baz", "world!"}}} - checkCacheBehavior(t, template, true) -} - -func TestBuildADDRemoteFileWithoutCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - run echo "first" - add http://{SERVERADDR}/baz /usr/lib/baz/quux - run echo "second" - `, - nil, - [][2]string{{"/baz", "world!"}}} - checkCacheBehavior(t, template, false) -} - -func TestBuildADDLocalAndRemoteFilesWithCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - run echo "first" - add foo /usr/lib/bla/bar - add http://{SERVERADDR}/baz /usr/lib/baz/quux - run echo "second" - `, - [][2]string{{"foo", "hello"}}, - [][2]string{{"/baz", "world!"}}} - checkCacheBehavior(t, template, true) -} - -func TestBuildADDLocalAndRemoteFilesWithoutCache(t *testing.T) { - template := testContextTemplate{` - from {IMAGE} - maintainer dockerio - run echo "first" - add foo /usr/lib/bla/bar - add http://{SERVERADDR}/baz /usr/lib/baz/quux - run echo "second" - `, - [][2]string{{"foo", "hello"}}, - [][2]string{{"/baz", "world!"}}} - checkCacheBehavior(t, template, false) -} - func TestForbiddenContextPath(t *testing.T) { eng := NewTestEngine(t) defer nuke(mkDaemonFromEngine(eng, t))