优化
This commit is contained in:
@@ -3,8 +3,9 @@ import { execFileSync } from 'node:child_process'
|
||||
import { dirname, resolve, join } from 'node:path'
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { AcceptanceRun, parseArguments, validateExecutionOptions, buildAcceptanceSummary } from './admin-test-env-acceptance.mjs'
|
||||
import { AcceptanceRun, parseArguments, validateExecutionOptions, buildAcceptanceSummary, createFleetPoolGrayOptions } from './admin-test-env-acceptance.mjs'
|
||||
import { createTestEvidenceReaders } from './fba-core-regression-evidence.mjs'
|
||||
import { createGrayEvidenceReaders } from './gray-regression-evidence.mjs'
|
||||
import { redactEvidence } from './fba-core-regression-test-env.mjs'
|
||||
import { resolvePickerAccess, createPicker, disablePicker } from './admin-test-env-modules/phase4-overseas-pda.mjs'
|
||||
import { verifyFleetCrossCustomer } from './admin-test-env-modules/fleet-cross-customer-acceptance.mjs'
|
||||
@@ -38,20 +39,36 @@ export function crossCustomerPlan(config) {
|
||||
limits: 'Prerequisite rejection is not mid-transaction rollback. No deployment, configuration change, SQL writes or automatic rerun. Retain business samples; disable temporary PDA in finally.' }
|
||||
}
|
||||
|
||||
export async function runCrossCustomer(config, { env = process.env, outputRoot = ROOT, readers, prepare, verify = verifyFleetCrossCustomer,
|
||||
finish = finishFleetTrip, contextFactory = options => new AcceptanceRun(options), pickerAccess = resolvePickerAccess, pickerCreate = createPicker, pickerDisable = disablePicker } = {}) {
|
||||
const plan = crossCustomerPlan(config)
|
||||
export async function runCrossCustomer(config, dependencies = {}) {
|
||||
return runCrossCustomerCore(config, dependencies, false)
|
||||
}
|
||||
|
||||
/** Not a CLI mode: called only by the explicit GRAY pool entry with its verified pool scenario. */
|
||||
export async function runFleetPoolGrayCrossCustomer(config, dependencies = {}) {
|
||||
if (Object.keys(dependencies).some(key => !['env', 'outputRoot', 'verify', 'contextFactory'].includes(key)))
|
||||
throw Error('Gray pool cannot override evidence readers or fixture lifecycle')
|
||||
if (config.execute && (typeof dependencies.verify !== 'function' || typeof dependencies.contextFactory !== 'function'))
|
||||
throw Error('Gray pool requires its dedicated scenario and journaled context')
|
||||
return runCrossCustomerCore(config, dependencies, true)
|
||||
}
|
||||
|
||||
async function runCrossCustomerCore(config, { env = process.env, outputRoot = ROOT, readers, prepare, verify = verifyFleetCrossCustomer,
|
||||
finish = finishFleetTrip, contextFactory = options => new AcceptanceRun(options), pickerAccess = resolvePickerAccess, pickerCreate = createPicker, pickerDisable = disablePicker } = {}, gray = false) {
|
||||
const environment = gray ? 'GRAY' : 'TEST', reportName = `${gray ? 'fleet-pool-gray' : 'fleet-cross'}-${config.runId}`
|
||||
const plan = { ...crossCustomerPlan(config), environment, output: `reports/${reportName}`,
|
||||
...(gray ? { scope: 'FLEET_CAPACITY_POOL_GRAY', stages: ['current pool fixture and full pool HTTP matrix', 'trip completion and separate resource release'] } : {}) }
|
||||
if (!config.execute) return plan
|
||||
if (config.environment !== 'TEST' || env.CHONGCHONG_ENV !== 'test' || !/^[A-Za-z0-9][A-Za-z0-9_-]{0,47}$/.test(config.runId)
|
||||
if (config.environment !== environment || !(gray ? ['gray', 'prod'].includes(env.CHONGCHONG_ENV) : env.CHONGCHONG_ENV === 'test') || !/^[A-Za-z0-9][A-Za-z0-9_-]{0,47}$/.test(config.runId)
|
||||
|| config.runId === 'plan' || !/^[1-9][0-9]{0,19}$/.test(config.warehouseId) || !/^[1-9][0-9]{0,19}$/.test(config.destinationWarehouseId)
|
||||
|| !env.CHONGCHONG_ADMIN_USERNAME || !env.CHONGCHONG_ADMIN_PASSWORD) throw Error('Explicit TEST configuration required')
|
||||
|| !env.CHONGCHONG_ADMIN_USERNAME || !env.CHONGCHONG_ADMIN_PASSWORD) throw Error(`Explicit ${environment} configuration required`)
|
||||
const base = new URL(env.CHONGCHONG_ADMIN_API_BASE_URL)
|
||||
if (!['http:', 'https:'].includes(base.protocol) || base.username || base.password || base.search || base.hash || !['/api', '/api/'].includes(base.pathname)) throw Error('Invalid TEST gateway')
|
||||
readers ||= createTestEvidenceReaders(env)
|
||||
if (!(gray ? base.protocol === 'https:' : ['http:', 'https:'].includes(base.protocol)) || base.username || base.password || base.search || base.hash || !['/api', '/api/'].includes(base.pathname)) throw Error(`Invalid ${environment} gateway`)
|
||||
if (gray) readers = createGrayEvidenceReaders(env)
|
||||
else readers ||= createTestEvidenceReaders(env)
|
||||
// Load the reviewed producer before creating any resources.
|
||||
prepare ||= (await import('./admin-test-env-modules/fleet-cross-customer-fixture.mjs')).createFleetCrossCustomerFixture
|
||||
if (typeof prepare !== 'function' || typeof readers.readFleetInventory !== 'function') throw Error('Fixture producer and inventory reader required')
|
||||
const reports = resolve(outputRoot, 'reports'), output = join(reports, `fleet-cross-${config.runId}`)
|
||||
const reports = resolve(outputRoot, 'reports'), output = join(reports, reportName)
|
||||
mkdirSync(reports, { recursive: true })
|
||||
const lockPath = join(reports, '.fleet-acceptance.lock'), lock = openSync(lockPath, 'wx')
|
||||
let context, picker, createdPicker, initialized = false, report, evidenceIndex = 0, requestIndex = 0
|
||||
@@ -61,14 +78,15 @@ export async function runCrossCustomer(config, { env = process.env, outputRoot =
|
||||
try {
|
||||
writeFileSync(lock, JSON.stringify({ pid: process.pid, runId: config.runId }))
|
||||
mkdirSync(output); initialized = true; mkdirSync(join(output, 'evidence')); mkdirSync(join(output, 'requests'))
|
||||
const sources = ['scripts/fleet-cross-customer-test-env.mjs', 'scripts/fleet-inventory-evidence.mjs', 'scripts/fba-core-regression-evidence.mjs',
|
||||
const sources = ['scripts/fleet-cross-customer-test-env.mjs', 'scripts/fleet-inventory-evidence.mjs', gray ? 'scripts/gray-regression-evidence.mjs' : 'scripts/fba-core-regression-evidence.mjs',
|
||||
'scripts/admin-test-env-modules/fleet-cross-customer-fixture.mjs', 'scripts/admin-test-env-modules/fleet-cross-customer-acceptance.mjs',
|
||||
'scripts/admin-test-env-modules/fleet-trip-fulfillment.mjs'].map(path => ({ path, sha256: createHash('sha256').update(readFileSync(join(ROOT, path))).digest('hex') }))
|
||||
save('manifest.json', { ...plan, sourceCommit: execFileSync('git', ['rev-parse', 'HEAD'], { cwd: ROOT, encoding: 'utf8' }).trim(), sources })
|
||||
save('manifest.json', { ...plan, runtimeProfile: env.CHONGCHONG_ENV, sourceCommit: execFileSync('git', ['rev-parse', 'HEAD'], { cwd: ROOT, encoding: 'utf8' }).trim(), sources })
|
||||
await readers.preflight()
|
||||
const options = validateExecutionOptions({ ...parseArguments(['--modules', 'merchant-qualification-fixture', '--quiet', 'true']),
|
||||
environment: 'test', gateway: base.origin, username: env.CHONGCHONG_ADMIN_USERNAME, password: env.CHONGCHONG_ADMIN_PASSWORD,
|
||||
markerNamespace: createHash('sha256').update(config.runId).digest('hex').slice(0, 12) })
|
||||
const transport = { gateway: base.origin, username: env.CHONGCHONG_ADMIN_USERNAME, password: env.CHONGCHONG_ADMIN_PASSWORD,
|
||||
output, markerNamespace: createHash('sha256').update(`${environment}:${config.runId}`).digest('hex').slice(0, 12) }
|
||||
const options = gray ? createFleetPoolGrayOptions(transport) : validateExecutionOptions({
|
||||
...parseArguments(['--modules', 'merchant-qualification-fixture', '--quiet', 'true']), ...transport, environment: 'test' })
|
||||
context = contextFactory(options)
|
||||
for (const method of ['request', 'requestWithBody']) {
|
||||
const original = context[method]
|
||||
@@ -92,7 +110,7 @@ export async function runCrossCustomer(config, { env = process.env, outputRoot =
|
||||
}
|
||||
}
|
||||
const login = await context.request('POST', '/api/auth/login', { loginId: options.username, password: options.password }, '')
|
||||
if (!ok(login) || !login.body.data?.accessToken) throw Error('TEST administrator login failed')
|
||||
if (!ok(login) || !login.body.data?.accessToken) throw Error(`${environment} administrator login failed`)
|
||||
context.token = login.body.data.accessToken; context.refreshToken = login.body.data.refreshToken
|
||||
const warehouses = await context.request('GET', '/api/platform/v1/last-leg/fleet/drivers/warehouse-options?region=OVERSEAS')
|
||||
if (!ok(warehouses) || !warehouses.body.data?.some(row => String(row.id) === config.warehouseId)) throw Error('Requested warehouse not available')
|
||||
@@ -137,6 +155,8 @@ export async function runCrossCustomer(config, { env = process.env, outputRoot =
|
||||
report.marker = context.marker; report.createdResources = context.createdResources; report.steps = context.steps
|
||||
}
|
||||
report ||= { success: false }
|
||||
report.environment = environment; report.runtimeProfile = env.CHONGCHONG_ENV
|
||||
if (gray) report.scope = 'FLEET_CAPACITY_POOL_GRAY'
|
||||
report.requestCount = requestIndex; report.inventorySnapshots = evidenceIndex; report.goalComplete = false
|
||||
try { if (initialized) save('report.json', report) } finally { closeSync(lock); unlinkSync(lockPath) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user