diff --git a/app/api_topology_test.go b/app/api_topology_test.go index b9622a534..0663484c7 100644 --- a/app/api_topology_test.go +++ b/app/api_topology_test.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "net/http/httptest" "reflect" "testing" @@ -9,7 +10,8 @@ import ( "github.com/gorilla/websocket" "github.com/weaveworks/scope/render" - "github.com/weaveworks/scope/report" + "github.com/weaveworks/scope/render/expected" + "github.com/weaveworks/scope/test" ) func TestAPITopologyApplications(t *testing.T) { @@ -22,49 +24,36 @@ func TestAPITopologyApplications(t *testing.T) { if err := json.Unmarshal(body, &topo); err != nil { t.Fatal(err) } - equals(t, 4, len(topo.Nodes)) - node, ok := topo.Nodes["process:hostA:23128"] - if !ok { - t.Errorf("missing curl node") + + want := render.OnlyConnected(expected.RenderedProcesses) + if !reflect.DeepEqual(want, topo.Nodes) { + t.Error("\n" + test.Diff(want, topo.Nodes)) } - equals(t, 1, len(node.Adjacency)) - equals(t, report.MakeIDList("process:hostB:215"), node.Adjacency) - equals(t, report.MakeIDList( - report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345"), - report.MakeEndpointNodeID("hostA", "192.168.1.1", "12346"), - report.MakeProcessNodeID("hostA", "23128"), - report.MakeHostNodeID("hostA"), - ), node.Origins) - equals(t, "curl", node.LabelMajor) - equals(t, "hostA (23128)", node.LabelMinor) - equals(t, "23128", node.Rank) - equals(t, false, node.Pseudo) } { - body := getRawJSON(t, ts, "/api/topology/applications/process:hostA:23128") + body := getRawJSON(t, ts, "/api/topology/applications/"+expected.ServerProcessID) var node APINode if err := json.Unmarshal(body, &node); err != nil { t.Fatal(err) } - equals(t, "process:hostA:23128", node.Node.ID) - equals(t, "curl", node.Node.LabelMajor) - equals(t, "hostA (23128)", node.Node.LabelMinor) + equals(t, expected.ServerProcessID, node.Node.ID) + equals(t, "apache", node.Node.LabelMajor) + equals(t, fmt.Sprintf("%s (%s)", test.ServerHostID, test.ServerPID), node.Node.LabelMinor) equals(t, false, node.Node.Pseudo) // Let's not unit-test the specific content of the detail tables } { - body := getRawJSON(t, ts, "/api/topology/applications/process:hostA:23128/process:hostB:215") + body := getRawJSON(t, ts, fmt.Sprintf("/api/topology/applications/%s/%s", expected.ClientProcessID, expected.ServerProcessID)) var edge APIEdge if err := json.Unmarshal(body, &edge); err != nil { t.Fatalf("JSON parse error: %s", err) } want := render.AggregateMetadata{ - "egress_bytes": 24, - "ingress_bytes": 0, - "max_conn_count_tcp": 401, + "egress_bytes": 30, + "ingress_bytes": 300, } if !reflect.DeepEqual(want, edge.Metadata) { - t.Errorf("Edge metadata error. Want %v, have %v", want, edge) + t.Error("\n" + test.Diff(want, edge.Metadata)) } } } @@ -79,44 +68,31 @@ func TestAPITopologyHosts(t *testing.T) { if err := json.Unmarshal(body, &topo); err != nil { t.Fatal(err) } - equals(t, 3, len(topo.Nodes)) - node, ok := topo.Nodes["host:hostB"] - if !ok { - t.Errorf("missing host:hostB node") - t.Errorf("%+v", topo) + + if !reflect.DeepEqual(expected.RenderedHosts, topo.Nodes) { + t.Error("\n" + test.Diff(expected.RenderedHosts, topo.Nodes)) } - equals(t, report.MakeIDList("host:hostA"), node.Adjacency) - equals(t, report.MakeIDList( - report.MakeAddressNodeID("hostB", "192.168.1.2"), - report.MakeHostNodeID("hostB"), - ), node.Origins) - equals(t, "node-b", node.LabelMajor) - equals(t, "local", node.LabelMinor) - equals(t, "local", node.Rank) - equals(t, false, node.Pseudo) } { - body := getRawJSON(t, ts, "/api/topology/hosts/host:hostB") + body := getRawJSON(t, ts, "/api/topology/hosts/"+expected.ServerHostRenderedID) var node APINode if err := json.Unmarshal(body, &node); err != nil { t.Fatal(err) } - equals(t, "host:hostB", node.Node.ID) - equals(t, "node-b", node.Node.LabelMajor) - equals(t, "local", node.Node.LabelMinor) + equals(t, expected.ServerHostRenderedID, node.Node.ID) + equals(t, "server", node.Node.LabelMajor) + equals(t, "hostname.com", node.Node.LabelMinor) equals(t, false, node.Node.Pseudo) // Let's not unit-test the specific content of the detail tables } { - body := getRawJSON(t, ts, "/api/topology/hosts/host:hostB/host:hostA") + body := getRawJSON(t, ts, fmt.Sprintf("/api/topology/hosts/%s/%s", expected.ServerHostRenderedID, expected.ClientHostRenderedID)) var edge APIEdge if err := json.Unmarshal(body, &edge); err != nil { t.Fatalf("JSON parse error: %s", err) } want := render.AggregateMetadata{ - "egress_bytes": 0, - "ingress_bytes": 12, - "max_conn_count_tcp": 16, + "max_conn_count_tcp": 3, } if !reflect.DeepEqual(want, edge.Metadata) { t.Errorf("Edge metadata error. Want %v, have %v", want, edge) @@ -153,7 +129,7 @@ func TestAPITopologyWebsocket(t *testing.T) { if err := json.Unmarshal(p, &d); err != nil { t.Fatalf("JSON parse error: %s", err) } - equals(t, 4, len(d.Add)) + equals(t, 5, len(d.Add)) equals(t, 0, len(d.Update)) equals(t, 0, len(d.Remove)) } diff --git a/app/mock_reporter_test.go b/app/mock_reporter_test.go index 2e730026a..20c03dcad 100644 --- a/app/mock_reporter_test.go +++ b/app/mock_reporter_test.go @@ -1,176 +1,13 @@ package main import ( - "net" - "github.com/weaveworks/scope/report" + "github.com/weaveworks/scope/test" ) // StaticReport is used as know test data in api tests. type StaticReport struct{} func (s StaticReport) Report() report.Report { - _, localNet, err := net.ParseCIDR("192.168.1.1/24") - if err != nil { - panic(err.Error()) - } - - var testReport = report.Report{ - Endpoint: report.Topology{ - Adjacency: report.Adjacency{ - report.MakeAdjacencyID(report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345")): report.MakeIDList(report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")), - report.MakeAdjacencyID(report.MakeEndpointNodeID("hostA", "192.168.1.1", "12346")): report.MakeIDList(report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")), - report.MakeAdjacencyID(report.MakeEndpointNodeID("hostA", "192.168.1.1", "8888")): report.MakeIDList(report.MakeEndpointNodeID("", "1.2.3.4", "22")), - report.MakeAdjacencyID(report.MakeEndpointNodeID("hostB", "192.168.1.2", "80")): report.MakeIDList(report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345")), - }, - EdgeMetadatas: report.EdgeMetadatas{ - 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, - }, - 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, - }, - 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, - }, - 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, - WithConnCountTCP: true, - MaxConnCountTCP: 203, - }, - }, - NodeMetadatas: report.NodeMetadatas{ - report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345"): report.NodeMetadata{ - "addr": "192.168.1.1", - "port": "12345", - "pid": "23128", - report.HostNodeID: report.MakeHostNodeID("hostA"), - }, - report.MakeEndpointNodeID("hostA", "192.168.1.1", "12346"): report.NodeMetadata{ // <-- same as :12345 - "addr": "192.168.1.1", - "port": "12346", - "pid": "23128", - report.HostNodeID: report.MakeHostNodeID("hostA"), - }, - report.MakeEndpointNodeID("hostA", "192.168.1.1", "8888"): report.NodeMetadata{ - "addr": "192.168.1.1", - "port": "8888", - "pid": "55100", - report.HostNodeID: report.MakeHostNodeID("hostA"), - }, - report.MakeEndpointNodeID("hostB", "192.168.1.2", "80"): report.NodeMetadata{ - "addr": "192.168.1.2", - "port": "80", - "pid": "215", - report.HostNodeID: report.MakeHostNodeID("hostB"), - }, - }, - }, - - Process: report.Topology{ - NodeMetadatas: report.NodeMetadatas{ - report.MakeProcessNodeID("hostA", "23128"): report.NodeMetadata{ - "pid": "23128", - "comm": "curl", - report.HostNodeID: report.MakeHostNodeID("hostA"), - }, - report.MakeProcessNodeID("hostA", "8888"): report.NodeMetadata{ - "pid": "8888", - "comm": "ssh", - report.HostNodeID: report.MakeHostNodeID("hostA"), - }, - report.MakeProcessNodeID("hostB", "80"): report.NodeMetadata{ - "pid": "80", - "comm": "apache", - "docker_container_id": "abcdefg", - report.HostNodeID: report.MakeHostNodeID("hostB"), - }, - }, - }, - - Container: report.Topology{ - NodeMetadatas: report.NodeMetadatas{ - report.MakeContainerNodeID("hostB", "abcdefg"): report.NodeMetadata{ - "docker_container_id": "abcdefg", - "docker_container_name": "server", - report.HostNodeID: report.MakeHostNodeID("hostB"), - }, - }, - }, - - Address: report.Topology{ - Adjacency: report.Adjacency{ - report.MakeAdjacencyID(report.MakeAddressNodeID("hostA", "192.168.1.1")): report.MakeIDList(report.MakeAddressNodeID("hostB", "192.168.1.2"), report.MakeAddressNodeID("", "1.2.3.4")), - report.MakeAdjacencyID(report.MakeAddressNodeID("hostB", "192.168.1.2")): report.MakeIDList(report.MakeAddressNodeID("hostA", "192.168.1.1")), - }, - EdgeMetadatas: report.EdgeMetadatas{ - 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, - }, - 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, - }, - report.MakeEdgeID(report.MakeAddressNodeID("hostB", "192.168.1.2"), report.MakeAddressNodeID("hostA", "192.168.1.1")): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 0, - BytesIngress: 12, - WithConnCountTCP: true, - MaxConnCountTCP: 16, - }, - }, - NodeMetadatas: report.NodeMetadatas{ - report.MakeAddressNodeID("hostA", "192.168.1.1"): report.NodeMetadata{ - "addr": "192.168.1.1", - report.HostNodeID: report.MakeHostNodeID("hostA"), - }, - report.MakeAddressNodeID("hostB", "192.168.1.2"): report.NodeMetadata{ - "addr": "192.168.1.2", - report.HostNodeID: report.MakeHostNodeID("hostB"), - }, - }, - }, - - Host: report.Topology{ - Adjacency: report.Adjacency{}, - EdgeMetadatas: report.EdgeMetadatas{}, - NodeMetadatas: report.NodeMetadatas{ - report.MakeHostNodeID("hostA"): report.NodeMetadata{ - "host_name": "node-a.local", - "os": "Linux", - "local_networks": localNet.String(), - "load": "3.14 2.71 1.61", - report.HostNodeID: report.MakeHostNodeID("hostA"), - }, - report.MakeHostNodeID("hostB"): report.NodeMetadata{ - "host_name": "node-b.local", - "os": "Linux", - "local_networks": localNet.String(), - report.HostNodeID: report.MakeHostNodeID("hostB"), - }, - }, - }, - } - return testReport + return test.Report } diff --git a/app/origin_host_test.go b/app/origin_host_test.go index c814b95e1..08240f232 100644 --- a/app/origin_host_test.go +++ b/app/origin_host_test.go @@ -2,8 +2,11 @@ package main import ( "encoding/json" + "fmt" "net/http/httptest" "testing" + + "github.com/weaveworks/scope/test" ) func TestAPIOriginHost(t *testing.T) { @@ -15,7 +18,7 @@ func TestAPIOriginHost(t *testing.T) { { // Origin - body := getRawJSON(t, ts, "/api/origin/host/hostA;") // TODO MakeHostNodeID + body := getRawJSON(t, ts, fmt.Sprintf("/api/origin/host/%s", test.ServerHostNodeID)) var o OriginHost if err := json.Unmarshal(body, &o); err != nil { t.Fatalf("JSON parse error: %s", err) @@ -23,7 +26,7 @@ func TestAPIOriginHost(t *testing.T) { if want, have := "Linux", o.OS; want != have { t.Errorf("Origin error. Want %v, have %v", want, have) } - if want, have := "3.14 2.71 1.61", o.Load; want != have { + if want, have := "0.01 0.01 0.01", o.Load; want != have { t.Errorf("Origin error. Want %v, have %v", want, have) } } diff --git a/render/detailed_node_test.go b/render/detailed_node_test.go index a5ec42004..e2dc91183 100644 --- a/render/detailed_node_test.go +++ b/render/detailed_node_test.go @@ -9,46 +9,46 @@ import ( ) func TestOriginTable(t *testing.T) { - if _, ok := render.OriginTable(rpt, "not-found"); ok { + if _, ok := render.OriginTable(test.Report, "not-found"); ok { t.Errorf("unknown origin ID gave unexpected success") } for originID, want := range map[string]render.Table{ - client54001NodeID: { + test.Client54001NodeID: { Title: "Origin Endpoint", Numeric: false, Rows: []render.Row{ - {"Endpoint", clientIP, ""}, - {"Port", clientPort54001, ""}, + {"Endpoint", test.ClientIP, ""}, + {"Port", test.ClientPort54001, ""}, }, }, - clientAddressNodeID: { + test.ClientAddressNodeID: { Title: "Origin Address", Numeric: false, Rows: []render.Row{ - {"Address", clientIP, ""}, + {"Address", test.ClientIP, ""}, }, }, - serverProcessNodeID: { + test.ServerProcessNodeID: { Title: "Origin Process", Numeric: false, Rank: 2, Rows: []render.Row{ {"Name (comm)", "apache", ""}, - {"PID", serverPID, ""}, + {"PID", test.ServerPID, ""}, }, }, - serverHostNodeID: { + test.ServerHostNodeID: { Title: "Origin Host", Numeric: false, Rank: 1, Rows: []render.Row{ - {"Host name", serverHostName, ""}, + {"Host name", test.ServerHostName, ""}, {"Load", "0.01 0.01 0.01", ""}, {"Operating system", "Linux", ""}, }, }, } { - have, ok := render.OriginTable(rpt, originID) + have, ok := render.OriginTable(test.Report, originID) if !ok { t.Errorf("%q: not OK", originID) continue @@ -60,12 +60,12 @@ func TestOriginTable(t *testing.T) { } func TestMakeDetailedNode(t *testing.T) { - renderableNode := render.ContainerRenderer.Render(rpt)[serverContainerID] - have := render.MakeDetailedNode(rpt, renderableNode) + renderableNode := render.ContainerRenderer.Render(test.Report)[test.ServerContainerID] + have := render.MakeDetailedNode(test.Report, renderableNode) want := render.DetailedNode{ - ID: serverContainerID, + ID: test.ServerContainerID, LabelMajor: "server", - LabelMinor: serverHostName, + LabelMinor: test.ServerHostName, Pseudo: false, Tables: []render.Table{ { @@ -82,9 +82,9 @@ func TestMakeDetailedNode(t *testing.T) { Numeric: false, Rank: 3, Rows: []render.Row{ - {"ID", "5e4d3c2b1a", ""}, + {"ID", test.ServerContainerID, ""}, {"Name", "server", ""}, - {"Image ID", "imageid456", ""}, + {"Image ID", test.ServerContainerImageID, ""}, }, }, { @@ -93,7 +93,7 @@ func TestMakeDetailedNode(t *testing.T) { Rank: 2, Rows: []render.Row{ {"Name (comm)", "apache", ""}, - {"PID", "215", ""}, + {"PID", test.ServerPID, ""}, }, }, { @@ -101,7 +101,7 @@ func TestMakeDetailedNode(t *testing.T) { Numeric: false, Rank: 1, Rows: []render.Row{ - {"Host name", "server.hostname.com", ""}, + {"Host name", test.ServerHostName, ""}, {"Load", "0.01 0.01 0.01", ""}, {"Operating system", "Linux", ""}, }, @@ -110,8 +110,8 @@ func TestMakeDetailedNode(t *testing.T) { Title: "Origin Endpoint", Numeric: false, Rows: []render.Row{ - {"Endpoint", "192.168.1.1", ""}, - {"Port", "80", ""}, + {"Endpoint", test.ServerIP, ""}, + {"Port", test.ServerPort, ""}, }, }, }, diff --git a/render/expected/expected.go b/render/expected/expected.go new file mode 100644 index 000000000..5d3e11349 --- /dev/null +++ b/render/expected/expected.go @@ -0,0 +1,313 @@ +package expected + +import ( + "fmt" + + "github.com/weaveworks/scope/render" + "github.com/weaveworks/scope/report" + "github.com/weaveworks/scope/test" +) + +// Exported for testing. +var ( + uncontainedServerID = render.MakePseudoNodeID(render.UncontainedID, test.ServerHostName) + unknownPseudoNode1ID = render.MakePseudoNodeID("10.10.10.10", test.ServerIP, "80") + unknownPseudoNode2ID = render.MakePseudoNodeID("10.10.10.11", test.ServerIP, "80") + unknownPseudoNode1 = render.RenderableNode{ + ID: unknownPseudoNode1ID, + LabelMajor: "10.10.10.10", + Pseudo: true, + AggregateMetadata: render.AggregateMetadata{}, + } + unknownPseudoNode2 = render.RenderableNode{ + ID: unknownPseudoNode2ID, + LabelMajor: "10.10.10.11", + Pseudo: true, + AggregateMetadata: render.AggregateMetadata{}, + } + theInternetNode = render.RenderableNode{ + ID: render.TheInternetID, + LabelMajor: render.TheInternetMajor, + Pseudo: true, + AggregateMetadata: render.AggregateMetadata{}, + } + + ClientProcessID = render.MakeProcessID(test.ClientHostID, test.ClientPID) + ServerProcessID = render.MakeProcessID(test.ServerHostID, test.ServerPID) + nonContainerProcessID = render.MakeProcessID(test.ServerHostID, test.NonContainerPID) + + RenderedProcesses = render.RenderableNodes{ + ClientProcessID: { + ID: ClientProcessID, + LabelMajor: "curl", + LabelMinor: fmt.Sprintf("%s (%s)", test.ClientHostID, test.ClientPID), + Rank: test.ClientPID, + Pseudo: false, + Adjacency: report.MakeIDList(ServerProcessID), + Origins: report.MakeIDList( + test.Client54001NodeID, + test.Client54002NodeID, + test.ClientProcessNodeID, + test.ClientHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 300, + render.KeyBytesEgress: 30, + }, + }, + ServerProcessID: { + ID: ServerProcessID, + LabelMajor: "apache", + LabelMinor: fmt.Sprintf("%s (%s)", test.ServerHostID, test.ServerPID), + Rank: test.ServerPID, + Pseudo: false, + Adjacency: report.MakeIDList( + ClientProcessID, + unknownPseudoNode1ID, + unknownPseudoNode2ID, + render.TheInternetID, + ), + Origins: report.MakeIDList( + test.Server80NodeID, + test.ServerProcessNodeID, + test.ServerHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 150, + render.KeyBytesEgress: 1500, + }, + }, + nonContainerProcessID: { + ID: nonContainerProcessID, + LabelMajor: "bash", + LabelMinor: fmt.Sprintf("%s (%s)", test.ServerHostID, test.NonContainerPID), + Rank: test.NonContainerPID, + Pseudo: false, + Adjacency: report.MakeIDList(), + Origins: report.MakeIDList( + test.NonContainerProcessNodeID, + test.ServerHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{}, + }, + unknownPseudoNode1ID: unknownPseudoNode1, + unknownPseudoNode2ID: unknownPseudoNode2, + render.TheInternetID: theInternetNode, + } + + RenderedProcessNames = render.RenderableNodes{ + "curl": { + ID: "curl", + LabelMajor: "curl", + LabelMinor: "", + Rank: "curl", + Pseudo: false, + Adjacency: report.MakeIDList("apache"), + Origins: report.MakeIDList( + test.Client54001NodeID, + test.Client54002NodeID, + test.ClientProcessNodeID, + test.ClientHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 300, + render.KeyBytesEgress: 30, + }, + }, + "apache": { + ID: "apache", + LabelMajor: "apache", + LabelMinor: "", + Rank: "apache", + Pseudo: false, + Adjacency: report.MakeIDList( + "curl", + unknownPseudoNode1ID, + unknownPseudoNode2ID, + render.TheInternetID, + ), + Origins: report.MakeIDList( + test.Server80NodeID, + test.ServerProcessNodeID, + test.ServerHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 150, + render.KeyBytesEgress: 1500, + }, + }, + "bash": { + ID: "bash", + LabelMajor: "bash", + LabelMinor: "", + Rank: "bash", + Pseudo: false, + Origins: report.MakeIDList( + test.NonContainerProcessNodeID, + test.ServerHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{}, + }, + unknownPseudoNode1ID: unknownPseudoNode1, + unknownPseudoNode2ID: unknownPseudoNode2, + render.TheInternetID: theInternetNode, + } + + RenderedContainers = render.RenderableNodes{ + test.ClientContainerID: { + ID: test.ClientContainerID, + LabelMajor: "client", + LabelMinor: test.ClientHostName, + Rank: test.ClientContainerImageID, + Pseudo: false, + Adjacency: report.MakeIDList(test.ServerContainerID), + Origins: report.MakeIDList( + test.ClientContainerNodeID, + test.Client54001NodeID, + test.Client54002NodeID, + test.ClientProcessNodeID, + test.ClientHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 300, + render.KeyBytesEgress: 30, + }, + }, + test.ServerContainerID: { + ID: test.ServerContainerID, + LabelMajor: "server", + LabelMinor: test.ServerHostName, + Rank: test.ServerContainerImageID, + Pseudo: false, + Adjacency: report.MakeIDList(test.ClientContainerID, render.TheInternetID), + Origins: report.MakeIDList( + test.ServerContainerNodeID, + test.Server80NodeID, + test.ServerProcessNodeID, + test.ServerHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 150, + render.KeyBytesEgress: 1500, + }, + }, + uncontainedServerID: { + ID: uncontainedServerID, + LabelMajor: render.UncontainedMajor, + LabelMinor: test.ServerHostName, + Rank: "", + Pseudo: true, + Origins: report.MakeIDList( + test.NonContainerProcessNodeID, + test.ServerHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{}, + }, + render.TheInternetID: theInternetNode, + } + + RenderedContainerImages = render.RenderableNodes{ + test.ClientContainerImageID: { + ID: test.ClientContainerImageID, + LabelMajor: "client_image", + LabelMinor: "", + Rank: test.ClientContainerImageID, + Pseudo: false, + Adjacency: report.MakeIDList(test.ServerContainerImageID), + Origins: report.MakeIDList( + test.ClientContainerImageNodeID, + test.ClientContainerNodeID, + test.Client54001NodeID, + test.Client54002NodeID, + test.ClientProcessNodeID, + test.ClientHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 300, + render.KeyBytesEgress: 30, + }, + }, + test.ServerContainerImageID: { + ID: test.ServerContainerImageID, + LabelMajor: "server_image", + LabelMinor: "", + Rank: test.ServerContainerImageID, + Pseudo: false, + Adjacency: report.MakeIDList(test.ClientContainerImageID, render.TheInternetID), + Origins: report.MakeIDList( + test.ServerContainerImageNodeID, + test.ServerContainerNodeID, + test.Server80NodeID, + test.ServerProcessNodeID, + test.ServerHostNodeID), + AggregateMetadata: render.AggregateMetadata{ + render.KeyBytesIngress: 150, + render.KeyBytesEgress: 1500, + }, + }, + uncontainedServerID: { + ID: uncontainedServerID, + LabelMajor: render.UncontainedMajor, + LabelMinor: test.ServerHostName, + Rank: "", + Pseudo: true, + Origins: report.MakeIDList( + test.NonContainerProcessNodeID, + test.ServerHostNodeID, + ), + AggregateMetadata: render.AggregateMetadata{}, + }, + render.TheInternetID: theInternetNode, + } + + ServerHostRenderedID = render.MakeHostID(test.ServerHostID) + ClientHostRenderedID = render.MakeHostID(test.ClientHostID) + pseudoHostID1 = render.MakePseudoNodeID("10.10.10.10", "192.168.1.1", "") + pseudoHostID2 = render.MakePseudoNodeID("10.10.10.11", "192.168.1.1", "") + + RenderedHosts = render.RenderableNodes{ + ServerHostRenderedID: { + ID: ServerHostRenderedID, + LabelMajor: "server", // before first . + LabelMinor: "hostname.com", // after first . + Rank: "hostname.com", + Pseudo: false, + Adjacency: report.MakeIDList(ClientHostRenderedID, render.TheInternetID, pseudoHostID1, pseudoHostID2), + Origins: report.MakeIDList( + test.ServerHostNodeID, + test.ServerAddressNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyMaxConnCountTCP: 3, + }, + }, + ClientHostRenderedID: { + ID: ClientHostRenderedID, + LabelMajor: "client", // before first . + LabelMinor: "hostname.com", // after first . + Rank: "hostname.com", + Pseudo: false, + Adjacency: report.MakeIDList(ServerHostRenderedID), + Origins: report.MakeIDList( + test.ClientHostNodeID, + test.ClientAddressNodeID, + ), + AggregateMetadata: render.AggregateMetadata{ + render.KeyMaxConnCountTCP: 3, + }, + }, + pseudoHostID1: { + ID: pseudoHostID1, + LabelMajor: "10.10.10.10", + Pseudo: true, + AggregateMetadata: render.AggregateMetadata{}, + }, + pseudoHostID2: { + ID: pseudoHostID2, + LabelMajor: "10.10.10.11", + Pseudo: true, + AggregateMetadata: render.AggregateMetadata{}, + }, + render.TheInternetID: theInternetNode, + } +) diff --git a/render/render.go b/render/render.go index 1fffa5e94..4d426e47c 100644 --- a/render/render.go +++ b/render/render.go @@ -245,7 +245,11 @@ func (m LeafMap) AggregateMetadata(rpt report.Report, srcRenderableID, dstRender // Render produces a set of RenderableNodes given a Report func (f FilterUnconnected) Render(rpt report.Report) RenderableNodes { - input := f.Renderer.Render(rpt) + return OnlyConnected(f.Renderer.Render(rpt)) +} + +// OnlyConnected filters out unconnected RenderedNodes +func OnlyConnected(input RenderableNodes) RenderableNodes { output := RenderableNodes{} for id, node := range input { if len(node.Adjacency) == 0 { diff --git a/render/topologies_test.go b/render/topologies_test.go index ca113ce8d..be6a51442 100644 --- a/render/topologies_test.go +++ b/render/topologies_test.go @@ -1,272 +1,14 @@ package render_test import ( - "fmt" "reflect" "testing" - "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/render" - "github.com/weaveworks/scope/report" + "github.com/weaveworks/scope/render/expected" "github.com/weaveworks/scope/test" ) -// This is an example Report: -// 2 hosts with probes installed - client & server. - -var ( - clientHostID = "client.hostname.com" - serverHostID = "server.hostname.com" - unknownHostID = "" - - clientIP = "10.10.10.20" - serverIP = "192.168.1.1" - clientPort54001 = "54001" - clientPort54002 = "54002" - serverPort = "80" - - clientHostName = clientHostID - serverHostName = serverHostID - - clientPID = "10001" - serverPID = "215" - nonContainerPID = "1234" - - clientHostNodeID = report.MakeHostNodeID(clientHostID) - serverHostNodeID = report.MakeHostNodeID(serverHostID) - - client54001NodeID = report.MakeEndpointNodeID(clientHostID, clientIP, clientPort54001) // curl (1) - client54002NodeID = report.MakeEndpointNodeID(clientHostID, clientIP, clientPort54002) // curl (2) - server80NodeID = report.MakeEndpointNodeID(serverHostID, serverIP, serverPort) // apache - unknownClient1NodeID = report.MakeEndpointNodeID(serverHostID, "10.10.10.10", "54010") // we want to ensure two unknown clients, connnected - unknownClient2NodeID = report.MakeEndpointNodeID(serverHostID, "10.10.10.10", "54020") // to the same server, are deduped. - unknownClient3NodeID = report.MakeEndpointNodeID(serverHostID, "10.10.10.11", "54020") // Check this one isn't deduped - randomClientNodeID = report.MakeEndpointNodeID(serverHostID, "51.52.53.54", "12345") // this should become an internet node - - clientProcessNodeID = report.MakeProcessNodeID(clientHostID, clientPID) - serverProcessNodeID = report.MakeProcessNodeID(serverHostID, serverPID) - nonContainerProcessNodeID = report.MakeProcessNodeID(serverHostID, nonContainerPID) - - clientContainerID = "a1b2c3d4e5" - serverContainerID = "5e4d3c2b1a" - clientContainerNodeID = report.MakeContainerNodeID(clientHostID, clientContainerID) - serverContainerNodeID = report.MakeContainerNodeID(serverHostID, serverContainerID) - uncontainedServerID = render.MakePseudoNodeID(render.UncontainedID, serverHostName) - - clientContainerImageID = "imageid123" - serverContainerImageID = "imageid456" - clientContainerImageNodeID = report.MakeContainerNodeID(clientHostID, clientContainerImageID) - serverContainerImageNodeID = report.MakeContainerNodeID(serverHostID, serverContainerImageID) - - clientAddressNodeID = report.MakeAddressNodeID(clientHostID, "10.10.10.20") - serverAddressNodeID = report.MakeAddressNodeID(serverHostID, "192.168.1.1") - unknownAddress1NodeID = report.MakeAddressNodeID(serverHostID, "10.10.10.10") - unknownAddress2NodeID = report.MakeAddressNodeID(serverHostID, "10.10.10.11") - randomAddressNodeID = report.MakeAddressNodeID(serverHostID, "51.52.53.54") // this should become an internet node - - unknownPseudoNode1ID = render.MakePseudoNodeID("10.10.10.10", "192.168.1.1", "80") - unknownPseudoNode2ID = render.MakePseudoNodeID("10.10.10.11", "192.168.1.1", "80") - unknownPseudoNode1 = render.RenderableNode{ - ID: unknownPseudoNode1ID, - LabelMajor: "10.10.10.10", - Pseudo: true, - AggregateMetadata: render.AggregateMetadata{}, - } - unknownPseudoNode2 = render.RenderableNode{ - ID: unknownPseudoNode2ID, - LabelMajor: "10.10.10.11", - Pseudo: true, - AggregateMetadata: render.AggregateMetadata{}, - } - theInternetNode = render.RenderableNode{ - ID: render.TheInternetID, - LabelMajor: render.TheInternetMajor, - Pseudo: true, - AggregateMetadata: render.AggregateMetadata{}, - } -) - -var ( - rpt = report.Report{ - Endpoint: report.Topology{ - Adjacency: report.Adjacency{ - report.MakeAdjacencyID(client54001NodeID): report.MakeIDList(server80NodeID), - report.MakeAdjacencyID(client54002NodeID): report.MakeIDList(server80NodeID), - report.MakeAdjacencyID(server80NodeID): report.MakeIDList( - client54001NodeID, client54002NodeID, unknownClient1NodeID, unknownClient2NodeID, - unknownClient3NodeID, randomClientNodeID), - }, - NodeMetadatas: report.NodeMetadatas{ - // NodeMetadata is arbitrary. We're free to put only precisely what we - // care to test into the fixture. Just be sure to include the bits - // that the mapping funcs extract :) - client54001NodeID: report.NodeMetadata{ - "addr": clientIP, - "port": clientPort54001, - "pid": clientPID, - report.HostNodeID: clientHostNodeID, - }, - client54002NodeID: report.NodeMetadata{ - "addr": clientIP, - "port": clientPort54002, - "pid": clientPID, // should be same as above! - report.HostNodeID: clientHostNodeID, - }, - server80NodeID: report.NodeMetadata{ - "addr": serverIP, - "port": serverPort, - "pid": serverPID, - report.HostNodeID: serverHostNodeID, - }, - }, - EdgeMetadatas: report.EdgeMetadatas{ - report.MakeEdgeID(client54001NodeID, server80NodeID): report.EdgeMetadata{ - WithBytes: true, - BytesIngress: 100, - BytesEgress: 10, - }, - report.MakeEdgeID(client54002NodeID, server80NodeID): report.EdgeMetadata{ - WithBytes: true, - BytesIngress: 200, - BytesEgress: 20, - }, - - report.MakeEdgeID(server80NodeID, client54001NodeID): report.EdgeMetadata{ - WithBytes: true, - BytesIngress: 10, - BytesEgress: 100, - }, - report.MakeEdgeID(server80NodeID, client54002NodeID): report.EdgeMetadata{ - WithBytes: true, - BytesIngress: 20, - BytesEgress: 200, - }, - report.MakeEdgeID(server80NodeID, unknownClient1NodeID): report.EdgeMetadata{ - WithBytes: true, - BytesIngress: 30, - BytesEgress: 300, - }, - report.MakeEdgeID(server80NodeID, unknownClient2NodeID): report.EdgeMetadata{ - WithBytes: true, - BytesIngress: 40, - BytesEgress: 400, - }, - report.MakeEdgeID(server80NodeID, unknownClient3NodeID): report.EdgeMetadata{ - WithBytes: true, - BytesIngress: 50, - BytesEgress: 500, - }, - }, - }, - Process: report.Topology{ - Adjacency: report.Adjacency{}, - NodeMetadatas: report.NodeMetadatas{ - clientProcessNodeID: report.NodeMetadata{ - "pid": clientPID, - "comm": "curl", - docker.ContainerID: clientContainerID, - report.HostNodeID: clientHostNodeID, - }, - serverProcessNodeID: report.NodeMetadata{ - "pid": serverPID, - "comm": "apache", - docker.ContainerID: serverContainerID, - report.HostNodeID: serverHostNodeID, - }, - nonContainerProcessNodeID: report.NodeMetadata{ - "pid": nonContainerPID, - "comm": "bash", - report.HostNodeID: serverHostNodeID, - }, - }, - EdgeMetadatas: report.EdgeMetadatas{}, - }, - Container: report.Topology{ - NodeMetadatas: report.NodeMetadatas{ - clientContainerNodeID: report.NodeMetadata{ - docker.ContainerID: clientContainerID, - docker.ContainerName: "client", - docker.ImageID: clientContainerImageID, - report.HostNodeID: clientHostNodeID, - }, - serverContainerNodeID: report.NodeMetadata{ - docker.ContainerID: serverContainerID, - docker.ContainerName: "server", - docker.ImageID: serverContainerImageID, - report.HostNodeID: serverHostNodeID, - }, - }, - }, - ContainerImage: report.Topology{ - NodeMetadatas: report.NodeMetadatas{ - clientContainerImageNodeID: report.NodeMetadata{ - docker.ImageID: clientContainerImageID, - docker.ImageName: "client_image", - report.HostNodeID: clientHostNodeID, - }, - serverContainerImageNodeID: report.NodeMetadata{ - docker.ImageID: serverContainerImageID, - docker.ImageName: "server_image", - report.HostNodeID: serverHostNodeID, - }, - }, - }, - Address: report.Topology{ - Adjacency: report.Adjacency{ - report.MakeAdjacencyID(clientAddressNodeID): report.MakeIDList(serverAddressNodeID), - report.MakeAdjacencyID(serverAddressNodeID): report.MakeIDList( - clientAddressNodeID, unknownAddress1NodeID, unknownAddress2NodeID, randomAddressNodeID), // no backlinks to unknown/random - }, - NodeMetadatas: report.NodeMetadatas{ - clientAddressNodeID: report.NodeMetadata{ - "addr": clientIP, - report.HostNodeID: clientHostNodeID, - }, - serverAddressNodeID: report.NodeMetadata{ - "addr": serverIP, - report.HostNodeID: serverHostNodeID, - }, - }, - EdgeMetadatas: report.EdgeMetadatas{ - report.MakeEdgeID(clientAddressNodeID, serverAddressNodeID): report.EdgeMetadata{ - WithConnCountTCP: true, - MaxConnCountTCP: 3, - }, - report.MakeEdgeID(serverAddressNodeID, clientAddressNodeID): report.EdgeMetadata{ - WithConnCountTCP: true, - MaxConnCountTCP: 3, - }, - }, - }, - Host: report.Topology{ - Adjacency: report.Adjacency{}, - NodeMetadatas: report.NodeMetadatas{ - clientHostNodeID: report.NodeMetadata{ - "host_name": clientHostName, - "local_networks": "10.10.10.0/24", - "os": "Linux", - "load": "0.01 0.01 0.01", - report.HostNodeID: clientHostNodeID, - }, - serverHostNodeID: report.NodeMetadata{ - "host_name": serverHostName, - "local_networks": "10.10.10.0/24", - "os": "Linux", - "load": "0.01 0.01 0.01", - report.HostNodeID: serverHostNodeID, - }, - }, - EdgeMetadatas: report.EdgeMetadatas{}, - }, - } -) - -func init() { - if err := rpt.Validate(); err != nil { - panic(err) - } -} - func trimNodeMetadata(rns render.RenderableNodes) render.RenderableNodes { result := render.RenderableNodes{} for id, rn := range rns { @@ -277,260 +19,41 @@ func trimNodeMetadata(rns render.RenderableNodes) render.RenderableNodes { } func TestProcessRenderer(t *testing.T) { - var ( - clientProcessID = render.MakeProcessID(clientHostID, clientPID) - serverProcessID = render.MakeProcessID(serverHostID, serverPID) - nonContainerProcessID = render.MakeProcessID(serverHostID, nonContainerPID) - ) - - want := render.RenderableNodes{ - clientProcessID: { - ID: clientProcessID, - LabelMajor: "curl", - LabelMinor: fmt.Sprintf("%s (%s)", clientHostID, clientPID), - Rank: clientPID, - Pseudo: false, - Adjacency: report.MakeIDList(serverProcessID), - Origins: report.MakeIDList(client54001NodeID, client54002NodeID, clientProcessNodeID, clientHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 300, - render.KeyBytesEgress: 30, - }, - }, - serverProcessID: { - ID: serverProcessID, - LabelMajor: "apache", - LabelMinor: fmt.Sprintf("%s (%s)", serverHostID, serverPID), - Rank: serverPID, - Pseudo: false, - Adjacency: report.MakeIDList( - clientProcessID, - unknownPseudoNode1ID, - unknownPseudoNode2ID, - render.TheInternetID, - ), - Origins: report.MakeIDList(server80NodeID, serverProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 150, - render.KeyBytesEgress: 1500, - }, - }, - nonContainerProcessID: { - ID: nonContainerProcessID, - LabelMajor: "bash", - LabelMinor: fmt.Sprintf("%s (%s)", serverHostID, nonContainerPID), - Rank: nonContainerPID, - Pseudo: false, - Adjacency: report.MakeIDList(), - Origins: report.MakeIDList(nonContainerProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{}, - }, - unknownPseudoNode1ID: unknownPseudoNode1, - unknownPseudoNode2ID: unknownPseudoNode2, - render.TheInternetID: theInternetNode, - } - have := render.ProcessRenderer.Render(rpt) + have := render.ProcessRenderer.Render(test.Report) have = trimNodeMetadata(have) - if !reflect.DeepEqual(want, have) { - t.Error("\n" + test.Diff(want, have)) + if !reflect.DeepEqual(expected.RenderedProcesses, have) { + t.Error("\n" + test.Diff(expected.RenderedProcesses, have)) } } func TestProcessNameRenderer(t *testing.T) { - want := render.RenderableNodes{ - "curl": { - ID: "curl", - LabelMajor: "curl", - LabelMinor: "", - Rank: "curl", - Pseudo: false, - Adjacency: report.MakeIDList("apache"), - Origins: report.MakeIDList(client54001NodeID, client54002NodeID, clientProcessNodeID, clientHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 300, - render.KeyBytesEgress: 30, - }, - }, - "apache": { - ID: "apache", - LabelMajor: "apache", - LabelMinor: "", - Rank: "apache", - Pseudo: false, - Adjacency: report.MakeIDList( - "curl", - unknownPseudoNode1ID, - unknownPseudoNode2ID, - render.TheInternetID, - ), - Origins: report.MakeIDList(server80NodeID, serverProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 150, - render.KeyBytesEgress: 1500, - }, - }, - "bash": { - ID: "bash", - LabelMajor: "bash", - LabelMinor: "", - Rank: "bash", - Pseudo: false, - Origins: report.MakeIDList(nonContainerProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{}, - }, - unknownPseudoNode1ID: unknownPseudoNode1, - unknownPseudoNode2ID: unknownPseudoNode2, - render.TheInternetID: theInternetNode, - } - have := render.ProcessNameRenderer.Render(rpt) + have := render.ProcessNameRenderer.Render(test.Report) have = trimNodeMetadata(have) - if !reflect.DeepEqual(want, have) { - t.Error("\n" + test.Diff(want, have)) + if !reflect.DeepEqual(expected.RenderedProcessNames, have) { + t.Error("\n" + test.Diff(expected.RenderedProcessNames, have)) } } func TestContainerRenderer(t *testing.T) { - want := render.RenderableNodes{ - clientContainerID: { - ID: clientContainerID, - LabelMajor: "client", - LabelMinor: clientHostName, - Rank: clientContainerImageID, - Pseudo: false, - Adjacency: report.MakeIDList(serverContainerID), - Origins: report.MakeIDList(clientContainerNodeID, client54001NodeID, client54002NodeID, clientProcessNodeID, clientHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 300, - render.KeyBytesEgress: 30, - }, - }, - serverContainerID: { - ID: serverContainerID, - LabelMajor: "server", - LabelMinor: serverHostName, - Rank: serverContainerImageID, - Pseudo: false, - Adjacency: report.MakeIDList(clientContainerID, render.TheInternetID), - Origins: report.MakeIDList(serverContainerNodeID, server80NodeID, serverProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 150, - render.KeyBytesEgress: 1500, - }, - }, - uncontainedServerID: { - ID: uncontainedServerID, - LabelMajor: render.UncontainedMajor, - LabelMinor: serverHostName, - Rank: "", - Pseudo: true, - Origins: report.MakeIDList(nonContainerProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{}, - }, - render.TheInternetID: theInternetNode, - } - have := render.ContainerRenderer.Render(rpt) + have := render.ContainerRenderer.Render(test.Report) have = trimNodeMetadata(have) - if !reflect.DeepEqual(want, have) { - t.Error("\n" + test.Diff(want, have)) + if !reflect.DeepEqual(expected.RenderedContainers, have) { + t.Error("\n" + test.Diff(expected.RenderedContainers, have)) } } func TestContainerImageRenderer(t *testing.T) { - want := render.RenderableNodes{ - clientContainerImageID: { - ID: clientContainerImageID, - LabelMajor: "client_image", - LabelMinor: "", - Rank: clientContainerImageID, - Pseudo: false, - Adjacency: report.MakeIDList(serverContainerImageID), - Origins: report.MakeIDList(clientContainerImageNodeID, clientContainerNodeID, client54001NodeID, client54002NodeID, clientProcessNodeID, clientHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 300, - render.KeyBytesEgress: 30, - }, - }, - serverContainerImageID: { - ID: serverContainerImageID, - LabelMajor: "server_image", - LabelMinor: "", - Rank: serverContainerImageID, - Pseudo: false, - Adjacency: report.MakeIDList(clientContainerImageID, render.TheInternetID), - Origins: report.MakeIDList(serverContainerImageNodeID, serverContainerNodeID, server80NodeID, serverProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyBytesIngress: 150, - render.KeyBytesEgress: 1500, - }, - }, - uncontainedServerID: { - ID: uncontainedServerID, - LabelMajor: render.UncontainedMajor, - LabelMinor: serverHostName, - Rank: "", - Pseudo: true, - Origins: report.MakeIDList(nonContainerProcessNodeID, serverHostNodeID), - AggregateMetadata: render.AggregateMetadata{}, - }, - render.TheInternetID: theInternetNode, - } - have := render.ContainerImageRenderer.Render(rpt) + have := render.ContainerImageRenderer.Render(test.Report) have = trimNodeMetadata(have) - if !reflect.DeepEqual(want, have) { - t.Error("\n" + test.Diff(want, have)) + if !reflect.DeepEqual(expected.RenderedContainerImages, have) { + t.Error("\n" + test.Diff(expected.RenderedContainerImages, have)) } } func TestHostRenderer(t *testing.T) { - var ( - serverHostRenderedID = render.MakeHostID(serverHostID) - clientHostRenderedID = render.MakeHostID(clientHostID) - pseudoHostID1 = render.MakePseudoNodeID("10.10.10.10", "192.168.1.1", "") - pseudoHostID2 = render.MakePseudoNodeID("10.10.10.11", "192.168.1.1", "") - ) - - want := render.RenderableNodes{ - serverHostRenderedID: { - ID: serverHostRenderedID, - LabelMajor: "server", // before first . - LabelMinor: "hostname.com", // after first . - Rank: "hostname.com", - Pseudo: false, - Adjacency: report.MakeIDList(clientHostRenderedID, render.TheInternetID, pseudoHostID1, pseudoHostID2), - Origins: report.MakeIDList(serverHostNodeID, serverAddressNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyMaxConnCountTCP: 3, - }, - }, - clientHostRenderedID: { - ID: clientHostRenderedID, - LabelMajor: "client", // before first . - LabelMinor: "hostname.com", // after first . - Rank: "hostname.com", - Pseudo: false, - Adjacency: report.MakeIDList(serverHostRenderedID), - Origins: report.MakeIDList(clientHostNodeID, clientAddressNodeID), - AggregateMetadata: render.AggregateMetadata{ - render.KeyMaxConnCountTCP: 3, - }, - }, - pseudoHostID1: { - ID: pseudoHostID1, - LabelMajor: "10.10.10.10", - Pseudo: true, - AggregateMetadata: render.AggregateMetadata{}, - }, - pseudoHostID2: { - ID: pseudoHostID2, - LabelMajor: "10.10.10.11", - Pseudo: true, - AggregateMetadata: render.AggregateMetadata{}, - }, - render.TheInternetID: theInternetNode, - } - have := render.HostRenderer.Render(rpt) + have := render.HostRenderer.Render(test.Report) have = trimNodeMetadata(have) - if !reflect.DeepEqual(want, have) { - t.Error("\n" + test.Diff(want, have)) + if !reflect.DeepEqual(expected.RenderedHosts, have) { + t.Error("\n" + test.Diff(expected.RenderedHosts, have)) } } diff --git a/report/id_test.go b/report/id_test.go index 0ac85fc7f..8b1984afe 100644 --- a/report/id_test.go +++ b/report/id_test.go @@ -8,6 +8,30 @@ 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) +) + func TestAdjacencyID(t *testing.T) { for _, bad := range []string{ client54001EndpointNodeID, diff --git a/report/report_fixture_test.go b/report/report_fixture_test.go deleted file mode 100644 index 72bd86bed..000000000 --- a/report/report_fixture_test.go +++ /dev/null @@ -1,167 +0,0 @@ -package report_test - -import ( - "github.com/weaveworks/scope/report" -) - -var reportFixture = report.Report{ - Endpoint: report.Topology{ - Adjacency: report.Adjacency{ - report.MakeAdjacencyID(client54001EndpointNodeID): report.MakeIDList(server80EndpointNodeID), - report.MakeAdjacencyID(client54002EndpointNodeID): report.MakeIDList(server80EndpointNodeID), - report.MakeAdjacencyID(server80EndpointNodeID): report.MakeIDList(client54001EndpointNodeID, client54002EndpointNodeID, unknown1EndpointNodeID, unknown2EndpointNodeID, unknown3EndpointNodeID), - }, - NodeMetadatas: report.NodeMetadatas{ - client54001EndpointNodeID: report.NodeMetadata{ - "process_node_id": report.MakeProcessNodeID(clientHostID, "4242"), - "address_node_id": report.MakeAddressNodeID(clientHostID, clientAddress), - "host_name": clientHostName, - }, - client54002EndpointNodeID: report.NodeMetadata{ - //"process_node_id": report.MakeProcessNodeID(clientHostID, "4242"), // leave it out, to test a branch in Render - "address_node_id": report.MakeAddressNodeID(clientHostID, clientAddress), - }, - server80EndpointNodeID: report.NodeMetadata{ - "process_node_id": report.MakeProcessNodeID(serverHostID, "215"), - "address_node_id": report.MakeAddressNodeID(serverHostID, serverAddress), - }, - - "process-not-available": report.NodeMetadata{}, // for TestProcess{PID,Name,Container[Name]} - "process-badly-linked": report.NodeMetadata{"process_node_id": "none"}, // for TestProcess{PID,Name,Container[Name]} - "process-no-container": report.NodeMetadata{"process_node_id": "no-container"}, // for TestProcessContainer[Name] - "address-not-available": report.NodeMetadata{}, // for TestAddressHostname - "address-badly-linked": report.NodeMetadata{"address_node_id": "none"}, // for TestAddressHostname - }, - EdgeMetadatas: report.EdgeMetadatas{ - report.MakeEdgeID(client54001EndpointNodeID, server80EndpointNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 10, // src -> dst - BytesIngress: 100, // src <- dst - }, - report.MakeEdgeID(client54002EndpointNodeID, server80EndpointNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 20, - BytesIngress: 200, - }, - report.MakeEdgeID(server80EndpointNodeID, client54001EndpointNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 100, - BytesIngress: 10, - }, - report.MakeEdgeID(server80EndpointNodeID, client54002EndpointNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 200, - BytesIngress: 20, - }, - report.MakeEdgeID(server80EndpointNodeID, unknown1EndpointNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 400, - BytesIngress: 40, - }, - report.MakeEdgeID(server80EndpointNodeID, unknown2EndpointNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 800, - BytesIngress: 80, - }, - report.MakeEdgeID(server80EndpointNodeID, unknown3EndpointNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 1600, - BytesIngress: 160, - }, - }, - }, - Address: report.Topology{ - Adjacency: report.Adjacency{ - report.MakeAdjacencyID(clientAddressNodeID): report.MakeIDList(serverAddressNodeID), - report.MakeAdjacencyID(serverAddressNodeID): report.MakeIDList(clientAddressNodeID, unknownAddressNodeID), - }, - NodeMetadatas: report.NodeMetadatas{ - clientAddressNodeID: report.NodeMetadata{ - "host_name": "client.host.com", - }, - serverAddressNodeID: report.NodeMetadata{}, - - "no-host-name": report.NodeMetadata{}, - }, - EdgeMetadatas: report.EdgeMetadatas{ - report.MakeEdgeID(clientAddressNodeID, serverAddressNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 10 + 20 + 1, - BytesIngress: 100 + 200 + 2, - }, - report.MakeEdgeID(serverAddressNodeID, clientAddressNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 100 + 200 + 3, - BytesIngress: 10 + 20 + 4, - }, - report.MakeEdgeID(serverAddressNodeID, unknownAddressNodeID): report.EdgeMetadata{ - WithBytes: true, - BytesEgress: 400 + 800 + 1600 + 5, - BytesIngress: 40 + 80 + 160 + 6, - }, - }, - }, - Process: report.Topology{ - Adjacency: report.Adjacency{}, - NodeMetadatas: report.NodeMetadatas{ - report.MakeProcessNodeID(clientHostID, "4242"): report.NodeMetadata{ - "host_name": "client.host.com", - "pid": "4242", - "comm": "curl", - "docker_container_id": "a1b2c3d4e5", - "docker_container_name": "fixture-container", - "docker_image_id": "0000000000", - "docker_image_name": "fixture/container:latest", - }, - report.MakeProcessNodeID(serverHostID, "215"): report.NodeMetadata{ - "pid": "215", - "process_name": "apache", - }, - - "no-container": report.NodeMetadata{}, - }, - EdgeMetadatas: report.EdgeMetadatas{}, - }, - Host: report.Topology{ - Adjacency: report.Adjacency{}, - NodeMetadatas: report.NodeMetadatas{ - report.MakeHostNodeID(clientHostID): report.NodeMetadata{ - "host_name": clientHostName, - "local_networks": "10.10.10.0/24", - "os": "OS/2", - "load": "0.11 0.22 0.33", - }, - report.MakeHostNodeID(serverHostID): report.NodeMetadata{ - "host_name": serverHostName, - "local_networks": "10.10.10.0/24", - "os": "Linux", - "load": "0.01 0.01 0.01", - }, - }, - EdgeMetadatas: report.EdgeMetadatas{}, - }, -} - -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/test/report_fixture.go b/test/report_fixture.go new file mode 100644 index 000000000..ff53be6d7 --- /dev/null +++ b/test/report_fixture.go @@ -0,0 +1,237 @@ +package test + +import ( + "github.com/weaveworks/scope/probe/docker" + "github.com/weaveworks/scope/report" +) + +// This is an example Report: +// 2 hosts with probes installed - client & server. +var ( + ClientHostID = "client.hostname.com" + ServerHostID = "server.hostname.com" + UnknownHostID = "" + + ClientIP = "10.10.10.20" + ServerIP = "192.168.1.1" + ClientPort54001 = "54001" + ClientPort54002 = "54002" + ServerPort = "80" + + ClientHostName = ClientHostID + ServerHostName = ServerHostID + + ClientPID = "10001" + ServerPID = "215" + NonContainerPID = "1234" + + ClientHostNodeID = report.MakeHostNodeID(ClientHostID) + ServerHostNodeID = report.MakeHostNodeID(ServerHostID) + + Client54001NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54001) // curl (1) + Client54002NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54002) // curl (2) + Server80NodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort) // apache + UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, "10.10.10.10", "54010") // we want to ensure two unknown clients, connnected + UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, "10.10.10.10", "54020") // to the same server, are deduped. + UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, "10.10.10.11", "54020") // Check this one isn't deduped + RandomClientNodeID = report.MakeEndpointNodeID(ServerHostID, "51.52.53.54", "12345") // this should become an internet node + + ClientProcessNodeID = report.MakeProcessNodeID(ClientHostID, ClientPID) + ServerProcessNodeID = report.MakeProcessNodeID(ServerHostID, ServerPID) + NonContainerProcessNodeID = report.MakeProcessNodeID(ServerHostID, NonContainerPID) + + ClientContainerID = "a1b2c3d4e5" + ServerContainerID = "5e4d3c2b1a" + ClientContainerNodeID = report.MakeContainerNodeID(ClientHostID, ClientContainerID) + ServerContainerNodeID = report.MakeContainerNodeID(ServerHostID, ServerContainerID) + + ClientContainerImageID = "imageid123" + ServerContainerImageID = "imageid456" + ClientContainerImageNodeID = report.MakeContainerNodeID(ClientHostID, ClientContainerImageID) + ServerContainerImageNodeID = report.MakeContainerNodeID(ServerHostID, ServerContainerImageID) + + ClientAddressNodeID = report.MakeAddressNodeID(ClientHostID, "10.10.10.20") + ServerAddressNodeID = report.MakeAddressNodeID(ServerHostID, "192.168.1.1") + UnknownAddress1NodeID = report.MakeAddressNodeID(ServerHostID, "10.10.10.10") + UnknownAddress2NodeID = report.MakeAddressNodeID(ServerHostID, "10.10.10.11") + RandomAddressNodeID = report.MakeAddressNodeID(ServerHostID, "51.52.53.54") // this should become an internet node + + Report = report.Report{ + Endpoint: report.Topology{ + Adjacency: report.Adjacency{ + report.MakeAdjacencyID(Client54001NodeID): report.MakeIDList(Server80NodeID), + report.MakeAdjacencyID(Client54002NodeID): report.MakeIDList(Server80NodeID), + report.MakeAdjacencyID(Server80NodeID): report.MakeIDList( + Client54001NodeID, Client54002NodeID, UnknownClient1NodeID, UnknownClient2NodeID, + UnknownClient3NodeID, RandomClientNodeID), + }, + NodeMetadatas: report.NodeMetadatas{ + // NodeMetadata is arbitrary. We're free to put only precisely what we + // care to test into the fixture. Just be sure to include the bits + // that the mapping funcs extract :) + Client54001NodeID: report.NodeMetadata{ + "addr": ClientIP, + "port": ClientPort54001, + "pid": ClientPID, + report.HostNodeID: ClientHostNodeID, + }, + Client54002NodeID: report.NodeMetadata{ + "addr": ClientIP, + "port": ClientPort54002, + "pid": ClientPID, // should be same as above! + report.HostNodeID: ClientHostNodeID, + }, + Server80NodeID: report.NodeMetadata{ + "addr": ServerIP, + "port": ServerPort, + "pid": ServerPID, + report.HostNodeID: ServerHostNodeID, + }, + }, + EdgeMetadatas: report.EdgeMetadatas{ + report.MakeEdgeID(Client54001NodeID, Server80NodeID): report.EdgeMetadata{ + WithBytes: true, + BytesIngress: 100, + BytesEgress: 10, + }, + report.MakeEdgeID(Client54002NodeID, Server80NodeID): report.EdgeMetadata{ + WithBytes: true, + BytesIngress: 200, + BytesEgress: 20, + }, + + report.MakeEdgeID(Server80NodeID, Client54001NodeID): report.EdgeMetadata{ + WithBytes: true, + BytesIngress: 10, + BytesEgress: 100, + }, + report.MakeEdgeID(Server80NodeID, Client54002NodeID): report.EdgeMetadata{ + WithBytes: true, + BytesIngress: 20, + BytesEgress: 200, + }, + report.MakeEdgeID(Server80NodeID, UnknownClient1NodeID): report.EdgeMetadata{ + WithBytes: true, + BytesIngress: 30, + BytesEgress: 300, + }, + report.MakeEdgeID(Server80NodeID, UnknownClient2NodeID): report.EdgeMetadata{ + WithBytes: true, + BytesIngress: 40, + BytesEgress: 400, + }, + report.MakeEdgeID(Server80NodeID, UnknownClient3NodeID): report.EdgeMetadata{ + WithBytes: true, + BytesIngress: 50, + BytesEgress: 500, + }, + }, + }, + Process: report.Topology{ + Adjacency: report.Adjacency{}, + NodeMetadatas: report.NodeMetadatas{ + ClientProcessNodeID: report.NodeMetadata{ + "pid": ClientPID, + "comm": "curl", + docker.ContainerID: ClientContainerID, + report.HostNodeID: ClientHostNodeID, + }, + ServerProcessNodeID: report.NodeMetadata{ + "pid": ServerPID, + "comm": "apache", + docker.ContainerID: ServerContainerID, + report.HostNodeID: ServerHostNodeID, + }, + NonContainerProcessNodeID: report.NodeMetadata{ + "pid": NonContainerPID, + "comm": "bash", + report.HostNodeID: ServerHostNodeID, + }, + }, + EdgeMetadatas: report.EdgeMetadatas{}, + }, + Container: report.Topology{ + NodeMetadatas: report.NodeMetadatas{ + ClientContainerNodeID: report.NodeMetadata{ + docker.ContainerID: ClientContainerID, + docker.ContainerName: "client", + docker.ImageID: ClientContainerImageID, + report.HostNodeID: ClientHostNodeID, + }, + ServerContainerNodeID: report.NodeMetadata{ + docker.ContainerID: ServerContainerID, + docker.ContainerName: "server", + docker.ImageID: ServerContainerImageID, + report.HostNodeID: ServerHostNodeID, + }, + }, + }, + ContainerImage: report.Topology{ + NodeMetadatas: report.NodeMetadatas{ + ClientContainerImageNodeID: report.NodeMetadata{ + docker.ImageID: ClientContainerImageID, + docker.ImageName: "client_image", + report.HostNodeID: ClientHostNodeID, + }, + ServerContainerImageNodeID: report.NodeMetadata{ + docker.ImageID: ServerContainerImageID, + docker.ImageName: "server_image", + report.HostNodeID: ServerHostNodeID, + }, + }, + }, + Address: report.Topology{ + Adjacency: report.Adjacency{ + report.MakeAdjacencyID(ClientAddressNodeID): report.MakeIDList(ServerAddressNodeID), + report.MakeAdjacencyID(ServerAddressNodeID): report.MakeIDList( + ClientAddressNodeID, UnknownAddress1NodeID, UnknownAddress2NodeID, RandomAddressNodeID), // no backlinks to unknown/random + }, + NodeMetadatas: report.NodeMetadatas{ + ClientAddressNodeID: report.NodeMetadata{ + "addr": ClientIP, + report.HostNodeID: ClientHostNodeID, + }, + ServerAddressNodeID: report.NodeMetadata{ + "addr": ServerIP, + report.HostNodeID: ServerHostNodeID, + }, + }, + EdgeMetadatas: report.EdgeMetadatas{ + report.MakeEdgeID(ClientAddressNodeID, ServerAddressNodeID): report.EdgeMetadata{ + WithConnCountTCP: true, + MaxConnCountTCP: 3, + }, + report.MakeEdgeID(ServerAddressNodeID, ClientAddressNodeID): report.EdgeMetadata{ + WithConnCountTCP: true, + MaxConnCountTCP: 3, + }, + }, + }, + Host: report.Topology{ + Adjacency: report.Adjacency{}, + NodeMetadatas: report.NodeMetadatas{ + ClientHostNodeID: report.NodeMetadata{ + "host_name": ClientHostName, + "local_networks": "10.10.10.0/24", + "os": "Linux", + "load": "0.01 0.01 0.01", + report.HostNodeID: ClientHostNodeID, + }, + ServerHostNodeID: report.NodeMetadata{ + "host_name": ServerHostName, + "local_networks": "10.10.10.0/24", + "os": "Linux", + "load": "0.01 0.01 0.01", + report.HostNodeID: ServerHostNodeID, + }, + }, + EdgeMetadatas: report.EdgeMetadatas{}, + }, + } +) + +func init() { + if err := Report.Validate(); err != nil { + panic(err) + } +}