2021-08-23 09:14:53 -04:00
|
|
|
//go:build !windows
|
2015-01-14 17:40:07 -05:00
|
|
|
// +build !windows
|
|
|
|
|
2015-01-13 18:33:05 -05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2015-04-10 23:17:55 -04:00
|
|
|
"bufio"
|
2021-08-24 06:10:50 -04:00
|
|
|
"io"
|
2015-01-13 18:33:05 -05:00
|
|
|
"os/exec"
|
|
|
|
"strings"
|
2019-09-09 17:06:12 -04:00
|
|
|
"testing"
|
2015-01-13 18:33:05 -05:00
|
|
|
"time"
|
|
|
|
|
2019-07-29 19:59:08 -04:00
|
|
|
"github.com/creack/pty"
|
2020-02-07 08:39:24 -05:00
|
|
|
"gotest.tools/v3/assert"
|
2015-01-13 18:33:05 -05:00
|
|
|
)
|
|
|
|
|
2015-09-29 10:57:58 -04:00
|
|
|
// #9860 Make sure attach ends when container ends (with no errors)
|
2022-06-16 17:32:10 -04:00
|
|
|
func (s *DockerCLIAttachSuite) TestAttachClosedOnContainerStop(c *testing.T) {
|
2018-12-24 07:25:53 -05:00
|
|
|
testRequires(c, testEnv.IsLocalDaemon)
|
2015-01-13 18:33:05 -05:00
|
|
|
|
2015-09-29 10:57:58 -04:00
|
|
|
out, _ := dockerCmd(c, "run", "-dti", "busybox", "/bin/sh", "-c", `trap 'exit 0' SIGTERM; while true; do sleep 1; done`)
|
2015-01-13 18:33:05 -05:00
|
|
|
|
2015-04-06 09:21:18 -04:00
|
|
|
id := strings.TrimSpace(out)
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, waitRun(id))
|
2015-01-13 18:33:05 -05:00
|
|
|
|
2016-10-05 18:48:04 -04:00
|
|
|
pty, tty, err := pty.Open()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-09-29 10:57:58 -04:00
|
|
|
|
|
|
|
attachCmd := exec.Command(dockerBinary, "attach", id)
|
|
|
|
attachCmd.Stdin = tty
|
|
|
|
attachCmd.Stdout = tty
|
|
|
|
attachCmd.Stderr = tty
|
|
|
|
err = attachCmd.Start()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-09-29 10:57:58 -04:00
|
|
|
|
2020-02-25 17:13:25 -05:00
|
|
|
errChan := make(chan error, 1)
|
2015-01-13 18:33:05 -05:00
|
|
|
go func() {
|
2016-10-05 18:48:04 -04:00
|
|
|
time.Sleep(300 * time.Millisecond)
|
2015-04-27 13:29:48 -04:00
|
|
|
defer close(errChan)
|
2015-12-13 11:00:39 -05:00
|
|
|
// Container is waiting for us to signal it to stop
|
2015-09-29 10:57:58 -04:00
|
|
|
dockerCmd(c, "stop", id)
|
|
|
|
// And wait for the attach command to end
|
|
|
|
errChan <- attachCmd.Wait()
|
2015-01-13 18:33:05 -05:00
|
|
|
}()
|
|
|
|
|
2015-09-29 10:57:58 -04:00
|
|
|
// Wait for the docker to end (should be done by the
|
|
|
|
// stop command in the go routine)
|
2015-07-14 02:35:36 -04:00
|
|
|
dockerCmd(c, "wait", id)
|
|
|
|
|
2015-01-13 18:33:05 -05:00
|
|
|
select {
|
2015-04-27 13:29:48 -04:00
|
|
|
case err := <-errChan:
|
2016-10-05 18:48:04 -04:00
|
|
|
tty.Close()
|
2021-08-24 06:10:50 -04:00
|
|
|
out, _ := io.ReadAll(pty)
|
2019-09-11 06:57:29 -04:00
|
|
|
assert.Assert(c, err == nil, "out: %v", string(out))
|
2015-01-13 18:33:05 -05:00
|
|
|
case <-time.After(attachWait):
|
2015-04-18 12:46:47 -04:00
|
|
|
c.Fatal("timed out without attach returning")
|
2015-01-13 18:33:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-06-16 17:32:10 -04:00
|
|
|
func (s *DockerCLIAttachSuite) TestAttachAfterDetach(c *testing.T) {
|
2015-01-13 18:33:05 -05:00
|
|
|
name := "detachtest"
|
|
|
|
|
|
|
|
cpty, tty, err := pty.Open()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err, "Could not open pty: %v", err)
|
2015-01-13 18:33:05 -05:00
|
|
|
cmd := exec.Command(dockerBinary, "run", "-ti", "--name", name, "busybox")
|
|
|
|
cmd.Stdin = tty
|
|
|
|
cmd.Stdout = tty
|
|
|
|
cmd.Stderr = tty
|
|
|
|
|
2020-02-25 17:13:25 -05:00
|
|
|
cmdExit := make(chan error, 1)
|
2015-01-13 18:33:05 -05:00
|
|
|
go func() {
|
2018-02-20 18:24:21 -05:00
|
|
|
cmdExit <- cmd.Run()
|
|
|
|
close(cmdExit)
|
2015-01-13 18:33:05 -05:00
|
|
|
}()
|
|
|
|
|
2019-09-09 17:05:57 -04:00
|
|
|
assert.Assert(c, waitRun(name) == nil)
|
2015-08-11 03:41:11 -04:00
|
|
|
|
2015-01-13 18:33:05 -05:00
|
|
|
cpty.Write([]byte{16})
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
cpty.Write([]byte{17})
|
|
|
|
|
2015-04-27 13:29:48 -04:00
|
|
|
select {
|
2018-02-20 18:24:21 -05:00
|
|
|
case <-cmdExit:
|
2015-04-27 13:29:48 -04:00
|
|
|
case <-time.After(5 * time.Second):
|
|
|
|
c.Fatal("timeout while detaching")
|
|
|
|
}
|
2015-01-13 18:33:05 -05:00
|
|
|
|
|
|
|
cpty, tty, err = pty.Open()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err, "Could not open pty: %v", err)
|
2015-01-13 18:33:05 -05:00
|
|
|
|
|
|
|
cmd = exec.Command(dockerBinary, "attach", name)
|
|
|
|
cmd.Stdin = tty
|
|
|
|
cmd.Stdout = tty
|
|
|
|
cmd.Stderr = tty
|
|
|
|
|
2015-10-27 23:18:01 -04:00
|
|
|
err = cmd.Start()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2018-02-20 18:24:21 -05:00
|
|
|
defer cmd.Process.Kill()
|
2015-01-13 18:33:05 -05:00
|
|
|
|
|
|
|
bytes := make([]byte, 10)
|
2015-01-16 18:33:26 -05:00
|
|
|
var nBytes int
|
|
|
|
readErr := make(chan error, 1)
|
2015-01-13 18:33:05 -05:00
|
|
|
|
2015-01-16 18:33:26 -05:00
|
|
|
go func() {
|
|
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
cpty.Write([]byte("\n"))
|
|
|
|
time.Sleep(500 * time.Millisecond)
|
2015-01-13 18:33:05 -05:00
|
|
|
|
2015-01-16 18:33:26 -05:00
|
|
|
nBytes, err = cpty.Read(bytes)
|
|
|
|
cpty.Close()
|
|
|
|
readErr <- err
|
|
|
|
}()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case err := <-readErr:
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-01-16 18:33:26 -05:00
|
|
|
case <-time.After(2 * time.Second):
|
2015-04-18 12:46:47 -04:00
|
|
|
c.Fatal("timeout waiting for attach read")
|
2015-01-13 18:33:05 -05:00
|
|
|
}
|
|
|
|
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.Assert(c, strings.Contains(string(bytes[:nBytes]), "/ #"))
|
2015-01-13 18:33:05 -05:00
|
|
|
}
|
2015-04-10 23:17:55 -04:00
|
|
|
|
|
|
|
// TestAttachDetach checks that attach in tty mode can be detached using the long container ID
|
2022-06-16 17:32:10 -04:00
|
|
|
func (s *DockerCLIAttachSuite) TestAttachDetach(c *testing.T) {
|
2015-04-18 12:46:47 -04:00
|
|
|
out, _ := dockerCmd(c, "run", "-itd", "busybox", "cat")
|
2015-04-10 23:17:55 -04:00
|
|
|
id := strings.TrimSpace(out)
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, waitRun(id))
|
2015-04-10 23:17:55 -04:00
|
|
|
|
|
|
|
cpty, tty, err := pty.Open()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-04-10 23:17:55 -04:00
|
|
|
defer cpty.Close()
|
|
|
|
|
|
|
|
cmd := exec.Command(dockerBinary, "attach", id)
|
|
|
|
cmd.Stdin = tty
|
|
|
|
stdout, err := cmd.StdoutPipe()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-04-10 23:17:55 -04:00
|
|
|
defer stdout.Close()
|
2015-10-27 23:18:01 -04:00
|
|
|
err = cmd.Start()
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
|
|
|
assert.NilError(c, waitRun(id))
|
2015-04-10 23:17:55 -04:00
|
|
|
|
2015-10-27 23:18:01 -04:00
|
|
|
_, err = cpty.Write([]byte("hello\n"))
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-04-10 23:17:55 -04:00
|
|
|
out, err = bufio.NewReader(stdout).ReadString('\n')
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
|
|
|
assert.Equal(c, strings.TrimSpace(out), "hello")
|
2015-04-10 23:17:55 -04:00
|
|
|
|
|
|
|
// escape sequence
|
2015-10-27 23:18:01 -04:00
|
|
|
_, err = cpty.Write([]byte{16})
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-04-10 23:17:55 -04:00
|
|
|
time.Sleep(100 * time.Millisecond)
|
2015-10-27 23:18:01 -04:00
|
|
|
_, err = cpty.Write([]byte{17})
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.NilError(c, err)
|
2015-04-10 23:17:55 -04:00
|
|
|
|
|
|
|
ch := make(chan struct{})
|
|
|
|
go func() {
|
|
|
|
cmd.Wait()
|
integration-cli: fix TestAttachDetach, rm TestAttachDetachTruncatedID
It looks like the logic of the test became wrong after commit
ae0883c ("Move TestAttachDetach to integration-cli").
The original logic was:
* (a few first steps skipped for clarity)
* send escape sequence to "attach";
* check "attach" is exiting (i.e. escape sequence works);
* check the container is still alive;
* kill the container.
Also, timeouts were big at that time, in the order of seconds.
The logic after the above mentioned commit and until now is:
* ...
* send escape sequence to "attach";
* check the container is running (why shouldn't it?);
* kill the container;
* checks that the "attach" has exited.
So, from the "let's check detach using escape sequence is working"
the test became something like "let's check that attach is gone
once we kill the container".
Let's fix the above test, also increasing the timeout waiting
for attach to exit (which fails from time to time on power CI).
Now, the second test, TestAttachDetachTruncatedID, does the exact
same thing, except it uses a truncated container ID. It does not
seem to be of much value, so let's remove it.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-08-24 17:37:26 -04:00
|
|
|
close(ch)
|
2015-04-10 23:17:55 -04:00
|
|
|
}()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-ch:
|
integration-cli: fix TestAttachDetach, rm TestAttachDetachTruncatedID
It looks like the logic of the test became wrong after commit
ae0883c ("Move TestAttachDetach to integration-cli").
The original logic was:
* (a few first steps skipped for clarity)
* send escape sequence to "attach";
* check "attach" is exiting (i.e. escape sequence works);
* check the container is still alive;
* kill the container.
Also, timeouts were big at that time, in the order of seconds.
The logic after the above mentioned commit and until now is:
* ...
* send escape sequence to "attach";
* check the container is running (why shouldn't it?);
* kill the container;
* checks that the "attach" has exited.
So, from the "let's check detach using escape sequence is working"
the test became something like "let's check that attach is gone
once we kill the container".
Let's fix the above test, also increasing the timeout waiting
for attach to exit (which fails from time to time on power CI).
Now, the second test, TestAttachDetachTruncatedID, does the exact
same thing, except it uses a truncated container ID. It does not
seem to be of much value, so let's remove it.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-08-24 17:37:26 -04:00
|
|
|
case <-time.After(1 * time.Second):
|
2015-04-18 12:46:47 -04:00
|
|
|
c.Fatal("timed out waiting for container to exit")
|
2015-04-10 23:17:55 -04:00
|
|
|
}
|
|
|
|
|
2016-01-28 09:19:25 -05:00
|
|
|
running := inspectField(c, id, "State.Running")
|
2019-04-04 09:23:19 -04:00
|
|
|
assert.Equal(c, running, "true") // container should be running
|
2015-04-10 23:21:45 -04:00
|
|
|
}
|