github.com/dinever/docker@v1.11.1/integration-cli/docker_cli_start_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "github.com/docker/docker/pkg/integration/checker" 9 "github.com/go-check/check" 10 ) 11 12 // Regression test for https://github.com/docker/docker/issues/7843 13 func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) { 14 // Windows does not support link 15 testRequires(c, DaemonIsLinux) 16 dockerCmd(c, "run", "--name", "test", "busybox") 17 18 // Expect this to fail because the above container is stopped, this is what we want 19 out, _, err := dockerCmdWithError("run", "--name", "test2", "--link", "test:test", "busybox") 20 // err shouldn't be nil because container test2 try to link to stopped container 21 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 22 23 ch := make(chan error) 24 go func() { 25 // Attempt to start attached to the container that won't start 26 // This should return an error immediately since the container can't be started 27 if _, _, err := dockerCmdWithError("start", "-a", "test2"); err == nil { 28 ch <- fmt.Errorf("Expected error but got none") 29 } 30 close(ch) 31 }() 32 33 select { 34 case err := <-ch: 35 c.Assert(err, check.IsNil) 36 case <-time.After(5 * time.Second): 37 c.Fatalf("Attach did not exit properly") 38 } 39 } 40 41 // gh#8555: Exit code should be passed through when using start -a 42 func (s *DockerSuite) TestStartAttachCorrectExitCode(c *check.C) { 43 testRequires(c, DaemonIsLinux) 44 out, _, _ := dockerCmdWithStdoutStderr(c, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1") 45 out = strings.TrimSpace(out) 46 47 // make sure the container has exited before trying the "start -a" 48 dockerCmd(c, "wait", out) 49 50 startOut, exitCode, err := dockerCmdWithError("start", "-a", out) 51 // start command should fail 52 c.Assert(err, checker.NotNil, check.Commentf("startOut: %s", startOut)) 53 // start -a did not respond with proper exit code 54 c.Assert(exitCode, checker.Equals, 1, check.Commentf("startOut: %s", startOut)) 55 56 } 57 58 func (s *DockerSuite) TestStartAttachSilent(c *check.C) { 59 name := "teststartattachcorrectexitcode" 60 dockerCmd(c, "run", "--name", name, "busybox", "echo", "test") 61 62 // make sure the container has exited before trying the "start -a" 63 dockerCmd(c, "wait", name) 64 65 startOut, _ := dockerCmd(c, "start", "-a", name) 66 // start -a produced unexpected output 67 c.Assert(startOut, checker.Equals, "test\n") 68 } 69 70 func (s *DockerSuite) TestStartRecordError(c *check.C) { 71 // TODO Windows CI: Requires further porting work. Should be possible. 72 testRequires(c, DaemonIsLinux) 73 // when container runs successfully, we should not have state.Error 74 dockerCmd(c, "run", "-d", "-p", "9999:9999", "--name", "test", "busybox", "top") 75 stateErr := inspectField(c, "test", "State.Error") 76 // Expected to not have state error 77 c.Assert(stateErr, checker.Equals, "") 78 79 // Expect this to fail and records error because of ports conflict 80 out, _, err := dockerCmdWithError("run", "-d", "--name", "test2", "-p", "9999:9999", "busybox", "top") 81 // err shouldn't be nil because docker run will fail 82 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 83 84 stateErr = inspectField(c, "test2", "State.Error") 85 c.Assert(stateErr, checker.Contains, "port is already allocated") 86 87 // Expect the conflict to be resolved when we stop the initial container 88 dockerCmd(c, "stop", "test") 89 dockerCmd(c, "start", "test2") 90 stateErr = inspectField(c, "test2", "State.Error") 91 // Expected to not have state error but got one 92 c.Assert(stateErr, checker.Equals, "") 93 } 94 95 func (s *DockerSuite) TestStartPausedContainer(c *check.C) { 96 // Windows does not support pausing containers 97 testRequires(c, DaemonIsLinux) 98 defer unpauseAllContainers() 99 100 dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "top") 101 102 dockerCmd(c, "pause", "testing") 103 104 out, _, err := dockerCmdWithError("start", "testing") 105 // an error should have been shown that you cannot start paused container 106 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 107 // an error should have been shown that you cannot start paused container 108 c.Assert(out, checker.Contains, "Cannot start a paused container, try unpause instead.") 109 } 110 111 func (s *DockerSuite) TestStartMultipleContainers(c *check.C) { 112 // Windows does not support --link 113 testRequires(c, DaemonIsLinux) 114 // run a container named 'parent' and create two container link to `parent` 115 dockerCmd(c, "run", "-d", "--name", "parent", "busybox", "top") 116 117 for _, container := range []string{"child_first", "child_second"} { 118 dockerCmd(c, "create", "--name", container, "--link", "parent:parent", "busybox", "top") 119 } 120 121 // stop 'parent' container 122 dockerCmd(c, "stop", "parent") 123 124 out := inspectField(c, "parent", "State.Running") 125 // Container should be stopped 126 c.Assert(out, checker.Equals, "false") 127 128 // start all the three containers, container `child_first` start first which should be failed 129 // container 'parent' start second and then start container 'child_second' 130 expOut := "Cannot link to a non running container" 131 expErr := "failed to start containers: [child_first]" 132 out, _, err := dockerCmdWithError("start", "child_first", "parent", "child_second") 133 // err shouldn't be nil because start will fail 134 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 135 // output does not correspond to what was expected 136 if !(strings.Contains(out, expOut) || strings.Contains(err.Error(), expErr)) { 137 c.Fatalf("Expected out: %v with err: %v but got out: %v with err: %v", expOut, expErr, out, err) 138 } 139 140 for container, expected := range map[string]string{"parent": "true", "child_first": "false", "child_second": "true"} { 141 out := inspectField(c, container, "State.Running") 142 // Container running state wrong 143 c.Assert(out, checker.Equals, expected) 144 } 145 } 146 147 func (s *DockerSuite) TestStartAttachMultipleContainers(c *check.C) { 148 // run multiple containers to test 149 for _, container := range []string{"test1", "test2", "test3"} { 150 runSleepingContainer(c, "--name", container) 151 } 152 153 // stop all the containers 154 for _, container := range []string{"test1", "test2", "test3"} { 155 dockerCmd(c, "stop", container) 156 } 157 158 // test start and attach multiple containers at once, expected error 159 for _, option := range []string{"-a", "-i", "-ai"} { 160 out, _, err := dockerCmdWithError("start", option, "test1", "test2", "test3") 161 // err shouldn't be nil because start will fail 162 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 163 // output does not correspond to what was expected 164 c.Assert(out, checker.Contains, "You cannot start and attach multiple containers at once.") 165 } 166 167 // confirm the state of all the containers be stopped 168 for container, expected := range map[string]string{"test1": "false", "test2": "false", "test3": "false"} { 169 out := inspectField(c, container, "State.Running") 170 // Container running state wrong 171 c.Assert(out, checker.Equals, expected) 172 } 173 }