65 lines
5.2 KiB
JavaScript
65 lines
5.2 KiB
JavaScript
#!/usr/bin/env node
|
|
// Controlul negativ al probelor clientului Go: fiecare paznic se strica intr-o COPIE a pachetului (sursa din depozit nu se
|
|
// atinge), `go test` ruleaza pe copie si proba tinta TREBUIE sa pice; o plantare care nu se aplica sau nu compileaza e STRICAT,
|
|
// nu rosu. La urma, pachetul neatins trebuie sa treaca intreg.
|
|
// node aerenew/sdk/go/control-negativ.mjs
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { spawnSync } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const AICI = path.dirname(fileURLToPath(import.meta.url));
|
|
const FISIERE = ['go.mod', 'aerecloud.go', 'aerecloud_test.go'];
|
|
const sursa = fs.readFileSync(path.join(AICI, 'aerecloud.go'), 'utf8');
|
|
|
|
const PLANTARI = [
|
|
['exportul jsonl declarat verificat fara hash', 'ok := e.Digest != "" && e.Digest == sha256Hex(r.body)', 'ok := true', 'TestExportulZilei'],
|
|
['piatra zilei sterse acceptata fara comparatie', 'Matches: local == t.Expired.Digest,', 'Matches: true,', 'TestExportulPastrat'],
|
|
['ziua tinuta acceptata fara comparatie', 'Matches: local == d}', 'Matches: true}', 'TestExportulPastrat'],
|
|
['cheia trimisa si fara attest', 'return c.jsonReq(ctx, "POST", "/pq/readiness", b, attest)', 'return c.jsonReq(ctx, "POST", "/pq/readiness", b, true)', 'TestReadinessCheiaNumaiLaAttest'],
|
|
['redirectarile urmate (cheia ar pleca spre alta gazda)', 'CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }', 'CheckRedirect: nil', 'TestRedirectareaNuEUrmata'],
|
|
['un 429 intors ca nepotrivire', 'return nil, &Error{Status: r.status, Body: r.body, Path: "/account/audit"}\n\t}\n\td := sha256Hex(r.body)',
|
|
'return &KeptCheck{Day: day, State: "held", Local: local}, nil\n\t}\n\td := sha256Hex(r.body)', 'TestExportulPastrat'],
|
|
// 2026-09-29: plicul trecut printr-un map de Go (cheile sortate = alt text canonic, un plic valid ar iesi INVALID la Trust API)
|
|
['Verify trece plicul printr-un map', 'return c.jsonReq(ctx, "POST", p, envelope, true)',
|
|
'var m map[string]any\n\t_ = json.Unmarshal(envelope, &m)\n\treturn c.jsonReq(ctx, "POST", p, m, true)', 'TestVerifyPastreazaOrdinea'],
|
|
// 1.7.0: prezentarea trecuta printr-un map (numerele mari devin float64) si ruta de conformitate trimisa la identitate
|
|
['IdentityVerify trece prezentarea printr-un map', 'return c.jsonReq(ctx, "POST", "/identity/verify", req, true)',
|
|
'var m map[string]any\n\t_ = json.Unmarshal(req.Presentation, &m)\n\tb, _ := json.Marshal(m)\n\treq.Presentation = b\n\treturn c.jsonReq(ctx, "POST", "/identity/verify", req, true)', 'TestIdentityVerifyPastreazaOctetii'],
|
|
['ComplianceCheck pe ruta de identitate', 'return c.jsonReq(ctx, "POST", "/compliance/check", req, true)', 'return c.jsonReq(ctx, "POST", "/identity/verify", req, true)', 'TestIdentityVerifyPastreazaOctetii'],
|
|
// 1.8.0: intrarile de risc trecute printr-un map (suma peste 2^53 devine float64) si chitanta trimisa pe ruta riscului
|
|
['PaymentsRisk trece intrarile printr-un map', 'return c.jsonReq(ctx, "POST", "/payments/risk", req, true)',
|
|
'var m map[string]any\n\t_ = json.Unmarshal(req.Inputs, &m)\n\tb, _ := json.Marshal(m)\n\treq.Inputs = b\n\treturn c.jsonReq(ctx, "POST", "/payments/risk", req, true)', 'TestPaymentsPastreazaOctetii'],
|
|
['PaymentsReceipt pe ruta riscului', 'return c.jsonReq(ctx, "POST", "/payments/receipt", req, true)', 'return c.jsonReq(ctx, "POST", "/payments/risk", req, true)', 'TestPaymentsPastreazaOctetii'],
|
|
];
|
|
|
|
function ruleaza(src) {
|
|
const d = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-go-cn-'));
|
|
try {
|
|
for (const f of FISIERE) fs.copyFileSync(path.join(AICI, f), path.join(d, f));
|
|
fs.writeFileSync(path.join(d, 'aerecloud.go'), src);
|
|
const r = spawnSync('go', ['test', '-count=1', '-v', './...'], { cwd: d, encoding: 'utf8' });
|
|
const out = (r.stdout || '') + (r.stderr || '');
|
|
if (/\[build failed\]|cannot use|undefined:|syntax error/.test(out)) return { stricat: 'nu compileaza: ' + out.split('\n').find((l) => /error|undefined|cannot/.test(l)) };
|
|
const picate = [...out.matchAll(/--- FAIL: (\w+)/g)].map((m) => m[1]);
|
|
const trecute = [...out.matchAll(/--- PASS: (\w+)/g)].map((m) => m[1]);
|
|
if (!picate.length && !trecute.length) return { stricat: 'probele nu au rulat' };
|
|
return { picate, trecute };
|
|
} finally { fs.rmSync(d, { recursive: true, force: true }); }
|
|
}
|
|
|
|
let rele = 0;
|
|
for (const [nume, vechi, nou, tinta] of PLANTARI) {
|
|
if (sursa.split(vechi).length !== 2) { console.log(` STRICAT ${nume}: ancora apare de ${sursa.split(vechi).length - 1} ori`); rele++; continue; }
|
|
const r = ruleaza(sursa.replace(vechi, nou));
|
|
if (r.stricat) { console.log(` STRICAT ${nume}: ${r.stricat}`); rele++; continue; }
|
|
if (r.picate.includes(tinta)) console.log(` ROSU cum trebuia ${nume} (pica ${r.picate.join(', ')})`);
|
|
else { console.log(` CONTROL CAZUT ${nume}: ${tinta} a ramas verde`); rele++; }
|
|
}
|
|
const m = ruleaza(sursa);
|
|
if (m.stricat || m.picate.length) { console.log(' MARTORUL nu e verde: ' + JSON.stringify(m)); rele++; }
|
|
else console.log(` martor: sursa neatinsa, ${m.trecute.length} probe verzi`);
|
|
console.log(rele ? `CONTROL NEGATIV: ${rele} probleme` : `CONTROL NEGATIV TRECUT (${PLANTARI.length} din ${PLANTARI.length} rosii, martorul verde)`);
|
|
process.exitCode = rele ? 1 : 0;
|