Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.
This commit is contained in:
130
agent/miner/execution_test.go
Normal file
130
agent/miner/execution_test.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"crypto-miner-agent/config"
|
||||
)
|
||||
|
||||
func TestResolveExecutionModeAutoWithDocker(t *testing.T) {
|
||||
SetRuntimeDetector(func() ContainerRuntimeInfo {
|
||||
return ContainerRuntimeInfo{Available: true, CLI: "docker", Version: "24.0.0"}
|
||||
})
|
||||
defer SetRuntimeDetector(nil)
|
||||
|
||||
mode, rt := ResolveExecutionMode(config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{MinerExecution: ExecutionAuto},
|
||||
})
|
||||
if mode != ExecutionContainer {
|
||||
t.Fatalf("got mode %q want container", mode)
|
||||
}
|
||||
if !rt.Available || rt.CLI != "docker" {
|
||||
t.Fatalf("runtime %+v", rt)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveExecutionModeAutoWithoutRuntime(t *testing.T) {
|
||||
SetRuntimeDetector(func() ContainerRuntimeInfo { return ContainerRuntimeInfo{} })
|
||||
defer SetRuntimeDetector(nil)
|
||||
|
||||
mode, _ := ResolveExecutionMode(config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{MinerExecution: ExecutionAuto},
|
||||
})
|
||||
if mode != ExecutionInProcess {
|
||||
t.Fatalf("got %q want inprocess", mode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveExecutionModeForcedContainer(t *testing.T) {
|
||||
SetRuntimeDetector(func() ContainerRuntimeInfo { return ContainerRuntimeInfo{} })
|
||||
defer SetRuntimeDetector(nil)
|
||||
|
||||
mode, _ := ResolveExecutionMode(config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{MinerExecution: ExecutionContainer},
|
||||
})
|
||||
if mode != ExecutionContainer {
|
||||
t.Fatalf("got %q want container", mode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveExecutionModeInProcess(t *testing.T) {
|
||||
SetRuntimeDetector(func() ContainerRuntimeInfo {
|
||||
return ContainerRuntimeInfo{Available: true, CLI: "docker"}
|
||||
})
|
||||
defer SetRuntimeDetector(nil)
|
||||
|
||||
mode, _ := ResolveExecutionMode(config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{MinerExecution: ExecutionInProcess},
|
||||
})
|
||||
if mode != ExecutionInProcess {
|
||||
t.Fatalf("got %q want inprocess", mode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveExecutionModeSubprocess(t *testing.T) {
|
||||
SetRuntimeDetector(func() ContainerRuntimeInfo { return ContainerRuntimeInfo{} })
|
||||
defer SetRuntimeDetector(nil)
|
||||
|
||||
mode, _ := ResolveExecutionMode(config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{MinerExecution: ExecutionSubprocess},
|
||||
})
|
||||
if mode != ExecutionSubprocess {
|
||||
t.Fatalf("got %q want subprocess", mode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerModeRequested(t *testing.T) {
|
||||
if !ContainerModeRequested(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{}}) {
|
||||
t.Fatal("empty should request auto/container")
|
||||
}
|
||||
if !ContainerModeRequested(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{MinerExecution: "auto"}}) {
|
||||
t.Fatal("auto should request container path")
|
||||
}
|
||||
if ContainerModeRequested(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{MinerExecution: "inprocess"}}) {
|
||||
t.Fatal("inprocess should not request container")
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveExecutionModePowerShell(t *testing.T) {
|
||||
mode, _ := ResolveExecutionMode(config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{MinerExecution: ExecutionPowerShell},
|
||||
})
|
||||
if mode != ExecutionPowerShell {
|
||||
t.Fatalf("got %q want powershell", mode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveExecutionModeDotnet(t *testing.T) {
|
||||
mode, _ := ResolveExecutionMode(config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{MinerExecution: ExecutionDotnet},
|
||||
})
|
||||
if mode != ExecutionDotnet {
|
||||
t.Fatalf("got %q want dotnet", mode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVBlockRecommendation(t *testing.T) {
|
||||
if msg := AVBlockRecommendation(ExecutionInProcess, ContainerRuntimeInfo{Available: true, CLI: "docker"}); msg == "" {
|
||||
t.Fatal("expected in-process guidance")
|
||||
}
|
||||
if msg := AVBlockRecommendation(ExecutionContainer, ContainerRuntimeInfo{Available: true, CLI: "docker"}); msg == "" {
|
||||
t.Fatal("expected container guidance")
|
||||
}
|
||||
if msg := AVBlockRecommendation(ExecutionAuto, ContainerRuntimeInfo{Available: true, CLI: "docker"}); msg == "" {
|
||||
t.Fatal("expected auto-mode guidance")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewContainerLauncherNoRuntime(t *testing.T) {
|
||||
_, err := NewContainerLauncher(config.RuntimeConfig{}, ContainerRuntimeInfo{})
|
||||
if err == nil {
|
||||
t.Fatal("expected error without runtime")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerNameSanitize(t *testing.T) {
|
||||
name := containerName(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{BuildID: "build/01 test"}})
|
||||
if name != "aetherforge-miner-build-01-test" {
|
||||
t.Fatalf("got %q", name)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user