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.

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