From 3987562890095ff19d5a9b5818594ee6568e3eff Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Sat, 3 Oct 2026 21:24:00 +0800 Subject: [PATCH] feat(test): support scoped Firstleg read-only receiver evidence --- scripts/fba-core-regression-evidence.mjs | 2 +- scripts/fba-core-regression-evidence.test.mjs | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/fba-core-regression-evidence.mjs b/scripts/fba-core-regression-evidence.mjs index e6fa56c5d..24dddbb64 100644 --- a/scripts/fba-core-regression-evidence.mjs +++ b/scripts/fba-core-regression-evidence.mjs @@ -130,7 +130,7 @@ const base64Expression = value => '['+Buffer.from(value).toString('base64').matc // Credentials stay in the executor's memory. No deploy, SQL mutation, or arbitrary SQL entry point. export function buildEvidenceRemoteScript(service, sql, agent) { assertReadOnlySql(sql) - if (!['order','lastleg'].includes(service) || !/^[A-Za-z0-9_.-]{1,128}$/.test(agent)) throw Error('Invalid TEST evidence target') + if (!['order','firstleg','lastleg'].includes(service) || !/^[A-Za-z0-9_.-]{1,128}$/.test(agent)) throw Error('Invalid TEST evidence target') const prefix=service.toUpperCase(),container=`firstleg-test-${service}` const python = `import json,os,subprocess,urllib.parse,base64,re try: diff --git a/scripts/fba-core-regression-evidence.test.mjs b/scripts/fba-core-regression-evidence.test.mjs index 60fb68ec2..206ea130d 100644 --- a/scripts/fba-core-regression-evidence.test.mjs +++ b/scripts/fba-core-regression-evidence.test.mjs @@ -58,3 +58,17 @@ test('transport frames valid empty rows and suppresses raw remote and connection const script=buildEvidenceRemoteScript('order',buildCompletionEvidenceSql(completion()),'java-test-agent') assert.equal(script.includes(env().JENKINS_API_TOKEN),false) }) + +test('Firstleg receiver evidence stays on its exact TEST container and rejects writes', () => { + const sql = buildCompletionEvidenceSql(completion()) + const decode = value => Buffer.from([...value.matchAll(/'([A-Za-z0-9+/=]{40,})'/g)].map(m => m[1]).join(''), 'base64').toString('utf8') + const python = decode(decode(buildEvidenceRemoteScript('firstleg', sql, 'java-test-agent'))) + assert.match(python, /docker','inspect','firstleg-test-firstleg'/) + assert.match(python, /get\('Name'\)!='\/firstleg-test-firstleg'/) + assert.match(python, /com\.docker\.compose\.project'\)!='firstleg-test'/) + assert.match(python, /e\['FIRSTLEG_DB_URL'\]/) + assert.match(python, /e\['FIRSTLEG_DB_USERNAME'\]/) + assert.match(python, /MYSQL_PWD=e\['FIRSTLEG_DB_PASSWORD'\]/) + assert.throws(() => buildEvidenceRemoteScript('firstleg', sql.replace('COMMIT;', 'DELETE FROM fl_inbound_order;\nCOMMIT;'), 'java-test-agent')) + assert.throws(() => buildEvidenceRemoteScript('firstleg-prod', sql, 'java-test-agent')) +})