build_squash_test.go 2.8 KB

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