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.

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