Files
pulse/internal/api/connections_handlers_continuity_test.go
T
2026-05-25 18:20:11 +01:00

159 lines
4.9 KiB
Go

package api
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/internal/monitoring"
agentshost "github.com/rcourtman/pulse-go-rewrite/pkg/agents/host"
)
func TestConnectionsHandleListIncludesContinuityBackedHostAgents(t *testing.T) {
dir := t.TempDir()
cfg := &config.Config{DataPath: dir}
now := time.Now().UTC()
seedMonitor, err := monitoring.New(cfg)
if err != nil {
t.Fatalf("monitoring.New seed monitor: %v", err)
}
t.Cleanup(seedMonitor.Stop)
_, err = seedMonitor.ApplyHostReport(agentshost.Report{
Agent: agentshost.AgentInfo{
ID: "agent-1",
Version: "6.0.0-rc.1",
IntervalSeconds: 30,
},
Host: agentshost.HostInfo{
ID: "machine-1",
MachineID: "machine-1",
Hostname: "host-1.local",
Platform: "linux",
},
Timestamp: now,
}, &config.APITokenRecord{ID: "token-1", Name: "Token One"})
if err != nil {
t.Fatalf("ApplyHostReport seed continuity: %v", err)
}
reloadedMonitor, err := monitoring.New(cfg)
if err != nil {
t.Fatalf("monitoring.New reloaded monitor: %v", err)
}
t.Cleanup(reloadedMonitor.Stop)
handler := NewConnectionsHandlers(
func(context.Context) *config.Config { return cfg },
func(context.Context) *config.ConfigPersistence { return nil },
func(context.Context) *monitoring.Monitor { return reloadedMonitor },
)
req := httptest.NewRequest(http.MethodGet, "/api/connections", nil)
rec := httptest.NewRecorder()
handler.HandleList(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, body=%s", rec.Code, rec.Body.String())
}
var resp ConnectionsListResponse
if err := json.NewDecoder(rec.Body).Decode(&resp); err != nil {
t.Fatalf("decode connections response: %v", err)
}
if len(resp.Connections) != 1 {
t.Fatalf("expected 1 continuity-backed connection, got %d", len(resp.Connections))
}
conn := resp.Connections[0]
if conn.ID != "agent:machine-1" {
t.Fatalf("connection id = %q, want %q", conn.ID, "agent:machine-1")
}
if conn.Type != ConnectionTypeAgent {
t.Fatalf("connection type = %q, want %q", conn.Type, ConnectionTypeAgent)
}
if conn.Name != "host-1.local" || conn.Address != "host-1.local" {
t.Fatalf("unexpected continuity-backed connection identity: name=%q address=%q", conn.Name, conn.Address)
}
if conn.State != ConnectionStateActive {
t.Fatalf("connection state = %q, want %q", conn.State, ConnectionStateActive)
}
if conn.Source != ConnectionSourceAgent {
t.Fatalf("connection source = %q, want %q", conn.Source, ConnectionSourceAgent)
}
if conn.LastSeen == nil || conn.LastSeen.IsZero() {
t.Fatalf("expected continuity-backed connection to carry lastSeen, got %#v", conn.LastSeen)
}
}
func TestConnectionsHandleListUsesTrueNASPollerRuntimeSummary(t *testing.T) {
persistence := config.NewConfigPersistence(t.TempDir())
connection := config.TrueNASInstance{
ID: "tn1",
Name: "TrueNAS",
Host: "truenas.lan",
APIKey: "secret",
UseHTTPS: true,
Enabled: true,
PollIntervalSecs: 60,
MonitorDatasets: true,
MonitorPools: true,
MonitorReplication: true,
}
if err := persistence.SaveTrueNASConfig([]config.TrueNASInstance{connection}); err != nil {
t.Fatalf("SaveTrueNASConfig: %v", err)
}
poller := monitoring.NewTrueNASPoller(nil, time.Minute, nil)
successAt := time.Now().UTC().Add(-30 * time.Second)
poller.RecordConnectionTestSuccess("default", connection.ID, connection, successAt)
handler := NewConnectionsHandlers(
func(context.Context) *config.Config { return nil },
func(context.Context) *config.ConfigPersistence { return persistence },
func(context.Context) *monitoring.Monitor { return nil },
)
handler.SetPlatformPollers(
func(context.Context) *monitoring.TrueNASPoller { return poller },
nil,
)
req := httptest.NewRequest(http.MethodGet, "/api/connections", nil)
rec := httptest.NewRecorder()
handler.HandleList(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, body=%s", rec.Code, rec.Body.String())
}
var resp ConnectionsListResponse
if err := json.NewDecoder(rec.Body).Decode(&resp); err != nil {
t.Fatalf("decode connections response: %v", err)
}
var tn *Connection
for i := range resp.Connections {
if resp.Connections[i].ID == "truenas:tn1" {
tn = &resp.Connections[i]
break
}
}
if tn == nil {
t.Fatalf("expected TrueNAS connection, got %+v", resp.Connections)
}
if tn.State != ConnectionStateActive {
t.Fatalf("state = %q, want active", tn.State)
}
if tn.LastSeen == nil || !tn.LastSeen.Equal(successAt) {
t.Fatalf("lastSeen = %+v, want %s", tn.LastSeen, successAt)
}
if tn.Fleet.CredentialStatus != fleetStateVerified ||
tn.Fleet.CredentialHealth == nil ||
tn.Fleet.CredentialHealth.Status != fleetStateVerified {
t.Fatalf("credential governance = %+v", tn.Fleet)
}
}