You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

379 lines
11 KiB

lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
  1. package events
  2. import (
  3. "context"
  4. "fmt"
  5. "math/rand"
  6. "testing"
  7. "time"
  8. "github.com/stretchr/testify/require"
  9. "github.com/tendermint/tendermint/libs/log"
  10. )
  11. // TestAddListenerForEventFireOnce sets up an EventSwitch, subscribes a single
  12. // listener to an event, and sends a string "data".
  13. func TestAddListenerForEventFireOnce(t *testing.T) {
  14. ctx, cancel := context.WithCancel(context.Background())
  15. defer cancel()
  16. logger := log.NewTestingLogger(t)
  17. evsw := NewEventSwitch(logger)
  18. messages := make(chan EventData)
  19. require.NoError(t, evsw.AddListenerForEvent("listener", "event",
  20. func(ctx context.Context, data EventData) error {
  21. select {
  22. case messages <- data:
  23. return nil
  24. case <-ctx.Done():
  25. return ctx.Err()
  26. }
  27. }))
  28. go evsw.FireEvent(ctx, "event", "data")
  29. received := <-messages
  30. if received != "data" {
  31. t.Errorf("message received does not match: %v", received)
  32. }
  33. }
  34. // TestAddListenerForEventFireMany sets up an EventSwitch, subscribes a single
  35. // listener to an event, and sends a thousand integers.
  36. func TestAddListenerForEventFireMany(t *testing.T) {
  37. ctx, cancel := context.WithCancel(context.Background())
  38. defer cancel()
  39. logger := log.NewTestingLogger(t)
  40. evsw := NewEventSwitch(logger)
  41. doneSum := make(chan uint64)
  42. doneSending := make(chan uint64)
  43. numbers := make(chan uint64, 4)
  44. // subscribe one listener for one event
  45. require.NoError(t, evsw.AddListenerForEvent("listener", "event",
  46. func(ctx context.Context, data EventData) error {
  47. select {
  48. case numbers <- data.(uint64):
  49. return nil
  50. case <-ctx.Done():
  51. return ctx.Err()
  52. }
  53. }))
  54. // collect received events
  55. go sumReceivedNumbers(numbers, doneSum)
  56. // go fire events
  57. go fireEvents(ctx, evsw, "event", doneSending, uint64(1))
  58. checkSum := <-doneSending
  59. close(numbers)
  60. eventSum := <-doneSum
  61. if checkSum != eventSum {
  62. t.Errorf("not all messages sent were received.\n")
  63. }
  64. }
  65. // TestAddListenerForDifferentEvents sets up an EventSwitch, subscribes a single
  66. // listener to three different events and sends a thousand integers for each
  67. // of the three events.
  68. func TestAddListenerForDifferentEvents(t *testing.T) {
  69. ctx, cancel := context.WithCancel(context.Background())
  70. defer cancel()
  71. logger := log.NewTestingLogger(t)
  72. evsw := NewEventSwitch(logger)
  73. doneSum := make(chan uint64)
  74. doneSending1 := make(chan uint64)
  75. doneSending2 := make(chan uint64)
  76. doneSending3 := make(chan uint64)
  77. numbers := make(chan uint64, 4)
  78. // subscribe one listener to three events
  79. require.NoError(t, evsw.AddListenerForEvent("listener", "event1",
  80. func(ctx context.Context, data EventData) error {
  81. select {
  82. case numbers <- data.(uint64):
  83. return nil
  84. case <-ctx.Done():
  85. return ctx.Err()
  86. }
  87. }))
  88. require.NoError(t, evsw.AddListenerForEvent("listener", "event2",
  89. func(ctx context.Context, data EventData) error {
  90. select {
  91. case numbers <- data.(uint64):
  92. return nil
  93. case <-ctx.Done():
  94. return ctx.Err()
  95. }
  96. }))
  97. require.NoError(t, evsw.AddListenerForEvent("listener", "event3",
  98. func(ctx context.Context, data EventData) error {
  99. select {
  100. case numbers <- data.(uint64):
  101. return nil
  102. case <-ctx.Done():
  103. return ctx.Err()
  104. }
  105. }))
  106. // collect received events
  107. go sumReceivedNumbers(numbers, doneSum)
  108. // go fire events
  109. go fireEvents(ctx, evsw, "event1", doneSending1, uint64(1))
  110. go fireEvents(ctx, evsw, "event2", doneSending2, uint64(1))
  111. go fireEvents(ctx, evsw, "event3", doneSending3, uint64(1))
  112. var checkSum uint64
  113. checkSum += <-doneSending1
  114. checkSum += <-doneSending2
  115. checkSum += <-doneSending3
  116. close(numbers)
  117. eventSum := <-doneSum
  118. if checkSum != eventSum {
  119. t.Errorf("not all messages sent were received.\n")
  120. }
  121. }
  122. // TestAddDifferentListenerForDifferentEvents sets up an EventSwitch,
  123. // subscribes a first listener to three events, and subscribes a second
  124. // listener to two of those three events, and then sends a thousand integers
  125. // for each of the three events.
  126. func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
  127. ctx, cancel := context.WithCancel(context.Background())
  128. defer cancel()
  129. logger := log.NewTestingLogger(t)
  130. evsw := NewEventSwitch(logger)
  131. doneSum1 := make(chan uint64)
  132. doneSum2 := make(chan uint64)
  133. doneSending1 := make(chan uint64)
  134. doneSending2 := make(chan uint64)
  135. doneSending3 := make(chan uint64)
  136. numbers1 := make(chan uint64, 4)
  137. numbers2 := make(chan uint64, 4)
  138. // subscribe two listener to three events
  139. require.NoError(t, evsw.AddListenerForEvent("listener1", "event1",
  140. func(ctx context.Context, data EventData) error {
  141. select {
  142. case numbers1 <- data.(uint64):
  143. return nil
  144. case <-ctx.Done():
  145. return ctx.Err()
  146. }
  147. }))
  148. require.NoError(t, evsw.AddListenerForEvent("listener1", "event2",
  149. func(ctx context.Context, data EventData) error {
  150. select {
  151. case numbers1 <- data.(uint64):
  152. return nil
  153. case <-ctx.Done():
  154. return ctx.Err()
  155. }
  156. }))
  157. require.NoError(t, evsw.AddListenerForEvent("listener1", "event3",
  158. func(ctx context.Context, data EventData) error {
  159. select {
  160. case numbers1 <- data.(uint64):
  161. return nil
  162. case <-ctx.Done():
  163. return ctx.Err()
  164. }
  165. }))
  166. require.NoError(t, evsw.AddListenerForEvent("listener2", "event2",
  167. func(ctx context.Context, data EventData) error {
  168. select {
  169. case numbers2 <- data.(uint64):
  170. return nil
  171. case <-ctx.Done():
  172. return ctx.Err()
  173. }
  174. }))
  175. require.NoError(t, evsw.AddListenerForEvent("listener2", "event3",
  176. func(ctx context.Context, data EventData) error {
  177. select {
  178. case numbers2 <- data.(uint64):
  179. return nil
  180. case <-ctx.Done():
  181. return ctx.Err()
  182. }
  183. }))
  184. // collect received events for listener1
  185. go sumReceivedNumbers(numbers1, doneSum1)
  186. // collect received events for listener2
  187. go sumReceivedNumbers(numbers2, doneSum2)
  188. // go fire events
  189. go fireEvents(ctx, evsw, "event1", doneSending1, uint64(1))
  190. go fireEvents(ctx, evsw, "event2", doneSending2, uint64(1001))
  191. go fireEvents(ctx, evsw, "event3", doneSending3, uint64(2001))
  192. checkSumEvent1 := <-doneSending1
  193. checkSumEvent2 := <-doneSending2
  194. checkSumEvent3 := <-doneSending3
  195. checkSum1 := checkSumEvent1 + checkSumEvent2 + checkSumEvent3
  196. checkSum2 := checkSumEvent2 + checkSumEvent3
  197. close(numbers1)
  198. close(numbers2)
  199. eventSum1 := <-doneSum1
  200. eventSum2 := <-doneSum2
  201. if checkSum1 != eventSum1 ||
  202. checkSum2 != eventSum2 {
  203. t.Errorf("not all messages sent were received for different listeners to different events.\n")
  204. }
  205. }
  206. // TestManagerLiistenersAsync sets up an EventSwitch, subscribes two
  207. // listeners to three events, and fires a thousand integers for each event.
  208. // These two listeners serve as the baseline validation while other listeners
  209. // are randomly subscribed and unsubscribed.
  210. // More precisely it randomly subscribes new listeners (different from the first
  211. // two listeners) to one of these three events. At the same time it starts
  212. // randomly unsubscribing these additional listeners from all events they are
  213. // at that point subscribed to.
  214. // NOTE: it is important to run this test with race conditions tracking on,
  215. // `go test -race`, to examine for possible race conditions.
  216. func TestManageListenersAsync(t *testing.T) {
  217. ctx, cancel := context.WithCancel(context.Background())
  218. defer cancel()
  219. logger := log.NewTestingLogger(t)
  220. evsw := NewEventSwitch(logger)
  221. doneSum1 := make(chan uint64)
  222. doneSum2 := make(chan uint64)
  223. doneSending1 := make(chan uint64)
  224. doneSending2 := make(chan uint64)
  225. doneSending3 := make(chan uint64)
  226. numbers1 := make(chan uint64, 4)
  227. numbers2 := make(chan uint64, 4)
  228. // subscribe two listener to three events
  229. require.NoError(t, evsw.AddListenerForEvent("listener1", "event1",
  230. func(ctx context.Context, data EventData) error {
  231. select {
  232. case numbers1 <- data.(uint64):
  233. return nil
  234. case <-ctx.Done():
  235. return ctx.Err()
  236. }
  237. }))
  238. require.NoError(t, evsw.AddListenerForEvent("listener1", "event2",
  239. func(ctx context.Context, data EventData) error {
  240. select {
  241. case numbers1 <- data.(uint64):
  242. return nil
  243. case <-ctx.Done():
  244. return ctx.Err()
  245. }
  246. }))
  247. require.NoError(t, evsw.AddListenerForEvent("listener1", "event3",
  248. func(ctx context.Context, data EventData) error {
  249. select {
  250. case numbers1 <- data.(uint64):
  251. return nil
  252. case <-ctx.Done():
  253. return ctx.Err()
  254. }
  255. }))
  256. require.NoError(t, evsw.AddListenerForEvent("listener2", "event1",
  257. func(ctx context.Context, data EventData) error {
  258. select {
  259. case numbers2 <- data.(uint64):
  260. return nil
  261. case <-ctx.Done():
  262. return ctx.Err()
  263. }
  264. }))
  265. require.NoError(t, evsw.AddListenerForEvent("listener2", "event2",
  266. func(ctx context.Context, data EventData) error {
  267. select {
  268. case numbers2 <- data.(uint64):
  269. return nil
  270. case <-ctx.Done():
  271. return ctx.Err()
  272. }
  273. }))
  274. require.NoError(t, evsw.AddListenerForEvent("listener2", "event3",
  275. func(ctx context.Context, data EventData) error {
  276. select {
  277. case numbers2 <- data.(uint64):
  278. return nil
  279. case <-ctx.Done():
  280. return ctx.Err()
  281. }
  282. }))
  283. // collect received events for event1
  284. go sumReceivedNumbers(numbers1, doneSum1)
  285. // collect received events for event2
  286. go sumReceivedNumbers(numbers2, doneSum2)
  287. addListenersStress := func() {
  288. r1 := rand.New(rand.NewSource(time.Now().Unix()))
  289. r1.Seed(time.Now().UnixNano())
  290. for k := uint16(0); k < 400; k++ {
  291. listenerNumber := r1.Intn(100) + 3
  292. eventNumber := r1.Intn(3) + 1
  293. go evsw.AddListenerForEvent(fmt.Sprintf("listener%v", listenerNumber), //nolint:errcheck // ignore for tests
  294. fmt.Sprintf("event%v", eventNumber),
  295. func(context.Context, EventData) error { return nil })
  296. }
  297. }
  298. addListenersStress()
  299. // go fire events
  300. go fireEvents(ctx, evsw, "event1", doneSending1, uint64(1))
  301. go fireEvents(ctx, evsw, "event2", doneSending2, uint64(1001))
  302. go fireEvents(ctx, evsw, "event3", doneSending3, uint64(2001))
  303. checkSumEvent1 := <-doneSending1
  304. checkSumEvent2 := <-doneSending2
  305. checkSumEvent3 := <-doneSending3
  306. checkSum := checkSumEvent1 + checkSumEvent2 + checkSumEvent3
  307. close(numbers1)
  308. close(numbers2)
  309. eventSum1 := <-doneSum1
  310. eventSum2 := <-doneSum2
  311. if checkSum != eventSum1 ||
  312. checkSum != eventSum2 {
  313. t.Errorf("not all messages sent were received.\n")
  314. }
  315. }
  316. //------------------------------------------------------------------------------
  317. // Helper functions
  318. // sumReceivedNumbers takes two channels and adds all numbers received
  319. // until the receiving channel `numbers` is closed; it then sends the sum
  320. // on `doneSum` and closes that channel. Expected to be run in a go-routine.
  321. func sumReceivedNumbers(numbers, doneSum chan uint64) {
  322. var sum uint64
  323. for {
  324. j, more := <-numbers
  325. sum += j
  326. if !more {
  327. doneSum <- sum
  328. close(doneSum)
  329. return
  330. }
  331. }
  332. }
  333. // fireEvents takes an EventSwitch and fires a thousand integers under
  334. // a given `event` with the integers mootonically increasing from `offset`
  335. // to `offset` + 999. It additionally returns the addition of all integers
  336. // sent on `doneChan` for assertion that all events have been sent, and enabling
  337. // the test to assert all events have also been received.
  338. func fireEvents(ctx context.Context, evsw Fireable, event string, doneChan chan uint64, offset uint64) {
  339. defer close(doneChan)
  340. var sentSum uint64
  341. for i := offset; i <= offset+uint64(999); i++ {
  342. if ctx.Err() != nil {
  343. break
  344. }
  345. evsw.FireEvent(ctx, event, i)
  346. sentSum += i
  347. }
  348. select {
  349. case <-ctx.Done():
  350. case doneChan <- sentSum:
  351. }
  352. }