events_test.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package events
  2. import (
  3. "strconv"
  4. "testing"
  5. "time"
  6. "github.com/docker/docker/api/types/events"
  7. timetypes "github.com/docker/docker/api/types/time"
  8. eventstestutils "github.com/docker/docker/daemon/events/testutils"
  9. "gotest.tools/v3/assert"
  10. is "gotest.tools/v3/assert/cmp"
  11. )
  12. // validateLegacyFields validates that the legacy "Status", "ID", and "From"
  13. // fields are set to the same value as their "current" (non-legacy) fields.
  14. //
  15. // These fields were deprecated since v1.10 (https://github.com/moby/moby/pull/18888).
  16. //
  17. // TODO remove this once we removed the deprecated `ID`, `Status`, and `From` fields.
  18. func validateLegacyFields(t *testing.T, msg events.Message) {
  19. t.Helper()
  20. assert.Check(t, is.Equal(msg.Status, string(msg.Action)), "Legacy Status field does not match Action")
  21. assert.Check(t, is.Equal(msg.ID, msg.Actor.ID), "Legacy ID field does not match Actor.ID")
  22. assert.Check(t, is.Equal(msg.From, msg.Actor.Attributes["image"]), "Legacy From field does not match Actor.Attributes.image")
  23. }
  24. func TestEventsLog(t *testing.T) {
  25. e := New()
  26. _, l1, _ := e.Subscribe()
  27. _, l2, _ := e.Subscribe()
  28. defer e.Evict(l1)
  29. defer e.Evict(l2)
  30. subscriberCount := e.SubscribersCount()
  31. assert.Check(t, is.Equal(subscriberCount, 2))
  32. e.Log("test", events.ContainerEventType, events.Actor{
  33. ID: "cont",
  34. Attributes: map[string]string{"image": "image"},
  35. })
  36. select {
  37. case msg := <-l1:
  38. assert.Check(t, is.Len(e.events, 1))
  39. jmsg, ok := msg.(events.Message)
  40. assert.Assert(t, ok, "unexpected type: %T", msg)
  41. validateLegacyFields(t, jmsg)
  42. assert.Check(t, is.Equal(jmsg.Action, events.Action("test")))
  43. assert.Check(t, is.Equal(jmsg.Actor.ID, "cont"))
  44. assert.Check(t, is.Equal(jmsg.Actor.Attributes["image"], "image"))
  45. case <-time.After(1 * time.Second):
  46. t.Fatal("Timeout waiting for broadcasted message")
  47. }
  48. select {
  49. case msg := <-l2:
  50. assert.Check(t, is.Len(e.events, 1))
  51. jmsg, ok := msg.(events.Message)
  52. assert.Assert(t, ok, "unexpected type: %T", msg)
  53. validateLegacyFields(t, jmsg)
  54. assert.Check(t, is.Equal(jmsg.Action, events.Action("test")))
  55. assert.Check(t, is.Equal(jmsg.Actor.ID, "cont"))
  56. assert.Check(t, is.Equal(jmsg.Actor.Attributes["image"], "image"))
  57. case <-time.After(1 * time.Second):
  58. t.Fatal("Timeout waiting for broadcasted message")
  59. }
  60. }
  61. func TestEventsLogTimeout(t *testing.T) {
  62. e := New()
  63. _, l, _ := e.Subscribe()
  64. defer e.Evict(l)
  65. c := make(chan struct{})
  66. go func() {
  67. e.Log("test", events.ImageEventType, events.Actor{
  68. ID: "image",
  69. })
  70. close(c)
  71. }()
  72. select {
  73. case <-c:
  74. case <-time.After(time.Second):
  75. t.Fatal("Timeout publishing message")
  76. }
  77. }
  78. func TestLogEvents(t *testing.T) {
  79. e := New()
  80. for i := 0; i < eventsLimit+16; i++ {
  81. num := strconv.Itoa(i)
  82. e.Log(events.Action("action_"+num), events.ContainerEventType, events.Actor{
  83. ID: "cont_" + num,
  84. Attributes: map[string]string{"image": "image_" + num},
  85. })
  86. }
  87. time.Sleep(50 * time.Millisecond)
  88. current, l, _ := e.Subscribe()
  89. for i := 0; i < 10; i++ {
  90. num := strconv.Itoa(i + eventsLimit + 16)
  91. e.Log(events.Action("action_"+num), events.ContainerEventType, events.Actor{
  92. ID: "cont_" + num,
  93. Attributes: map[string]string{"image": "image_" + num},
  94. })
  95. }
  96. assert.Assert(t, is.Len(e.events, eventsLimit))
  97. var msgs []events.Message
  98. for len(msgs) < 10 {
  99. m := <-l
  100. jm, ok := (m).(events.Message)
  101. if !ok {
  102. t.Fatalf("Unexpected type %T", m)
  103. }
  104. msgs = append(msgs, jm)
  105. }
  106. assert.Assert(t, is.Len(current, eventsLimit))
  107. first := current[0]
  108. validateLegacyFields(t, first)
  109. assert.Check(t, is.Equal(first.Action, events.Action("action_16")))
  110. last := current[len(current)-1]
  111. assert.Check(t, is.Equal(last.Action, events.Action("action_271")))
  112. firstC := msgs[0]
  113. assert.Check(t, is.Equal(firstC.Action, events.Action("action_272")))
  114. lastC := msgs[len(msgs)-1]
  115. assert.Check(t, is.Equal(lastC.Action, events.Action("action_281")))
  116. }
  117. // Regression-test for https://github.com/moby/moby/issues/20999
  118. //
  119. // Fixtures:
  120. //
  121. // 2016-03-07T17:28:03.022433271+02:00 container die 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)
  122. // 2016-03-07T17:28:03.091719377+02:00 network disconnect 19c5ed41acb798f26b751e0035cd7821741ab79e2bbd59a66b5fd8abf954eaa0 (type=bridge, container=0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079, name=bridge)
  123. // 2016-03-07T17:28:03.129014751+02:00 container destroy 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)
  124. func TestLoadBufferedEvents(t *testing.T) {
  125. now := time.Now()
  126. f, err := timetypes.GetTimestamp("2016-03-07T17:28:03.100000000+02:00", now)
  127. assert.NilError(t, err)
  128. s, sNano, err := timetypes.ParseTimestamps(f, -1)
  129. assert.NilError(t, err)
  130. m1, err := eventstestutils.Scan("2016-03-07T17:28:03.022433271+02:00 container die 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)")
  131. assert.NilError(t, err)
  132. m2, err := eventstestutils.Scan("2016-03-07T17:28:03.091719377+02:00 network disconnect 19c5ed41acb798f26b751e0035cd7821741ab79e2bbd59a66b5fd8abf954eaa0 (type=bridge, container=0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079, name=bridge)")
  133. assert.NilError(t, err)
  134. m3, err := eventstestutils.Scan("2016-03-07T17:28:03.129014751+02:00 container destroy 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)")
  135. assert.NilError(t, err)
  136. evts := &Events{
  137. events: []events.Message{*m1, *m2, *m3},
  138. }
  139. since := time.Unix(s, sNano)
  140. until := time.Time{}
  141. messages := evts.loadBufferedEvents(since, until, nil)
  142. assert.Assert(t, is.Len(messages, 1))
  143. }
  144. func TestLoadBufferedEventsOnlyFromPast(t *testing.T) {
  145. now := time.Now()
  146. f, err := timetypes.GetTimestamp("2016-03-07T17:28:03.090000000+02:00", now)
  147. assert.NilError(t, err)
  148. s, sNano, err := timetypes.ParseTimestamps(f, 0)
  149. assert.NilError(t, err)
  150. f, err = timetypes.GetTimestamp("2016-03-07T17:28:03.100000000+02:00", now)
  151. assert.NilError(t, err)
  152. u, uNano, err := timetypes.ParseTimestamps(f, 0)
  153. assert.NilError(t, err)
  154. m1, err := eventstestutils.Scan("2016-03-07T17:28:03.022433271+02:00 container die 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)")
  155. assert.NilError(t, err)
  156. m2, err := eventstestutils.Scan("2016-03-07T17:28:03.091719377+02:00 network disconnect 19c5ed41acb798f26b751e0035cd7821741ab79e2bbd59a66b5fd8abf954eaa0 (type=bridge, container=0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079, name=bridge)")
  157. assert.NilError(t, err)
  158. m3, err := eventstestutils.Scan("2016-03-07T17:28:03.129014751+02:00 container destroy 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)")
  159. assert.NilError(t, err)
  160. evts := &Events{
  161. events: []events.Message{*m1, *m2, *m3},
  162. }
  163. since := time.Unix(s, sNano)
  164. until := time.Unix(u, uNano)
  165. messages := evts.loadBufferedEvents(since, until, nil)
  166. assert.Assert(t, is.Len(messages, 1))
  167. assert.Check(t, is.Equal(messages[0].Type, events.NetworkEventType))
  168. }
  169. // Regression-test for https://github.com/moby/moby/issues/13753
  170. func TestIgnoreBufferedWhenNoTimes(t *testing.T) {
  171. m1, err := eventstestutils.Scan("2016-03-07T17:28:03.022433271+02:00 container die 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)")
  172. assert.NilError(t, err)
  173. m2, err := eventstestutils.Scan("2016-03-07T17:28:03.091719377+02:00 network disconnect 19c5ed41acb798f26b751e0035cd7821741ab79e2bbd59a66b5fd8abf954eaa0 (type=bridge, container=0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079, name=bridge)")
  174. assert.NilError(t, err)
  175. m3, err := eventstestutils.Scan("2016-03-07T17:28:03.129014751+02:00 container destroy 0b863f2a26c18557fc6cdadda007c459f9ec81b874780808138aea78a3595079 (image=ubuntu, name=small_hoover)")
  176. assert.NilError(t, err)
  177. evts := &Events{
  178. events: []events.Message{*m1, *m2, *m3},
  179. }
  180. since := time.Time{}
  181. until := time.Time{}
  182. messages := evts.loadBufferedEvents(since, until, nil)
  183. assert.Assert(t, is.Len(messages, 0))
  184. }