Source code for TrigDroid_Infrastructure.interfaces

"""Core interfaces for TrigDroid following SOLID principles.

This module defines the core abstractions that enable dependency inversion
and make the system more maintainable and testable.
"""

from abc import ABC, abstractmethod
from typing import Protocol, TypeVar, Generic, Any, Dict, List, Optional, Union
from enum import Enum

# Type definitions
T = TypeVar('T')
ConfigValue = Union[str, int, bool, List[str], None]


[docs] class LogLevel(Enum): """Logging levels for the application.""" DEBUG = "DEBUG" INFO = "INFO" WARNING = "WARNING" ERROR = "ERROR" CRITICAL = "CRITICAL"
[docs] class TestResult(Enum): """Result of test execution.""" SUCCESS = "SUCCESS" FAILURE = "FAILURE" SKIPPED = "SKIPPED"
[docs] class DeviceConnectionState(Enum): """Android device connection states.""" CONNECTED = "CONNECTED" DISCONNECTED = "DISCONNECTED" UNAUTHORIZED = "UNAUTHORIZED"
# Core Interfaces
[docs] class ILogger(Protocol): """Logger interface for dependency inversion."""
[docs] def debug(self, message: str, *args: Any) -> None: ...
[docs] def info(self, message: str, *args: Any) -> None: ...
[docs] def warning(self, message: str, *args: Any) -> None: ...
[docs] def error(self, message: str, *args: Any) -> None: ...
[docs] def critical(self, message: str, *args: Any) -> None: ...
[docs] class IConfigurationProvider(Protocol): """Configuration provider interface."""
[docs] def get_value(self, key: str) -> ConfigValue: ...
[docs] def set_value(self, key: str, value: ConfigValue) -> None: ...
[docs] def has_key(self, key: str) -> bool: ...
[docs] def validate(self) -> bool: ...
[docs] class IConfigurationValidator(Protocol): """Configuration validation interface."""
[docs] def validate_config(self, config: Dict[str, ConfigValue]) -> List[str]: ...
[docs] def is_valid(self, key: str, value: ConfigValue) -> bool: ...
[docs] class IAndroidDevice(Protocol): """Android device interface."""
[docs] def execute_command(self, command: str) -> 'ICommandResult': ...
[docs] def install_app(self, apk_path: str) -> bool: ...
[docs] def uninstall_app(self, package_name: str) -> bool: ...
[docs] def start_app(self, package_name: str) -> bool: ...
[docs] def stop_app(self, package_name: str) -> bool: ...
[docs] def is_app_installed(self, package_name: str) -> bool: ...
[docs] def get_device_info(self) -> Dict[str, str]: ...
[docs] class ICommandResult(Protocol): """Command execution result interface.""" @property def return_code(self) -> int: ... @property def stdout(self) -> bytes: ... @property def stderr(self) -> bytes: ... @property def success(self) -> bool: ...
[docs] class ITestRunner(Protocol): """Test runner interface for different test types."""
[docs] def can_run(self, test_type: str) -> bool: ...
[docs] def execute(self, context: 'ITestContext') -> TestResult: ...
[docs] def setup(self) -> bool: ...
[docs] def teardown(self) -> bool: ...
[docs] class ITestContext(Protocol): """Test execution context interface.""" @property def device(self) -> IAndroidDevice: ... @property def config(self) -> IConfigurationProvider: ... @property def logger(self) -> ILogger: ... @property def package_name(self) -> str: ...
[docs] class IFridaHookProvider(Protocol): """Frida hook provider interface."""
[docs] def get_hook_script(self) -> str: ...
[docs] def get_hook_config(self) -> Dict[str, Any]: ...
[docs] def supports_hook(self, hook_name: str) -> bool: ...
[docs] class IChangelogWriter(Protocol): """Changelog writer interface."""
[docs] def write_entry(self, property_name: str, old_value: str, new_value: str, description: str = "") -> None: ...
[docs] def flush(self) -> None: ...
[docs] class IApplicationOrchestrator(Protocol): """Main application orchestrator interface."""
[docs] def setup(self) -> bool: ...
[docs] def execute_tests(self) -> bool: ...
[docs] def teardown(self) -> bool: ...
# Abstract Base Classes
[docs] class TestRunnerBase(ABC): """Base class for test runners implementing common functionality."""
[docs] def __init__(self, logger: ILogger): self._logger = logger self._is_setup = False
[docs] @abstractmethod def can_run(self, test_type: str) -> bool: """Check if this runner can handle the given test type.""" pass
@abstractmethod def _execute_internal(self, context: ITestContext) -> TestResult: """Internal execution logic to be implemented by subclasses.""" pass
[docs] def execute(self, context: ITestContext) -> TestResult: """Execute the test with proper error handling.""" try: if not self._is_setup: if not self.setup(): return TestResult.FAILURE return self._execute_internal(context) except Exception as e: self._logger.error(f"Test execution failed: {e}") return TestResult.FAILURE
[docs] def setup(self) -> bool: """Setup the test runner.""" self._is_setup = True return True
[docs] def teardown(self) -> bool: """Cleanup after test execution.""" self._is_setup = False return True
[docs] class ConfigurationProviderBase(ABC): """Base class for configuration providers."""
[docs] def __init__(self, logger: ILogger): self._logger = logger self._config: Dict[str, ConfigValue] = {}
@abstractmethod def _load_configuration(self) -> Dict[str, ConfigValue]: """Load configuration from the specific source.""" pass
[docs] def get_value(self, key: str) -> ConfigValue: """Get configuration value by key.""" if not self._config: self._config = self._load_configuration() return self._config.get(key)
[docs] def set_value(self, key: str, value: ConfigValue) -> None: """Set configuration value.""" self._config[key] = value
[docs] def has_key(self, key: str) -> bool: """Check if configuration key exists.""" if not self._config: self._config = self._load_configuration() return key in self._config