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.

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