github.com/adxhyt/docker@v1.4.2-0.20150117221845-467b7c821390/integration-cli/docker_cli_daemon_test.go (about)

     1  // +build daemon
     2  
     3  package main
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"os/exec"
    11  	"strings"
    12  	"testing"
    13  )
    14  
    15  func TestDaemonRestartWithRunningContainersPorts(t *testing.T) {
    16  	d := NewDaemon(t)
    17  	if err := d.StartWithBusybox(); err != nil {
    18  		t.Fatalf("Could not start daemon with busybox: %v", err)
    19  	}
    20  	defer d.Stop()
    21  
    22  	if out, err := d.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"); err != nil {
    23  		t.Fatalf("Could not run top1: err=%v\n%s", err, out)
    24  	}
    25  	// --restart=no by default
    26  	if out, err := d.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"); err != nil {
    27  		t.Fatalf("Could not run top2: err=%v\n%s", err, out)
    28  	}
    29  
    30  	testRun := func(m map[string]bool, prefix string) {
    31  		var format string
    32  		for c, shouldRun := range m {
    33  			out, err := d.Cmd("ps")
    34  			if err != nil {
    35  				t.Fatalf("Could not run ps: err=%v\n%q", err, out)
    36  			}
    37  			if shouldRun {
    38  				format = "%scontainer %q is not running"
    39  			} else {
    40  				format = "%scontainer %q is running"
    41  			}
    42  			if shouldRun != strings.Contains(out, c) {
    43  				t.Fatalf(format, prefix, c)
    44  			}
    45  		}
    46  	}
    47  
    48  	testRun(map[string]bool{"top1": true, "top2": true}, "")
    49  
    50  	if err := d.Restart(); err != nil {
    51  		t.Fatalf("Could not restart daemon: %v", err)
    52  	}
    53  
    54  	testRun(map[string]bool{"top1": true, "top2": false}, "After daemon restart: ")
    55  
    56  	logDone("daemon - running containers on daemon restart")
    57  }
    58  
    59  func TestDaemonRestartWithVolumesRefs(t *testing.T) {
    60  	d := NewDaemon(t)
    61  	if err := d.StartWithBusybox(); err != nil {
    62  		t.Fatal(err)
    63  	}
    64  	defer d.Stop()
    65  
    66  	if out, err := d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil {
    67  		t.Fatal(err, out)
    68  	}
    69  	if err := d.Restart(); err != nil {
    70  		t.Fatal(err)
    71  	}
    72  	if _, err := d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil {
    73  		t.Fatal(err)
    74  	}
    75  	if out, err := d.Cmd("rm", "-fv", "volrestarttest2"); err != nil {
    76  		t.Fatal(err, out)
    77  	}
    78  	v, err := d.Cmd("inspect", "--format", "{{ json .Volumes }}", "volrestarttest1")
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	volumes := make(map[string]string)
    83  	json.Unmarshal([]byte(v), &volumes)
    84  	if _, err := os.Stat(volumes["/foo"]); err != nil {
    85  		t.Fatalf("Expected volume to exist: %s - %s", volumes["/foo"], err)
    86  	}
    87  
    88  	logDone("daemon - volume refs are restored")
    89  }
    90  
    91  func TestDaemonStartIptablesFalse(t *testing.T) {
    92  	d := NewDaemon(t)
    93  	if err := d.Start("--iptables=false"); err != nil {
    94  		t.Fatalf("we should have been able to start the daemon with passing iptables=false: %v", err)
    95  	}
    96  	d.Stop()
    97  
    98  	logDone("daemon - started daemon with iptables=false")
    99  }
   100  
   101  // Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and
   102  // no longer has an IP associated, we should gracefully handle that case and associate
   103  // an IP with it rather than fail daemon start
   104  func TestDaemonStartBridgeWithoutIPAssociation(t *testing.T) {
   105  	d := NewDaemon(t)
   106  	// rather than depending on brctl commands to verify docker0 is created and up
   107  	// let's start the daemon and stop it, and then make a modification to run the
   108  	// actual test
   109  	if err := d.Start(); err != nil {
   110  		t.Fatalf("Could not start daemon: %v", err)
   111  	}
   112  	if err := d.Stop(); err != nil {
   113  		t.Fatalf("Could not stop daemon: %v", err)
   114  	}
   115  
   116  	// now we will remove the ip from docker0 and then try starting the daemon
   117  	ipCmd := exec.Command("ip", "addr", "flush", "dev", "docker0")
   118  	stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd)
   119  	if err != nil {
   120  		t.Fatalf("failed to remove docker0 IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr)
   121  	}
   122  
   123  	if err := d.Start(); err != nil {
   124  		warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix"
   125  		t.Fatalf("Could not start daemon when docker0 has no IP address: %v\n%s", err, warning)
   126  	}
   127  
   128  	// cleanup - stop the daemon if test passed
   129  	if err := d.Stop(); err != nil {
   130  		t.Fatalf("Could not stop daemon: %v", err)
   131  	}
   132  
   133  	logDone("daemon - successful daemon start when bridge has no IP association")
   134  }
   135  
   136  func TestDaemonIptablesClean(t *testing.T) {
   137  	d := NewDaemon(t)
   138  	if err := d.StartWithBusybox(); err != nil {
   139  		t.Fatalf("Could not start daemon with busybox: %v", err)
   140  	}
   141  	defer d.Stop()
   142  
   143  	if out, err := d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil {
   144  		t.Fatalf("Could not run top: %s, %v", out, err)
   145  	}
   146  
   147  	// get output from iptables with container running
   148  	ipTablesSearchString := "tcp dpt:80"
   149  	ipTablesCmd := exec.Command("iptables", "-nvL")
   150  	out, _, err := runCommandWithOutput(ipTablesCmd)
   151  	if err != nil {
   152  		t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
   153  	}
   154  
   155  	if !strings.Contains(out, ipTablesSearchString) {
   156  		t.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
   157  	}
   158  
   159  	if err := d.Stop(); err != nil {
   160  		t.Fatalf("Could not stop daemon: %v", err)
   161  	}
   162  
   163  	// get output from iptables after restart
   164  	ipTablesCmd = exec.Command("iptables", "-nvL")
   165  	out, _, err = runCommandWithOutput(ipTablesCmd)
   166  	if err != nil {
   167  		t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
   168  	}
   169  
   170  	if strings.Contains(out, ipTablesSearchString) {
   171  		t.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out)
   172  	}
   173  
   174  	deleteAllContainers()
   175  
   176  	logDone("daemon - run,iptables - iptables rules cleaned after daemon restart")
   177  }
   178  
   179  func TestDaemonIptablesCreate(t *testing.T) {
   180  	d := NewDaemon(t)
   181  	if err := d.StartWithBusybox(); err != nil {
   182  		t.Fatalf("Could not start daemon with busybox: %v", err)
   183  	}
   184  	defer d.Stop()
   185  
   186  	if out, err := d.Cmd("run", "-d", "--name", "top", "--restart=always", "-p", "80", "busybox:latest", "top"); err != nil {
   187  		t.Fatalf("Could not run top: %s, %v", out, err)
   188  	}
   189  
   190  	// get output from iptables with container running
   191  	ipTablesSearchString := "tcp dpt:80"
   192  	ipTablesCmd := exec.Command("iptables", "-nvL")
   193  	out, _, err := runCommandWithOutput(ipTablesCmd)
   194  	if err != nil {
   195  		t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
   196  	}
   197  
   198  	if !strings.Contains(out, ipTablesSearchString) {
   199  		t.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out)
   200  	}
   201  
   202  	if err := d.Restart(); err != nil {
   203  		t.Fatalf("Could not restart daemon: %v", err)
   204  	}
   205  
   206  	// make sure the container is not running
   207  	runningOut, err := d.Cmd("inspect", "--format='{{.State.Running}}'", "top")
   208  	if err != nil {
   209  		t.Fatalf("Could not inspect on container: %s, %v", out, err)
   210  	}
   211  	if strings.TrimSpace(runningOut) != "true" {
   212  		t.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut))
   213  	}
   214  
   215  	// get output from iptables after restart
   216  	ipTablesCmd = exec.Command("iptables", "-nvL")
   217  	out, _, err = runCommandWithOutput(ipTablesCmd)
   218  	if err != nil {
   219  		t.Fatalf("Could not run iptables -nvL: %s, %v", out, err)
   220  	}
   221  
   222  	if !strings.Contains(out, ipTablesSearchString) {
   223  		t.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out)
   224  	}
   225  
   226  	deleteAllContainers()
   227  
   228  	logDone("daemon - run,iptables - iptables rules for always restarted container created after daemon restart")
   229  }
   230  
   231  func TestDaemonLoggingLevel(t *testing.T) {
   232  	d := NewDaemon(t)
   233  
   234  	if err := d.Start("--log-level=bogus"); err == nil {
   235  		t.Fatal("Daemon should not have been able to start")
   236  	}
   237  
   238  	d = NewDaemon(t)
   239  	if err := d.Start("--log-level=debug"); err != nil {
   240  		t.Fatal(err)
   241  	}
   242  	d.Stop()
   243  	content, _ := ioutil.ReadFile(d.logFile.Name())
   244  	if !strings.Contains(string(content), `level="debug"`) {
   245  		t.Fatalf(`Missing level="debug" in log file:\n%s`, string(content))
   246  	}
   247  
   248  	d = NewDaemon(t)
   249  	if err := d.Start("--log-level=fatal"); err != nil {
   250  		t.Fatal(err)
   251  	}
   252  	d.Stop()
   253  	content, _ = ioutil.ReadFile(d.logFile.Name())
   254  	if strings.Contains(string(content), `level="debug"`) {
   255  		t.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content))
   256  	}
   257  
   258  	d = NewDaemon(t)
   259  	if err := d.Start("-D"); err != nil {
   260  		t.Fatal(err)
   261  	}
   262  	d.Stop()
   263  	content, _ = ioutil.ReadFile(d.logFile.Name())
   264  	if !strings.Contains(string(content), `level="debug"`) {
   265  		t.Fatalf(`Missing level="debug" in log file using -D:\n%s`, string(content))
   266  	}
   267  
   268  	d = NewDaemon(t)
   269  	if err := d.Start("--debug"); err != nil {
   270  		t.Fatal(err)
   271  	}
   272  	d.Stop()
   273  	content, _ = ioutil.ReadFile(d.logFile.Name())
   274  	if !strings.Contains(string(content), `level="debug"`) {
   275  		t.Fatalf(`Missing level="debug" in log file using --debug:\n%s`, string(content))
   276  	}
   277  
   278  	d = NewDaemon(t)
   279  	if err := d.Start("--debug", "--log-level=fatal"); err != nil {
   280  		t.Fatal(err)
   281  	}
   282  	d.Stop()
   283  	content, _ = ioutil.ReadFile(d.logFile.Name())
   284  	if !strings.Contains(string(content), `level="debug"`) {
   285  		t.Fatalf(`Missing level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content))
   286  	}
   287  
   288  	logDone("daemon - Logging Level")
   289  }
   290  
   291  func TestDaemonAllocatesListeningPort(t *testing.T) {
   292  	listeningPorts := [][]string{
   293  		{"0.0.0.0", "0.0.0.0", "5678"},
   294  		{"127.0.0.1", "127.0.0.1", "1234"},
   295  		{"localhost", "127.0.0.1", "1235"},
   296  	}
   297  
   298  	cmdArgs := []string{}
   299  	for _, hostDirective := range listeningPorts {
   300  		cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2]))
   301  	}
   302  
   303  	d := NewDaemon(t)
   304  	if err := d.StartWithBusybox(cmdArgs...); err != nil {
   305  		t.Fatalf("Could not start daemon with busybox: %v", err)
   306  	}
   307  	defer d.Stop()
   308  
   309  	for _, hostDirective := range listeningPorts {
   310  		output, err := d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true")
   311  		if err == nil {
   312  			t.Fatalf("Container should not start, expected port already allocated error: %q", output)
   313  		} else if !strings.Contains(output, "port is already allocated") {
   314  			t.Fatalf("Expected port is already allocated error: %q", output)
   315  		}
   316  	}
   317  
   318  	logDone("daemon - daemon listening port is allocated")
   319  }