* test_curs_bnr_headless.prg * Proba headless pentru citeste_curs_bnr (clasa actualizare_curs_bnr, onom_curs.vcx) dupa * patch-ul arhiva 10 zile + fisier anual BNR. Apeleaza metoda DIRECT (nu initializeaza), ca sa * nu atinga Oracle (initializeaza ar chema scrie_curs_bnr la succes). * * Capcana descoperita si ocolita AICI, in test, nu in cod: citeste_curs_bnr incepe cu * creeaza_backup_cursoare(This.cCursor), care cheama copiaza_structura_cursor() din * oproceduri_comune.prg (linia ~3024). Daca cursorul cCursor ("ccrsbnr") nu e deja deschis, * copiaza_structura_cursor cade pe ramura Else si cheama amessagebox("Eroare interna 2 - * copiaza structura cursor",...) - apel INTRA-FISIER (amessagebox e tot in oproceduri_comune.prg), * deci mock_amessagebox.prg NU il intercepteaza (limita documentata in antetul mock-ului). Rezultat: * dialog real, headless agata. In productie nu se intampla pentru ca initializeaza() creeaza * cursorul via goExecutor.oExecute(lcSql, This.cCursor) INAINTE de a chema citeste_curs_bnr. * Aici, apeland metoda direct, precream cursorul ccrsbnr gol (crea_cursor_gol) inainte de FIECARE * apel - metoda oricum il inchide (Use In) si il reface din raspunsul HTTP (Xmltocursor). SET SAFETY OFF SET TALK OFF SET DELETED ON LOCAL lcLog lcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\_test_curs_bnr_out.txt" STRTOFILE("RUN " + TTOC(DATETIME()) + " marca=" + SYS(2015) + CHR(13) + CHR(10), lcLog) ON ERROR DO log_eroare WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() DO (ADDBS("D:\ROA\ROAFACTURARE\COMUN\utile\Teste") + "test_init_env_auto_roafacturare.prg") WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' DO log_txt WITH "env init OK, ClassLibrary onom_curs incarcat: " + IIF(('ONOM_CURS' $ UPPER(SET('CLASSLIB'))), 'DA', 'NU') LOCAL lnPass, lnFail lnPass = 0 lnFail = 0 * ---------- Caz 1: sursa 1, azi (zi lucratoare) -> Return 0, cursor populat, EUR>0 ---------- LOCAL loCurs, lnRet, ldData, lnT0, lnT1, lnDur loCurs = CREATEOBJECT("actualizare_curs_bnr", 1) DO crea_cursor_gol WITH loCurs.cCursor ldData = DATE() loCurs.dData = ldData lnT0 = SECONDS() lnRet = loCurs.citeste_curs_bnr(1) lnT1 = SECONDS() DO verifica_caz WITH "CAZ1_sursa1_azi", lnRet, 0, loCurs, .T., (lnT1-lnT0), lnPass, lnFail * ---------- Caz 2: sursa 1, luni recenta -> Return 0 (cade pe publicarea de vineri) ---------- LOCAL ldLuni ldLuni = DATE() - (DOW(DATE(),2) - 1) IF ldLuni = DATE() ldLuni = ldLuni - 7 ENDIF loCurs = CREATEOBJECT("actualizare_curs_bnr", 1) DO crea_cursor_gol WITH loCurs.cCursor loCurs.dData = ldLuni lnT0 = SECONDS() lnRet = loCurs.citeste_curs_bnr(1) lnT1 = SECONDS() DO log_txt WITH "CAZ2 dData(luni)=" + DTOC(ldLuni) DO verifica_caz WITH "CAZ2_sursa1_luni", lnRet, 0, loCurs, .T., (lnT1-lnT0), lnPass, lnFail * ---------- Caz 3: sursa 2, martie anul curent -> Return 0 ---------- LOCAL ldMartie ldMartie = DATE(YEAR(DATE()), 3, 15) loCurs = CREATEOBJECT("actualizare_curs_bnr", 1) DO crea_cursor_gol WITH loCurs.cCursor loCurs.dData = ldMartie lnT0 = SECONDS() lnRet = loCurs.citeste_curs_bnr(2) lnT1 = SECONDS() DO verifica_caz WITH "CAZ3_sursa2_martie", lnRet, 0, loCurs, .T., (lnT1-lnT0), lnPass, lnFail * ---------- Caz 4: sursa 2, 2 ianuarie anul curent -> Return 0 (trecere in anul precedent) ---------- LOCAL ld2Ian ld2Ian = DATE(YEAR(DATE()), 1, 2) loCurs = CREATEOBJECT("actualizare_curs_bnr", 1) DO crea_cursor_gol WITH loCurs.cCursor loCurs.dData = ld2Ian lnT0 = SECONDS() lnRet = loCurs.citeste_curs_bnr(2) lnT1 = SECONDS() DO verifica_caz WITH "CAZ4_sursa2_2ian", lnRet, 0, loCurs, .T., (lnT1-lnT0), lnPass, lnFail * ---------- Caz 5: sursa 1, data mult mai veche decat arhiva 10 zile -> Return 2 ---------- LOCAL ldVeche, loCurs5 ldVeche = DATE(YEAR(DATE()), 1, 1) loCurs5 = CREATEOBJECT("actualizare_curs_bnr", 1) DO crea_cursor_gol WITH loCurs5.cCursor loCurs5.dData = ldVeche lnT0 = SECONDS() lnRet = loCurs5.citeste_curs_bnr(1) lnT1 = SECONDS() DO verifica_caz WITH "CAZ5_sursa1_veche", lnRet, 2, loCurs5, .F., (lnT1-lnT0), lnPass, lnFail * ---------- Caz 8 (cascada dubla, cerut suplimentar): acelasi obiect/data, sursa 2 dupa ---------- * ---------- Return 2 pe sursa 1 - verifica ca ccrsbnr e refacut de repune_backup_cursoare si ---------- * ---------- ca al doilea apel NU mai loveste "Eroare interna 2" (creeaza_backup_cursoare cere ---------- * ---------- Used(cCursor) la intrare). ---------- lnT0 = SECONDS() lnRet = loCurs5.citeste_curs_bnr(2) lnT1 = SECONDS() DO verifica_caz WITH "CAZ8_cascada_sursa1_apoi_sursa2", lnRet, 0, loCurs5, .T., (lnT1-lnT0), lnPass, lnFail * ---------- Caz 6: sursa 1, host invalid -> Return 1, fara agatare (timeouts 5s/5s/5s/15s) ---------- LOCAL loCurs6 loCurs6 = CREATEOBJECT("actualizare_curs_bnr", 1) DO crea_cursor_gol WITH loCurs6.cCursor loCurs6.cLinkArhiva = "https://host-inexistent-romfast-test.invalid/nbrfxrates10days.xml" loCurs6.dData = DATE() lnT0 = SECONDS() lnRet = loCurs6.citeste_curs_bnr(1) lnT1 = SECONDS() lnDur = lnT1 - lnT0 DO log_txt WITH "CAZ6 durata=" + TRANSFORM(lnDur) + "s" DO verifica_caz WITH "CAZ6_sursa1_host_invalid", lnRet, 1, loCurs6, .F., lnDur, lnPass, lnFail * ---------- Caz 7: fara parametru -> comportament ca sursa 0, This.dData se actualizeaza ---------- LOCAL loCurs7, ldDataInainte loCurs7 = CREATEOBJECT("actualizare_curs_bnr", 1) DO crea_cursor_gol WITH loCurs7.cCursor ldDataInainte = DATE() - 30 loCurs7.dData = ldDataInainte lnT0 = SECONDS() lnRet = loCurs7.citeste_curs_bnr() lnT1 = SECONDS() DO log_txt WITH "CAZ7 dData inainte=" + DTOC(ldDataInainte) + " dData dupa=" + DTOC(loCurs7.dData) + " (trebuie sa difere, s-a suprascris ca la sursa 0)" DO verifica_caz WITH "CAZ7_fara_parametru", lnRet, 0, loCurs7, .T., (lnT1-lnT0), lnPass, lnFail DO log_txt WITH "=== SUMAR: PASS=" + TRANSFORM(lnPass) + " FAIL=" + TRANSFORM(lnFail) + " ===" DO log_txt WITH "Nicio scriere in Oracle: nu s-a apelat initializeaza() nici scrie_curs_bnr() in acest test." QUIT * ============================================================ PROCEDURE crea_cursor_gol LPARAMETERS tcCursor IF USED(tcCursor) USE IN (tcCursor) ENDIF CREATE CURSOR (tcCursor) (Currency C(10), multiplier N(10,4), Curs N(14,6)) ENDPROC PROCEDURE log_txt LPARAMETERS tcTxt STRTOFILE(TRANSFORM(tcTxt) + CHR(13) + CHR(10), "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\_test_curs_bnr_out.txt", 1) ENDPROC PROCEDURE log_eroare LPARAMETERS tnErr, tcMsg, tcProg, tnLine DO log_txt WITH " [ON ERROR] " + TRANSFORM(tnErr) + " " + TRANSFORM(tcMsg) + " in " + TRANSFORM(tcProg) + " linia " + TRANSFORM(tnLine) ENDPROC PROCEDURE verifica_caz LPARAMETERS tcLabel, tnRetObtinut, tnRetAsteptat, toCurs, tlAsteaptaDate, tnDur, tnPassRef, tnFailRef LOCAL llOk, lcDetaliu, lnRc, lcEur llOk = (tnRetObtinut = tnRetAsteptat) lcDetaliu = "Return obtinut=" + TRANSFORM(tnRetObtinut) + " asteptat=" + TRANSFORM(tnRetAsteptat) + " durata=" + TRANSFORM(tnDur) + "s" IF tlAsteaptaDate IF USED(toCurs.cCursor) lnRc = RECCOUNT(toCurs.cCursor) lcDetaliu = lcDetaliu + " Reccount=" + TRANSFORM(lnRc) IF lnRc > 0 SELECT (toCurs.cCursor) LOCATE FOR UPPER(ALLTRIM(NVL(Currency,""))) = "EUR" IF FOUND() AND Curs > 0 lcEur = "EUR curs=" + TRANSFORM(Curs) + " (OK)" ELSE lcEur = "EUR NU s-a gasit sau curs<=0" llOk = .F. ENDIF lcDetaliu = lcDetaliu + " " + lcEur ELSE llOk = .F. lcDetaliu = lcDetaliu + " (cursor gol, esuat)" ENDIF ELSE llOk = .F. lcDetaliu = lcDetaliu + " (cursor neincarcat)" ENDIF ENDIF IF llOk tnPassRef = tnPassRef + 1 DO log_txt WITH "PASS " + tcLabel + " :: " + lcDetaliu ELSE tnFailRef = tnFailRef + 1 DO log_txt WITH "FAIL " + tcLabel + " :: " + lcDetaliu ENDIF ENDPROC