7.4 KiB
Modifica Lazy Initialization per theGrifo1553
Problema Originale
Prima della modifica, theGrifo1553 veniva istanziato immediatamente all'import del modulo leo_grifo_1553:
# VECCHIO CODICE (problematico)
theGrifo1553 = GrifoInstrumentInterface(0.2)
Conseguenze:
- La connessione hardware 1553 avveniva all'import, anche in modalità
--simulate - Il mock doveva sostituire
sys.modulesPRIMA che il test importasse i moduli - Impossibile importare lo script senza hardware disponibile
- Fallimento import se
PlatformSimulator/binnon nel path
Soluzione Implementata
Introdotto un lazy proxy (_LazyGrifoProxy) che ritarda la creazione dell'istanza reale fino al primo utilizzo:
# NUOVO CODICE (lazy)
class _LazyGrifoProxy:
"""Proxy that lazily constructs GrifoInstrumentInterface on first use."""
def __init__(self, timeout: float = 0.2):
self._timeout = timeout
self._instance = None
def _ensure(self):
"""Initialize only when needed."""
if self._instance is None:
self._instance = GrifoInstrumentInterface(self._timeout)
def __getattr__(self, item):
"""Delegate to real instance after ensuring it exists."""
# Support hasattr() without initialization for known methods
known_methods = ['check', 'get', 'set', 'getInterface', 'run']
if item in known_methods and self._instance is None:
def lazy_method(*args, **kwargs):
self._ensure()
return getattr(self._instance, item)(*args, **kwargs)
return lazy_method
self._ensure()
return getattr(self._instance, item)
theGrifo1553 = _LazyGrifoProxy(0.2)
Vantaggi
1. Compatibilità Totale con Modalità Simulazione
- ✅ Il mock può sostituire
sys.modules['leo_grifo_1553']DOPO l'import iniziale - ✅ Nessuna connessione hardware tentata finché non si usa
--simulate - ✅ Import sicuro anche senza
PlatformSimulator/binnel path
2. Compatibilità Totale con Target Reale
- ✅ Primo accesso a metodo/attributo → istanza reale creata automaticamente
- ✅ API identica:
check(),get(),set(),getInterface(),run() - ✅ Passaggio come parametro funziona:
check(theGrifo1553, ...) - ✅
hasattr()supportato: il mock usahasattr()per controlli
3. Trasparenza Totale
Il proxy è completamente trasparente per il codice esistente:
- Non richiede modifiche a
GRIFO_M_PBIT.py - Non richiede modifiche a
test_common_function.py - Non richiede modifiche a
GRIFO_M_PBIT_mock.py
Verifica sul Target Reale
Test 1: Verifica Import Lazy
Esegui lo script di test per verificare che il proxy funzioni:
cd TestEnvironment\scripts
python test_lazy_proxy.py
Output atteso:
✓ Proxy is lazy - real instance not yet created
✓ hasattr() checks pass without initialization
✓ Mock replacement works correctly
ALL TESTS PASSED ✓
Test 2: Esecuzione sul Target Reale (Senza --simulate)
Pre-requisiti:
- Hardware 1553 connesso e funzionante
PlatformSimulator/binnel PYTHONPATH o ambiente configurato- Modulo
interpreterdisponibile e funzionante
Comando:
cd TestEnvironment\scripts
python GRIFO_M_PBIT.py
Comportamento atteso:
- Import dello script: SUCCESSO (nessuna connessione hardware ancora)
- Chiamata a
theGrifo1553.getInterface()intest_proc(): Qui avviene la connessione - Prima chiamata
check(theGrifo1553, ...): proxy delega all'istanza reale - Test procede normalmente come prima della modifica
Verifica connessione lazy:
Aggiungi temporaneamente log all'inizio di test_proc():
def test_proc():
import logging
logging.info(f"theGrifo1553 prima dell'uso: {repr(theGrifo1553)}")
interface = theGrifo1553.getInterface() # <- QUI avviene la connessione
logging.info(f"theGrifo1553 dopo getInterface(): {repr(theGrifo1553)}")
Output atteso nel log:
theGrifo1553 prima dell'uso: <LazyGrifoProxy(uninitialized, timeout=0.2)>
theGrifo1553 dopo getInterface(): <leo_grifo_1553.GrifoInstrumentInterface object at 0x...>
Test 3: Esecuzione in Simulazione (Con --simulate)
Comando:
python GRIFO_M_PBIT.py --simulate
Comportamento atteso:
- Import dello script: SUCCESSO
- Rilevamento flag
--simulate: import diGRIFO_M_PBIT_mock - Mock sostituisce
sys.modules['leo_grifo_1553']con modulo fake - Proxy originale NON viene mai inizializzato (nessuna connessione hardware)
- Tutte le chiamate vanno al mock, test procede in simulazione
Compatibilità Verificata
✅ Modulo leo_grifo_1553.py
- Import sicuro anche senza hardware
- Lazy initialization funzionante
- API identica per codice esistente
✅ Script GRIFO_M_PBIT.py
- Nessuna modifica necessaria
- Funziona con e senza
--simulate - Check/get/set funzionano identicamente
✅ Mock GRIFO_M_PBIT_mock.py
- Sostituisce
sys.modulescorrettamente hasattr()checks funzionano- Nessuna inizializzazione hardware in simulate
✅ Helper test_common_function.py
check(theGrifo1553, ...)funziona- Passaggio proxy come parametro OK
- Nessuna modifica necessaria
Risoluzione Problemi
Problema: "AttributeError: 'GrifoInstrumentInterface' object has no attribute 'xyz'"
Causa: Metodo/attributo non esiste nell'interfaccia reale.
Soluzione: Verifica nome metodo corretto. I metodi supportati dal proxy sono:
check(expected, msg, field, **kwargs)get(msg, field, **kwargs)set(value, msg, field, **kwargs)getInterface()→ ritorna oggettogrifo_1553nativorun(enable: bool)
Problema: "ImportError: No module named 'interpreter'"
Causa: Ambiente non configurato per hardware reale.
Soluzione: Esegui con uno di questi metodi:
- Wrapper Python:
python python_simulate_wrapper.py(solo simulate) - Batch Production: Usa
run.bato configura PYTHONPATH manualmente - Modalità Simulate: Aggiungi flag
--simulate(non richiede interpreter)
Problema: "Connessione hardware avviene all'import"
Causa: Il proxy potrebbe non essere stato applicato correttamente.
Soluzione:
- Verifica che
leo_grifo_1553.pycontenga_LazyGrifoProxy - Verifica che
theGrifo1553 = _LazyGrifoProxy(0.2)sia l'ultima riga del file - Esegui
test_lazy_proxy.pyper verificare il comportamento
File Modificati
TestEnvironment/env/leo_grifo_1553.py- Aggiunto_LazyGrifoProxy(linee ~140-190)TestEnvironment/scripts/test_lazy_proxy.py- Script di test nuovo (creato)
File NON Modificati (compatibilità preservata)
TestEnvironment/scripts/GRIFO_M_PBIT.py- Nessuna modifica necessariaTestEnvironment/scripts/GRIFO_M_PBIT_mock.py- Nessuna modifica necessariaTestEnvironment/env/test_common_function.py- Nessuna modifica necessariaTestEnvironment/env/leo_grifo_common.py- Nessuna modifica necessaria
Conclusioni
La modifica garantisce:
- ✅ 100% compatibilità con codice esistente (nessuna modifica ai test)
- ✅ Target reale funziona identicamente (connessione lazy al primo uso)
- ✅ Simulazione funziona correttamente (mock sostituisce prima dell'init)
- ✅ Import sicuro (no hardware all'import)
- ✅ Trasparenza totale (API identica per utente finale)
Puoi eseguire sul target reale con sicurezza: il comportamento è identico, solo la temporizzazione della connessione hardware è cambiata (da import-time a first-use-time).