Files
wild-central/internal/api/v1/handlers_haproxy_test.go
2026-07-10 05:21:03 +00:00

141 lines
3.6 KiB
Go

package v1
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
)
func setupTestHaproxy(t *testing.T) (*API, string) {
tmpDir := t.TempDir()
haproxyPath := filepath.Join(tmpDir, "haproxy.cfg")
t.Setenv("WILD_CENTRAL_HAPROXY_CONFIG_PATH", haproxyPath)
t.Setenv("WILD_CENTRAL_NFTABLES_RULES_PATH", filepath.Join(tmpDir, "wild-central.nft"))
api, err := NewAPI(tmpDir, "", nil)
if err != nil {
t.Fatalf("failed to create test API: %v", err)
}
api.haproxy.SetSocketPath(filepath.Join(tmpDir, "haproxy.sock"))
return api, tmpDir
}
func TestHaproxyStatus_ReturnsStatus(t *testing.T) {
api, _ := setupTestHaproxy(t)
req := httptest.NewRequest("GET", "/api/v1/haproxy/status", nil)
w := httptest.NewRecorder()
api.HaproxyStatus(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
var resp map[string]any
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("invalid JSON: %v", err)
}
if _, ok := resp["status"]; !ok {
t.Error("expected 'status' field in response")
}
}
func TestHaproxyGetConfig_WhenFileExists(t *testing.T) {
api, tmpDir := setupTestHaproxy(t)
configPath := filepath.Join(tmpDir, "haproxy.cfg")
content := "# test haproxy config\nglobal\n daemon\n"
if err := os.WriteFile(configPath, []byte(content), 0644); err != nil {
t.Fatalf("failed to write config: %v", err)
}
req := httptest.NewRequest("GET", "/api/v1/haproxy/config", nil)
w := httptest.NewRecorder()
api.HaproxyGetConfig(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
var resp map[string]any
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("invalid JSON: %v", err)
}
if got, _ := resp["content"].(string); got != content {
t.Errorf("content mismatch: got %q, want %q", got, content)
}
}
func TestHaproxyGetConfig_WhenFileMissing(t *testing.T) {
api, _ := setupTestHaproxy(t)
req := httptest.NewRequest("GET", "/api/v1/haproxy/config", nil)
w := httptest.NewRecorder()
api.HaproxyGetConfig(w, req)
if w.Code != http.StatusInternalServerError {
t.Fatalf("expected 500, got %d: %s", w.Code, w.Body.String())
}
}
func TestHaproxyStats_WhenSocketMissing(t *testing.T) {
api, _ := setupTestHaproxy(t)
req := httptest.NewRequest("GET", "/api/v1/haproxy/stats", nil)
w := httptest.NewRecorder()
api.HaproxyStats(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
var resp map[string]any
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("invalid JSON: %v", err)
}
backends, ok := resp["backends"].([]any)
if !ok {
t.Fatalf("expected 'backends' array, got %T: %v", resp["backends"], resp["backends"])
}
if len(backends) != 0 {
t.Errorf("expected empty backends, got %d", len(backends))
}
}
func TestHaproxyGenerate_MissingGlobalConfig(t *testing.T) {
api, tmpDir := setupTestHaproxy(t)
os.Remove(filepath.Join(tmpDir, "state.yaml"))
req := httptest.NewRequest("POST", "/api/v1/haproxy/generate", nil)
w := httptest.NewRecorder()
api.HaproxyGenerate(w, req)
if w.Code != http.StatusInternalServerError {
t.Fatalf("expected 500, got %d: %s", w.Code, w.Body.String())
}
}
func TestHaproxyGenerate_NoServices(t *testing.T) {
api, _ := setupTestHaproxy(t)
req := httptest.NewRequest("POST", "/api/v1/haproxy/generate", nil)
w := httptest.NewRecorder()
api.HaproxyGenerate(w, req)
// 200 on device, 500 in CI (no systemctl)
if w.Code != http.StatusOK && w.Code != http.StatusInternalServerError {
t.Errorf("unexpected status %d: %s", w.Code, w.Body.String())
}
}