This commit is contained in:
2026-08-27 09:21:01 +08:00
parent 817e356c21
commit 554b6c93b7
8 changed files with 419 additions and 27 deletions
+146
View File
@@ -0,0 +1,146 @@
import { randomInt } from 'node:crypto'
import { appendFile, mkdir, writeFile } from 'node:fs/promises'
import { resolve } from 'node:path'
import process from 'node:process'
import { AcceptanceRun, parseArguments, validateExecutionOptions } from './admin-test-env-acceptance.mjs'
function argumentsMap(argv) {
const values = new Map()
for (let index = 0; index < argv.length; index += 1) {
const argument = argv[index]
if (!argument.startsWith('--')) throw new Error(`无法识别的参数: ${argument}`)
const name = argument.slice(2)
const value = argv[index + 1]
if (!value || value.startsWith('--')) throw new Error(`参数 --${name} 缺少值`)
values.set(name, value)
index += 1
}
return values
}
function positiveInteger(value, fallback, name) {
const parsed = Number(value ?? fallback)
if (!Number.isInteger(parsed) || parsed < 1) throw new Error(`${name}必须是正整数`)
return parsed
}
function increment(record, key) {
const normalized = String(key || 'UNKNOWN')
record[normalized] = Number(record[normalized] || 0) + 1
}
async function main() {
const values = argumentsMap(process.argv.slice(2))
const count = positiveInteger(values.get('count'), 8000, 'count')
const batchSize = positiveInteger(values.get('batch-size'), 100, 'batch-size')
const startIndex = positiveInteger(values.get('start-index'), 1, 'start-index')
const boxMin = positiveInteger(values.get('box-min'), 1, 'box-min')
const boxMax = positiveInteger(values.get('box-max'), 300, 'box-max')
if (boxMax < boxMin || boxMax > 300) throw new Error('箱数范围必须满足1 <= box-min <= box-max <= 300')
const customerName = values.get('customer-name') || 'IT测试'
const originWarehouseName = values.get('origin-warehouse-name') || '义乌仓'
const workerId = values.get('worker-id') || 'worker-1'
const timestamp = new Date().toISOString().replace(/\D/g, '').slice(0, 14)
const outputDirectory = resolve(values.get('output-dir') || `reports/it-test-wait-split-8000-${timestamp}`)
const journalPath = resolve(outputDirectory, 'results.jsonl')
const summaryPath = resolve(outputDirectory, 'summary.json')
const failureDirectory = resolve(outputDirectory, 'failures')
await mkdir(failureDirectory, { recursive: true })
const summary = {
workerId, customerName, originWarehouseName, requested: count, startIndex, batchSize,
boxMin, boxMax, attempted: 0, succeeded: 0, failed: 0, totalPackages: 0, totalPallets: 0,
minPackages: null, maxPackages: null, channels: {}, destinationTypes: {},
processId: process.pid, startedAt: new Date().toISOString(),
updatedAt: new Date().toISOString(), outputDirectory,
}
await writeFile(summaryPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8')
console.log(`OUTPUT_DIR=${outputDirectory}`)
for (let offset = 0; offset < count; offset += 1) {
const sequence = startIndex + offset
const packageCount = randomInt(boxMin, boxMax + 1)
const randomValue = randomInt(1, 2_147_483_647)
const batchNo = Math.floor(offset / batchSize) + 1
const planned = { event: 'planned', sequence, batchNo, packageCount, randomValue,
plannedAt: new Date().toISOString() }
await appendFile(journalPath, `${JSON.stringify(planned)}\n`, 'utf8')
let report = null
let thrown = null
try {
const options = validateExecutionOptions(parseArguments([
'--modules', 'orders,inbound-measurement',
'--customer-name', customerName,
'--origin-warehouse-name', originWarehouseName,
'--order-profile-mode', 'randomized',
'--route-mode', 'random',
'--wait-split-count', '1',
'--wait-split-package-count', String(packageCount),
'--wait-split-sequence', String(sequence),
'--wait-split-random-value', String(randomValue),
'--quiet', 'true',
]))
options.markerNamespace = workerId
report = await new AcceptanceRun(options).run()
} catch (error) {
thrown = error instanceof Error ? error.message : String(error)
}
const fixture = report?.createdResources?.waitSplitFixtures?.find?.(
(item) => Number(item.sequence) === sequence)
const completed = Boolean(fixture?.processStatus === 'WAIT_SPLIT'
&& fixture?.reviewStatus === 'APPROVED'
&& Number(fixture?.totalPackageCount) === packageCount
&& Number(fixture?.palletCount) === Math.ceil(packageCount / 30)
&& fixture?.receivingWarehouseName === originWarehouseName)
const result = {
event: 'result', sequence, batchNo, packageCount, completed,
orderId: fixture?.orderId || null, orderNo: fixture?.orderNo || null,
inboundId: fixture?.inboundId || null, inboundCode: fixture?.inboundCode || null,
palletCount: fixture?.palletCount || null,
channelCode: fixture?.channelCode || null, channelName: fixture?.channelName || null,
destinationType: fixture?.destinationType || null,
destinationWarehouseCode: fixture?.destinationWarehouseCode || null,
reportSuccess: report?.success ?? false, assertionFailures: report?.summary?.failed ?? null,
deploymentBlockers: report?.deploymentBlockers || [], error: thrown,
finishedAt: new Date().toISOString(),
}
await appendFile(journalPath, `${JSON.stringify(result)}\n`, 'utf8')
summary.attempted += 1
if (completed) {
summary.succeeded += 1
summary.totalPackages += packageCount
summary.totalPallets += Number(fixture.palletCount)
summary.minPackages = summary.minPackages === null ? packageCount : Math.min(summary.minPackages, packageCount)
summary.maxPackages = summary.maxPackages === null ? packageCount : Math.max(summary.maxPackages, packageCount)
increment(summary.channels, fixture.channelCode)
increment(summary.destinationTypes, fixture.destinationType)
} else {
summary.failed += 1
if (report) {
await writeFile(resolve(failureDirectory, `sequence-${String(sequence).padStart(5, '0')}.json`),
`${JSON.stringify(report, null, 2)}\n`, 'utf8')
}
}
summary.updatedAt = new Date().toISOString()
summary.averagePackages = summary.succeeded > 0
? Number((summary.totalPackages / summary.succeeded).toFixed(3)) : null
summary.averagePallets = summary.succeeded > 0
? Number((summary.totalPallets / summary.succeeded).toFixed(3)) : null
if (summary.attempted % batchSize === 0 || !completed || summary.attempted === count) {
await writeFile(summaryPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8')
console.log(`PROGRESS attempted=${summary.attempted}/${count} succeeded=${summary.succeeded} failed=${summary.failed} batch=${batchNo}`)
}
}
summary.finishedAt = new Date().toISOString()
await writeFile(summaryPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8')
console.log(`RESULT attempted=${summary.attempted} succeeded=${summary.succeeded} failed=${summary.failed}`)
}
main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error))
process.exitCode = 1
})