package api import ( "encoding/json" "testing" "crypto-miner-server/internal/epidemiology" ) func TestMiningSelfSurgeryAuthOneShot(t *testing.T) { hub := NewWSHub(nil) hub.mu.Lock() hub.serverPolicy.AIControlEnabled = true hub.mu.Unlock() hub.WireDefaultMiningSurgeryReporter() hub.observeMiningSelfSurgeryFromStats("agent-surgery", epidemiology.StatsInput{ ChainExhausted: true, FailedMethods: []epidemiology.MethodFailure{ {Method: "container", Reason: "exited"}, }, }) resp := map[string]interface{}{} hub.attachMiningSelfSurgery(resp, "agent-surgery") if _, ok := resp["mining_self_surgery"]; !ok { t.Fatal("expected mining_self_surgery on auth pass") } raw, _ := json.Marshal(resp["mining_self_surgery"]) var plan struct { AgentID string `json:"agent_id"` Actions []string `json:"actions"` } if err := json.Unmarshal(raw, &plan); err != nil { t.Fatal(err) } if plan.AgentID != "agent-surgery" || len(plan.Actions) == 0 { t.Fatalf("plan=%+v", plan) } resp2 := map[string]interface{}{} hub.attachMiningSelfSurgery(resp2, "agent-surgery") if _, ok := resp2["mining_self_surgery"]; ok { t.Fatal("plan should be consumed after first auth pass") } } func TestMiningSelfSurgerySkippedWithoutAIControl(t *testing.T) { hub := NewWSHub(nil) hub.observeMiningSelfSurgeryFromStats("agent-off", epidemiology.StatsInput{ ChainExhausted: true, }) resp := map[string]interface{}{} hub.attachMiningSelfSurgery(resp, "agent-off") if _, ok := resp["mining_self_surgery"]; ok { t.Fatal("expected no plan when ai_control_enabled is false") } } func TestMiningSelfSurgeryLowHashrate(t *testing.T) { hub := NewWSHub(nil) hub.mu.Lock() hub.serverPolicy.AIControlEnabled = true hub.mu.Unlock() hub.observeMiningSelfSurgeryFromStats("agent-low", epidemiology.StatsInput{ MiningHashrate: 0.2, ActiveMethod: "inprocess", }) resp := map[string]interface{}{} hub.attachMiningSelfSurgery(resp, "agent-low") if _, ok := resp["mining_self_surgery"]; !ok { t.Fatal("expected low hashrate plan") } } func TestSelfSurgeryReportHandled(t *testing.T) { hub := NewWSHub(nil) hub.mu.Lock() hub.serverPolicy.AIControlEnabled = true hub.mu.Unlock() hub.WireDefaultMiningSurgeryReporter() hub.observeMiningSelfSurgeryFromStats("agent-report", epidemiology.StatsInput{ChainExhausted: true}) _, _ = hub.miningSurgery.ConsumePlan("agent-report") payload, _ := json.Marshal(map[string]interface{}{ "outcome": "ok", "results": []map[string]interface{}{{"action": "randomx_restart", "ok": true}}, }) hub.handleSelfSurgeryReport("agent-report", payload) }