Repository: moby/moby
File: integration-cli/docker_cli_exec_test.go (Go)

Code before:

	out = cli.DockerCmd(c, "top", "exec_tty_stdin").Combined()
	outArr := strings.Split(out, "\n")
	assert.Assert(c, len(outArr) <= 3, "exec process left running")
	assert.Assert(c, !strings.Contains(out, "nsenter-exec"))
}

func (s *DockerCLIExecSuite) TestExecTTYWithoutStdin(c *testing.T) {
	out := cli.DockerCmd(c, "run", "-d", "-ti", "busybox").Stdout()
	id := strings.TrimSpace(out)
	cli.WaitRun(c, id)

	errChan := make(chan error, 1)
	go func() {
		defer close(errChan)

		cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true")
		if _, err := cmd.StdinPipe(); err != nil {
			errChan <- err
			return
		}

		expected := "the input device is not a TTY"
		if runtime.GOOS == "windows" {
			expected += ".  If you are using mintty, try prefixing the command with 'winpty'"
		}
		if out, _, err := runCommandWithOutput(cmd); err == nil {
			errChan <- errors.New("exec should have failed")
			return
		} else if !strings.Contains(out, expected) {
			errChan <- fmt.Errorf("exec failed with error %q: expected %q", out, expected)
			return
		}
	}()

	select {
	case err := <-errChan:
		assert.NilError(c, err)
	case <-time.After(3 * time.Second):
		c.Fatal("exec is running but should have failed")
	}
}

// FIXME(vdemeester) this should be a unit tests on cli/command/container package
func (s *DockerCLIExecSuite) TestExecParseError(c *testing.T) {
	// TODO Windows CI: Requires some extra work. Consider copying the
	// runSleepingContainer helper to have an exec version.
	testRequires(c, DaemonIsLinux)
	cli.DockerCmd(c, "run", "-d", "--name", "top", "busybox", "top")

	// Test normal (non-detached) case first

Review comment (suggestion):
This didn't add value; the extra hint is added in the CLI, so we only need to check for the first part of the error; https://github.com/docker/cli/blob/5d8fb335d4e0db3a7250892de0e07b1fa7d3a730/cli/streams/in.go#L46-L52

Code after:
		Env:     cmd.Env,
		Dir:     cmd.Dir,
		Stdin:   cmd.Stdin,
		Stdout:  cmd.Stdout,
	})
	out, err := res.Combined(), res.Error
	assert.NilError(c, err, out)

	out = cli.DockerCmd(c, "top", "exec_tty_stdin").Combined()
	outArr := strings.Split(out, "\n")
	assert.Assert(c, len(outArr) <= 3, "exec process left running")
	assert.Assert(c, !strings.Contains(out, "nsenter-exec"))
}

func (s *DockerCLIExecSuite) TestExecTTYWithoutStdin(c *testing.T) {
	out := cli.DockerCmd(c, "run", "-d", "-ti", "busybox").Stdout()
	id := strings.TrimSpace(out)
	cli.WaitRun(c, id)

	errChan := make(chan error, 1)
	go func() {
		defer close(errChan)

		cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true")
		if _, err := cmd.StdinPipe(); err != nil {
			errChan <- err
			return
		}

		expected := "the input device is not a TTY"

		res := icmd.RunCmd(icmd.Cmd{
			Command: cmd.Args,
			Env:     cmd.Env,
			Dir:     cmd.Dir,
			Stdin:   cmd.Stdin,
			Stdout:  cmd.Stdout,
		})
		out, err := res.Combined(), res.Error
		if err == nil {
			errChan <- errors.New("exec should have failed")
			return
		} else if !strings.Contains(out, expected) {
			errChan <- fmt.Errorf("exec failed with error %q: expected %q", out, expected)
			return
		}
	}()

	select {
	case err := <-errChan:
		assert.NilError(c, err)