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.

155 lines
4.5 KiB

  1. package p2ptest
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/gogo/protobuf/proto"
  6. "github.com/stretchr/testify/require"
  7. "github.com/tendermint/tendermint/p2p"
  8. )
  9. // RequireEmpty requires that the given channel is empty.
  10. func RequireEmpty(t *testing.T, channels ...*p2p.Channel) {
  11. for _, channel := range channels {
  12. select {
  13. case e := <-channel.In:
  14. require.Fail(t, "unexpected message", "channel %v should be empty, got %v", channel.ID, e)
  15. case <-time.After(10 * time.Millisecond):
  16. }
  17. }
  18. }
  19. // RequireReceive requires that the given envelope is received on the channel.
  20. func RequireReceive(t *testing.T, channel *p2p.Channel, expect p2p.Envelope) {
  21. timer := time.NewTimer(time.Second) // not time.After due to goroutine leaks
  22. defer timer.Stop()
  23. select {
  24. case e, ok := <-channel.In:
  25. require.True(t, ok, "channel %v is closed", channel.ID)
  26. require.Equal(t, expect, e)
  27. case <-channel.Done():
  28. require.Fail(t, "channel %v is closed", channel.ID)
  29. case <-timer.C:
  30. require.Fail(t, "timed out waiting for message", "%v on channel %v", expect, channel.ID)
  31. }
  32. }
  33. // RequireReceiveUnordered requires that the given envelopes are all received on
  34. // the channel, ignoring order.
  35. func RequireReceiveUnordered(t *testing.T, channel *p2p.Channel, expect []p2p.Envelope) {
  36. timer := time.NewTimer(time.Second) // not time.After due to goroutine leaks
  37. defer timer.Stop()
  38. actual := []p2p.Envelope{}
  39. for {
  40. select {
  41. case e, ok := <-channel.In:
  42. require.True(t, ok, "channel %v is closed", channel.ID)
  43. actual = append(actual, e)
  44. if len(actual) == len(expect) {
  45. require.ElementsMatch(t, expect, actual)
  46. return
  47. }
  48. case <-channel.Done():
  49. require.Fail(t, "channel %v is closed", channel.ID)
  50. case <-timer.C:
  51. require.ElementsMatch(t, expect, actual)
  52. return
  53. }
  54. }
  55. }
  56. // RequireSend requires that the given envelope is sent on the channel.
  57. func RequireSend(t *testing.T, channel *p2p.Channel, envelope p2p.Envelope) {
  58. timer := time.NewTimer(time.Second) // not time.After due to goroutine leaks
  59. defer timer.Stop()
  60. select {
  61. case channel.Out <- envelope:
  62. case <-timer.C:
  63. require.Fail(t, "timed out sending message", "%v on channel %v", envelope, channel.ID)
  64. }
  65. }
  66. // RequireSendReceive requires that a given Protobuf message is sent to the
  67. // given peer, and then that the given response is received back.
  68. func RequireSendReceive(
  69. t *testing.T,
  70. channel *p2p.Channel,
  71. peerID p2p.NodeID,
  72. send proto.Message,
  73. receive proto.Message,
  74. ) {
  75. RequireSend(t, channel, p2p.Envelope{To: peerID, Message: send})
  76. RequireReceive(t, channel, p2p.Envelope{From: peerID, Message: send})
  77. }
  78. // RequireNoUpdates requires that a PeerUpdates subscription is empty.
  79. func RequireNoUpdates(t *testing.T, peerUpdates *p2p.PeerUpdates) {
  80. select {
  81. case update := <-peerUpdates.Updates():
  82. require.Fail(t, "unexpected peer updates", "got %v", update)
  83. default:
  84. }
  85. }
  86. // RequireError requires that the given peer error is submitted for a peer.
  87. func RequireError(t *testing.T, channel *p2p.Channel, peerError p2p.PeerError) {
  88. timer := time.NewTimer(time.Second) // not time.After due to goroutine leaks
  89. defer timer.Stop()
  90. select {
  91. case channel.Error <- peerError:
  92. case <-timer.C:
  93. require.Fail(t, "timed out reporting error", "%v on %v", peerError, channel.ID)
  94. }
  95. }
  96. // RequireUpdate requires that a PeerUpdates subscription yields the given update.
  97. func RequireUpdate(t *testing.T, peerUpdates *p2p.PeerUpdates, expect p2p.PeerUpdate) {
  98. timer := time.NewTimer(time.Second) // not time.After due to goroutine leaks
  99. defer timer.Stop()
  100. select {
  101. case update := <-peerUpdates.Updates():
  102. require.Equal(t, expect, update, "peer update did not match")
  103. case <-peerUpdates.Done():
  104. require.Fail(t, "peer updates subscription is closed")
  105. case <-timer.C:
  106. require.Fail(t, "timed out waiting for peer update", "expected %v", expect)
  107. }
  108. }
  109. // RequireUpdates requires that a PeerUpdates subscription yields the given updates
  110. // in the given order.
  111. func RequireUpdates(t *testing.T, peerUpdates *p2p.PeerUpdates, expect []p2p.PeerUpdate) {
  112. timer := time.NewTimer(time.Second) // not time.After due to goroutine leaks
  113. defer timer.Stop()
  114. actual := []p2p.PeerUpdate{}
  115. for {
  116. select {
  117. case update := <-peerUpdates.Updates():
  118. actual = append(actual, update)
  119. if len(actual) == len(expect) {
  120. require.Equal(t, expect, actual)
  121. return
  122. }
  123. case <-peerUpdates.Done():
  124. require.Fail(t, "peer updates subscription is closed")
  125. case <-timer.C:
  126. require.Equal(t, expect, actual, "did not receive expected peer updates")
  127. return
  128. }
  129. }
  130. }