github.com/ruphin/docker@v1.10.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) 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 processor := processEventMatch(testActions) 228 go observer.Match(matcher, processor) 229 230 select { 231 case <-time.After(5 * time.Second): 232 observer.CheckEventError(c, containerID, "create", matcher) 233 case <-testActions["create"]: 234 // ignore, done 235 } 236 237 select { 238 case <-time.After(5 * time.Second): 239 observer.CheckEventError(c, containerID, "start", matcher) 240 case <-testActions["start"]: 241 // ignore, done 242 } 243 244 select { 245 case <-time.After(5 * time.Second): 246 observer.CheckEventError(c, containerID, "die", matcher) 247 case <-testActions["die"]: 248 // ignore, done 249 } 250 251 dockerCmd(c, "rm", containerID) 252 253 select { 254 case <-time.After(5 * time.Second): 255 observer.CheckEventError(c, containerID, "destroy", matcher) 256 case <-testActions["destroy"]: 257 // ignore, done 258 } 259 } 260 261 func (s *DockerSuite) TestEventsImageUntagDelete(c *check.C) { 262 testRequires(c, DaemonIsLinux) 263 264 observer, err := newEventObserver(c) 265 c.Assert(err, checker.IsNil) 266 err = observer.Start() 267 c.Assert(err, checker.IsNil) 268 defer observer.Stop() 269 270 name := "testimageevents" 271 imageID, err := buildImage(name, 272 `FROM scratch 273 MAINTAINER "docker"`, 274 true) 275 c.Assert(err, checker.IsNil) 276 c.Assert(deleteImages(name), checker.IsNil) 277 278 testActions := map[string]chan bool{ 279 "untag": make(chan bool), 280 "delete": make(chan bool), 281 } 282 283 matcher := matchEventLine(imageID, "image", testActions) 284 processor := processEventMatch(testActions) 285 go observer.Match(matcher, processor) 286 287 select { 288 case <-time.After(10 * time.Second): 289 observer.CheckEventError(c, imageID, "untag", matcher) 290 case <-testActions["untag"]: 291 // ignore, done 292 } 293 294 select { 295 case <-time.After(10 * time.Second): 296 observer.CheckEventError(c, imageID, "delete", matcher) 297 case <-testActions["delete"]: 298 // ignore, done 299 } 300 } 301 302 func (s *DockerSuite) TestEventsFilterVolumeAndNetworkType(c *check.C) { 303 testRequires(c, DaemonIsLinux) 304 305 since := daemonTime(c).Unix() 306 307 dockerCmd(c, "network", "create", "test-event-network-type") 308 dockerCmd(c, "volume", "create", "--name", "test-event-volume-type") 309 310 out, _ := dockerCmd(c, "events", "--filter", "type=volume", "--filter", "type=network", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 311 events := strings.Split(strings.TrimSpace(out), "\n") 312 c.Assert(len(events), checker.GreaterOrEqualThan, 2, check.Commentf(out)) 313 314 networkActions := eventActionsByIDAndType(c, events, "test-event-network-type", "network") 315 volumeActions := eventActionsByIDAndType(c, events, "test-event-volume-type", "volume") 316 317 c.Assert(volumeActions[0], checker.Equals, "create") 318 c.Assert(networkActions[0], checker.Equals, "create") 319 } 320 321 func (s *DockerSuite) TestEventsFilterVolumeID(c *check.C) { 322 testRequires(c, DaemonIsLinux) 323 324 since := daemonTime(c).Unix() 325 326 dockerCmd(c, "volume", "create", "--name", "test-event-volume-id") 327 out, _ := dockerCmd(c, "events", "--filter", "volume=test-event-volume-id", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 328 events := strings.Split(strings.TrimSpace(out), "\n") 329 c.Assert(events, checker.HasLen, 1) 330 331 c.Assert(events[0], checker.Contains, "test-event-volume-id") 332 c.Assert(events[0], checker.Contains, "driver=local") 333 } 334 335 func (s *DockerSuite) TestEventsFilterNetworkID(c *check.C) { 336 testRequires(c, DaemonIsLinux) 337 338 since := daemonTime(c).Unix() 339 340 dockerCmd(c, "network", "create", "test-event-network-local") 341 out, _ := dockerCmd(c, "events", "--filter", "network=test-event-network-local", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix())) 342 events := strings.Split(strings.TrimSpace(out), "\n") 343 c.Assert(events, checker.HasLen, 1) 344 345 c.Assert(events[0], checker.Contains, "test-event-network-local") 346 c.Assert(events[0], checker.Contains, "type=bridge") 347 }