func TestLatestMapEncoding(t *testing.T) { now := time.Now() want := EmptyLatestMap. Set("foo", now, "bar"). Set("bar", now, "baz") { gobs, err := want.GobEncode() if err != nil { t.Fatal(err) } have := EmptyLatestMap have.GobDecode(gobs) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { json, err := want.MarshalJSON() if err != nil { t.Fatal(err) } have := EmptyLatestMap have.UnmarshalJSON(json) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } }
func TestEdgeMetadatasEncoding(t *testing.T) { want := EmptyEdgeMetadatas. Add("foo", EdgeMetadata{ EgressPacketCount: newu64(1), MaxConnCountTCP: newu64(2), }). Add("bar", EdgeMetadata{ EgressPacketCount: newu64(3), MaxConnCountTCP: newu64(5), }) { gobs, err := want.GobEncode() if err != nil { t.Fatal(err) } have := EmptyEdgeMetadatas have.GobDecode(gobs) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { json, err := want.MarshalJSON() if err != nil { t.Fatal(err) } have := EmptyEdgeMetadatas have.UnmarshalJSON(json) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } }
func TestFilterUnconnectedPesudoNodes(t *testing.T) { // Test pseudo nodes that are made unconnected by filtering // are also removed. { nodes := render.RenderableNodes{ "foo": {ID: "foo", Node: report.MakeNode().WithAdjacent("bar")}, "bar": {ID: "bar", Node: report.MakeNode().WithAdjacent("baz")}, "baz": {ID: "baz", Node: report.MakeNode(), Pseudo: true}, } renderer := render.Filter{ FilterFunc: func(node render.RenderableNode) bool { return true }, Renderer: mockRenderer{RenderableNodes: nodes}, } want := nodes.Prune() have := renderer.Render(report.MakeReport()).Prune() if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { renderer := render.Filter{ FilterFunc: func(node render.RenderableNode) bool { return node.ID != "bar" }, Renderer: mockRenderer{RenderableNodes: render.RenderableNodes{ "foo": {ID: "foo", Node: report.MakeNode().WithAdjacent("bar")}, "bar": {ID: "bar", Node: report.MakeNode().WithAdjacent("baz")}, "baz": {ID: "baz", Node: report.MakeNode(), Pseudo: true}, }}, } want := render.RenderableNodes{ "foo": {ID: "foo", Node: report.MakeNode()}, } have := renderer.Render(report.MakeReport()).Prune() if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { renderer := render.Filter{ FilterFunc: func(node render.RenderableNode) bool { return node.ID != "bar" }, Renderer: mockRenderer{RenderableNodes: render.RenderableNodes{ "foo": {ID: "foo", Node: report.MakeNode()}, "bar": {ID: "bar", Node: report.MakeNode().WithAdjacent("foo")}, "baz": {ID: "baz", Node: report.MakeNode().WithAdjacent("bar"), Pseudo: true}, }}, } want := render.RenderableNodes{ "foo": {ID: "foo", Node: report.MakeNode()}, } have := renderer.Render(report.MakeReport()).Prune() if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } }
func TestCollector(t *testing.T) { window := time.Millisecond c := xfer.NewCollector(window) r1 := report.MakeReport() r1.Endpoint.NodeMetadatas["foo"] = report.MakeNodeMetadata() r2 := report.MakeReport() r2.Endpoint.NodeMetadatas["bar"] = report.MakeNodeMetadata() if want, have := report.MakeReport(), c.Report(); !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } c.Add(r1) if want, have := r1, c.Report(); !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } c.Add(r2) merged := report.MakeReport() merged = merged.Merge(r1) merged = merged.Merge(r2) if want, have := merged, c.Report(); !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestCountersEncoding(t *testing.T) { want := EmptyCounters. Add("foo", 1). Add("bar", 2) { gobs, err := want.GobEncode() if err != nil { t.Fatal(err) } have := EmptyCounters have.GobDecode(gobs) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { json, err := want.MarshalJSON() if err != nil { t.Fatal(err) } have := EmptyCounters have.UnmarshalJSON(json) if !reflect.DeepEqual(want, have) { t.Error(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 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().WithEdge(dstEndpointNodeID, report.EdgeMetadata{ EgressPacketCount: newu64(1), EgressByteCount: newu64(256), }), dstEndpointNodeID: report.MakeNode(), }, }), 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().WithEdge(dstAddressNodeID, report.EdgeMetadata{ EgressPacketCount: newu64(1), EgressByteCount: newu64(512), }), dstAddressNodeID: report.MakeNode(), }, }), rpt.Address; !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestMetricCopy(t *testing.T) { want := report.MakeMetric() have := want.Copy() if !reflect.DeepEqual(want, have) { t.Errorf("diff: %s", test.Diff(want, have)) } want = report.MakeMetric().Add(time.Now(), 1) have = want.Copy() if !reflect.DeepEqual(want, have) { t.Errorf("diff: %s", test.Diff(want, have)) } }
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 TestEdgeMetadataFlatten(t *testing.T) { // Test two EdgeMetadatas flatten to the correct values { have := (EdgeMetadata{ EgressPacketCount: newu64(1), MaxConnCountTCP: newu64(2), }).Flatten(EdgeMetadata{ EgressPacketCount: newu64(4), EgressByteCount: newu64(8), MaxConnCountTCP: newu64(16), }) want := EdgeMetadata{ EgressPacketCount: newu64(1 + 4), EgressByteCount: newu64(8), MaxConnCountTCP: newu64(2 + 16), // flatten should sum MaxConnCountTCP } if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } // Test an EdgeMetadatas flatten to the correct value (should // just sum) { have := EmptyEdgeMetadatas. Add("foo", EdgeMetadata{ EgressPacketCount: newu64(1), MaxConnCountTCP: newu64(2), }). Add("bar", EdgeMetadata{ EgressPacketCount: newu64(3), MaxConnCountTCP: newu64(5), }).Flatten() want := EdgeMetadata{ EgressPacketCount: newu64(1 + 3), MaxConnCountTCP: newu64(2 + 5), } if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { // Should not panic on nil have := EdgeMetadatas{}.Flatten() want := EdgeMetadata{} if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } }
func TestCountersDeepEquals(t *testing.T) { want := EmptyCounters. Add("foo", 3) have := EmptyCounters. Add("foo", 3) if !reflect.DeepEqual(want, have) { t.Errorf(test.Diff(want, have)) } notequal := EmptyCounters. Add("foo", 4) if reflect.DeepEqual(want, notequal) { t.Errorf(test.Diff(want, have)) } }
func TestLatestMapDeepEquals(t *testing.T) { now := time.Now() want := EmptyLatestMap. Set("foo", now, "Bar") have := EmptyLatestMap. Set("foo", now, "Bar") if !reflect.DeepEqual(want, have) { t.Errorf(test.Diff(want, have)) } notequal := EmptyLatestMap. Set("foo", now, "Baz") if reflect.DeepEqual(want, notequal) { t.Errorf(test.Diff(want, have)) } }
func TestWeaveTaggerOverlayTopology(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(mockWeaveRouter)) defer s.Close() w, err := overlay.NewWeave(s.URL) if err != nil { t.Fatal(err) } have, err := w.Report() if err != nil { t.Fatal(err) } if want, have := (report.Topology{ Adjacency: report.Adjacency{}, EdgeMetadatas: report.EdgeMetadatas{}, NodeMetadatas: report.NodeMetadatas{ report.MakeOverlayNodeID(mockWeavePeerName): report.NewNodeMetadata(map[string]string{ overlay.WeavePeerName: mockWeavePeerName, overlay.WeavePeerNickName: mockWeavePeerNickName, }), }, }), have.Overlay; !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestAPITopologyApplications(t *testing.T) { ts := httptest.NewServer(Router(StaticReport{})) defer ts.Close() is404(t, ts, "/api/topology/applications/foobar") { 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, expected.ServerProcessID, node.Node.ID) equals(t, "apache", node.Node.LabelMajor) equals(t, fmt.Sprintf("%s (server:%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, fmt.Sprintf("/api/topology/applications/%s/%s", expected.ClientProcess1ID, expected.ServerProcessID)) var edge APIEdge if err := json.Unmarshal(body, &edge); err != nil { t.Fatalf("JSON parse error: %s", err) } if want, have := (report.EdgeMetadata{ EgressPacketCount: newu64(10), EgressByteCount: newu64(100), }), edge.Metadata; !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } }
func TestHostRenderer(t *testing.T) { have := render.HostRenderer.Render(test.Report).Prune() want := expected.RenderedHosts if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestReporter(t *testing.T) { want := report.MakeReport() want.Container = report.Topology{ Adjacency: report.Adjacency{}, EdgeMetadatas: report.EdgeMetadatas{}, NodeMetadatas: report.NodeMetadatas{ report.MakeContainerNodeID("", "ping"): report.NewNodeMetadata(map[string]string{ docker.ContainerID: "ping", docker.ContainerName: "pong", docker.ImageID: "baz", }), }, } want.ContainerImage = report.Topology{ Adjacency: report.Adjacency{}, EdgeMetadatas: report.EdgeMetadatas{}, NodeMetadatas: report.NodeMetadatas{ report.MakeContainerNodeID("", "baz"): report.NewNodeMetadata(map[string]string{ docker.ImageID: "baz", docker.ImageName: "bang", }), }, } reporter := docker.NewReporter(mockRegistryInstance, "") have, _ := reporter.Report() if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestMetadataRowCopy(t *testing.T) { var ( row = report.MetadataRow{ ID: "id", Value: "value", Priority: 1, Datatype: "datatype", } cp = row.Copy() ) // copy should be identical if !reflect.DeepEqual(row, cp) { t.Error(test.Diff(row, cp)) } // changing the copy should not change the original cp.ID = "" cp.Value = "" cp.Priority = 2 cp.Datatype = "" if row.ID != "id" || row.Value != "value" || row.Priority != 1 || row.Datatype != "datatype" { t.Errorf("Expected changing the copy not to modify the original") } }
func TestLatestMapDeleteNil(t *testing.T) { want := LatestMap{} have := LatestMap{}.Delete("foo") if !reflect.DeepEqual(want, have) { t.Errorf(test.Diff(want, have)) } }
func TestContainerImageRenderer(t *testing.T) { have := render.ContainerImageRenderer.Render(fixture.Report).Prune() want := expected.RenderedContainerImages if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestMergeRenderableNode(t *testing.T) { node1 := render.RenderableNode{ ID: "foo", LabelMajor: "", LabelMinor: "minor", Rank: "", Pseudo: false, Node: report.MakeNode().WithAdjacent("a1"), Origins: report.MakeIDList("o1"), } node2 := render.RenderableNode{ ID: "foo", LabelMajor: "major", LabelMinor: "", Rank: "rank", Pseudo: false, Node: report.MakeNode().WithAdjacent("a2"), Origins: report.MakeIDList("o2"), } want := render.RenderableNode{ ID: "foo", LabelMajor: "major", LabelMinor: "minor", Rank: "rank", Pseudo: false, Node: report.MakeNode().WithAdjacency(report.MakeIDList("a1", "a2")), Origins: report.MakeIDList("o1", "o2"), EdgeMetadata: report.EdgeMetadata{}, } have := node1.Merge(node2) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestMemoise(t *testing.T) { calls := 0 r := renderFunc(func(rpt report.Report) render.RenderableNodes { calls++ return render.RenderableNodes{rpt.ID: render.NewRenderableNode(rpt.ID)} }) m := render.Memoise(r) rpt1 := report.MakeReport() result1 := m.Render(rpt1) // 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) 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) 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") } }
func TestHostRenderer(t *testing.T) { have := Prune(render.HostRenderer.Render(fixture.Report, FilterNoop)) want := Prune(expected.RenderedHosts) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestMetricRowSummary(t *testing.T) { var ( now = time.Now() metric = report.MakeMetric().Add(now, 1.234) row = report.MetricRow{ ID: "id", Format: "format", Group: "group", Value: 1.234, Priority: 1, Metric: &metric, } summary = row.Summary() ) // summary should not have any samples if summary.Metric.Len() != 0 { t.Errorf("Expected summary to have no samples, but had %d", summary.Metric.Len()) } // original metric should still have its samples if metric.Len() != 1 { t.Errorf("Expected original metric to still have it's samples, but had %d", metric.Len()) } // summary should have all the same fields (minus the metric) summary.Metric = nil row.Metric = nil if !reflect.DeepEqual(summary, row) { t.Errorf("Expected summary to have same fields as original: %s", test.Diff(summary, row)) } }
func TestLinuxConnections(t *testing.T) { fs_hook.Mock(mockFS) defer fs_hook.Restore() iter, err := cbConnections(true, process.NewWalker("/proc")) if err != nil { t.Fatal(err) } have := iter.Next() want := &Connection{ LocalAddress: net.ParseIP("0.0.0.0").To4(), LocalPort: 42688, RemoteAddress: net.ParseIP("0.0.0.0").To4(), RemotePort: 0, inode: 5107, Proc: Proc{ PID: 1, Name: "foo", }, } if !reflect.DeepEqual(want, have) { t.Fatal(test.Diff(want, have)) } if have := iter.Next(); have != nil { t.Fatal(have) } }
func TestTagger(t *testing.T) { oldProcessTree := docker.NewProcessTreeStub defer func() { docker.NewProcessTreeStub = oldProcessTree }() docker.NewProcessTreeStub = func(_ process.Walker) (process.Tree, error) { return &mockProcessTree{map[int]int{3: 2}}, nil } var ( pid1NodeID = report.MakeProcessNodeID("somehost.com", "2") pid2NodeID = report.MakeProcessNodeID("somehost.com", "3") wantNode = report.MakeNodeWith(map[string]string{docker.ContainerID: "ping"}) ) input := report.MakeReport() input.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"})) input.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"})) want := report.MakeReport() want.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"}).Merge(wantNode)) want.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"}).Merge(wantNode)) tagger := docker.NewTagger(mockRegistryInstance, nil) have, err := tagger.Tag(input) if err != nil { t.Errorf("%v", err) } if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestLinuxConnections(t *testing.T) { fs_hook.Mock(mockFS) defer fs_hook.Restore() scanner := NewConnectionScanner(process.NewWalker("/proc")) defer scanner.Stop() // let the background scanner finish its first pass time.Sleep(1 * time.Second) iter, err := scanner.Connections(true) if err != nil { t.Fatal(err) } have := iter.Next() want := &Connection{ LocalAddress: net.ParseIP("0.0.0.0").To4(), LocalPort: 42688, RemoteAddress: net.ParseIP("0.0.0.0").To4(), RemotePort: 0, inode: 5107, Proc: Proc{ PID: 1, Name: "foo", }, } if !reflect.DeepEqual(want, have) { t.Fatal(test.Diff(want, have)) } if have := iter.Next(); have != nil { t.Fatal(have) } }
func TestContainerRenderer(t *testing.T) { have := (render.ContainerWithImageNameRenderer.Render(test.Report)).Prune() want := expected.RenderedContainers if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestPipes(t *testing.T) { oldNewPipe := controls.NewPipe defer func() { controls.NewPipe = oldNewPipe }() controls.NewPipe = func(_ controls.PipeClient, _ string) (string, xfer.Pipe, error) { return "pipeid", mockPipe{}, nil } mdc := newMockClient() setupStubs(mdc, func() { registry, _ := docker.NewRegistry(10*time.Second, nil) defer registry.Stop() test.Poll(t, 100*time.Millisecond, true, func() interface{} { _, ok := registry.GetContainer("ping") return ok }) for _, tc := range []string{ docker.AttachContainer, docker.ExecContainer, } { result := controls.HandleControlRequest(xfer.Request{ Control: tc, NodeID: report.MakeContainerNodeID("ping"), }) want := xfer.Response{ Pipe: "pipeid", RawTTY: true, } if !reflect.DeepEqual(result, want) { t.Errorf("diff: %s", test.Diff(want, result)) } } }) }
func TestPodRenderer(t *testing.T) { have := render.PodRenderer.Render(fixture.Report).Prune() want := expected.RenderedPods if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestDNSAdd(t *testing.T) { mtx := sync.Mutex{} published := map[string]entry{} s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mtx.Lock() defer mtx.Unlock() parts := strings.SplitN(r.URL.Path, "/", 4) containerID, ip := parts[2], net.ParseIP(parts[3]) fqdn := r.FormValue("fqdn") published[fqdn] = entry{containerID, ip} w.WriteHeader(http.StatusNoContent) })) defer s.Close() client := weave.NewClient(s.URL) err := client.AddDNSEntry(mockHostname, mockContainerID, mockIP) if err != nil { t.Fatal(err) } want := map[string]entry{ mockHostname: {mockContainerID, mockIP}, } if !reflect.DeepEqual(published, want) { t.Fatal(test.Diff(published, want)) } }