""" Test script to verify lazy proxy behavior for theGrifo1553. This script verifies that: 1. The proxy does NOT initialize hardware at import time 2. The proxy supports all operations used in production code 3. The mock can still replace sys.modules successfully Run this before and after changes to verify compatibility. Usage: # Test without hardware (should not fail on import) python test_lazy_proxy.py --check-import # Test that all operations are supported python test_lazy_proxy.py --check-api """ import sys import os # Add test environment paths (same as __init__.py) LIB_DIR = os.path.join(os.path.dirname(__file__), '..', 'env') sys.path.insert(0, LIB_DIR) sys.path.insert(0, os.path.join(LIB_DIR, 'site-packages')) def test_import_no_hardware(): """Verify that import does NOT require hardware.""" print("=" * 80) print("TEST 1: Import without hardware initialization") print("=" * 80) # Mock the interpreter module to prevent immediate hardware access import types import warnings warnings.filterwarnings('ignore') # Suppress warnings during test # Create minimal mock for interpreter mock_interpreter = types.ModuleType('interpreter') sys.modules['interpreter'] = mock_interpreter # Also mock potential missing stdlib modules for missing_mod in ['uu']: if missing_mod not in sys.modules: sys.modules[missing_mod] = types.ModuleType(missing_mod) # Import should succeed now try: # Clear any previous imports if 'leo_grifo_1553' in sys.modules: del sys.modules['leo_grifo_1553'] if 'leo_grifo_common' in sys.modules: del sys.modules['leo_grifo_common'] if 'leo_grifo_core' in sys.modules: del sys.modules['leo_grifo_core'] from leo_grifo_1553 import theGrifo1553 print("✓ Import successful - no hardware initialization triggered") print(f" theGrifo1553 type: {type(theGrifo1553).__name__}") print(f" theGrifo1553 repr: {repr(theGrifo1553)}") # Check that instance is not yet initialized if hasattr(theGrifo1553, '_instance'): if theGrifo1553._instance is None: print("✓ Proxy is lazy - real instance not yet created") print(" Hardware connection will be made only on first method call") success = True else: print("✗ WARNING: Real instance already created at import!") print(" This means hardware connection happens at import time!") print(" The lazy loading is NOT working correctly.") success = False else: print("✓ theGrifo1553 does not expose _instance (might be replaced by mock)") success = True # Clean up mocks for mod in ['interpreter', 'uu']: if mod in sys.modules: del sys.modules[mod] return success except ImportError as e: print(f"✗ FAIL: Import failed with: {e}") print("\n NOTE: Some dependencies are missing in this Python environment.") print(" This test cannot verify lazy loading without all dependencies.") print(" Run this test in the production environment with PlatformSimulator.") return False except Exception as e: print(f"✗ FAIL: Unexpected error: {e}") import traceback traceback.print_exc() return False def test_api_compatibility(): """Verify that proxy supports all operations used in production code.""" print("\n") print("=" * 80) print("TEST 2: API compatibility checks (no actual hardware calls)") print("=" * 80) try: from leo_grifo_1553 import theGrifo1553 # Check that key methods/attributes exist api_methods = ['check', 'get', 'set', 'getInterface', 'run'] print("\nChecking API methods availability (using dir()):") available = dir(theGrifo1553) missing = [] for method in api_methods: if method in available: print(f" ✓ {method} - available") else: print(f" ✗ {method} - MISSING") missing.append(method) if missing: print(f"\n✗ FAIL: Missing methods: {missing}") return False # Check hasattr (used by mock) print("\nChecking hasattr() support:") for method in api_methods: result = hasattr(theGrifo1553, method) if result: print(f" ✓ hasattr(theGrifo1553, '{method}') = True") else: print(f" ✗ hasattr(theGrifo1553, '{method}') = False") # Check truthiness print("\nChecking truthiness:") if theGrifo1553: print(" ✓ bool(theGrifo1553) = True") else: print(" ✗ bool(theGrifo1553) = False (unexpected)") # Check passability as parameter (type check) print("\nChecking usability as parameter:") def dummy_function(interface): """Dummy function that accepts interface parameter.""" return interface is not None result = dummy_function(theGrifo1553) if result: print(" ✓ Can be passed as parameter") else: print(" ✗ Cannot be passed as parameter") print("\n✓ All API compatibility checks passed") return True except Exception as e: print(f"\n✗ FAIL: API check failed with: {e}") import traceback traceback.print_exc() return False def test_mock_compatibility(): """Verify that mock can replace sys.modules successfully.""" print("\n") print("=" * 80) print("TEST 3: Mock replacement compatibility") print("=" * 80) try: import types # Simulate what the mock does print("\nSimulating mock module injection...") # Create fake mock module class FakeMockInterface: def __init__(self): self.is_mock = True def check(self, *args, **kwargs): return True, None, None def get(self, *args, **kwargs): return "mock_value", None def set(self, *args, **kwargs): return True, None def getInterface(self): return self def run(self, enable): pass # Replace sys.modules (like setup_simulation does) mock_leo_grifo_1553 = types.ModuleType('leo_grifo_1553') mock_leo_grifo_1553.theGrifo1553 = FakeMockInterface() original_module = sys.modules.get('leo_grifo_1553') sys.modules['leo_grifo_1553'] = mock_leo_grifo_1553 print(" ✓ Mock module injected into sys.modules") # Re-import should get mock from leo_grifo_1553 import theGrifo1553 print(f" theGrifo1553 type after mock: {type(theGrifo1553)}") # Check if it's the mock if hasattr(theGrifo1553, 'is_mock') and theGrifo1553.is_mock: print(" ✓ Re-import successfully retrieved mock object") else: print(" ✗ Re-import did NOT get mock (got original)") # Test mock methods work result = theGrifo1553.check("test") print(f" ✓ Mock method call successful: check() returned {result}") # Restore original module if original_module: sys.modules['leo_grifo_1553'] = original_module print(" ✓ Original module restored") print("\n✓ Mock compatibility test passed") return True except Exception as e: print(f"\n✗ FAIL: Mock compatibility test failed: {e}") import traceback traceback.print_exc() return False def main(): """Run all tests based on command line arguments.""" if len(sys.argv) < 2 or '--check-import' in sys.argv: success1 = test_import_no_hardware() if not success1: sys.exit(1) if len(sys.argv) < 2 or '--check-api' in sys.argv: success2 = test_api_compatibility() success3 = test_mock_compatibility() if not (success2 and success3): sys.exit(1) print("\n") print("=" * 80) print("ALL TESTS PASSED ✓") print("=" * 80) print("\nThe lazy proxy implementation:") print(" ✓ Does not initialize hardware at import time") print(" ✓ Supports all API methods used in production code") print(" ✓ Is compatible with mock module injection") print("\nYou can now safely run:") print(" - Production mode: python GRIFO_M_PBIT.py (on target reale)") print(" - Simulation mode: python GRIFO_M_PBIT.py --simulate") print() if __name__ == '__main__': main()