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  }