github.com/pritambaral/docker@v1.4.2-0.20150120174542-b2fe1b3dd952/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 }