github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/integration-cli/docker_cli_exec_unix_test.go (about)

     1  // +build !windows
     2  
     3  package main
     4  
     5  import (
     6  	"bytes"
     7  	"io"
     8  	"os/exec"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/creack/pty"
    14  	"gotest.tools/v3/assert"
    15  )
    16  
    17  // regression test for #12546
    18  func (s *DockerSuite) TestExecInteractiveStdinClose(c *testing.T) {
    19  	testRequires(c, DaemonIsLinux)
    20  	out, _ := dockerCmd(c, "run", "-itd", "busybox", "/bin/cat")
    21  	contID := strings.TrimSpace(out)
    22  
    23  	cmd := exec.Command(dockerBinary, "exec", "-i", contID, "echo", "-n", "hello")
    24  	p, err := pty.Start(cmd)
    25  	assert.NilError(c, err)
    26  
    27  	b := bytes.NewBuffer(nil)
    28  
    29  	ch := make(chan error, 1)
    30  	go func() { ch <- cmd.Wait() }()
    31  
    32  	select {
    33  	case err := <-ch:
    34  		assert.NilError(c, err)
    35  		io.Copy(b, p)
    36  		p.Close()
    37  		bs := b.Bytes()
    38  		bs = bytes.Trim(bs, "\x00")
    39  		output := string(bs[:])
    40  		assert.Equal(c, strings.TrimSpace(output), "hello")
    41  	case <-time.After(5 * time.Second):
    42  		p.Close()
    43  		c.Fatal("timed out running docker exec")
    44  	}
    45  }
    46  
    47  func (s *DockerSuite) TestExecTTY(c *testing.T) {
    48  	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon)
    49  	dockerCmd(c, "run", "-d", "--name=test", "busybox", "sh", "-c", "echo hello > /foo && top")
    50  
    51  	cmd := exec.Command(dockerBinary, "exec", "-it", "test", "sh")
    52  	p, err := pty.Start(cmd)
    53  	assert.NilError(c, err)
    54  	defer p.Close()
    55  
    56  	_, err = p.Write([]byte("cat /foo && exit\n"))
    57  	assert.NilError(c, err)
    58  
    59  	chErr := make(chan error, 1)
    60  	go func() {
    61  		chErr <- cmd.Wait()
    62  	}()
    63  	select {
    64  	case err := <-chErr:
    65  		assert.NilError(c, err)
    66  	case <-time.After(3 * time.Second):
    67  		c.Fatal("timeout waiting for exec to exit")
    68  	}
    69  
    70  	buf := make([]byte, 256)
    71  	read, err := p.Read(buf)
    72  	assert.NilError(c, err)
    73  	assert.Assert(c, bytes.Contains(buf, []byte("hello")), string(buf[:read]))
    74  }
    75  
    76  // Test the TERM env var is set when -t is provided on exec
    77  func (s *DockerSuite) TestExecWithTERM(c *testing.T) {
    78  	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon)
    79  	out, _ := dockerCmd(c, "run", "-id", "busybox", "/bin/cat")
    80  	contID := strings.TrimSpace(out)
    81  	cmd := exec.Command(dockerBinary, "exec", "-t", contID, "sh", "-c", "if [ -z $TERM ]; then exit 1; else exit 0; fi")
    82  	if err := cmd.Run(); err != nil {
    83  		assert.NilError(c, err)
    84  	}
    85  }
    86  
    87  // Test that the TERM env var is not set on exec when -t is not provided, even if it was set
    88  // on run
    89  func (s *DockerSuite) TestExecWithNoTERM(c *testing.T) {
    90  	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon)
    91  	out, _ := dockerCmd(c, "run", "-itd", "busybox", "/bin/cat")
    92  	contID := strings.TrimSpace(out)
    93  	cmd := exec.Command(dockerBinary, "exec", contID, "sh", "-c", "if [ -z $TERM ]; then exit 0; else exit 1; fi")
    94  	if err := cmd.Run(); err != nil {
    95  		assert.NilError(c, err)
    96  	}
    97  }