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