first commit
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from librenet_scanner.actions import normalize_mac
|
||||
from librenet_scanner.comparison import compare_hosts
|
||||
from librenet_scanner.intelligence import canonical_service_name, enrich_host
|
||||
from librenet_scanner.models import Host, PortInfo
|
||||
from librenet_scanner.storage import HistoryStore
|
||||
|
||||
|
||||
class IntelligenceTests(unittest.TestCase):
|
||||
def test_canonical_proxmox_service(self):
|
||||
self.assertEqual(canonical_service_name(8006, "tcp", "wpl-analytics"), "Proxmox VE")
|
||||
|
||||
def test_proxmox_classification(self):
|
||||
host = Host("192.168.5.1", hostname="pve01.local", ports=[PortInfo(8006, service="wpl-analytics")])
|
||||
enrich_host(host)
|
||||
self.assertEqual(host.device_type, "Hyperviseur Proxmox")
|
||||
self.assertEqual(host.ports[0].service, "Proxmox VE")
|
||||
|
||||
def test_synology_classification(self):
|
||||
host = Host("192.168.5.11", hostname="syno.maison.bro", ports=[PortInfo(5001)])
|
||||
enrich_host(host)
|
||||
self.assertEqual(host.device_type, "NAS Synology")
|
||||
|
||||
def test_pbs_classification(self):
|
||||
host = Host("192.168.5.12", hostname="pbs01.local.raspot.in", ports=[PortInfo(8007, service="ajp13")])
|
||||
enrich_host(host)
|
||||
self.assertEqual(host.device_type, "Proxmox Backup Server")
|
||||
self.assertEqual(host.ports[0].service, "Proxmox Backup Server")
|
||||
|
||||
def test_wol_mac_normalization(self):
|
||||
self.assertEqual(normalize_mac("aa-bb-cc-dd-ee-ff"), "AA:BB:CC:DD:EE:FF")
|
||||
with self.assertRaises(ValueError):
|
||||
normalize_mac("not-a-mac")
|
||||
|
||||
|
||||
class ComparisonTests(unittest.TestCase):
|
||||
def test_new_modified_disappeared(self):
|
||||
previous = [
|
||||
Host("10.0.0.1", hostname="srv", ports=[PortInfo(22, service="SSH")]),
|
||||
Host("10.0.0.2", hostname="old"),
|
||||
]
|
||||
current = [
|
||||
Host("10.0.0.1", hostname="srv", ports=[PortInfo(22, service="SSH"), PortInfo(80, service="HTTP")]),
|
||||
Host("10.0.0.3", hostname="new"),
|
||||
]
|
||||
result = compare_hosts(current, previous)
|
||||
by_ip = {h.ip: h for h in result}
|
||||
self.assertEqual(by_ip["10.0.0.1"].change_status, "Modifié")
|
||||
self.assertIn("80/tcp", by_ip["10.0.0.1"].change_detail)
|
||||
self.assertEqual(by_ip["10.0.0.3"].change_status, "Nouveau")
|
||||
self.assertEqual(by_ip["10.0.0.2"].change_status, "Disparu")
|
||||
self.assertEqual(by_ip["10.0.0.2"].status, "down")
|
||||
|
||||
def test_ip_move_by_mac(self):
|
||||
previous = [Host("10.0.0.10", mac="AA:BB:CC:DD:EE:FF")]
|
||||
current = [Host("10.0.0.20", mac="AA:BB:CC:DD:EE:FF")]
|
||||
result = compare_hosts(current, previous)
|
||||
self.assertEqual(len(result), 1)
|
||||
self.assertEqual(result[0].change_status, "IP modifiée")
|
||||
self.assertEqual(result[0].previous_ip, "10.0.0.10")
|
||||
|
||||
def test_first_scan_is_reference(self):
|
||||
current = [Host("10.0.0.1")]
|
||||
result = compare_hosts(current, None)
|
||||
self.assertEqual(result[0].change_status, "")
|
||||
|
||||
|
||||
class StorageTests(unittest.TestCase):
|
||||
def test_history_roundtrip(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
store = HistoryStore(Path(tmp) / "history.sqlite3")
|
||||
host = Host(
|
||||
"192.168.1.2",
|
||||
hostname="pve01.local",
|
||||
mac="AA:BB:CC:DD:EE:01",
|
||||
ports=[PortInfo(22, service="SSH"), PortInfo(8006, service="Proxmox VE")],
|
||||
)
|
||||
scan_id = store.save_scan("192.168.1.0/24", "Standard", [host], "standard-test-v2")
|
||||
latest = store.latest_scan("192.168.1.0/24", "Standard", "standard-test-v2")
|
||||
self.assertIsNotNone(latest)
|
||||
self.assertEqual(int(latest["id"]), scan_id)
|
||||
loaded = store.load_scan_hosts(scan_id)
|
||||
self.assertEqual(len(loaded), 1)
|
||||
self.assertEqual(loaded[0].hostname, "pve01.local")
|
||||
self.assertEqual(loaded[0].device_type, "Hyperviseur Proxmox")
|
||||
|
||||
def test_v01_database_is_migrated_without_becoming_v02_baseline(self):
|
||||
import sqlite3
|
||||
from contextlib import closing
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
db = Path(tmp) / "history.sqlite3"
|
||||
with closing(sqlite3.connect(db)) as conn:
|
||||
conn.executescript(
|
||||
"""
|
||||
CREATE TABLE scans (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
created_at TEXT NOT NULL,
|
||||
target TEXT NOT NULL,
|
||||
profile TEXT NOT NULL,
|
||||
host_count INTEGER NOT NULL
|
||||
);
|
||||
CREATE TABLE scan_hosts (
|
||||
scan_id INTEGER NOT NULL,
|
||||
ip TEXT NOT NULL,
|
||||
hostname TEXT,
|
||||
mac TEXT,
|
||||
vendor TEXT,
|
||||
os_name TEXT,
|
||||
ports_json TEXT NOT NULL
|
||||
);
|
||||
INSERT INTO scans(created_at, target, profile, host_count)
|
||||
VALUES ('2026-08-21T12:00:00+02:00', '192.168.5.0/24', 'Standard', 1);
|
||||
INSERT INTO scan_hosts(scan_id, ip, hostname, mac, vendor, os_name, ports_json)
|
||||
VALUES (1, '192.168.5.1', 'pve01.local', '', '', '', '[]');
|
||||
"""
|
||||
)
|
||||
store = HistoryStore(db)
|
||||
self.assertIsNone(store.latest_scan("192.168.5.0/24", "Standard", "standard-v2:test"))
|
||||
self.assertEqual(len(store.recent_scans()), 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user