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