github.com/uriddle/docker@v0.0.0-20210926094723-4072e6aeb013/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 testRequires(c, DaemonIsLinux) 15 dockerCmd(c, "run", "-d", "--name", "test", "busybox") 16 dockerCmd(c, "wait", "test") 17 18 // Expect this to fail because the above container is stopped, this is what we want 19 out, _, err := dockerCmdWithError("run", "-d", "--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 testRequires(c, DaemonIsLinux) 60 name := "teststartattachcorrectexitcode" 61 dockerCmd(c, "run", "--name", name, "busybox", "echo", "test") 62 63 // make sure the container has exited before trying the "start -a" 64 dockerCmd(c, "wait", name) 65 66 startOut, _ := dockerCmd(c, "start", "-a", name) 67 // start -a produced unexpected output 68 c.Assert(startOut, checker.Equals, "test\n") 69 } 70 71 func (s *DockerSuite) TestStartRecordError(c *check.C) { 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, err := inspectField("test", "State.Error") 76 c.Assert(err, checker.IsNil, check.Commentf("stateErr: %s", stateErr)) 77 // Expected to not have state error 78 c.Assert(stateErr, checker.Equals, "") 79 80 // Expect this to fail and records error because of ports conflict 81 out, _, err := dockerCmdWithError("run", "-d", "--name", "test2", "-p", "9999:9999", "busybox", "top") 82 // err shouldn't be nil because docker run will fail 83 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 84 85 stateErr, err = inspectField("test2", "State.Error") 86 c.Assert(err, check.IsNil, check.Commentf("stateErr: %s", stateErr)) 87 c.Assert(stateErr, checker.Contains, "port is already allocated") 88 89 // Expect the conflict to be resolved when we stop the initial container 90 dockerCmd(c, "stop", "test") 91 dockerCmd(c, "start", "test2") 92 stateErr, err = inspectField("test2", "State.Error") 93 c.Assert(err, check.IsNil, check.Commentf("stateErr: %s", stateErr)) 94 // Expected to not have state error but got one 95 c.Assert(stateErr, checker.Equals, "") 96 } 97 98 func (s *DockerSuite) TestStartPausedContainer(c *check.C) { 99 testRequires(c, DaemonIsLinux) 100 defer unpauseAllContainers() 101 102 dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "top") 103 104 dockerCmd(c, "pause", "testing") 105 106 out, _, err := dockerCmdWithError("start", "testing") 107 // an error should have been shown that you cannot start paused container 108 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 109 // an error should have been shown that you cannot start paused container 110 c.Assert(out, checker.Contains, "Cannot start a paused container, try unpause instead.") 111 } 112 113 func (s *DockerSuite) TestStartMultipleContainers(c *check.C) { 114 testRequires(c, DaemonIsLinux) 115 // run a container named 'parent' and create two container link to `parent` 116 dockerCmd(c, "run", "-d", "--name", "parent", "busybox", "top") 117 118 for _, container := range []string{"child_first", "child_second"} { 119 dockerCmd(c, "create", "--name", container, "--link", "parent:parent", "busybox", "top") 120 } 121 122 // stop 'parent' container 123 dockerCmd(c, "stop", "parent") 124 125 out, err := inspectField("parent", "State.Running") 126 c.Assert(err, check.IsNil, check.Commentf("out: %s", out)) 127 // Container should be stopped 128 c.Assert(out, checker.Equals, "false") 129 130 // start all the three containers, container `child_first` start first which should be failed 131 // container 'parent' start second and then start container 'child_second' 132 expOut := "Cannot link to a non running container" 133 expErr := "failed to start containers: [child_first]" 134 out, _, err = dockerCmdWithError("start", "child_first", "parent", "child_second") 135 // err shouldn't be nil because start will fail 136 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 137 // output does not correspond to what was expected 138 if !(strings.Contains(out, expOut) || strings.Contains(err.Error(), expErr)) { 139 c.Fatalf("Expected out: %v with err: %v but got out: %v with err: %v", expOut, expErr, out, err) 140 } 141 142 for container, expected := range map[string]string{"parent": "true", "child_first": "false", "child_second": "true"} { 143 out, err := inspectField(container, "State.Running") 144 // Container running state wrong 145 c.Assert(err, check.IsNil, check.Commentf("out: %s", out)) 146 // Container running state wrong 147 c.Assert(out, checker.Equals, expected) 148 } 149 } 150 151 func (s *DockerSuite) TestStartAttachMultipleContainers(c *check.C) { 152 testRequires(c, DaemonIsLinux) 153 // run multiple containers to test 154 for _, container := range []string{"test1", "test2", "test3"} { 155 dockerCmd(c, "run", "-d", "--name", container, "busybox", "top") 156 } 157 158 // stop all the containers 159 for _, container := range []string{"test1", "test2", "test3"} { 160 dockerCmd(c, "stop", container) 161 } 162 163 // test start and attach multiple containers at once, expected error 164 for _, option := range []string{"-a", "-i", "-ai"} { 165 out, _, err := dockerCmdWithError("start", option, "test1", "test2", "test3") 166 // err shouldn't be nil because start will fail 167 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 168 // output does not correspond to what was expected 169 c.Assert(out, checker.Contains, "You cannot start and attach multiple containers at once.") 170 } 171 172 // confirm the state of all the containers be stopped 173 for container, expected := range map[string]string{"test1": "false", "test2": "false", "test3": "false"} { 174 out, err := inspectField(container, "State.Running") 175 // Container running state wrong 176 c.Assert(err, check.IsNil, check.Commentf("out: %s", out)) 177 // Container running state wrong 178 c.Assert(out, checker.Equals, expected) 179 } 180 }