feat: migrate receiver to Fuego framework with OpenAPI generation
Replace net/http handlers with Fuego framework for automatic OpenAPI 3.0 spec generation. Add generated Go client package, OpenAPI extraction script, and update Makefile with separate build/run targets for both binaries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
479c13f596
commit
bc9d0dd8ea
11 changed files with 2245 additions and 252 deletions
|
|
@ -11,6 +11,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-fuego/fuego"
|
||||
|
||||
"edp.buildth.ing/DevFW-CICD/forgejo-runner-sizer/internal/summary"
|
||||
)
|
||||
|
||||
|
|
@ -42,9 +44,8 @@ func TestHandler_ReceiveMetrics(t *testing.T) {
|
|||
req.Header.Set("Authorization", "Bearer "+pushToken)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusCreated {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusCreated)
|
||||
|
|
@ -69,9 +70,8 @@ func TestHandler_ReceiveMetrics_InvalidJSON(t *testing.T) {
|
|||
req := httptest.NewRequest(http.MethodPost, "/api/v1/metrics", bytes.NewReader([]byte("not json")))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusBadRequest {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
||||
|
|
@ -95,9 +95,8 @@ func TestHandler_ReceiveMetrics_MissingRunID(t *testing.T) {
|
|||
req := httptest.NewRequest(http.MethodPost, "/api/v1/metrics", bytes.NewReader(body))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusBadRequest {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
||||
|
|
@ -125,9 +124,8 @@ func TestHandler_GetByWorkflowJob(t *testing.T) {
|
|||
req.Header.Set("Authorization", "Bearer "+readToken)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusOK)
|
||||
|
|
@ -151,9 +149,8 @@ func TestHandler_GetByWorkflowJob_NotFound(t *testing.T) {
|
|||
req.Header.Set("Authorization", "Bearer "+readToken)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusOK)
|
||||
|
|
@ -180,8 +177,7 @@ func TestHandler_GetByWorkflowJob_WithToken(t *testing.T) {
|
|||
t.Fatalf("SaveMetric() error = %v", err)
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
s := newTestServer(h)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -201,7 +197,7 @@ func TestHandler_GetByWorkflowJob_WithToken(t *testing.T) {
|
|||
req.Header.Set("Authorization", tt.authHeader)
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rec, req)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != tt.wantCode {
|
||||
t.Errorf("status = %d, want %d", rec.Code, tt.wantCode)
|
||||
|
|
@ -217,9 +213,8 @@ func TestHandler_Health(t *testing.T) {
|
|||
req := httptest.NewRequest(http.MethodGet, "/health", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusOK)
|
||||
|
|
@ -250,9 +245,8 @@ func TestHandler_GenerateToken(t *testing.T) {
|
|||
req.Header.Set("Content-Type", "application/json")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d", rec.Code, http.StatusOK)
|
||||
|
|
@ -289,9 +283,8 @@ func TestHandler_GenerateToken_NoAuth(t *testing.T) {
|
|||
req := httptest.NewRequest(http.MethodPost, "/api/v1/token", bytes.NewReader(body))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusUnauthorized {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusUnauthorized)
|
||||
|
|
@ -314,9 +307,8 @@ func TestHandler_GenerateToken_MissingFields(t *testing.T) {
|
|||
req.Header.Set("Content-Type", "application/json")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusBadRequest {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
||||
|
|
@ -338,12 +330,12 @@ func TestHandler_GenerateToken_NoReadToken(t *testing.T) {
|
|||
req.Header.Set("Content-Type", "application/json")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusBadRequest {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
||||
// With no read token, the middleware rejects before we reach the handler
|
||||
if rec.Code != http.StatusUnauthorized {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,8 +344,7 @@ func TestHandler_ReceiveMetrics_WithPushToken(t *testing.T) {
|
|||
h, cleanup := newTestHandlerWithToken(t, readToken)
|
||||
defer cleanup()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
s := newTestServer(h)
|
||||
|
||||
exec := ExecutionContext{
|
||||
Organization: "org",
|
||||
|
|
@ -391,7 +382,7 @@ func TestHandler_ReceiveMetrics_WithPushToken(t *testing.T) {
|
|||
req.Header.Set("Authorization", tt.authHeader)
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rec, req)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != tt.wantCode {
|
||||
t.Errorf("status = %d, want %d", rec.Code, tt.wantCode)
|
||||
|
|
@ -420,9 +411,8 @@ func TestHandler_ReceiveMetrics_RejectsWhenNoReadToken(t *testing.T) {
|
|||
req.Header.Set("Content-Type", "application/json")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusUnauthorized {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusUnauthorized)
|
||||
|
|
@ -436,15 +426,27 @@ func TestHandler_GetByWorkflowJob_RejectsWhenNoReadToken(t *testing.T) {
|
|||
req := httptest.NewRequest(http.MethodGet, "/api/v1/metrics/repo/org/repo/ci.yml/build", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
mux.ServeHTTP(rec, req)
|
||||
s := newTestServer(h)
|
||||
s.Mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusUnauthorized {
|
||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestServer(h *Handler) *fuego.Server {
|
||||
s := fuego.NewServer(
|
||||
fuego.WithoutStartupMessages(),
|
||||
fuego.WithEngineOptions(
|
||||
fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{
|
||||
Disabled: true,
|
||||
}),
|
||||
),
|
||||
)
|
||||
h.RegisterRoutes(s)
|
||||
return s
|
||||
}
|
||||
|
||||
func newTestHandler(t *testing.T) (*Handler, func()) {
|
||||
t.Helper()
|
||||
dbPath := filepath.Join(t.TempDir(), "test.db")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue