mirror of https://github.com/docker/docs.git
c.Fatal won't fail and exit test inside a goroutine, errors should be handled outside with a channel
Signed-off-by: Antonio Murdaca <me@runcom.ninja>
This commit is contained in:
parent
f2f8e4c5c9
commit
4203230cbb
|
@ -260,15 +260,14 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) {
|
||||||
c.Fatalf("Error on container creation: %v, output: %q", err, out)
|
c.Fatalf("Error on container creation: %v, output: %q", err, out)
|
||||||
}
|
}
|
||||||
type b struct {
|
type b struct {
|
||||||
body []byte
|
status int
|
||||||
err error
|
body []byte
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
bc := make(chan b, 1)
|
bc := make(chan b, 1)
|
||||||
go func() {
|
go func() {
|
||||||
status, body, err := sockRequest("GET", "/containers/"+name+"/stats", nil)
|
status, body, err := sockRequest("GET", "/containers/"+name+"/stats", nil)
|
||||||
c.Assert(status, check.Equals, http.StatusOK)
|
bc <- b{status, body, err}
|
||||||
c.Assert(err, check.IsNil)
|
|
||||||
bc <- b{body, err}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// allow some time to stream the stats from the container
|
// allow some time to stream the stats from the container
|
||||||
|
@ -283,9 +282,8 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) {
|
||||||
case <-time.After(2 * time.Second):
|
case <-time.After(2 * time.Second):
|
||||||
c.Fatal("stream was not closed after container was removed")
|
c.Fatal("stream was not closed after container was removed")
|
||||||
case sr := <-bc:
|
case sr := <-bc:
|
||||||
if sr.err != nil {
|
c.Assert(sr.err, check.IsNil)
|
||||||
c.Fatal(sr.err)
|
c.Assert(sr.status, check.Equals, http.StatusOK)
|
||||||
}
|
|
||||||
|
|
||||||
dec := json.NewDecoder(bytes.NewBuffer(sr.body))
|
dec := json.NewDecoder(bytes.NewBuffer(sr.body))
|
||||||
var s *types.Stats
|
var s *types.Stats
|
||||||
|
@ -297,6 +295,7 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestGetStoppedContainerStats(c *check.C) {
|
func (s *DockerSuite) TestGetStoppedContainerStats(c *check.C) {
|
||||||
|
// TODO: this test does nothing because we are c.Assert'ing in goroutine
|
||||||
var (
|
var (
|
||||||
name = "statscontainer"
|
name = "statscontainer"
|
||||||
runCmd = exec.Command(dockerBinary, "create", "--name", name, "busybox", "top")
|
runCmd = exec.Command(dockerBinary, "create", "--name", name, "busybox", "top")
|
||||||
|
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -89,7 +90,6 @@ func (s *DockerSuite) TestAttachMultipleAndRestart(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) {
|
func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) {
|
||||||
|
|
||||||
cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox")
|
cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox")
|
||||||
out, _, err := runCommandWithOutput(cmd)
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -108,29 +108,32 @@ func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
cmd := exec.Command(dockerBinary, "attach", id)
|
cmd := exec.Command(dockerBinary, "attach", id)
|
||||||
if _, err := cmd.StdinPipe(); err != nil {
|
if _, err := cmd.StdinPipe(); err != nil {
|
||||||
c.Fatal(err)
|
done <- err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "cannot enable tty mode"
|
expected := "cannot enable tty mode"
|
||||||
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
||||||
c.Fatal("attach should have failed")
|
done <- fmt.Errorf("attach should have failed")
|
||||||
|
return
|
||||||
} else if !strings.Contains(out, expected) {
|
} else if !strings.Contains(out, expected) {
|
||||||
c.Fatalf("attach failed with error %q: expected %q", out, expected)
|
done <- fmt.Errorf("attach failed with error %q: expected %q", out, expected)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case err := <-done:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(attachWait):
|
case <-time.After(attachWait):
|
||||||
c.Fatal("attach is running but should have failed")
|
c.Fatal("attach is running but should have failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestAttachDisconnect(c *check.C) {
|
func (s *DockerSuite) TestAttachDisconnect(c *check.C) {
|
||||||
|
|
|
@ -27,14 +27,14 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) {
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
done := make(chan struct{})
|
errChan := make(chan error)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(errChan)
|
||||||
|
|
||||||
_, tty, err := pty.Open()
|
_, tty, err := pty.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fatalf("could not open pty: %v", err)
|
errChan <- err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
attachCmd := exec.Command(dockerBinary, "attach", id)
|
attachCmd := exec.Command(dockerBinary, "attach", id)
|
||||||
attachCmd.Stdin = tty
|
attachCmd.Stdin = tty
|
||||||
|
@ -42,7 +42,8 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) {
|
||||||
attachCmd.Stderr = tty
|
attachCmd.Stderr = tty
|
||||||
|
|
||||||
if err := attachCmd.Run(); err != nil {
|
if err := attachCmd.Run(); err != nil {
|
||||||
c.Fatalf("attach returned error %s", err)
|
errChan <- err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -51,7 +52,8 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) {
|
||||||
c.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
c.Fatalf("error thrown while waiting for container: %s, %v", out, err)
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(attachWait):
|
case <-time.After(attachWait):
|
||||||
c.Fatal("timed out without attach returning")
|
c.Fatal("timed out without attach returning")
|
||||||
}
|
}
|
||||||
|
@ -71,12 +73,10 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) {
|
||||||
cmd.Stdout = tty
|
cmd.Stdout = tty
|
||||||
cmd.Stderr = tty
|
cmd.Stderr = tty
|
||||||
|
|
||||||
detached := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
if err := cmd.Run(); err != nil {
|
errChan <- cmd.Run()
|
||||||
c.Fatalf("attach returned error %s", err)
|
close(errChan)
|
||||||
}
|
|
||||||
close(detached)
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
@ -87,7 +87,12 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
cpty.Write([]byte{17})
|
cpty.Write([]byte{17})
|
||||||
|
|
||||||
<-detached
|
select {
|
||||||
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
c.Fatal("timeout while detaching")
|
||||||
|
}
|
||||||
|
|
||||||
cpty, tty, err = pty.Open()
|
cpty, tty, err = pty.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -119,9 +124,7 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case err := <-readErr:
|
case err := <-readErr:
|
||||||
if err != nil {
|
c.Assert(err, check.IsNil)
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
case <-time.After(2 * time.Second):
|
case <-time.After(2 * time.Second):
|
||||||
c.Fatal("timeout waiting for attach read")
|
c.Fatal("timeout waiting for attach read")
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -764,17 +763,17 @@ ADD test_file .`,
|
||||||
}
|
}
|
||||||
defer ctx.Close()
|
defer ctx.Close()
|
||||||
|
|
||||||
done := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
_, err := buildImageFromContext(name, ctx, true)
|
||||||
c.Fatal(err)
|
errChan <- err
|
||||||
}
|
close(errChan)
|
||||||
close(done)
|
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
c.Fatal("Build with adding to workdir timed out")
|
c.Fatal("Build with adding to workdir timed out")
|
||||||
case <-done:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1365,17 +1364,17 @@ COPY test_file .`,
|
||||||
}
|
}
|
||||||
defer ctx.Close()
|
defer ctx.Close()
|
||||||
|
|
||||||
done := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
if _, err := buildImageFromContext(name, ctx, true); err != nil {
|
_, err := buildImageFromContext(name, ctx, true)
|
||||||
c.Fatal(err)
|
errChan <- err
|
||||||
}
|
close(errChan)
|
||||||
close(done)
|
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
c.Fatal("Build with adding to workdir timed out")
|
c.Fatal("Build with adding to workdir timed out")
|
||||||
case <-done:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1829,9 +1828,6 @@ func (s *DockerSuite) TestBuildForceRm(c *check.C) {
|
||||||
// * When docker events sees container start, close the "docker build" command
|
// * When docker events sees container start, close the "docker build" command
|
||||||
// * Wait for docker events to emit a dying event.
|
// * Wait for docker events to emit a dying event.
|
||||||
func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) {
|
func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) {
|
||||||
var wg sync.WaitGroup
|
|
||||||
defer wg.Wait()
|
|
||||||
|
|
||||||
name := "testbuildcancelation"
|
name := "testbuildcancelation"
|
||||||
|
|
||||||
// (Note: one year, will never finish)
|
// (Note: one year, will never finish)
|
||||||
|
@ -1849,26 +1845,21 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) {
|
||||||
containerID := make(chan string)
|
containerID := make(chan string)
|
||||||
|
|
||||||
startEpoch := daemonTime(c).Unix()
|
startEpoch := daemonTime(c).Unix()
|
||||||
|
// Watch for events since epoch.
|
||||||
|
eventsCmd := exec.Command(
|
||||||
|
dockerBinary, "events",
|
||||||
|
"--since", strconv.FormatInt(startEpoch, 10))
|
||||||
|
stdout, err := eventsCmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := eventsCmd.Start(); err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
defer eventsCmd.Process.Kill()
|
||||||
|
|
||||||
wg.Add(1)
|
|
||||||
// Goroutine responsible for watching start/die events from `docker events`
|
// Goroutine responsible for watching start/die events from `docker events`
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
|
||||||
// Watch for events since epoch.
|
|
||||||
eventsCmd := exec.Command(
|
|
||||||
dockerBinary, "events",
|
|
||||||
"--since", strconv.FormatInt(startEpoch, 10))
|
|
||||||
stdout, err := eventsCmd.StdoutPipe()
|
|
||||||
err = eventsCmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
c.Fatalf("failed to start 'docker events': %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
<-finish
|
|
||||||
eventsCmd.Process.Kill()
|
|
||||||
}()
|
|
||||||
|
|
||||||
cid := <-containerID
|
cid := <-containerID
|
||||||
|
|
||||||
matchStart := regexp.MustCompile(cid + `(.*) start$`)
|
matchStart := regexp.MustCompile(cid + `(.*) start$`)
|
||||||
|
@ -1886,19 +1877,13 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) {
|
||||||
close(eventDie)
|
close(eventDie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = eventsCmd.Wait()
|
|
||||||
if err != nil && !IsKilled(err) {
|
|
||||||
c.Fatalf("docker events had bad exit status: %s", err)
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".")
|
buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".")
|
||||||
buildCmd.Dir = ctx.Dir
|
buildCmd.Dir = ctx.Dir
|
||||||
|
|
||||||
stdoutBuild, err := buildCmd.StdoutPipe()
|
stdoutBuild, err := buildCmd.StdoutPipe()
|
||||||
err = buildCmd.Start()
|
if err := buildCmd.Start(); err != nil {
|
||||||
if err != nil {
|
|
||||||
c.Fatalf("failed to run build: %s", err)
|
c.Fatalf("failed to run build: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1923,14 +1908,12 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) {
|
||||||
|
|
||||||
// Send a kill to the `docker build` command.
|
// Send a kill to the `docker build` command.
|
||||||
// Causes the underlying build to be cancelled due to socket close.
|
// Causes the underlying build to be cancelled due to socket close.
|
||||||
err = buildCmd.Process.Kill()
|
if err := buildCmd.Process.Kill(); err != nil {
|
||||||
if err != nil {
|
|
||||||
c.Fatalf("error killing build command: %s", err)
|
c.Fatalf("error killing build command: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the exit status of `docker build`, check it exited because killed.
|
// Get the exit status of `docker build`, check it exited because killed.
|
||||||
err = buildCmd.Wait()
|
if err := buildCmd.Wait(); err != nil && !IsKilled(err) {
|
||||||
if err != nil && !IsKilled(err) {
|
|
||||||
c.Fatalf("wait failed during build run: %T %s", err, err)
|
c.Fatalf("wait failed during build run: %T %s", err, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,7 @@ func (s *DockerSuite) TestEventsLimit(c *check.C) {
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer waitGroup.Done()
|
defer waitGroup.Done()
|
||||||
err := exec.Command(dockerBinary, args...).Run()
|
errChan <- exec.Command(dockerBinary, args...).Run()
|
||||||
errChan <- err
|
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,8 +228,7 @@ func (s *DockerSuite) TestEventsImageImport(c *check.C) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
}
|
}
|
||||||
err = eventsCmd.Start()
|
if err := eventsCmd.Start(); err != nil {
|
||||||
if err != nil {
|
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
}
|
}
|
||||||
defer eventsCmd.Process.Kill()
|
defer eventsCmd.Process.Kill()
|
||||||
|
@ -424,30 +422,23 @@ func (s *DockerSuite) TestEventsFilterContainer(c *check.C) {
|
||||||
func (s *DockerSuite) TestEventsStreaming(c *check.C) {
|
func (s *DockerSuite) TestEventsStreaming(c *check.C) {
|
||||||
start := daemonTime(c).Unix()
|
start := daemonTime(c).Unix()
|
||||||
|
|
||||||
finish := make(chan struct{})
|
|
||||||
defer close(finish)
|
|
||||||
id := make(chan string)
|
id := make(chan string)
|
||||||
eventCreate := make(chan struct{})
|
eventCreate := make(chan struct{})
|
||||||
eventStart := make(chan struct{})
|
eventStart := make(chan struct{})
|
||||||
eventDie := make(chan struct{})
|
eventDie := make(chan struct{})
|
||||||
eventDestroy := make(chan struct{})
|
eventDestroy := make(chan struct{})
|
||||||
|
|
||||||
|
eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10))
|
||||||
|
stdout, err := eventsCmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := eventsCmd.Start(); err != nil {
|
||||||
|
c.Fatalf("failed to start 'docker events': %s", err)
|
||||||
|
}
|
||||||
|
defer eventsCmd.Process.Kill()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10))
|
|
||||||
stdout, err := eventsCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
err = eventsCmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
c.Fatalf("failed to start 'docker events': %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
<-finish
|
|
||||||
eventsCmd.Process.Kill()
|
|
||||||
}()
|
|
||||||
|
|
||||||
containerID := <-id
|
containerID := <-id
|
||||||
|
|
||||||
matchCreate := regexp.MustCompile(containerID + `: \(from busybox:latest\) create$`)
|
matchCreate := regexp.MustCompile(containerID + `: \(from busybox:latest\) create$`)
|
||||||
|
@ -468,11 +459,6 @@ func (s *DockerSuite) TestEventsStreaming(c *check.C) {
|
||||||
close(eventDestroy)
|
close(eventDestroy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = eventsCmd.Wait()
|
|
||||||
if err != nil && !IsKilled(err) {
|
|
||||||
c.Fatalf("docker events had bad exit status: %s", err)
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox:latest", "true")
|
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox:latest", "true")
|
||||||
|
@ -516,5 +502,4 @@ func (s *DockerSuite) TestEventsStreaming(c *check.C) {
|
||||||
case <-eventDestroy:
|
case <-eventDestroy:
|
||||||
// ignore, done
|
// ignore, done
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,15 +74,14 @@ func (s *DockerSuite) TestExecInteractive(c *check.C) {
|
||||||
if err := stdin.Close(); err != nil {
|
if err := stdin.Close(); err != nil {
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
}
|
}
|
||||||
finish := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
if err := execCmd.Wait(); err != nil {
|
errChan <- execCmd.Wait()
|
||||||
c.Fatal(err)
|
close(errChan)
|
||||||
}
|
|
||||||
close(finish)
|
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-finish:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(1 * time.Second):
|
||||||
c.Fatal("docker exec failed to exit on stdin close")
|
c.Fatal("docker exec failed to exit on stdin close")
|
||||||
}
|
}
|
||||||
|
@ -278,25 +277,29 @@ func (s *DockerSuite) TestExecTtyWithoutStdin(c *check.C) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
done := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(errChan)
|
||||||
|
|
||||||
cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true")
|
cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true")
|
||||||
if _, err := cmd.StdinPipe(); err != nil {
|
if _, err := cmd.StdinPipe(); err != nil {
|
||||||
c.Fatal(err)
|
errChan <- err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "cannot enable tty mode"
|
expected := "cannot enable tty mode"
|
||||||
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
||||||
c.Fatal("exec should have failed")
|
errChan <- fmt.Errorf("exec should have failed")
|
||||||
|
return
|
||||||
} else if !strings.Contains(out, expected) {
|
} else if !strings.Contains(out, expected) {
|
||||||
c.Fatalf("exec failed with error %q: expected %q", out, expected)
|
errChan <- fmt.Errorf("exec failed with error %q: expected %q", out, expected)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
c.Fatal("exec is running but should have failed")
|
c.Fatal("exec is running but should have failed")
|
||||||
}
|
}
|
||||||
|
@ -326,17 +329,22 @@ func (s *DockerSuite) TestExecStopNotHanging(c *check.C) {
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wait := make(chan struct{})
|
type dstop struct {
|
||||||
|
out []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
ch := make(chan dstop)
|
||||||
go func() {
|
go func() {
|
||||||
if out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput(); err != nil {
|
out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput()
|
||||||
c.Fatal(out, err)
|
ch <- dstop{out, err}
|
||||||
}
|
close(ch)
|
||||||
close(wait)
|
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
c.Fatal("Container stop timed out")
|
c.Fatal("Container stop timed out")
|
||||||
case <-wait:
|
case s := <-ch:
|
||||||
|
c.Assert(s.err, check.IsNil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,6 +367,7 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
execCgroups := []sort.StringSlice{}
|
execCgroups := []sort.StringSlice{}
|
||||||
|
errChan := make(chan error)
|
||||||
// exec a few times concurrently to get consistent failure
|
// exec a few times concurrently to get consistent failure
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
@ -366,7 +375,8 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) {
|
||||||
cmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/proc/self/cgroup")
|
cmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/proc/self/cgroup")
|
||||||
out, _, err := runCommandWithOutput(cmd)
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fatal(out, err)
|
errChan <- err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
cg := sort.StringSlice(strings.Split(string(out), "\n"))
|
cg := sort.StringSlice(strings.Split(string(out), "\n"))
|
||||||
|
|
||||||
|
@ -377,6 +387,11 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
close(errChan)
|
||||||
|
|
||||||
|
for err := range errChan {
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
for _, cg := range execCgroups {
|
for _, cg := range execCgroups {
|
||||||
if !reflect.DeepEqual(cg, containerCgroups) {
|
if !reflect.DeepEqual(cg, containerCgroups) {
|
||||||
|
|
|
@ -260,16 +260,15 @@ func (s *DockerSuite) TestLogsFollowStopped(c *check.C) {
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
if err := logsCmd.Wait(); err != nil {
|
errChan <- logsCmd.Wait()
|
||||||
c.Fatal(err)
|
close(errChan)
|
||||||
}
|
|
||||||
close(ch)
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ch:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(1 * time.Second):
|
||||||
c.Fatal("Following logs is hanged")
|
c.Fatal("Following logs is hanged")
|
||||||
}
|
}
|
||||||
|
@ -298,9 +297,7 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) {
|
||||||
logCmd := exec.Command(dockerBinary, "logs", "-f", cleanedContainerID)
|
logCmd := exec.Command(dockerBinary, "logs", "-f", cleanedContainerID)
|
||||||
|
|
||||||
stdout, err := logCmd.StdoutPipe()
|
stdout, err := logCmd.StdoutPipe()
|
||||||
if err != nil {
|
c.Assert(err, check.IsNil)
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := logCmd.Start(); err != nil {
|
if err := logCmd.Start(); err != nil {
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
|
@ -308,15 +305,11 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) {
|
||||||
|
|
||||||
// First read slowly
|
// First read slowly
|
||||||
bytes1, err := consumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
|
bytes1, err := consumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
|
||||||
if err != nil {
|
c.Assert(err, check.IsNil)
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// After the container has finished we can continue reading fast
|
// After the container has finished we can continue reading fast
|
||||||
bytes2, err := consumeWithSpeed(stdout, 32*1024, 0, nil)
|
bytes2, err := consumeWithSpeed(stdout, 32*1024, 0, nil)
|
||||||
if err != nil {
|
c.Assert(err, check.IsNil)
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := bytes1 + bytes2
|
actual := bytes1 + bytes2
|
||||||
expected := 200000
|
expected := 200000
|
||||||
|
|
|
@ -255,7 +255,6 @@ func assertContainerList(out string, expected []string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestPsListContainersSize(c *check.C) {
|
func (s *DockerSuite) TestPsListContainersSize(c *check.C) {
|
||||||
|
|
||||||
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello")
|
cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello")
|
||||||
runCommandWithOutput(cmd)
|
runCommandWithOutput(cmd)
|
||||||
cmd = exec.Command(dockerBinary, "ps", "-s", "-n=1")
|
cmd = exec.Command(dockerBinary, "ps", "-s", "-n=1")
|
||||||
|
|
|
@ -756,17 +756,22 @@ func (s *DockerSuite) TestRunTwoConcurrentContainers(c *check.C) {
|
||||||
group := sync.WaitGroup{}
|
group := sync.WaitGroup{}
|
||||||
group.Add(2)
|
group.Add(2)
|
||||||
|
|
||||||
|
errChan := make(chan error, 2)
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
defer group.Done()
|
defer group.Done()
|
||||||
cmd := exec.Command(dockerBinary, "run", "busybox", "sleep", "2")
|
cmd := exec.Command(dockerBinary, "run", "busybox", "sleep", "2")
|
||||||
if _, err := runCommand(cmd); err != nil {
|
_, err := runCommand(cmd)
|
||||||
c.Fatal(err)
|
errChan <- err
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
group.Wait()
|
group.Wait()
|
||||||
|
close(errChan)
|
||||||
|
|
||||||
|
for err := range errChan {
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestRunEnvironment(c *check.C) {
|
func (s *DockerSuite) TestRunEnvironment(c *check.C) {
|
||||||
|
@ -1851,22 +1856,20 @@ func (s *DockerSuite) TestRunExitOnStdinClose(c *check.C) {
|
||||||
if err := stdin.Close(); err != nil {
|
if err := stdin.Close(); err != nil {
|
||||||
c.Fatal(err)
|
c.Fatal(err)
|
||||||
}
|
}
|
||||||
finish := make(chan struct{})
|
finish := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
if err := runCmd.Wait(); err != nil {
|
finish <- runCmd.Wait()
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
close(finish)
|
close(finish)
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-finish:
|
case err := <-finish:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(1 * time.Second):
|
||||||
c.Fatal("docker run failed to exit on stdin close")
|
c.Fatal("docker run failed to exit on stdin close")
|
||||||
}
|
}
|
||||||
state, err := inspectField(name, "State.Running")
|
state, err := inspectField(name, "State.Running")
|
||||||
if err != nil {
|
c.Assert(err, check.IsNil)
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
if state != "false" {
|
if state != "false" {
|
||||||
c.Fatal("Container must be stopped after stdin closing")
|
c.Fatal("Container must be stopped after stdin closing")
|
||||||
}
|
}
|
||||||
|
@ -2762,25 +2765,29 @@ func (s *DockerSuite) TestRunPortFromDockerRangeInUse(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestRunTtyWithPipe(c *check.C) {
|
func (s *DockerSuite) TestRunTtyWithPipe(c *check.C) {
|
||||||
done := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(errChan)
|
||||||
|
|
||||||
cmd := exec.Command(dockerBinary, "run", "-ti", "busybox", "true")
|
cmd := exec.Command(dockerBinary, "run", "-ti", "busybox", "true")
|
||||||
if _, err := cmd.StdinPipe(); err != nil {
|
if _, err := cmd.StdinPipe(); err != nil {
|
||||||
c.Fatal(err)
|
errChan <- err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "cannot enable tty mode"
|
expected := "cannot enable tty mode"
|
||||||
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
if out, _, err := runCommandWithOutput(cmd); err == nil {
|
||||||
c.Fatal("run should have failed")
|
errChan <- fmt.Errorf("run should have failed")
|
||||||
|
return
|
||||||
} else if !strings.Contains(out, expected) {
|
} else if !strings.Contains(out, expected) {
|
||||||
c.Fatalf("run failed with error %q: expected %q", out, expected)
|
errChan <- fmt.Errorf("run failed with error %q: expected %q", out, expected)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
c.Fatal("container is running but should have failed")
|
c.Fatal("container is running but should have failed")
|
||||||
}
|
}
|
||||||
|
@ -2875,19 +2882,19 @@ func (s *DockerSuite) TestRunAllowPortRangeThroughPublish(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestRunOOMExitCode(c *check.C) {
|
func (s *DockerSuite) TestRunOOMExitCode(c *check.C) {
|
||||||
done := make(chan struct{})
|
errChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(errChan)
|
||||||
|
|
||||||
runCmd := exec.Command(dockerBinary, "run", "-m", "4MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
|
runCmd := exec.Command(dockerBinary, "run", "-m", "4MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
|
||||||
out, exitCode, _ := runCommandWithOutput(runCmd)
|
out, exitCode, _ := runCommandWithOutput(runCmd)
|
||||||
if expected := 137; exitCode != expected {
|
if expected := 137; exitCode != expected {
|
||||||
c.Fatalf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
|
errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case err := <-errChan:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(30 * time.Second):
|
case <-time.After(30 * time.Second):
|
||||||
c.Fatal("Timeout waiting for container to die on OOM")
|
c.Fatal("Timeout waiting for container to die on OOM")
|
||||||
}
|
}
|
||||||
|
@ -3030,9 +3037,7 @@ func (s *DockerSuite) TestRunPidHostWithChildIsKillable(c *check.C) {
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case err := <-errchan:
|
case err := <-errchan:
|
||||||
if err != nil {
|
c.Assert(err, check.IsNil)
|
||||||
c.Fatal(err)
|
|
||||||
}
|
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
c.Fatal("Kill container timed out")
|
c.Fatal("Kill container timed out")
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,21 +29,22 @@ func (s *DockerSuite) TestRunRedirectStdout(c *check.C) {
|
||||||
cmd.Stdin = tty
|
cmd.Stdin = tty
|
||||||
cmd.Stdout = tty
|
cmd.Stdout = tty
|
||||||
cmd.Stderr = tty
|
cmd.Stderr = tty
|
||||||
ch := make(chan struct{})
|
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
c.Fatalf("start err: %v", err)
|
c.Fatalf("start err: %v", err)
|
||||||
}
|
}
|
||||||
|
ch := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
if err := cmd.Wait(); err != nil {
|
ch <- cmd.Wait()
|
||||||
c.Fatalf("wait err=%v", err)
|
|
||||||
}
|
|
||||||
close(ch)
|
close(ch)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(10 * time.Second):
|
case <-time.After(10 * time.Second):
|
||||||
c.Fatal("command timeout")
|
c.Fatal("command timeout")
|
||||||
case <-ch:
|
case err := <-ch:
|
||||||
|
if err != nil {
|
||||||
|
c.Fatalf("wait err=%v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,19 @@ func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) {
|
||||||
c.Fatal("Expected error but got none")
|
c.Fatal("Expected error but got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := make(chan struct{})
|
ch := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
// Attempt to start attached to the container that won't start
|
// Attempt to start attached to the container that won't start
|
||||||
// This should return an error immediately since the container can't be started
|
// This should return an error immediately since the container can't be started
|
||||||
if _, err := runCommand(exec.Command(dockerBinary, "start", "-a", "test2")); err == nil {
|
if _, err := runCommand(exec.Command(dockerBinary, "start", "-a", "test2")); err == nil {
|
||||||
c.Fatal("Expected error but got none")
|
ch <- fmt.Errorf("Expected error but got none")
|
||||||
}
|
}
|
||||||
close(ch)
|
close(ch)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ch:
|
case err := <-ch:
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
case <-time.After(time.Second):
|
case <-time.After(time.Second):
|
||||||
c.Fatalf("Attach did not exit properly")
|
c.Fatalf("Attach did not exit properly")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue