Bootstrap copied BFF and local accounts with public Sendico contracts (#34)
This commit is contained in:
1 parent
67dc5b5b1e
commit
7062672a87
556 files changed
+42291
-777
No files matched your search
@@ -0,0 +1,155 @@
|
||||
package httptransport
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
amr "git.sendico.io/tech/sxchnge/bff/pkg/api/routers"
|
||||
"git.sendico.io/tech/sxchnge/bff/pkg/api/routers/health"
|
||||
"github.com/go-chi/chi/v5"
|
||||
chimetrics "github.com/go-chi/metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"go.uber.org/zap/zaptest/observer"
|
||||
"moul.io/chizap"
|
||||
)
|
||||
|
||||
func TestHTTPCollectorDoesNotGatherHealthOrMetricsRequests(t *testing.T) {
|
||||
router := chi.NewRouter()
|
||||
router.Use(chimetrics.Collector(chimetrics.CollectorOpts{
|
||||
Proto: true,
|
||||
Skip: func(r *http.Request) bool {
|
||||
return isObservabilityRequest("/api/v1", r.URL.Path)
|
||||
},
|
||||
}))
|
||||
router.Get("/api/v1/health", func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })
|
||||
router.Handle("/metrics", chimetrics.Handler())
|
||||
router.Handle("/api/v1/metrics", chimetrics.Handler())
|
||||
router.Get("/api/v1/accounts", func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })
|
||||
|
||||
beforeHealth := gatheredHTTPRequestCount(t, "GET /api/v1/health")
|
||||
beforeMetrics := gatheredHTTPRequestCount(t, "GET /metrics")
|
||||
beforeAPIMetrics := gatheredHTTPRequestCount(t, "GET /api/v1/metrics")
|
||||
beforeApplication := gatheredHTTPRequestCount(t, "GET /api/v1/accounts")
|
||||
|
||||
for _, requestPath := range []string{"/api/v1/health", "/metrics", "/api/v1/metrics", "/api/v1/accounts"} {
|
||||
request := httptest.NewRequestWithContext(context.Background(), http.MethodGet, requestPath, nil)
|
||||
response := httptest.NewRecorder()
|
||||
router.ServeHTTP(response, request)
|
||||
if response.Code != http.StatusOK {
|
||||
t.Fatalf("GET %s returned %d", requestPath, response.Code)
|
||||
}
|
||||
}
|
||||
|
||||
if got := gatheredHTTPRequestCount(t, "GET /api/v1/health") - beforeHealth; got != 0 {
|
||||
t.Fatalf("health probe changed http_requests_total by %v", got)
|
||||
}
|
||||
if got := gatheredHTTPRequestCount(t, "GET /metrics") - beforeMetrics; got != 0 {
|
||||
t.Fatalf("metrics scrape changed http_requests_total by %v", got)
|
||||
}
|
||||
if got := gatheredHTTPRequestCount(t, "GET /api/v1/metrics") - beforeAPIMetrics; got != 0 {
|
||||
t.Fatalf("API metrics scrape changed http_requests_total by %v", got)
|
||||
}
|
||||
if got := gatheredHTTPRequestCount(t, "GET /api/v1/accounts") - beforeApplication; got != 1 {
|
||||
t.Fatalf("application request changed http_requests_total by %v, want 1", got)
|
||||
}
|
||||
}
|
||||
|
||||
func gatheredHTTPRequestCount(t *testing.T, endpoint string) float64 {
|
||||
t.Helper()
|
||||
|
||||
families, err := prometheus.DefaultGatherer.Gather()
|
||||
if err != nil {
|
||||
t.Fatalf("gather metrics: %v", err)
|
||||
}
|
||||
for _, family := range families {
|
||||
if family.GetName() != "http_requests_total" {
|
||||
continue
|
||||
}
|
||||
|
||||
var total float64
|
||||
for _, metric := range family.GetMetric() {
|
||||
for _, label := range metric.GetLabel() {
|
||||
if label.GetName() == "endpoint" && label.GetValue() == endpoint {
|
||||
total += metric.GetCounter().GetValue()
|
||||
}
|
||||
}
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func TestObservabilityRequestsAreExcludedFromHTTPMetrics(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
apiEndpoint string
|
||||
requestPath string
|
||||
want bool
|
||||
}{
|
||||
{name: "health under API endpoint", apiEndpoint: "/api/v1", requestPath: "/api/v1/health", want: true},
|
||||
{name: "metrics at root", apiEndpoint: "/api/v1", requestPath: "/metrics", want: true},
|
||||
{name: "metrics under API endpoint", apiEndpoint: "/api/v1", requestPath: "/api/v1/metrics", want: true},
|
||||
{name: "trailing endpoint slash", apiEndpoint: "/api/v1/", requestPath: "/api/v1/health", want: true},
|
||||
{name: "application endpoint", apiEndpoint: "/api/v1", requestPath: "/api/v1/accounts", want: false},
|
||||
{name: "health suffix is not a probe", apiEndpoint: "/api/v1", requestPath: "/api/v1/health/history", want: false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := isObservabilityRequest(tt.apiEndpoint, tt.requestPath); got != tt.want {
|
||||
t.Fatalf("isObservabilityRequest(%q, %q) = %t, want %t", tt.apiEndpoint, tt.requestPath, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealthMountedOutsideTraceMiddleware(t *testing.T) {
|
||||
core, observed := observer.New(zapcore.InfoLevel)
|
||||
logger := zap.New(core)
|
||||
|
||||
rootRouter := chi.NewRouter()
|
||||
apiRouter := chi.NewRouter()
|
||||
|
||||
apiRouter.Use(chizap.New(logger.Named("middleware").Named("http_trace"), &chizap.Opts{}))
|
||||
apiRouter.Get("/api/v1/accounts", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
healthRouter, err := amr.NewHealthRouter(logger.Named("middleware"), rootRouter, "/api/v1")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create health router: %v", err)
|
||||
}
|
||||
healthRouter.SetStatus(health.SSRunning)
|
||||
|
||||
rootRouter.Mount("/", apiRouter)
|
||||
|
||||
healthReq := httptest.NewRequestWithContext(context.Background(), http.MethodGet, "/api/v1/health", nil)
|
||||
healthRes := httptest.NewRecorder()
|
||||
rootRouter.ServeHTTP(healthRes, healthReq)
|
||||
if healthRes.Code != http.StatusOK {
|
||||
t.Fatalf("expected health status %d, got %d", http.StatusOK, healthRes.Code)
|
||||
}
|
||||
if got := observed.FilterMessage("Served").Len(); got != 0 {
|
||||
t.Fatalf("expected no trace logs for /health, got %d", got)
|
||||
}
|
||||
|
||||
apiReq := httptest.NewRequestWithContext(context.Background(), http.MethodGet, "/api/v1/accounts", nil)
|
||||
apiRes := httptest.NewRecorder()
|
||||
rootRouter.ServeHTTP(apiRes, apiReq)
|
||||
if apiRes.Code != http.StatusOK {
|
||||
t.Fatalf("expected api status %d, got %d", http.StatusOK, apiRes.Code)
|
||||
}
|
||||
|
||||
entries := observed.FilterMessage("Served").All()
|
||||
if len(entries) != 1 {
|
||||
t.Fatalf("expected one trace log for non-health request, got %d", len(entries))
|
||||
}
|
||||
if got := entries[0].ContextMap()["path"]; got != "/api/v1/accounts" {
|
||||
t.Fatalf("expected logged path %q, got %#v", "/api/v1/accounts", got)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user