optimization: store just IDs of child nodes

IDs are a lot smaller, hence quicker to manage.
Any time we want to refer back to the full node we look it up in its topology.

(This relies on nobody trying to store a rendered node as a child).
This commit is contained in:
Bryan Boreham
2020-06-08 16:39:50 +00:00
parent b4a73b7f87
commit d76da767d8
13 changed files with 233 additions and 280 deletions

View File

@@ -103,13 +103,7 @@ func FilterEmpty(topology string, r Renderer) Renderer {
// topology.
func HasChildren(topology string) FilterFunc {
return func(n report.Node) bool {
count := 0
n.Children.ForEach(func(child report.Node) {
if child.Topology == topology {
count++
}
})
return count > 0
return len(n.ChildIDs) > 0
}
}

View File

@@ -167,7 +167,7 @@ func (c *connectionCounters) rows(r report.Report, ns report.Nodes, includeLocal
}
func incomingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes) ConnectionsSummary {
localEndpointIDs, localEndpointIDCopies := endpointChildIDsAndCopyMapOf(n)
localEndpointIDs, localEndpointIDCopies := endpointChildIDsAndCopyMapOf(r, n)
counts := newConnectionCounters()
// For each node which has an edge TO me
@@ -175,7 +175,7 @@ func incomingConnectionsSummary(topologyID string, r report.Report, n report.Nod
if !node.Adjacency.Contains(n.ID) {
continue
}
for _, remoteEndpoint := range endpointChildrenOf(node) {
for _, remoteEndpoint := range endpointChildrenOf(r, node) {
for _, localEndpointID := range remoteEndpoint.Adjacency.Intersection(localEndpointIDs) {
localEndpointID = canonicalEndpointID(localEndpointIDCopies, localEndpointID)
counts.add(r.DNS, false, n, node, r.Endpoint.Nodes[localEndpointID], remoteEndpoint)
@@ -197,7 +197,7 @@ func incomingConnectionsSummary(topologyID string, r report.Report, n report.Nod
}
func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes) ConnectionsSummary {
localEndpoints := endpointChildrenOf(n)
localEndpoints := endpointChildrenOf(r, n)
counts := newConnectionCounters()
// For each node which has an edge FROM me
@@ -206,7 +206,7 @@ func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Nod
if !ok {
continue
}
remoteEndpointIDs, remoteEndpointIDCopies := endpointChildIDsAndCopyMapOf(node)
remoteEndpointIDs, remoteEndpointIDCopies := endpointChildIDsAndCopyMapOf(r, node)
for _, localEndpoint := range localEndpoints {
for _, remoteEndpointID := range localEndpoint.Adjacency.Intersection(remoteEndpointIDs) {
remoteEndpointID = canonicalEndpointID(remoteEndpointIDCopies, remoteEndpointID)
@@ -228,27 +228,31 @@ func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Nod
}
}
func endpointChildrenOf(n report.Node) []report.Node {
func endpointChildrenOf(r report.Report, n report.Node) []report.Node {
result := []report.Node{}
n.Children.ForEach(func(child report.Node) {
if child.Topology == report.Endpoint {
result = append(result, child)
for _, childID := range n.ChildIDs {
if ty, ok := report.NodeIDType(childID); ok && ty == report.Endpoint {
if child, found := r.Endpoint.Nodes[childID]; found {
result = append(result, child)
}
}
})
}
return result
}
func endpointChildIDsAndCopyMapOf(n report.Node) (report.IDList, map[string]string) {
func endpointChildIDsAndCopyMapOf(r report.Report, n report.Node) (report.IDList, map[string]string) {
ids := report.MakeIDList()
copies := map[string]string{}
n.Children.ForEach(func(child report.Node) {
if child.Topology == report.Endpoint {
ids = ids.Add(child.ID)
if copyID, _, ok := child.Latest.LookupEntry(endpoint.CopyOf); ok {
copies[child.ID] = copyID
for _, childID := range n.ChildIDs {
if ty, ok := report.NodeIDType(childID); ok && ty == report.Endpoint {
ids = ids.Add(childID)
if child, found := r.Endpoint.Nodes[childID]; found {
if copyID, _, ok := child.Latest.LookupEntry(endpoint.CopyOf); ok {
copies[child.ID] = copyID
}
}
}
})
}
return ids, copies
}

View File

@@ -223,16 +223,20 @@ var nodeSummaryGroupSpecs = []struct {
func children(rc RenderContext, n report.Node) []NodeSummaryGroup {
summaries := map[string][]NodeSummary{}
n.Children.ForEach(func(child report.Node) {
if child.ID == n.ID {
return
for _, childID := range n.ChildIDs {
if childID == n.ID {
continue
}
summary, ok := MakeNodeSummary(rc, child)
if !ok {
return
if ty, ok := report.NodeIDType(childID); ok {
if topology, ok := rc.Report.Topology(ty); ok {
if child, ok := topology.Nodes[childID]; ok {
if summary, ok := MakeNodeSummary(rc, child); ok {
summaries[ty] = append(summaries[ty], summary.SummarizeMetrics())
}
}
}
}
summaries[child.Topology] = append(summaries[child.Topology], summary.SummarizeMetrics())
})
}
nodeSummaryGroups := []NodeSummaryGroup{}
// Apply specific group specs in the order they're listed

View File

@@ -51,28 +51,26 @@ var (
unknownPseudoNode1 = func(adjacent ...string) report.Node {
return pseudo(UnknownPseudoNode1ID, adjacent...).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.UnknownClient1NodeID],
RenderedEndpoints[fixture.UnknownClient2NodeID],
WithChildren(report.MakeIDList(
fixture.UnknownClient1NodeID,
fixture.UnknownClient2NodeID,
))
}
unknownPseudoNode2 = func(adjacent ...string) report.Node {
return pseudo(UnknownPseudoNode2ID, adjacent...).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.UnknownClient3NodeID],
WithChildren(report.MakeIDList(
fixture.UnknownClient3NodeID,
))
}
theIncomingInternetNode = func(adjacent ...string) report.Node {
return pseudo(render.IncomingInternetID, adjacent...).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.RandomClientNodeID],
WithChildren(report.MakeIDList(
fixture.RandomClientNodeID,
))
}
theOutgoingInternetNode = pseudo(render.OutgoingInternetID).WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.GoogleEndpointNodeID],
))
theOutgoingInternetNode = pseudo(render.OutgoingInternetID).WithChildID(fixture.GoogleEndpointNodeID)
RenderedEndpoints = report.Nodes{
fixture.Client54001NodeID: endpoint(fixture.Client54001NodeID, fixture.Server80NodeID),
@@ -93,24 +91,16 @@ var (
process.PID: fixture.Client1PID,
process.Name: fixture.Client1Name,
}).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
)),
WithChildID(fixture.Client54001NodeID),
fixture.ClientProcess2NodeID: processNode(fixture.ClientProcess2NodeID, fixture.ServerProcessNodeID).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54002NodeID],
)),
WithChildID(fixture.Client54002NodeID),
fixture.ServerProcessNodeID: processNode(fixture.ServerProcessNodeID).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Server80NodeID],
)),
WithChildID(fixture.Server80NodeID),
fixture.NonContainerProcessNodeID: processNode(fixture.NonContainerProcessNodeID, render.OutgoingInternetID).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.NonContainerNodeID],
)),
WithChildID(fixture.NonContainerNodeID),
// due to https://github.com/weaveworks/scope/issues/1323 we are dropping
// all non-internet pseudo nodes for now.
@@ -124,26 +114,26 @@ var (
fixture.Client1Name: processNameNode(fixture.Client1Name, fixture.ServerName).
WithLatests(map[string]string{process.Name: fixture.Client1Name}).
AddCounter(report.Process, 2).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
RenderedEndpoints[fixture.Client54002NodeID],
RenderedProcesses[fixture.ClientProcess1NodeID],
RenderedProcesses[fixture.ClientProcess2NodeID],
WithChildren(report.MakeIDList(
fixture.Client54001NodeID,
fixture.Client54002NodeID,
fixture.ClientProcess1NodeID,
fixture.ClientProcess2NodeID,
)),
fixture.ServerName: processNameNode(fixture.ServerName).
WithLatests(map[string]string{process.Name: fixture.ServerName}).
AddCounter(report.Process, 1).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Server80NodeID],
RenderedProcesses[fixture.ServerProcessNodeID],
WithChildren(report.MakeIDList(
fixture.Server80NodeID,
fixture.ServerProcessNodeID,
)),
fixture.NonContainerName: processNameNode(fixture.NonContainerName, render.OutgoingInternetID).
AddCounter(report.Process, 1).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.NonContainerNodeID],
RenderedProcesses[fixture.NonContainerProcessNodeID],
WithChildren(report.MakeIDList(
fixture.NonContainerNodeID,
fixture.NonContainerProcessNodeID,
)),
// due to https://github.com/weaveworks/scope/issues/1323 we are dropping
@@ -155,9 +145,9 @@ var (
}
uncontainedServerID = render.MakePseudoNodeID(render.UncontainedID, fixture.ServerHostID)
uncontainedServerNode = pseudo(uncontainedServerID, render.OutgoingInternetID).WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.NonContainerNodeID],
RenderedProcesses[fixture.NonContainerProcessNodeID],
uncontainedServerNode = pseudo(uncontainedServerID, render.OutgoingInternetID).WithChildren(report.MakeIDList(
fixture.NonContainerNodeID,
fixture.NonContainerProcessNodeID,
))
RenderedContainers = report.Nodes{
@@ -168,17 +158,17 @@ var (
docker.ContainerName: fixture.ClientContainerName,
docker.ImageName: fixture.ClientContainerImageName,
}).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
RenderedEndpoints[fixture.Client54002NodeID],
RenderedProcesses[fixture.ClientProcess1NodeID],
RenderedProcesses[fixture.ClientProcess2NodeID],
WithChildren(report.MakeIDList(
fixture.Client54001NodeID,
fixture.Client54002NodeID,
fixture.ClientProcess1NodeID,
fixture.ClientProcess2NodeID,
)),
fixture.ServerContainerNodeID: container(fixture.ServerContainerNodeID).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Server80NodeID],
RenderedProcesses[fixture.ServerProcessNodeID],
WithChildren(report.MakeIDList(
fixture.Server80NodeID,
fixture.ServerProcessNodeID,
)),
fixture.ServerContainer2NodeID: container(fixture.ServerContainer2NodeID),
@@ -194,12 +184,12 @@ var (
docker.ContainerHostname: fixture.ClientContainerHostname,
}).
AddCounter(report.Container, 1).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
RenderedEndpoints[fixture.Client54002NodeID],
RenderedProcesses[fixture.ClientProcess1NodeID],
RenderedProcesses[fixture.ClientProcess2NodeID],
RenderedContainers[fixture.ClientContainerNodeID],
WithChildren(report.MakeIDList(
fixture.Client54001NodeID,
fixture.Client54002NodeID,
fixture.ClientProcess1NodeID,
fixture.ClientProcess2NodeID,
fixture.ClientContainerNodeID,
)),
fixture.ServerContainerHostname: containerHostnameNode(fixture.ServerContainerHostname).
@@ -207,11 +197,11 @@ var (
docker.ContainerHostname: fixture.ServerContainerHostname,
}).
AddCounter(report.Container, 2).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Server80NodeID],
RenderedProcesses[fixture.ServerProcessNodeID],
RenderedContainers[fixture.ServerContainerNodeID],
RenderedContainers[fixture.ServerContainer2NodeID],
WithChildren(report.MakeIDList(
fixture.Server80NodeID,
fixture.ServerProcessNodeID,
fixture.ServerContainerNodeID,
fixture.ServerContainer2NodeID,
)),
uncontainedServerID: uncontainedServerNode,
@@ -230,21 +220,21 @@ var (
docker.ImageName: fixture.ClientContainerImageName,
}).
AddCounter(report.Container, 1).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
RenderedEndpoints[fixture.Client54002NodeID],
RenderedProcesses[fixture.ClientProcess1NodeID],
RenderedProcesses[fixture.ClientProcess2NodeID],
RenderedContainers[fixture.ClientContainerNodeID],
WithChildren(report.MakeIDList(
fixture.Client54001NodeID,
fixture.Client54002NodeID,
fixture.ClientProcess1NodeID,
fixture.ClientProcess2NodeID,
fixture.ClientContainerNodeID,
)),
ServerContainerImageNodeID: containerImage(ServerContainerImageNodeID).
AddCounter(report.Container, 2).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Server80NodeID],
RenderedProcesses[fixture.ServerProcessNodeID],
RenderedContainers[fixture.ServerContainerNodeID],
RenderedContainers[fixture.ServerContainer2NodeID],
WithChildren(report.MakeIDList(
fixture.Server80NodeID,
fixture.ServerProcessNodeID,
fixture.ServerContainerNodeID,
fixture.ServerContainer2NodeID,
)),
uncontainedServerID: uncontainedServerNode,
@@ -253,11 +243,11 @@ var (
}
UnmanagedServerID = render.MakePseudoNodeID(render.UnmanagedID, fixture.ServerHostID)
unmanagedServerNode = pseudo(UnmanagedServerID, render.OutgoingInternetID).WithChildren(report.MakeNodeSet(
uncontainedServerNode,
RenderedEndpoints[fixture.NonContainerNodeID],
RenderedProcesses[fixture.NonContainerProcessNodeID],
RenderedContainers[fixture.ServerContainer2NodeID],
unmanagedServerNode = pseudo(UnmanagedServerID, render.OutgoingInternetID).WithChildren(report.MakeIDList(
uncontainedServerID,
fixture.NonContainerNodeID,
fixture.NonContainerProcessNodeID,
fixture.ServerContainer2NodeID,
)).
AddCounter(report.Container, 1).
AddCounter(render.Pseudo, 1)
@@ -265,20 +255,20 @@ var (
RenderedPods = report.Nodes{
fixture.ClientPodNodeID: pod(fixture.ClientPodNodeID, fixture.ServerPodNodeID).
AddCounter(report.Container, 1).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
RenderedEndpoints[fixture.Client54002NodeID],
RenderedProcesses[fixture.ClientProcess1NodeID],
RenderedProcesses[fixture.ClientProcess2NodeID],
RenderedContainers[fixture.ClientContainerNodeID],
WithChildren(report.MakeIDList(
fixture.Client54001NodeID,
fixture.Client54002NodeID,
fixture.ClientProcess1NodeID,
fixture.ClientProcess2NodeID,
fixture.ClientContainerNodeID,
)),
fixture.ServerPodNodeID: pod(fixture.ServerPodNodeID).
AddCounter(report.Container, 1).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Server80NodeID],
RenderedProcesses[fixture.ServerProcessNodeID],
RenderedContainers[fixture.ServerContainerNodeID],
WithChildren(report.MakeIDList(
fixture.Server80NodeID,
fixture.ServerProcessNodeID,
fixture.ServerContainerNodeID,
)),
fixture.PersistentVolumeClaimNodeID: persistentVolumeClaim(fixture.PersistentVolumeClaimNodeID, fixture.PersistentVolumeNodeID).
@@ -289,7 +279,7 @@ var (
kubernetes.VolumeName: "pongvolume",
kubernetes.AccessModes: "ReadWriteOnce",
kubernetes.StorageClassName: "standard",
}).WithChild(report.MakeNode(fixture.PersistentVolumeNodeID).WithTopology(report.PersistentVolume)),
}).WithChildID(fixture.PersistentVolumeNodeID),
fixture.PersistentVolumeNodeID: persistentVolume(fixture.PersistentVolumeNodeID, fixture.VolumeSnapshotNodeID).
WithLatests(map[string]string{
@@ -300,13 +290,13 @@ var (
kubernetes.AccessModes: "ReadWriteOnce",
kubernetes.StorageClassName: "standard",
kubernetes.StorageDriver: "iSCSI",
}).WithChild(report.MakeNode(fixture.VolumeSnapshotNodeID).WithTopology(report.VolumeSnapshot)),
}).WithChildID(fixture.VolumeSnapshotNodeID),
fixture.StorageClassNodeID: StorageClass(fixture.StorageClassNodeID, fixture.PersistentVolumeClaimNodeID).
WithLatests(map[string]string{
kubernetes.Name: "standard",
kubernetes.Provisioner: "pong",
}).WithChild(report.MakeNode(fixture.PersistentVolumeClaimNodeID).WithTopology(report.PersistentVolumeClaim)),
}).WithChildID(fixture.PersistentVolumeClaimNodeID),
fixture.VolumeSnapshotNodeID: volumeSnapshot(fixture.VolumeSnapshotNodeID, fixture.VolumeSnapshotDataNodeID).
WithLatests(map[string]string{
@@ -315,7 +305,7 @@ var (
kubernetes.VolumeClaim: "pvc-6124",
kubernetes.SnapshotData: "vsd-1234",
kubernetes.VolumeName: "pongvolume",
}).WithChild(report.MakeNode(fixture.VolumeSnapshotDataNodeID).WithTopology(report.VolumeSnapshotData)),
}).WithChildID(fixture.VolumeSnapshotDataNodeID),
fixture.VolumeSnapshotDataNodeID: volumeSnapshotData(fixture.VolumeSnapshotDataNodeID).
WithLatests(map[string]string{
@@ -332,17 +322,17 @@ var (
RenderedPodServices = report.Nodes{
fixture.ServiceNodeID: service(fixture.ServiceNodeID, fixture.ServiceNodeID).
AddCounter(report.Pod, 2).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
RenderedEndpoints[fixture.Client54002NodeID],
RenderedEndpoints[fixture.Server80NodeID],
RenderedProcesses[fixture.ClientProcess1NodeID],
RenderedProcesses[fixture.ClientProcess2NodeID],
RenderedProcesses[fixture.ServerProcessNodeID],
RenderedContainers[fixture.ClientContainerNodeID],
RenderedContainers[fixture.ServerContainerNodeID],
RenderedPods[fixture.ClientPodNodeID],
RenderedPods[fixture.ServerPodNodeID],
WithChildren(report.MakeIDList(
fixture.Client54001NodeID,
fixture.Client54002NodeID,
fixture.Server80NodeID,
fixture.ClientProcess1NodeID,
fixture.ClientProcess2NodeID,
fixture.ServerProcessNodeID,
fixture.ClientContainerNodeID,
fixture.ServerContainerNodeID,
fixture.ClientPodNodeID,
fixture.ServerPodNodeID,
)),
UnmanagedServerID: unmanagedServerNode,
@@ -359,14 +349,14 @@ var (
AddCounter(report.ContainerImage, 1).
AddCounter(report.Pod, 1).
AddCounter(report.Process, 2).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Client54001NodeID],
RenderedEndpoints[fixture.Client54002NodeID],
RenderedProcesses[fixture.ClientProcess1NodeID],
RenderedProcesses[fixture.ClientProcess2NodeID],
RenderedContainers[fixture.ClientContainerNodeID],
RenderedContainerImages[ClientContainerImageNodeID],
RenderedPods[fixture.ClientPodNodeID],
WithChildren(report.MakeIDList(
fixture.Client54001NodeID,
fixture.Client54002NodeID,
fixture.ClientProcess1NodeID,
fixture.ClientProcess2NodeID,
fixture.ClientContainerNodeID,
ClientContainerImageNodeID,
fixture.ClientPodNodeID,
)),
fixture.ServerHostNodeID: hostNode(fixture.ServerHostNodeID, render.OutgoingInternetID).
@@ -374,15 +364,15 @@ var (
AddCounter(report.ContainerImage, 1).
AddCounter(report.Pod, 1).
AddCounter(report.Process, 2).
WithChildren(report.MakeNodeSet(
RenderedEndpoints[fixture.Server80NodeID],
RenderedEndpoints[fixture.NonContainerNodeID],
RenderedProcesses[fixture.ServerProcessNodeID],
RenderedProcesses[fixture.NonContainerProcessNodeID],
RenderedContainers[fixture.ServerContainerNodeID],
RenderedContainers[fixture.ServerContainer2NodeID],
RenderedContainerImages[ServerContainerImageNodeID],
RenderedPods[fixture.ServerPodNodeID],
WithChildren(report.MakeIDList(
fixture.Server80NodeID,
fixture.NonContainerNodeID,
fixture.ServerProcessNodeID,
fixture.NonContainerProcessNodeID,
fixture.ServerContainerNodeID,
fixture.ServerContainer2NodeID,
ServerContainerImageNodeID,
fixture.ServerPodNodeID,
)),
// due to https://github.com/weaveworks/scope/issues/1323 we are dropping

View File

@@ -52,7 +52,7 @@ func ParseGroupNodeTopology(topology string) (string, string, bool) {
// NewDerivedNode makes a node based on node, but with a new ID
func NewDerivedNode(id string, node report.Node) report.Node {
return report.MakeNode(id).WithChildren(node.Children.Add(node))
return report.MakeNode(id).WithChildren(node.ChildIDs.Add(node.ID))
}
// NewDerivedPseudoNode makes a new pseudo node with the node as a child

View File

@@ -22,11 +22,13 @@ type propagateSingleMetrics struct {
func (p propagateSingleMetrics) Render(ctx context.Context, rpt report.Report) Nodes {
nodes := p.r.Render(ctx, rpt)
outputs := make(report.Nodes, len(nodes.Nodes))
topology, _ := rpt.Topology(p.topology)
for id, n := range nodes.Nodes {
var first report.Node
found := 0
n.Children.ForEach(func(child report.Node) {
if child.Topology == p.topology {
for _, childID := range n.ChildIDs {
if ty, ok := report.NodeIDType(childID); ok && ty == p.topology {
child := topology.Nodes[childID]
if _, ok := child.Latest.Lookup(report.DoesNotMakeConnections); !ok {
if found == 0 {
first = child
@@ -34,7 +36,7 @@ func (p propagateSingleMetrics) Render(ctx context.Context, rpt report.Report) N
found++
}
}
})
}
if found == 1 {
n = n.WithMetrics(first.Metrics)
}

View File

@@ -13,6 +13,36 @@ import (
func TestPropagateSingleMetrics(t *testing.T) {
now := time.Now()
empty := report.MakeNode("empty")
child1 := report.MakeNode(report.MakeContainerNodeID("child1")).
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
})
child2 := report.MakeNode(report.MakeContainerNodeID("child2")).
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
})
child2p := report.MakeNode(report.MakeProcessNodeID("host1", "child2")).
WithTopology("Process").
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
})
pause := report.MakeNode(report.MakeContainerNodeID("pause")).
WithLatest(report.DoesNotMakeConnections, now, "").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
})
a := report.MakeNode("a").WithChildID(child1.ID)
rpt := report.MakeReport()
rpt.Container.AddNode(empty)
rpt.Container.AddNode(a)
rpt.Container.AddNode(child1)
rpt.Container.AddNode(child2)
rpt.Container.AddNode(pause)
rpt.Process.AddNode(child2p)
for _, c := range []struct {
name string
input report.Node
@@ -21,146 +51,50 @@ func TestPropagateSingleMetrics(t *testing.T) {
}{
{
name: "empty",
input: report.MakeNode("empty"),
input: empty,
topology: "",
output: report.Nodes{"empty": report.MakeNode("empty")},
},
{
name: "one child",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
),
),
name: "one child",
input: a,
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}).WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
),
),
}).WithChildID(child1.ID),
},
},
{
name: "ignores other topologies",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
report.MakeNode("child2").
WithTopology("otherTopology").
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
}),
),
),
name: "ignores other topologies",
input: report.MakeNode("a").WithChildren(report.MakeIDList(child1.ID, child2p.ID)),
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}).WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
report.MakeNode("child2").
WithTopology("otherTopology").
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
}),
),
),
}).WithChildren(report.MakeIDList(child1.ID, child2p.ID)),
},
},
{
name: "two children",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
report.MakeNode("child2").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
}),
),
),
name: "two children",
input: report.MakeNode("a").WithChildren(report.MakeIDList(child1.ID, child2.ID)),
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
report.MakeNode("child2").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
}),
),
),
"a": report.MakeNode("a").WithChildren(report.MakeIDList(child1.ID, child2.ID)),
},
},
{
name: "ignores k8s pause container",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
report.MakeNode("child2").
WithLatest(report.DoesNotMakeConnections, now, "").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
}),
),
),
name: "ignores k8s pause container",
input: report.MakeNode("a").WithChildren(report.MakeIDList(child1.ID, pause.ID)),
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}).WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(nil),
}),
report.MakeNode("child2").
WithLatest(report.DoesNotMakeConnections, now, "").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(nil),
}),
),
),
}).WithChildren(report.MakeIDList(child1.ID, pause.ID)),
},
},
} {
got := render.PropagateSingleMetrics(c.topology, mockRenderer{report.Nodes{c.input.ID: c.input}}).Render(context.Background(), report.Report{}).Nodes
got := render.PropagateSingleMetrics(c.topology, mockRenderer{report.Nodes{c.input.ID: c.input}}).Render(context.Background(), rpt).Nodes
if !reflect.DeepEqual(got, c.output) {
t.Errorf("[%s] Diff: %s", c.name, test.Diff(c.output, got))
}

View File

@@ -33,7 +33,7 @@ func (v volumesRenderer) Render(ctx context.Context, rpt report.Report) Nodes {
volumeName, _ := p.Latest.Lookup(report.KubernetesName)
if volume == volumeName {
n.Adjacency = n.Adjacency.Add(p.ID)
n.Children = n.Children.Add(p)
n = n.WithChildID(p.ID)
}
}
nodes[id] = n
@@ -65,7 +65,7 @@ func (v podToVolumesRenderer) Render(ctx context.Context, rpt report.Report) Nod
pvcNamespace, _ := pvcNode.Latest.Lookup(report.KubernetesNamespace)
if (pvcName == ClaimName) && (podNamespace == pvcNamespace) {
podNode.Adjacency = podNode.Adjacency.Add(pvcNode.ID)
podNode.Children = podNode.Children.Add(pvcNode)
podNode = podNode.WithChildID(pvcNode.ID)
break
}
}
@@ -91,7 +91,7 @@ func (v pvcToStorageClassRenderer) Render(ctx context.Context, rpt report.Report
storageClassName, _ := pvcNode.Latest.Lookup(report.KubernetesStorageClassName)
if storageClassName == storageClass {
scNode.Adjacency = scNode.Adjacency.Add(pvcNode.ID)
scNode.Children = scNode.Children.Add(pvcNode)
scNode = scNode.WithChildID(pvcNode.ID)
}
}
nodes[scID] = scNode
@@ -114,7 +114,7 @@ func (v pvToSnapshotRenderer) Render(ctx context.Context, rpt report.Report) Nod
snapshotPVName, _ := volumeSnapshotNode.Latest.Lookup(report.KubernetesVolumeName)
if volumeName == snapshotPVName {
p.Adjacency = p.Adjacency.Add(volumeSnapshotNode.ID)
p.Children = p.Children.Add(volumeSnapshotNode)
p = p.WithChildID(volumeSnapshotNode.ID)
}
}
nodes[pvNodeID] = p
@@ -138,7 +138,7 @@ func (v volumeSnapshotRenderer) Render(ctx context.Context, rpt report.Report) N
snapshotDataName, _ := volumeSnapshotDataNode.Latest.Lookup(report.KubernetesName)
if snapshotDataName == snapshotData {
volumeSnapshotNode.Adjacency = volumeSnapshotNode.Adjacency.Add(volumeSnapshotDataNode.ID)
volumeSnapshotNode.Children = volumeSnapshotNode.Children.Add(volumeSnapshotDataNode)
volumeSnapshotNode = volumeSnapshotNode.WithChildID(volumeSnapshotDataNode.ID)
}
nodes[volumeSnapshotDataID] = volumeSnapshotDataNode
}

View File

@@ -161,8 +161,7 @@ type joinResults struct {
func newJoinResults(inputNodes report.Nodes) joinResults {
nodes := make(report.Nodes, len(inputNodes))
for id, n := range inputNodes {
n.Adjacency = nil // result() assumes all nodes start with no adjacencies
n.Children = n.Children.Copy() // so we can do unsafe adds
n.Adjacency = nil // result() assumes all nodes start with no adjacencies
nodes[id] = n
}
return joinResults{nodes: nodes, mapped: map[string]string{}, multi: map[string][]string{}}
@@ -193,7 +192,7 @@ func (ret *joinResults) addUnmappedChild(m report.Node, id string, topology stri
if !exists {
result = report.MakeNode(id).WithTopology(topology)
}
result.Children.UnsafeAdd(m)
result = result.WithChildID(m.ID)
if m.Topology != report.Endpoint { // optimisation: we never look at endpoint counts
result = result.AddCounter(m.Topology, 1)
}
@@ -212,7 +211,7 @@ func (ret *joinResults) addChild(m report.Node, id string, topology string) {
func (ret *joinResults) addChildAndChildren(m report.Node, id string, topology string) {
ret.addUnmappedChild(m, id, topology)
result := ret.nodes[id]
result.Children.UnsafeMerge(m.Children)
result = result.WithChildren(m.ChildIDs)
ret.nodes[id] = result
ret.mapChild(m.ID, id)
}
@@ -221,7 +220,6 @@ func (ret *joinResults) addChildAndChildren(m report.Node, id string, topology s
func (ret *joinResults) passThrough(n report.Node) {
n.Adjacency = nil // result() assumes all nodes start with no adjacencies
ret.nodes[n.ID] = n
n.Children = n.Children.Copy() // so we can do unsafe adds
ret.mapChild(n.ID, n.ID)
}