149 lines
4.6 KiB
Python
149 lines
4.6 KiB
Python
"""Tests for dashboard store."""
|
|
import threading
|
|
|
|
import pytest
|
|
|
|
from ayn_antivirus.dashboard.store import DashboardStore
|
|
|
|
|
|
@pytest.fixture
|
|
def store(tmp_path):
|
|
s = DashboardStore(str(tmp_path / "test_dashboard.db"))
|
|
yield s
|
|
s.close()
|
|
|
|
|
|
def test_record_and_get_metrics(store):
|
|
store.record_metric(
|
|
cpu=50.0, mem_pct=60.0, mem_used=4000, mem_total=8000,
|
|
disk_usage=[{"mount": "/", "percent": 50}],
|
|
load_avg=[1.0, 0.5, 0.3], net_conns=10,
|
|
)
|
|
latest = store.get_latest_metrics()
|
|
assert latest is not None
|
|
assert latest["cpu_percent"] == 50.0
|
|
assert latest["mem_percent"] == 60.0
|
|
assert latest["disk_usage"] == [{"mount": "/", "percent": 50}]
|
|
assert latest["load_avg"] == [1.0, 0.5, 0.3]
|
|
|
|
|
|
def test_record_and_get_threats(store):
|
|
store.record_threat(
|
|
"/tmp/evil", "TestVirus", "malware", "HIGH",
|
|
"test_det", "abc", "quarantined", "test detail",
|
|
)
|
|
threats = store.get_recent_threats(10)
|
|
assert len(threats) == 1
|
|
assert threats[0]["threat_name"] == "TestVirus"
|
|
assert threats[0]["action_taken"] == "quarantined"
|
|
|
|
|
|
def test_threat_stats(store):
|
|
store.record_threat("/a", "V1", "malware", "CRITICAL", "d", "", "detected", "")
|
|
store.record_threat("/b", "V2", "miner", "HIGH", "d", "", "killed", "")
|
|
store.record_threat("/c", "V3", "spyware", "MEDIUM", "d", "", "detected", "")
|
|
stats = store.get_threat_stats()
|
|
assert stats["total"] == 3
|
|
assert stats["by_severity"]["CRITICAL"] == 1
|
|
assert stats["by_severity"]["HIGH"] == 1
|
|
assert stats["by_severity"]["MEDIUM"] == 1
|
|
assert stats["last_24h"] == 3
|
|
assert stats["last_7d"] == 3
|
|
|
|
|
|
def test_record_and_get_scans(store):
|
|
store.record_scan("full", "/", 1000, 50, 2, 10.5)
|
|
scans = store.get_recent_scans(10)
|
|
assert len(scans) == 1
|
|
assert scans[0]["files_scanned"] == 1000
|
|
assert scans[0]["scan_type"] == "full"
|
|
assert scans[0]["status"] == "completed"
|
|
|
|
|
|
def test_scan_chart_data(store):
|
|
store.record_scan("full", "/", 100, 5, 1, 5.0)
|
|
data = store.get_scan_chart_data(30)
|
|
assert len(data) >= 1
|
|
row = data[0]
|
|
assert "day" in row
|
|
assert "scans" in row
|
|
assert "threats" in row
|
|
|
|
|
|
def test_sig_updates(store):
|
|
store.record_sig_update("malwarebazaar", hashes=100, ips=50, domains=20, urls=10)
|
|
updates = store.get_recent_sig_updates(10)
|
|
assert len(updates) == 1
|
|
assert updates[0]["feed_name"] == "malwarebazaar"
|
|
stats = store.get_sig_stats()
|
|
assert stats["total_hashes"] == 100
|
|
assert stats["total_ips"] == 50
|
|
assert stats["total_domains"] == 20
|
|
assert stats["total_urls"] == 10
|
|
|
|
|
|
def test_activity_log(store):
|
|
store.log_activity("Test message", "INFO", "test")
|
|
logs = store.get_recent_logs(10)
|
|
assert len(logs) == 1
|
|
assert logs[0]["message"] == "Test message"
|
|
assert logs[0]["level"] == "INFO"
|
|
assert logs[0]["source"] == "test"
|
|
|
|
|
|
def test_metrics_history(store):
|
|
store.record_metric(
|
|
cpu=10, mem_pct=20, mem_used=1000, mem_total=8000,
|
|
disk_usage=[], load_avg=[0.1], net_conns=5,
|
|
)
|
|
store.record_metric(
|
|
cpu=20, mem_pct=30, mem_used=2000, mem_total=8000,
|
|
disk_usage=[], load_avg=[0.2], net_conns=10,
|
|
)
|
|
history = store.get_metrics_history(hours=1)
|
|
assert len(history) == 2
|
|
assert history[0]["cpu_percent"] == 10
|
|
assert history[1]["cpu_percent"] == 20
|
|
|
|
|
|
def test_cleanup_retains_fresh(store):
|
|
"""Cleanup with 0 hours should not delete just-inserted metrics."""
|
|
store.record_metric(
|
|
cpu=10, mem_pct=20, mem_used=1000, mem_total=8000,
|
|
disk_usage=[], load_avg=[], net_conns=0,
|
|
)
|
|
store.cleanup_old_metrics(hours=0)
|
|
assert store.get_latest_metrics() is not None
|
|
|
|
|
|
def test_empty_store_returns_none(store):
|
|
"""Empty store returns None / empty lists gracefully."""
|
|
assert store.get_latest_metrics() is None
|
|
assert store.get_recent_threats(10) == []
|
|
assert store.get_recent_scans(10) == []
|
|
assert store.get_recent_logs(10) == []
|
|
stats = store.get_threat_stats()
|
|
assert stats["total"] == 0
|
|
|
|
|
|
def test_thread_safety(store):
|
|
"""Concurrent writes from multiple threads should not crash."""
|
|
errors = []
|
|
|
|
def writer(n):
|
|
try:
|
|
for i in range(10):
|
|
store.record_metric(
|
|
cpu=float(n * 10 + i), mem_pct=50, mem_used=4000,
|
|
mem_total=8000, disk_usage=[], load_avg=[], net_conns=0,
|
|
)
|
|
except Exception as e:
|
|
errors.append(e)
|
|
|
|
threads = [threading.Thread(target=writer, args=(i,)) for i in range(5)]
|
|
for t in threads:
|
|
t.start()
|
|
for t in threads:
|
|
t.join()
|
|
assert len(errors) == 0
|