func (r *Reporter) podTopology(services []Service) (report.Topology, report.Topology, error) { pods, containers := report.MakeTopology(), report.MakeTopology() selectors := map[string]labels.Selector{} for _, service := range services { selectors[service.ID()] = service.Selector() } err := r.client.WalkPods(func(p Pod) error { for serviceID, selector := range selectors { if selector.Matches(p.Labels()) { p.AddServiceID(serviceID) } } nodeID := report.MakePodNodeID(p.Namespace(), p.Name()) pods = pods.AddNode(nodeID, p.GetNode()) container := report.MakeNodeWith(map[string]string{ PodID: p.ID(), Namespace: p.Namespace(), }).WithParents(report.EmptySets.Add(report.Pod, report.MakeStringSet(nodeID))) for _, containerID := range p.ContainerIDs() { containers.AddNode(report.MakeContainerNodeID(containerID), container) } return nil }) return pods, containers, err }
func TestReporter(t *testing.T) { want := report.MakeReport() pod1ID := report.MakePodNodeID("ping", "pong-a") pod2ID := report.MakePodNodeID("ping", "pong-b") serviceID := report.MakeServiceNodeID("ping", "pongservice") want.Pod = report.MakeTopology().AddNode(pod1ID, report.MakeNodeWith(map[string]string{ kubernetes.PodID: "ping/pong-a", kubernetes.PodName: "pong-a", kubernetes.Namespace: "ping", kubernetes.PodCreated: pod1.Created(), kubernetes.PodContainerIDs: "container1 container2", kubernetes.ServiceIDs: "ping/pongservice", }).WithParents(report.Sets{ report.Service: report.MakeStringSet(serviceID), })).AddNode(pod2ID, report.MakeNodeWith(map[string]string{ kubernetes.PodID: "ping/pong-b", kubernetes.PodName: "pong-b", kubernetes.Namespace: "ping", kubernetes.PodCreated: pod1.Created(), kubernetes.PodContainerIDs: "container3 container4", kubernetes.ServiceIDs: "ping/pongservice", }).WithParents(report.Sets{ report.Service: report.MakeStringSet(serviceID), })) want.Service = report.MakeTopology().AddNode(serviceID, report.MakeNodeWith(map[string]string{ kubernetes.ServiceID: "ping/pongservice", kubernetes.ServiceName: "pongservice", kubernetes.Namespace: "ping", kubernetes.ServiceCreated: pod1.Created(), })) want.Container = report.MakeTopology().AddNode(report.MakeContainerNodeID("container1"), report.MakeNodeWith(map[string]string{ kubernetes.PodID: "ping/pong-a", kubernetes.Namespace: "ping", }).WithParents(report.Sets{ report.Pod: report.MakeStringSet(pod1ID), })).AddNode(report.MakeContainerNodeID("container2"), report.MakeNodeWith(map[string]string{ kubernetes.PodID: "ping/pong-a", kubernetes.Namespace: "ping", }).WithParents(report.Sets{ report.Pod: report.MakeStringSet(pod1ID), })).AddNode(report.MakeContainerNodeID("container3"), report.MakeNodeWith(map[string]string{ kubernetes.PodID: "ping/pong-b", kubernetes.Namespace: "ping", }).WithParents(report.Sets{ report.Pod: report.MakeStringSet(pod2ID), })).AddNode(report.MakeContainerNodeID("container4"), report.MakeNodeWith(map[string]string{ kubernetes.PodID: "ping/pong-b", kubernetes.Namespace: "ping", }).WithParents(report.Sets{ report.Pod: report.MakeStringSet(pod2ID), })) reporter := kubernetes.NewReporter(mockClientInstance) have, _ := reporter.Report() if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestWeaveTaggerOverlayTopology(t *testing.T) { oldExecCmd := exec.Command defer func() { exec.Command = oldExecCmd }() exec.Command = func(name string, args ...string) exec.Cmd { return testExec.NewMockCmdString(fmt.Sprintf("%s %s %s/24\n", mockContainerID, mockContainerMAC, mockContainerIP)) } s := httptest.NewServer(http.HandlerFunc(mockWeaveRouter)) defer s.Close() w := overlay.NewWeave(mockHostID, s.URL) defer w.Stop() w.Tick() { have, err := w.Report() if err != nil { t.Fatal(err) } if want, have := report.MakeTopology().AddNode( report.MakeOverlayNodeID(mockWeavePeerName), report.MakeNodeWith(map[string]string{ overlay.WeavePeerName: mockWeavePeerName, overlay.WeavePeerNickName: mockWeavePeerNickName, }), ), have.Overlay; !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { nodeID := report.MakeContainerNodeID(mockHostID, mockContainerID) want := report.Report{ Container: report.MakeTopology().AddNode(nodeID, report.MakeNodeWith(map[string]string{ docker.ContainerID: mockContainerID, overlay.WeaveDNSHostname: mockHostname, overlay.WeaveMACAddress: mockContainerMAC, }).WithSets(report.Sets{ docker.ContainerIPs: report.MakeStringSet(mockContainerIP), docker.ContainerIPsWithScopes: report.MakeStringSet(mockContainerIPWithScope), })), } have, err := w.Tag(report.Report{ Container: report.MakeTopology().AddNode(nodeID, report.MakeNodeWith(map[string]string{ docker.ContainerID: mockContainerID, })), }) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } }
func (r *Reporter) containerTopology(localAddrs []net.IP) report.Topology { result := report.MakeTopology() result.Controls.AddControl(report.Control{ ID: StopContainer, Human: "Stop", Icon: "fa-stop", }) result.Controls.AddControl(report.Control{ ID: StartContainer, Human: "Start", Icon: "fa-play", }) result.Controls.AddControl(report.Control{ ID: RestartContainer, Human: "Restart", Icon: "fa-repeat", }) result.Controls.AddControl(report.Control{ ID: PauseContainer, Human: "Pause", Icon: "fa-pause", }) result.Controls.AddControl(report.Control{ ID: UnpauseContainer, Human: "Unpause", Icon: "fa-play", }) r.registry.WalkContainers(func(c Container) { nodeID := report.MakeContainerNodeID(r.hostID, c.ID()) result.AddNode(nodeID, c.GetNode(r.hostID, localAddrs)) }) return result }
func TestAPITopologyAddsKubernetes(t *testing.T) { router := mux.NewRouter() c := app.NewCollector(1 * time.Minute) app.RegisterReportPostHandler(c, router) app.RegisterTopologyRoutes(router, c) ts := httptest.NewServer(router) defer ts.Close() body := getRawJSON(t, ts, "/api/topology") var topologies []app.APITopologyDesc decoder := codec.NewDecoderBytes(body, &codec.JsonHandle{}) if err := decoder.Decode(&topologies); err != nil { t.Fatalf("JSON parse error: %s", err) } equals(t, 4, len(topologies)) // Enable the kubernetes topologies rpt := report.MakeReport() rpt.Pod = report.MakeTopology() rpt.Pod.Nodes[fixture.ClientPodNodeID] = kubernetes.NewPod(&api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pong-a", Namespace: "ping", Labels: map[string]string{"ponger": "true"}, }, Status: api.PodStatus{ HostIP: "1.2.3.4", ContainerStatuses: []api.ContainerStatus{ {ContainerID: "container1"}, {ContainerID: "container2"}, }, }, }).GetNode("") buf := &bytes.Buffer{} encoder := codec.NewEncoder(buf, &codec.MsgpackHandle{}) if err := encoder.Encode(rpt); err != nil { t.Fatalf("GOB encoding error: %s", err) } checkRequest(t, ts, "POST", "/api/report", buf.Bytes()) body = getRawJSON(t, ts, "/api/topology") decoder = codec.NewDecoderBytes(body, &codec.JsonHandle{}) if err := decoder.Decode(&topologies); err != nil { t.Fatalf("JSON parse error: %s", err) } equals(t, 4, len(topologies)) found := false for _, topology := range topologies { if topology.Name == "Pods" { found = true break } } if !found { t.Error("Could not find pods topology") } }
func TestReporter(t *testing.T) { walker := &mockWalker{ processes: []process.Process{ {PID: 1, PPID: 0, Name: "init"}, {PID: 2, PPID: 1, Name: "bash"}, {PID: 3, PPID: 1, Name: "apache", Threads: 2}, {PID: 4, PPID: 2, Name: "ping", Cmdline: "ping foo.bar.local"}, {PID: 5, PPID: 1, Cmdline: "tail -f /var/log/syslog"}, }, } getDeltaTotalJiffies := func() (uint64, float64, error) { return 0, 0., nil } now := time.Now() mtime.NowForce(now) defer mtime.NowReset() reporter := process.NewReporter(walker, "", getDeltaTotalJiffies) want := report.MakeReport() want.Process = report.MakeTopology().AddNode( report.MakeProcessNodeID("", "1"), report.MakeNodeWith(map[string]string{ process.PID: "1", process.Name: "init", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "2"), report.MakeNodeWith(map[string]string{ process.PID: "2", process.Name: "bash", process.PPID: "1", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "3"), report.MakeNodeWith(map[string]string{ process.PID: "3", process.Name: "apache", process.PPID: "1", process.Threads: "2", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "4"), report.MakeNodeWith(map[string]string{ process.PID: "4", process.Name: "ping", process.PPID: "2", process.Cmdline: "ping foo.bar.local", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "5"), report.MakeNodeWith(map[string]string{ process.PID: "5", process.PPID: "1", process.Cmdline: "tail -f /var/log/syslog", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ) have, err := reporter.Report() if err != nil || !reflect.DeepEqual(want, have) { t.Errorf("%s (%v)", test.Diff(want, have), err) } }
// 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.com/weaveworks/scope/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) }
func (r *Reporter) containerTopology() report.Topology { result := report.MakeTopology() r.registry.WalkContainers(func(c Container) { nodeID := report.MakeContainerNodeID(r.hostID, c.ID()) result.AddNode(nodeID, c.GetNode()) }) return result }
func (r *Reporter) containerTopology() report.Topology { result := report.MakeTopology() r.registry.WalkContainers(func(c Container) { nodeID := report.MakeContainerNodeID(r.scope, c.ID()) result.NodeMetadatas[nodeID] = c.GetNodeMetadata() }) return result }
func TestReporter(t *testing.T) { walker := &mockWalker{ processes: []process.Process{ {PID: 1, PPID: 0, Comm: "init"}, {PID: 2, PPID: 1, Comm: "bash"}, {PID: 3, PPID: 1, Comm: "apache", Threads: 2}, {PID: 4, PPID: 2, Comm: "ping", Cmdline: "ping foo.bar.local"}, {PID: 5, PPID: 1, Cmdline: "tail -f /var/log/syslog"}, }, } reporter := process.NewReporter(walker, "") want := report.MakeReport() want.Process = report.MakeTopology().AddNode( report.MakeProcessNodeID("", "1"), report.MakeNodeWith(map[string]string{ process.PID: "1", process.Comm: "init", process.Threads: "0", }), ).AddNode( report.MakeProcessNodeID("", "2"), report.MakeNodeWith(map[string]string{ process.PID: "2", process.Comm: "bash", process.PPID: "1", process.Threads: "0", }), ).AddNode( report.MakeProcessNodeID("", "3"), report.MakeNodeWith(map[string]string{ process.PID: "3", process.Comm: "apache", process.PPID: "1", process.Threads: "2", }), ).AddNode( report.MakeProcessNodeID("", "4"), report.MakeNodeWith(map[string]string{ process.PID: "4", process.Comm: "ping", process.PPID: "2", process.Cmdline: "ping foo.bar.local", process.Threads: "0", }), ).AddNode( report.MakeProcessNodeID("", "5"), report.MakeNodeWith(map[string]string{ process.PID: "5", process.PPID: "1", process.Cmdline: "tail -f /var/log/syslog", process.Threads: "0", }), ) have, err := reporter.Report() if err != nil || !reflect.DeepEqual(want, have) { t.Errorf("%s (%v)", test.Diff(want, have), err) } }
func (r *Reporter) serviceTopology() (report.Topology, []Service, error) { var ( result = report.MakeTopology() services = []Service{} ) err := r.client.WalkServices(func(s Service) error { nodeID := report.MakeServiceNodeID(s.Namespace(), s.Name()) result = result.AddNode(nodeID, s.GetNode()) services = append(services, s) return nil }) return result, services, err }
func TestMakeRenderableNodes(t *testing.T) { var ( newu64 = func(value uint64) *uint64 { return &value } srcNodeID = "srcNode" dstNode1ID = "dstNode1" dstNode2ID = "dstNode2" srcNode = report.MakeNode(). WithEdge(dstNode1ID, report.EdgeMetadata{EgressPacketCount: newu64(100), EgressByteCount: newu64(1000)}). WithEdge(dstNode2ID, report.EdgeMetadata{EgressPacketCount: newu64(200), EgressByteCount: newu64(2000)}) dstNode1 = report.MakeNode() dstNode2 = report.MakeNode() topology = report.MakeTopology(). AddNode(srcNodeID, srcNode). AddNode(dstNode1ID, dstNode1). AddNode(dstNode2ID, dstNode2) ) result := render.MakeRenderableNodes(topology) mustLookup := func(id string) render.RenderableNode { node, ok := result[id] if !ok { t.Fatalf("Expected result to contain node: %q, got: %v", id, result) } return node } // Source nodes should have the flattened edge metadata { have := mustLookup(srcNodeID).EdgeMetadata want := report.EdgeMetadata{EgressPacketCount: newu64(300), EgressByteCount: newu64(3000)} if !reflect.DeepEqual(want, have) { t.Errorf(test.Diff(want, have)) } } // Result destination nodes should have the reverse of the source nodes { have := mustLookup(dstNode1ID).EdgeMetadata want := report.EdgeMetadata{IngressPacketCount: newu64(100), IngressByteCount: newu64(1000)} if !reflect.DeepEqual(want, have) { t.Errorf(test.Diff(want, have)) } have = mustLookup(dstNode2ID).EdgeMetadata want = report.EdgeMetadata{IngressPacketCount: newu64(200), IngressByteCount: newu64(2000)} if !reflect.DeepEqual(want, have) { t.Errorf(test.Diff(want, have)) } } }
func (r *Reporter) podTopology(services []Service, replicaSets []ReplicaSet) (report.Topology, error) { var ( pods = report.MakeTopology(). WithMetadataTemplates(PodMetadataTemplates). WithMetricTemplates(PodMetricTemplates). WithTableTemplates(TableTemplates) selectors = []func(labelledChild){} ) pods.Controls.AddControl(report.Control{ ID: GetLogs, Human: "Get logs", Icon: "fa-desktop", Rank: 0, }) pods.Controls.AddControl(report.Control{ ID: DeletePod, Human: "Delete", Icon: "fa-trash-o", Rank: 1, }) for _, service := range services { selectors = append(selectors, match( service.Selector(), report.Service, report.MakeServiceNodeID(service.UID()), )) } for _, replicaSet := range replicaSets { selectors = append(selectors, match( replicaSet.Selector(), report.ReplicaSet, report.MakeReplicaSetNodeID(replicaSet.UID()), )) } thisNodeName, err := GetNodeName(r) if err != nil { return pods, err } err = r.client.WalkPods(func(p Pod) error { if p.NodeName() != thisNodeName { return nil } for _, selector := range selectors { selector(p) } pods = pods.AddNode(p.GetNode(r.probeID)) return nil }) return pods, err }
func (r *Reporter) podTopology(services []Service) (report.Topology, error) { result := report.MakeTopology() err := r.client.WalkPods(func(p Pod) error { for _, service := range services { if service.Selector().Matches(p.Labels()) { p.AddServiceID(service.ID()) } } nodeID := report.MakePodNodeID(p.Namespace(), p.Name()) result = result.AddNode(nodeID, p.GetNode()) return nil }) return result, err }
func (r *Reporter) serviceTopology() (report.Topology, []Service, error) { var ( result = report.MakeTopology(). WithMetadataTemplates(ServiceMetadataTemplates). WithMetricTemplates(ServiceMetricTemplates). WithTableTemplates(TableTemplates) services = []Service{} ) err := r.client.WalkServices(func(s Service) error { result = result.AddNode(s.GetNode()) services = append(services, s) return nil }) return result, services, err }
// Make sure we don't add a topology and miss it in the Topologies method. func TestReportTopologies(t *testing.T) { var ( reportType = reflect.TypeOf(report.MakeReport()) topologyType = reflect.TypeOf(report.MakeTopology()) ) var want int for i := 0; i < reportType.NumField(); i++ { if reportType.Field(i).Type == topologyType { want++ } } if have := len(report.MakeReport().Topologies()); want != have { t.Errorf("want %d, have %d", want, have) } }
func (r *Reporter) deploymentTopology(probeID string) (report.Topology, []Deployment, error) { var ( result = report.MakeTopology(). WithMetadataTemplates(DeploymentMetadataTemplates). WithMetricTemplates(DeploymentMetricTemplates). WithTableTemplates(TableTemplates) deployments = []Deployment{} ) result.Controls.AddControls(ScalingControls) err := r.client.WalkDeployments(func(d Deployment) error { result = result.AddNode(d.GetNode(probeID)) deployments = append(deployments, d) return nil }) return result, deployments, err }
func (r *Reporter) containerImageTopology() report.Topology { result := report.MakeTopology() r.registry.WalkImages(func(image *docker_client.APIImages) { nmd := report.MakeNodeWith(map[string]string{ ImageID: image.ID, }) AddLabels(nmd, image.Labels) if len(image.RepoTags) > 0 { nmd.Metadata[ImageName] = image.RepoTags[0] } nodeID := report.MakeContainerNodeID(r.hostID, image.ID) result.AddNode(nodeID, nmd) }) return result }
func (r *Reporter) containerImageTopology() report.Topology { result := report.MakeTopology() r.registry.WalkImages(func(image *docker_client.APIImages) { node := report.MakeNodeWith(map[string]string{ ImageID: image.ID, }) node = AddLabels(node, image.Labels) if len(image.RepoTags) > 0 { node = node.WithLatests(map[string]string{ImageName: image.RepoTags[0]}) } nodeID := report.MakeContainerImageNodeID(image.ID) result.AddNode(nodeID, node) }) return result }
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 }
func (r *Reporter) replicaSetTopology(probeID string, deployments []Deployment) (report.Topology, []ReplicaSet, error) { var ( result = report.MakeTopology(). WithMetadataTemplates(ReplicaSetMetadataTemplates). WithMetricTemplates(ReplicaSetMetricTemplates). WithTableTemplates(TableTemplates) replicaSets = []ReplicaSet{} selectors = []func(labelledChild){} ) result.Controls.AddControls(ScalingControls) for _, deployment := range deployments { selectors = append(selectors, match( deployment.Selector(), report.Deployment, report.MakeDeploymentNodeID(deployment.UID()), )) } err := r.client.WalkReplicaSets(func(r ReplicaSet) error { for _, selector := range selectors { selector(r) } result = result.AddNode(r.GetNode(probeID)) replicaSets = append(replicaSets, r) return nil }) if err != nil { return result, replicaSets, err } err = r.client.WalkReplicationControllers(func(r ReplicationController) error { for _, selector := range selectors { selector(r) } result = result.AddNode(r.GetNode(probeID)) replicaSets = append(replicaSets, ReplicaSet(r)) return nil }) return result, replicaSets, err }
func (r *Reporter) processTopology() (report.Topology, error) { t := report.MakeTopology() err := r.walker.Walk(func(p Process) { pidstr := strconv.Itoa(p.PID) nodeID := report.MakeProcessNodeID(r.scope, pidstr) t.Nodes[nodeID] = report.MakeNode() for _, tuple := range []struct{ key, value string }{ {PID, pidstr}, {Comm, p.Comm}, {Cmdline, p.Cmdline}, {Threads, strconv.Itoa(p.Threads)}, } { if tuple.value != "" { t.Nodes[nodeID].Metadata[tuple.key] = tuple.value } } if p.PPID > 0 { t.Nodes[nodeID].Metadata[PPID] = strconv.Itoa(p.PPID) } }) return t, err }
func TestAppClientPublish(t *testing.T) { var ( token = "abcdefg" id = "1234567" version = "0.18" rpt = report.MakeReport() done = make(chan struct{}, 10) ) // marshalling->unmarshaling is not idempotent due to `json:"omitempty"` // tags, transforming empty slices into nils. So, we make DeepEqual // happy by setting empty `json:"omitempty"` entries to nil rpt.Endpoint = report.MakeTopology() rpt.Process = report.MakeTopology() rpt.Container = report.MakeTopology() rpt.ContainerImage = report.MakeTopology() rpt.Pod = report.MakeTopology() rpt.Service = report.MakeTopology() rpt.Deployment = report.MakeTopology() rpt.ReplicaSet = report.MakeTopology() rpt.Host = report.MakeTopology() rpt.Overlay = report.MakeTopology() rpt.Endpoint.Controls = nil rpt.Process.Controls = nil rpt.Container.Controls = nil rpt.ContainerImage.Controls = nil rpt.Pod.Controls = nil rpt.Service.Controls = nil rpt.Deployment.Controls = nil rpt.ReplicaSet.Controls = nil rpt.Host.Controls = nil rpt.Overlay.Controls = nil s := dummyServer(t, token, id, version, rpt, done) defer s.Close() u, err := url.Parse(s.URL) if err != nil { t.Fatal(err) } pc := ProbeConfig{ Token: token, ProbeVersion: version, ProbeID: id, Insecure: false, } p, err := NewAppClient(pc, u.Host, s.URL, nil) if err != nil { t.Fatal(err) } defer p.Stop() // First few reports might be dropped as the client is spinning up. rp := NewReportPublisher(p) for i := 0; i < 10; i++ { if err := rp.Publish(rpt); err != nil { t.Error(err) } time.Sleep(10 * time.Millisecond) } select { case <-done: case <-time.After(100 * time.Millisecond): t.Error("timeout") } }
func TestWeaveTaggerOverlayTopology(t *testing.T) { w := overlay.NewWeave(mockHostID, weave.MockClient{}) defer w.Stop() // Wait until the reporter reports some nodes test.Poll(t, 300*time.Millisecond, 1, func() interface{} { have, _ := w.Report() return len(have.Overlay.Nodes) }) { // Overlay node should include peer name and nickname have, err := w.Report() if err != nil { t.Fatal(err) } nodeID := report.MakeOverlayNodeID(weave.MockWeavePeerName) node, ok := have.Overlay.Nodes[nodeID] if !ok { t.Errorf("Expected overlay node %q, but not found", nodeID) } if peerName, ok := node.Latest.Lookup(overlay.WeavePeerName); !ok || peerName != weave.MockWeavePeerName { t.Errorf("Expected weave peer name %q, got %q", weave.MockWeavePeerName, peerName) } if peerNick, ok := node.Latest.Lookup(overlay.WeavePeerNickName); !ok || peerNick != weave.MockWeavePeerNickName { t.Errorf("Expected weave peer nickname %q, got %q", weave.MockWeavePeerNickName, peerNick) } if localNetworks, ok := node.Sets.Lookup(host.LocalNetworks); !ok || !reflect.DeepEqual(localNetworks, report.MakeStringSet(weave.MockWeaveDefaultSubnet)) { t.Errorf("Expected weave node local_networks %q, got %q", report.MakeStringSet(weave.MockWeaveDefaultSubnet), localNetworks) } } { // Container nodes should be tagged with their overlay info nodeID := report.MakeContainerNodeID(weave.MockContainerID) have, err := w.Tag(report.Report{ Container: report.MakeTopology().AddNode(report.MakeNodeWith(nodeID, map[string]string{ docker.ContainerID: weave.MockContainerID, })), }) if err != nil { t.Fatal(err) } node, ok := have.Container.Nodes[nodeID] if !ok { t.Errorf("Expected container node %q, but not found", nodeID) } // Should have Weave DNS Hostname if have, ok := node.Latest.Lookup(overlay.WeaveDNSHostname); !ok || have != weave.MockHostname { t.Errorf("Expected weave dns hostname %q, got %q", weave.MockHostname, have) } // Should have Weave MAC Address if have, ok := node.Latest.Lookup(overlay.WeaveMACAddress); !ok || have != weave.MockContainerMAC { t.Errorf("Expected weave mac address %q, got %q", weave.MockContainerMAC, have) } // Should have Weave container ip if have, ok := node.Sets.Lookup(docker.ContainerIPs); !ok || !have.Contains(weave.MockContainerIP) { t.Errorf("Expected container ips to include the weave IP %q, got %q", weave.MockContainerIP, have) } // Should have Weave container ip (with scope) if have, ok := node.Sets.Lookup(docker.ContainerIPsWithScopes); !ok || !have.Contains(mockContainerIPWithScope) { t.Errorf("Expected container ips to include the weave IP (with scope) %q, got %q", mockContainerIPWithScope, have) } } }