feat: add network scanner module with nmap discovery, config merge, and ping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
70
backend/tests/test_network_scanner.py
Normal file
70
backend/tests/test_network_scanner.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
from modules.network_scanner import NetworkScanner
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def scanner():
|
||||
return NetworkScanner(subnet="192.168.1.0/24")
|
||||
|
||||
|
||||
def test_parse_scan_results(scanner):
|
||||
mock_scan_result = {
|
||||
"scan": {
|
||||
"192.168.1.1": {
|
||||
"status": {"state": "up"},
|
||||
"hostnames": [{"name": "router.local", "type": "PTR"}],
|
||||
"vendor": {"AA:BB:CC:DD:EE:FF": "Cisco"},
|
||||
},
|
||||
"192.168.1.10": {
|
||||
"status": {"state": "up"},
|
||||
"hostnames": [{"name": "", "type": ""}],
|
||||
"vendor": {},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
nodes = scanner.parse_scan_results(mock_scan_result)
|
||||
assert len(nodes) == 2
|
||||
assert nodes[0]["ip"] == "192.168.1.1"
|
||||
assert nodes[0]["hostname"] == "router.local"
|
||||
assert nodes[0]["status"] == "up"
|
||||
assert nodes[1]["ip"] == "192.168.1.10"
|
||||
|
||||
|
||||
def test_merge_with_config(scanner):
|
||||
discovered = [
|
||||
{"ip": "192.168.1.1", "hostname": "router.local", "status": "up", "vendor": "Cisco"},
|
||||
{"ip": "192.168.1.50", "hostname": "", "status": "up", "vendor": ""},
|
||||
]
|
||||
configured = [
|
||||
{
|
||||
"name": "Router Principal",
|
||||
"ip": "192.168.1.1",
|
||||
"username": "admin",
|
||||
"password": "pass",
|
||||
"icon": "router",
|
||||
"connections": [],
|
||||
},
|
||||
]
|
||||
|
||||
merged = scanner.merge_with_config(discovered, configured)
|
||||
# Router should have config data merged in
|
||||
router = next(n for n in merged if n["ip"] == "192.168.1.1")
|
||||
assert router["name"] == "Router Principal"
|
||||
assert router["username"] == "admin"
|
||||
assert router["status"] == "up"
|
||||
# Unknown device keeps discovered data
|
||||
unknown = next(n for n in merged if n["ip"] == "192.168.1.50")
|
||||
assert unknown["name"] == "192.168.1.50"
|
||||
assert unknown.get("username") is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ping_host(scanner):
|
||||
with patch("asyncio.create_subprocess_exec", new_callable=AsyncMock) as mock_exec:
|
||||
mock_proc = MagicMock()
|
||||
mock_proc.wait = AsyncMock(return_value=0)
|
||||
mock_exec.return_value = mock_proc
|
||||
result = await scanner.ping_host("192.168.1.1")
|
||||
assert result is True
|
||||
Reference in New Issue
Block a user