github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/integration/container/exec_test.go (about)

     1  package container // import "github.com/docker/docker/integration/container"
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     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, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
    21  	defer setupTest(t)()
    22  
    23  	ctx := context.Background()
    24  	client := testEnv.APIClient()
    25  
    26  	// run top with detached mode
    27  	cID := container.Run(ctx, t, client)
    28  
    29  	expected := "closeIO"
    30  	execResp, err := client.ContainerExecCreate(ctx, cID,
    31  		types.ExecConfig{
    32  			AttachStdin:  true,
    33  			AttachStdout: true,
    34  			Cmd:          strslice.StrSlice([]string{"sh", "-c", "cat && echo " + expected}),
    35  		},
    36  	)
    37  	assert.NilError(t, err)
    38  
    39  	resp, err := client.ContainerExecAttach(ctx, execResp.ID,
    40  		types.ExecStartCheck{
    41  			Detach: false,
    42  			Tty:    false,
    43  		},
    44  	)
    45  	assert.NilError(t, err)
    46  	defer resp.Close()
    47  
    48  	// close stdin to send EOF to cat
    49  	assert.NilError(t, resp.CloseWrite())
    50  
    51  	var (
    52  		waitCh = make(chan struct{})
    53  		resCh  = make(chan struct {
    54  			content string
    55  			err     error
    56  		}, 1)
    57  	)
    58  
    59  	go func() {
    60  		close(waitCh)
    61  		defer close(resCh)
    62  		r, err := ioutil.ReadAll(resp.Reader)
    63  
    64  		resCh <- struct {
    65  			content string
    66  			err     error
    67  		}{
    68  			content: string(r),
    69  			err:     err,
    70  		}
    71  	}()
    72  
    73  	<-waitCh
    74  	select {
    75  	case <-time.After(3 * time.Second):
    76  		t.Fatal("failed to read the content in time")
    77  	case got := <-resCh:
    78  		assert.NilError(t, got.err)
    79  
    80  		// NOTE: using Contains because no-tty's stream contains UX information
    81  		// like size, stream type.
    82  		assert.Assert(t, is.Contains(got.content, expected))
    83  	}
    84  }
    85  
    86  func TestExec(t *testing.T) {
    87  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.35"), "broken in earlier versions")
    88  	skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")
    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 := ioutil.ReadAll(resp.Reader)
   118  	assert.NilError(t, err)
   119  	out := string(r)
   120  	assert.NilError(t, err)
   121  	assert.Assert(t, is.Contains(out, "PWD=/tmp"), "exec command not running in expected /tmp working directory")
   122  	assert.Assert(t, is.Contains(out, "FOO=BAR"), "exec command not running with expected environment variable FOO")
   123  }
   124  
   125  func TestExecUser(t *testing.T) {
   126  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
   127  	skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")
   128  	defer setupTest(t)()
   129  	ctx := context.Background()
   130  	client := testEnv.APIClient()
   131  
   132  	cID := container.Run(ctx, t, client, container.WithTty(true), container.WithUser("1:1"))
   133  
   134  	result, err := container.Exec(ctx, client, 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  }