Files
baiyue-firstleg/scripts/gray-regression-evidence.test.mjs
2026-10-08 17:07:57 +08:00

55 lines
4.1 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { buildGrayEvidenceRemoteScript, createGrayEvidenceReaders, validateGrayEvidenceConfig } from './gray-regression-evidence.mjs'
const env = { JENKINS_URL: 'https://jenkins.example.invalid/', JENKINS_USER: 'reader', JENKINS_API_TOKEN: 'private-test-token' }
const probeSql = "SET NAMES utf8mb4 COLLATE utf8mb4_bin;\nSET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;\nSTART TRANSACTION WITH CONSISTENT SNAPSHOT, READ ONLY;\nSELECT JSON_OBJECT('grayProbe',1);\nCOMMIT;"
test('gray reader refuses missing credentials, embedded URL credentials and SQL mutations', () => {
assert.throws(() => validateGrayEvidenceConfig({}), /Missing/)
assert.throws(() => validateGrayEvidenceConfig({ ...env, JENKINS_URL: 'https://secret@host.invalid' }), /Invalid/)
assert.throws(() => buildGrayEvidenceRemoteScript('auth', probeSql), /target/)
assert.throws(() => buildGrayEvidenceRemoteScript('order', probeSql.replace('SELECT JSON_OBJECT', 'DELETE JSON_OBJECT')), /Read-only/)
})
test('gray SSH reader pins registered production host, known hosts, runtime and database credentials', () => {
const script = buildGrayEvidenceRemoteScript('order', probeSql)
for (const credential of ['ssh', 'host', 'known-hosts', 'env']) assert.ok(script.includes(`firstleg-production-${credential}`))
assert.ok(script.includes('StrictHostKeyChecking=yes'))
assert.ok(script.includes('finally {dir.listFiles().each{it.delete()};dir.delete()}'))
assert.ok(!script.includes('java-test-agent') && !script.includes('RemotingDiagnostics'))
const encodedPython = [...script.matchAll(/\['([A-Za-z0-9+/=]+)'(?:,'[A-Za-z0-9+/=]+')*\]\.join\(''\)/g)]
.map(match => [...match[0].matchAll(/'([A-Za-z0-9+/=]+)'/g)].map(part => part[1]).join(''))
const python = encodedPython.map(value => Buffer.from(value, 'base64').toString()).find(value => value.includes('subprocess'))
assert.ok(python?.includes("labels.get('com.docker.compose.project')!='firstleg-production'"))
assert.ok(python.includes("e.get(key)!=expected[key]"))
assert.ok(python.includes("u.path!='/'+ 'baiyue_order'"))
assert.ok(python.includes('READ ONLY') === false, 'SQL is encoded independently')
const lastleg = buildGrayEvidenceRemoteScript('lastleg', probeSql)
const payload = [...lastleg.matchAll(/\['([A-Za-z0-9+/=]+)'(?:,'[A-Za-z0-9+/=]+')*\]\.join\(''\)/g)]
.map(match => [...match[0].matchAll(/'([A-Za-z0-9+/=]+)'/g)].map(part => part[1]).join(''))
.map(value => Buffer.from(value, 'base64').toString()).find(value => value.includes('subprocess'))
assert.ok(payload.includes("labels.get('com.docker.compose.service')!='lastleg-service'"))
})
test('preflight performs only two scoped gray probes and never exposes remote raw errors', async () => {
const requests = []
const readers = createGrayEvidenceReaders(env, async (url, options) => {
requests.push({ url: String(url), script: options.body.get('script') })
return { ok: true, text: async () => 'GRAY_EVIDENCE_JSON={"ok":true,"rows":[{"grayProbe":1}]}\n' }
})
await readers.preflight()
assert.equal(requests.length, 2)
assert.ok(requests.every(request => request.url === 'https://jenkins.example.invalid/scriptText'))
const failed = createGrayEvidenceReaders(env, async () => ({ ok: true, text: async () => 'MYSQL_PWD=hidden\nTraceback secret-value' }))
await assert.rejects(failed.preflight(), error => error.message === 'Gray evidence JSON missing or ambiguous')
})
test('preflight rejects failed probes and ambiguous results', async () => {
for (const raw of ['GRAY_EVIDENCE_JSON={"ok":true,"rows":[{"grayProbe":0}]}',
'GRAY_EVIDENCE_JSON={"ok":false,"error":"MYSQL_1146"}',
'GRAY_EVIDENCE_JSON={}\nGRAY_EVIDENCE_JSON={}']) {
const readers = createGrayEvidenceReaders(env, async () => ({ ok: true, text: async () => raw }))
await assert.rejects(readers.preflight())
}
const sourceFailure = createGrayEvidenceReaders(env, async () => ({ ok: true,
text: async () => 'GRAY_EVIDENCE_JSON={"ok":false,"error":"GRAY_DATABASE_SOURCE_FAILED"}' }))
await assert.rejects(sourceFailure.preflight(), { message: 'GRAY_DATABASE_SOURCE_FAILED' })
})