github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/integration-cli/docker_cli_restart_test.go (about) 1 package main 2 3 import ( 4 "os" 5 "strconv" 6 "strings" 7 "time" 8 9 "github.com/docker/docker/integration-cli/checker" 10 "github.com/go-check/check" 11 "gotest.tools/assert" 12 is "gotest.tools/assert/cmp" 13 ) 14 15 func (s *DockerSuite) TestRestartStoppedContainer(c *check.C) { 16 dockerCmd(c, "run", "--name=test", "busybox", "echo", "foobar") 17 cleanedContainerID := getIDByName(c, "test") 18 19 out, _ := dockerCmd(c, "logs", cleanedContainerID) 20 assert.Equal(c, out, "foobar\n") 21 22 dockerCmd(c, "restart", cleanedContainerID) 23 24 // Wait until the container has stopped 25 err := waitInspect(cleanedContainerID, "{{.State.Running}}", "false", 20*time.Second) 26 assert.NilError(c, err) 27 28 out, _ = dockerCmd(c, "logs", cleanedContainerID) 29 assert.Equal(c, out, "foobar\nfoobar\n") 30 } 31 32 func (s *DockerSuite) TestRestartRunningContainer(c *check.C) { 33 out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "echo foobar && sleep 30 && echo 'should not print this'") 34 35 cleanedContainerID := strings.TrimSpace(out) 36 37 assert.NilError(c, waitRun(cleanedContainerID)) 38 39 getLogs := func(c *check.C) (interface{}, check.CommentInterface) { 40 out, _ := dockerCmd(c, "logs", cleanedContainerID) 41 return out, nil 42 } 43 44 // Wait 10 seconds for the 'echo' to appear in the logs 45 waitAndAssert(c, 10*time.Second, getLogs, checker.Equals, "foobar\n") 46 47 dockerCmd(c, "restart", "-t", "1", cleanedContainerID) 48 assert.NilError(c, waitRun(cleanedContainerID)) 49 50 // Wait 10 seconds for first 'echo' appear (again) in the logs 51 waitAndAssert(c, 10*time.Second, getLogs, checker.Equals, "foobar\nfoobar\n") 52 } 53 54 // Test that restarting a container with a volume does not create a new volume on restart. Regression test for #819. 55 func (s *DockerSuite) TestRestartWithVolumes(c *check.C) { 56 prefix, slash := getPrefixAndSlashFromDaemonPlatform() 57 out := runSleepingContainer(c, "-d", "-v", prefix+slash+"test") 58 59 cleanedContainerID := strings.TrimSpace(out) 60 out, err := inspectFilter(cleanedContainerID, "len .Mounts") 61 assert.NilError(c, err, "failed to inspect %s: %s", cleanedContainerID, out) 62 out = strings.Trim(out, " \n\r") 63 assert.Equal(c, out, "1") 64 65 source, err := inspectMountSourceField(cleanedContainerID, prefix+slash+"test") 66 assert.NilError(c, err) 67 68 dockerCmd(c, "restart", cleanedContainerID) 69 70 out, err = inspectFilter(cleanedContainerID, "len .Mounts") 71 assert.NilError(c, err, "failed to inspect %s: %s", cleanedContainerID, out) 72 out = strings.Trim(out, " \n\r") 73 assert.Equal(c, out, "1") 74 75 sourceAfterRestart, err := inspectMountSourceField(cleanedContainerID, prefix+slash+"test") 76 assert.NilError(c, err) 77 assert.Equal(c, source, sourceAfterRestart) 78 } 79 80 func (s *DockerSuite) TestRestartDisconnectedContainer(c *check.C) { 81 testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon, NotUserNamespace, NotArm) 82 83 // Run a container on the default bridge network 84 out, _ := dockerCmd(c, "run", "-d", "--name", "c0", "busybox", "top") 85 cleanedContainerID := strings.TrimSpace(out) 86 assert.NilError(c, waitRun(cleanedContainerID)) 87 88 // Disconnect the container from the network 89 out, exitCode := dockerCmd(c, "network", "disconnect", "bridge", "c0") 90 assert.Assert(c, exitCode == 0, out) 91 92 // Restart the container 93 out, exitCode = dockerCmd(c, "restart", "c0") 94 assert.Assert(c, exitCode == 0, out) 95 } 96 97 func (s *DockerSuite) TestRestartPolicyNO(c *check.C) { 98 out, _ := dockerCmd(c, "create", "--restart=no", "busybox") 99 100 id := strings.TrimSpace(string(out)) 101 name := inspectField(c, id, "HostConfig.RestartPolicy.Name") 102 assert.Equal(c, name, "no") 103 } 104 105 func (s *DockerSuite) TestRestartPolicyAlways(c *check.C) { 106 out, _ := dockerCmd(c, "create", "--restart=always", "busybox") 107 108 id := strings.TrimSpace(string(out)) 109 name := inspectField(c, id, "HostConfig.RestartPolicy.Name") 110 assert.Equal(c, name, "always") 111 112 MaximumRetryCount := inspectField(c, id, "HostConfig.RestartPolicy.MaximumRetryCount") 113 114 // MaximumRetryCount=0 if the restart policy is always 115 assert.Equal(c, MaximumRetryCount, "0") 116 } 117 118 func (s *DockerSuite) TestRestartPolicyOnFailure(c *check.C) { 119 out, _, err := dockerCmdWithError("create", "--restart=on-failure:-1", "busybox") 120 assert.ErrorContains(c, err, "", out) 121 assert.Assert(c, strings.Contains(out, "maximum retry count cannot be negative")) 122 123 out, _ = dockerCmd(c, "create", "--restart=on-failure:1", "busybox") 124 125 id := strings.TrimSpace(string(out)) 126 name := inspectField(c, id, "HostConfig.RestartPolicy.Name") 127 maxRetry := inspectField(c, id, "HostConfig.RestartPolicy.MaximumRetryCount") 128 129 assert.Equal(c, name, "on-failure") 130 assert.Equal(c, maxRetry, "1") 131 132 out, _ = dockerCmd(c, "create", "--restart=on-failure:0", "busybox") 133 134 id = strings.TrimSpace(string(out)) 135 name = inspectField(c, id, "HostConfig.RestartPolicy.Name") 136 maxRetry = inspectField(c, id, "HostConfig.RestartPolicy.MaximumRetryCount") 137 138 assert.Equal(c, name, "on-failure") 139 assert.Equal(c, maxRetry, "0") 140 141 out, _ = dockerCmd(c, "create", "--restart=on-failure", "busybox") 142 143 id = strings.TrimSpace(string(out)) 144 name = inspectField(c, id, "HostConfig.RestartPolicy.Name") 145 maxRetry = inspectField(c, id, "HostConfig.RestartPolicy.MaximumRetryCount") 146 147 assert.Equal(c, name, "on-failure") 148 assert.Equal(c, maxRetry, "0") 149 } 150 151 // a good container with --restart=on-failure:3 152 // MaximumRetryCount!=0; RestartCount=0 153 func (s *DockerSuite) TestRestartContainerwithGoodContainer(c *check.C) { 154 out, _ := dockerCmd(c, "run", "-d", "--restart=on-failure:3", "busybox", "true") 155 156 id := strings.TrimSpace(string(out)) 157 err := waitInspect(id, "{{ .State.Restarting }} {{ .State.Running }}", "false false", 30*time.Second) 158 assert.NilError(c, err) 159 160 count := inspectField(c, id, "RestartCount") 161 assert.Equal(c, count, "0") 162 163 MaximumRetryCount := inspectField(c, id, "HostConfig.RestartPolicy.MaximumRetryCount") 164 assert.Equal(c, MaximumRetryCount, "3") 165 } 166 167 func (s *DockerSuite) TestRestartContainerSuccess(c *check.C) { 168 testRequires(c, testEnv.IsLocalDaemon) 169 170 out := runSleepingContainer(c, "-d", "--restart=always") 171 id := strings.TrimSpace(out) 172 assert.NilError(c, waitRun(id)) 173 174 pidStr := inspectField(c, id, "State.Pid") 175 176 pid, err := strconv.Atoi(pidStr) 177 assert.NilError(c, err) 178 179 p, err := os.FindProcess(pid) 180 assert.NilError(c, err) 181 assert.Assert(c, p != nil) 182 183 err = p.Kill() 184 assert.NilError(c, err) 185 186 err = waitInspect(id, "{{.RestartCount}}", "1", 30*time.Second) 187 assert.NilError(c, err) 188 189 err = waitInspect(id, "{{.State.Status}}", "running", 30*time.Second) 190 assert.NilError(c, err) 191 } 192 193 func (s *DockerSuite) TestRestartWithPolicyUserDefinedNetwork(c *check.C) { 194 // TODO Windows. This may be portable following HNS integration post TP5. 195 testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon, NotUserNamespace, NotArm) 196 dockerCmd(c, "network", "create", "-d", "bridge", "udNet") 197 198 dockerCmd(c, "run", "-d", "--net=udNet", "--name=first", "busybox", "top") 199 assert.NilError(c, waitRun("first")) 200 201 dockerCmd(c, "run", "-d", "--restart=always", "--net=udNet", "--name=second", 202 "--link=first:foo", "busybox", "top") 203 assert.NilError(c, waitRun("second")) 204 205 // ping to first and its alias foo must succeed 206 _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") 207 assert.NilError(c, err) 208 _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo") 209 assert.NilError(c, err) 210 211 // Now kill the second container and let the restart policy kick in 212 pidStr := inspectField(c, "second", "State.Pid") 213 214 pid, err := strconv.Atoi(pidStr) 215 assert.NilError(c, err) 216 217 p, err := os.FindProcess(pid) 218 assert.NilError(c, err) 219 assert.Assert(c, p != nil) 220 221 err = p.Kill() 222 assert.NilError(c, err) 223 224 err = waitInspect("second", "{{.RestartCount}}", "1", 5*time.Second) 225 assert.NilError(c, err) 226 227 err = waitInspect("second", "{{.State.Status}}", "running", 5*time.Second) 228 assert.NilError(c, err) 229 230 // ping to first and its alias foo must still succeed 231 _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") 232 assert.NilError(c, err) 233 _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo") 234 assert.NilError(c, err) 235 } 236 237 func (s *DockerSuite) TestRestartPolicyAfterRestart(c *check.C) { 238 testRequires(c, testEnv.IsLocalDaemon) 239 240 out := runSleepingContainer(c, "-d", "--restart=always") 241 id := strings.TrimSpace(out) 242 assert.NilError(c, waitRun(id)) 243 244 dockerCmd(c, "restart", id) 245 246 assert.NilError(c, waitRun(id)) 247 248 pidStr := inspectField(c, id, "State.Pid") 249 250 pid, err := strconv.Atoi(pidStr) 251 assert.NilError(c, err) 252 253 p, err := os.FindProcess(pid) 254 assert.NilError(c, err) 255 assert.Assert(c, p != nil) 256 257 err = p.Kill() 258 assert.NilError(c, err) 259 260 err = waitInspect(id, "{{.RestartCount}}", "1", 30*time.Second) 261 assert.NilError(c, err) 262 263 err = waitInspect(id, "{{.State.Status}}", "running", 30*time.Second) 264 assert.NilError(c, err) 265 } 266 267 func (s *DockerSuite) TestRestartContainerwithRestartPolicy(c *check.C) { 268 out1, _ := dockerCmd(c, "run", "-d", "--restart=on-failure:3", "busybox", "false") 269 out2, _ := dockerCmd(c, "run", "-d", "--restart=always", "busybox", "false") 270 271 id1 := strings.TrimSpace(string(out1)) 272 id2 := strings.TrimSpace(string(out2)) 273 waitTimeout := 15 * time.Second 274 if testEnv.OSType == "windows" { 275 waitTimeout = 150 * time.Second 276 } 277 err := waitInspect(id1, "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTimeout) 278 assert.NilError(c, err) 279 280 dockerCmd(c, "restart", id1) 281 dockerCmd(c, "restart", id2) 282 283 // Make sure we can stop/start (regression test from a705e166cf3bcca62543150c2b3f9bfeae45ecfa) 284 dockerCmd(c, "stop", id1) 285 dockerCmd(c, "stop", id2) 286 dockerCmd(c, "start", id1) 287 dockerCmd(c, "start", id2) 288 289 // Kill the containers, making sure the are stopped at the end of the test 290 dockerCmd(c, "kill", id1) 291 dockerCmd(c, "kill", id2) 292 err = waitInspect(id1, "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTimeout) 293 assert.NilError(c, err) 294 err = waitInspect(id2, "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTimeout) 295 assert.NilError(c, err) 296 } 297 298 func (s *DockerSuite) TestRestartAutoRemoveContainer(c *check.C) { 299 out := runSleepingContainer(c, "--rm") 300 301 id := strings.TrimSpace(string(out)) 302 dockerCmd(c, "restart", id) 303 err := waitInspect(id, "{{ .State.Restarting }} {{ .State.Running }}", "false true", 15*time.Second) 304 assert.NilError(c, err) 305 306 out, _ = dockerCmd(c, "ps") 307 assert.Assert(c, is.Contains(out, id[:12]), "container should be restarted instead of removed: %v", out) 308 309 // Kill the container to make sure it will be removed 310 dockerCmd(c, "kill", id) 311 }