exec_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package container // import "github.com/docker/docker/integration/container"
  2. import (
  3. "context"
  4. "io/ioutil"
  5. "testing"
  6. "time"
  7. "github.com/docker/docker/api/types"
  8. "github.com/docker/docker/api/types/strslice"
  9. "github.com/docker/docker/api/types/versions"
  10. "github.com/docker/docker/integration/internal/container"
  11. "gotest.tools/assert"
  12. is "gotest.tools/assert/cmp"
  13. "gotest.tools/skip"
  14. )
  15. // TestExecWithCloseStdin adds case for moby#37870 issue.
  16. func TestExecWithCloseStdin(t *testing.T) {
  17. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
  18. defer setupTest(t)()
  19. ctx := context.Background()
  20. client := testEnv.APIClient()
  21. // run top with detached mode
  22. cID := container.Run(t, ctx, client)
  23. expected := "closeIO"
  24. execResp, err := client.ContainerExecCreate(ctx, cID,
  25. types.ExecConfig{
  26. AttachStdin: true,
  27. AttachStdout: true,
  28. Cmd: strslice.StrSlice([]string{"sh", "-c", "cat && echo " + expected}),
  29. },
  30. )
  31. assert.NilError(t, err)
  32. resp, err := client.ContainerExecAttach(ctx, execResp.ID,
  33. types.ExecStartCheck{
  34. Detach: false,
  35. Tty: false,
  36. },
  37. )
  38. assert.NilError(t, err)
  39. defer resp.Close()
  40. // close stdin to send EOF to cat
  41. assert.NilError(t, resp.CloseWrite())
  42. var (
  43. waitCh = make(chan struct{})
  44. resCh = make(chan struct {
  45. content string
  46. err error
  47. })
  48. )
  49. go func() {
  50. close(waitCh)
  51. defer close(resCh)
  52. r, err := ioutil.ReadAll(resp.Reader)
  53. resCh <- struct {
  54. content string
  55. err error
  56. }{
  57. content: string(r),
  58. err: err,
  59. }
  60. }()
  61. <-waitCh
  62. select {
  63. case <-time.After(3 * time.Second):
  64. t.Fatal("failed to read the content in time")
  65. case got := <-resCh:
  66. assert.NilError(t, got.err)
  67. // NOTE: using Contains because no-tty's stream contains UX information
  68. // like size, stream type.
  69. assert.Assert(t, is.Contains(got.content, expected))
  70. }
  71. }
  72. func TestExec(t *testing.T) {
  73. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.35"), "broken in earlier versions")
  74. skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")
  75. defer setupTest(t)()
  76. ctx := context.Background()
  77. client := testEnv.APIClient()
  78. cID := container.Run(t, ctx, client, container.WithTty(true), container.WithWorkingDir("/root"))
  79. id, err := client.ContainerExecCreate(ctx, cID,
  80. types.ExecConfig{
  81. WorkingDir: "/tmp",
  82. Env: strslice.StrSlice([]string{"FOO=BAR"}),
  83. AttachStdout: true,
  84. Cmd: strslice.StrSlice([]string{"sh", "-c", "env"}),
  85. },
  86. )
  87. assert.NilError(t, err)
  88. resp, err := client.ContainerExecAttach(ctx, id.ID,
  89. types.ExecStartCheck{
  90. Detach: false,
  91. Tty: false,
  92. },
  93. )
  94. assert.NilError(t, err)
  95. defer resp.Close()
  96. r, err := ioutil.ReadAll(resp.Reader)
  97. assert.NilError(t, err)
  98. out := string(r)
  99. assert.NilError(t, err)
  100. assert.Assert(t, is.Contains(out, "PWD=/tmp"), "exec command not running in expected /tmp working directory")
  101. assert.Assert(t, is.Contains(out, "FOO=BAR"), "exec command not running with expected environment variable FOO")
  102. }
  103. func TestExecUser(t *testing.T) {
  104. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
  105. skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")
  106. defer setupTest(t)()
  107. ctx := context.Background()
  108. client := testEnv.APIClient()
  109. cID := container.Run(t, ctx, client, container.WithTty(true), container.WithUser("1:1"))
  110. result, err := container.Exec(ctx, client, cID, []string{"id"})
  111. assert.NilError(t, err)
  112. assert.Assert(t, is.Contains(result.Stdout(), "uid=1(daemon) gid=1(daemon)"), "exec command not running as uid/gid 1")
  113. }