143 lines
3.7 KiB
Go
143 lines
3.7 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_MissingState(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)
|
|
|
|
// Missing state.yaml is handled gracefully — reconciliation proceeds
|
|
// with empty config, generating a minimal HAProxy config.
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("expected 200, 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())
|
|
}
|
|
}
|