From 4832ee76f3392273ab2c476516cbc65a74bdfc25 Mon Sep 17 00:00:00 2001 From: Peter Bourgon Date: Mon, 8 Jun 2015 15:51:02 +0200 Subject: [PATCH] Add the various ID constructors - Use constructors instead of ScopeDelim everywhere - Use constructors instead of IDDelim everywhere - IDDelim is renamed EdgeDelim, for clarity - Partial import of the new test fixtures, to be completed later --- app/mock_reporter_test.go | 38 ++++---- experimental/bridge/main.go | 2 +- experimental/demoprobe/generate.go | 21 +++-- experimental/genreport/generate.go | 21 +++-- probe/spy.go | 30 ++---- probe/spy_test.go | 37 ++------ report/fixture_test.go | 29 ++++++ report/id.go | 118 ++++++++++++++++++++--- report/id_test.go | 147 +++++++++++++++++++++++++++++ report/mapping_functions.go | 10 +- report/mapping_test.go | 4 +- report/report.go | 4 +- report/squash.go | 18 ++-- report/squash_test.go | 2 +- report/topology.go | 35 +++---- report/topology_test.go | 107 +++++++++++---------- xfer/collector_test.go | 2 +- 17 files changed, 432 insertions(+), 193 deletions(-) create mode 100644 report/fixture_test.go create mode 100644 report/id_test.go diff --git a/app/mock_reporter_test.go b/app/mock_reporter_test.go index c3740d0e5..d1076346b 100644 --- a/app/mock_reporter_test.go +++ b/app/mock_reporter_test.go @@ -18,34 +18,34 @@ func (s StaticReport) Report() report.Report { var testReport = report.Report{ Process: report.Topology{ Adjacency: report.Adjacency{ - "hostA|;192.168.1.1;12345": []string{";192.168.1.2;80"}, - "hostA|;192.168.1.1;12346": []string{";192.168.1.2;80"}, - "hostA|;192.168.1.1;8888": []string{";1.2.3.4;22"}, - "hostB|;192.168.1.2;80": []string{";192.168.1.1;12345"}, + report.MakeAdjacencyID("hostA", report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345")): report.NewIDList(report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")), + report.MakeAdjacencyID("hostA", report.MakeEndpointNodeID("hostA", "192.168.1.1", "12346")): report.NewIDList(report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")), + report.MakeAdjacencyID("hostA", report.MakeEndpointNodeID("hostA", "192.168.1.1", "8888")): report.NewIDList(report.MakeEndpointNodeID("", "1.2.3.4", "22")), + report.MakeAdjacencyID("hostB", report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")): report.NewIDList(report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345")), }, EdgeMetadatas: report.EdgeMetadatas{ - ";192.168.1.1;12345|;192.168.1.2;80": report.EdgeMetadata{ + report.MakeEdgeID(report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345"), report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")): report.EdgeMetadata{ WithBytes: true, BytesEgress: 12, BytesIngress: 0, WithConnCountTCP: true, MaxConnCountTCP: 200, }, - ";192.168.1.1;12346|;192.168.1.2;80": report.EdgeMetadata{ + report.MakeEdgeID(report.MakeEndpointNodeID("hostA", "192.168.1.1", "12346"), report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")): report.EdgeMetadata{ WithBytes: true, BytesEgress: 12, BytesIngress: 0, WithConnCountTCP: true, MaxConnCountTCP: 201, }, - ";192.168.1.1;8888|;1.2.3.4;80": report.EdgeMetadata{ + report.MakeEdgeID(report.MakeEndpointNodeID("hostA", "192.168.1.1", "8888"), report.MakeEndpointNodeID("", "1.2.3.4", "80")): report.EdgeMetadata{ WithBytes: true, BytesEgress: 200, BytesIngress: 0, WithConnCountTCP: true, MaxConnCountTCP: 202, }, - ";192.168.1.2;80|;192.168.1.1;12345": report.EdgeMetadata{ + report.MakeEdgeID(report.MakeEndpointNodeID("hostB", "192.168.1.2", "80"), report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345")): report.EdgeMetadata{ WithBytes: true, BytesEgress: 0, BytesIngress: 12, @@ -54,22 +54,22 @@ func (s StaticReport) Report() report.Report { }, }, NodeMetadatas: report.NodeMetadatas{ - ";192.168.1.1;12345": report.NodeMetadata{ + report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345"): report.NodeMetadata{ "pid": "23128", "name": "curl", "domain": "node-a.local", }, - ";192.168.1.1;12346": report.NodeMetadata{ // <-- same as :12345 + report.MakeEndpointNodeID("hostA", "192.168.1.1", "12346"): report.NodeMetadata{ // <-- same as :12345 "pid": "23128", "name": "curl", "domain": "node-a.local", }, - ";192.168.1.1;8888": report.NodeMetadata{ + report.MakeEndpointNodeID("hostA", "192.168.1.1", "8888"): report.NodeMetadata{ "pid": "55100", "name": "ssh", "domain": "node-a.local", }, - ";192.168.1.2;80": report.NodeMetadata{ + report.MakeEndpointNodeID("hostB", "192.168.1.2", "80"): report.NodeMetadata{ "pid": "215", "name": "apache", "domain": "node-b.local", @@ -79,25 +79,25 @@ func (s StaticReport) Report() report.Report { Network: report.Topology{ Adjacency: report.Adjacency{ - "hostA|;192.168.1.1": []string{";192.168.1.2", ";1.2.3.4"}, - "hostB|;192.168.1.2": []string{";192.168.1.1"}, + report.MakeAdjacencyID("hostA", report.MakeAddressNodeID("hostA", "192.168.1.1")): report.NewIDList(report.MakeAddressNodeID("hostB", "192.168.1.2"), report.MakeAddressNodeID("", "1.2.3.4")), + report.MakeAdjacencyID("hostB", report.MakeAddressNodeID("hostB", "192.168.1.2")): report.NewIDList(report.MakeAddressNodeID("hostA", "192.168.1.1")), }, EdgeMetadatas: report.EdgeMetadatas{ - ";192.168.1.1|;192.168.1.2": report.EdgeMetadata{ + report.MakeEdgeID(report.MakeAddressNodeID("hostA", "192.168.1.1"), report.MakeAddressNodeID("hostB", "192.168.1.2")): report.EdgeMetadata{ WithBytes: true, BytesEgress: 12, BytesIngress: 0, WithConnCountTCP: true, MaxConnCountTCP: 14, }, - ";192.168.1.1|;1.2.3.4": report.EdgeMetadata{ + report.MakeEdgeID(report.MakeAddressNodeID("hostA", "192.168.1.1"), report.MakeAddressNodeID("", "1.2.3.4")): report.EdgeMetadata{ WithBytes: true, BytesEgress: 200, BytesIngress: 0, WithConnCountTCP: true, MaxConnCountTCP: 15, }, - ";192.168.1.2|;192.168.1.1": report.EdgeMetadata{ + report.MakeEdgeID(report.MakeAddressNodeID("hostB", "192.168.1.2"), report.MakeAddressNodeID("hostA", "192.168.1.1")): report.EdgeMetadata{ WithBytes: true, BytesEgress: 0, BytesIngress: 12, @@ -106,10 +106,10 @@ func (s StaticReport) Report() report.Report { }, }, NodeMetadatas: report.NodeMetadatas{ - ";192.168.1.1": report.NodeMetadata{ + report.MakeAddressNodeID("hostA", "192.168.1.1"): report.NodeMetadata{ "name": "host-a", }, - ";192.168.1.2": report.NodeMetadata{ + report.MakeAddressNodeID("hostB", "192.168.1.2"): report.NodeMetadata{ "name": "host-b", }, }, diff --git a/experimental/bridge/main.go b/experimental/bridge/main.go index 5d6856bb2..4d27bd1a6 100644 --- a/experimental/bridge/main.go +++ b/experimental/bridge/main.go @@ -132,7 +132,7 @@ func discover(c collector, p publisher, fixed []string) { for _, adjacent := range r.Network.Adjacency { for _, a := range adjacent { - ip := report.AddressIP(a) // address id -> IP + ip := report.AddressIDAddresser(a) // address id -> IP if ip == nil { continue } diff --git a/experimental/demoprobe/generate.go b/experimental/demoprobe/generate.go index 0a7039753..20d6e6520 100644 --- a/experimental/demoprobe/generate.go +++ b/experimental/demoprobe/generate.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "net" + "strconv" "time" "github.com/weaveworks/scope/report" @@ -56,14 +57,14 @@ func DemoReport(nodeCount int) report.Report { src = hosts[rand.Intn(len(hosts))] dst = hosts[rand.Intn(len(hosts))] srcPort = rand.Intn(50000) + 10000 - srcPortID = fmt.Sprintf("%s%s%s%d", report.ScopeDelim, src, report.ScopeDelim, srcPort) - dstPortID = fmt.Sprintf("%s%s%s%d", report.ScopeDelim, dst, report.ScopeDelim, c.dstPort) - srcID = "hostX" + report.IDDelim + srcPortID - dstID = "hostX" + report.IDDelim + dstPortID - srcAddressID = fmt.Sprintf("%s%s", report.ScopeDelim, src) - dstAddressID = fmt.Sprintf("%s%s", report.ScopeDelim, dst) - nodeSrcAddressID = "hostX" + report.IDDelim + srcAddressID - nodeDstAddressID = "hostX" + report.IDDelim + dstAddressID + srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort)) + dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort)) + srcID = report.MakeAdjacencyID("hostX", srcPortID) + dstID = report.MakeAdjacencyID("hostX", dstPortID) + srcAddressID = report.MakeAddressNodeID("", src) + dstAddressID = report.MakeAddressNodeID("", dst) + nodeSrcAddressID = report.MakeAdjacencyID("hostX", srcAddressID) + nodeDstAddressID = report.MakeAdjacencyID("hostX", dstAddressID) ) // Process topology @@ -84,8 +85,8 @@ func DemoReport(nodeCount int) report.Report { } r.Process.Adjacency[dstID] = r.Process.Adjacency[dstID].Add(srcPortID) var ( - edgeKeyEgress = srcPortID + report.IDDelim + dstPortID - edgeKeyIngress = dstPortID + report.IDDelim + srcPortID + edgeKeyEgress = report.MakeEdgeID(srcPortID, dstPortID) + edgeKeyIngress = report.MakeEdgeID(dstPortID, srcPortID) ) r.Process.EdgeMetadatas[edgeKeyEgress] = report.EdgeMetadata{ WithConnCountTCP: true, diff --git a/experimental/genreport/generate.go b/experimental/genreport/generate.go index 79308416e..5bf0d50d4 100644 --- a/experimental/genreport/generate.go +++ b/experimental/genreport/generate.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "net" + "strconv" "time" "github.com/weaveworks/scope/report" @@ -56,14 +57,14 @@ func DemoReport(nodeCount int) report.Report { src = hosts[rand.Intn(len(hosts))] dst = hosts[rand.Intn(len(hosts))] srcPort = rand.Intn(50000) + 10000 - srcPortID = fmt.Sprintf("%s%s%s%d", report.ScopeDelim, src, report.ScopeDelim, srcPort) - dstPortID = fmt.Sprintf("%s%s%s%d", report.ScopeDelim, dst, report.ScopeDelim, c.dstPort) - srcID = "hostX" + report.IDDelim + srcPortID - dstID = "hostX" + report.IDDelim + dstPortID - srcAddressID = fmt.Sprintf("%s%s", report.ScopeDelim, src) - dstAddressID = fmt.Sprintf("%s%s", report.ScopeDelim, dst) - nodeSrcAddressID = "hostX" + report.IDDelim + srcAddressID - nodeDstAddressID = "hostX" + report.IDDelim + dstAddressID + srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort)) + dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort)) + srcID = report.MakeAdjacencyID("hostX", srcPortID) + dstID = report.MakeAdjacencyID("hostX", dstPortID) + srcAddressID = report.MakeAddressNodeID("", src) + dstAddressID = report.MakeAddressNodeID("", dst) + nodeSrcAddressID = report.MakeAdjacencyID("hostX", srcAddressID) + nodeDstAddressID = report.MakeAdjacencyID("hostX", dstAddressID) ) // Process topology @@ -84,8 +85,8 @@ func DemoReport(nodeCount int) report.Report { } r.Process.Adjacency[dstID] = r.Process.Adjacency[dstID].Add(srcPortID) var ( - edgeKeyEgress = srcPortID + report.IDDelim + dstPortID - edgeKeyIngress = dstPortID + report.IDDelim + srcPortID + edgeKeyEgress = report.MakeEdgeID(srcPortID, dstPortID) + edgeKeyIngress = report.MakeEdgeID(dstPortID, srcPortID) ) r.Process.EdgeMetadatas[edgeKeyEgress] = report.EdgeMetadata{ WithConnCountTCP: true, diff --git a/probe/spy.go b/probe/spy.go index 5d40a2bd4..c77700c46 100644 --- a/probe/spy.go +++ b/probe/spy.go @@ -3,7 +3,6 @@ package main import ( "fmt" "log" - "net" "strconv" "time" @@ -44,10 +43,10 @@ func addConnection( hostID, hostName string, ) { var ( - scopedLocal = scopedIP(hostID, c.LocalAddress) - scopedRemote = scopedIP(hostID, c.RemoteAddress) - key = hostID + report.IDDelim + scopedLocal - edgeKey = scopedLocal + report.IDDelim + scopedRemote + scopedLocal = report.MakeAddressNodeID(hostID, c.LocalAddress.String()) + scopedRemote = report.MakeAddressNodeID(hostID, c.RemoteAddress.String()) + key = report.MakeAdjacencyID(hostID, scopedLocal) + edgeKey = report.MakeEdgeID(scopedLocal, scopedRemote) ) r.Network.Adjacency[key] = r.Network.Adjacency[key].Add(scopedRemote) @@ -66,10 +65,10 @@ func addConnection( if c.Proc.PID > 0 { var ( - scopedLocal = scopedIPPort(hostID, c.LocalAddress, c.LocalPort) - scopedRemote = scopedIPPort(hostID, c.RemoteAddress, c.RemotePort) - key = hostID + report.IDDelim + scopedLocal - edgeKey = scopedLocal + report.IDDelim + scopedRemote + scopedLocal = report.MakeEndpointNodeID(hostID, c.LocalAddress.String(), strconv.Itoa(int(c.LocalPort))) + scopedRemote = report.MakeEndpointNodeID(hostID, c.RemoteAddress.String(), strconv.Itoa(int(c.RemotePort))) + key = report.MakeAdjacencyID(hostID, scopedLocal) + edgeKey = report.MakeEdgeID(scopedLocal, scopedRemote) ) r.Process.Adjacency[key] = r.Process.Adjacency[key].Add(scopedRemote) @@ -91,16 +90,3 @@ func addConnection( r.Process.EdgeMetadatas[edgeKey] = edgeMeta } } - -// scopedIP makes an IP unique over multiple networks. -func scopedIP(scope string, ip net.IP) string { - if ip.IsLoopback() { - return scope + report.ScopeDelim + ip.String() - } - return report.ScopeDelim + ip.String() -} - -// scopedIPPort makes an IP+port tuple unique over multiple networks. -func scopedIPPort(scope string, ip net.IP, port uint16) string { - return scopedIP(scope, ip) + report.ScopeDelim + strconv.FormatUint(uint64(port), 10) -} diff --git a/probe/spy_test.go b/probe/spy_test.go index 04f5319e8..b9d3e65d1 100644 --- a/probe/spy_test.go +++ b/probe/spy_test.go @@ -9,23 +9,6 @@ import ( "github.com/weaveworks/scope/report" ) -func TestScopedIP(t *testing.T) { - const scope = "my-scope" - - for ip, want := range map[string]string{ - "1.2.3.4": report.ScopeDelim + "1.2.3.4", - "192.168.1.2": report.ScopeDelim + "192.168.1.2", - "127.0.0.1": scope + report.ScopeDelim + "127.0.0.1", // loopback - "::1": scope + report.ScopeDelim + "::1", // loopback - "fd00::451b:b714:85da:489e": report.ScopeDelim + "fd00::451b:b714:85da:489e", // global address - "fe80::82ee:73ff:fe83:588f": report.ScopeDelim + "fe80::82ee:73ff:fe83:588f", // link-local address - } { - if have := scopedIP(scope, net.ParseIP(ip)); have != want { - t.Errorf("%q: have %q, want %q", ip, have, want) - } - } -} - var ( fixLocalAddress = net.ParseIP("192.168.1.1") fixLocalPort = uint16(80) @@ -83,8 +66,8 @@ func TestSpyNetwork(t *testing.T) { procspy.SetFixtures(fixConnections) const ( - nodeID = "heinz-tomato-ketchup" - nodeName = "frenchs-since-1904" + nodeID = "heinz-tomato-ketchup" // TODO rename to hostID + nodeName = "frenchs-since-1904" // TODO rename to hostNmae ) r := spy(nodeID, nodeName, false) @@ -97,9 +80,9 @@ func TestSpyNetwork(t *testing.T) { } var ( - scopedLocal = scopedIP(nodeID, fixLocalAddress) - scopedRemote = scopedIP(nodeID, fixRemoteAddress) - localKey = nodeID + report.IDDelim + scopedLocal + scopedLocal = report.MakeAddressNodeID(nodeID, fixLocalAddress.String()) + scopedRemote = report.MakeAddressNodeID(nodeID, fixRemoteAddress.String()) + localKey = report.MakeAdjacencyID(nodeID, scopedLocal) ) if want, have := 1, len(r.Network.Adjacency[localKey]); want != have { @@ -119,17 +102,17 @@ func TestSpyProcess(t *testing.T) { procspy.SetFixtures(fixConnectionsWithProcesses) const ( - nodeID = "nikon" - nodeName = "fishermans-friend" + nodeID = "nikon" // TODO rename to hostID + nodeName = "fishermans-friend" // TODO rename to hostNmae ) r := spy(nodeID, nodeName, true) // buf, _ := json.MarshalIndent(r, "", " ") ; t.Logf("\n%s\n", buf) var ( - scopedLocal = scopedIPPort(nodeID, fixLocalAddress, fixLocalPort) - scopedRemote = scopedIPPort(nodeID, fixRemoteAddress, fixRemotePort) - localKey = nodeID + report.IDDelim + scopedLocal + scopedLocal = report.MakeEndpointNodeID(nodeID, fixLocalAddress.String(), strconv.Itoa(int(fixLocalPort))) + scopedRemote = report.MakeEndpointNodeID(nodeID, fixRemoteAddress.String(), strconv.Itoa(int(fixRemotePort))) + localKey = report.MakeAdjacencyID(nodeID, scopedLocal) ) if want, have := 1, len(r.Process.Adjacency[localKey]); want != have { diff --git a/report/fixture_test.go b/report/fixture_test.go new file mode 100644 index 000000000..9aa92c23f --- /dev/null +++ b/report/fixture_test.go @@ -0,0 +1,29 @@ +package report_test + +import ( + "github.com/weaveworks/scope/report" +) + +var ( + clientHostID = "client.host.com" + clientHostName = clientHostID + clientHostNodeID = report.MakeHostNodeID(clientHostID) + clientAddress = "10.10.10.20" + serverHostID = "server.host.com" + serverHostName = serverHostID + serverHostNodeID = report.MakeHostNodeID(serverHostID) + serverAddress = "10.10.10.1" + unknownHostID = "" // by definition, we don't know it + unknownAddress = "172.16.93.112" // will be a pseudonode, no corresponding host + + client54001EndpointNodeID = report.MakeEndpointNodeID(clientHostID, clientAddress, "54001") // i.e. curl + client54002EndpointNodeID = report.MakeEndpointNodeID(clientHostID, clientAddress, "54002") // also curl + server80EndpointNodeID = report.MakeEndpointNodeID(serverHostID, serverAddress, "80") // i.e. apache + unknown1EndpointNodeID = report.MakeEndpointNodeID(unknownHostID, unknownAddress, "10001") + unknown2EndpointNodeID = report.MakeEndpointNodeID(unknownHostID, unknownAddress, "10002") + unknown3EndpointNodeID = report.MakeEndpointNodeID(unknownHostID, unknownAddress, "10003") + + clientAddressNodeID = report.MakeAddressNodeID(clientHostID, clientAddress) + serverAddressNodeID = report.MakeAddressNodeID(serverHostID, serverAddress) + unknownAddressNodeID = report.MakeAddressNodeID(unknownHostID, unknownAddress) +) diff --git a/report/id.go b/report/id.go index 20f48c2be..f53644e6e 100644 --- a/report/id.go +++ b/report/id.go @@ -1,29 +1,117 @@ package report import ( + "fmt" "net" "strings" ) -// IDAddresser is used to get the IP address from an addressID. Or nil. +// TheInternet is used as a node ID to indicate a remote IP. +const TheInternet = "theinternet" + +// Delimiters are used to separate parts of node IDs, to guarantee uniqueness +// in particular contexts. +const ( + // ScopeDelim is a general-purpose delimiter used within node IDs to + // separate different contextual scopes. Different topologies have + // different key structures. + ScopeDelim = ";" + + // EdgeDelim separates two node IDs when they need to exist in the same key. + // Concretely, it separates node IDs in keys that represent edges. + EdgeDelim = "|" +) + +// MakeAdjacencyID produces an adjacency ID from composite parts. +func MakeAdjacencyID(hostID, srcNodeID string) string { + // Here we rely on the fact that every possible source node ID has the + // host ID as the first scope-delimited field, and therefore don't + // duplicate that information. + return ">" + srcNodeID +} + +// ParseAdjacencyID splits an adjacency ID to its composite parts. +func ParseAdjacencyID(adjacencyID string) (hostID, srcNodeID string, ok bool) { + if !strings.HasPrefix(adjacencyID, ">") { + return "", "", false + } + // This relies on every node ID having hostID as its first scoped field. + adjacencyID = adjacencyID[1:] + fields := strings.SplitN(adjacencyID, ScopeDelim, 2) + if len(fields) != 2 { + return "", "", false + } + return fields[0], adjacencyID, true +} + +// MakeEdgeID produces an edge ID from composite parts. +func MakeEdgeID(srcNodeID, dstNodeID string) string { + return srcNodeID + EdgeDelim + dstNodeID +} + +// ParseEdgeID splits an edge ID to its composite parts. +func ParseEdgeID(edgeID string) (srcNodeID, dstNodeID string, ok bool) { + fields := strings.SplitN(edgeID, EdgeDelim, 2) + if len(fields) != 2 { + return "", "", false + } + return fields[0], fields[1], true +} + +// MakeEndpointNodeID produces an endpoint node ID from its composite parts. +func MakeEndpointNodeID(hostID, address, port string) string { + return MakeAddressNodeID(hostID, address) + ScopeDelim + port +} + +// MakeAddressNodeID produces an address node ID from its composite parts. +func MakeAddressNodeID(hostID, address string) string { + return hostID + ScopeDelim + address +} + +// MakeProcessNodeID produces a process node ID from its composite parts. +func MakeProcessNodeID(hostID, pid string) string { + return hostID + ScopeDelim + pid +} + +// MakeHostNodeID produces a host node ID from its composite parts. +func MakeHostNodeID(hostID string) string { + // hostIDs come from the probe and are presumed to be globally-unique. + // But, suffix something to elicit failures if we try to use probe host + // IDs directly as node IDs in the host topology. + return hostID + ScopeDelim + "" +} + +// MakePseudoNodeID produces a pseudo node ID from its composite parts. +func MakePseudoNodeID(parts ...string) string { + return strings.Join(append([]string{"pseudo"}, parts...), ScopeDelim) +} + +// IDAddresser tries to convert a node ID to a net.IP, if possible. type IDAddresser func(string) net.IP -// AddressIPPort translates "scope;ip;port" to the IP address. These are used -// by Process topologies. -func AddressIPPort(id string) net.IP { - parts := strings.SplitN(id, ScopeDelim, 3) - if len(parts) != 3 { - return nil // hmm +// EndpointIDAddresser converts an endpoint node ID to an IP. +func EndpointIDAddresser(id string) net.IP { + fields := strings.SplitN(id, ScopeDelim, 3) + if len(fields) != 3 { + //log.Printf("EndpointIDAddresser: bad input %q", id) + return nil } - return net.ParseIP(parts[1]) + return net.ParseIP(fields[1]) } -// AddressIP translates "scope;ip" to the IP address. These are used by -// Network topologies. -func AddressIP(id string) net.IP { - parts := strings.SplitN(id, ScopeDelim, 2) - if len(parts) != 2 { - return nil // hmm +// AddressIDAddresser converts an address node ID to an IP. +func AddressIDAddresser(id string) net.IP { + fields := strings.SplitN(id, ScopeDelim, 2) + if len(fields) != 2 { + //log.Printf("AddressIDAddresser: bad input %q", id) + return nil } - return net.ParseIP(parts[1]) + return net.ParseIP(fields[1]) +} + +// PanicIDAddresser will panic if it's ever called. It's used in topologies +// where there are never any edges, and so it's nonsensical to try and extract +// IPs from the node IDs. +func PanicIDAddresser(id string) net.IP { + panic(fmt.Sprintf("PanicIDAddresser called on %q", id)) } diff --git a/report/id_test.go b/report/id_test.go new file mode 100644 index 000000000..ab8a10e14 --- /dev/null +++ b/report/id_test.go @@ -0,0 +1,147 @@ +package report_test + +import ( + "net" + "reflect" + "testing" + + "github.com/weaveworks/scope/report" +) + +func TestAdjacencyID(t *testing.T) { + for _, bad := range []string{ + client54001EndpointNodeID, + client54002EndpointNodeID, + unknown1EndpointNodeID, + unknown2EndpointNodeID, + unknown3EndpointNodeID, + clientAddressNodeID, + serverAddressNodeID, + unknownAddressNodeID, + clientHostNodeID, + serverHostNodeID, + ">1.2.3.4", + ">", + ";", + "", + } { + if hostID, srcNodeID, ok := report.ParseAdjacencyID(bad); ok { + t.Errorf("%q: expected failure, but got (%q, %q)", bad, hostID, srcNodeID) + } + } + + for input, want := range map[string]struct{ hostID, srcNodeID string }{ + report.MakeAdjacencyID("a", report.MakeEndpointNodeID("a", "b", "c")): {"a", report.MakeEndpointNodeID("a", "b", "c")}, + report.MakeAdjacencyID("a", report.MakeAddressNodeID("a", "b")): {"a", report.MakeAddressNodeID("a", "b")}, + report.MakeAdjacencyID("a", report.MakeProcessNodeID("a", "b")): {"a", report.MakeProcessNodeID("a", "b")}, + report.MakeAdjacencyID("a", report.MakeHostNodeID("a")): {"a", report.MakeHostNodeID("a")}, + ">host.com;1.2.3.4": {"host.com", "host.com;1.2.3.4"}, + ">a;b;c": {"a", "a;b;c"}, + ">a;b": {"a", "a;b"}, + ">a;": {"a", "a;"}, + ">;b": {"", ";b"}, + ">;": {"", ";"}, + } { + hostID, srcNodeID, ok := report.ParseAdjacencyID(input) + if !ok { + t.Errorf("%q: not OK", input) + continue + } + if want, have := want.hostID, hostID; want != have { + t.Errorf("%q: want %q, have %q", input, want, have) + } + if want, have := want.srcNodeID, srcNodeID; want != have { + t.Errorf("%q: want %q, have %q", input, want, have) + } + } +} + +func TestEdgeID(t *testing.T) { + for _, bad := range []string{ + client54001EndpointNodeID, + client54002EndpointNodeID, + unknown1EndpointNodeID, + unknown2EndpointNodeID, + unknown3EndpointNodeID, + clientAddressNodeID, + serverAddressNodeID, + unknownAddressNodeID, + clientHostNodeID, + serverHostNodeID, + ">1.2.3.4", + ">", + ";", + "", + } { + if srcNodeID, dstNodeID, ok := report.ParseEdgeID(bad); ok { + t.Errorf("%q: expected failure, but got (%q, %q)", bad, srcNodeID, dstNodeID) + } + } + + for input, want := range map[string]struct{ srcNodeID, dstNodeID string }{ + report.MakeEdgeID("a", report.MakeEndpointNodeID("a", "b", "c")): {"a", report.MakeEndpointNodeID("a", "b", "c")}, + report.MakeEdgeID("a", report.MakeAddressNodeID("a", "b")): {"a", report.MakeAddressNodeID("a", "b")}, + report.MakeEdgeID("a", report.MakeProcessNodeID("a", "b")): {"a", report.MakeProcessNodeID("a", "b")}, + report.MakeEdgeID("a", report.MakeHostNodeID("a")): {"a", report.MakeHostNodeID("a")}, + "host.com|1.2.3.4": {"host.com", "1.2.3.4"}, + "a|b;c": {"a", "b;c"}, + "a|b": {"a", "b"}, + "a|": {"a", ""}, + "|b": {"", "b"}, + "|": {"", ""}, + } { + srcNodeID, dstNodeID, ok := report.ParseEdgeID(input) + if !ok { + t.Errorf("%q: not OK", input) + continue + } + if want, have := want.srcNodeID, srcNodeID; want != have { + t.Errorf("%q: want %q, have %q", input, want, have) + } + if want, have := want.dstNodeID, dstNodeID; want != have { + t.Errorf("%q: want %q, have %q", input, want, have) + } + } +} + +func TestEndpointIDAddresser(t *testing.T) { + if nodeID := "1.2.4.5"; report.EndpointIDAddresser(nodeID) != nil { + t.Errorf("%q: bad node ID parsed as good", nodeID) + } + var ( + nodeID = report.MakeEndpointNodeID(clientHostID, clientAddress, "12345") + want = net.ParseIP(clientAddress) + have = report.EndpointIDAddresser(nodeID) + ) + if !reflect.DeepEqual(want, have) { + t.Errorf("want %s, have %s", want, have) + } +} + +func TestAddressIDAddresser(t *testing.T) { + if nodeID := "1.2.4.5"; report.AddressIDAddresser(nodeID) != nil { + t.Errorf("%q: bad node ID parsed as good", nodeID) + } + var ( + nodeID = report.MakeAddressNodeID(clientHostID, clientAddress) + want = net.ParseIP(clientAddress) + have = report.AddressIDAddresser(nodeID) + ) + if !reflect.DeepEqual(want, have) { + t.Errorf("want %s, have %s", want, have) + } +} + +func TestPanicIDAddresser(t *testing.T) { + if panicked := func() (recovered bool) { + defer func() { + if r := recover(); r != nil { + recovered = true + } + }() + report.PanicIDAddresser("irrelevant") + return false + }(); !panicked { + t.Errorf("expected panic, didn't get it") + } +} diff --git a/report/mapping_functions.go b/report/mapping_functions.go index e04024ebc..1baae3f6c 100644 --- a/report/mapping_functions.go +++ b/report/mapping_functions.go @@ -151,7 +151,7 @@ func GenericPseudoNode(src string, srcMapped RenderableNode, dst string) (Mapped srcNodeAddr, srcNodePort := trySplitAddr(src) dstNodeAddr, _ := trySplitAddr(dst) - outputID = strings.Join([]string{"pseudo:", dstNodeAddr, srcNodeAddr, srcNodePort}, ScopeDelim) + outputID = MakePseudoNodeID(dstNodeAddr, srcNodeAddr, srcNodePort) maj, min = dstNodeAddr, "" } @@ -174,7 +174,7 @@ func GenericGroupedPseudoNode(src string, srcMapped RenderableNode, dst string) // When grouping, emit one pseudo node per (srcNodeAddress, dstNodeAddr) dstNodeAddr, _ := trySplitAddr(dst) - outputID = strings.Join([]string{"pseudo:", dstNodeAddr, srcMapped.ID}, ScopeDelim) + outputID = MakePseudoNodeID(dstNodeAddr, srcMapped.ID) maj, min = dstNodeAddr, "" } @@ -193,6 +193,12 @@ func InternetOnlyPseudoNode(_ string, _ RenderableNode, dst string) (MappedNode, return MappedNode{}, false } +// trySplitAddr is basically ParseArbitraryNodeID, since its callsites +// (pseudo funcs) just have opaque node IDs and don't know what topology they +// come from. Without changing how pseudo funcs work, we can't make it much +// smarter. +// +// TODO change how pseudofuncs work, and eliminate this helper. func trySplitAddr(addr string) (string, string) { fields := strings.SplitN(addr, ScopeDelim, 3) if len(fields) == 3 { diff --git a/report/mapping_test.go b/report/mapping_test.go index c413fa62f..67f59fb24 100644 --- a/report/mapping_test.go +++ b/report/mapping_test.go @@ -15,7 +15,7 @@ func TestUngroupedMapping(t *testing.T) { }{ { f: NetworkHostname, - id: ScopeDelim + "1.2.3.4", + id: MakeAddressNodeID("", "1.2.3.4"), meta: NodeMetadata{ "name": "my.host", }, @@ -27,7 +27,7 @@ func TestUngroupedMapping(t *testing.T) { }, { f: NetworkHostname, - id: ScopeDelim + "1.2.3.4", + id: MakeAddressNodeID("", "1.2.3.4"), meta: NodeMetadata{ "name": "localhost", }, diff --git a/report/report.go b/report/report.go index 6d2b33b03..d7a655fef 100644 --- a/report/report.go +++ b/report/report.go @@ -93,8 +93,8 @@ func MakeReport() Report { func (r Report) SquashRemote() Report { localNets := r.HostMetadatas.LocalNets() return Report{ - Process: Squash(r.Process, AddressIPPort, localNets), - Network: Squash(r.Network, AddressIP, localNets), + Process: Squash(r.Process, EndpointIDAddresser, localNets), + Network: Squash(r.Network, AddressIDAddresser, localNets), HostMetadatas: r.HostMetadatas, } } diff --git a/report/squash.go b/report/squash.go index 3c6e46bd2..a25158d45 100644 --- a/report/squash.go +++ b/report/squash.go @@ -1,14 +1,8 @@ package report import ( + "log" "net" - "strings" -) - -const ( - // TheInternet is the ID that we assign to the super-node composed of all - // remote nodes that have been squashed together. - TheInternet = "theinternet" ) // Squash takes a Topology, and folds all remote nodes into a supernode. @@ -34,9 +28,13 @@ func Squash(t Topology, f IDAddresser, localNets []*net.IPNet) Topology { // Edge metadata keys are "|". If the dst node // ID is remote, rename it to TheInternet. for key, metadata := range t.EdgeMetadatas { - parts := strings.SplitN(key, IDDelim, 2) - if ip := f(parts[1]); ip != nil && isRemote(ip) { - key = parts[0] + IDDelim + TheInternet + srcNodeID, dstNodeID, ok := ParseEdgeID(key) + if !ok { + log.Printf("bad edge ID %q", key) + continue + } + if ip := f(dstNodeID); ip != nil && isRemote(ip) { + key = MakeEdgeID(srcNodeID, TheInternet) } // Could be we're merging two keys into one now. diff --git a/report/squash_test.go b/report/squash_test.go index 2e5cf4aba..4dd732f4f 100644 --- a/report/squash_test.go +++ b/report/squash_test.go @@ -166,7 +166,7 @@ func TestSquashTopology(t *testing.T) { NodeMetadatas: reportToSquash().Process.NodeMetadatas, } - have := Squash(reportToSquash().Process, AddressIPPort, reportToSquash().HostMetadatas.LocalNets()) + have := Squash(reportToSquash().Process, EndpointIDAddresser, reportToSquash().HostMetadatas.LocalNets()) if !reflect.DeepEqual(want, have) { t.Errorf("want\n\t%#v, have\n\t%#v", want, have) } diff --git a/report/topology.go b/report/topology.go index 0836e0292..50affeb0a 100644 --- a/report/topology.go +++ b/report/topology.go @@ -1,20 +1,11 @@ package report import ( + "log" "reflect" - "strings" ) -const ( - // ScopeDelim separates the scope portion of an address from the address - // string itself. - ScopeDelim = ";" - - // IDDelim separates fields in a node ID. - IDDelim = "|" - - localUnknown = "localUnknown" -) +const localUnknown = "localUnknown" // Topology describes a specific view of a network. It consists of nodes and // edges, represented by Adjacency, and metadata about those nodes and edges, @@ -122,12 +113,14 @@ func (t Topology) RenderBy(mapFunc MapFunc, pseudoFunc PseudoFunc) map[string]Re // Walk the graph and make connections. for src, dsts := range t.Adjacency { var ( - fields = strings.SplitN(src, IDDelim, 2) // "|
" - srcOriginHostID = fields[0] - srcNodeAddress = fields[1] - srcRenderableID = address2mapped[srcNodeAddress] // must exist - srcRenderableNode = nodes[srcRenderableID] // must exist + srcOriginHostID, srcNodeAddress, ok = ParseAdjacencyID(src) + srcRenderableID = address2mapped[srcNodeAddress] // must exist + srcRenderableNode = nodes[srcRenderableID] // must exist ) + if !ok { + log.Printf("bad adjacency ID %q", src) + continue + } for _, dstNodeAddress := range dsts { dstRenderableID, ok := address2mapped[dstNodeAddress] @@ -150,7 +143,7 @@ func (t Topology) RenderBy(mapFunc MapFunc, pseudoFunc PseudoFunc) map[string]Re srcRenderableNode.Adjacency = srcRenderableNode.Adjacency.Add(dstRenderableID) srcRenderableNode.OriginHosts = srcRenderableNode.OriginHosts.Add(srcOriginHostID) srcRenderableNode.OriginNodes = srcRenderableNode.OriginNodes.Add(srcNodeAddress) - edgeID := srcNodeAddress + IDDelim + dstNodeAddress + edgeID := MakeEdgeID(srcNodeAddress, dstNodeAddress) if md, ok := t.EdgeMetadatas[edgeID]; ok { srcRenderableNode.Metadata.Merge(md.Transform()) } @@ -169,13 +162,15 @@ func (t Topology) RenderBy(mapFunc MapFunc, pseudoFunc PseudoFunc) map[string]Re func (t Topology) EdgeMetadata(mapFunc MapFunc, srcRenderableID, dstRenderableID string) EdgeMetadata { metadata := EdgeMetadata{} for edgeID, edgeMeta := range t.EdgeMetadatas { - edgeParts := strings.SplitN(edgeID, IDDelim, 2) - src := edgeParts[0] + src, dst, ok := ParseEdgeID(edgeID) + if !ok { + log.Printf("bad edge ID %q", edgeID) + continue + } if src != TheInternet { mapped, _ := mapFunc(src, t.NodeMetadatas[src]) src = mapped.ID } - dst := edgeParts[1] if dst != TheInternet { mapped, _ := mapFunc(dst, t.NodeMetadatas[dst]) dst = mapped.ID diff --git a/report/topology_test.go b/report/topology_test.go index 9a6d8ff26..8d17dcaad 100644 --- a/report/topology_test.go +++ b/report/topology_test.go @@ -13,27 +13,32 @@ func init() { spew.Config.SortKeys = true // :\ } -const ( - client54001 = ScopeDelim + "10.10.10.20" + ScopeDelim + "54001" // curl (1) - client54002 = ScopeDelim + "10.10.10.20" + ScopeDelim + "54002" // curl (2) - unknownClient1 = ScopeDelim + "10.10.10.10" + ScopeDelim + "54010" // we want to ensure two unknown clients, connnected - unknownClient2 = ScopeDelim + "10.10.10.10" + ScopeDelim + "54020" // to the same server, are deduped. - unknownClient3 = ScopeDelim + "10.10.10.11" + ScopeDelim + "54020" // Check this one isn't deduped - server80 = ScopeDelim + "192.168.1.1" + ScopeDelim + "80" // apache +var ( + clientHostID = "client.hostname.com" + serverHostID = "server.hostname.com" + randomHostID = "random.hostname.com" + unknownHostID = "" - clientIP = ScopeDelim + "10.10.10.20" - serverIP = ScopeDelim + "192.168.1.1" - randomIP = ScopeDelim + "172.16.11.9" // only in Network topology - unknownIP = ScopeDelim + "10.10.10.10" + client54001 = MakeEndpointNodeID(clientHostID, "10.10.10.20", "54001") // curl (1) + client54002 = MakeEndpointNodeID(clientHostID, "10.10.10.20", "54002") // curl (2) + unknownClient1 = MakeEndpointNodeID(serverHostID, "10.10.10.10", "54010") // we want to ensure two unknown clients, connnected + unknownClient2 = MakeEndpointNodeID(serverHostID, "10.10.10.10", "54020") // to the same server, are deduped. + unknownClient3 = MakeEndpointNodeID(serverHostID, "10.10.10.11", "54020") // Check this one isn't deduped + server80 = MakeEndpointNodeID(serverHostID, "192.168.1.1", "80") // apache + + clientIP = MakeAddressNodeID(clientHostID, "10.10.10.20") + serverIP = MakeAddressNodeID(serverHostID, "192.168.1.1") + randomIP = MakeAddressNodeID(randomHostID, "172.16.11.9") // only in Network topology + unknownIP = MakeAddressNodeID(unknownHostID, "10.10.10.10") ) var ( report = Report{ Process: Topology{ Adjacency: Adjacency{ - "client.hostname.com" + IDDelim + client54001: NewIDList(server80), - "client.hostname.com" + IDDelim + client54002: NewIDList(server80), - "server.hostname.com" + IDDelim + server80: NewIDList(client54001, client54002, unknownClient1, unknownClient2, unknownClient3), + MakeAdjacencyID("client.hostname.com", client54001): NewIDList(server80), + MakeAdjacencyID("client.hostname.com", client54002): NewIDList(server80), + MakeAdjacencyID("server.hostname.com", server80): NewIDList(client54001, client54002, unknownClient1, unknownClient2, unknownClient3), }, NodeMetadatas: NodeMetadatas{ // NodeMetadata is arbitrary. We're free to put only precisely what we @@ -56,38 +61,38 @@ var ( }, }, EdgeMetadatas: EdgeMetadatas{ - client54001 + IDDelim + server80: EdgeMetadata{ + MakeEdgeID(client54001, server80): EdgeMetadata{ WithBytes: true, BytesIngress: 100, BytesEgress: 10, }, - client54002 + IDDelim + server80: EdgeMetadata{ + MakeEdgeID(client54002, server80): EdgeMetadata{ WithBytes: true, BytesIngress: 200, BytesEgress: 20, }, - server80 + IDDelim + client54001: EdgeMetadata{ + MakeEdgeID(server80, client54001): EdgeMetadata{ WithBytes: true, BytesIngress: 10, BytesEgress: 100, }, - server80 + IDDelim + client54002: EdgeMetadata{ + MakeEdgeID(server80, client54002): EdgeMetadata{ WithBytes: true, BytesIngress: 20, BytesEgress: 200, }, - server80 + IDDelim + unknownClient1: EdgeMetadata{ + MakeEdgeID(server80, unknownClient1): EdgeMetadata{ WithBytes: true, BytesIngress: 30, BytesEgress: 300, }, - server80 + IDDelim + unknownClient2: EdgeMetadata{ + MakeEdgeID(server80, unknownClient2): EdgeMetadata{ WithBytes: true, BytesIngress: 40, BytesEgress: 400, }, - server80 + IDDelim + unknownClient3: EdgeMetadata{ + MakeEdgeID(server80, unknownClient3): EdgeMetadata{ WithBytes: true, BytesIngress: 50, BytesEgress: 500, @@ -96,9 +101,9 @@ var ( }, Network: Topology{ Adjacency: Adjacency{ - "client.hostname.com" + IDDelim + clientIP: NewIDList(serverIP), - "random.hostname.com" + IDDelim + randomIP: NewIDList(serverIP), - "server.hostname.com" + IDDelim + serverIP: NewIDList(clientIP, unknownIP), // no backlink to random + MakeAdjacencyID("client.hostname.com", clientIP): NewIDList(serverIP), + MakeAdjacencyID("random.hostname.com", randomIP): NewIDList(serverIP), + MakeAdjacencyID("server.hostname.com", serverIP): NewIDList(clientIP, unknownIP), // no backlink to random }, NodeMetadatas: NodeMetadatas{ clientIP: NodeMetadata{ @@ -112,19 +117,19 @@ var ( }, }, EdgeMetadatas: EdgeMetadatas{ - clientIP + IDDelim + serverIP: EdgeMetadata{ + MakeEdgeID(clientIP, serverIP): EdgeMetadata{ WithConnCountTCP: true, MaxConnCountTCP: 3, }, - randomIP + IDDelim + serverIP: EdgeMetadata{ + MakeEdgeID(randomIP, serverIP): EdgeMetadata{ WithConnCountTCP: true, MaxConnCountTCP: 20, // dangling connections, weird but possible }, - serverIP + IDDelim + clientIP: EdgeMetadata{ + MakeEdgeID(serverIP, clientIP): EdgeMetadata{ WithConnCountTCP: true, MaxConnCountTCP: 3, }, - serverIP + IDDelim + unknownIP: EdgeMetadata{ + MakeEdgeID(serverIP, unknownIP): EdgeMetadata{ WithConnCountTCP: true, MaxConnCountTCP: 7, }, @@ -143,7 +148,7 @@ func TestRenderByProcessPID(t *testing.T) { Pseudo: false, Adjacency: NewIDList("pid:server-80-domain:215"), OriginHosts: NewIDList("client.hostname.com"), - OriginNodes: NewIDList(";10.10.10.20;54001"), + OriginNodes: NewIDList("client.hostname.com;10.10.10.20;54001"), Metadata: AggregateMetadata{ KeyBytesIngress: 100, KeyBytesEgress: 10, @@ -157,7 +162,7 @@ func TestRenderByProcessPID(t *testing.T) { Pseudo: false, Adjacency: NewIDList("pid:server-80-domain:215"), OriginHosts: NewIDList("client.hostname.com"), - OriginNodes: NewIDList(";10.10.10.20;54002"), + OriginNodes: NewIDList("client.hostname.com;10.10.10.20;54002"), Metadata: AggregateMetadata{ KeyBytesIngress: 200, KeyBytesEgress: 20, @@ -172,24 +177,24 @@ func TestRenderByProcessPID(t *testing.T) { Adjacency: NewIDList( "pid:client-54001-domain:10001", "pid:client-54002-domain:10001", - "pseudo:;10.10.10.10;192.168.1.1;80", - "pseudo:;10.10.10.11;192.168.1.1;80", + "pseudo;10.10.10.10;192.168.1.1;80", + "pseudo;10.10.10.11;192.168.1.1;80", ), OriginHosts: NewIDList("server.hostname.com"), - OriginNodes: NewIDList(";192.168.1.1;80"), + OriginNodes: NewIDList("server.hostname.com;192.168.1.1;80"), Metadata: AggregateMetadata{ KeyBytesIngress: 150, KeyBytesEgress: 1500, }, }, - "pseudo:;10.10.10.10;192.168.1.1;80": { - ID: "pseudo:;10.10.10.10;192.168.1.1;80", + "pseudo;10.10.10.10;192.168.1.1;80": { + ID: "pseudo;10.10.10.10;192.168.1.1;80", LabelMajor: "10.10.10.10", Pseudo: true, Metadata: AggregateMetadata{}, }, - "pseudo:;10.10.10.11;192.168.1.1;80": { - ID: "pseudo:;10.10.10.11;192.168.1.1;80", + "pseudo;10.10.10.11;192.168.1.1;80": { + ID: "pseudo;10.10.10.11;192.168.1.1;80", LabelMajor: "10.10.10.11", Pseudo: true, Metadata: AggregateMetadata{}, @@ -214,7 +219,7 @@ func TestRenderByProcessPIDGrouped(t *testing.T) { Pseudo: false, Adjacency: NewIDList("apache"), OriginHosts: NewIDList("client.hostname.com"), - OriginNodes: NewIDList(";10.10.10.20;54001", ";10.10.10.20;54002"), + OriginNodes: NewIDList("client.hostname.com;10.10.10.20;54001", "client.hostname.com;10.10.10.20;54002"), Metadata: AggregateMetadata{ KeyBytesIngress: 300, KeyBytesEgress: 30, @@ -228,24 +233,24 @@ func TestRenderByProcessPIDGrouped(t *testing.T) { Pseudo: false, Adjacency: NewIDList( "curl", - "pseudo:;10.10.10.10;apache", - "pseudo:;10.10.10.11;apache", + "pseudo;10.10.10.10;apache", + "pseudo;10.10.10.11;apache", ), OriginHosts: NewIDList("server.hostname.com"), - OriginNodes: NewIDList(";192.168.1.1;80"), + OriginNodes: NewIDList("server.hostname.com;192.168.1.1;80"), Metadata: AggregateMetadata{ KeyBytesIngress: 150, KeyBytesEgress: 1500, }, }, - "pseudo:;10.10.10.10;apache": { - ID: "pseudo:;10.10.10.10;apache", + "pseudo;10.10.10.10;apache": { + ID: "pseudo;10.10.10.10;apache", LabelMajor: "10.10.10.10", Pseudo: true, Metadata: AggregateMetadata{}, }, - "pseudo:;10.10.10.11;apache": { - ID: "pseudo:;10.10.10.11;apache", + "pseudo;10.10.10.11;apache": { + ID: "pseudo;10.10.10.11;apache", LabelMajor: "10.10.10.11", Pseudo: true, Metadata: AggregateMetadata{}, @@ -267,7 +272,7 @@ func TestRenderByNetworkHostname(t *testing.T) { Pseudo: false, Adjacency: NewIDList("host:server.hostname.com"), OriginHosts: NewIDList("client.hostname.com"), - OriginNodes: NewIDList(";10.10.10.20"), + OriginNodes: NewIDList("client.hostname.com;10.10.10.20"), Metadata: AggregateMetadata{ KeyMaxConnCountTCP: 3, }, @@ -280,7 +285,7 @@ func TestRenderByNetworkHostname(t *testing.T) { Pseudo: false, Adjacency: NewIDList("host:server.hostname.com"), OriginHosts: NewIDList("random.hostname.com"), - OriginNodes: NewIDList(";172.16.11.9"), + OriginNodes: NewIDList("random.hostname.com;172.16.11.9"), Metadata: AggregateMetadata{ KeyMaxConnCountTCP: 20, }, @@ -291,15 +296,15 @@ func TestRenderByNetworkHostname(t *testing.T) { LabelMinor: "hostname.com", // after first . Rank: "server", Pseudo: false, - Adjacency: NewIDList("host:client.hostname.com", "pseudo:;10.10.10.10;192.168.1.1;"), + Adjacency: NewIDList("host:client.hostname.com", "pseudo;10.10.10.10;192.168.1.1;"), OriginHosts: NewIDList("server.hostname.com"), - OriginNodes: NewIDList(";192.168.1.1"), + OriginNodes: NewIDList("server.hostname.com;192.168.1.1"), Metadata: AggregateMetadata{ KeyMaxConnCountTCP: 10, }, }, - "pseudo:;10.10.10.10;192.168.1.1;": { - ID: "pseudo:;10.10.10.10;192.168.1.1;", + "pseudo;10.10.10.10;192.168.1.1;": { + ID: "pseudo;10.10.10.10;192.168.1.1;", LabelMajor: "10.10.10.10", LabelMinor: "", // after first . Rank: "", diff --git a/xfer/collector_test.go b/xfer/collector_test.go index be56fc586..9bbd82c7f 100644 --- a/xfer/collector_test.go +++ b/xfer/collector_test.go @@ -43,7 +43,7 @@ func TestCollector(t *testing.T) { // Push a report through everything reports <- report.Report{Network: report.Topology{NodeMetadatas: report.NodeMetadatas{"a": report.NodeMetadata{}}}} - poll(t, time.Millisecond, func() bool { return len(concreteCollector.peek().Network.NodeMetadatas) == 1 }, "missed the report") + poll(t, 10*time.Millisecond, func() bool { return len(concreteCollector.peek().Network.NodeMetadatas) == 1 }, "missed the report") go func() { publish <- time.Now() }() if want, have := 1, len((<-collector.Reports()).Network.NodeMetadatas); want != have { t.Errorf("want %d, have %d", want, have)