From f1fc09ccee7f10d98f554d9b02197f6177f3e768 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Wed, 17 Dec 2014 11:08:00 -0800 Subject: [PATCH] mocknet: printing internal mocknet state --- net/mock/interface.go | 26 ++++++++++++++++++++++++-- net/mock/mock_net.go | 36 +++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/net/mock/interface.go b/net/mock/interface.go index d09e41ef3..0f9855e5e 100644 --- a/net/mock/interface.go +++ b/net/mock/interface.go @@ -23,11 +23,10 @@ type Mocknet interface { Peers() []peer.Peer Net(peer.ID) inet.Network Nets() []inet.Network + Links() LinkMap LinksBetweenPeers(a, b peer.Peer) []Link LinksBetweenNets(a, b inet.Network) []Link - PrintLinkMap(io.Writer) - // Links are the **ability to connect**. // think of Links as the physical medium. // For p1 and p2 to connect, a link must exist between them. @@ -52,12 +51,19 @@ type Mocknet interface { DisconnectNets(inet.Network, inet.Network) error } +// LinkOptions are used to change aspects of the links. +// Sorry but they dont work yet :( type LinkOptions struct { Latency time.Duration Bandwidth int // in bytes-per-second // we can make these values distributions down the road. } +// Link represents the **possibility** of a connection between +// two peers. Think of it like physical network links. Without +// them, the peers can try and try but they won't be able to +// connect. This allows constructing topologies where specific +// nodes cannot talk to each other directly. :) type Link interface { Networks() []inet.Network Peers() []peer.Peer @@ -67,3 +73,19 @@ type Link interface { // Metrics() Metrics } + +// LinkMap is a 3D map to give us an easy way to track links. +// (wow, much map. so data structure. how compose. ahhh pointer) +type LinkMap map[string]map[string]map[Link]struct{} + +// Printer lets you inspect things :) +type Printer interface { + // MocknetLinks shows the entire Mocknet's link table :) + MocknetLinks(mn Mocknet) + NetworkConns(ni inet.Network) +} + +// PrinterTo returns a Printer ready to write to w. +func PrinterTo(w io.Writer) Printer { + return &printer{w} +} diff --git a/net/mock/mock_net.go b/net/mock/mock_net.go index dd6bc92ff..20a4dc0a2 100644 --- a/net/mock/mock_net.go +++ b/net/mock/mock_net.go @@ -2,7 +2,6 @@ package mocknet import ( "fmt" - "io" "sync" inet "github.com/jbenet/go-ipfs/net" @@ -120,6 +119,27 @@ func (mn *mocknet) Nets() []inet.Network { return cp } +// Links returns a copy of the internal link state map. +// (wow, much map. so data structure. how compose. ahhh pointer) +func (mn *mocknet) Links() LinkMap { + mn.RLock() + defer mn.RUnlock() + + links := map[string]map[string]map[Link]struct{}{} + for p1, lm := range mn.links { + sp1 := string(p1) + links[sp1] = map[string]map[Link]struct{}{} + for p2, ls := range lm { + sp2 := string(p2) + links[sp1][sp2] = map[Link]struct{}{} + for l := range ls { + links[sp1][sp2][l] = struct{}{} + } + } + } + return links +} + func (mn *mocknet) LinkAll() error { nets := mn.Nets() for _, n1 := range nets { @@ -309,17 +329,3 @@ func (mn *mocknet) LinkDefaults() LinkOptions { defer mn.RUnlock() return mn.linkDefaults } - -func (mn *mocknet) PrintLinkMap(w io.Writer) { - mn.RLock() - defer mn.RUnlock() - - fmt.Fprintf(w, "Mocknet link map:\n") - for p1, lm := range mn.links { - fmt.Fprintf(w, "\t%s linked to:\n", peer.ID(p1)) - for p2, l := range lm { - fmt.Fprintf(w, "\t\t%s (%d links)\n", peer.ID(p2), len(l)) - } - } - fmt.Fprintf(w, "\n") -}