""" Integration test: SP_CREEAZA_COMANDA_PROTOTIP persist + reconnect verify — Săpt 9-10 Verifies that: 1. callproc SP_CREEAZA_COMANDA_PROTOTIP writes a row to DEV_ORDL 2. After commit + disconnect, a NEW connection sees the row (true durability) 3. Cleanup removes all prototype rows from DEV_ORDL and NOM_LUCRARI Run: cd /workspace/roa2web python -m pytest backend/modules/service_auto/tests/test_comanda_persist.py -v -m integration """ import os import sys import time import pytest import oracledb # Add backend to path so secrets/ is accessible sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')) HOST = "10.0.20.121" PORT = 1521 SERVICE_NAME = "ROA" USER = "CONTAFIN_ORACLE" SECRETS_FILE = os.path.join( os.path.dirname(__file__), '..', '..', '..', 'secrets', 'central.oracle_pass' ) def _read_password() -> str: with open(SECRETS_FILE) as f: return f.read().strip() def _connect() -> oracledb.Connection: return oracledb.connect( user=USER, password=_read_password(), host=HOST, port=PORT, service_name=SERVICE_NAME, ) @pytest.mark.integration @pytest.mark.skip( reason=( "Obsolete target SP: commit 9cd7f35 migrated comanda creation to " "PACK_AUTO (+PACK_SERII_NUMERE). SP_CREEAZA_COMANDA_PROTOTIP is no " "longer the production path; callproc signature drift causes " "PLS-00306. Persist/durability is now covered by live smoke tests " "via /api/service-auto/comenzi — see docs/service-auto/" "decision-log.md (2026-04-13)." ) ) def test_comanda_persist_and_reconnect(): """ Full round-trip: callproc → commit → close → NEW connection → SELECT → assert exists. Cleans up all inserted rows after verification. """ # --- Phase 1: Call SP and commit --- conn1 = _connect() id_ordl = None id_lucrare = None try: with conn1.cursor() as cursor: out_id_ordl = cursor.var(oracledb.NUMBER) out_nrord = cursor.var(oracledb.STRING) t0 = time.perf_counter() cursor.callproc( "MARIUSM_AUTO.SP_CREEAZA_COMANDA_PROTOTIP", [ 3, # p_tip IN NUMBER 200, # p_id_masiniclient IN NUMBER 'Test pytest persist', # p_solicitari IN VARCHAR2 110, # p_id_firma IN NUMBER out_id_ordl, # p_id_ordl OUT NUMBER out_nrord, # p_nrord OUT VARCHAR2 ], ) t_callproc = time.perf_counter() - t0 id_ordl = int(out_id_ordl.getvalue()) nrord = out_nrord.getvalue() or "" print(f"\n[PERSIST] callproc OK in {t_callproc*1000:.1f}ms → id_ordl={id_ordl} nrord={nrord}") assert id_ordl > 0, f"Expected positive id_ordl, got {id_ordl}" assert nrord.startswith("P"), f"Expected nrord starting with 'P', got {nrord!r}" conn1.commit() print(f"[PERSIST] commit OK on connection 1") finally: conn1.close() print("[PERSIST] connection 1 closed") # --- Phase 2: Open NEW connection and verify row exists --- assert id_ordl is not None, "id_ordl must be set before reconnect phase" conn2 = _connect() try: with conn2.cursor() as cursor: cursor.execute( "SELECT id_ordl, id_lucrare FROM MARIUSM_AUTO.DEV_ORDL WHERE id_ordl = :id", {"id": id_ordl}, ) row = cursor.fetchone() print(f"[PERSIST] NEW connection SELECT → row={row}") assert row is not None, f"Row id_ordl={id_ordl} not found after reconnect — durability FAILED" assert int(row[0]) == id_ordl, f"id_ordl mismatch: got {row[0]}, expected {id_ordl}" id_lucrare = int(row[1]) print(f"[PERSIST] ASSERT PASSED: row exists in new connection ✅ (id_lucrare={id_lucrare})") finally: conn2.close() print("[PERSIST] connection 2 closed") # --- Phase 3: Cleanup — delete child then parent --- assert id_lucrare is not None, "id_lucrare must be set for cleanup" conn3 = _connect() try: with conn3.cursor() as cursor: # Child first (FK constraint: DEV_ORDL → NOM_LUCRARI) cursor.execute( "DELETE FROM MARIUSM_AUTO.DEV_ORDL WHERE id_ordl = :id", {"id": id_ordl}, ) deleted_ordl = cursor.rowcount print(f"[PERSIST] DELETE DEV_ORDL id_ordl={id_ordl} → {deleted_ordl} row(s)") # Parent second cursor.execute( "DELETE FROM MARIUSM_AUTO.NOM_LUCRARI WHERE id_lucrare = :id", {"id": id_lucrare}, ) deleted_nom = cursor.rowcount print(f"[PERSIST] DELETE NOM_LUCRARI id_lucrare={id_lucrare} → {deleted_nom} row(s)") conn3.commit() print("[PERSIST] cleanup commit OK ✅") assert deleted_ordl == 1, f"Expected 1 DEV_ORDL row deleted, got {deleted_ordl}" assert deleted_nom == 1, f"Expected 1 NOM_LUCRARI row deleted, got {deleted_nom}" finally: conn3.close() print("[PERSIST] connection 3 (cleanup) closed")