"""Tests for modules/stealth/ — Stealth module import and structure validation.""" import inspect import importlib import os import sys from unittest.mock import MagicMock, patch import pytest from modules.base import BaseModule # All stealth modules defined in modules/stealth/__init__.py STEALTH_MODULE_NAMES = [ "MacManager", "ProcessDisguise", "LogSuppression", "EncryptedStorage", "TmpfsManager", "Watchdog", "AntiForensics", "TrafficMimicry", "JA3Spoofer", "IDSTester", "LKMRootkit", "OverlayfsManager", ] STEALTH_MODULE_DOTTED = [ "modules.stealth.mac_manager", "modules.stealth.process_disguise", "modules.stealth.log_suppression", "modules.stealth.encrypted_storage", "modules.stealth.tmpfs_manager", "modules.stealth.watchdog", "modules.stealth.anti_forensics", "modules.stealth.traffic_mimicry", "modules.stealth.ja3_spoofer", "modules.stealth.ids_tester", "modules.stealth.lkm_rootkit", "modules.stealth.overlayfs_manager", ] class TestStealthModulesImportable: @pytest.mark.parametrize("dotted_path", STEALTH_MODULE_DOTTED) def test_all_stealth_modules_importable(self, dotted_path): """Each stealth module file can be imported without errors.""" mod = importlib.import_module(dotted_path) assert mod is not None class TestStealthModulesAreBaseModule: @pytest.mark.parametrize("class_name", STEALTH_MODULE_NAMES) def test_stealth_modules_are_base_module(self, class_name): """Each stealth module class is a subclass of BaseModule.""" import modules.stealth as stealth_pkg cls = getattr(stealth_pkg, class_name) assert issubclass(cls, BaseModule), f"{class_name} is not a BaseModule subclass" class TestStealthModuleAttributes: @pytest.mark.parametrize("class_name", STEALTH_MODULE_NAMES) def test_stealth_module_attributes(self, class_name): """Each stealth module has required class attributes: name, module_type, priority.""" import modules.stealth as stealth_pkg cls = getattr(stealth_pkg, class_name) assert hasattr(cls, "name"), f"{class_name} missing 'name'" assert hasattr(cls, "module_type"), f"{class_name} missing 'module_type'" assert hasattr(cls, "priority"), f"{class_name} missing 'priority'" assert hasattr(cls, "dependencies"), f"{class_name} missing 'dependencies'" assert hasattr(cls, "requires_root"), f"{class_name} missing 'requires_root'" # name should not be 'unnamed' (BaseModule default) assert cls.name != "unnamed", f"{class_name} still has default name 'unnamed'" # module_type should be 'stealth' assert cls.module_type == "stealth", f"{class_name} module_type is '{cls.module_type}', expected 'stealth'" # priority should be an integer assert isinstance(cls.priority, int), f"{class_name} priority is not an int" # dependencies should be a list assert isinstance(cls.dependencies, list), f"{class_name} dependencies is not a list" # Check abstract methods are implemented for method_name in ("start", "stop", "status", "configure"): method = getattr(cls, method_name, None) assert method is not None, f"{class_name} missing method '{method_name}'" assert callable(method), f"{class_name}.{method_name} is not callable" class TestStealthModuleInstantiate: @pytest.mark.parametrize("class_name", STEALTH_MODULE_NAMES) def test_stealth_module_instantiate(self, class_name, mock_bus, mock_state, mock_config): """Each stealth module can be instantiated with mock bus/state/config.""" import modules.stealth as stealth_pkg cls = getattr(stealth_pkg, class_name) # Instantiate (should not crash) instance = cls(bus=mock_bus, state=mock_state, config=mock_config) assert instance is not None assert instance.bus is mock_bus assert instance.state is mock_state assert instance.config is mock_config assert instance._running is False