| package container |
| |
| import ( |
| "os/exec" |
| "strings" |
| "syscall" |
| "testing" |
| "time" |
| |
| "github.com/creack/pty" |
| "github.com/docker/cli/e2e/internal/fixtures" |
| "gotest.tools/v3/assert" |
| "gotest.tools/v3/icmd" |
| "gotest.tools/v3/poll" |
| ) |
| |
| // TestSigProxyWithTTY tests that killing the docker CLI forwards the signal to |
| // the container, and kills the container's process. Test-case for moby/moby#28872 |
| func TestSigProxyWithTTY(t *testing.T) { |
| cmd := exec.Command("docker", "run", "-i", "-t", "--init", "--name", t.Name(), fixtures.BusyboxImage, "sleep", "30") |
| p, err := pty.Start(cmd) |
| defer func() { |
| _ = cmd.Wait() |
| _ = p.Close() |
| }() |
| assert.NilError(t, err, "failed to start container") |
| defer icmd.RunCommand("docker", "container", "rm", "-f", t.Name()) |
| |
| poll.WaitOn(t, containerExistsWithStatus(t.Name(), "running"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(5*time.Second)) |
| |
| pid := cmd.Process.Pid |
| t.Logf("terminating PID %d", pid) |
| err = syscall.Kill(pid, syscall.SIGTERM) |
| assert.NilError(t, err) |
| |
| poll.WaitOn(t, containerExistsWithStatus(t.Name(), "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(5*time.Second)) |
| } |
| |
| func containerExistsWithStatus(containerID, status string) func(poll.LogT) poll.Result { |
| return func(poll.LogT) poll.Result { |
| result := icmd.RunCommand("docker", "inspect", "-f", "{{ .State.Status }}", containerID) |
| // ignore initial failures as the container may not yet exist (i.e., don't result.Assert(t, icmd.Success)) |
| |
| actual := strings.TrimSpace(result.Stdout()) |
| if actual == status { |
| return poll.Success() |
| } |
| return poll.Continue("expected status %s != %s", status, actual) |
| } |
| } |