gopkg.in/docker/docker.v20@v20.10.27/integration/build/build_squash_test.go (about)

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