Add main CLI entry point and full test suite
- bigbrother.py: Click CLI with start/stop/status/activate/deactivate/ kill/config/selftest/modules commands plus Rich interactive menu. Module discovery scans modules/stealth/ for BaseModule subclasses. Supports --daemon mode with PID file and --passive-only flag. - tests/conftest.py: Shared fixtures (tmp_dir, mock_config, mock_bus, mock_state, hardware_tier_override, project_root) - tests/test_bus.py: 6 tests for EventBus pub/sub, filtering, wildcards - tests/test_engine.py: 5 tests for Engine lifecycle, deps, tier, phase - tests/test_crypto.py: 5 tests for AES-256-GCM, file encryption, KDF - tests/test_resource.py: 7 tests for hardware detection, memory, disk - tests/test_tool_manager.py: 6 tests for subprocess management - tests/test_stealth_modules.py: 4 parametrized test classes covering all 12 stealth modules (import, inheritance, attributes, instantiation)
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
"""Shared pytest fixtures for BigBrother tests."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Ensure project root is on sys.path
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
PROJECT_ROOT = str(Path(__file__).resolve().parent.parent)
|
||||
if PROJECT_ROOT not in sys.path:
|
||||
sys.path.insert(0, PROJECT_ROOT)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def project_root():
|
||||
"""Return the project root directory and ensure it is on sys.path."""
|
||||
return PROJECT_ROOT
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_dir(tmp_path):
|
||||
"""Provide a temporary directory for test artifacts."""
|
||||
return str(tmp_path)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config():
|
||||
"""Return a valid BigBrother config dict (no YAML file needed)."""
|
||||
return {
|
||||
"device": {
|
||||
"platform": "generic",
|
||||
"hostname": "test-device",
|
||||
"install_path": "/tmp/bb-test",
|
||||
},
|
||||
"network": {
|
||||
"primary_interface": "eth0",
|
||||
"scope_enforcement": False,
|
||||
},
|
||||
"connectivity": {
|
||||
"primary": "wireguard",
|
||||
},
|
||||
"security": {
|
||||
"encryption": "aes-256-gcm",
|
||||
"encryption_key_derive": "argon2id",
|
||||
"kill_switch_enabled": True,
|
||||
},
|
||||
"capture": {
|
||||
"interface": "eth0",
|
||||
"snap_length": 65535,
|
||||
"pcap_rotation_hours": 1,
|
||||
"pcap_compression": "zstd",
|
||||
"pcap_compression_level": 19,
|
||||
},
|
||||
"stealth": {
|
||||
"mac_profile": "auto",
|
||||
"process_disguise": True,
|
||||
"log_suppression": True,
|
||||
},
|
||||
"engagement_phase": {
|
||||
"mode": "passive_only",
|
||||
"passive_days": 7,
|
||||
},
|
||||
"bettercap": {
|
||||
"binary": "/usr/local/bin/bettercap",
|
||||
"api_address": "127.0.0.1",
|
||||
"api_port": 8083,
|
||||
},
|
||||
"storage_path": "/tmp/bb-test/storage",
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_bus():
|
||||
"""Return a started EventBus instance. Stopped after test."""
|
||||
from core.bus import EventBus
|
||||
|
||||
bus = EventBus()
|
||||
bus.start()
|
||||
yield bus
|
||||
bus.stop()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_state(tmp_path):
|
||||
"""Return a StateManager backed by a temp SQLite database. Stopped after test."""
|
||||
from core.state import StateManager
|
||||
|
||||
db_path = str(tmp_path / "test_state.db")
|
||||
state = StateManager(db_path=db_path)
|
||||
state.start()
|
||||
yield state
|
||||
state.stop()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hardware_tier_override():
|
||||
"""Context manager fixture to patch detect_hardware_tier to return a specific tier.
|
||||
|
||||
Usage:
|
||||
def test_foo(hardware_tier_override):
|
||||
with hardware_tier_override("pi_zero"):
|
||||
...
|
||||
"""
|
||||
from contextlib import contextmanager
|
||||
|
||||
@contextmanager
|
||||
def _override(tier: str):
|
||||
with patch("core.engine.detect_hardware_tier", return_value=tier):
|
||||
yield
|
||||
|
||||
return _override
|
||||
Reference in New Issue
Block a user