Organize codebase into hub, clients, and common packages with backward compatibility and comprehensive unit test suites
CI Test Suite / Run Component Tests & Pipeline Verification (push) Failing after 1m18s

This commit is contained in:
2026-10-02 23:14:55 +02:00
parent 9ebfadbe89
commit df9f5d191b
47 changed files with 10262 additions and 9068 deletions
+150
View File
@@ -0,0 +1,150 @@
"""
Comprehensive unit tests for LOGAR UpdateManager, AuthManager, and IngestQueue.
"""
import os
import sys
import time
import shutil
import tempfile
import unittest
from unittest.mock import MagicMock, patch
from src.hub.update_manager import ServerUpdateManager
from src.hub.auth_manager import PasswordManager, TOTPManager, SessionManager, RateLimiter
from src.hub.ingest_queue import IngestQueueManager
class TestHubUpdateAuthDeep(unittest.TestCase):
def setUp(self):
self.temp_dir = tempfile.mkdtemp()
self.update_dir = os.path.join(self.temp_dir, "updates")
self.db_path = os.path.join(self.temp_dir, "auth_test.db")
def tearDown(self):
shutil.rmtree(self.temp_dir, ignore_errors=True)
def test_update_manager_caching_and_manifest(self):
"""Tests package registration, SHA256 integrity, local caching, and download serving."""
manager = ServerUpdateManager(update_dir=self.update_dir, check_enabled=False)
# Create dummy binaries
win_bin = os.path.join(self.temp_dir, "Win_Client.exe")
linux_bin = os.path.join(self.temp_dir, "Linux_Client")
with open(win_bin, "wb") as f:
f.write(b"MZ_TEST_WIN_CLIENT_BINARY_2026")
with open(linux_bin, "wb") as f:
f.write(b"\x7fELF_TEST_LINUX_CLIENT_BINARY_2026")
# Register packages
res_win = manager.register_client_package(
os_type="windows",
file_path=win_bin,
version="2.5.0",
filename="Win_Client.exe"
)
self.assertEqual(res_win.get("version"), "2.5.0")
self.assertEqual(res_win.get("os"), "windows")
self.assertIsNotNone(res_win.get("sha256"))
res_linux = manager.register_client_package(
os_type="linux",
file_path=linux_bin,
version="2.5.0",
filename="Linux_Client"
)
self.assertEqual(res_linux.get("os"), "linux")
# Get hosted packages
packages = manager.get_hosted_packages()
self.assertIn("windows", packages)
self.assertIn("linux", packages)
self.assertEqual(packages["windows"]["version"], "2.5.0")
# Test download path resolution
pkg_res = manager.get_client_package_path(os_type="windows")
self.assertIsNotNone(pkg_res)
win_path, win_filename, win_sha = pkg_res
self.assertTrue(os.path.exists(win_path))
self.assertEqual(win_filename, "Win_Client.exe")
# Test update decision logic
decision = manager.check_client_update(client_id="node-win-01", current_version="1.0.0", os_type="windows")
self.assertTrue(decision.get("update_available"))
self.assertEqual(decision.get("latest_version"), "2.5.0")
decision_uptodate = manager.check_client_update(client_id="node-win-01", current_version="2.5.0", os_type="windows")
self.assertFalse(decision_uptodate.get("update_available"))
def test_auth_manager_components(self):
"""Tests PasswordManager, TOTPManager, SessionManager, and RateLimiter."""
# 1. PasswordManager
pwd = "Enterprise_Admin_Password_!2026"
pwd_hash, salt = PasswordManager.hash_password(pwd)
self.assertTrue(PasswordManager.verify_password(pwd, salt, pwd_hash))
self.assertFalse(PasswordManager.verify_password("WrongPassword", salt, pwd_hash))
# 2. TOTPManager
secret = TOTPManager.generate_totp_secret()
self.assertTrue(len(secret) >= 16)
uri = TOTPManager.get_totp_uri("admin", secret, "LOGAR Fleet Hub")
self.assertIn("otpauth://totp/", uri)
token = TOTPManager.get_totp_token(secret)
self.assertEqual(len(token), 6)
self.assertTrue(TOTPManager.verify_totp_code(secret, token))
self.assertFalse(TOTPManager.verify_totp_code(secret, "000000" if token != "000000" else "111111"))
# 3. SessionManager
session_token = SessionManager.generate_session_token("admin", db_path=self.db_path)
self.assertIsNotNone(session_token)
username = SessionManager.verify_session_token(session_token, db_path=self.db_path)
self.assertEqual(username, "admin")
self.assertIsNone(SessionManager.verify_session_token("invalid:token:format", db_path=self.db_path))
# 4. RateLimiter
limiter = RateLimiter()
ip = "192.168.1.100"
for _ in range(5):
self.assertTrue(limiter.check_ip_rate_limit(ip, max_attempts=5, window_seconds=60, db_path=self.db_path))
limiter.record_failed_ip_attempt(ip, db_path=self.db_path)
# 6th attempt exceeded
self.assertFalse(limiter.check_ip_rate_limit(ip, max_attempts=5, window_seconds=60, db_path=self.db_path))
# Reset
limiter.reset_failed_ip_attempts(ip, db_path=self.db_path)
self.assertTrue(limiter.check_ip_rate_limit(ip, max_attempts=5, window_seconds=60, db_path=self.db_path))
def test_ingest_queue_lifecycle_and_batching(self):
"""Tests IngestQueueManager push, stats, and flush callback."""
processed_items = []
def mock_processor(payload, db_path, window_hours, min_runs):
processed_items.extend(payload.get("logs", []))
return {"processed": len(payload.get("logs", [])), "promoted_verified": 0}
queue = IngestQueueManager(flush_interval=0.05, batch_size=10, max_queue=100)
# Enqueue items
for i in range(15):
pushed = queue.push({"server": "node1", "logs": [{"id": i, "data": f"log_{i}"}]})
self.assertTrue(pushed)
stats = queue.get_stats()
self.assertEqual(stats["queue_size"], 15)
self.assertEqual(stats["total_ingested"], 15)
# Flush
flush_res = queue.flush(db_path=self.db_path, process_callback=mock_processor)
self.assertEqual(flush_res["status"], "success")
self.assertEqual(flush_res["flushed_runs"], 15)
self.assertEqual(flush_res["processed_logs"], 15)
self.assertEqual(len(processed_items), 15)
stats_after = queue.get_stats()
self.assertEqual(stats_after["queue_size"], 0)
self.assertEqual(stats_after["total_flushed"], 15)
if __name__ == "__main__":
unittest.main()