diff --git a/probe/endpoint/connection_tracker.go b/probe/endpoint/connection_tracker.go index cd8dac7a03..762afdfffa 100644 --- a/probe/endpoint/connection_tracker.go +++ b/probe/endpoint/connection_tracker.go @@ -217,7 +217,7 @@ func (t *connectionTracker) addConnection(rpt *report.Report, incoming bool, ft fromNode = t.makeEndpointNode(namespaceID, ft.fromAddr, ft.fromPort, extraFromNode) toNode = t.makeEndpointNode(namespaceID, ft.toAddr, ft.toPort, extraToNode) ) - rpt.Endpoint = rpt.Endpoint.AddNode(fromNode.WithEdge(toNode.ID, report.EdgeMetadata{})) + rpt.Endpoint = rpt.Endpoint.AddNode(fromNode.WithAdjacent(toNode.ID)) rpt.Endpoint = rpt.Endpoint.AddNode(toNode) } diff --git a/report/edge_metadatas.go b/report/edge_metadatas.go deleted file mode 100644 index d8f915656e..0000000000 --- a/report/edge_metadatas.go +++ /dev/null @@ -1,246 +0,0 @@ -package report - -import ( - "fmt" - "reflect" - "strconv" - - "github.com/ugorji/go/codec" - "github.com/weaveworks/ps" -) - -// EdgeMetadatas collect metadata about each edge in a topology. Keys are the -// remote node IDs, as in Adjacency. -type EdgeMetadatas struct { - psMap ps.Map -} - -var emptyEdgeMetadatas = EdgeMetadatas{ps.NewMap()} - -// MakeEdgeMetadatas returns EmptyEdgeMetadatas -func MakeEdgeMetadatas() EdgeMetadatas { - return emptyEdgeMetadatas -} - -// Add value to the counter 'key' -func (c EdgeMetadatas) Add(key string, value EdgeMetadata) EdgeMetadatas { - if c.psMap == nil { - c = emptyEdgeMetadatas - } - if existingValue, ok := c.psMap.Lookup(key); ok { - value = value.Merge(existingValue.(EdgeMetadata)) - } - return EdgeMetadatas{ - c.psMap.Set(key, value), - } -} - -// Lookup the counter 'key' -func (c EdgeMetadatas) Lookup(key string) (EdgeMetadata, bool) { - if c.psMap != nil { - existingValue, ok := c.psMap.Lookup(key) - if ok { - return existingValue.(EdgeMetadata), true - } - } - return EdgeMetadata{}, false -} - -// Size is the number of elements -func (c EdgeMetadatas) Size() int { - if c.psMap == nil { - return 0 - } - return c.psMap.Size() -} - -// Merge produces a fresh Counters, container the keys from both inputs. When -// both inputs container the same key, the latter value is used. -func (c EdgeMetadatas) Merge(other EdgeMetadatas) EdgeMetadatas { - var ( - cSize = c.Size() - otherSize = other.Size() - output = c.psMap - iter = other.psMap - ) - switch { - case cSize == 0: - return other - case otherSize == 0: - return c - case cSize < otherSize: - output, iter = iter, output - } - iter.ForEach(func(key string, otherVal interface{}) { - if val, ok := output.Lookup(key); ok { - output = output.Set(key, otherVal.(EdgeMetadata).Merge(val.(EdgeMetadata))) - } else { - output = output.Set(key, otherVal) - } - }) - return EdgeMetadatas{output} -} - -// Flatten flattens all the EdgeMetadatas in this set and returns the result. -// The original is not modified. -func (c EdgeMetadatas) Flatten() EdgeMetadata { - result := EdgeMetadata{} - c.ForEach(func(_ string, e EdgeMetadata) { - result = result.Flatten(e) - }) - return result -} - -// ForEach executes f on each key value pair in the map -func (c EdgeMetadatas) ForEach(fn func(k string, v EdgeMetadata)) { - if c.psMap != nil { - c.psMap.ForEach(func(key string, value interface{}) { - fn(key, value.(EdgeMetadata)) - }) - } -} - -func (c EdgeMetadatas) String() string { - return mapToString(c.psMap) -} - -// DeepEqual tests equality with other Counters -func (c EdgeMetadatas) DeepEqual(d EdgeMetadatas) bool { - return mapEqual(c.psMap, d.psMap, reflect.DeepEqual) -} - -// CodecEncodeSelf implements codec.Selfer -func (c *EdgeMetadatas) CodecEncodeSelf(encoder *codec.Encoder) { - mapWrite(c.psMap, encoder, func(encoder *codec.Encoder, val interface{}) { - e := val.(EdgeMetadata) - (&e).CodecEncodeSelf(encoder) - }) -} - -// CodecDecodeSelf implements codec.Selfer -func (c *EdgeMetadatas) CodecDecodeSelf(decoder *codec.Decoder) { - out := mapRead(decoder, func(isNil bool) interface{} { - var value EdgeMetadata - if !isNil { - value.CodecDecodeSelf(decoder) - } - return value - }) - *c = EdgeMetadatas{out} -} - -// MarshalJSON shouldn't be used, use CodecEncodeSelf instead -func (EdgeMetadatas) MarshalJSON() ([]byte, error) { - panic("MarshalJSON shouldn't be used, use CodecEncodeSelf instead") -} - -// UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead -func (*EdgeMetadatas) UnmarshalJSON(b []byte) error { - panic("UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead") -} - -// EdgeMetadata describes a superset of the metadata that probes can possibly -// collect about a directed edge between two nodes in any topology. -type EdgeMetadata struct { - EgressPacketCount *uint64 `json:"egress_packet_count,omitempty"` - IngressPacketCount *uint64 `json:"ingress_packet_count,omitempty"` - EgressByteCount *uint64 `json:"egress_byte_count,omitempty"` // Transport layer - IngressByteCount *uint64 `json:"ingress_byte_count,omitempty"` // Transport layer - dummySelfer -} - -// String returns a string representation of this EdgeMetadata -// Helps with our use of Spew and diff. -func (e EdgeMetadata) String() string { - f := func(i *uint64) string { - if i == nil { - return "nil" - } - return strconv.FormatUint(*i, 10) - } - - return fmt.Sprintf(`{ -EgressPacketCount: %v, -IngressPacketCount: %v, -EgressByteCount: %v, -IngressByteCount: %v, -}`, - f(e.EgressPacketCount), - f(e.IngressPacketCount), - f(e.EgressByteCount), - f(e.IngressByteCount)) -} - -// Copy returns a value copy of the EdgeMetadata. -func (e EdgeMetadata) Copy() EdgeMetadata { - return EdgeMetadata{ - EgressPacketCount: cpu64ptr(e.EgressPacketCount), - IngressPacketCount: cpu64ptr(e.IngressPacketCount), - EgressByteCount: cpu64ptr(e.EgressByteCount), - IngressByteCount: cpu64ptr(e.IngressByteCount), - } -} - -// Reversed returns a value copy of the EdgeMetadata, with the direction reversed. -func (e EdgeMetadata) Reversed() EdgeMetadata { - return EdgeMetadata{ - EgressPacketCount: cpu64ptr(e.IngressPacketCount), - IngressPacketCount: cpu64ptr(e.EgressPacketCount), - EgressByteCount: cpu64ptr(e.IngressByteCount), - IngressByteCount: cpu64ptr(e.EgressByteCount), - } -} - -func cpu64ptr(u *uint64) *uint64 { - if u == nil { - return nil - } - value := *u // oh man - return &value // this sucks -} - -// Merge merges another EdgeMetadata into the receiver and returns the result. -// The receiver is not modified. The two edge metadatas should represent the -// same edge on different times. -func (e EdgeMetadata) Merge(other EdgeMetadata) EdgeMetadata { - cp := e.Copy() - cp.EgressPacketCount = merge(cp.EgressPacketCount, other.EgressPacketCount, sum) - cp.IngressPacketCount = merge(cp.IngressPacketCount, other.IngressPacketCount, sum) - cp.EgressByteCount = merge(cp.EgressByteCount, other.EgressByteCount, sum) - cp.IngressByteCount = merge(cp.IngressByteCount, other.IngressByteCount, sum) - return cp -} - -// Flatten sums two EdgeMetadatas and returns the result. The receiver is not -// modified. The two edge metadata windows should be the same duration; they -// should represent different edges at the same time. -func (e EdgeMetadata) Flatten(other EdgeMetadata) EdgeMetadata { - cp := e.Copy() - cp.EgressPacketCount = merge(cp.EgressPacketCount, other.EgressPacketCount, sum) - cp.IngressPacketCount = merge(cp.IngressPacketCount, other.IngressPacketCount, sum) - cp.EgressByteCount = merge(cp.EgressByteCount, other.EgressByteCount, sum) - cp.IngressByteCount = merge(cp.IngressByteCount, other.IngressByteCount, sum) - return cp -} - -func merge(dst, src *uint64, op func(uint64, uint64) uint64) *uint64 { - if src == nil { - return dst - } - if dst == nil { - dst = new(uint64) - } - (*dst) = op(*dst, *src) - return dst -} - -func sum(dst, src uint64) uint64 { - return dst + src -} - -func max(dst, src uint64) uint64 { - if dst > src { - return dst - } - return src -} diff --git a/report/edge_metadatas_internal_test.go b/report/edge_metadatas_internal_test.go deleted file mode 100644 index 0949986583..0000000000 --- a/report/edge_metadatas_internal_test.go +++ /dev/null @@ -1,288 +0,0 @@ -package report - -import ( - "bytes" - "testing" - - "github.com/ugorji/go/codec" - - "github.com/weaveworks/common/test" - "github.com/weaveworks/scope/test/reflect" -) - -func TestEdgeMetadatasAdd(t *testing.T) { - have := MakeEdgeMetadatas(). - Add("foo", - EdgeMetadata{ - EgressPacketCount: newu64(1), - }). - Add("foo", - EdgeMetadata{ - EgressPacketCount: newu64(2), - }) - if emd, ok := have.Lookup("foo"); !ok || *emd.EgressPacketCount != 3 { - t.Errorf("foo.EgressPacketCount != 3") - } - if emd, ok := have.Lookup("bar"); ok || emd.EgressPacketCount != nil { - t.Errorf("bar.EgressPacketCount != nil") - } - have.ForEach(func(k string, emd EdgeMetadata) { - if k != "foo" || *emd.EgressPacketCount != 3 { - t.Errorf("foo.EgressPacketCount != 3") - } - }) -} - -func TestEdgeMetadatasAddNil(t *testing.T) { - have := EdgeMetadatas{}.Add("foo", EdgeMetadata{EgressPacketCount: newu64(1)}) - if have.Size() != 1 { - t.Errorf("Adding to a zero-value EdgeMetadatas failed, got: %v", have) - } -} - -func TestEdgeMetadatasDeepEquals(t *testing.T) { - want := MakeEdgeMetadatas(). - Add("foo", - EdgeMetadata{ - EgressPacketCount: newu64(3), - }) - have := MakeEdgeMetadatas(). - Add("foo", - EdgeMetadata{ - EgressPacketCount: newu64(3), - }) - if !reflect.DeepEqual(want, have) { - t.Errorf(test.Diff(want, have)) - } -} - -func TestEdgeMetadatasMerge(t *testing.T) { - for name, c := range map[string]struct { - a, b, want EdgeMetadatas - }{ - "nils": { - a: EdgeMetadatas{}, - b: EdgeMetadatas{}, - want: EdgeMetadatas{}, - }, - "Empty a": { - a: MakeEdgeMetadatas(), - b: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(1), - }), - want: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(1), - }), - }, - "Empty b": { - a: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(12), - EgressByteCount: newu64(999), - }), - b: MakeEdgeMetadatas(), - want: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(12), - EgressByteCount: newu64(999), - }), - }, - "Disjoint a & b": { - a: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(12), - EgressByteCount: newu64(500), - }), - b: MakeEdgeMetadatas(). - Add("hostQ|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(1), - EgressByteCount: newu64(2), - }), - want: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(12), - EgressByteCount: newu64(500), - }). - Add("hostQ|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(1), - EgressByteCount: newu64(2), - }), - }, - "Overlapping a & b": { - a: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(12), - EgressByteCount: newu64(1000), - }), - b: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(1), - IngressByteCount: newu64(123), - EgressByteCount: newu64(2), - }), - want: MakeEdgeMetadatas(). - Add("hostA|:192.168.1.1:12345|:192.168.1.2:80", - EdgeMetadata{ - EgressPacketCount: newu64(13), - IngressByteCount: newu64(123), - EgressByteCount: newu64(1002), - }), - }, - } { - if have := c.a.Merge(c.b); !reflect.DeepEqual(c.want, have) { - t.Errorf("%s:\n%s", name, test.Diff(c.want, have)) - } - } -} - -func TestEdgeMetadataFlatten(t *testing.T) { - // Test two EdgeMetadatas flatten to the correct values - { - have := (EdgeMetadata{ - EgressPacketCount: newu64(1), - }).Flatten(EdgeMetadata{ - EgressPacketCount: newu64(4), - EgressByteCount: newu64(8), - }) - want := EdgeMetadata{ - EgressPacketCount: newu64(1 + 4), - EgressByteCount: newu64(8), - } - if !reflect.DeepEqual(want, have) { - t.Error(test.Diff(want, have)) - } - } - - // Test an EdgeMetadatas flatten to the correct value (should - // just sum) - { - have := MakeEdgeMetadatas(). - Add("foo", EdgeMetadata{ - EgressPacketCount: newu64(1), - }). - Add("bar", EdgeMetadata{ - EgressPacketCount: newu64(3), - }).Flatten() - want := EdgeMetadata{ - EgressPacketCount: newu64(1 + 3), - } - if !reflect.DeepEqual(want, have) { - t.Error(test.Diff(want, have)) - } - } - - { - // Should not panic on nil - have := EdgeMetadatas{}.Flatten() - want := EdgeMetadata{} - if !reflect.DeepEqual(want, have) { - t.Error(test.Diff(want, have)) - } - } -} - -func TestEdgeMetadataReversed(t *testing.T) { - have := EdgeMetadata{ - EgressPacketCount: newu64(1), - }.Reversed() - want := EdgeMetadata{ - IngressPacketCount: newu64(1), - } - if !reflect.DeepEqual(want, have) { - t.Error(test.Diff(want, have)) - } -} - -func TestEdgeMetadatasEncoding(t *testing.T) { - want := MakeEdgeMetadatas(). - Add("foo", EdgeMetadata{ - EgressPacketCount: newu64(1), - }). - Add("bar", EdgeMetadata{ - EgressPacketCount: newu64(3), - }) - - { - for _, h := range []codec.Handle{ - codec.Handle(&codec.MsgpackHandle{}), - codec.Handle(&codec.JsonHandle{}), - } { - buf := &bytes.Buffer{} - encoder := codec.NewEncoder(buf, h) - want.CodecEncodeSelf(encoder) - decoder := codec.NewDecoder(buf, h) - have := MakeEdgeMetadatas() - have.CodecDecodeSelf(decoder) - if !reflect.DeepEqual(want, have) { - t.Error(test.Diff(want, have)) - } - } - } -} - -func TestEdgeMetadatasEncodingNil(t *testing.T) { - want := EdgeMetadatas{} - - { - - for _, h := range []codec.Handle{ - codec.Handle(&codec.MsgpackHandle{}), - codec.Handle(&codec.JsonHandle{}), - } { - buf := &bytes.Buffer{} - encoder := codec.NewEncoder(buf, h) - want.CodecEncodeSelf(encoder) - decoder := codec.NewDecoder(buf, h) - have := MakeEdgeMetadatas() - have.CodecDecodeSelf(decoder) - if !reflect.DeepEqual(want, have) { - t.Error(test.Diff(want, have)) - } - } - } -} - -func newu64(value uint64) *uint64 { return &value } - -func TestEdgeMetadataDeepEquals(t *testing.T) { - for _, c := range []struct { - name string - a, b interface{} - want bool - }{ - { - name: "zero values", - a: EdgeMetadata{}, - b: EdgeMetadata{}, - want: true, - }, - { - name: "matching, but different pointers", - a: EdgeMetadata{EgressPacketCount: newu64(3)}, - b: EdgeMetadata{EgressPacketCount: newu64(3)}, - want: true, - }, - { - name: "mismatching", - a: EdgeMetadata{EgressPacketCount: newu64(3)}, - b: EdgeMetadata{EgressPacketCount: newu64(4)}, - want: false, - }, - } { - if have := reflect.DeepEqual(c.a, c.b); have != c.want { - t.Errorf("reflect.DeepEqual(%v, %v) != %v", c.a, c.b, c.want) - } - } -} diff --git a/report/node.go b/report/node.go index db22873fcb..28386e3e6a 100644 --- a/report/node.go +++ b/report/node.go @@ -6,16 +6,15 @@ import ( "github.com/weaveworks/common/mtime" ) -// Node describes a superset of the metadata that probes can collect about a -// given node in a given topology, along with the edges emanating from the -// node and metadata about those edges. +// Node describes a superset of the metadata that probes can collect +// about a given node in a given topology, along with the edges (aka +// adjacency) emanating from the node. type Node struct { ID string `json:"id,omitempty"` Topology string `json:"topology,omitempty"` Counters Counters `json:"counters,omitempty"` Sets Sets `json:"sets,omitempty"` Adjacency IDList `json:"adjacency"` - Edges EdgeMetadatas `json:"edges,omitempty"` Controls NodeControls `json:"controls,omitempty"` LatestControls NodeControlDataLatestMap `json:"latestControls,omitempty"` Latest StringLatestMap `json:"latest,omitempty"` @@ -31,7 +30,6 @@ func MakeNode(id string) Node { Counters: MakeCounters(), Sets: MakeSets(), Adjacency: MakeIDList(), - Edges: MakeEdgeMetadatas(), Controls: MakeNodeControls(), LatestControls: MakeNodeControlDataLatestMap(), Latest: MakeStringLatestMap(), @@ -124,14 +122,6 @@ func (n Node) WithAdjacent(a ...string) Node { return n } -// WithEdge returns a fresh copy of n, with 'dst' added to Adjacency and md -// added to EdgeMetadata. -func (n Node) WithEdge(dst string, md EdgeMetadata) Node { - n.Adjacency = n.Adjacency.Add(dst) - n.Edges = n.Edges.Add(dst, md) - return n -} - // WithControls returns a fresh copy of n, with cs added to Controls. func (n Node) WithControls(cs ...string) Node { n.Controls = n.Controls.Add(cs...) @@ -205,7 +195,6 @@ func (n Node) Merge(other Node) Node { Counters: n.Counters.Merge(other.Counters), Sets: n.Sets.Merge(other.Sets), Adjacency: n.Adjacency.Merge(other.Adjacency), - Edges: n.Edges.Merge(other.Edges), Controls: n.Controls.Merge(other.Controls), LatestControls: n.LatestControls.Merge(other.LatestControls), Latest: n.Latest.Merge(other.Latest), diff --git a/report/report.go b/report/report.go index 3c2bcba80b..e25f35b693 100644 --- a/report/report.go +++ b/report/report.go @@ -121,7 +121,7 @@ type Report struct { // Overlay nodes are active peers in any software-defined network that's // overlaid on the infrastructure. The information is scraped by polling - // their status endpoints. Edges could be present, but aren't currently. + // their status endpoints. Edges are present. Overlay Topology // Sampling data for this report. diff --git a/report/report_test.go b/report/report_test.go index aec9052868..bf5dc2a366 100644 --- a/report/report_test.go +++ b/report/report_test.go @@ -66,17 +66,6 @@ func TestNode(t *testing.T) { t.Errorf("want foo, have %v", node.Adjacency) } } - { - node := report.MakeNode("foo").WithEdge("foo", report.EdgeMetadata{ - EgressPacketCount: newu64(13), - }) - if node.Adjacency[0] != "foo" { - t.Errorf("want foo, have %v", node.Adjacency) - } - if v, ok := node.Edges.Lookup("foo"); ok && *v.EgressPacketCount != 13 { - t.Errorf("want 13, have %v", node.Edges) - } - } } func TestReportBackwardCompatibility(t *testing.T) { diff --git a/report/topology.go b/report/topology.go index 5c276086c2..4f94e54f59 100644 --- a/report/topology.go +++ b/report/topology.go @@ -5,9 +5,8 @@ import ( "strings" ) -// Topology describes a specific view of a network. It consists of nodes and -// edges, and metadata about those nodes and edges, represented by -// EdgeMetadatas and Nodes respectively. Edges are directional, and embedded +// Topology describes a specific view of a network. It consists of +// nodes with metadata, and edges. Edges are directional, and embedded // in the Node struct. type Topology struct { Shape string `json:"shape,omitempty"` @@ -206,13 +205,6 @@ func (t Topology) Validate() error { errs = append(errs, fmt.Sprintf("node missing from adjacency %q -> %q", nodeID, dstNodeID)) } } - - // Check all the edge metadatas have entries in adjacencies - nmd.Edges.ForEach(func(dstNodeID string, _ EdgeMetadata) { - if _, ok := t.Nodes[dstNodeID]; !ok { - errs = append(errs, fmt.Sprintf("node %s missing for edge %q", dstNodeID, nodeID)) - } - }) } if len(errs) > 0 { diff --git a/test/fixture/report_fixture.go b/test/fixture/report_fixture.go index 3083c86636..dea5b40af4 100644 --- a/test/fixture/report_fixture.go +++ b/test/fixture/report_fixture.go @@ -129,18 +129,12 @@ var ( Client54001NodeID: report.MakeNode(Client54001NodeID).WithTopology(report.Endpoint).WithLatests(map[string]string{ process.PID: Client1PID, report.HostNodeID: ClientHostNodeID, - }).WithEdge(Server80NodeID, report.EdgeMetadata{ - EgressPacketCount: newu64(10), - EgressByteCount: newu64(100), - }), + }).WithAdjacent(Server80NodeID), Client54002NodeID: report.MakeNode(Client54002NodeID).WithTopology(report.Endpoint).WithLatests(map[string]string{ process.PID: Client2PID, report.HostNodeID: ClientHostNodeID, - }).WithEdge(Server80NodeID, report.EdgeMetadata{ - EgressPacketCount: newu64(20), - EgressByteCount: newu64(200), - }), + }).WithAdjacent(Server80NodeID), Server80NodeID: report.MakeNode(Server80NodeID).WithTopology(report.Endpoint).WithLatests(map[string]string{ process.PID: ServerPID, @@ -153,26 +147,10 @@ var ( }).WithAdjacent(GoogleEndpointNodeID), // Probe pseudo nodes - UnknownClient1NodeID: report.MakeNode(UnknownClient1NodeID).WithTopology(report.Endpoint).WithEdge(Server80NodeID, report.EdgeMetadata{ - EgressPacketCount: newu64(30), - EgressByteCount: newu64(300), - }), - - UnknownClient2NodeID: report.MakeNode(UnknownClient2NodeID).WithTopology(report.Endpoint).WithEdge(Server80NodeID, report.EdgeMetadata{ - EgressPacketCount: newu64(40), - EgressByteCount: newu64(400), - }), - - UnknownClient3NodeID: report.MakeNode(UnknownClient3NodeID).WithTopology(report.Endpoint).WithEdge(Server80NodeID, report.EdgeMetadata{ - EgressPacketCount: newu64(50), - EgressByteCount: newu64(500), - }), - - RandomClientNodeID: report.MakeNode(RandomClientNodeID).WithTopology(report.Endpoint).WithEdge(Server80NodeID, report.EdgeMetadata{ - EgressPacketCount: newu64(60), - EgressByteCount: newu64(600), - }), - + UnknownClient1NodeID: report.MakeNode(UnknownClient1NodeID).WithTopology(report.Endpoint).WithAdjacent(Server80NodeID), + UnknownClient2NodeID: report.MakeNode(UnknownClient2NodeID).WithTopology(report.Endpoint).WithAdjacent(Server80NodeID), + UnknownClient3NodeID: report.MakeNode(UnknownClient3NodeID).WithTopology(report.Endpoint).WithAdjacent(Server80NodeID), + RandomClientNodeID: report.MakeNode(RandomClientNodeID).WithTopology(report.Endpoint).WithAdjacent(Server80NodeID), GoogleEndpointNodeID: report.MakeNode(GoogleEndpointNodeID).WithTopology(report.Endpoint), }, },