github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/integration-cli/docker_cli_events_unix_test.go (about) 1 // +build !windows 2 3 package main 4 5 import ( 6 "bufio" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "strings" 12 "time" 13 "unicode" 14 15 "github.com/docker/docker/pkg/integration/checker" 16 "github.com/go-check/check" 17 "github.com/kr/pty" 18 ) 19 20 // #5979 21 func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) { 22 since := daemonTime(c).Unix() 23 dockerCmd(c, "run", "busybox", "true") 24 25 file, err := ioutil.TempFile("", "") 26 c.Assert(err, checker.IsNil, check.Commentf("could not create temp file")) 27 defer os.Remove(file.Name()) 28 29 command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, daemonTime(c).Unix(), file.Name()) 30 _, tty, err := pty.Open() 31 c.Assert(err, checker.IsNil, check.Commentf("Could not open pty")) 32 cmd := exec.Command("sh", "-c", command) 33 cmd.Stdin = tty 34 cmd.Stdout = tty 35 cmd.Stderr = tty 36 c.Assert(cmd.Run(), checker.IsNil, check.Commentf("run err for command %q", command)) 37 38 scanner := bufio.NewScanner(file) 39 for scanner.Scan() { 40 for _, ch := range scanner.Text() { 41 c.Assert(unicode.IsControl(ch), checker.False, check.Commentf("found control character %v", []byte(string(ch)))) 42 } 43 } 44 c.Assert(scanner.Err(), checker.IsNil, check.Commentf("Scan err for command %q", command)) 45 46 } 47 48 func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) { 49 testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO) 50 51 errChan := make(chan error) 52 go func() { 53 defer close(errChan) 54 out, exitCode, _ := dockerCmdWithError("run", "--name", "oomFalse", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done") 55 if expected := 137; exitCode != expected { 56 errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out) 57 } 58 }() 59 select { 60 case err := <-errChan: 61 c.Assert(err, checker.IsNil) 62 case <-time.After(30 * time.Second): 63 c.Fatal("Timeout waiting for container to die on OOM") 64 } 65 66 out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=oomFalse", fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 67 events := strings.Split(strings.TrimSuffix(out, "\n"), "\n") 68 nEvents := len(events) 69 70 c.Assert(nEvents, checker.GreaterOrEqualThan, 5) //Missing expected event 71 c.Assert(parseEventAction(c, events[nEvents-5]), checker.Equals, "create") 72 c.Assert(parseEventAction(c, events[nEvents-4]), checker.Equals, "attach") 73 c.Assert(parseEventAction(c, events[nEvents-3]), checker.Equals, "start") 74 c.Assert(parseEventAction(c, events[nEvents-2]), checker.Equals, "oom") 75 c.Assert(parseEventAction(c, events[nEvents-1]), checker.Equals, "die") 76 } 77 78 func (s *DockerSuite) TestEventsOOMDisableTrue(c *check.C) { 79 testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO) 80 81 errChan := make(chan error) 82 go func() { 83 defer close(errChan) 84 out, exitCode, _ := dockerCmdWithError("run", "--oom-kill-disable=true", "--name", "oomTrue", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done") 85 if expected := 137; exitCode != expected { 86 errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out) 87 } 88 }() 89 select { 90 case err := <-errChan: 91 c.Assert(err, checker.IsNil) 92 case <-time.After(20 * time.Second): 93 defer dockerCmd(c, "kill", "oomTrue") 94 95 out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=oomTrue", fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 96 events := strings.Split(strings.TrimSuffix(out, "\n"), "\n") 97 nEvents := len(events) 98 c.Assert(nEvents, checker.GreaterOrEqualThan, 4) //Missing expected event 99 100 c.Assert(parseEventAction(c, events[nEvents-4]), checker.Equals, "create") 101 c.Assert(parseEventAction(c, events[nEvents-3]), checker.Equals, "attach") 102 c.Assert(parseEventAction(c, events[nEvents-2]), checker.Equals, "start") 103 c.Assert(parseEventAction(c, events[nEvents-1]), checker.Equals, "oom") 104 105 out, _ = dockerCmd(c, "inspect", "-f", "{{.State.Status}}", "oomTrue") 106 c.Assert(strings.TrimSpace(out), checker.Equals, "running", check.Commentf("container should be still running")) 107 } 108 } 109 110 // #18453 111 func (s *DockerSuite) TestEventsContainerFilterByName(c *check.C) { 112 testRequires(c, DaemonIsLinux) 113 cOut, _ := dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top") 114 c1 := strings.TrimSpace(cOut) 115 waitRun("foo") 116 cOut, _ = dockerCmd(c, "run", "--name=bar", "-d", "busybox", "top") 117 c2 := strings.TrimSpace(cOut) 118 waitRun("bar") 119 out, _ := dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 120 c.Assert(out, checker.Contains, c1, check.Commentf(out)) 121 c.Assert(out, checker.Not(checker.Contains), c2, check.Commentf(out)) 122 } 123 124 // #18453 125 func (s *DockerSuite) TestEventsContainerFilterBeforeCreate(c *check.C) { 126 testRequires(c, DaemonIsLinux) 127 var ( 128 out string 129 ch chan struct{} 130 ) 131 ch = make(chan struct{}) 132 133 // calculate the time it takes to create and start a container and sleep 2 seconds 134 // this is to make sure the docker event will recevie the event of container 135 since := daemonTime(c).Unix() 136 id, _ := dockerCmd(c, "run", "-d", "busybox", "top") 137 cID := strings.TrimSpace(id) 138 waitRun(cID) 139 time.Sleep(2 * time.Second) 140 duration := daemonTime(c).Unix() - since 141 142 go func() { 143 out, _ = dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()+2*duration)) 144 close(ch) 145 }() 146 // Sleep 2 second to wait docker event to start 147 time.Sleep(2 * time.Second) 148 id, _ = dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top") 149 cID = strings.TrimSpace(id) 150 waitRun(cID) 151 <-ch 152 c.Assert(out, checker.Contains, cID, check.Commentf("Missing event of container (foo)")) 153 } 154 155 func (s *DockerSuite) TestVolumeEvents(c *check.C) { 156 testRequires(c, DaemonIsLinux) 157 158 since := daemonTime(c).Unix() 159 160 // Observe create/mount volume actions 161 dockerCmd(c, "volume", "create", "--name", "test-event-volume-local") 162 dockerCmd(c, "run", "--name", "test-volume-container", "--volume", "test-event-volume-local:/foo", "-d", "busybox", "true") 163 waitRun("test-volume-container") 164 165 // Observe unmount/destroy volume actions 166 dockerCmd(c, "rm", "-f", "test-volume-container") 167 dockerCmd(c, "volume", "rm", "test-event-volume-local") 168 169 out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 170 events := strings.Split(strings.TrimSpace(out), "\n") 171 c.Assert(len(events), checker.GreaterThan, 4) 172 173 volumeEvents := eventActionsByIDAndType(c, events, "test-event-volume-local", "volume") 174 c.Assert(volumeEvents, checker.HasLen, 4) 175 c.Assert(volumeEvents[0], checker.Equals, "create") 176 c.Assert(volumeEvents[1], checker.Equals, "mount") 177 c.Assert(volumeEvents[2], checker.Equals, "unmount") 178 c.Assert(volumeEvents[3], checker.Equals, "destroy") 179 } 180 181 func (s *DockerSuite) TestNetworkEvents(c *check.C) { 182 testRequires(c, DaemonIsLinux) 183 184 since := daemonTime(c).Unix() 185 186 // Observe create/connect network actions 187 dockerCmd(c, "network", "create", "test-event-network-local") 188 dockerCmd(c, "run", "--name", "test-network-container", "--net", "test-event-network-local", "-d", "busybox", "true") 189 waitRun("test-network-container") 190 191 // Observe disconnect/destroy network actions 192 dockerCmd(c, "rm", "-f", "test-network-container") 193 dockerCmd(c, "network", "rm", "test-event-network-local") 194 195 out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 196 events := strings.Split(strings.TrimSpace(out), "\n") 197 c.Assert(len(events), checker.GreaterThan, 4) 198 199 netEvents := eventActionsByIDAndType(c, events, "test-event-network-local", "network") 200 c.Assert(netEvents, checker.HasLen, 4) 201 c.Assert(netEvents[0], checker.Equals, "create") 202 c.Assert(netEvents[1], checker.Equals, "connect") 203 c.Assert(netEvents[2], checker.Equals, "disconnect") 204 c.Assert(netEvents[3], checker.Equals, "destroy") 205 } 206 207 func (s *DockerSuite) TestEventsStreaming(c *check.C) { 208 testRequires(c, DaemonIsLinux) 209 210 observer, err := newEventObserver(c) 211 c.Assert(err, checker.IsNil) 212 err = observer.Start() 213 c.Assert(err, checker.IsNil) 214 defer observer.Stop() 215 216 out, _ := dockerCmd(c, "run", "-d", "busybox:latest", "true") 217 containerID := strings.TrimSpace(out) 218 219 testActions := map[string]chan bool{ 220 "create": make(chan bool), 221 "start": make(chan bool), 222 "die": make(chan bool), 223 "destroy": make(chan bool), 224 } 225 226 matcher := matchEventLine(containerID, "container", testActions) 227 go observer.Match(matcher) 228 229 select { 230 case <-time.After(5 * time.Second): 231 observer.CheckEventError(c, containerID, "create", matcher) 232 case <-testActions["create"]: 233 // ignore, done 234 } 235 236 select { 237 case <-time.After(5 * time.Second): 238 observer.CheckEventError(c, containerID, "start", matcher) 239 case <-testActions["start"]: 240 // ignore, done 241 } 242 243 select { 244 case <-time.After(5 * time.Second): 245 observer.CheckEventError(c, containerID, "die", matcher) 246 case <-testActions["die"]: 247 // ignore, done 248 } 249 250 dockerCmd(c, "rm", containerID) 251 252 select { 253 case <-time.After(5 * time.Second): 254 observer.CheckEventError(c, containerID, "destroy", matcher) 255 case <-testActions["destroy"]: 256 // ignore, done 257 } 258 } 259 260 func (s *DockerSuite) TestEventsImageUntagDelete(c *check.C) { 261 testRequires(c, DaemonIsLinux) 262 263 observer, err := newEventObserver(c) 264 c.Assert(err, checker.IsNil) 265 err = observer.Start() 266 c.Assert(err, checker.IsNil) 267 defer observer.Stop() 268 269 name := "testimageevents" 270 imageID, err := buildImage(name, 271 `FROM scratch 272 MAINTAINER "docker"`, 273 true) 274 c.Assert(err, checker.IsNil) 275 c.Assert(deleteImages(name), checker.IsNil) 276 277 testActions := map[string]chan bool{ 278 "untag": make(chan bool), 279 "delete": make(chan bool), 280 } 281 282 matcher := matchEventLine(imageID, "image", testActions) 283 go observer.Match(matcher) 284 285 select { 286 case <-time.After(10 * time.Second): 287 observer.CheckEventError(c, imageID, "untag", matcher) 288 case <-testActions["untag"]: 289 // ignore, done 290 } 291 292 select { 293 case <-time.After(10 * time.Second): 294 observer.CheckEventError(c, imageID, "delete", matcher) 295 case <-testActions["delete"]: 296 // ignore, done 297 } 298 } 299 300 func (s *DockerSuite) TestEventsFilterVolumeAndNetworkType(c *check.C) { 301 testRequires(c, DaemonIsLinux) 302 303 since := daemonTime(c).Unix() 304 305 dockerCmd(c, "network", "create", "test-event-network-type") 306 dockerCmd(c, "volume", "create", "--name", "test-event-volume-type") 307 308 out, _ := dockerCmd(c, "events", "--filter", "type=volume", "--filter", "type=network", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 309 events := strings.Split(strings.TrimSpace(out), "\n") 310 c.Assert(len(events), checker.GreaterOrEqualThan, 2, check.Commentf(out)) 311 312 networkActions := eventActionsByIDAndType(c, events, "test-event-network-type", "network") 313 volumeActions := eventActionsByIDAndType(c, events, "test-event-volume-type", "volume") 314 315 c.Assert(volumeActions[0], checker.Equals, "create") 316 c.Assert(networkActions[0], checker.Equals, "create") 317 } 318 319 func (s *DockerSuite) TestEventsFilterVolumeID(c *check.C) { 320 testRequires(c, DaemonIsLinux) 321 322 since := daemonTime(c).Unix() 323 324 dockerCmd(c, "volume", "create", "--name", "test-event-volume-id") 325 out, _ := dockerCmd(c, "events", "--filter", "volume=test-event-volume-id", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 326 events := strings.Split(strings.TrimSpace(out), "\n") 327 c.Assert(events, checker.HasLen, 1) 328 329 c.Assert(events[0], checker.Contains, "test-event-volume-id") 330 c.Assert(events[0], checker.Contains, "driver=local") 331 } 332 333 func (s *DockerSuite) TestEventsFilterNetworkID(c *check.C) { 334 testRequires(c, DaemonIsLinux) 335 336 since := daemonTime(c).Unix() 337 338 dockerCmd(c, "network", "create", "test-event-network-local") 339 out, _ := dockerCmd(c, "events", "--filter", "network=test-event-network-local", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 340 events := strings.Split(strings.TrimSpace(out), "\n") 341 c.Assert(events, checker.HasLen, 1) 342 343 c.Assert(events[0], checker.Contains, "test-event-network-local") 344 c.Assert(events[0], checker.Contains, "type=bridge") 345 }