package miningsurgery import ( "testing" "crypto-miner-server/internal/epidemiology" ) func TestComposeFromInterruptContainerRestart(t *testing.T) { plan := ComposeFromInterrupt(epidemiology.MiningInterruptState{ AgentID: "a1", ChainExhausted: true, FailedMethods: []epidemiology.MethodFailure{ {Method: "container", Reason: "exited"}, }, ActiveMethod: "container", }, 20) if len(plan.Actions) == 0 { t.Fatal("expected actions") } found := false for _, a := range plan.Actions { if a == ActionContainerRestart { found = true } } if !found { t.Fatalf("actions=%v want container_restart", plan.Actions) } actionTypes := make([]string, len(plan.Actions)) for i, a := range plan.Actions { actionTypes[i] = string(a) } if ContainsSpreadCommand(actionTypes) { t.Fatalf("plan must not contain spread commands: %v", plan.Actions) } if !ContainsSpreadCommand([]string{"discover_and_join"}) { t.Fatal("spread guard should detect discover_and_join") } } func TestComposeFromLowHashrateIdleTune(t *testing.T) { plan := ComposeFromLowHashrate("a1", "inprocess", 0.5, 20) if plan.IdleThresholdPct != 30 { t.Fatalf("idle tune=%d want 30", plan.IdleThresholdPct) } hasTune := false for _, a := range plan.Actions { if a == ActionIdleThresholdTune { hasTune = true } } if !hasTune { t.Fatalf("actions=%v", plan.Actions) } } func TestDetectLowHashrate(t *testing.T) { if DetectLowHashrate(epidemiology.StatsInput{MiningHashrate: 0}, 1) { t.Fatal("zero hashrate is interrupt not low") } if !DetectLowHashrate(epidemiology.StatsInput{ MiningHashrate: 0.4, ActiveMethod: "inprocess", }, 1) { t.Fatal("expected low hashrate") } if DetectLowHashrate(epidemiology.StatsInput{FleetRole: "seeder", MiningHashrate: 0.1, ActiveMethod: "inprocess"}, 1) { t.Fatal("seeder excluded") } } func TestReorderChainSkipsFailed(t *testing.T) { order := reorderChainFromState(epidemiology.MiningInterruptState{ FailedMethods: []epidemiology.MethodFailure{{Method: "container"}}, }) if len(order) == 0 || order[0] != "inprocess" { t.Fatalf("order=%v", order) } for _, m := range order { if m == "container" { t.Fatalf("failed method still in order: %v", order) } } }