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  }