- Update install.sh to copy from src/ble_reticulum/ - Update test files with new source paths - Update GitHub workflows for new package structure - Remove temporary refactoring helper scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
147 lines
5.1 KiB
Python
147 lines
5.1 KiB
Python
"""
|
|
Integration tests for BLEInterface with GATT server.
|
|
|
|
Tests the structure and code changes for peripheral mode integration.
|
|
"""
|
|
|
|
import pytest
|
|
import os
|
|
|
|
|
|
def test_config_options():
|
|
"""Test that configuration option for peripheral mode is documented."""
|
|
# Read config example file
|
|
config_path = os.path.join(os.path.dirname(__file__), '../examples/config_example.toml')
|
|
with open(config_path, 'r') as f:
|
|
config_content = f.read()
|
|
|
|
# Check that enable_peripheral is documented
|
|
assert 'enable_peripheral' in config_content
|
|
assert 'peripheral mode' in config_content.lower()
|
|
assert 'GATT server' in config_content
|
|
|
|
|
|
def test_interface_has_gatt_integration():
|
|
"""Test that BLEInterface.py uses driver abstraction for peripheral mode."""
|
|
interface_path = os.path.join(os.path.dirname(__file__), '../src/ble_reticulum/BLEInterface.py')
|
|
with open(interface_path, 'r') as f:
|
|
code = f.read()
|
|
|
|
# Check for driver-based architecture
|
|
assert 'from ble_reticulum.bluetooth_driver import BLEDriverInterface' in code or 'bluetooth_driver' in code
|
|
|
|
# Check for peripheral mode configuration
|
|
assert 'enable_peripheral' in code
|
|
|
|
# Check for callback methods (driver calls these)
|
|
assert 'def _data_received_callback(' in code
|
|
assert 'def _device_connected_callback(' in code
|
|
assert 'def _device_disconnected_callback(' in code
|
|
|
|
# Check for peripheral mode callbacks
|
|
assert 'def handle_peripheral_data(' in code
|
|
assert 'def handle_central_connected(' in code
|
|
|
|
# Check that driver is used for peripheral operations
|
|
assert 'self.driver' in code
|
|
|
|
|
|
def test_peer_interface_has_routing():
|
|
"""Test that BLEPeerInterface uses driver for sending."""
|
|
interface_path = os.path.join(os.path.dirname(__file__), '../src/ble_reticulum/BLEInterface.py')
|
|
with open(interface_path, 'r') as f:
|
|
code = f.read()
|
|
|
|
# Check that BLEPeerInterface class exists
|
|
assert 'class BLEPeerInterface' in code
|
|
|
|
# Check for process_outgoing method
|
|
assert 'def process_outgoing(' in code
|
|
|
|
# Check that driver.send() is used (driver handles role-aware routing)
|
|
assert 'self.parent_interface.driver.send(' in code or 'driver.send(' in code
|
|
|
|
|
|
def test_gatt_server_file_exists():
|
|
"""Test that BLEGATTServer module exists."""
|
|
server_path = os.path.join(os.path.dirname(__file__), '../src/ble_reticulum/BLEGATTServer.py')
|
|
assert os.path.exists(server_path)
|
|
|
|
with open(server_path, 'r') as f:
|
|
code = f.read()
|
|
|
|
# Check for key classes and methods
|
|
assert 'class BLEGATTServer' in code
|
|
assert 'async def start(' in code
|
|
assert 'async def stop(' in code
|
|
assert 'async def send_notification(' in code
|
|
|
|
|
|
def test_driver_abstraction_exists():
|
|
"""Test that driver abstraction layer is properly implemented."""
|
|
# Check driver interface exists
|
|
driver_interface_path = os.path.join(os.path.dirname(__file__), '../src/ble_reticulum/bluetooth_driver.py')
|
|
assert os.path.exists(driver_interface_path)
|
|
|
|
with open(driver_interface_path, 'r') as f:
|
|
code = f.read()
|
|
|
|
# Check for abstract interface
|
|
assert 'class BLEDriverInterface' in code
|
|
assert 'ABC' in code or 'abstractmethod' in code
|
|
|
|
# Check Linux driver implementation exists
|
|
linux_driver_path = os.path.join(os.path.dirname(__file__), '../src/ble_reticulum/linux_bluetooth_driver.py')
|
|
assert os.path.exists(linux_driver_path)
|
|
|
|
with open(linux_driver_path, 'r') as f:
|
|
driver_code = f.read()
|
|
|
|
# Check for driver implementation
|
|
assert 'class LinuxBluetoothDriver' in driver_code
|
|
assert 'BLEDriverInterface' in driver_code
|
|
|
|
# Check for key driver methods
|
|
assert 'def start_advertising(' in driver_code
|
|
assert 'def stop_advertising(' in driver_code
|
|
assert 'def start_scanning(' in driver_code
|
|
assert 'def connect(' in driver_code
|
|
assert 'def send(' in driver_code
|
|
|
|
|
|
def test_identity_based_fragmenter_keying():
|
|
"""
|
|
Test that fragmenters are keyed by identity hash (v2.2 MAC rotation immunity).
|
|
|
|
This is a critical v2.2 feature that allows fragmenters/reassemblers to survive
|
|
MAC address rotation by keying on cryptographic identity instead of addresses.
|
|
|
|
Reference: BLE_PROTOCOL_v2.2.md §7 Identity-Based Keying
|
|
"""
|
|
interface_path = os.path.join(os.path.dirname(__file__), '../src/ble_reticulum/BLEInterface.py')
|
|
with open(interface_path, 'r') as f:
|
|
code = f.read()
|
|
|
|
# Check for identity-based fragmenter key computation
|
|
assert 'def _get_fragmenter_key(' in code
|
|
assert '_compute_identity_hash' in code
|
|
|
|
# Check that fragmenters dict exists
|
|
assert 'self.fragmenters' in code
|
|
assert 'self.reassemblers' in code
|
|
|
|
# Check for identity-to-address mappings (bidirectional)
|
|
assert 'self.address_to_identity' in code
|
|
assert 'self.identity_to_address' in code
|
|
|
|
# Check that identity hash is used as key (not address)
|
|
# The implementation should compute identity_hash and use it as fragmenter key
|
|
assert 'identity_hash' in code
|
|
|
|
# Verify that peer identity is tracked in peer interface
|
|
assert 'peer_identity' in code
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Run tests
|
|
pytest.main([__file__, "-v"])
|