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  }