Browse Source

Merge pull request #6143 from LK4D4/move_some_more_tests_to_cli

Move some more tests to integration cli
Michael Crosby 11 years ago
parent
commit
f65fadbda0
3 changed files with 595 additions and 324 deletions
  1. 473 104
      integration-cli/docker_cli_build_test.go
  2. 122 0
      integration-cli/docker_utils.go
  3. 0 220
      integration/buildfile_test.go

+ 473 - 104
integration-cli/docker_cli_build_test.go

@@ -2,6 +2,7 @@ package main
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
 	"path/filepath"
 	"path/filepath"
@@ -10,25 +11,6 @@ import (
 	"time"
 	"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) {
 func TestBuildCacheADD(t *testing.T) {
 	buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildCacheADD", "1")
 	buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildCacheADD", "1")
 	buildCmd := exec.Command(dockerBinary, "build", "-t", "testcacheadd1", ".")
 	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 doesn't leave containers behind and that --rm=true is the default")
 	logDone("build - ensure --rm=false overrides 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) {
 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")
 	logDone("build - maintainer")
 }
 }
 
 
 func TestBuildUser(t *testing.T) {
 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
 		RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
 		USER dockerio
 		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")
 	logDone("build - user")
 }
 }
 
 
 func TestBuildRelativeWorkdir(t *testing.T) {
 func TestBuildRelativeWorkdir(t *testing.T) {
-	checkSimpleBuild(t,
-		`
-		FROM busybox
+	name := "testbuildrelativeworkdir"
+	expected := "/test2/test3"
+	defer deleteImages(name)
+	_, err := buildImage(name,
+		`FROM busybox
 		RUN [ "$PWD" = '/' ]
 		RUN [ "$PWD" = '/' ]
 		WORKDIR test1
 		WORKDIR test1
 		RUN [ "$PWD" = '/test1' ]
 		RUN [ "$PWD" = '/test1' ]
 		WORKDIR /test2
 		WORKDIR /test2
 		RUN [ "$PWD" = '/test2' ]
 		RUN [ "$PWD" = '/test2' ]
 		WORKDIR test3
 		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")
 	logDone("build - relative workdir")
 }
 }
 
 
 func TestBuildEnv(t *testing.T) {
 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
         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")
 	logDone("build - env")
 }
 }
 
 
 func TestBuildCmd(t *testing.T) {
 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")
 	logDone("build - cmd")
 }
 }
 
 
 func TestBuildExpose(t *testing.T) {
 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")
 	logDone("build - expose")
 }
 }
 
 
 func TestBuildEntrypoint(t *testing.T) {
 func TestBuildEntrypoint(t *testing.T) {
-	checkSimpleBuild(t,
-		`
+	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")
+}
+
+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")
+}
+
+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
         FROM scratch
-        ENTRYPOINT ["/bin/echo"]
-        `,
-		"testbuildimg",
-		"{{json .Config.Entrypoint}}",
-		`["/bin/echo"]`)
+        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")
+}
 
 
-	deleteImages("testbuildimg")
-	logDone("build - entrypoint")
+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")
 }
 }
 
 
-// TODO: TestCaching
+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")
+}
 
 
-// TODO: TestADDCacheInvalidation
+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")
+}

+ 122 - 0
integration-cli/docker_utils.go

@@ -2,7 +2,12 @@ package main
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/http/httptest"
+	"os"
 	"os/exec"
 	"os/exec"
+	"path"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
@@ -97,3 +102,120 @@ func getContainerCount() (int, error) {
 	}
 	}
 	return 0, fmt.Errorf("couldn't find the Container count in the output")
 	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)
+}

+ 0 - 220
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) {
 func TestForbiddenContextPath(t *testing.T) {
 	eng := NewTestEngine(t)
 	eng := NewTestEngine(t)
 	defer nuke(mkDaemonFromEngine(eng, t))
 	defer nuke(mkDaemonFromEngine(eng, t))