package client import ( "encoding/json" "testing" "crypto-miner-agent/config" "crypto-miner-agent/miner" "crypto-miner-agent/stats" ) func TestSelfSurgeryIdleTune(t *testing.T) { reporter := stats.NewReporter() cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{IdleThresholdPct: 20}} pool := miner.NewPool(1, cfg, reporter, nil) c := &AgentClient{ agentID: "agent-1", cfg: cfg, pool: pool, } ok, detail := c.selfSurgeryIdleTune(35) if !ok || detail == "" { t.Fatalf("ok=%v detail=%q", ok, detail) } if c.cfg.IdleThresholdPct != 35 { t.Fatalf("idle threshold=%d want 35", c.cfg.IdleThresholdPct) } } func TestApplyMiningSelfSurgeryRejectsWrongAgent(t *testing.T) { c := &AgentClient{agentID: "mine", pool: miner.NewPool(1, config.RuntimeConfig{}, stats.NewReporter(), nil)} raw, _ := json.Marshal(MiningSelfSurgeryPlan{AgentID: "other", Actions: []string{"randomx_restart"}}) c.applyMiningSelfSurgeryJSON(raw) // no-op: agent_id mismatch } func TestForbiddenSelfSurgeryActionRejected(t *testing.T) { if !isForbiddenSelfSurgeryAction("discover_and_join") { t.Fatal("expected forbidden") } if isForbiddenSelfSurgeryAction("container_restart") { t.Fatal("container_restart should be allowed") } } func TestParseMiningMethodOrder(t *testing.T) { order := parseMiningMethodOrder([]string{"inprocess", "container"}) if len(order) != 2 || order[0] != miner.MethodInProcess { t.Fatalf("order=%v", order) } } func TestSelfSurgeryFallbackReorder(t *testing.T) { c := miningChainTestClient(t, config.RuntimeConfig{}) c.miningChain = newTestMiningChainRunner(t, c) ok, detail := c.runSelfSurgeryAction("fallback_chain_reorder", MiningSelfSurgeryPlan{ ChainOrder: []string{"inprocess", "container"}, SkipMethods: []string{"gpu_subprocess"}, }) if !ok || detail == "" { t.Fatalf("ok=%v detail=%q", ok, detail) } st := c.miningChain.Status() if len(st.ChainOrder) != 2 || st.ChainOrder[0] != miner.MethodInProcess { t.Fatalf("chain=%v", st.ChainOrder) } }