Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Dashboard ambient layer, comrade presence, Mission Deck and War Room, Emberwake supply chain, spread/docs publishing, fleet policy and modules API, CI docker mining, and refreshed USB pack.
88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
func TestListModulesAPI(t *testing.T) {
|
|
store := NewModuleStore(t.TempDir(), func() string { return "list-secret" })
|
|
h := NewModuleHandler(store)
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/fleet/modules", nil)
|
|
rec := httptest.NewRecorder()
|
|
h.ListModules(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status %d: %s", rec.Code, rec.Body.String())
|
|
}
|
|
var mods []ModuleManifest
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &mods); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(mods) < 3 {
|
|
t.Fatalf("expected at least 3 default packs, got %d", len(mods))
|
|
}
|
|
names := map[string]ModuleManifest{}
|
|
for _, m := range mods {
|
|
names[m.Name] = m
|
|
}
|
|
for _, want := range []string{"crucible_ops", "spread", "gpu"} {
|
|
m, ok := names[want]
|
|
if !ok {
|
|
t.Fatalf("missing pack %q", want)
|
|
}
|
|
if m.DisplayName == "" || m.Summary == "" || len(m.Capabilities) == 0 {
|
|
t.Fatalf("pack %q missing UI metadata: %+v", want, m)
|
|
}
|
|
if len(m.Features) == 0 {
|
|
t.Fatalf("pack %q missing features", want)
|
|
}
|
|
if m.Signature == "" {
|
|
t.Fatalf("pack %q unsigned", want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetAgentModuleAPI(t *testing.T) {
|
|
store := NewModuleStore(t.TempDir(), func() string { return "agent-mod-secret" })
|
|
h := NewModuleHandler(store)
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/agent/module/gpu", nil)
|
|
rctx := chi.NewRouteContext()
|
|
rctx.URLParams.Add("name", "gpu")
|
|
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
|
|
rec := httptest.NewRecorder()
|
|
h.GetAgentModule(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status %d: %s", rec.Code, rec.Body.String())
|
|
}
|
|
var m ModuleManifest
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &m); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if m.Name != "gpu" || m.Features["gpu_enabled"] != true {
|
|
t.Fatalf("unexpected gpu manifest: %+v", m)
|
|
}
|
|
if !VerifyModuleSignature(m, "agent-mod-secret") {
|
|
t.Fatal("agent module signature invalid")
|
|
}
|
|
}
|
|
|
|
func TestVerifyModuleSignatureRejectsTamper(t *testing.T) {
|
|
store := NewModuleStore(t.TempDir(), func() string { return "tamper-secret" })
|
|
m, err := store.Get("crucible_ops")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !VerifyModuleSignature(m, "tamper-secret") {
|
|
t.Fatal("expected valid signature")
|
|
}
|
|
m.Features["auto_spread"] = true
|
|
if VerifyModuleSignature(m, "tamper-secret") {
|
|
t.Fatal("expected tampered manifest to fail verification")
|
|
}
|
|
}
|