@ -1,58 +1,121 @@
package p2p
package p2p_test
import (
"net"
"sync"
"testing"
"github.com/tendermint/tendermint/p2p"
)
// TestMockPeerBehaviour tests the MockPeerBehaviour' ability to store reported
// peer behaviour in memory indexed by the peerID
func TestMockPeerBehaviourReporter ( t * testing . T ) {
peer := newMockPeer ( net . IP { 127 , 0 , 0 , 1 } )
pr := NewMockPeerBehaviourReporter ( )
var peerID p2p . ID = "MockPeer"
pr := p2p . NewMockPeerBehaviourReporter ( )
behaviours := pr . GetBehaviours ( peer . ID ( ) )
behaviours := pr . GetBehaviours ( peerID )
if len ( behaviours ) != 0 {
t . Errorf ( "Expected to have no behaviours reported" )
t . Error ( "Expected to have no behaviours reported" )
}
pr . Report ( peer . ID ( ) , PeerBehaviourBadMessage )
behaviours = pr . GetBehaviours ( peer . ID ( ) )
pr . Report ( peerID , p2p . PeerBehaviourBadMessage )
behaviours = pr . GetBehaviours ( peerID )
if len ( behaviours ) != 1 {
t . Errorf ( "Expected the peer have one reported behaviour" )
t . Error ( "Expected the peer have one reported behaviour" )
}
if behaviours [ 0 ] != PeerBehaviourBadMessage {
t . Errorf ( "Expected PeerBehaviourBadMessage to have been reported" )
if behaviours [ 0 ] != p2p . PeerBehaviourBadMessage {
t . Error ( "Expected PeerBehaviourBadMessage to have been reported" )
}
}
type scriptedBehaviours struct {
PeerID ID
Behaviours [ ] PeerBehaviour
PeerID p2p . ID
Behaviours [ ] p2p . PeerBehaviour
}
type scriptItem struct {
PeerID ID
Behaviour PeerBehaviour
PeerID p2p . ID
Behaviour p2p . PeerBehaviour
}
func equalBehaviours ( a [ ] PeerBehaviour , b [ ] PeerBehaviour ) bool {
if len ( a ) != len ( b ) {
// equalBehaviours returns true if a and b contain the same PeerBehaviours with
// the same freequency and otherwise false.
func equalBehaviours ( a [ ] p2p . PeerBehaviour , b [ ] p2p . PeerBehaviour ) bool {
aHistogram := map [ p2p . PeerBehaviour ] int { }
bHistogram := map [ p2p . PeerBehaviour ] int { }
for _ , behaviour := range a {
aHistogram [ behaviour ] += 1
}
for _ , behaviour := range b {
bHistogram [ behaviour ] += 1
}
if len ( aHistogram ) != len ( bHistogram ) {
return false
}
same := make ( [ ] PeerBehaviour , len ( a ) )
for i , aBehaviour := range a {
for _ , bBehaviour := range b {
if aBehaviour == bBehaviour {
same [ i ] = aBehaviour
}
for _ , behaviour := range a {
if aHistogram [ behaviour ] != bHistogram [ behaviour ] {
return false
}
}
return len ( same ) == len ( a )
for _ , behaviour := range b {
if bHistogram [ behaviour ] != aHistogram [ behaviour ] {
return false
}
}
return true
}
// TestEqualPeerBehaviours tests that equalBehaviours can tell that two slices
// of peer behaviours can be compared for the behaviours they contain and the
// freequencies that those behaviours occur.
func TestEqualPeerBehaviours ( t * testing . T ) {
equals := [ ] struct {
left [ ] p2p . PeerBehaviour
right [ ] p2p . PeerBehaviour
} {
// Empty sets
{ [ ] p2p . PeerBehaviour { } , [ ] p2p . PeerBehaviour { } } ,
// Single behaviours
{ [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote } , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote } } ,
// Equal Frequencies
{ [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote , p2p . PeerBehaviourVote } ,
[ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote , p2p . PeerBehaviourVote } } ,
// Equal frequencies different orders
{ [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote , p2p . PeerBehaviourBlockPart } ,
[ ] p2p . PeerBehaviour { p2p . PeerBehaviourBlockPart , p2p . PeerBehaviourVote } } ,
}
for _ , test := range equals {
if ! equalBehaviours ( test . left , test . right ) {
t . Errorf ( "Expected %#v and %#v to be equal" , test . left , test . right )
}
}
unequals := [ ] struct {
left [ ] p2p . PeerBehaviour
right [ ] p2p . PeerBehaviour
} {
// Comparing empty sets to non empty sets
{ [ ] p2p . PeerBehaviour { } , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote } } ,
// Different behaviours
{ [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote } , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourBlockPart } } ,
// Same behaviour with different frequencies
{ [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote } ,
[ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote , p2p . PeerBehaviourVote } } ,
}
for _ , test := range unequals {
if equalBehaviours ( test . left , test . right ) {
t . Errorf ( "Expected %#v and %#v to be unequal" , test . left , test . right )
}
}
}
// TestPeerBehaviourConcurrency constructs a scenario in which
@ -61,15 +124,15 @@ func equalBehaviours(a []PeerBehaviour, b []PeerBehaviour) bool {
// be used within a Reactor Receive method tests to ensure thread safety.
func TestMockPeerBehaviourReporterConcurrency ( t * testing . T ) {
behaviourScript := [ ] scriptedBehaviours {
{ "1" , [ ] PeerBehaviour { PeerBehaviourVote } } ,
{ "2" , [ ] PeerBehaviour { PeerBehaviourVote , PeerBehaviourVote , PeerBehaviourVote , PeerBehaviourVote } } ,
{ "3" , [ ] PeerBehaviour { PeerBehaviourBlockPart , PeerBehaviourVote , PeerBehaviourBlockPart , PeerBehaviourVote } } ,
{ "4" , [ ] PeerBehaviour { PeerBehaviourVote , PeerBehaviourVote , PeerBehaviourVote , PeerBehaviourVote } } ,
{ "5" , [ ] PeerBehaviour { PeerBehaviourBlockPart , PeerBehaviourVote , PeerBehaviourBlockPart , PeerBehaviourVote } } ,
{ "1" , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote } } ,
{ "2" , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote , p2p . PeerBehaviourVote , p2p . PeerBehaviourVote , p2p . PeerBehaviourVote } } ,
{ "3" , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourBlockPart , p2p . PeerBehaviourVote , p2p . PeerBehaviourBlockPart , p2p . PeerBehaviourVote } } ,
{ "4" , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourVote , p2p . PeerBehaviourVote , p2p . PeerBehaviourVote , p2p . PeerBehaviourVote } } ,
{ "5" , [ ] p2p . PeerBehaviour { p2p . PeerBehaviourBlockPart , p2p . PeerBehaviourVote , p2p . PeerBehaviourBlockPart , p2p . PeerBehaviourVote } } ,
}
var receiveWg sync . WaitGroup
pr := NewMockPeerBehaviourReporter ( )
pr := p2p . NewMockPeerBehaviourReporter ( )
scriptItems := make ( chan scriptItem )
done := make ( chan int )
numConsumers := 3
@ -108,8 +171,10 @@ func TestMockPeerBehaviourReporterConcurrency(t *testing.T) {
receiveWg . Wait ( )
for _ , items := range behaviourScript {
if ! equalBehaviours ( pr . GetBehaviours ( items . PeerID ) , items . Behaviours ) {
t . Errorf ( "Expected peer %s to have behaved \n" , items . PeerID )
reported := pr . GetBehaviours ( items . PeerID )
if ! equalBehaviours ( reported , items . Behaviours ) {
t . Errorf ( "Expected peer %s to have behaved \nExpected: %#v \nGot %#v \n" ,
items . PeerID , items . Behaviours , reported )
}
}
}