Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Tonis Tiigi authored on 2016/09/23 06:32:17... | ... |
@@ -6931,3 +6931,96 @@ func (s *DockerSuite) TestBuildWithFailure(c *check.C) { |
6931 | 6931 |
c.Assert(stdout, checker.Not(checker.Contains), "Step 1/2 : FROM busybox") |
6932 | 6932 |
c.Assert(stdout, checker.Not(checker.Contains), "Step 2/2 : RUN nobody") |
6933 | 6933 |
} |
6934 |
+ |
|
6935 |
+func (s *DockerSuite) TestBuildCacheFrom(c *check.C) { |
|
6936 |
+ testRequires(c, DaemonIsLinux) // All tests that do save are skipped in windows |
|
6937 |
+ dockerfile := ` |
|
6938 |
+ FROM busybox |
|
6939 |
+ ENV FOO=bar |
|
6940 |
+ ADD baz / |
|
6941 |
+ RUN touch bax` |
|
6942 |
+ ctx, err := fakeContext(dockerfile, map[string]string{ |
|
6943 |
+ "Dockerfile": dockerfile, |
|
6944 |
+ "baz": "baz", |
|
6945 |
+ }) |
|
6946 |
+ c.Assert(err, checker.IsNil) |
|
6947 |
+ defer ctx.Close() |
|
6948 |
+ |
|
6949 |
+ id1, err := buildImageFromContext("build1", ctx, true) |
|
6950 |
+ c.Assert(err, checker.IsNil) |
|
6951 |
+ |
|
6952 |
+ // rebuild with cache-from |
|
6953 |
+ id2, out, err := buildImageFromContextWithOut("build2", ctx, true, "--cache-from=build1") |
|
6954 |
+ c.Assert(err, checker.IsNil) |
|
6955 |
+ c.Assert(id1, checker.Equals, id2) |
|
6956 |
+ c.Assert(strings.Count(out, "Using cache"), checker.Equals, 3) |
|
6957 |
+ dockerCmd(c, "rmi", "build2") |
|
6958 |
+ |
|
6959 |
+ // no cache match with unknown source |
|
6960 |
+ id2, out, err = buildImageFromContextWithOut("build2", ctx, true, "--cache-from=nosuchtag") |
|
6961 |
+ c.Assert(err, checker.IsNil) |
|
6962 |
+ c.Assert(id1, checker.Not(checker.Equals), id2) |
|
6963 |
+ c.Assert(strings.Count(out, "Using cache"), checker.Equals, 0) |
|
6964 |
+ dockerCmd(c, "rmi", "build2") |
|
6965 |
+ |
|
6966 |
+ // clear parent images |
|
6967 |
+ tempDir, err := ioutil.TempDir("", "test-build-cache-from-") |
|
6968 |
+ if err != nil { |
|
6969 |
+ c.Fatalf("failed to create temporary directory: %s", tempDir) |
|
6970 |
+ } |
|
6971 |
+ defer os.RemoveAll(tempDir) |
|
6972 |
+ tempFile := filepath.Join(tempDir, "img.tar") |
|
6973 |
+ dockerCmd(c, "save", "-o", tempFile, "build1") |
|
6974 |
+ dockerCmd(c, "rmi", "build1") |
|
6975 |
+ dockerCmd(c, "load", "-i", tempFile) |
|
6976 |
+ parentID, _ := dockerCmd(c, "inspect", "-f", "{{.Parent}}", "build1") |
|
6977 |
+ c.Assert(strings.TrimSpace(parentID), checker.Equals, "") |
|
6978 |
+ |
|
6979 |
+ // cache still applies without parents |
|
6980 |
+ id2, out, err = buildImageFromContextWithOut("build2", ctx, true, "--cache-from=build1") |
|
6981 |
+ c.Assert(err, checker.IsNil) |
|
6982 |
+ c.Assert(id1, checker.Equals, id2) |
|
6983 |
+ c.Assert(strings.Count(out, "Using cache"), checker.Equals, 3) |
|
6984 |
+ history1, _ := dockerCmd(c, "history", "-q", "build2") |
|
6985 |
+ |
|
6986 |
+ // Retry, no new intermediate images |
|
6987 |
+ id3, out, err := buildImageFromContextWithOut("build3", ctx, true, "--cache-from=build1") |
|
6988 |
+ c.Assert(err, checker.IsNil) |
|
6989 |
+ c.Assert(id1, checker.Equals, id3) |
|
6990 |
+ c.Assert(strings.Count(out, "Using cache"), checker.Equals, 3) |
|
6991 |
+ history2, _ := dockerCmd(c, "history", "-q", "build3") |
|
6992 |
+ |
|
6993 |
+ c.Assert(history1, checker.Equals, history2) |
|
6994 |
+ dockerCmd(c, "rmi", "build2") |
|
6995 |
+ dockerCmd(c, "rmi", "build3") |
|
6996 |
+ dockerCmd(c, "rmi", "build1") |
|
6997 |
+ dockerCmd(c, "load", "-i", tempFile) |
|
6998 |
+ |
|
6999 |
+ // Modify file, everything up to last command and layers are reused |
|
7000 |
+ dockerfile = ` |
|
7001 |
+ FROM busybox |
|
7002 |
+ ENV FOO=bar |
|
7003 |
+ ADD baz / |
|
7004 |
+ RUN touch newfile` |
|
7005 |
+ err = ioutil.WriteFile(filepath.Join(ctx.Dir, "Dockerfile"), []byte(dockerfile), 0644) |
|
7006 |
+ c.Assert(err, checker.IsNil) |
|
7007 |
+ |
|
7008 |
+ id2, out, err = buildImageFromContextWithOut("build2", ctx, true, "--cache-from=build1") |
|
7009 |
+ c.Assert(err, checker.IsNil) |
|
7010 |
+ c.Assert(id1, checker.Not(checker.Equals), id2) |
|
7011 |
+ c.Assert(strings.Count(out, "Using cache"), checker.Equals, 2) |
|
7012 |
+ |
|
7013 |
+ layers1Str, _ := dockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build1") |
|
7014 |
+ layers2Str, _ := dockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build2") |
|
7015 |
+ |
|
7016 |
+ var layers1 []string |
|
7017 |
+ var layers2 []string |
|
7018 |
+ c.Assert(json.Unmarshal([]byte(layers1Str), &layers1), checker.IsNil) |
|
7019 |
+ c.Assert(json.Unmarshal([]byte(layers2Str), &layers2), checker.IsNil) |
|
7020 |
+ |
|
7021 |
+ c.Assert(len(layers1), checker.Equals, len(layers2)) |
|
7022 |
+ for i := 0; i < len(layers1)-1; i++ { |
|
7023 |
+ c.Assert(layers1[i], checker.Equals, layers2[i]) |
|
7024 |
+ } |
|
7025 |
+ c.Assert(layers1[len(layers1)-1], checker.Not(checker.Equals), layers2[len(layers1)-1]) |
|
7026 |
+} |