docker_cli_events_test.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. package main
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "os"
  9. "os/exec"
  10. "regexp"
  11. "strconv"
  12. "strings"
  13. "sync"
  14. "time"
  15. "github.com/docker/docker/pkg/integration/checker"
  16. "github.com/go-check/check"
  17. )
  18. func (s *DockerSuite) TestEventsTimestampFormats(c *check.C) {
  19. testRequires(c, DaemonIsLinux)
  20. image := "busybox"
  21. // Start stopwatch, generate an event
  22. time.Sleep(1 * time.Second) // so that we don't grab events from previous test occured in the same second
  23. start := daemonTime(c)
  24. dockerCmd(c, "tag", image, "timestamptest:1")
  25. dockerCmd(c, "rmi", "timestamptest:1")
  26. time.Sleep(1 * time.Second) // so that until > since
  27. end := daemonTime(c)
  28. // List of available time formats to --since
  29. unixTs := func(t time.Time) string { return fmt.Sprintf("%v", t.Unix()) }
  30. rfc3339 := func(t time.Time) string { return t.Format(time.RFC3339) }
  31. duration := func(t time.Time) string { return time.Now().Sub(t).String() }
  32. // --since=$start must contain only the 'untag' event
  33. for _, f := range []func(time.Time) string{unixTs, rfc3339, duration} {
  34. since, until := f(start), f(end)
  35. out, _ := dockerCmd(c, "events", "--since="+since, "--until="+until)
  36. events := strings.Split(strings.TrimSpace(out), "\n")
  37. c.Assert(events, checker.HasLen, 2, check.Commentf("unexpected events, was expecting only 2 events tag/untag (since=%s, until=%s) out=%s", since, until, out))
  38. c.Assert(out, checker.Contains, "untag", check.Commentf("expected 'untag' event not found (since=%s, until=%s)", since, until))
  39. }
  40. }
  41. func (s *DockerSuite) TestEventsUntag(c *check.C) {
  42. testRequires(c, DaemonIsLinux)
  43. image := "busybox"
  44. dockerCmd(c, "tag", image, "utest:tag1")
  45. dockerCmd(c, "tag", image, "utest:tag2")
  46. dockerCmd(c, "rmi", "utest:tag1")
  47. dockerCmd(c, "rmi", "utest:tag2")
  48. eventsCmd := exec.Command(dockerBinary, "events", "--since=1")
  49. out, exitCode, _, err := runCommandWithOutputForDuration(eventsCmd, time.Duration(time.Millisecond*2500))
  50. c.Assert(err, checker.IsNil)
  51. c.Assert(exitCode, checker.Equals, 0, check.Commentf("Failed to get events"))
  52. events := strings.Split(out, "\n")
  53. nEvents := len(events)
  54. // The last element after the split above will be an empty string, so we
  55. // get the two elements before the last, which are the untags we're
  56. // looking for.
  57. for _, v := range events[nEvents-3 : nEvents-1] {
  58. c.Assert(v, checker.Contains, "untag", check.Commentf("event should be untag"))
  59. }
  60. }
  61. func (s *DockerSuite) TestEventsContainerFailStartDie(c *check.C) {
  62. out, _ := dockerCmd(c, "images", "-q")
  63. image := strings.Split(out, "\n")[0]
  64. _, _, err := dockerCmdWithError("run", "--name", "testeventdie", image, "blerg")
  65. c.Assert(err, checker.NotNil, check.Commentf("Container run with command blerg should have failed, but it did not, out=%s", out))
  66. out, _ = dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  67. events := strings.Split(out, "\n")
  68. c.Assert(len(events), checker.GreaterThan, 1) //Missing expected event
  69. startEvent := strings.Fields(events[len(events)-3])
  70. dieEvent := strings.Fields(events[len(events)-2])
  71. c.Assert(startEvent[len(startEvent)-1], checker.Equals, "start", check.Commentf("event should be start, not %#v", startEvent))
  72. c.Assert(dieEvent[len(dieEvent)-1], checker.Equals, "die", check.Commentf("event should be die, not %#v", dieEvent))
  73. }
  74. func (s *DockerSuite) TestEventsLimit(c *check.C) {
  75. testRequires(c, DaemonIsLinux)
  76. var waitGroup sync.WaitGroup
  77. errChan := make(chan error, 17)
  78. args := []string{"run", "--rm", "busybox", "true"}
  79. for i := 0; i < 17; i++ {
  80. waitGroup.Add(1)
  81. go func() {
  82. defer waitGroup.Done()
  83. errChan <- exec.Command(dockerBinary, args...).Run()
  84. }()
  85. }
  86. waitGroup.Wait()
  87. close(errChan)
  88. for err := range errChan {
  89. c.Assert(err, checker.IsNil, check.Commentf("%q failed with error", strings.Join(args, " ")))
  90. }
  91. out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  92. events := strings.Split(out, "\n")
  93. nEvents := len(events) - 1
  94. c.Assert(nEvents, checker.Equals, 64, check.Commentf("events should be limited to 64, but received %d", nEvents))
  95. }
  96. func (s *DockerSuite) TestEventsContainerEvents(c *check.C) {
  97. testRequires(c, DaemonIsLinux)
  98. dockerCmd(c, "run", "--rm", "busybox", "true")
  99. out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  100. events := strings.Split(out, "\n")
  101. events = events[:len(events)-1]
  102. c.Assert(len(events), checker.GreaterOrEqualThan, 5) //Missing expected event
  103. createEvent := strings.Fields(events[len(events)-5])
  104. attachEvent := strings.Fields(events[len(events)-4])
  105. startEvent := strings.Fields(events[len(events)-3])
  106. dieEvent := strings.Fields(events[len(events)-2])
  107. destroyEvent := strings.Fields(events[len(events)-1])
  108. c.Assert(createEvent[len(createEvent)-1], checker.Equals, "create", check.Commentf("event should be create, not %#v", createEvent))
  109. c.Assert(attachEvent[len(attachEvent)-1], checker.Equals, "attach", check.Commentf("event should be attach, not %#v", attachEvent))
  110. c.Assert(startEvent[len(startEvent)-1], checker.Equals, "start", check.Commentf("event should be start, not %#v", startEvent))
  111. c.Assert(dieEvent[len(dieEvent)-1], checker.Equals, "die", check.Commentf("event should be die, not %#v", dieEvent))
  112. c.Assert(destroyEvent[len(destroyEvent)-1], checker.Equals, "destroy", check.Commentf("event should be destroy, not %#v", destroyEvent))
  113. }
  114. func (s *DockerSuite) TestEventsContainerEventsSinceUnixEpoch(c *check.C) {
  115. testRequires(c, DaemonIsLinux)
  116. dockerCmd(c, "run", "--rm", "busybox", "true")
  117. timeBeginning := time.Unix(0, 0).Format(time.RFC3339Nano)
  118. timeBeginning = strings.Replace(timeBeginning, "Z", ".000000000Z", -1)
  119. out, _ := dockerCmd(c, "events", fmt.Sprintf("--since='%s'", timeBeginning),
  120. fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  121. events := strings.Split(out, "\n")
  122. events = events[:len(events)-1]
  123. c.Assert(len(events), checker.GreaterOrEqualThan, 5) //Missing expected event
  124. createEvent := strings.Fields(events[len(events)-5])
  125. attachEvent := strings.Fields(events[len(events)-4])
  126. startEvent := strings.Fields(events[len(events)-3])
  127. dieEvent := strings.Fields(events[len(events)-2])
  128. destroyEvent := strings.Fields(events[len(events)-1])
  129. c.Assert(createEvent[len(createEvent)-1], checker.Equals, "create", check.Commentf("event should be create, not %#v", createEvent))
  130. c.Assert(attachEvent[len(attachEvent)-1], checker.Equals, "attach", check.Commentf("event should be attach, not %#v", attachEvent))
  131. c.Assert(startEvent[len(startEvent)-1], checker.Equals, "start", check.Commentf("event should be start, not %#v", startEvent))
  132. c.Assert(dieEvent[len(dieEvent)-1], checker.Equals, "die", check.Commentf("event should be die, not %#v", dieEvent))
  133. c.Assert(destroyEvent[len(destroyEvent)-1], checker.Equals, "destroy", check.Commentf("event should be destroy, not %#v", destroyEvent))
  134. }
  135. func (s *DockerSuite) TestEventsImageUntagDelete(c *check.C) {
  136. testRequires(c, DaemonIsLinux)
  137. name := "testimageevents"
  138. _, err := buildImage(name,
  139. `FROM scratch
  140. MAINTAINER "docker"`,
  141. true)
  142. c.Assert(err, checker.IsNil)
  143. c.Assert(deleteImages(name), checker.IsNil)
  144. out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  145. events := strings.Split(out, "\n")
  146. events = events[:len(events)-1]
  147. c.Assert(len(events), checker.GreaterOrEqualThan, 2) //Missing expected event
  148. untagEvent := strings.Fields(events[len(events)-2])
  149. deleteEvent := strings.Fields(events[len(events)-1])
  150. c.Assert(untagEvent[len(untagEvent)-1], checker.Equals, "untag", check.Commentf("untag should be untag, not %#v", untagEvent))
  151. c.Assert(deleteEvent[len(deleteEvent)-1], checker.Equals, "delete", check.Commentf("untag should be delete, not %#v", untagEvent))
  152. }
  153. func (s *DockerSuite) TestEventsImageTag(c *check.C) {
  154. testRequires(c, DaemonIsLinux)
  155. time.Sleep(1 * time.Second) // because API has seconds granularity
  156. since := daemonTime(c).Unix()
  157. image := "testimageevents:tag"
  158. dockerCmd(c, "tag", "busybox", image)
  159. out, _ := dockerCmd(c, "events",
  160. fmt.Sprintf("--since=%d", since),
  161. fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  162. events := strings.Split(strings.TrimSpace(out), "\n")
  163. c.Assert(events, checker.HasLen, 1, check.Commentf("was expecting 1 event. out=%s", out))
  164. event := strings.TrimSpace(events[0])
  165. expectedStr := image + ": tag"
  166. c.Assert(event, checker.HasSuffix, expectedStr, check.Commentf("wrong event format. expected='%s' got=%s", expectedStr, event))
  167. }
  168. func (s *DockerSuite) TestEventsImagePull(c *check.C) {
  169. testRequires(c, DaemonIsLinux)
  170. since := daemonTime(c).Unix()
  171. testRequires(c, Network)
  172. dockerCmd(c, "pull", "hello-world")
  173. out, _ := dockerCmd(c, "events",
  174. fmt.Sprintf("--since=%d", since),
  175. fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  176. events := strings.Split(strings.TrimSpace(out), "\n")
  177. event := strings.TrimSpace(events[len(events)-1])
  178. c.Assert(event, checker.HasSuffix, "hello-world:latest: pull", check.Commentf("Missing pull event - got:%q", event))
  179. }
  180. func (s *DockerSuite) TestEventsImageImport(c *check.C) {
  181. testRequires(c, DaemonIsLinux)
  182. since := daemonTime(c).Unix()
  183. id := make(chan string)
  184. eventImport := make(chan struct{})
  185. eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(since, 10))
  186. stdout, err := eventsCmd.StdoutPipe()
  187. c.Assert(err, checker.IsNil)
  188. c.Assert(eventsCmd.Start(), checker.IsNil)
  189. defer eventsCmd.Process.Kill()
  190. go func() {
  191. containerID := <-id
  192. matchImport := regexp.MustCompile(containerID + `: import$`)
  193. scanner := bufio.NewScanner(stdout)
  194. for scanner.Scan() {
  195. if matchImport.MatchString(scanner.Text()) {
  196. close(eventImport)
  197. }
  198. }
  199. }()
  200. out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
  201. cleanedContainerID := strings.TrimSpace(out)
  202. out, _, err = runCommandPipelineWithOutput(
  203. exec.Command(dockerBinary, "export", cleanedContainerID),
  204. exec.Command(dockerBinary, "import", "-"),
  205. )
  206. c.Assert(err, checker.IsNil, check.Commentf("import failed with output: %q", out))
  207. newContainerID := strings.TrimSpace(out)
  208. id <- newContainerID
  209. select {
  210. case <-time.After(5 * time.Second):
  211. c.Fatal("failed to observe image import in timely fashion")
  212. case <-eventImport:
  213. // ignore, done
  214. }
  215. }
  216. func (s *DockerSuite) TestEventsFilters(c *check.C) {
  217. testRequires(c, DaemonIsLinux)
  218. parseEvents := func(out, match string) {
  219. events := strings.Split(out, "\n")
  220. events = events[:len(events)-1]
  221. for _, event := range events {
  222. eventFields := strings.Fields(event)
  223. eventName := eventFields[len(eventFields)-1]
  224. c.Assert(eventName, checker.Matches, match)
  225. }
  226. }
  227. since := daemonTime(c).Unix()
  228. dockerCmd(c, "run", "--rm", "busybox", "true")
  229. dockerCmd(c, "run", "--rm", "busybox", "true")
  230. out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "event=die")
  231. parseEvents(out, "die")
  232. out, _ = dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "event=die", "--filter", "event=start")
  233. parseEvents(out, "((die)|(start))")
  234. // make sure we at least got 2 start events
  235. count := strings.Count(out, "start")
  236. c.Assert(strings.Count(out, "start"), checker.GreaterOrEqualThan, 2, check.Commentf("should have had 2 start events but had %d, out: %s", count, out))
  237. }
  238. func (s *DockerSuite) TestEventsFilterImageName(c *check.C) {
  239. testRequires(c, DaemonIsLinux)
  240. since := daemonTime(c).Unix()
  241. out, _ := dockerCmd(c, "run", "--name", "container_1", "-d", "busybox:latest", "true")
  242. container1 := strings.TrimSpace(out)
  243. out, _ = dockerCmd(c, "run", "--name", "container_2", "-d", "busybox", "true")
  244. container2 := strings.TrimSpace(out)
  245. name := "busybox"
  246. out, _ = dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", fmt.Sprintf("image=%s", name))
  247. events := strings.Split(out, "\n")
  248. events = events[:len(events)-1]
  249. c.Assert(events, checker.Not(checker.HasLen), 0) //Expected events but found none for the image busybox:latest
  250. count1 := 0
  251. count2 := 0
  252. for _, e := range events {
  253. if strings.Contains(e, container1) {
  254. count1++
  255. } else if strings.Contains(e, container2) {
  256. count2++
  257. }
  258. }
  259. c.Assert(count1, checker.Not(checker.Equals), 0, check.Commentf("Expected event from container but got %d from %s", count1, container1))
  260. c.Assert(count2, checker.Not(checker.Equals), 0, check.Commentf("Expected event from container but got %d from %s", count2, container2))
  261. }
  262. func (s *DockerSuite) TestEventsFilterLabels(c *check.C) {
  263. testRequires(c, DaemonIsLinux)
  264. since := daemonTime(c).Unix()
  265. label := "io.docker.testing=foo"
  266. out, _ := dockerCmd(c, "run", "-d", "-l", label, "busybox:latest", "true")
  267. container1 := strings.TrimSpace(out)
  268. out, _ = dockerCmd(c, "run", "-d", "busybox", "true")
  269. container2 := strings.TrimSpace(out)
  270. out, _ = dockerCmd(
  271. c,
  272. "events",
  273. fmt.Sprintf("--since=%d", since),
  274. fmt.Sprintf("--until=%d", daemonTime(c).Unix()),
  275. "--filter", fmt.Sprintf("label=%s", label))
  276. events := strings.Split(strings.TrimSpace(out), "\n")
  277. c.Assert(len(events), checker.Equals, 3)
  278. for _, e := range events {
  279. c.Assert(e, checker.Contains, container1)
  280. c.Assert(e, checker.Not(checker.Contains), container2)
  281. }
  282. }
  283. func (s *DockerSuite) TestEventsFilterImageLabels(c *check.C) {
  284. testRequires(c, DaemonIsLinux)
  285. since := daemonTime(c).Unix()
  286. name := "labelfiltertest"
  287. label := "io.docker.testing=image"
  288. // Build a test image.
  289. _, err := buildImage(name, fmt.Sprintf(`
  290. FROM busybox:latest
  291. LABEL %s`, label), true)
  292. c.Assert(err, checker.IsNil, check.Commentf("Couldn't create image"))
  293. dockerCmd(c, "tag", name, "labelfiltertest:tag1")
  294. dockerCmd(c, "tag", name, "labelfiltertest:tag2")
  295. dockerCmd(c, "tag", "busybox:latest", "labelfiltertest:tag3")
  296. out, _ := dockerCmd(
  297. c,
  298. "events",
  299. fmt.Sprintf("--since=%d", since),
  300. fmt.Sprintf("--until=%d", daemonTime(c).Unix()),
  301. "--filter", fmt.Sprintf("label=%s", label))
  302. events := strings.Split(strings.TrimSpace(out), "\n")
  303. // 2 events from the "docker tag" command, another one is from "docker build"
  304. c.Assert(events, checker.HasLen, 3, check.Commentf("Events == %s", events))
  305. for _, e := range events {
  306. c.Assert(e, checker.Contains, "labelfiltertest")
  307. }
  308. }
  309. func (s *DockerSuite) TestEventsFilterContainer(c *check.C) {
  310. testRequires(c, DaemonIsLinux)
  311. since := fmt.Sprintf("%d", daemonTime(c).Unix())
  312. nameID := make(map[string]string)
  313. for _, name := range []string{"container_1", "container_2"} {
  314. dockerCmd(c, "run", "--name", name, "busybox", "true")
  315. id, err := inspectField(name, "Id")
  316. c.Assert(err, checker.IsNil)
  317. nameID[name] = id
  318. }
  319. until := fmt.Sprintf("%d", daemonTime(c).Unix())
  320. checkEvents := func(id string, events []string) error {
  321. if len(events) != 4 { // create, attach, start, die
  322. return fmt.Errorf("expected 4 events, got %v", events)
  323. }
  324. for _, event := range events {
  325. e := strings.Fields(event)
  326. if len(e) < 3 {
  327. return fmt.Errorf("got malformed event: %s", event)
  328. }
  329. // Check the id
  330. parsedID := strings.TrimSuffix(e[1], ":")
  331. if parsedID != id {
  332. return fmt.Errorf("expected event for container id %s: %s - parsed container id: %s", id, event, parsedID)
  333. }
  334. }
  335. return nil
  336. }
  337. for name, ID := range nameID {
  338. // filter by names
  339. out, _ := dockerCmd(c, "events", "--since", since, "--until", until, "--filter", "container="+name)
  340. events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
  341. c.Assert(checkEvents(ID, events), checker.IsNil)
  342. // filter by ID's
  343. out, _ = dockerCmd(c, "events", "--since", since, "--until", until, "--filter", "container="+ID)
  344. events = strings.Split(strings.TrimSuffix(out, "\n"), "\n")
  345. c.Assert(checkEvents(ID, events), checker.IsNil)
  346. }
  347. }
  348. func (s *DockerSuite) TestEventsStreaming(c *check.C) {
  349. testRequires(c, DaemonIsLinux)
  350. start := daemonTime(c).Unix()
  351. id := make(chan string)
  352. eventCreate := make(chan struct{})
  353. eventStart := make(chan struct{})
  354. eventDie := make(chan struct{})
  355. eventDestroy := make(chan struct{})
  356. eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10))
  357. stdout, err := eventsCmd.StdoutPipe()
  358. c.Assert(err, checker.IsNil)
  359. c.Assert(eventsCmd.Start(), checker.IsNil, check.Commentf("failed to start 'docker events'"))
  360. defer eventsCmd.Process.Kill()
  361. buffer := new(bytes.Buffer)
  362. go func() {
  363. containerID := <-id
  364. matchCreate := regexp.MustCompile(containerID + `: \(from busybox:latest\) create\z`)
  365. matchStart := regexp.MustCompile(containerID + `: \(from busybox:latest\) start\z`)
  366. matchDie := regexp.MustCompile(containerID + `: \(from busybox:latest\) die\z`)
  367. matchDestroy := regexp.MustCompile(containerID + `: \(from busybox:latest\) destroy\z`)
  368. scanner := bufio.NewScanner(stdout)
  369. for scanner.Scan() {
  370. text := scanner.Text()
  371. buffer.WriteString(text + "\n")
  372. switch {
  373. case matchCreate.MatchString(text):
  374. close(eventCreate)
  375. case matchStart.MatchString(text):
  376. close(eventStart)
  377. case matchDie.MatchString(text):
  378. close(eventDie)
  379. case matchDestroy.MatchString(text):
  380. close(eventDestroy)
  381. }
  382. }
  383. }()
  384. out, _ := dockerCmd(c, "run", "-d", "busybox:latest", "true")
  385. cleanedContainerID := strings.TrimSpace(out)
  386. id <- cleanedContainerID
  387. select {
  388. case <-time.After(5 * time.Second):
  389. c.Fatal("failed to observe container create in timely fashion", "\n", buffer.String())
  390. case <-eventCreate:
  391. // ignore, done
  392. }
  393. select {
  394. case <-time.After(5 * time.Second):
  395. c.Fatal("failed to observe container start in timely fashion", "\n", buffer.String())
  396. case <-eventStart:
  397. // ignore, done
  398. }
  399. select {
  400. case <-time.After(5 * time.Second):
  401. c.Fatal("failed to observe container die in timely fashion", "\n", buffer.String())
  402. case <-eventDie:
  403. // ignore, done
  404. }
  405. dockerCmd(c, "rm", cleanedContainerID)
  406. select {
  407. case <-time.After(5 * time.Second):
  408. c.Fatal("failed to observe container destroy in timely fashion", "\n", buffer.String())
  409. case <-eventDestroy:
  410. // ignore, done
  411. }
  412. }
  413. func (s *DockerSuite) TestEventsCommit(c *check.C) {
  414. testRequires(c, DaemonIsLinux)
  415. since := daemonTime(c).Unix()
  416. out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
  417. cID := strings.TrimSpace(out)
  418. c.Assert(waitRun(cID), checker.IsNil)
  419. dockerCmd(c, "commit", "-m", "test", cID)
  420. dockerCmd(c, "stop", cID)
  421. out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
  422. c.Assert(out, checker.Contains, " commit\n", check.Commentf("Missing 'commit' log event"))
  423. }
  424. func (s *DockerSuite) TestEventsCopy(c *check.C) {
  425. testRequires(c, DaemonIsLinux)
  426. since := daemonTime(c).Unix()
  427. // Build a test image.
  428. id, err := buildImage("cpimg", `
  429. FROM busybox
  430. RUN echo HI > /tmp/file`, true)
  431. c.Assert(err, checker.IsNil, check.Commentf("Couldn't create image"))
  432. // Create an empty test file.
  433. tempFile, err := ioutil.TempFile("", "test-events-copy-")
  434. c.Assert(err, checker.IsNil)
  435. defer os.Remove(tempFile.Name())
  436. c.Assert(tempFile.Close(), checker.IsNil)
  437. dockerCmd(c, "create", "--name=cptest", id)
  438. dockerCmd(c, "cp", "cptest:/tmp/file", tempFile.Name())
  439. out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=cptest", "--until="+strconv.Itoa(int(since)))
  440. c.Assert(out, checker.Contains, " archive-path\n", check.Commentf("Missing 'archive-path' log event\n"))
  441. dockerCmd(c, "cp", tempFile.Name(), "cptest:/tmp/filecopy")
  442. out, _ = dockerCmd(c, "events", "--since=0", "-f", "container=cptest", "--until="+strconv.Itoa(int(since)))
  443. c.Assert(out, checker.Contains, " extract-to-dir\n", check.Commentf("Missing 'extract-to-dir' log event"))
  444. }
  445. func (s *DockerSuite) TestEventsResize(c *check.C) {
  446. testRequires(c, DaemonIsLinux)
  447. since := daemonTime(c).Unix()
  448. out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
  449. cID := strings.TrimSpace(out)
  450. c.Assert(waitRun(cID), checker.IsNil)
  451. endpoint := "/containers/" + cID + "/resize?h=80&w=24"
  452. status, _, err := sockRequest("POST", endpoint, nil)
  453. c.Assert(status, checker.Equals, http.StatusOK)
  454. c.Assert(err, checker.IsNil)
  455. dockerCmd(c, "stop", cID)
  456. out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
  457. c.Assert(out, checker.Contains, " resize\n", check.Commentf("Missing 'resize' log event"))
  458. }
  459. func (s *DockerSuite) TestEventsAttach(c *check.C) {
  460. testRequires(c, DaemonIsLinux)
  461. since := daemonTime(c).Unix()
  462. out, _ := dockerCmd(c, "run", "-di", "busybox", "/bin/cat")
  463. cID := strings.TrimSpace(out)
  464. cmd := exec.Command(dockerBinary, "attach", cID)
  465. stdin, err := cmd.StdinPipe()
  466. c.Assert(err, checker.IsNil)
  467. defer stdin.Close()
  468. stdout, err := cmd.StdoutPipe()
  469. c.Assert(err, checker.IsNil)
  470. defer stdout.Close()
  471. c.Assert(cmd.Start(), checker.IsNil)
  472. defer cmd.Process.Kill()
  473. // Make sure we're done attaching by writing/reading some stuff
  474. _, err = stdin.Write([]byte("hello\n"))
  475. c.Assert(err, checker.IsNil)
  476. out, err = bufio.NewReader(stdout).ReadString('\n')
  477. c.Assert(err, checker.IsNil)
  478. c.Assert(strings.TrimSpace(out), checker.Equals, "hello", check.Commentf("expected 'hello'"))
  479. c.Assert(stdin.Close(), checker.IsNil)
  480. dockerCmd(c, "stop", cID)
  481. out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
  482. c.Assert(out, checker.Contains, " attach\n", check.Commentf("Missing 'attach' log event"))
  483. }
  484. func (s *DockerSuite) TestEventsRename(c *check.C) {
  485. testRequires(c, DaemonIsLinux)
  486. since := daemonTime(c).Unix()
  487. dockerCmd(c, "run", "--name", "oldName", "busybox", "true")
  488. dockerCmd(c, "rename", "oldName", "newName")
  489. out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=newName", "--until="+strconv.Itoa(int(since)))
  490. c.Assert(out, checker.Contains, " rename\n", check.Commentf("Missing 'rename' log event\n"))
  491. }
  492. func (s *DockerSuite) TestEventsTop(c *check.C) {
  493. testRequires(c, DaemonIsLinux)
  494. since := daemonTime(c).Unix()
  495. out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
  496. cID := strings.TrimSpace(out)
  497. c.Assert(waitRun(cID), checker.IsNil)
  498. dockerCmd(c, "top", cID)
  499. dockerCmd(c, "stop", cID)
  500. out, _ = dockerCmd(c, "events", "--since=0", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
  501. c.Assert(out, checker.Contains, " top\n", check.Commentf("Missing 'top' log event"))
  502. }
  503. // #13753
  504. func (s *DockerSuite) TestEventsDefaultEmpty(c *check.C) {
  505. testRequires(c, DaemonIsLinux)
  506. dockerCmd(c, "run", "busybox")
  507. out, _ := dockerCmd(c, "events", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
  508. c.Assert(strings.TrimSpace(out), checker.Equals, "")
  509. }
  510. // #14316
  511. func (s *DockerRegistrySuite) TestEventsImageFilterPush(c *check.C) {
  512. testRequires(c, DaemonIsLinux)
  513. testRequires(c, Network)
  514. since := daemonTime(c).Unix()
  515. repoName := fmt.Sprintf("%v/dockercli/testf", privateRegistryURL)
  516. out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
  517. cID := strings.TrimSpace(out)
  518. c.Assert(waitRun(cID), checker.IsNil)
  519. dockerCmd(c, "commit", cID, repoName)
  520. dockerCmd(c, "stop", cID)
  521. dockerCmd(c, "push", repoName)
  522. out, _ = dockerCmd(c, "events", "--since=0", "-f", "image="+repoName, "-f", "event=push", "--until="+strconv.Itoa(int(since)))
  523. c.Assert(out, checker.Contains, repoName+": push\n", check.Commentf("Missing 'push' log event"))
  524. }