|
|
@ -2,8 +2,11 @@ package p2p |
|
|
|
|
|
|
|
import ( |
|
|
|
"math/rand" |
|
|
|
"sync" |
|
|
|
"testing" |
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert" |
|
|
|
|
|
|
|
cmn "github.com/tendermint/tmlibs/common" |
|
|
|
) |
|
|
|
|
|
|
@ -18,28 +21,47 @@ func randPeer() *Peer { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func TestAddRemoveOne(t *testing.T) { |
|
|
|
func TestPeerSetAddRemoveOne(t *testing.T) { |
|
|
|
t.Parallel() |
|
|
|
peerSet := NewPeerSet() |
|
|
|
|
|
|
|
peer := randPeer() |
|
|
|
err := peerSet.Add(peer) |
|
|
|
if err != nil { |
|
|
|
t.Errorf("Failed to add new peer") |
|
|
|
var peerList []*Peer |
|
|
|
for i := 0; i < 5; i++ { |
|
|
|
p := randPeer() |
|
|
|
peerSet.Add(p) |
|
|
|
peerList = append(peerList, p) |
|
|
|
} |
|
|
|
if peerSet.Size() != 1 { |
|
|
|
t.Errorf("Failed to add new peer and increment size") |
|
|
|
|
|
|
|
n := len(peerList) |
|
|
|
// 1. Test removing from the front
|
|
|
|
for i, peerAtFront := range peerList { |
|
|
|
peerSet.Remove(peerAtFront) |
|
|
|
wantSize := n - i - 1 |
|
|
|
for j := 0; j < 2; j++ { |
|
|
|
assert.Equal(t, false, peerSet.Has(peerAtFront.Key), "#%d Run #%d: failed to remove peer", i, j) |
|
|
|
assert.Equal(t, wantSize, peerSet.Size(), "#%d Run #%d: failed to remove peer and decrement size", i, j) |
|
|
|
// Test the route of removing the now non-existent element
|
|
|
|
peerSet.Remove(peerAtFront) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
peerSet.Remove(peer) |
|
|
|
if peerSet.Has(peer.Key) { |
|
|
|
t.Errorf("Failed to remove peer") |
|
|
|
// 2. Next we are testing removing the peer at the end
|
|
|
|
// a) Replenish the peerSet
|
|
|
|
for _, peer := range peerList { |
|
|
|
peerSet.Add(peer) |
|
|
|
} |
|
|
|
if peerSet.Size() != 0 { |
|
|
|
t.Errorf("Failed to remove peer and decrement size") |
|
|
|
|
|
|
|
// b) In reverse, remove each element
|
|
|
|
for i := n - 1; i >= 0; i-- { |
|
|
|
peerAtEnd := peerList[i] |
|
|
|
peerSet.Remove(peerAtEnd) |
|
|
|
assert.Equal(t, false, peerSet.Has(peerAtEnd.Key), "#%d: failed to remove item at end", i) |
|
|
|
assert.Equal(t, i, peerSet.Size(), "#%d: differing sizes after peerSet.Remove(atEndPeer)", i) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func TestAddRemoveMany(t *testing.T) { |
|
|
|
func TestPeerSetAddRemoveMany(t *testing.T) { |
|
|
|
t.Parallel() |
|
|
|
peerSet := NewPeerSet() |
|
|
|
|
|
|
|
peers := []*Peer{} |
|
|
@ -65,3 +87,61 @@ func TestAddRemoveMany(t *testing.T) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func TestPeerSetAddDuplicate(t *testing.T) { |
|
|
|
t.Parallel() |
|
|
|
peerSet := NewPeerSet() |
|
|
|
peer := randPeer() |
|
|
|
|
|
|
|
n := 20 |
|
|
|
errsChan := make(chan error) |
|
|
|
// Add the same asynchronously to test the
|
|
|
|
// concurrent guarantees of our APIs, and
|
|
|
|
// our expectation in the end is that only
|
|
|
|
// one addition succeeded, but the rest are
|
|
|
|
// instances of ErrSwitchDuplicatePeer.
|
|
|
|
for i := 0; i < n; i++ { |
|
|
|
go func() { |
|
|
|
errsChan <- peerSet.Add(peer) |
|
|
|
}() |
|
|
|
} |
|
|
|
|
|
|
|
// Now collect and tally the results
|
|
|
|
errsTally := make(map[error]int) |
|
|
|
for i := 0; i < n; i++ { |
|
|
|
err := <-errsChan |
|
|
|
errsTally[err] += 1 |
|
|
|
} |
|
|
|
|
|
|
|
// Our next procedure is to ensure that only one addition
|
|
|
|
// succeeded and that the rest are each ErrSwitchDuplicatePeer.
|
|
|
|
wantErrCount, gotErrCount := n-1, errsTally[ErrSwitchDuplicatePeer] |
|
|
|
assert.Equal(t, wantErrCount, gotErrCount, "invalid ErrSwitchDuplicatePeer count") |
|
|
|
|
|
|
|
wantNilErrCount, gotNilErrCount := 1, errsTally[nil] |
|
|
|
assert.Equal(t, wantNilErrCount, gotNilErrCount, "invalid nil errCount") |
|
|
|
} |
|
|
|
|
|
|
|
func TestPeerSetGet(t *testing.T) { |
|
|
|
t.Parallel() |
|
|
|
peerSet := NewPeerSet() |
|
|
|
peer := randPeer() |
|
|
|
assert.Nil(t, peerSet.Get(peer.Key), "expecting a nil lookup, before .Add") |
|
|
|
|
|
|
|
if err := peerSet.Add(peer); err != nil { |
|
|
|
t.Fatalf("Failed to add new peer: %v", err) |
|
|
|
} |
|
|
|
|
|
|
|
var wg sync.WaitGroup |
|
|
|
for i := 0; i < 10; i++ { |
|
|
|
// Add them asynchronously to test the
|
|
|
|
// concurrent guarantees of our APIs.
|
|
|
|
wg.Add(1) |
|
|
|
go func(i int) { |
|
|
|
defer wg.Done() |
|
|
|
got, want := peerSet.Get(peer.Key), peer |
|
|
|
assert.Equal(t, got, want, "#%d: got=%v want=%v", i, got, want) |
|
|
|
}(i) |
|
|
|
} |
|
|
|
wg.Wait() |
|
|
|
} |