From f1904a626f885d826d69ecfbf5ad9277c080fd02 Mon Sep 17 00:00:00 2001 From: Filip Barl Date: Wed, 15 Feb 2017 16:15:48 +0100 Subject: [PATCH 1/2] Fix filtering issue for uncontained nodes in DNS name view (#2170). --- render/container.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/render/container.go b/render/container.go index a79dee7d8..77ca2ef35 100644 --- a/render/container.go +++ b/render/container.go @@ -23,7 +23,7 @@ const ( // NB We only want processes in container _or_ processes with network connections // but we need to be careful to ensure we only include each edge once, by only // including the ProcessRenderer once. -var ContainerRenderer = MakeFilter( +var ContainerRenderer = ApplyDecorators(MakeFilter( func(n report.Node) bool { // Drop deleted containers state, ok := n.Latest.Lookup(docker.ContainerState) @@ -43,7 +43,7 @@ var ContainerRenderer = MakeFilter( SelectContainer, ), -) +)) const originalNodeID = "original_node_id" const originalNodeTopology = "original_node_topology" @@ -204,7 +204,7 @@ func (r containerWithImageNameRenderer) Render(rpt report.Report, dct Decorator) // ContainerWithImageNameRenderer is a Renderer which produces a container // graph where the ranks are the image names, not their IDs -var ContainerWithImageNameRenderer = ApplyDecorators(containerWithImageNameRenderer{ContainerRenderer}) +var ContainerWithImageNameRenderer = containerWithImageNameRenderer{ContainerRenderer} // ContainerImageRenderer is a Renderer which produces a renderable container // image graph by merging the container graph and the container image topology. From 2e9255b190e15321240dbeaf6002eae5f8aeebfa Mon Sep 17 00:00:00 2001 From: Filip Barl Date: Fri, 17 Feb 2017 14:21:53 +0100 Subject: [PATCH 2/2] Addressed the comments and fixed the tests. --- app/api_topologies.go | 5 +- app/api_topologies_test.go | 62 ++++++++++++++++++++ render/container.go | 4 +- render/container_test.go | 81 ++++++++++---------------- render/ecs.go | 32 +++++----- render/host.go | 4 +- render/host_test.go | 5 +- render/pod.go | 52 ++++++++--------- render/pod_test.go | 23 +++++--- render/process.go | 4 +- render/process_test.go | 13 +++-- render/render.go | 5 +- render/render_test.go | 25 -------- render/short_lived_connections_test.go | 5 +- test/utils/prune.go | 30 ++++++++++ 15 files changed, 200 insertions(+), 150 deletions(-) create mode 100644 test/utils/prune.go diff --git a/app/api_topologies.go b/app/api_topologies.go index fdef6e8ab..ecc44fc85 100644 --- a/app/api_topologies.go +++ b/app/api_topologies.go @@ -439,7 +439,10 @@ func (r *Registry) RendererForTopology(topologyID string, values url.Values, rpt } } if len(decorators) > 0 { - return topology.renderer, render.ComposeDecorators(decorators...), nil + // Here we tell the topology renderer to apply the filtering decorator + // that we construct as a composition of all the selected filters. + composedFilterDecorator := render.ComposeDecorators(decorators...) + return render.ApplyDecorator(topology.renderer), composedFilterDecorator, nil } return topology.renderer, nil, nil } diff --git a/app/api_topologies_test.go b/app/api_topologies_test.go index 87a6500da..ed28e0c33 100644 --- a/app/api_topologies_test.go +++ b/app/api_topologies_test.go @@ -11,12 +11,17 @@ import ( "github.com/ugorji/go/codec" "k8s.io/kubernetes/pkg/api" + "github.com/weaveworks/common/test" "github.com/weaveworks/scope/app" + "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/kubernetes" "github.com/weaveworks/scope/render" "github.com/weaveworks/scope/render/detailed" + "github.com/weaveworks/scope/render/expected" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test/fixture" + "github.com/weaveworks/scope/test/reflect" + "github.com/weaveworks/scope/test/utils" ) const ( @@ -91,6 +96,63 @@ func TestContainerLabelFilterExclude(t *testing.T) { } } +func TestRendererForTopologyWithFiltering(t *testing.T) { + ts := topologyServer() + defer ts.Close() + + topologyRegistry := app.MakeRegistry() + option := app.MakeAPITopologyOption(customAPITopologyOptionFilterID, "title", render.IsApplication, false) + topologyRegistry.AddContainerFilters(option) + + urlvalues := url.Values{} + urlvalues.Set(systemGroupID, customAPITopologyOptionFilterID) + renderer, decorator, err := topologyRegistry.RendererForTopology("containers", urlvalues, fixture.Report) + if err != nil { + t.Fatalf("Topology Registry Report error: %s", err) + } + + input := fixture.Report.Copy() + input.Container.Nodes[fixture.ClientContainerNodeID] = input.Container.Nodes[fixture.ClientContainerNodeID].WithLatests(map[string]string{ + docker.LabelPrefix + "works.weave.role": "system", + }) + have := utils.Prune(renderer.Render(input, decorator)) + want := utils.Prune(expected.RenderedContainers.Copy()) + delete(want, fixture.ClientContainerNodeID) + delete(want, render.MakePseudoNodeID(render.UncontainedID, fixture.ServerHostID)) + delete(want, render.OutgoingInternetID) + if !reflect.DeepEqual(want, have) { + t.Error(test.Diff(want, have)) + } +} + +func TestRendererForTopologyNoFiltering(t *testing.T) { + ts := topologyServer() + defer ts.Close() + + topologyRegistry := app.MakeRegistry() + option := app.MakeAPITopologyOption(customAPITopologyOptionFilterID, "title", nil, false) + topologyRegistry.AddContainerFilters(option) + + urlvalues := url.Values{} + urlvalues.Set(systemGroupID, customAPITopologyOptionFilterID) + renderer, decorator, err := topologyRegistry.RendererForTopology("containers", urlvalues, fixture.Report) + if err != nil { + t.Fatalf("Topology Registry Report error: %s", err) + } + + input := fixture.Report.Copy() + input.Container.Nodes[fixture.ClientContainerNodeID] = input.Container.Nodes[fixture.ClientContainerNodeID].WithLatests(map[string]string{ + docker.LabelPrefix + "works.weave.role": "system", + }) + have := utils.Prune(renderer.Render(input, decorator)) + want := utils.Prune(expected.RenderedContainers.Copy()) + delete(want, render.MakePseudoNodeID(render.UncontainedID, fixture.ServerHostID)) + delete(want, render.OutgoingInternetID) + if !reflect.DeepEqual(want, have) { + t.Error(test.Diff(want, have)) + } +} + func getTestContainerLabelFilterTopologySummary(t *testing.T, exclude bool) (detailed.NodeSummaries, error) { ts := topologyServer() defer ts.Close() diff --git a/render/container.go b/render/container.go index 77ca2ef35..1a4670c91 100644 --- a/render/container.go +++ b/render/container.go @@ -23,7 +23,7 @@ const ( // NB We only want processes in container _or_ processes with network connections // but we need to be careful to ensure we only include each edge once, by only // including the ProcessRenderer once. -var ContainerRenderer = ApplyDecorators(MakeFilter( +var ContainerRenderer = MakeFilter( func(n report.Node) bool { // Drop deleted containers state, ok := n.Latest.Lookup(docker.ContainerState) @@ -43,7 +43,7 @@ var ContainerRenderer = ApplyDecorators(MakeFilter( SelectContainer, ), -)) +) const originalNodeID = "original_node_id" const originalNodeTopology = "original_node_topology" diff --git a/render/container_test.go b/render/container_test.go index 5eb3fb2fd..d873c601b 100644 --- a/render/container_test.go +++ b/render/container_test.go @@ -13,6 +13,7 @@ import ( "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test/fixture" "github.com/weaveworks/scope/test/reflect" + "github.com/weaveworks/scope/test/utils" ) // FilterApplication is a Renderer which filters out application nodes. @@ -20,6 +21,11 @@ func FilterApplication(r render.Renderer) render.Renderer { return render.MakeFilter(render.IsApplication, r) } +// FilterSystem is a Renderer which filters out system nodes. +func FilterSystem(r render.Renderer) render.Renderer { + return render.MakeFilter(render.IsSystem, r) +} + // FilterNoop does nothing. func FilterNoop(r render.Renderer) render.Renderer { return r } @@ -55,8 +61,8 @@ func testMap(t *testing.T, f render.MapFunc, input testcase) { } func TestContainerRenderer(t *testing.T) { - have := Prune(render.ContainerWithImageNameRenderer.Render(fixture.Report, FilterNoop)) - want := Prune(expected.RenderedContainers) + have := utils.Prune(render.ContainerWithImageNameRenderer.Render(fixture.Report, FilterNoop)) + want := utils.Prune(expected.RenderedContainers) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } @@ -66,11 +72,14 @@ func TestContainerFilterRenderer(t *testing.T) { // tag on of the containers in the topology and ensure // it is filtered out correctly. input := fixture.Report.Copy() + renderer := render.ApplyDecorator(render.ContainerWithImageNameRenderer) + input.Container.Nodes[fixture.ClientContainerNodeID] = input.Container.Nodes[fixture.ClientContainerNodeID].WithLatests(map[string]string{ docker.LabelPrefix + "works.weave.role": "system", }) - have := Prune(render.ContainerWithImageNameRenderer.Render(input, FilterApplication)) - want := Prune(expected.RenderedContainers.Copy()) + + have := utils.Prune(renderer.Render(input, FilterApplication)) + want := utils.Prune(expected.RenderedContainers.Copy()) delete(want, fixture.ClientContainerNodeID) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -78,70 +87,42 @@ func TestContainerFilterRenderer(t *testing.T) { } func TestContainerHostnameRenderer(t *testing.T) { - have := Prune(render.ContainerHostnameRenderer.Render(fixture.Report, FilterNoop)) - want := Prune(expected.RenderedContainerHostnames) + renderer := render.ApplyDecorator(render.ContainerHostnameRenderer) + have := utils.Prune(renderer.Render(fixture.Report, FilterNoop)) + want := utils.Prune(expected.RenderedContainerHostnames) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } func TestContainerHostnameFilterRenderer(t *testing.T) { - // add a system container into the topology and ensure - // it is filtered out correctly. - input := fixture.Report.Copy() - - clientContainer2ID := "f6g7h8i9j1" - clientContainer2NodeID := report.MakeContainerNodeID(clientContainer2ID) - input.Container.AddNode(report.MakeNodeWith(clientContainer2NodeID, map[string]string{ - docker.LabelPrefix + "works.weave.role": "system", - docker.ContainerHostname: fixture.ClientContainerHostname, - report.HostNodeID: fixture.ClientHostNodeID, - }). - WithParents(report.EmptySets. - Add("host", report.MakeStringSet(fixture.ClientHostNodeID)), - ).WithTopology(report.Container)) - - have := Prune(render.ContainerHostnameRenderer.Render(input, FilterApplication)) - want := Prune(expected.RenderedContainerHostnames) - // Test works by virtue of the RenderedContainerHostname only having a container - // counter == 1 - + renderer := render.ApplyDecorator(render.ContainerHostnameRenderer) + have := utils.Prune(renderer.Render(fixture.Report, FilterSystem)) + want := utils.Prune(expected.RenderedContainerHostnames.Copy()) + delete(want, fixture.ClientContainerHostname) + delete(want, fixture.ServerContainerHostname) + delete(want, render.IncomingInternetID) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } func TestContainerImageRenderer(t *testing.T) { - have := Prune(render.ContainerImageRenderer.Render(fixture.Report, FilterNoop)) - want := Prune(expected.RenderedContainerImages) + renderer := render.ApplyDecorator(render.ContainerImageRenderer) + have := utils.Prune(renderer.Render(fixture.Report, FilterNoop)) + want := utils.Prune(expected.RenderedContainerImages) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } func TestContainerImageFilterRenderer(t *testing.T) { - // add a system container into the topology and ensure - // it is filtered out correctly. - input := fixture.Report.Copy() - - clientContainer2ID := "f6g7h8i9j1" - clientContainer2NodeID := report.MakeContainerNodeID(clientContainer2ID) - input.Container.AddNode(report.MakeNodeWith(clientContainer2NodeID, map[string]string{ - docker.LabelPrefix + "works.weave.role": "system", - - docker.ImageID: fixture.ClientContainerImageID, - docker.ImageName: fixture.ClientContainerImageName, - report.HostNodeID: fixture.ClientHostNodeID, - }). - WithParents(report.EmptySets. - Add("host", report.MakeStringSet(fixture.ClientHostNodeID)), - ).WithTopology(report.ContainerImage)) - - have := Prune(render.ContainerImageRenderer.Render(input, FilterApplication)) - want := Prune(expected.RenderedContainerImages.Copy()) - // Test works by virtue of the RenderedContainerImage only having a container - // counter == 1 - + renderer := render.ApplyDecorator(render.ContainerImageRenderer) + have := utils.Prune(renderer.Render(fixture.Report, FilterSystem)) + want := utils.Prune(expected.RenderedContainerHostnames.Copy()) + delete(want, fixture.ClientContainerHostname) + delete(want, fixture.ServerContainerHostname) + delete(want, render.IncomingInternetID) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } diff --git a/render/ecs.go b/render/ecs.go index 10ba0e75a..bf46d2c84 100644 --- a/render/ecs.go +++ b/render/ecs.go @@ -9,32 +9,28 @@ import ( // ECSTaskRenderer is a Renderer for Amazon ECS tasks. var ECSTaskRenderer = ConditionalRenderer(renderECSTopologies, - ApplyDecorators( - MakeMap( - PropagateSingleMetrics(report.Container), - MakeReduce( - MakeMap( - MapContainer2ECSTask, - ContainerWithImageNameRenderer, - ), - SelectECSTask, + MakeMap( + PropagateSingleMetrics(report.Container), + MakeReduce( + MakeMap( + MapContainer2ECSTask, + ContainerWithImageNameRenderer, ), + SelectECSTask, ), ), ) // ECSServiceRenderer is a Renderer for Amazon ECS services. var ECSServiceRenderer = ConditionalRenderer(renderECSTopologies, - ApplyDecorators( - MakeMap( - PropagateSingleMetrics(report.ECSTask), - MakeReduce( - MakeMap( - Map2Parent(report.ECSService), - ECSTaskRenderer, - ), - SelectECSService, + MakeMap( + PropagateSingleMetrics(report.ECSTask), + MakeReduce( + MakeMap( + Map2Parent(report.ECSService), + ECSTaskRenderer, ), + SelectECSService, ), ), ) diff --git a/render/host.go b/render/host.go index 19b4cf3b0..f56c28035 100644 --- a/render/host.go +++ b/render/host.go @@ -6,7 +6,7 @@ import ( // HostRenderer is a Renderer which produces a renderable host // graph from the host topology. -var HostRenderer = ApplyDecorators(MakeReduce( +var HostRenderer = MakeReduce( MakeMap( MapEndpoint2Host, EndpointRenderer, @@ -28,7 +28,7 @@ var HostRenderer = ApplyDecorators(MakeReduce( PodRenderer, ), SelectHost, -)) +) // MapX2Host maps any Nodes to host Nodes. // diff --git a/render/host_test.go b/render/host_test.go index a4e244772..93660bc03 100644 --- a/render/host_test.go +++ b/render/host_test.go @@ -8,11 +8,12 @@ import ( "github.com/weaveworks/scope/render/expected" "github.com/weaveworks/scope/test/fixture" "github.com/weaveworks/scope/test/reflect" + "github.com/weaveworks/scope/test/utils" ) func TestHostRenderer(t *testing.T) { - have := Prune(render.HostRenderer.Render(fixture.Report, FilterNoop)) - want := Prune(expected.RenderedHosts) + have := utils.Prune(render.HostRenderer.Render(fixture.Report, FilterNoop)) + want := utils.Prune(expected.RenderedHosts) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } diff --git a/render/pod.go b/render/pod.go index 66a555e2d..8194163a5 100644 --- a/render/pod.go +++ b/render/pod.go @@ -21,7 +21,7 @@ func renderKubernetesTopologies(rpt report.Report) bool { // PodRenderer is a Renderer which produces a renderable kubernetes // graph by merging the container graph and the pods topology. var PodRenderer = ConditionalRenderer(renderKubernetesTopologies, - ApplyDecorators(MakeFilter( + MakeFilter( func(n report.Node) bool { state, ok := n.Latest.Lookup(kubernetes.State) return (!ok || state != kubernetes.StateDeleted) @@ -37,22 +37,20 @@ var PodRenderer = ConditionalRenderer(renderKubernetesTopologies, SelectPod, ), ), - )), + ), ) // PodServiceRenderer is a Renderer which produces a renderable kubernetes services // graph by merging the pods graph and the services topology. var PodServiceRenderer = ConditionalRenderer(renderKubernetesTopologies, - ApplyDecorators( - MakeMap( - PropagateSingleMetrics(report.Pod), - MakeReduce( - MakeMap( - Map2Service, - PodRenderer, - ), - SelectService, + MakeMap( + PropagateSingleMetrics(report.Pod), + MakeReduce( + MakeMap( + Map2Service, + PodRenderer, ), + SelectService, ), ), ) @@ -60,16 +58,14 @@ var PodServiceRenderer = ConditionalRenderer(renderKubernetesTopologies, // DeploymentRenderer is a Renderer which produces a renderable kubernetes deployments // graph by merging the pods graph and the deployments topology. var DeploymentRenderer = ConditionalRenderer(renderKubernetesTopologies, - ApplyDecorators( - MakeMap( - PropagateSingleMetrics(report.ReplicaSet), - MakeReduce( - MakeMap( - Map2Deployment, - ReplicaSetRenderer, - ), - SelectDeployment, + MakeMap( + PropagateSingleMetrics(report.ReplicaSet), + MakeReduce( + MakeMap( + Map2Deployment, + ReplicaSetRenderer, ), + SelectDeployment, ), ), ) @@ -77,16 +73,14 @@ var DeploymentRenderer = ConditionalRenderer(renderKubernetesTopologies, // ReplicaSetRenderer is a Renderer which produces a renderable kubernetes replica sets // graph by merging the pods graph and the replica sets topology. var ReplicaSetRenderer = ConditionalRenderer(renderKubernetesTopologies, - ApplyDecorators( - MakeMap( - PropagateSingleMetrics(report.Pod), - MakeReduce( - MakeMap( - Map2ReplicaSet, - PodRenderer, - ), - SelectReplicaSet, + MakeMap( + PropagateSingleMetrics(report.Pod), + MakeReduce( + MakeMap( + Map2ReplicaSet, + PodRenderer, ), + SelectReplicaSet, ), ), ) diff --git a/render/pod_test.go b/render/pod_test.go index 75a02b6d2..1fa56f934 100644 --- a/render/pod_test.go +++ b/render/pod_test.go @@ -9,11 +9,12 @@ import ( "github.com/weaveworks/scope/render/expected" "github.com/weaveworks/scope/test/fixture" "github.com/weaveworks/scope/test/reflect" + "github.com/weaveworks/scope/test/utils" ) func TestPodRenderer(t *testing.T) { - have := Prune(render.PodRenderer.Render(fixture.Report, nil)) - want := Prune(expected.RenderedPods) + have := utils.Prune(render.PodRenderer.Render(fixture.Report, nil)) + want := utils.Prune(expected.RenderedPods) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } @@ -27,11 +28,14 @@ func TestPodFilterRenderer(t *testing.T) { // tag on containers or pod namespace in the topology and ensure // it is filtered out correctly. input := fixture.Report.Copy() + renderer := render.ApplyDecorator(render.PodRenderer) + input.Pod.Nodes[fixture.ClientPodNodeID] = input.Pod.Nodes[fixture.ClientPodNodeID].WithLatests(map[string]string{ kubernetes.Namespace: "kube-system", }) - have := Prune(render.PodRenderer.Render(input, filterNonKubeSystem)) - want := Prune(expected.RenderedPods.Copy()) + + have := utils.Prune(renderer.Render(input, filterNonKubeSystem)) + want := utils.Prune(expected.RenderedPods.Copy()) delete(want, fixture.ClientPodNodeID) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -39,8 +43,8 @@ func TestPodFilterRenderer(t *testing.T) { } func TestPodServiceRenderer(t *testing.T) { - have := Prune(render.PodServiceRenderer.Render(fixture.Report, nil)) - want := Prune(expected.RenderedPodServices) + have := utils.Prune(render.PodServiceRenderer.Render(fixture.Report, nil)) + want := utils.Prune(expected.RenderedPodServices) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } @@ -50,11 +54,14 @@ func TestPodServiceFilterRenderer(t *testing.T) { // tag on containers or pod namespace in the topology and ensure // it is filtered out correctly. input := fixture.Report.Copy() + renderer := render.ApplyDecorator(render.PodServiceRenderer) + input.Service.Nodes[fixture.ServiceNodeID] = input.Service.Nodes[fixture.ServiceNodeID].WithLatests(map[string]string{ kubernetes.Namespace: "kube-system", }) - have := Prune(render.PodServiceRenderer.Render(input, filterNonKubeSystem)) - want := Prune(expected.RenderedPodServices.Copy()) + + have := utils.Prune(renderer.Render(input, filterNonKubeSystem)) + want := utils.Prune(expected.RenderedPodServices.Copy()) delete(want, fixture.ServiceNodeID) delete(want, render.IncomingInternetID) if !reflect.DeepEqual(want, have) { diff --git a/render/process.go b/render/process.go index 982a52ebd..82d756fb8 100644 --- a/render/process.go +++ b/render/process.go @@ -28,13 +28,13 @@ var EndpointRenderer = FilterNonProcspied(SelectEndpoint) // ProcessRenderer is a Renderer which produces a renderable process // graph by merging the endpoint graph and the process topology. var ProcessRenderer = ConditionalRenderer(renderProcesses, - ApplyDecorators(ColorConnected(MakeReduce( + ColorConnected(MakeReduce( MakeMap( MapEndpoint2Process, EndpointRenderer, ), SelectProcess, - ))), + )), ) // processWithContainerNameRenderer is a Renderer which produces a process diff --git a/render/process_test.go b/render/process_test.go index 7881b6bc2..a9f620958 100644 --- a/render/process_test.go +++ b/render/process_test.go @@ -8,27 +8,28 @@ import ( "github.com/weaveworks/scope/render/expected" "github.com/weaveworks/scope/test/fixture" "github.com/weaveworks/scope/test/reflect" + "github.com/weaveworks/scope/test/utils" ) func TestEndpointRenderer(t *testing.T) { - have := Prune(render.EndpointRenderer.Render(fixture.Report, FilterNoop)) - want := Prune(expected.RenderedEndpoints) + have := utils.Prune(render.EndpointRenderer.Render(fixture.Report, FilterNoop)) + want := utils.Prune(expected.RenderedEndpoints) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } func TestProcessRenderer(t *testing.T) { - have := Prune(render.ProcessRenderer.Render(fixture.Report, FilterNoop)) - want := Prune(expected.RenderedProcesses) + have := utils.Prune(render.ProcessRenderer.Render(fixture.Report, FilterNoop)) + want := utils.Prune(expected.RenderedProcesses) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } func TestProcessNameRenderer(t *testing.T) { - have := Prune(render.ProcessNameRenderer.Render(fixture.Report, FilterNoop)) - want := Prune(expected.RenderedProcessNames) + have := utils.Prune(render.ProcessNameRenderer.Render(fixture.Report, FilterNoop)) + want := utils.Prune(expected.RenderedProcessNames) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } diff --git a/render/render.go b/render/render.go index 56928304f..415bc3ffb 100644 --- a/render/render.go +++ b/render/render.go @@ -146,9 +146,8 @@ func (ad applyDecorator) Stats(rpt report.Report, dct Decorator) Stats { return Stats{} } -// ApplyDecorators returns a renderer which will apply the given decorators -// to the child render. -func ApplyDecorators(renderer Renderer) Renderer { +// ApplyDecorator returns a renderer which will apply the given decorator to the child render. +func ApplyDecorator(renderer Renderer) Renderer { return applyDecorator{renderer} } diff --git a/render/render_test.go b/render/render_test.go index d334cc3d5..e6a0dc48b 100644 --- a/render/render_test.go +++ b/render/render_test.go @@ -21,31 +21,6 @@ func (m mockRenderer) Render(rpt report.Report, d render.Decorator) report.Nodes } func (m mockRenderer) Stats(rpt report.Report, _ render.Decorator) render.Stats { return render.Stats{} } -// Prune returns a copy of the Nodes with all information not strictly -// necessary for rendering nodes and edges in the UI cut away. -func Prune(nodes report.Nodes) report.Nodes { - result := report.Nodes{} - for id, node := range nodes { - result[id] = PruneNode(node) - } - return result -} - -// PruneNode returns a copy of the Node with all information not strictly -// necessary for rendering nodes and edges stripped away. Specifically, that -// means cutting out parts of the Node. -func PruneNode(node report.Node) report.Node { - prunedChildren := report.MakeNodeSet() - node.Children.ForEach(func(child report.Node) { - prunedChildren = prunedChildren.Add(PruneNode(child)) - }) - return report.MakeNode( - node.ID). - WithTopology(node.Topology). - WithAdjacent(node.Adjacency.Copy()...). - WithChildren(prunedChildren) -} - func TestReduceRender(t *testing.T) { renderer := render.Reduce([]render.Renderer{ mockRenderer{Nodes: report.Nodes{"foo": report.MakeNode("foo")}}, diff --git a/render/short_lived_connections_test.go b/render/short_lived_connections_test.go index f9bca6f69..3a3dfa9ff 100644 --- a/render/short_lived_connections_test.go +++ b/render/short_lived_connections_test.go @@ -11,6 +11,7 @@ import ( "github.com/weaveworks/scope/probe/host" "github.com/weaveworks/scope/render" "github.com/weaveworks/scope/report" + "github.com/weaveworks/scope/test/utils" ) var ( @@ -125,7 +126,7 @@ var ( ) func TestShortLivedInternetNodeConnections(t *testing.T) { - have := Prune(render.ContainerWithImageNameRenderer.Render(rpt, FilterNoop)) + have := utils.Prune(render.ContainerWithImageNameRenderer.Render(rpt, FilterNoop)) // Conntracked-only connections from the internet should be assigned to the internet pseudonode internet, ok := have[render.IncomingInternetID] @@ -139,7 +140,7 @@ func TestShortLivedInternetNodeConnections(t *testing.T) { } func TestPauseContainerDiscarded(t *testing.T) { - have := Prune(render.ContainerWithImageNameRenderer.Render(rpt, FilterNoop)) + have := utils.Prune(render.ContainerWithImageNameRenderer.Render(rpt, FilterNoop)) // There should only be a connection from container1 and the destination should be container2 container1, ok := have[container1NodeID] if !ok { diff --git a/test/utils/prune.go b/test/utils/prune.go new file mode 100644 index 000000000..8e158636a --- /dev/null +++ b/test/utils/prune.go @@ -0,0 +1,30 @@ +package utils + +import ( + "github.com/weaveworks/scope/report" +) + +// Prune returns a copy of the Nodes with all information not strictly +// necessary for rendering nodes and edges in the UI cut away. +func Prune(nodes report.Nodes) report.Nodes { + result := report.Nodes{} + for id, node := range nodes { + result[id] = PruneNode(node) + } + return result +} + +// PruneNode returns a copy of the Node with all information not strictly +// necessary for rendering nodes and edges stripped away. Specifically, that +// means cutting out parts of the Node. +func PruneNode(node report.Node) report.Node { + prunedChildren := report.MakeNodeSet() + node.Children.ForEach(func(child report.Node) { + prunedChildren = prunedChildren.Add(PruneNode(child)) + }) + return report.MakeNode( + node.ID). + WithTopology(node.Topology). + WithAdjacent(node.Adjacency.Copy()...). + WithChildren(prunedChildren) +}