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.

171 lines
4.1 KiB

  1. package p2p
  2. import (
  3. "net"
  4. "sync"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. crypto "github.com/tendermint/tendermint/crypto"
  8. cmn "github.com/tendermint/tendermint/libs/common"
  9. )
  10. // Returns an empty kvstore peer
  11. func randPeer(ip net.IP) *peer {
  12. if ip == nil {
  13. ip = net.IP{127, 0, 0, 1}
  14. }
  15. nodeKey := NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
  16. p := &peer{
  17. nodeInfo: NodeInfo{
  18. ID: nodeKey.ID(),
  19. ListenAddr: cmn.Fmt("%v.%v.%v.%v:26656", cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256),
  20. },
  21. }
  22. p.ip = ip
  23. return p
  24. }
  25. func TestPeerSetAddRemoveOne(t *testing.T) {
  26. t.Parallel()
  27. peerSet := NewPeerSet()
  28. var peerList []Peer
  29. for i := 0; i < 5; i++ {
  30. p := randPeer(net.IP{127, 0, 0, byte(i)})
  31. if err := peerSet.Add(p); err != nil {
  32. t.Error(err)
  33. }
  34. peerList = append(peerList, p)
  35. }
  36. n := len(peerList)
  37. // 1. Test removing from the front
  38. for i, peerAtFront := range peerList {
  39. peerSet.Remove(peerAtFront)
  40. wantSize := n - i - 1
  41. for j := 0; j < 2; j++ {
  42. assert.Equal(t, false, peerSet.Has(peerAtFront.ID()), "#%d Run #%d: failed to remove peer", i, j)
  43. assert.Equal(t, wantSize, peerSet.Size(), "#%d Run #%d: failed to remove peer and decrement size", i, j)
  44. // Test the route of removing the now non-existent element
  45. peerSet.Remove(peerAtFront)
  46. }
  47. }
  48. // 2. Next we are testing removing the peer at the end
  49. // a) Replenish the peerSet
  50. for _, peer := range peerList {
  51. if err := peerSet.Add(peer); err != nil {
  52. t.Error(err)
  53. }
  54. }
  55. // b) In reverse, remove each element
  56. for i := n - 1; i >= 0; i-- {
  57. peerAtEnd := peerList[i]
  58. peerSet.Remove(peerAtEnd)
  59. assert.Equal(t, false, peerSet.Has(peerAtEnd.ID()), "#%d: failed to remove item at end", i)
  60. assert.Equal(t, i, peerSet.Size(), "#%d: differing sizes after peerSet.Remove(atEndPeer)", i)
  61. }
  62. }
  63. func TestPeerSetAddRemoveMany(t *testing.T) {
  64. t.Parallel()
  65. peerSet := NewPeerSet()
  66. peers := []Peer{}
  67. N := 100
  68. for i := 0; i < N; i++ {
  69. peer := randPeer(net.IP{127, 0, 0, byte(i)})
  70. if err := peerSet.Add(peer); err != nil {
  71. t.Errorf("Failed to add new peer")
  72. }
  73. if peerSet.Size() != i+1 {
  74. t.Errorf("Failed to add new peer and increment size")
  75. }
  76. peers = append(peers, peer)
  77. }
  78. for i, peer := range peers {
  79. peerSet.Remove(peer)
  80. if peerSet.Has(peer.ID()) {
  81. t.Errorf("Failed to remove peer")
  82. }
  83. if peerSet.Size() != len(peers)-i-1 {
  84. t.Errorf("Failed to remove peer and decrement size")
  85. }
  86. }
  87. }
  88. func TestPeerSetAddDuplicate(t *testing.T) {
  89. t.Parallel()
  90. peerSet := NewPeerSet()
  91. peer := randPeer(nil)
  92. n := 20
  93. errsChan := make(chan error)
  94. // Add the same asynchronously to test the
  95. // concurrent guarantees of our APIs, and
  96. // our expectation in the end is that only
  97. // one addition succeeded, but the rest are
  98. // instances of ErrSwitchDuplicatePeer.
  99. for i := 0; i < n; i++ {
  100. go func() {
  101. errsChan <- peerSet.Add(peer)
  102. }()
  103. }
  104. // Now collect and tally the results
  105. errsTally := make(map[string]int)
  106. for i := 0; i < n; i++ {
  107. err := <-errsChan
  108. switch err.(type) {
  109. case ErrSwitchDuplicatePeerID:
  110. errsTally["duplicateID"]++
  111. default:
  112. errsTally["other"]++
  113. }
  114. }
  115. // Our next procedure is to ensure that only one addition
  116. // succeeded and that the rest are each ErrSwitchDuplicatePeer.
  117. wantErrCount, gotErrCount := n-1, errsTally["duplicateID"]
  118. assert.Equal(t, wantErrCount, gotErrCount, "invalid ErrSwitchDuplicatePeer count")
  119. wantNilErrCount, gotNilErrCount := 1, errsTally["other"]
  120. assert.Equal(t, wantNilErrCount, gotNilErrCount, "invalid nil errCount")
  121. }
  122. func TestPeerSetGet(t *testing.T) {
  123. t.Parallel()
  124. var (
  125. peerSet = NewPeerSet()
  126. peer = randPeer(nil)
  127. )
  128. assert.Nil(t, peerSet.Get(peer.ID()), "expecting a nil lookup, before .Add")
  129. if err := peerSet.Add(peer); err != nil {
  130. t.Fatalf("Failed to add new peer: %v", err)
  131. }
  132. var wg sync.WaitGroup
  133. for i := 0; i < 10; i++ {
  134. // Add them asynchronously to test the
  135. // concurrent guarantees of our APIs.
  136. wg.Add(1)
  137. go func(i int) {
  138. defer wg.Done()
  139. have, want := peerSet.Get(peer.ID()), peer
  140. assert.Equal(t, have, want, "%d: have %v, want %v", i, have, want)
  141. }(i)
  142. }
  143. wg.Wait()
  144. }