github.com/rish1988/moby@v25.0.2+incompatible/integration/build/build_squash_test.go (about) 1 package build 2 3 import ( 4 "bytes" 5 "io" 6 "strings" 7 "testing" 8 9 "github.com/docker/docker/api/types" 10 containertypes "github.com/docker/docker/api/types/container" 11 dclient "github.com/docker/docker/client" 12 "github.com/docker/docker/integration/internal/container" 13 "github.com/docker/docker/pkg/stdcopy" 14 "github.com/docker/docker/testutil" 15 "github.com/docker/docker/testutil/daemon" 16 "github.com/docker/docker/testutil/fakecontext" 17 "gotest.tools/v3/assert" 18 is "gotest.tools/v3/assert/cmp" 19 "gotest.tools/v3/skip" 20 ) 21 22 func TestBuildSquashParent(t *testing.T) { 23 skip.If(t, testEnv.DaemonInfo.OSType == "windows") 24 skip.If(t, testEnv.UsingSnapshotter(), "squash is not implemented for containerd image store") 25 26 ctx := testutil.StartSpan(baseContext, t) 27 28 var client dclient.APIClient 29 if !testEnv.DaemonInfo.ExperimentalBuild { 30 skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") 31 32 d := daemon.New(t, daemon.WithExperimental()) 33 d.StartWithBusybox(ctx, t) 34 defer d.Stop(t) 35 client = d.NewClientT(t) 36 } else { 37 client = testEnv.APIClient() 38 } 39 40 dockerfile := ` 41 FROM busybox 42 RUN echo hello > /hello 43 RUN echo world >> /hello 44 RUN echo hello > /remove_me 45 ENV HELLO world 46 RUN rm /remove_me 47 ` 48 49 // build and get the ID that we can use later for history comparison 50 source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile)) 51 defer source.Close() 52 53 name := strings.ToLower(t.Name()) 54 resp, err := client.ImageBuild(ctx, 55 source.AsTarReader(t), 56 types.ImageBuildOptions{ 57 Remove: true, 58 ForceRemove: true, 59 Tags: []string{name}, 60 }) 61 assert.NilError(t, err) 62 _, err = io.Copy(io.Discard, resp.Body) 63 resp.Body.Close() 64 assert.NilError(t, err) 65 66 inspect, _, err := client.ImageInspectWithRaw(ctx, name) 67 assert.NilError(t, err) 68 origID := inspect.ID 69 70 // build with squash 71 resp, err = client.ImageBuild(ctx, 72 source.AsTarReader(t), 73 types.ImageBuildOptions{ 74 Remove: true, 75 ForceRemove: true, 76 Squash: true, 77 Tags: []string{name}, 78 }) 79 assert.NilError(t, err) 80 _, err = io.Copy(io.Discard, resp.Body) 81 resp.Body.Close() 82 assert.NilError(t, err) 83 84 cid := container.Run(ctx, t, client, 85 container.WithImage(name), 86 container.WithCmd("/bin/sh", "-c", "cat /hello"), 87 ) 88 reader, err := client.ContainerLogs(ctx, cid, containertypes.LogsOptions{ 89 ShowStdout: true, 90 }) 91 assert.NilError(t, err) 92 93 actualStdout := new(bytes.Buffer) 94 actualStderr := io.Discard 95 _, err = stdcopy.StdCopy(actualStdout, actualStderr, reader) 96 assert.NilError(t, err) 97 assert.Check(t, is.Equal(strings.TrimSpace(actualStdout.String()), "hello\nworld")) 98 99 container.Run(ctx, t, client, 100 container.WithImage(name), 101 container.WithCmd("/bin/sh", "-c", "[ ! -f /remove_me ]"), 102 ) 103 container.Run(ctx, t, client, 104 container.WithImage(name), 105 container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" = "world" ]`), 106 ) 107 108 origHistory, err := client.ImageHistory(ctx, origID) 109 assert.NilError(t, err) 110 testHistory, err := client.ImageHistory(ctx, name) 111 assert.NilError(t, err) 112 113 inspect, _, err = client.ImageInspectWithRaw(ctx, name) 114 assert.NilError(t, err) 115 assert.Check(t, is.Len(testHistory, len(origHistory)+1)) 116 assert.Check(t, is.Len(inspect.RootFS.Layers, 2)) 117 }