150 lines
5.3 KiB
Python
150 lines
5.3 KiB
Python
"""
|
|
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")
|