From f861d2259330f552e0145d154e07fac0a4eb9449 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Tue, 28 Jul 2015 09:02:52 +0100 Subject: [PATCH] do proper mock periodic gossip instead of abusing broadcast gossip Fixes #1203. --- testing/gossip/mocks.go | 43 +++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/testing/gossip/mocks.go b/testing/gossip/mocks.go index 95f7d976..ebc63242 100644 --- a/testing/gossip/mocks.go +++ b/testing/gossip/mocks.go @@ -2,6 +2,7 @@ package gossip import ( "fmt" + "math" "math/rand" "time" @@ -18,6 +19,10 @@ type broadcastMessage struct { sender router.PeerName data router.GossipData } +type gossipMessage struct { + sender router.PeerName + data router.GossipData +} type exitMessage struct { exitChan chan struct{} } @@ -51,6 +56,25 @@ func (grouter *TestRouter) gossipBroadcast(sender router.PeerName, update router return nil } +func (grouter *TestRouter) gossip(sender router.PeerName, update router.GossipData) error { + count := int(math.Log2(float64(len(grouter.gossipChans)))) + for dest, gossipChan := range grouter.gossipChans { + if dest == sender { + continue + } + select { + case gossipChan <- gossipMessage{sender: sender, data: update}: + default: // drop the message if we cannot send it + common.Log.Errorf("Dropping message") + } + count-- + if count <= 0 { + break + } + } + return nil +} + func (grouter *TestRouter) Flush() { for _, gossipChan := range grouter.gossipChans { flushChan := make(chan struct{}) @@ -98,12 +122,18 @@ func (grouter *TestRouter) run(sender router.PeerName, gossiper router.Gossiper, continue } for _, msg := range message.data.Encode() { - // TODO: this should call OnGossipBroadcast, and we should implement - // 'trickle' gossip correctly in this mock. But no one depends on this - // difference for testing right now, so we abuse the interface here. + if _, err := gossiper.OnGossipBroadcast(message.sender, msg); err != nil { + panic(fmt.Sprintf("Error doing gossip broadcast: %s", err)) + } + } + case gossipMessage: + if rand.Float32() > (1.0 - grouter.loss) { + continue + } + for _, msg := range message.data.Encode() { diff, err := gossiper.OnGossip(msg) if err != nil { - panic(fmt.Sprintf("Error doing gossip broadcast: %s", err)) + panic(fmt.Sprintf("Error doing gossip: %s", err)) } if diff == nil { continue @@ -111,15 +141,16 @@ func (grouter *TestRouter) run(sender router.PeerName, gossiper router.Gossiper, // Sanity check - reconsuming the diff should yield nil for _, diffMsg := range diff.Encode() { if nextDiff, err := gossiper.OnGossip(diffMsg); err != nil { - panic(fmt.Sprintf("Error doing gossip broadcast: %s", err)) + panic(fmt.Sprintf("Error doing gossip: %s", err)) } else if nextDiff != nil { panic(fmt.Sprintf("Breach of gossip interface: %v != nil", nextDiff)) } } + grouter.gossip(message.sender, diff) } } case <-gossipTimer: - grouter.gossipBroadcast(sender, gossiper.Gossip()) + grouter.gossip(sender, gossiper.Gossip()) } } }