Beispiel #1
0
func TestReportLocalNetworks(t *testing.T) {
	r := report.MakeReport().Merge(report.Report{
		Host: report.Topology{
			Nodes: report.Nodes{
				"nonets": report.MakeNode("nonets"),
				"foo": report.MakeNode("foo").WithSets(report.EmptySets.
					Add(host.LocalNetworks, report.MakeStringSet(
						"10.0.0.1/8", "192.168.1.1/24", "10.0.0.1/8", "badnet/33")),
				),
			},
		},
		Overlay: report.Topology{
			Nodes: report.Nodes{
				"router": report.MakeNode("router").WithSets(report.EmptySets.
					Add(host.LocalNetworks, report.MakeStringSet("10.32.0.1/12")),
				),
			},
		},
	})
	want := report.Networks([]*net.IPNet{
		mustParseCIDR("10.0.0.1/8"),
		mustParseCIDR("192.168.1.1/24"),
		mustParseCIDR("10.32.0.1/12"),
	})
	have := render.LocalNetworks(r)
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Beispiel #2
0
func TestMerge(t *testing.T) {
	var (
		hostID = "xyz"
		src    = newMockSource([]byte{}, nil)
		on     = time.Millisecond
		off    = time.Millisecond
		rpt    = report.MakeReport()
		p      = sniff.Packet{
			SrcIP:     "1.0.0.0",
			SrcPort:   "1000",
			DstIP:     "2.0.0.0",
			DstPort:   "2000",
			Network:   512,
			Transport: 256,
		}

		_, ipnet, _ = net.ParseCIDR(p.SrcIP + "/24") // ;)
		localNets   = report.Networks([]*net.IPNet{ipnet})
	)
	sniff.New(hostID, localNets, src, on, off).Merge(p, &rpt)

	var (
		srcEndpointNodeID = report.MakeEndpointNodeID(hostID, p.SrcIP, p.SrcPort)
		dstEndpointNodeID = report.MakeEndpointNodeID(hostID, p.DstIP, p.DstPort)
	)
	if want, have := (report.Topology{
		Nodes: report.Nodes{
			srcEndpointNodeID: report.MakeNode(srcEndpointNodeID).WithEdge(dstEndpointNodeID, report.EdgeMetadata{
				EgressPacketCount: newu64(1),
				EgressByteCount:   newu64(256),
			}),
			dstEndpointNodeID: report.MakeNode(dstEndpointNodeID),
		},
	}), rpt.Endpoint; !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}

	var (
		srcAddressNodeID = report.MakeAddressNodeID(hostID, p.SrcIP)
		dstAddressNodeID = report.MakeAddressNodeID(hostID, p.DstIP)
	)
	if want, have := (report.Topology{
		Nodes: report.Nodes{
			srcAddressNodeID: report.MakeNode(srcAddressNodeID).WithEdge(dstAddressNodeID, report.EdgeMetadata{
				EgressPacketCount: newu64(1),
				EgressByteCount:   newu64(512),
			}),
			dstAddressNodeID: report.MakeNode(dstAddressNodeID),
		},
	}), rpt.Address; !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Beispiel #3
0
func TestNodeSetDelete(t *testing.T) {
	for _, testcase := range []struct {
		input report.NodeSet
		nodes []string
		want  report.NodeSet
	}{
		{
			input: report.NodeSet{},
			nodes: []string{},
			want:  report.NodeSet{},
		},
		{
			input: report.EmptyNodeSet,
			nodes: []string{},
			want:  report.EmptyNodeSet,
		},
		{
			input: report.MakeNodeSet(report.MakeNode("a")),
			nodes: []string{},
			want:  report.MakeNodeSet(report.MakeNode("a")),
		},
		{
			input: report.EmptyNodeSet,
			nodes: []string{"a"},
			want:  report.EmptyNodeSet,
		},
		{
			input: report.MakeNodeSet(report.MakeNode("a")),
			nodes: []string{"a"},
			want:  report.EmptyNodeSet,
		},
		{
			input: report.MakeNodeSet(report.MakeNode("b")),
			nodes: []string{"a", "b"},
			want:  report.EmptyNodeSet,
		},
		{
			input: report.MakeNodeSet(report.MakeNode("a")),
			nodes: []string{"c", "b"},
			want:  report.MakeNodeSet(report.MakeNode("a")),
		},
		{
			input: report.MakeNodeSet(report.MakeNode("a"), report.MakeNode("c")),
			nodes: []string{"a", "a", "a"},
			want:  report.MakeNodeSet(report.MakeNode("c")),
		},
	} {
		originalLen := testcase.input.Size()
		if want, have := testcase.want, testcase.input.Delete(testcase.nodes...); !reflect.DeepEqual(want, have) {
			t.Errorf("%v + %v: want %v, have %v", testcase.input, testcase.nodes, want, have)
		}
		if testcase.input.Size() != originalLen {
			t.Errorf("%v + %v: modified the original input!", testcase.input, testcase.nodes)
		}
	}
}
Beispiel #4
0
func TestReduceRender(t *testing.T) {
	renderer := render.Reduce([]render.Renderer{
		mockRenderer{Nodes: report.Nodes{"foo": report.MakeNode("foo")}},
		mockRenderer{Nodes: report.Nodes{"bar": report.MakeNode("bar")}},
	})

	want := report.Nodes{
		"foo": report.MakeNode("foo"),
		"bar": report.MakeNode("bar"),
	}
	have := renderer.Render(report.MakeReport(), render.FilterNoop)
	if !reflect.DeepEqual(want, have) {
		t.Errorf("want %+v, have %+v", want, have)
	}
}
Beispiel #5
0
func TestFilterRender(t *testing.T) {
	renderer := mockRenderer{Nodes: report.Nodes{
		"foo": report.MakeNode("foo").WithAdjacent("bar"),
		"bar": report.MakeNode("bar").WithAdjacent("foo"),
		"baz": report.MakeNode("baz"),
	}}
	have := report.MakeIDList()
	for id := range renderer.Render(report.MakeReport(), render.FilterUnconnected) {
		have = have.Add(id)
	}
	want := report.MakeIDList("foo", "bar")
	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Beispiel #6
0
func TestApply(t *testing.T) {
	var (
		endpointNodeID = "c"
		endpointNode   = report.MakeNodeWith(endpointNodeID, map[string]string{"5": "6"})
	)

	p := New(0, 0, nil)
	p.AddTagger(NewTopologyTagger())

	r := report.MakeReport()
	r.Endpoint.AddNode(endpointNode)
	r = p.tag(r)

	for _, tuple := range []struct {
		want report.Node
		from report.Topology
		via  string
	}{
		{endpointNode.Merge(report.MakeNode("c").WithTopology(report.Endpoint)), r.Endpoint, endpointNodeID},
	} {
		if want, have := tuple.want, tuple.from.Nodes[tuple.via]; !reflect.DeepEqual(want, have) {
			t.Errorf("want %+v, have %+v", want, have)
		}
	}
}
Beispiel #7
0
func TestMakeNodeSet(t *testing.T) {
	for _, testcase := range []struct {
		inputs []string
		wants  []string
	}{
		{inputs: nil, wants: nil},
		{
			inputs: []string{"a"},
			wants:  []string{"a"},
		},
		{
			inputs: []string{"b", "c", "a"},
			wants:  []string{"a", "b", "c"},
		},
		{
			inputs: []string{"a", "a", "a"},
			wants:  []string{"a"},
		},
	} {
		var inputs []report.Node
		for _, id := range testcase.inputs {
			inputs = append(inputs, report.MakeNode(id))
		}
		set := report.MakeNodeSet(inputs...)
		var have []string
		set.ForEach(func(node report.Node) { have = append(have, node.ID) })
		if !reflect.DeepEqual(testcase.wants, have) {
			t.Errorf("%#v: want %#v, have %#v", testcase.inputs, testcase.wants, have)
		}
	}
}
Beispiel #8
0
func benchmarkMerger(b *testing.B, merger app.Merger) {
	makeReport := func() report.Report {
		rpt := report.MakeReport()
		for i := 0; i < 100; i++ {
			rpt.Endpoint.AddNode(report.MakeNode(fmt.Sprintf("%x", rand.Int63())))
		}
		return rpt
	}

	reports := []report.Report{}
	for i := 0; i < numHosts*5; i++ {
		reports = append(reports, makeReport())
	}

	b.ReportAllocs()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		// replace 1/3 of hosts work of reports & merge them all
		for i := 0; i < numHosts/3; i++ {
			reports[rand.Intn(len(reports))] = makeReport()
		}

		merger.Merge(reports)
	}
}
Beispiel #9
0
// Report implements Reporter.
func (w *Weave) Report() (report.Report, error) {
	w.mtx.RLock()
	defer w.mtx.RUnlock()

	r := report.MakeReport()
	r.Container = r.Container.WithMetadataTemplates(report.MetadataTemplates{
		WeaveMACAddress:  {ID: WeaveMACAddress, Label: "Weave MAC", From: report.FromLatest, Priority: 17},
		WeaveDNSHostname: {ID: WeaveDNSHostname, Label: "Weave DNS Name", From: report.FromLatest, Priority: 18},
	})
	for _, peer := range w.statusCache.Router.Peers {
		r.Overlay.AddNode(report.MakeNodeWith(report.MakeOverlayNodeID(peer.Name), map[string]string{
			WeavePeerName:     peer.Name,
			WeavePeerNickName: peer.NickName,
		}))

	}
	if w.statusCache.IPAM.DefaultSubnet != "" {
		r.Overlay.AddNode(
			report.MakeNode(report.MakeOverlayNodeID(w.statusCache.Router.Name)).WithSets(
				report.MakeSets().Add(host.LocalNetworks, report.MakeStringSet(w.statusCache.IPAM.DefaultSubnet)),
			),
		)
	}
	return r, nil
}
Beispiel #10
0
func TestMapProcess2Container(t *testing.T) {
	for _, input := range []testcase{
		{"empty", report.MakeNode("empty"), true},
		{"basic process", report.MakeNodeWith("basic", map[string]string{process.PID: "201", docker.ContainerID: "a1b2c3"}), true},
		{"uncontained", report.MakeNodeWith("uncontained", map[string]string{process.PID: "201", report.HostNodeID: report.MakeHostNodeID("foo")}), true},
	} {
		testMap(t, render.MapProcess2Container, input)
	}
}
Beispiel #11
0
// FIXME: Hideous hack to remove persistent-connection edges to virtual service
//        IPs attributed to the internet. We add each service IP as a /32 network
//        (the global service-cluster-ip-range is not exposed by the API
//        server so we treat each IP as a /32 network see
//        https://github.com/kubernetes/kubernetes/issues/25533).
//        The right way of fixing this is performing DNAT mapping on persistent
//        connections for which we don't have a robust solution
//        (see https://$GITHUB_URI/issues/1491)
func (r *Reporter) hostTopology(services []Service) report.Topology {
	localNetworks := report.EmptyStringSet
	for _, service := range services {
		localNetworks = localNetworks.Add(service.ClusterIP() + "/32")
	}
	node := report.MakeNode(report.MakeHostNodeID(r.hostID))
	node = node.WithSets(report.EmptySets.
		Add(host.LocalNetworks, localNetworks))
	return report.MakeTopology().AddNode(node)
}
Beispiel #12
0
// 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)
}
Beispiel #13
0
func TestMapRender3(t *testing.T) {
	// 3. Check we can remap adjacencies
	mapper := render.Map{
		MapFunc: func(nodes report.Node, _ report.Networks) report.Nodes {
			id := "_" + nodes.ID
			return report.Nodes{id: report.MakeNode(id)}
		},
		Renderer: mockRenderer{Nodes: report.Nodes{
			"foo": report.MakeNode("foo").WithAdjacent("baz"),
			"baz": report.MakeNode("baz").WithAdjacent("foo"),
		}},
	}
	want := report.Nodes{
		"_foo": report.MakeNode("_foo").WithAdjacent("_baz"),
		"_baz": report.MakeNode("_baz").WithAdjacent("_foo"),
	}
	have := mapper.Render(report.MakeReport(), render.FilterNoop)
	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Beispiel #14
0
func TestFilterRender2(t *testing.T) {
	// Test adjacencies are removed for filtered nodes.
	filter := func(renderer render.Renderer) render.Renderer {
		return &render.Filter{
			FilterFunc: func(node report.Node) bool {
				return node.ID != "bar"
			},
			Renderer: renderer,
		}
	}
	renderer := mockRenderer{Nodes: report.Nodes{
		"foo": report.MakeNode("foo").WithAdjacent("bar"),
		"bar": report.MakeNode("bar").WithAdjacent("foo"),
		"baz": report.MakeNode("baz"),
	}}

	have := renderer.Render(report.MakeReport(), filter)
	if have["foo"].Adjacency.Contains("bar") {
		t.Error("adjacencies for removed nodes should have been removed")
	}
}
Beispiel #15
0
func TestMapRender2(t *testing.T) {
	// 2. Check we can remap two nodes into one
	mapper := render.Map{
		MapFunc: func(nodes report.Node, _ report.Networks) report.Nodes {
			return report.Nodes{
				"bar": report.MakeNode("bar"),
			}
		},
		Renderer: mockRenderer{Nodes: report.Nodes{
			"foo": report.MakeNode("foo"),
			"baz": report.MakeNode("baz"),
		}},
	}
	want := report.Nodes{
		"bar": report.MakeNode("bar"),
	}
	have := mapper.Render(report.MakeReport(), render.FilterNoop)
	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Beispiel #16
0
func TestCollector(t *testing.T) {
	ctx := context.Background()
	window := 10 * time.Second
	c := app.NewCollector(window)

	r1 := report.MakeReport()
	r1.Endpoint.AddNode(report.MakeNode("foo"))

	r2 := report.MakeReport()
	r2.Endpoint.AddNode(report.MakeNode("foo"))

	have, err := c.Report(ctx)
	if err != nil {
		t.Error(err)
	}
	if want := report.MakeReport(); !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}

	c.Add(ctx, r1)
	have, err = c.Report(ctx)
	if err != nil {
		t.Error(err)
	}
	if want := r1; !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}

	c.Add(ctx, r2)
	merged := report.MakeReport()
	merged = merged.Merge(r1)
	merged = merged.Merge(r2)
	have, err = c.Report(ctx)
	if err != nil {
		t.Error(err)
	}
	if want := merged; !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Beispiel #17
0
func TestMerger(t *testing.T) {
	// Use 3 reports to check the pair-wise merging in SmartMerger
	report1 := report.MakeReport()
	report1.Endpoint.AddNode(report.MakeNode("foo"))
	report2 := report.MakeReport()
	report2.Endpoint.AddNode(report.MakeNode("bar"))
	report3 := report.MakeReport()
	report3.Endpoint.AddNode(report.MakeNode("baz"))
	reports := []report.Report{
		report1, report2, report3,
	}
	want := report.MakeReport()
	want.Endpoint.
		AddNode(report.MakeNode("foo")).
		AddNode(report.MakeNode("bar")).
		AddNode(report.MakeNode("baz"))

	for _, merger := range []app.Merger{app.MakeDumbMerger(), app.NewSmartMerger()} {
		// Test the empty list case
		if have := merger.Merge([]report.Report{}); !reflect.DeepEqual(have, report.MakeReport()) {
			t.Errorf("Bad merge: %s", test.Diff(have, want))
		}

		if have := merger.Merge(reports); !reflect.DeepEqual(have, want) {
			t.Errorf("Bad merge: %s", test.Diff(have, want))
		}

		// Repeat the above test to ensure caching works
		if have := merger.Merge(reports); !reflect.DeepEqual(have, want) {
			t.Errorf("Bad merge: %s", test.Diff(have, want))
		}
	}
}
Beispiel #18
0
func TestSmartMerger(t *testing.T) {
	// Use 3 reports _WITH SAME ID_
	report1 := report.MakeReport()
	report1.Endpoint.AddNode(report.MakeNode("foo"))
	report1.ID = "foo"
	report2 := report.MakeReport()
	report2.Endpoint.AddNode(report.MakeNode("bar"))
	report2.ID = "foo"
	report3 := report.MakeReport()
	report3.Endpoint.AddNode(report.MakeNode("baz"))
	report3.ID = "foo"
	reports := []report.Report{
		report1, report2, report3,
	}
	want := report.MakeReport()
	want.Endpoint.AddNode(report.MakeNode("foo"))

	merger := app.NewSmartMerger()
	if have := merger.Merge(reports); !reflect.DeepEqual(have, want) {
		t.Errorf("Bad merge: %s", test.Diff(have, want))
	}
}
Beispiel #19
0
func TestFilterUnconnectedSelf(t *testing.T) {
	// Test nodes that are only connected to themselves are filtered.
	{
		nodes := report.Nodes{
			"foo": report.MakeNode("foo").WithAdjacent("foo"),
		}
		renderer := mockRenderer{Nodes: nodes}
		have := renderer.Render(report.MakeReport(), render.FilterUnconnected)
		if len(have) > 0 {
			t.Error("expected node only connected to self to be removed")
		}
	}
}
Beispiel #20
0
func TestNode(t *testing.T) {
	{
		node := report.MakeNodeWith("foo", map[string]string{
			"foo": "bar",
		})

		if v, _ := node.Latest.Lookup("foo"); v != "bar" {
			t.Errorf("want foo, have %s", v)
		}
	}
	{
		node := report.MakeNode("foo").WithCounters(
			map[string]int{"foo": 1},
		)
		if value, _ := node.Counters.Lookup("foo"); value != 1 {
			t.Errorf("want foo, have %d", value)
		}
	}
	{
		node := report.MakeNode("foo").WithAdjacent("foo")
		if node.Adjacency[0] != "foo" {
			t.Errorf("want foo, have %v", node.Adjacency)
		}
	}
	{
		node := report.MakeNode("foo").WithEdge("foo", report.EdgeMetadata{
			EgressPacketCount: newu64(13),
		})
		if node.Adjacency[0] != "foo" {
			t.Errorf("want foo, have %v", node.Adjacency)
		}
		if v, ok := node.Edges.Lookup("foo"); ok && *v.EgressPacketCount != 13 {
			t.Errorf("want 13, have %v", node.Edges)
		}
	}
}
Beispiel #21
0
func TestMapRender1(t *testing.T) {
	// 1. Check when we return false, the node gets filtered out
	mapper := render.Map{
		MapFunc: func(nodes report.Node, _ report.Networks) report.Nodes {
			return report.Nodes{}
		},
		Renderer: mockRenderer{Nodes: report.Nodes{
			"foo": report.MakeNode("foo"),
		}},
	}
	want := report.Nodes{}
	have := mapper.Render(report.MakeReport(), render.FilterNoop)
	if !reflect.DeepEqual(want, have) {
		t.Errorf("want %+v, have %+v", want, have)
	}
}
Beispiel #22
0
func TestTables(t *testing.T) {
	want := map[string]string{
		"foo1": "bar1",
		"foo2": "bar2",
	}
	nmd := report.MakeNode("foo1")

	nmd = nmd.AddTable("foo_", want)
	have, truncationCount := nmd.ExtractTable("foo_")

	if truncationCount != 0 {
		t.Error("Table shouldn't had been truncated")
	}

	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Beispiel #23
0
func TestMemoise(t *testing.T) {
	calls := 0
	r := renderFunc(func(rpt report.Report) report.Nodes {
		calls++
		return report.Nodes{rpt.ID: report.MakeNode(rpt.ID)}
	})
	m := render.Memoise(r)
	rpt1 := report.MakeReport()

	result1 := m.Render(rpt1, nil)
	// it should have rendered it.
	if _, ok := result1[rpt1.ID]; !ok {
		t.Errorf("Expected rendered report to contain a node, but got: %v", result1)
	}
	if calls != 1 {
		t.Errorf("Expected renderer to have been called the first time")
	}

	result2 := m.Render(rpt1, nil)
	if !reflect.DeepEqual(result1, result2) {
		t.Errorf("Expected memoised result to be returned: %s", test.Diff(result1, result2))
	}
	if calls != 1 {
		t.Errorf("Expected renderer to not have been called the second time")
	}

	rpt2 := report.MakeReport()
	result3 := m.Render(rpt2, nil)
	if reflect.DeepEqual(result1, result3) {
		t.Errorf("Expected different result for different report, but were the same")
	}
	if calls != 2 {
		t.Errorf("Expected renderer to have been called again for a different report")
	}

	render.ResetCache()
	result4 := m.Render(rpt1, nil)
	if !reflect.DeepEqual(result1, result4) {
		t.Errorf("Expected original result to be returned: %s", test.Diff(result1, result4))
	}
	if calls != 3 {
		t.Errorf("Expected renderer to have been called again after cache reset")
	}
}
Beispiel #24
0
func (r *Reporter) processTopology() (report.Topology, error) {
	t := report.MakeTopology().
		WithMetadataTemplates(MetadataTemplates).
		WithMetricTemplates(MetricTemplates)
	now := mtime.Now()
	deltaTotal, maxCPU, err := r.jiffies()
	if err != nil {
		return t, err
	}

	err = r.walker.Walk(func(p, prev Process) {
		pidstr := strconv.Itoa(p.PID)
		nodeID := report.MakeProcessNodeID(r.scope, pidstr)
		node := report.MakeNode(nodeID)
		for _, tuple := range []struct{ key, value string }{
			{PID, pidstr},
			{Name, p.Name},
			{Cmdline, p.Cmdline},
			{Threads, strconv.Itoa(p.Threads)},
		} {
			if tuple.value != "" {
				node = node.WithLatests(map[string]string{tuple.key: tuple.value})
			}
		}

		if p.PPID > 0 {
			node = node.WithLatests(map[string]string{PPID: strconv.Itoa(p.PPID)})
		}

		if deltaTotal > 0 {
			cpuUsage := float64(p.Jiffies-prev.Jiffies) / float64(deltaTotal) * 100.
			node = node.WithMetric(CPUUsage, report.MakeMetric().Add(now, cpuUsage).WithMax(maxCPU))
		}

		node = node.WithMetric(MemoryUsage, report.MakeMetric().Add(now, float64(p.RSSBytes)).WithMax(float64(p.RSSBytesLimit)))
		node = node.WithMetric(OpenFilesCount, report.MakeMetric().Add(now, float64(p.OpenFilesCount)).WithMax(float64(p.OpenFilesLimit)))

		t.AddNode(node)
	})

	return t, err
}
Beispiel #25
0
func TestInterpolateCounts(t *testing.T) {
	var (
		hostID        = "macbook-air"
		srcNodeID     = report.MakeEndpointNodeID(hostID, "1.2.3.4", "5678")
		dstNodeID     = report.MakeEndpointNodeID(hostID, "5.6.7.8", "9012")
		samplingCount = uint64(200)
		samplingTotal = uint64(2345)
		packetCount   = uint64(123)
		byteCount     = uint64(4096)
	)

	r := report.MakeReport()
	r.Sampling.Count = samplingCount
	r.Sampling.Total = samplingTotal
	r.Endpoint.AddNode(report.MakeNode(srcNodeID).WithEdge(dstNodeID, report.EdgeMetadata{
		EgressPacketCount:  newu64(packetCount),
		IngressPacketCount: newu64(packetCount),
		EgressByteCount:    newu64(byteCount),
		IngressByteCount:   newu64(byteCount),
	}))

	interpolateCounts(r)

	var (
		rate   = float64(samplingCount) / float64(samplingTotal)
		factor = 1.0 / rate
		apply  = func(v uint64) uint64 { return uint64(factor * float64(v)) }
		emd    = r.Endpoint.Nodes[srcNodeID].Edges[dstNodeID]
	)
	if want, have := apply(packetCount), (*emd.EgressPacketCount); want != have {
		t.Errorf("want %d packets, have %d", want, have)
	}
	if want, have := apply(packetCount), (*emd.IngressPacketCount); want != have {
		t.Errorf("want %d packets, have %d", want, have)
	}
	if want, have := apply(byteCount), (*emd.EgressByteCount); want != have {
		t.Errorf("want %d bytes, have %d", want, have)
	}
	if want, have := apply(byteCount), (*emd.IngressByteCount); want != have {
		t.Errorf("want %d bytes, have %d", want, have)
	}
}
Beispiel #26
0
func TestNodeOrdering(t *testing.T) {
	ids := [][2]string{{}, {"a", "0"}, {"a", "1"}, {"b", "0"}, {"b", "1"}, {"c", "3"}}
	nodes := []report.Node{}
	for _, id := range ids {
		nodes = append(nodes, report.MakeNode(id[1]).WithTopology(id[0]))
	}

	for i, node := range nodes {
		if !node.Equal(node) {
			t.Errorf("Expected %q %q == %q %q, but was not", node.Topology, node.ID, node.Topology, node.ID)
		}
		if i > 0 {
			if !node.After(nodes[i-1]) {
				t.Errorf("Expected %q %q > %q %q, but was not", node.Topology, node.ID, nodes[i-1].Topology, nodes[i-1].ID)
			}
			if !nodes[i-1].Before(node) {
				t.Errorf("Expected %q %q < %q %q, but was not", nodes[i-1].Topology, nodes[i-1].ID, node.Topology, node.ID)
			}
		}
	}
}
Beispiel #27
0
func TestCollectorExpire(t *testing.T) {
	now := time.Now()
	mtime.NowForce(now)
	defer mtime.NowReset()

	ctx := context.Background()
	window := 10 * time.Second
	c := app.NewCollector(window)

	// 1st check the collector is empty
	have, err := c.Report(ctx)
	if err != nil {
		t.Error(err)
	}
	if want := report.MakeReport(); !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}

	// Now check an added report is returned
	r1 := report.MakeReport()
	r1.Endpoint.AddNode(report.MakeNode("foo"))
	c.Add(ctx, r1)
	have, err = c.Report(ctx)
	if err != nil {
		t.Error(err)
	}
	if want := r1; !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}

	// Finally move time forward to expire the report
	mtime.NowForce(now.Add(window))
	have, err = c.Report(ctx)
	if err != nil {
		t.Error(err)
	}
	if want := report.MakeReport(); !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Beispiel #28
0
func TestTruncation(t *testing.T) {
	wantTruncationCount := 1
	want := map[string]string{}
	for i := 0; i < report.MaxTableRows+wantTruncationCount; i++ {
		key := fmt.Sprintf("key%d", i)
		value := fmt.Sprintf("value%d", i)
		want[key] = value
	}

	nmd := report.MakeNode("foo1")

	nmd = nmd.AddTable("foo_", want)
	_, truncationCount := nmd.ExtractTable("foo_")

	if truncationCount != wantTruncationCount {
		t.Error(
			"Table should had been truncated by",
			wantTruncationCount,
			"and not",
			truncationCount,
		)
	}
}
Beispiel #29
0
func TestFilterUnconnectedPseudoNodes(t *testing.T) {
	// Test pseudo nodes that are made unconnected by filtering
	// are also removed.
	{
		nodes := report.Nodes{
			"foo": report.MakeNode("foo").WithAdjacent("bar"),
			"bar": report.MakeNode("bar").WithAdjacent("baz"),
			"baz": report.MakeNode("baz").WithTopology(render.Pseudo),
		}
		renderer := mockRenderer{Nodes: nodes}
		filter := func(renderer render.Renderer) render.Renderer {
			return &render.Filter{
				FilterFunc: func(node report.Node) bool {
					return true
				},
				Renderer: renderer,
			}
		}
		want := nodes
		have := renderer.Render(report.MakeReport(), filter)
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
	{
		filter := func(renderer render.Renderer) render.Renderer {
			return &render.Filter{
				FilterFunc: func(node report.Node) bool {
					return node.ID != "bar"
				},
				Renderer: renderer,
			}
		}
		renderer := mockRenderer{Nodes: report.Nodes{
			"foo": report.MakeNode("foo").WithAdjacent("bar"),
			"bar": report.MakeNode("bar").WithAdjacent("baz"),
			"baz": report.MakeNode("baz").WithTopology(render.Pseudo),
		}}
		have := renderer.Render(report.MakeReport(), filter)
		if _, ok := have["baz"]; ok {
			t.Error("expected the unconnected pseudonode baz to have been removed")
		}
	}
	{
		filter := func(renderer render.Renderer) render.Renderer {
			return &render.Filter{
				FilterFunc: func(node report.Node) bool {
					return node.ID != "bar"
				},
				Renderer: renderer,
			}
		}
		renderer := mockRenderer{Nodes: report.Nodes{
			"foo": report.MakeNode("foo"),
			"bar": report.MakeNode("bar").WithAdjacent("foo"),
			"baz": report.MakeNode("baz").WithTopology(render.Pseudo).WithAdjacent("bar"),
		}}
		have := renderer.Render(report.MakeReport(), filter)
		if _, ok := have["baz"]; ok {
			t.Error("expected the unconnected pseudonode baz to have been removed")
		}
	}
}
Beispiel #30
0
func TestNodeMetrics(t *testing.T) {
	inputs := []struct {
		name string
		node report.Node
		want []report.MetricRow
	}{
		{
			name: "process",
			node: fixture.Report.Process.Nodes[fixture.ClientProcess1NodeID],
			want: []report.MetricRow{
				{
					ID:       process.CPUUsage,
					Label:    "CPU",
					Format:   "percent",
					Group:    "",
					Value:    0.01,
					Priority: 1,
					Metric:   &fixture.ClientProcess1CPUMetric,
				},
				{
					ID:       process.MemoryUsage,
					Label:    "Memory",
					Format:   "filesize",
					Group:    "",
					Value:    0.02,
					Priority: 2,
					Metric:   &fixture.ClientProcess1MemoryMetric,
				},
			},
		},
		{
			name: "container",
			node: fixture.Report.Container.Nodes[fixture.ClientContainerNodeID],
			want: []report.MetricRow{
				{
					ID:       docker.CPUTotalUsage,
					Label:    "CPU",
					Format:   "percent",
					Group:    "",
					Value:    0.03,
					Priority: 1,
					Metric:   &fixture.ClientContainerCPUMetric,
				},
				{
					ID:       docker.MemoryUsage,
					Label:    "Memory",
					Format:   "filesize",
					Group:    "",
					Value:    0.04,
					Priority: 2,
					Metric:   &fixture.ClientContainerMemoryMetric,
				},
			},
		},
		{
			name: "host",
			node: fixture.Report.Host.Nodes[fixture.ClientHostNodeID],
			want: []report.MetricRow{
				{
					ID:       host.CPUUsage,
					Label:    "CPU",
					Format:   "percent",
					Group:    "",
					Value:    0.07,
					Priority: 1,
					Metric:   &fixture.ClientHostCPUMetric,
				},
				{
					ID:       host.MemoryUsage,
					Label:    "Memory",
					Format:   "filesize",
					Group:    "",
					Value:    0.08,
					Priority: 2,
					Metric:   &fixture.ClientHostMemoryMetric,
				},
				{
					ID:       host.Load1,
					Label:    "Load (1m)",
					Group:    "load",
					Value:    0.09,
					Priority: 11,
					Metric:   &fixture.ClientHostLoad1Metric,
				},
			},
		},
		{
			name: "unknown topology",
			node: report.MakeNode(fixture.ClientContainerNodeID).WithTopology("foobar"),
			want: nil,
		},
	}
	for _, input := range inputs {
		have := detailed.NodeMetrics(fixture.Report, input.node)
		if !reflect.DeepEqual(input.want, have) {
			t.Errorf("%s: %s", input.name, test.Diff(input.want, have))
		}
	}
}