build_squash_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package build
  2. import (
  3. "bytes"
  4. "context"
  5. "io"
  6. "io/ioutil"
  7. "strings"
  8. "testing"
  9. "github.com/docker/docker/api/types"
  10. "github.com/docker/docker/integration-cli/cli/build/fakecontext"
  11. "github.com/docker/docker/integration-cli/daemon"
  12. "github.com/docker/docker/integration/internal/container"
  13. "github.com/docker/docker/pkg/stdcopy"
  14. "github.com/gotestyourself/gotestyourself/assert"
  15. is "github.com/gotestyourself/gotestyourself/assert/cmp"
  16. )
  17. func TestBuildSquashParent(t *testing.T) {
  18. d := daemon.New(t, "", "dockerd", daemon.Config{
  19. Experimental: true,
  20. })
  21. d.StartWithBusybox(t)
  22. defer d.Stop(t)
  23. client, err := d.NewClient()
  24. assert.NilError(t, err)
  25. dockerfile := `
  26. FROM busybox
  27. RUN echo hello > /hello
  28. RUN echo world >> /hello
  29. RUN echo hello > /remove_me
  30. ENV HELLO world
  31. RUN rm /remove_me
  32. `
  33. // build and get the ID that we can use later for history comparison
  34. ctx := context.Background()
  35. source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile))
  36. defer source.Close()
  37. name := "test"
  38. resp, err := client.ImageBuild(ctx,
  39. source.AsTarReader(t),
  40. types.ImageBuildOptions{
  41. Remove: true,
  42. ForceRemove: true,
  43. Tags: []string{name},
  44. })
  45. assert.NilError(t, err)
  46. _, err = io.Copy(ioutil.Discard, resp.Body)
  47. resp.Body.Close()
  48. assert.NilError(t, err)
  49. inspect, _, err := client.ImageInspectWithRaw(ctx, name)
  50. assert.NilError(t, err)
  51. origID := inspect.ID
  52. // build with squash
  53. resp, err = client.ImageBuild(ctx,
  54. source.AsTarReader(t),
  55. types.ImageBuildOptions{
  56. Remove: true,
  57. ForceRemove: true,
  58. Squash: true,
  59. Tags: []string{name},
  60. })
  61. assert.NilError(t, err)
  62. _, err = io.Copy(ioutil.Discard, resp.Body)
  63. resp.Body.Close()
  64. assert.NilError(t, err)
  65. cid := container.Run(t, ctx, client,
  66. container.WithImage(name),
  67. container.WithCmd("/bin/sh", "-c", "cat /hello"),
  68. )
  69. reader, err := client.ContainerLogs(ctx, cid, types.ContainerLogsOptions{
  70. ShowStdout: true,
  71. })
  72. assert.NilError(t, err)
  73. actualStdout := new(bytes.Buffer)
  74. actualStderr := ioutil.Discard
  75. _, err = stdcopy.StdCopy(actualStdout, actualStderr, reader)
  76. assert.NilError(t, err)
  77. assert.Check(t, is.Equal(strings.TrimSpace(actualStdout.String()), "hello\nworld"))
  78. container.Run(t, ctx, client,
  79. container.WithImage(name),
  80. container.WithCmd("/bin/sh", "-c", "[ ! -f /remove_me ]"),
  81. )
  82. container.Run(t, ctx, client,
  83. container.WithImage(name),
  84. container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" == "world" ]`),
  85. )
  86. origHistory, err := client.ImageHistory(ctx, origID)
  87. assert.NilError(t, err)
  88. testHistory, err := client.ImageHistory(ctx, name)
  89. assert.NilError(t, err)
  90. inspect, _, err = client.ImageInspectWithRaw(ctx, name)
  91. assert.NilError(t, err)
  92. assert.Check(t, is.Len(testHistory, len(origHistory)+1))
  93. assert.Check(t, is.Len(inspect.RootFS.Layers, 2))
  94. }