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