func TestReportPostHandler(t *testing.T) { test := func(contentType string, encoder func(interface{}) ([]byte, error)) { router := mux.NewRouter() c := app.NewCollector(1 * time.Minute) app.RegisterReportPostHandler(c, router) ts := httptest.NewServer(router) defer ts.Close() b, err := encoder(fixture.Report) if err != nil { t.Fatalf("Content-Type %s: %s", contentType, err) } req, err := http.NewRequest("POST", ts.URL+"/api/report", bytes.NewReader(b)) if err != nil { t.Fatalf("Error posting report: %v", err) } req.Header.Set("Content-Type", contentType) resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("Error posting report %v", err) } _, err = ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { t.Fatalf("Error posting report: %v", err) } if resp.StatusCode != http.StatusOK { t.Fatalf("Error posting report: %d", resp.StatusCode) } ctx := context.Background() report, err := c.Report(ctx) if err != nil { t.Error(err) } if want, have := fixture.Report.Endpoint.Nodes, report.Endpoint.Nodes; len(have) == 0 || len(want) != len(have) { t.Fatalf("Content-Type %s: %v", contentType, test.Diff(have, want)) } } test("", func(v interface{}) ([]byte, error) { buf := &bytes.Buffer{} err := gob.NewEncoder(buf).Encode(v) return buf.Bytes(), err }) test("application/json", func(v interface{}) ([]byte, error) { buf := &bytes.Buffer{} err := codec.NewEncoder(buf, &codec.JsonHandle{}).Encode(v) return buf.Bytes(), err }) test("application/msgpack", func(v interface{}) ([]byte, error) { buf := &bytes.Buffer{} err := codec.NewEncoder(buf, &codec.MsgpackHandle{}).Encode(v) return buf.Bytes(), err }) }
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") } }
// Router creates the mux for all the various app components. func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.PipeRouter) http.Handler { router := mux.NewRouter().SkipClean(true) // We pull in the http.DefaultServeMux to get the pprof routes router.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux) router.Path("/metrics").Handler(prometheus.Handler()) app.RegisterReportPostHandler(collector, router) app.RegisterControlRoutes(router, controlRouter) app.RegisterPipeRoutes(router, pipeRouter) app.RegisterTopologyRoutes(router, collector) router.PathPrefix("/").Handler(http.FileServer(FS(false))) instrument := middleware.Instrument{ RouteMatcher: router, Duration: requestDuration, } return instrument.Wrap(router) }