60 lines
4.2 KiB
JavaScript
60 lines
4.2 KiB
JavaScript
// Mecanismul comun al controalelor negative ale Proof of Software 1.3.0: o COPIE (pos.mjs + suita + sdk-pq-sign + sdk, intr-un dosar
|
|
// temporar; depozitul nu se atinge), un paznic scos in pos.mjs-ul copiei, suita rulata pe copie. Martorul (copia neatinsa) trebuie
|
|
// verde; fiecare plantare trebuie sa inroseasca EXACT proba numita, cu suita chiar rulata (rezumatul ei exista). O ancora care nu
|
|
// apare exact o data e un esec al controlului (STRICAT), nu o linie informativa.
|
|
// 1.5.0 (2026-09-29): plantarile ruleaza cate PARALEL deodata (fiecare in copia ei), ca toate controalele sa incapa in bugetul portii
|
|
// D-424; rezultatele se tiparesc in ordinea plantarilor. Deci controleaza() intoarce o promisiune: `process.exitCode = await controleaza(...)`.
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { spawn } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const AICI = path.dirname(fileURLToPath(import.meta.url));
|
|
const RAD = path.resolve(AICI, '..', '..', '..');
|
|
|
|
const PARALEL = 4;
|
|
export async function controleaza(suita, plantari) {
|
|
function copie() {
|
|
const t = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-pos-cn-'));
|
|
for (const d of ['sdk-pq-sign', 'sdk']) fs.cpSync(path.join(RAD, d), path.join(t, d), { recursive: true });
|
|
fs.mkdirSync(path.join(t, 'tools', 'proof-of-software', 'test'), { recursive: true });
|
|
fs.copyFileSync(path.join(RAD, 'tools', 'proof-of-software', 'pos.mjs'), path.join(t, 'tools', 'proof-of-software', 'pos.mjs'));
|
|
fs.copyFileSync(path.join(AICI, suita), path.join(t, 'tools', 'proof-of-software', 'test', suita));
|
|
// 1.4.0: fixturile suitelor (dosarele fixturi-*, de ex. go.mod/go.sum reale) merg si ele in copie
|
|
for (const d of fs.readdirSync(AICI).filter((n) => n.startsWith('fixturi') && fs.statSync(path.join(AICI, n)).isDirectory())) {
|
|
fs.cpSync(path.join(AICI, d), path.join(t, 'tools', 'proof-of-software', 'test', d), { recursive: true });
|
|
}
|
|
return t;
|
|
}
|
|
function ruleaza(t) {
|
|
return new Promise((resolve) => {
|
|
const c = spawn(process.execPath, [path.join(t, 'tools', 'proof-of-software', 'test', suita)]); let out = '';
|
|
const ceas = setTimeout(() => c.kill(), 400000);
|
|
c.stdout.on('data', (x) => { out += x; }); c.stderr.on('data', (x) => { out += x; });
|
|
c.on('close', (cod) => { clearTimeout(ceas); resolve({ cod, rulat: /\d+ treceri, \d+ esecuri/.test(out), picate: out.split('\n').filter((l) => l.startsWith(' ESEC')) }); });
|
|
});
|
|
}
|
|
async function planteaza([nume, din, inl, tinta]) {
|
|
const t = copie();
|
|
try {
|
|
const f = path.join(t, 'tools', 'proof-of-software', 'pos.mjs'); const src = fs.readFileSync(f, 'utf8');
|
|
if (src.split(din).length !== 2) return [false, ` STRICAT ${nume}: ancora apare de ${src.split(din).length - 1} ori`];
|
|
fs.writeFileSync(f, src.replace(din, inl));
|
|
const r = await ruleaza(t);
|
|
if (!r.rulat) return [false, ` STRICAT ${nume}: suita nu a ajuns la rezumat (cod ${r.cod})`];
|
|
if (r.picate.some((l) => l.includes(tinta))) return [true, ` ROSU cum trebuia ${nume} (proba '${tinta}' pica)`];
|
|
return [false, ` CONTROL CAZUT ${nume}: proba '${tinta}' a ramas verde (${r.picate.length} esecuri altundeva)`];
|
|
} catch (e) { return [false, ` STRICAT ${nume}: controlul a cazut pe ea (${String(e.message || e).slice(0, 80)})`]; }
|
|
finally { fs.rmSync(t, { recursive: true, force: true }); }
|
|
}
|
|
let rele = 0;
|
|
const t0 = copie(); const m = await ruleaza(t0); fs.rmSync(t0, { recursive: true, force: true });
|
|
if (m.cod === 0 && m.rulat && !m.picate.length) console.log(' OK martorul: copia neatinsa verde'); else { rele++; console.log(` STRICAT martorul nu e verde (cod ${m.cod}, ${m.picate.length} esecuri)`); }
|
|
const rez = new Array(plantari.length); let i = 0;
|
|
await Promise.all(Array.from({ length: PARALEL }, async () => { while (i < plantari.length) { const k = i++; rez[k] = await planteaza(plantari[k]); } }));
|
|
for (const [bun, linie] of rez) { console.log(linie); if (!bun) rele++; }
|
|
console.log(rele ? `CONTROL NEGATIV: ${rele} probleme` : `DOVEDIT: martorul verde, ${plantari.length} din ${plantari.length} paznici scosi -> proba lor rosie`);
|
|
return rele ? 1 : 0;
|
|
}
|