github.com/akerouanton/docker@v1.11.0-rc3/integration-cli/docker_cli_daemon_experimental_test.go (about)

     1  // +build daemon,!windows,experimental
     2  
     3  package main
     4  
     5  import (
     6  	"io/ioutil"
     7  	"os"
     8  	"os/exec"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/go-check/check"
    13  )
    14  
    15  // TestDaemonRestartWithKilledRunningContainer requires live restore of running containers
    16  func (s *DockerDaemonSuite) TestDaemonRestartWithKilledRunningContainer(t *check.C) {
    17  	// TODO(mlaventure): Not sure what would the exit code be on windows
    18  	testRequires(t, DaemonIsLinux)
    19  	if err := s.d.StartWithBusybox(); err != nil {
    20  		t.Fatal(err)
    21  	}
    22  
    23  	cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top")
    24  	defer s.d.Stop()
    25  	if err != nil {
    26  		t.Fatal(cid, err)
    27  	}
    28  	cid = strings.TrimSpace(cid)
    29  
    30  	// Kill the daemon
    31  	if err := s.d.Kill(); err != nil {
    32  		t.Fatal(err)
    33  	}
    34  
    35  	// kill the container
    36  	runCmd := exec.Command(ctrBinary, "--address", "/var/run/docker/libcontainerd/docker-containerd.sock", "containers", "kill", cid)
    37  	if out, ec, err := runCommandWithOutput(runCmd); err != nil {
    38  		t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid)
    39  	}
    40  
    41  	// Give time to containerd to process the command if we don't
    42  	// the exit event might be received after we do the inspect
    43  	time.Sleep(3 * time.Second)
    44  
    45  	// restart the daemon
    46  	if err := s.d.Start(); err != nil {
    47  		t.Fatal(err)
    48  	}
    49  
    50  	// Check that we've got the correct exit code
    51  	out, err := s.d.Cmd("inspect", "-f", "{{.State.ExitCode}}", cid)
    52  	t.Assert(err, check.IsNil)
    53  
    54  	out = strings.TrimSpace(out)
    55  	if out != "143" {
    56  		t.Fatalf("Expected exit code '%s' got '%s' for container '%s'\n", "143", out, cid)
    57  	}
    58  
    59  }
    60  
    61  // os.Kill should kill daemon ungracefully, leaving behind live containers.
    62  // The live containers should be known to the restarted daemon. Stopping
    63  // them now, should remove the mounts.
    64  func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonCrash(c *check.C) {
    65  	testRequires(c, DaemonIsLinux)
    66  	c.Assert(s.d.StartWithBusybox(), check.IsNil)
    67  
    68  	out, err := s.d.Cmd("run", "-d", "busybox", "top")
    69  	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
    70  	id := strings.TrimSpace(out)
    71  
    72  	c.Assert(s.d.cmd.Process.Signal(os.Kill), check.IsNil)
    73  	mountOut, err := ioutil.ReadFile("/proc/self/mountinfo")
    74  	c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut))
    75  
    76  	// container mounts should exist even after daemon has crashed.
    77  	comment := check.Commentf("%s should stay mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut)
    78  	c.Assert(strings.Contains(string(mountOut), id), check.Equals, true, comment)
    79  
    80  	// restart daemon.
    81  	if err := s.d.Restart(); err != nil {
    82  		c.Fatal(err)
    83  	}
    84  
    85  	// container should be running.
    86  	out, err = s.d.Cmd("inspect", "--format='{{.State.Running}}'", id)
    87  	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
    88  	out = strings.TrimSpace(out)
    89  	if out != "true" {
    90  		c.Fatalf("Container %s expected to stay alive after daemon restart", id)
    91  	}
    92  
    93  	// 'docker stop' should work.
    94  	out, err = s.d.Cmd("stop", id)
    95  	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
    96  
    97  	// Now, container mounts should be gone.
    98  	mountOut, err = ioutil.ReadFile("/proc/self/mountinfo")
    99  	c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut))
   100  	comment = check.Commentf("%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut)
   101  	c.Assert(strings.Contains(string(mountOut), id), check.Equals, false, comment)
   102  }
   103  
   104  // TestDaemonRestartWithPausedRunningContainer requires live restore of running containers
   105  func (s *DockerDaemonSuite) TestDaemonRestartWithPausedRunningContainer(t *check.C) {
   106  	if err := s.d.StartWithBusybox(); err != nil {
   107  		t.Fatal(err)
   108  	}
   109  
   110  	cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top")
   111  	defer s.d.Stop()
   112  	if err != nil {
   113  		t.Fatal(cid, err)
   114  	}
   115  	cid = strings.TrimSpace(cid)
   116  
   117  	// Kill the daemon
   118  	if err := s.d.Kill(); err != nil {
   119  		t.Fatal(err)
   120  	}
   121  
   122  	// kill the container
   123  	runCmd := exec.Command(ctrBinary, "--address", "/var/run/docker/libcontainerd/docker-containerd.sock", "containers", "pause", cid)
   124  	if out, ec, err := runCommandWithOutput(runCmd); err != nil {
   125  		t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid)
   126  	}
   127  
   128  	// Give time to containerd to process the command if we don't
   129  	// the pause event might be received after we do the inspect
   130  	time.Sleep(3 * time.Second)
   131  
   132  	// restart the daemon
   133  	if err := s.d.Start(); err != nil {
   134  		t.Fatal(err)
   135  	}
   136  
   137  	// Check that we've got the correct status
   138  	out, err := s.d.Cmd("inspect", "-f", "{{.State.Status}}", cid)
   139  	t.Assert(err, check.IsNil)
   140  
   141  	out = strings.TrimSpace(out)
   142  	if out != "paused" {
   143  		t.Fatalf("Expected exit code '%s' got '%s' for container '%s'\n", "paused", out, cid)
   144  	}
   145  }
   146  
   147  // TestDaemonRestartWithUnpausedRunningContainer requires live restore of running containers.
   148  func (s *DockerDaemonSuite) TestDaemonRestartWithUnpausedRunningContainer(t *check.C) {
   149  	// TODO(mlaventure): Not sure what would the exit code be on windows
   150  	testRequires(t, DaemonIsLinux)
   151  	if err := s.d.StartWithBusybox(); err != nil {
   152  		t.Fatal(err)
   153  	}
   154  
   155  	cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top")
   156  	defer s.d.Stop()
   157  	if err != nil {
   158  		t.Fatal(cid, err)
   159  	}
   160  	cid = strings.TrimSpace(cid)
   161  
   162  	// pause the container
   163  	if _, err := s.d.Cmd("pause", cid); err != nil {
   164  		t.Fatal(cid, err)
   165  	}
   166  
   167  	// Kill the daemon
   168  	if err := s.d.Kill(); err != nil {
   169  		t.Fatal(err)
   170  	}
   171  
   172  	// resume the container
   173  	runCmd := exec.Command(ctrBinary, "--address", "/var/run/docker/libcontainerd/docker-containerd.sock", "containers", "resume", cid)
   174  	if out, ec, err := runCommandWithOutput(runCmd); err != nil {
   175  		t.Fatalf("Failed to run ctr, ExitCode: %d, err: '%v' output: '%s' cid: '%s'\n", ec, err, out, cid)
   176  	}
   177  
   178  	// Give time to containerd to process the command if we don't
   179  	// the resume event might be received after we do the inspect
   180  	time.Sleep(3 * time.Second)
   181  
   182  	// restart the daemon
   183  	if err := s.d.Start(); err != nil {
   184  		t.Fatal(err)
   185  	}
   186  
   187  	// Check that we've got the correct status
   188  	out, err := s.d.Cmd("inspect", "-f", "{{.State.Status}}", cid)
   189  	t.Assert(err, check.IsNil)
   190  
   191  	out = strings.TrimSpace(out)
   192  	if out != "running" {
   193  		t.Fatalf("Expected exit code '%s' got '%s' for container '%s'\n", "running", out, cid)
   194  	}
   195  }