Make net_alerter alerts readable — fix hostname dedup and inline OUI lookup
- Replace broken OUI file lookup with inline dict of 200+ common vendors (works on Armbian) - Fix hostname/IP duplication when reverse DNS fails (show IP once, not twice) - Add format_arrival() and format_departure() helpers for consistent alert formatting - Update on_arrival/on_departure to use new formatting functions - Add comprehensive tests for hostname dedup and OUI lookup
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test suite for net_alerter.py — alert formatting fixes.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add parent dir to path so we can import net_alerter
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
import net_alerter
|
||||
|
||||
|
||||
def test_hostname_dedup_when_hostname_equals_ip():
|
||||
"""Test that hostname is not repeated when DNS fails (hostname == IP)."""
|
||||
# Simulate a device where hostname lookup returned the IP address itself
|
||||
mac = "88:a2:9e:8e:f2:90"
|
||||
ip = "10.0.0.0"
|
||||
hostname = ip # This is what happens when reverse DNS fails
|
||||
|
||||
# Format the alert using internal logic
|
||||
msg = net_alerter.format_arrival(hostname, ip, "Apple", mac)
|
||||
|
||||
# Should show IP only once
|
||||
assert msg == "[NET] ARRIVED: 10.0.0.0 [Apple] MAC:88:a2:9e:8e:f2:90"
|
||||
assert msg.count("10.0.0.0") == 1, "IP should appear exactly once"
|
||||
|
||||
|
||||
def test_hostname_shown_when_different_from_ip():
|
||||
"""Test that hostname is shown separately when it differs from IP."""
|
||||
mac = "88:a2:9e:8e:f2:90"
|
||||
ip = "10.0.0.0"
|
||||
hostname = "mydevice.local"
|
||||
|
||||
# Format the alert
|
||||
msg = net_alerter.format_arrival(hostname, ip, "Apple", mac)
|
||||
|
||||
# Should show both hostname and IP
|
||||
assert msg == "[NET] ARRIVED: mydevice.local (10.0.0.0) [Apple] MAC:88:a2:9e:8e:f2:90"
|
||||
assert "mydevice.local" in msg
|
||||
assert "10.0.0.0" in msg
|
||||
|
||||
|
||||
def test_oui_lookup_with_inline_dict():
|
||||
"""Test that OUI lookup returns vendor for known MACs."""
|
||||
# These are real OUI prefixes
|
||||
test_cases = [
|
||||
("88:a2:9e", "Apple"), # Apple
|
||||
("00:1a:7d", "Apple"), # Apple
|
||||
("18:5f:3f", "Apple"), # Apple
|
||||
("a4:c3:f0", "Apple"), # Apple
|
||||
("28:87:ba", "Google"), # Google
|
||||
("54:27:58", "Google"), # Google
|
||||
("34:15:13", "Amazon"), # Amazon
|
||||
("b8:27:eb", "Raspberry Pi"), # Raspberry Pi
|
||||
]
|
||||
|
||||
for mac_prefix, expected_vendor in test_cases:
|
||||
vendor = net_alerter.lookup_oui(mac_prefix + ":00:00:00")
|
||||
assert vendor == expected_vendor, f"Expected {expected_vendor} for {mac_prefix}, got {vendor}"
|
||||
|
||||
|
||||
def test_oui_lookup_unknown_vendor():
|
||||
"""Test that unknown OUI returns 'unknown'."""
|
||||
vendor = net_alerter.lookup_oui("aa:bb:cc:dd:ee:ff")
|
||||
assert vendor == "unknown", f"Expected 'unknown' for unknown OUI, got {vendor}"
|
||||
|
||||
|
||||
def test_departure_format_dedup():
|
||||
"""Test that departure message also deduplicates hostname and IP."""
|
||||
mac = "88:a2:9e:8e:f2:90"
|
||||
ip = "10.0.0.0"
|
||||
hostname = ip
|
||||
duration = "5m 30s"
|
||||
|
||||
msg = net_alerter.format_departure(hostname, ip, "Apple", mac, duration)
|
||||
assert msg == "[NET] DEPARTED: 10.0.0.0 [Apple] MAC:88:a2:9e:8e:f2:90 — present 5m 30s"
|
||||
assert msg.count("10.0.0.0") == 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_hostname_dedup_when_hostname_equals_ip()
|
||||
print("✓ test_hostname_dedup_when_hostname_equals_ip")
|
||||
|
||||
test_hostname_shown_when_different_from_ip()
|
||||
print("✓ test_hostname_shown_when_different_from_ip")
|
||||
|
||||
test_oui_lookup_with_inline_dict()
|
||||
print("✓ test_oui_lookup_with_inline_dict")
|
||||
|
||||
test_oui_lookup_unknown_vendor()
|
||||
print("✓ test_oui_lookup_unknown_vendor")
|
||||
|
||||
test_departure_format_dedup()
|
||||
print("✓ test_departure_format_dedup")
|
||||
|
||||
print("\nAll tests passed!")
|
||||
Reference in New Issue
Block a user