github.com/dinever/docker@v1.11.1/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, swapMemorySupport) 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, NotArm, swapMemorySupport) 80 81 errChan := make(chan error) 82 observer, err := newEventObserver(c) 83 c.Assert(err, checker.IsNil) 84 err = observer.Start() 85 c.Assert(err, checker.IsNil) 86 defer observer.Stop() 87 88 go func() { 89 defer close(errChan) 90 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") 91 if expected := 137; exitCode != expected { 92 errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out) 93 } 94 }() 95 96 c.Assert(waitRun("oomTrue"), checker.IsNil) 97 defer dockerCmd(c, "kill", "oomTrue") 98 containerID := inspectField(c, "oomTrue", "Id") 99 100 testActions := map[string]chan bool{ 101 "oom": make(chan bool), 102 } 103 104 matcher := matchEventLine(containerID, "container", testActions) 105 processor := processEventMatch(testActions) 106 go observer.Match(matcher, processor) 107 108 select { 109 case <-time.After(20 * time.Second): 110 observer.CheckEventError(c, containerID, "oom", matcher) 111 case <-testActions["oom"]: 112 // ignore, done 113 case errRun := <-errChan: 114 if errRun != nil { 115 c.Fatalf("%v", errRun) 116 } else { 117 c.Fatalf("container should be still running but it's not") 118 } 119 } 120 121 status := inspectField(c, "oomTrue", "State.Status") 122 c.Assert(strings.TrimSpace(status), checker.Equals, "running", check.Commentf("container should be still running")) 123 } 124 125 // #18453 126 func (s *DockerSuite) TestEventsContainerFilterByName(c *check.C) { 127 testRequires(c, DaemonIsLinux) 128 cOut, _ := dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top") 129 c1 := strings.TrimSpace(cOut) 130 waitRun("foo") 131 cOut, _ = dockerCmd(c, "run", "--name=bar", "-d", "busybox", "top") 132 c2 := strings.TrimSpace(cOut) 133 waitRun("bar") 134 out, _ := dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 135 c.Assert(out, checker.Contains, c1, check.Commentf(out)) 136 c.Assert(out, checker.Not(checker.Contains), c2, check.Commentf(out)) 137 } 138 139 // #18453 140 func (s *DockerSuite) TestEventsContainerFilterBeforeCreate(c *check.C) { 141 testRequires(c, DaemonIsLinux) 142 var ( 143 out string 144 ch chan struct{} 145 ) 146 ch = make(chan struct{}) 147 148 // calculate the time it takes to create and start a container and sleep 2 seconds 149 // this is to make sure the docker event will recevie the event of container 150 since := daemonTime(c).Unix() 151 id, _ := dockerCmd(c, "run", "-d", "busybox", "top") 152 cID := strings.TrimSpace(id) 153 waitRun(cID) 154 time.Sleep(2 * time.Second) 155 duration := daemonTime(c).Unix() - since 156 157 go func() { 158 out, _ = dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()+2*duration)) 159 close(ch) 160 }() 161 // Sleep 2 second to wait docker event to start 162 time.Sleep(2 * time.Second) 163 id, _ = dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top") 164 cID = strings.TrimSpace(id) 165 waitRun(cID) 166 <-ch 167 c.Assert(out, checker.Contains, cID, check.Commentf("Missing event of container (foo)")) 168 } 169 170 func (s *DockerSuite) TestVolumeEvents(c *check.C) { 171 testRequires(c, DaemonIsLinux) 172 173 since := daemonTime(c).Unix() 174 175 // Observe create/mount volume actions 176 dockerCmd(c, "volume", "create", "--name", "test-event-volume-local") 177 dockerCmd(c, "run", "--name", "test-volume-container", "--volume", "test-event-volume-local:/foo", "-d", "busybox", "true") 178 waitRun("test-volume-container") 179 180 // Observe unmount/destroy volume actions 181 dockerCmd(c, "rm", "-f", "test-volume-container") 182 dockerCmd(c, "volume", "rm", "test-event-volume-local") 183 184 out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 185 events := strings.Split(strings.TrimSpace(out), "\n") 186 c.Assert(len(events), checker.GreaterThan, 4) 187 188 volumeEvents := eventActionsByIDAndType(c, events, "test-event-volume-local", "volume") 189 c.Assert(volumeEvents, checker.HasLen, 4) 190 c.Assert(volumeEvents[0], checker.Equals, "create") 191 c.Assert(volumeEvents[1], checker.Equals, "mount") 192 c.Assert(volumeEvents[2], checker.Equals, "unmount") 193 c.Assert(volumeEvents[3], checker.Equals, "destroy") 194 } 195 196 func (s *DockerSuite) TestNetworkEvents(c *check.C) { 197 testRequires(c, DaemonIsLinux) 198 199 since := daemonTime(c).Unix() 200 201 // Observe create/connect network actions 202 dockerCmd(c, "network", "create", "test-event-network-local") 203 dockerCmd(c, "run", "--name", "test-network-container", "--net", "test-event-network-local", "-d", "busybox", "true") 204 waitRun("test-network-container") 205 206 // Observe disconnect/destroy network actions 207 dockerCmd(c, "rm", "-f", "test-network-container") 208 dockerCmd(c, "network", "rm", "test-event-network-local") 209 210 out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 211 events := strings.Split(strings.TrimSpace(out), "\n") 212 c.Assert(len(events), checker.GreaterThan, 4) 213 214 netEvents := eventActionsByIDAndType(c, events, "test-event-network-local", "network") 215 c.Assert(netEvents, checker.HasLen, 4) 216 c.Assert(netEvents[0], checker.Equals, "create") 217 c.Assert(netEvents[1], checker.Equals, "connect") 218 c.Assert(netEvents[2], checker.Equals, "disconnect") 219 c.Assert(netEvents[3], checker.Equals, "destroy") 220 } 221 222 func (s *DockerSuite) TestEventsStreaming(c *check.C) { 223 testRequires(c, DaemonIsLinux) 224 225 observer, err := newEventObserver(c) 226 c.Assert(err, checker.IsNil) 227 err = observer.Start() 228 c.Assert(err, checker.IsNil) 229 defer observer.Stop() 230 231 out, _ := dockerCmd(c, "run", "-d", "busybox:latest", "true") 232 containerID := strings.TrimSpace(out) 233 234 testActions := map[string]chan bool{ 235 "create": make(chan bool, 1), 236 "start": make(chan bool, 1), 237 "die": make(chan bool, 1), 238 "destroy": make(chan bool, 1), 239 } 240 241 matcher := matchEventLine(containerID, "container", testActions) 242 processor := processEventMatch(testActions) 243 go observer.Match(matcher, processor) 244 245 select { 246 case <-time.After(5 * time.Second): 247 observer.CheckEventError(c, containerID, "create", matcher) 248 case <-testActions["create"]: 249 // ignore, done 250 } 251 252 select { 253 case <-time.After(5 * time.Second): 254 observer.CheckEventError(c, containerID, "start", matcher) 255 case <-testActions["start"]: 256 // ignore, done 257 } 258 259 select { 260 case <-time.After(5 * time.Second): 261 observer.CheckEventError(c, containerID, "die", matcher) 262 case <-testActions["die"]: 263 // ignore, done 264 } 265 266 dockerCmd(c, "rm", containerID) 267 268 select { 269 case <-time.After(5 * time.Second): 270 observer.CheckEventError(c, containerID, "destroy", matcher) 271 case <-testActions["destroy"]: 272 // ignore, done 273 } 274 } 275 276 func (s *DockerSuite) TestEventsImageUntagDelete(c *check.C) { 277 testRequires(c, DaemonIsLinux) 278 279 observer, err := newEventObserver(c) 280 c.Assert(err, checker.IsNil) 281 err = observer.Start() 282 c.Assert(err, checker.IsNil) 283 defer observer.Stop() 284 285 name := "testimageevents" 286 imageID, err := buildImage(name, 287 `FROM scratch 288 MAINTAINER "docker"`, 289 true) 290 c.Assert(err, checker.IsNil) 291 c.Assert(deleteImages(name), checker.IsNil) 292 293 testActions := map[string]chan bool{ 294 "untag": make(chan bool, 1), 295 "delete": make(chan bool, 1), 296 } 297 298 matcher := matchEventLine(imageID, "image", testActions) 299 processor := processEventMatch(testActions) 300 go observer.Match(matcher, processor) 301 302 select { 303 case <-time.After(10 * time.Second): 304 observer.CheckEventError(c, imageID, "untag", matcher) 305 case <-testActions["untag"]: 306 // ignore, done 307 } 308 309 select { 310 case <-time.After(10 * time.Second): 311 observer.CheckEventError(c, imageID, "delete", matcher) 312 case <-testActions["delete"]: 313 // ignore, done 314 } 315 } 316 317 func (s *DockerSuite) TestEventsFilterVolumeAndNetworkType(c *check.C) { 318 testRequires(c, DaemonIsLinux) 319 320 since := daemonTime(c).Unix() 321 322 dockerCmd(c, "network", "create", "test-event-network-type") 323 dockerCmd(c, "volume", "create", "--name", "test-event-volume-type") 324 325 out, _ := dockerCmd(c, "events", "--filter", "type=volume", "--filter", "type=network", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 326 events := strings.Split(strings.TrimSpace(out), "\n") 327 c.Assert(len(events), checker.GreaterOrEqualThan, 2, check.Commentf(out)) 328 329 networkActions := eventActionsByIDAndType(c, events, "test-event-network-type", "network") 330 volumeActions := eventActionsByIDAndType(c, events, "test-event-volume-type", "volume") 331 332 c.Assert(volumeActions[0], checker.Equals, "create") 333 c.Assert(networkActions[0], checker.Equals, "create") 334 } 335 336 func (s *DockerSuite) TestEventsFilterVolumeID(c *check.C) { 337 testRequires(c, DaemonIsLinux) 338 339 since := daemonTime(c).Unix() 340 341 dockerCmd(c, "volume", "create", "--name", "test-event-volume-id") 342 out, _ := dockerCmd(c, "events", "--filter", "volume=test-event-volume-id", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 343 events := strings.Split(strings.TrimSpace(out), "\n") 344 c.Assert(events, checker.HasLen, 1) 345 346 c.Assert(events[0], checker.Contains, "test-event-volume-id") 347 c.Assert(events[0], checker.Contains, "driver=local") 348 } 349 350 func (s *DockerSuite) TestEventsFilterNetworkID(c *check.C) { 351 testRequires(c, DaemonIsLinux) 352 353 since := daemonTime(c).Unix() 354 355 dockerCmd(c, "network", "create", "test-event-network-local") 356 out, _ := dockerCmd(c, "events", "--filter", "network=test-event-network-local", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 357 events := strings.Split(strings.TrimSpace(out), "\n") 358 c.Assert(events, checker.HasLen, 1) 359 360 c.Assert(events[0], checker.Contains, "test-event-network-local") 361 c.Assert(events[0], checker.Contains, "type=bridge") 362 }