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.

449 lines
14 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. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. "github.com/tendermint/tendermint/libs/rand"
  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. evsw := NewEventSwitch()
  17. require.NoError(t, evsw.Start(ctx))
  18. t.Cleanup(evsw.Wait)
  19. messages := make(chan EventData)
  20. require.NoError(t, evsw.AddListenerForEvent("listener", "event",
  21. func(data EventData) {
  22. // test there's no deadlock if we remove the listener inside a callback
  23. evsw.RemoveListener("listener")
  24. messages <- data
  25. }))
  26. go evsw.FireEvent("event", "data")
  27. received := <-messages
  28. if received != "data" {
  29. t.Errorf("message received does not match: %v", received)
  30. }
  31. }
  32. // TestAddListenerForEventFireMany sets up an EventSwitch, subscribes a single
  33. // listener to an event, and sends a thousand integers.
  34. func TestAddListenerForEventFireMany(t *testing.T) {
  35. ctx, cancel := context.WithCancel(context.Background())
  36. defer cancel()
  37. evsw := NewEventSwitch()
  38. require.NoError(t, evsw.Start(ctx))
  39. t.Cleanup(evsw.Wait)
  40. doneSum := make(chan uint64)
  41. doneSending := make(chan uint64)
  42. numbers := make(chan uint64, 4)
  43. // subscribe one listener for one event
  44. require.NoError(t, evsw.AddListenerForEvent("listener", "event",
  45. func(data EventData) {
  46. numbers <- data.(uint64)
  47. }))
  48. // collect received events
  49. go sumReceivedNumbers(numbers, doneSum)
  50. // go fire events
  51. go fireEvents(evsw, "event", doneSending, uint64(1))
  52. checkSum := <-doneSending
  53. close(numbers)
  54. eventSum := <-doneSum
  55. if checkSum != eventSum {
  56. t.Errorf("not all messages sent were received.\n")
  57. }
  58. }
  59. // TestAddListenerForDifferentEvents sets up an EventSwitch, subscribes a single
  60. // listener to three different events and sends a thousand integers for each
  61. // of the three events.
  62. func TestAddListenerForDifferentEvents(t *testing.T) {
  63. ctx, cancel := context.WithCancel(context.Background())
  64. defer cancel()
  65. evsw := NewEventSwitch()
  66. require.NoError(t, evsw.Start(ctx))
  67. t.Cleanup(evsw.Wait)
  68. doneSum := make(chan uint64)
  69. doneSending1 := make(chan uint64)
  70. doneSending2 := make(chan uint64)
  71. doneSending3 := make(chan uint64)
  72. numbers := make(chan uint64, 4)
  73. // subscribe one listener to three events
  74. require.NoError(t, evsw.AddListenerForEvent("listener", "event1",
  75. func(data EventData) {
  76. numbers <- data.(uint64)
  77. }))
  78. require.NoError(t, evsw.AddListenerForEvent("listener", "event2",
  79. func(data EventData) {
  80. numbers <- data.(uint64)
  81. }))
  82. require.NoError(t, evsw.AddListenerForEvent("listener", "event3",
  83. func(data EventData) {
  84. numbers <- data.(uint64)
  85. }))
  86. // collect received events
  87. go sumReceivedNumbers(numbers, doneSum)
  88. // go fire events
  89. go fireEvents(evsw, "event1", doneSending1, uint64(1))
  90. go fireEvents(evsw, "event2", doneSending2, uint64(1))
  91. go fireEvents(evsw, "event3", doneSending3, uint64(1))
  92. var checkSum uint64
  93. checkSum += <-doneSending1
  94. checkSum += <-doneSending2
  95. checkSum += <-doneSending3
  96. close(numbers)
  97. eventSum := <-doneSum
  98. if checkSum != eventSum {
  99. t.Errorf("not all messages sent were received.\n")
  100. }
  101. }
  102. // TestAddDifferentListenerForDifferentEvents sets up an EventSwitch,
  103. // subscribes a first listener to three events, and subscribes a second
  104. // listener to two of those three events, and then sends a thousand integers
  105. // for each of the three events.
  106. func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
  107. ctx, cancel := context.WithCancel(context.Background())
  108. defer cancel()
  109. evsw := NewEventSwitch()
  110. require.NoError(t, evsw.Start(ctx))
  111. t.Cleanup(evsw.Wait)
  112. doneSum1 := make(chan uint64)
  113. doneSum2 := make(chan uint64)
  114. doneSending1 := make(chan uint64)
  115. doneSending2 := make(chan uint64)
  116. doneSending3 := make(chan uint64)
  117. numbers1 := make(chan uint64, 4)
  118. numbers2 := make(chan uint64, 4)
  119. // subscribe two listener to three events
  120. require.NoError(t, evsw.AddListenerForEvent("listener1", "event1",
  121. func(data EventData) {
  122. numbers1 <- data.(uint64)
  123. }))
  124. require.NoError(t, evsw.AddListenerForEvent("listener1", "event2",
  125. func(data EventData) {
  126. numbers1 <- data.(uint64)
  127. }))
  128. require.NoError(t, evsw.AddListenerForEvent("listener1", "event3",
  129. func(data EventData) {
  130. numbers1 <- data.(uint64)
  131. }))
  132. require.NoError(t, evsw.AddListenerForEvent("listener2", "event2",
  133. func(data EventData) {
  134. numbers2 <- data.(uint64)
  135. }))
  136. require.NoError(t, evsw.AddListenerForEvent("listener2", "event3",
  137. func(data EventData) {
  138. numbers2 <- data.(uint64)
  139. }))
  140. // collect received events for listener1
  141. go sumReceivedNumbers(numbers1, doneSum1)
  142. // collect received events for listener2
  143. go sumReceivedNumbers(numbers2, doneSum2)
  144. // go fire events
  145. go fireEvents(evsw, "event1", doneSending1, uint64(1))
  146. go fireEvents(evsw, "event2", doneSending2, uint64(1001))
  147. go fireEvents(evsw, "event3", doneSending3, uint64(2001))
  148. checkSumEvent1 := <-doneSending1
  149. checkSumEvent2 := <-doneSending2
  150. checkSumEvent3 := <-doneSending3
  151. checkSum1 := checkSumEvent1 + checkSumEvent2 + checkSumEvent3
  152. checkSum2 := checkSumEvent2 + checkSumEvent3
  153. close(numbers1)
  154. close(numbers2)
  155. eventSum1 := <-doneSum1
  156. eventSum2 := <-doneSum2
  157. if checkSum1 != eventSum1 ||
  158. checkSum2 != eventSum2 {
  159. t.Errorf("not all messages sent were received for different listeners to different events.\n")
  160. }
  161. }
  162. func TestAddAndRemoveListenerConcurrency(t *testing.T) {
  163. var (
  164. stopInputEvent = false
  165. roundCount = 2000
  166. )
  167. ctx, cancel := context.WithCancel(context.Background())
  168. defer cancel()
  169. evsw := NewEventSwitch()
  170. require.NoError(t, evsw.Start(ctx))
  171. t.Cleanup(evsw.Wait)
  172. done1 := make(chan struct{})
  173. done2 := make(chan struct{})
  174. // Must be executed concurrently to uncover the data race.
  175. // 1. RemoveListener
  176. go func() {
  177. defer close(done1)
  178. for i := 0; i < roundCount; i++ {
  179. evsw.RemoveListener("listener")
  180. }
  181. }()
  182. // 2. AddListenerForEvent
  183. go func() {
  184. defer close(done2)
  185. for i := 0; i < roundCount; i++ {
  186. index := i
  187. // we explicitly ignore errors here, since the listener will sometimes be removed
  188. // (that's what we're testing)
  189. _ = evsw.AddListenerForEvent("listener", fmt.Sprintf("event%d", index),
  190. func(data EventData) {
  191. t.Errorf("should not run callback for %d.\n", index)
  192. stopInputEvent = true
  193. })
  194. }
  195. }()
  196. <-done1
  197. <-done2
  198. evsw.RemoveListener("listener") // remove the last listener
  199. for i := 0; i < roundCount && !stopInputEvent; i++ {
  200. evsw.FireEvent(fmt.Sprintf("event%d", i), uint64(1001))
  201. }
  202. }
  203. // TestAddAndRemoveListener sets up an EventSwitch, subscribes a listener to
  204. // two events, fires a thousand integers for the first event, then unsubscribes
  205. // the listener and fires a thousand integers for the second event.
  206. func TestAddAndRemoveListener(t *testing.T) {
  207. ctx, cancel := context.WithCancel(context.Background())
  208. defer cancel()
  209. evsw := NewEventSwitch()
  210. require.NoError(t, evsw.Start(ctx))
  211. t.Cleanup(evsw.Wait)
  212. doneSum1 := make(chan uint64)
  213. doneSum2 := make(chan uint64)
  214. doneSending1 := make(chan uint64)
  215. doneSending2 := make(chan uint64)
  216. numbers1 := make(chan uint64, 4)
  217. numbers2 := make(chan uint64, 4)
  218. // subscribe two listener to three events
  219. require.NoError(t, evsw.AddListenerForEvent("listener", "event1",
  220. func(data EventData) {
  221. numbers1 <- data.(uint64)
  222. }))
  223. require.NoError(t, evsw.AddListenerForEvent("listener", "event2",
  224. func(data EventData) {
  225. numbers2 <- data.(uint64)
  226. }))
  227. // collect received events for event1
  228. go sumReceivedNumbers(numbers1, doneSum1)
  229. // collect received events for event2
  230. go sumReceivedNumbers(numbers2, doneSum2)
  231. // go fire events
  232. go fireEvents(evsw, "event1", doneSending1, uint64(1))
  233. checkSumEvent1 := <-doneSending1
  234. // after sending all event1, unsubscribe for all events
  235. evsw.RemoveListener("listener")
  236. go fireEvents(evsw, "event2", doneSending2, uint64(1001))
  237. checkSumEvent2 := <-doneSending2
  238. close(numbers1)
  239. close(numbers2)
  240. eventSum1 := <-doneSum1
  241. eventSum2 := <-doneSum2
  242. if checkSumEvent1 != eventSum1 ||
  243. // correct value asserted by preceding tests, suffices to be non-zero
  244. checkSumEvent2 == uint64(0) ||
  245. eventSum2 != uint64(0) {
  246. t.Errorf("not all messages sent were received or unsubscription did not register.\n")
  247. }
  248. }
  249. // TestRemoveListener does basic tests on adding and removing
  250. func TestRemoveListener(t *testing.T) {
  251. ctx, cancel := context.WithCancel(context.Background())
  252. defer cancel()
  253. evsw := NewEventSwitch()
  254. require.NoError(t, evsw.Start(ctx))
  255. t.Cleanup(evsw.Wait)
  256. count := 10
  257. sum1, sum2 := 0, 0
  258. // add some listeners and make sure they work
  259. require.NoError(t, evsw.AddListenerForEvent("listener", "event1",
  260. func(data EventData) {
  261. sum1++
  262. }))
  263. require.NoError(t, evsw.AddListenerForEvent("listener", "event2",
  264. func(data EventData) {
  265. sum2++
  266. }))
  267. for i := 0; i < count; i++ {
  268. evsw.FireEvent("event1", true)
  269. evsw.FireEvent("event2", true)
  270. }
  271. assert.Equal(t, count, sum1)
  272. assert.Equal(t, count, sum2)
  273. // remove one by event and make sure it is gone
  274. evsw.RemoveListenerForEvent("event2", "listener")
  275. for i := 0; i < count; i++ {
  276. evsw.FireEvent("event1", true)
  277. evsw.FireEvent("event2", true)
  278. }
  279. assert.Equal(t, count*2, sum1)
  280. assert.Equal(t, count, sum2)
  281. // remove the listener entirely and make sure both gone
  282. evsw.RemoveListener("listener")
  283. for i := 0; i < count; i++ {
  284. evsw.FireEvent("event1", true)
  285. evsw.FireEvent("event2", true)
  286. }
  287. assert.Equal(t, count*2, sum1)
  288. assert.Equal(t, count, sum2)
  289. }
  290. // TestAddAndRemoveListenersAsync sets up an EventSwitch, subscribes two
  291. // listeners to three events, and fires a thousand integers for each event.
  292. // These two listeners serve as the baseline validation while other listeners
  293. // are randomly subscribed and unsubscribed.
  294. // More precisely it randomly subscribes new listeners (different from the first
  295. // two listeners) to one of these three events. At the same time it starts
  296. // randomly unsubscribing these additional listeners from all events they are
  297. // at that point subscribed to.
  298. // NOTE: it is important to run this test with race conditions tracking on,
  299. // `go test -race`, to examine for possible race conditions.
  300. func TestRemoveListenersAsync(t *testing.T) {
  301. ctx, cancel := context.WithCancel(context.Background())
  302. defer cancel()
  303. evsw := NewEventSwitch()
  304. require.NoError(t, evsw.Start(ctx))
  305. t.Cleanup(evsw.Wait)
  306. doneSum1 := make(chan uint64)
  307. doneSum2 := make(chan uint64)
  308. doneSending1 := make(chan uint64)
  309. doneSending2 := make(chan uint64)
  310. doneSending3 := make(chan uint64)
  311. numbers1 := make(chan uint64, 4)
  312. numbers2 := make(chan uint64, 4)
  313. // subscribe two listener to three events
  314. require.NoError(t, evsw.AddListenerForEvent("listener1", "event1",
  315. func(data EventData) {
  316. numbers1 <- data.(uint64)
  317. }))
  318. require.NoError(t, evsw.AddListenerForEvent("listener1", "event2",
  319. func(data EventData) {
  320. numbers1 <- data.(uint64)
  321. }))
  322. require.NoError(t, evsw.AddListenerForEvent("listener1", "event3",
  323. func(data EventData) {
  324. numbers1 <- data.(uint64)
  325. }))
  326. require.NoError(t, evsw.AddListenerForEvent("listener2", "event1",
  327. func(data EventData) {
  328. numbers2 <- data.(uint64)
  329. }))
  330. require.NoError(t, evsw.AddListenerForEvent("listener2", "event2",
  331. func(data EventData) {
  332. numbers2 <- data.(uint64)
  333. }))
  334. require.NoError(t, evsw.AddListenerForEvent("listener2", "event3",
  335. func(data EventData) {
  336. numbers2 <- data.(uint64)
  337. }))
  338. // collect received events for event1
  339. go sumReceivedNumbers(numbers1, doneSum1)
  340. // collect received events for event2
  341. go sumReceivedNumbers(numbers2, doneSum2)
  342. addListenersStress := func() {
  343. r1 := rand.NewRand()
  344. r1.Seed(time.Now().UnixNano())
  345. for k := uint16(0); k < 400; k++ {
  346. listenerNumber := r1.Intn(100) + 3
  347. eventNumber := r1.Intn(3) + 1
  348. go evsw.AddListenerForEvent(fmt.Sprintf("listener%v", listenerNumber), //nolint:errcheck // ignore for tests
  349. fmt.Sprintf("event%v", eventNumber),
  350. func(_ EventData) {})
  351. }
  352. }
  353. removeListenersStress := func() {
  354. r2 := rand.NewRand()
  355. r2.Seed(time.Now().UnixNano())
  356. for k := uint16(0); k < 80; k++ {
  357. listenerNumber := r2.Intn(100) + 3
  358. go evsw.RemoveListener(fmt.Sprintf("listener%v", listenerNumber))
  359. }
  360. }
  361. addListenersStress()
  362. // go fire events
  363. go fireEvents(evsw, "event1", doneSending1, uint64(1))
  364. removeListenersStress()
  365. go fireEvents(evsw, "event2", doneSending2, uint64(1001))
  366. go fireEvents(evsw, "event3", doneSending3, uint64(2001))
  367. checkSumEvent1 := <-doneSending1
  368. checkSumEvent2 := <-doneSending2
  369. checkSumEvent3 := <-doneSending3
  370. checkSum := checkSumEvent1 + checkSumEvent2 + checkSumEvent3
  371. close(numbers1)
  372. close(numbers2)
  373. eventSum1 := <-doneSum1
  374. eventSum2 := <-doneSum2
  375. if checkSum != eventSum1 ||
  376. checkSum != eventSum2 {
  377. t.Errorf("not all messages sent were received.\n")
  378. }
  379. }
  380. //------------------------------------------------------------------------------
  381. // Helper functions
  382. // sumReceivedNumbers takes two channels and adds all numbers received
  383. // until the receiving channel `numbers` is closed; it then sends the sum
  384. // on `doneSum` and closes that channel. Expected to be run in a go-routine.
  385. func sumReceivedNumbers(numbers, doneSum chan uint64) {
  386. var sum uint64
  387. for {
  388. j, more := <-numbers
  389. sum += j
  390. if !more {
  391. doneSum <- sum
  392. close(doneSum)
  393. return
  394. }
  395. }
  396. }
  397. // fireEvents takes an EventSwitch and fires a thousand integers under
  398. // a given `event` with the integers mootonically increasing from `offset`
  399. // to `offset` + 999. It additionally returns the addition of all integers
  400. // sent on `doneChan` for assertion that all events have been sent, and enabling
  401. // the test to assert all events have also been received.
  402. func fireEvents(evsw Fireable, event string, doneChan chan uint64,
  403. offset uint64) {
  404. var sentSum uint64
  405. for i := offset; i <= offset+uint64(999); i++ {
  406. sentSum += i
  407. evsw.FireEvent(event, i)
  408. }
  409. doneChan <- sentSum
  410. close(doneChan)
  411. }