github.com/lacework-dev/go-moby@v20.10.12+incompatible/integration/build/build_squash_test.go (about)

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