PlatSim_Genova/LAZY_INITIALIZATION_GUIDE.md
2026-02-02 09:43:12 +01:00

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.modules PRIMA che il test importasse i moduli
  • Impossibile importare lo script senza hardware disponibile
  • Fallimento import se PlatformSimulator/bin non 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/bin nel 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 usa hasattr() 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/bin nel PYTHONPATH o ambiente configurato
  • Modulo interpreter disponibile e funzionante

Comando:

cd TestEnvironment\scripts
python GRIFO_M_PBIT.py

Comportamento atteso:

  1. Import dello script: SUCCESSO (nessuna connessione hardware ancora)
  2. Chiamata a theGrifo1553.getInterface() in test_proc(): Qui avviene la connessione
  3. Prima chiamata check(theGrifo1553, ...): proxy delega all'istanza reale
  4. 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:

  1. Import dello script: SUCCESSO
  2. Rilevamento flag --simulate: import di GRIFO_M_PBIT_mock
  3. Mock sostituisce sys.modules['leo_grifo_1553'] con modulo fake
  4. Proxy originale NON viene mai inizializzato (nessuna connessione hardware)
  5. 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.modules correttamente
  • 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 oggetto grifo_1553 nativo
  • run(enable: bool)

Problema: "ImportError: No module named 'interpreter'"

Causa: Ambiente non configurato per hardware reale.

Soluzione: Esegui con uno di questi metodi:

  1. Wrapper Python: python python_simulate_wrapper.py (solo simulate)
  2. Batch Production: Usa run.bat o configura PYTHONPATH manualmente
  3. Modalità Simulate: Aggiungi flag --simulate (non richiede interpreter)

Problema: "Connessione hardware avviene all'import"

Causa: Il proxy potrebbe non essere stato applicato correttamente.

Soluzione:

  1. Verifica che leo_grifo_1553.py contenga _LazyGrifoProxy
  2. Verifica che theGrifo1553 = _LazyGrifoProxy(0.2) sia l'ultima riga del file
  3. Esegui test_lazy_proxy.py per 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 necessaria
  • TestEnvironment/scripts/GRIFO_M_PBIT_mock.py - Nessuna modifica necessaria
  • TestEnvironment/env/test_common_function.py - Nessuna modifica necessaria
  • TestEnvironment/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).