374 lines
50 KiB
JavaScript
374 lines
50 KiB
JavaScript
import EmbeddedPostgres from 'embedded-postgres'
|
|
import { runOwnedVrfProductionProfile } from './vrf-production-profile.mjs'
|
|
import { mkdtemp, rm, readFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join, resolve, relative, isAbsolute, delimiter, dirname } from 'node:path'
|
|
import { randomBytes } from 'node:crypto'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { createServer } from 'node:net'
|
|
import { spawn, execFile } from 'node:child_process'
|
|
|
|
// Explicit targeted reruns use a fresh owned regression database. They never
|
|
// claim the primary integration or terminal restore was rerun.
|
|
// Fixed groups only; ordinary full/selected regression semantics stay unchanged.
|
|
function profilesOnlyGroup(args) {
|
|
const groups = args.filter(arg => arg.startsWith('--profiles-group='))
|
|
if (!groups.length) return null
|
|
const group = groups[0].slice('--profiles-group='.length)
|
|
if (groups.length !== 1 || args.length !== 3 || !args.includes('--all') || !args.includes('--profiles-only') || !['base37', 'vrf1'].includes(group)) {
|
|
throw new Error('Fixed profile group requires exactly --all --profiles-only --profiles-group=base37|vrf1')
|
|
}
|
|
return group
|
|
}
|
|
function regressionProfiles(profiles, selected, group) {
|
|
if (group === null) return [...new Set([...profiles, 'test:logs:pg', ...(!selected ? ['test:vrf:production'] : [])])]
|
|
if (!['base37', 'vrf1'].includes(group) || selected || profiles.length !== 36 || new Set(profiles).size !== 36 || profiles.includes('test:logs:pg') || profiles.includes('test:vrf:production')) {
|
|
throw new Error('Fixed 37+1 profile coverage changed; review groups before running')
|
|
}
|
|
return group === 'base37' ? [...profiles, 'test:logs:pg'] : ['test:vrf:production']
|
|
}
|
|
// End fixed-group pure selectors.
|
|
const profilesGroup = profilesOnlyGroup(process.argv.slice(2))
|
|
const profilesOnly = process.argv.includes('--profiles-only')
|
|
if (profilesOnly && (process.argv.length !== 4 + (profilesGroup ? 1 : 0) || !process.argv.includes('--all') ||
|
|
process.argv.slice(2).some(arg => !['--all', '--profiles-only', ...(profilesGroup ? ['--profiles-group=' + profilesGroup] : [])].includes(arg)))) {
|
|
throw new Error('Profiles-only requires exactly --all --profiles-only, without restore, selected profiles or other flags')
|
|
}
|
|
const regressionOnly = process.argv.includes('--regression-only')
|
|
if (regressionOnly && (!process.argv.includes('--all') || process.argv.filter(arg => arg.startsWith('--profile=')).length !== 1 ||
|
|
process.argv.slice(2).some(arg => !['--all', '--regression-only'].includes(arg) && !arg.startsWith('--profile=')))) {
|
|
throw new Error('Regression-only requires exactly --all --regression-only --profile=<known script>, without restore or other profiles')
|
|
}
|
|
const operatorDockerSql = process.argv.includes('--operator-docker-sql')
|
|
if (operatorDockerSql && process.argv.slice(2).some(arg => arg !== '--operator-docker-sql')) throw new Error('Operator Docker SQL requires a separate disposable cluster without restore')
|
|
const pollMemoryCost = process.argv.includes('--poll-memory-cost')
|
|
const pollMemoryBootstrap = process.argv.includes('--poll-memory-bootstrap')
|
|
const pollMemory = process.argv.includes('--poll-memory') || pollMemoryCost || pollMemoryBootstrap
|
|
if (pollMemory && (process.argv.length !== 3 || process.argv[2] !== (pollMemoryBootstrap ? '--poll-memory-bootstrap' : pollMemoryCost ? '--poll-memory-cost' : '--poll-memory'))) throw new Error('Compiled poll memory requires its own disposable cluster without other profiles')
|
|
const pollMemoryEnvironment = Object.fromEntries(['SystemRoot', 'WINDIR', 'TEMP', 'TMP', 'LANG', 'LC_ALL']
|
|
.filter(key => typeof process.env[key] === 'string').map(key => [key, process.env[key]]))
|
|
const pollJournalSnapshot = process.argv.includes('--poll-journal-snapshot')
|
|
if (pollJournalSnapshot && process.argv.slice(2).some(arg => arg !== '--poll-journal-snapshot')) throw new Error('Journal snapshot lock evidence requires its own disposable cluster')
|
|
const principalSecuritySource = process.argv.includes('--principal-security-source')
|
|
if (principalSecuritySource && process.argv.slice(2).some(arg => arg !== '--principal-security-source')) throw new Error('Principal security source requires its own disposable cluster')
|
|
const pollArchiveFlags = ['--poll-terminal-archive', '--poll-terminal-archive-lost-ack', '--poll-terminal-archive-history', '--poll-terminal-archive-history-cold', '--poll-terminal-archive-claim-loss']
|
|
const chosenArchiveFlags = process.argv.slice(2).filter(arg => pollArchiveFlags.includes(arg))
|
|
const pollArchiveLostAck = chosenArchiveFlags[0] === '--poll-terminal-archive-lost-ack'
|
|
const pollArchiveCold = chosenArchiveFlags[0] === '--poll-terminal-archive-history-cold'
|
|
const pollArchiveHistory = chosenArchiveFlags[0] === '--poll-terminal-archive-history' || pollArchiveCold
|
|
const pollArchiveClaimLoss = chosenArchiveFlags[0] === '--poll-terminal-archive-claim-loss'
|
|
const pollTerminalArchive = chosenArchiveFlags.length > 0
|
|
if (pollTerminalArchive && (chosenArchiveFlags.length !== 1 || process.argv.slice(2).some(arg => ![chosenArchiveFlags[0], '--restore'].includes(arg)))) throw new Error('Poll terminal archive requires its own disposable cluster')
|
|
const pollArchiveSchema = process.argv.includes('--poll-archive-schema')
|
|
if (pollArchiveSchema && process.argv.slice(2).some(arg => arg !== '--poll-archive-schema')) throw new Error('Poll archive schema requires its own disposable cluster')
|
|
const telemetrySettingsConfiguration = process.argv.includes('--telemetry-settings-configuration')
|
|
if (telemetrySettingsConfiguration && process.argv.slice(2).some(arg => arg !== '--telemetry-settings-configuration')) throw new Error('Telemetry settings configuration requires its own disposable cluster')
|
|
const routingReservationSchema = process.argv.includes('--routing-reservation-schema')
|
|
if (routingReservationSchema && process.argv.slice(2).some(arg => arg !== '--routing-reservation-schema')) throw new Error('Routing reservation schema requires its own disposable cluster')
|
|
const routingOriginalEffects = process.argv.includes('--routing-original-effects')
|
|
const routingForwardRounds = routingOriginalEffects || process.argv.includes('--routing-network-forward-rounds')
|
|
if (routingForwardRounds && process.argv.slice(2).some(arg => arg !== (routingOriginalEffects ? '--routing-original-effects' : '--routing-network-forward-rounds'))) throw new Error('Routing forward rounds requires its own disposable cluster')
|
|
const flowActiveServices = process.argv.includes('--flow-active-services')
|
|
if (flowActiveServices && process.argv.slice(2).some(arg => arg !== '--flow-active-services')) throw new Error('Flow active services requires its own disposable cluster')
|
|
const flowActiveRebuild = process.argv.includes('--flow-active-rebuild')
|
|
if (flowActiveRebuild && process.argv.slice(2).some(arg => arg !== '--flow-active-rebuild')) throw new Error('Flow active rebuild requires its own disposable cluster')
|
|
const flowQuality = process.argv.includes('--flow-quality')
|
|
if (flowQuality && process.argv.slice(2).some(arg => arg !== '--flow-quality')) throw new Error('Flow quality requires its own disposable cluster')
|
|
const flowWorkerIpc = process.argv.includes('--flow-worker-ipc')
|
|
if (flowWorkerIpc && process.argv.slice(2).some(arg => arg !== '--flow-worker-ipc')) throw new Error('Flow worker IPC requires its own disposable cluster')
|
|
const manualUptime = process.argv.includes('--manual-uptime')
|
|
if (manualUptime && process.argv.slice(2).some(arg => arg !== '--manual-uptime')) throw new Error('Manual uptime requires its own disposable cluster')
|
|
const manualPingGroup = process.argv.includes('--manual-ping-group')
|
|
if (manualPingGroup && process.argv.slice(2).some(arg => arg !== '--manual-ping-group')) throw new Error('Manual Ping group requires its own disposable cluster')
|
|
const manualTraffic = process.argv.includes('--manual-traffic')
|
|
if (manualTraffic && process.argv.slice(2).some(arg => arg !== '--manual-traffic')) throw new Error('Manual traffic requires its own disposable cluster')
|
|
const manualApiPing = process.argv.includes('--manual-api-ping')
|
|
if (manualApiPing && process.argv.slice(2).some(arg => arg !== '--manual-api-ping')) throw new Error('Manual API Ping requires its own disposable cluster')
|
|
const simpleSpeed = process.argv.includes('--simple-speed')
|
|
if (simpleSpeed && process.argv.slice(2).some(arg => arg !== '--simple-speed')) throw new Error('Simple speed acceptance requires its own disposable cluster')
|
|
const simpleSpeedChr = process.argv.includes('--simple-speed-chr')
|
|
if (simpleSpeedChr && process.argv.slice(2).some(arg => arg !== '--simple-speed-chr')) throw new Error('Simple speed CHR acceptance requires its own disposable cluster')
|
|
const publicRegistryMetadata = process.argv.includes('--public-registry-metadata')
|
|
if (publicRegistryMetadata && process.argv.slice(2).some(arg => arg !== '--public-registry-metadata')) throw new Error('Public registry metadata requires a separate disposable cluster without restore')
|
|
const operatorPeerMetadata = process.argv.includes('--operator-peer-metadata')
|
|
if (operatorPeerMetadata && process.argv.slice(2).some(arg => arg !== '--operator-peer-metadata')) throw new Error('Operator peer metadata requires a separate disposable cluster without restore')
|
|
const externalPeerMetadata = process.argv.includes('--external-peer-metadata')
|
|
if (externalPeerMetadata && process.argv.slice(2).some(arg => arg !== '--external-peer-metadata')) throw new Error('Guarded external peer metadata requires a separate disposable cluster without restore')
|
|
const pollOperationRetirement = process.argv.includes('--poll-operation-retirement')
|
|
const ordinaryOperationRetirement = process.argv.includes('--ordinary-operation-retirement')
|
|
const probeOperationRetirement = process.argv.includes('--probe-operation-retirement')
|
|
const mcpOperationOrigin = process.argv.includes('--mcp-operation-origin') || pollOperationRetirement || ordinaryOperationRetirement || probeOperationRetirement
|
|
if (mcpOperationOrigin && process.argv.slice(2).some(arg => arg !== (probeOperationRetirement ? '--probe-operation-retirement' : ordinaryOperationRetirement ? '--ordinary-operation-retirement' : pollOperationRetirement ? '--poll-operation-retirement' : '--mcp-operation-origin'))) throw new Error('MCP operation root requires a separate disposable cluster without restore')
|
|
const mcpSpeedOriginal = process.argv.includes('--mcp-speed-original')
|
|
if (mcpSpeedOriginal && process.argv.slice(2).some(arg => arg !== '--mcp-speed-original')) throw new Error('MCP speed component requires a separate disposable cluster without restore')
|
|
const routerConfigurationGuard = process.argv.includes('--router-configuration-guard')
|
|
if (routerConfigurationGuard && process.argv.slice(2).some(arg => arg !== '--router-configuration-guard')) throw new Error('Router configuration guard requires a separate disposable cluster without restore')
|
|
const scheduledSpeedOriginal = process.argv.includes('--scheduled-speed-original')
|
|
if (scheduledSpeedOriginal && process.argv.slice(2).some(arg => arg !== '--scheduled-speed-original')) throw new Error('Scheduled speed origin requires a separate disposable cluster without restore')
|
|
const bandwidthSpeedWorkflow = process.argv.includes('--bandwidth-speed-workflow')
|
|
if (bandwidthSpeedWorkflow && process.argv.slice(2).some(arg => arg !== '--bandwidth-speed-workflow')) throw new Error('Whole speed workflow requires its own disposable cluster; restore is not implemented')
|
|
const restSpeedOriginal = process.argv.includes('--rest-speed-original')
|
|
if (restSpeedOriginal && process.argv.slice(2).some(arg => arg !== '--rest-speed-original')) throw new Error('REST speed origin acceptance requires its own disposable cluster; restore is not implemented for this profile')
|
|
const operationLocks = process.argv.includes('--operation-locks')
|
|
const serviceExecutionOrigin = process.argv.includes('--service-execution-origin')
|
|
const bandwidthNodeSource = process.argv.includes('--bandwidth-node-source')
|
|
const bandwidthExternalRegistry = process.argv.includes('--bandwidth-external-registry')
|
|
if (bandwidthExternalRegistry && process.argv.slice(2).some(arg => arg !== '--bandwidth-external-registry')) throw new Error('External registry acceptance requires its own disposable cluster; restore is not implemented for this profile')
|
|
const bandwidthNodeRegistry = process.argv.includes('--bandwidth-node-registry')
|
|
const bandwidthControlSource = process.argv.includes('--bandwidth-control-source')
|
|
const bandwidthAdmission = process.argv.includes('--bandwidth-admission')
|
|
const diagnosticCancelHost = process.argv.includes('--diagnostic-cancel-host')
|
|
const ipsecExportHttp = process.argv.includes('--ipsec-export-http')
|
|
const ipsecExportJournal = process.argv.includes('--ipsec-export-journal')
|
|
const routingRecoveryAuthority = process.argv.includes('--routing-recovery-authority')
|
|
const legacyFlowRebuild = process.argv.includes('--legacy-flow-rebuild')
|
|
const serverPollStorageFresh = process.argv.includes('--server-poll-storage-fresh')
|
|
const serverPollStorage = process.argv.includes('--server-poll-storage')
|
|
const serverPollDurable = process.argv.includes('--server-poll-durable')
|
|
const collectorPartitionWriters = process.argv.includes('--collector-partition-writers')
|
|
const routingReservations = process.argv.includes('--routing-reservations')
|
|
const routingReservationRuntime = process.argv.includes('--routing-reservation-runtime')
|
|
const routingNetworkNative = process.argv.includes('--routing-network-native')
|
|
const migrationDataInventory = process.argv.includes('--migration-data-inventory')
|
|
const migrationSchemaInventory = process.argv.includes('--migration-schema-inventory')
|
|
const databaseSchemaControl = process.argv.includes('--database-schema-control')
|
|
const controlledMigrations = process.argv.includes('--controlled-migrations')
|
|
const controlledSchemaReference = process.argv.includes('--controlled-schema-reference')
|
|
const probeStorageHistory = process.argv.includes('--probe-storage-history')
|
|
const probeStorageJournal = process.argv.includes('--probe-storage-journal')
|
|
const probeLegacyOrphans = process.argv.includes('--probe-legacy-orphans')
|
|
const probeStorageFresh = process.argv.includes('--probe-storage-fresh')
|
|
for (const [selected, flag] of [[operationLocks, '--operation-locks'], [serviceExecutionOrigin, '--service-execution-origin'], [bandwidthNodeSource, '--bandwidth-node-source'], [bandwidthNodeRegistry, '--bandwidth-node-registry'], [bandwidthExternalRegistry, '--bandwidth-external-registry'], [bandwidthControlSource, '--bandwidth-control-source'], [bandwidthAdmission, '--bandwidth-admission'], [serverPollStorageFresh, '--server-poll-storage-fresh'], [serverPollStorage, '--server-poll-storage'], [diagnosticCancelHost, '--diagnostic-cancel-host'], [ipsecExportHttp, '--ipsec-export-http'], [ipsecExportJournal, '--ipsec-export-journal'], [routingRecoveryAuthority, '--routing-recovery-authority'], [legacyFlowRebuild, '--legacy-flow-rebuild'], [serverPollDurable, '--server-poll-durable'], [collectorPartitionWriters, '--collector-partition-writers'], [routingReservations, '--routing-reservations'], [routingReservationRuntime, '--routing-reservation-runtime'], [routingNetworkNative, '--routing-network-native'], [migrationDataInventory, '--migration-data-inventory'], [migrationSchemaInventory, '--migration-schema-inventory'], [databaseSchemaControl, '--database-schema-control'], [controlledMigrations, '--controlled-migrations'], [controlledSchemaReference, '--controlled-schema-reference'], [probeStorageHistory, '--probe-storage-history'], [probeStorageJournal, '--probe-storage-journal'], [probeLegacyOrphans, '--probe-legacy-orphans'], [probeStorageFresh, '--probe-storage-fresh']]) {
|
|
if (selected && process.argv.slice(2).some(arg => ![flag, '--restore'].includes(arg))) throw new Error('Focused writer/recovery acceptance requires a separate disposable run')
|
|
}
|
|
const probeJournal = process.argv.includes('--server-probe-journal')
|
|
if (probeJournal && process.argv.slice(2).some(arg => !['--server-probe-journal', '--restore'].includes(arg))) throw new Error('Server probe journal acceptance requires a separate disposable run')
|
|
const flowHostKeys = process.argv.includes('--flow-host-keys')
|
|
if (flowHostKeys && process.argv.slice(2).some(arg => !['--flow-host-keys','--restore'].includes(arg))) throw new Error('Host keys acceptance requires a separate disposable run')
|
|
const flowRebuildMcp = process.argv.includes('--flow-rebuild-mcp')
|
|
if (flowRebuildMcp && process.argv.slice(2).some(arg => arg !== '--flow-rebuild-mcp')) throw new Error('MCP flow rebuild acceptance requires a separate disposable run')
|
|
const flowRebuild = process.argv.includes('--flow-rebuild')
|
|
if (flowRebuild && process.argv.slice(2).some(arg => arg !== '--flow-rebuild')) throw new Error('Flow rebuild SQL acceptance requires a separate disposable run')
|
|
const flowWrites = process.argv.includes('--flow-writes')
|
|
if (flowWrites && process.argv.slice(2).some(arg => arg !== '--flow-writes')) throw new Error('Flow writer SQL acceptance requires a separate disposable run')
|
|
const chrGreMutation = process.argv.includes('--chr-gre-mutation')
|
|
const chrGreRevision = process.argv.includes('--chr-gre-revision')
|
|
const chrGreRevisionRecovery = process.argv.includes('--chr-gre-revision-recovery')
|
|
const chrRead = process.argv.includes('--chr-read')
|
|
const chrIdentity = process.argv.includes('--chr-ospf-identity-read')
|
|
const chrRecursive = process.argv.includes('--chr-recursive-restore')
|
|
const chrFirewallRestore = process.argv.includes('--chr-firewall-restore')
|
|
const chrAddress = process.argv.includes('--chr-address-list')
|
|
const chrFirewallWrite = process.argv.includes('--chr-firewall-write')
|
|
const chrFirewallMove = process.argv.includes('--chr-firewall-move')
|
|
const chrVpn = process.argv.includes('--chr-vpn-catalog')
|
|
const chrFilters = process.argv.includes('--chr-filter-write')
|
|
const chrLegacyOspf = process.argv.includes('--chr-ospf-legacy')
|
|
const greRevision = process.argv.includes('--gre-revision')
|
|
const applicationAdapters = process.argv.includes('--application-adapters')
|
|
const scopedRoutingDiagnostics = process.argv.includes('--scoped-routing-diagnostics')
|
|
const interfaceEventsCompatibility = process.argv.includes('--interface-events-compatibility')
|
|
const wireguardExport = process.argv.includes('--wireguard-export')
|
|
if (wireguardExport && process.argv.includes('--wireguard-transfer')) throw new Error('Choose WireGuard transfer or export acceptance mode')
|
|
const wireguardTransfer = process.argv.includes('--wireguard-transfer') || wireguardExport
|
|
const scopedCheckpointAdapters = process.argv.includes('--scoped-checkpoint-adapters')
|
|
const nativeConservation = process.argv.includes('--native-conservation')
|
|
const nativeCreateId = process.argv.includes('--native-create-id')
|
|
const moduleCompletion = process.argv.includes('--module-completion')
|
|
const completionTarget = process.argv.find(arg => arg.startsWith('--only='))?.slice(7) ?? 'all'
|
|
if (!['all','wireguard','ipsec-init','ipsec-restore','ipsec-delete','ipsec-create','vrf'].includes(completionTarget) || (completionTarget !== 'all' && !moduleCompletion)) throw new Error('Unknown isolated module target')
|
|
if (moduleCompletion && process.argv.slice(2).some(arg => !['--module-completion', '--restore', `--only=${completionTarget}`].includes(arg))) throw new Error('Module completion acceptance requires a separate disposable run')
|
|
const ipsecAdapters = process.argv.includes('--ipsec-adapters') || moduleCompletion
|
|
if (nativeCreateId && (ipsecAdapters || process.argv.includes('--recovery-maintenance'))) throw new Error('Choose native CREATE ID or another focused acceptance mode')
|
|
if (ipsecAdapters && process.argv.includes('--recovery-maintenance')) throw new Error('Choose IPsec adapters or recovery maintenance acceptance mode')
|
|
if (nativeConservation && (nativeCreateId || ipsecAdapters || process.argv.includes('--recovery-maintenance'))) throw new Error('Choose native conservation or another focused acceptance mode')
|
|
const recoveryMaintenance = process.argv.includes('--recovery-maintenance') || ipsecAdapters || nativeCreateId || nativeConservation
|
|
if (Number(chrGreMutation) + Number(chrGreRevision) + Number(chrGreRevisionRecovery) + Number(chrFirewallRestore) + Number(chrAddress) + Number(chrFirewallWrite) + Number(chrRead) + Number(chrIdentity) + Number(chrRecursive) + Number(chrFirewallMove) + Number(chrVpn) + Number(chrFilters) + Number(chrLegacyOspf) + Number(process.argv.includes('--chr')) > 1) throw new Error('Choose exactly one CHR acceptance mode')
|
|
const chr = process.argv.includes('--chr') || chrGreMutation || chrGreRevision || chrGreRevisionRecovery || chrFirewallRestore || chrAddress || chrFirewallWrite || chrRead || chrIdentity || chrRecursive || chrFirewallMove || chrVpn || chrFilters || chrLegacyOspf
|
|
if (recoveryMaintenance && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics || interfaceEventsCompatibility || wireguardTransfer || scopedCheckpointAdapters)) throw new Error('Recovery maintenance SQL/HTTP mode cannot run with another focused mode')
|
|
if (scopedCheckpointAdapters && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics || interfaceEventsCompatibility || wireguardTransfer)) throw new Error('Scoped checkpoint SQL/HTTP mode cannot run with another focused mode')
|
|
if (wireguardTransfer && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics || interfaceEventsCompatibility)) throw new Error('WireGuard transfer SQL/HTTP mode cannot run with another focused mode')
|
|
if (interfaceEventsCompatibility && (chr || greRevision || applicationAdapters || scopedRoutingDiagnostics)) throw new Error('Interface events SQL/HTTP mode cannot run with other focused modes')
|
|
if (scopedRoutingDiagnostics && (chr || greRevision || applicationAdapters)) throw new Error('Scoped routing SQL/HTTP mode cannot run with other focused modes')
|
|
if (applicationAdapters && (chr || greRevision)) throw new Error('Application SQL/HTTP mode cannot run with other focused modes')
|
|
if (greRevision && chr) throw new Error('GRE revision SQL/HTTP mode cannot run with CHR acceptance')
|
|
if (chr) {
|
|
if (!process.env.MMAPP_TEST_CHR_HOSTS || !process.env.MMAPP_TEST_CHR_USER) throw new Error('CHR hosts and user must be explicitly configured')
|
|
if (!process.env.MMAPP_TEST_CHR_PASSWORD) {
|
|
if (!process.stdin.isTTY) throw new Error('Use a terminal for the private CHR password prompt')
|
|
process.stdout.write('CHR password (hidden): ')
|
|
process.env.MMAPP_TEST_CHR_PASSWORD = await new Promise((resolve, reject) => {
|
|
let value = ''
|
|
const timer = setTimeout(() => finish(new Error('Password input timed out')), 60000)
|
|
const finish = error => {
|
|
clearTimeout(timer); process.stdin.off('data', read); process.stdin.setRawMode(false); process.stdin.pause(); process.stdout.write('\n')
|
|
if (error) reject(error); else resolve(value)
|
|
}
|
|
const read = chunk => {
|
|
for (const character of chunk.toString()) {
|
|
if (character === '\r' || character === '\n') { finish(); return }
|
|
if (character === '\u0003') { finish(new Error('Cancelled')); return }
|
|
if (character === '\u007f' || character === '\b') value = value.slice(0, -1)
|
|
else value += character
|
|
}
|
|
}
|
|
process.stdin.setRawMode(true); process.stdin.resume(); process.stdin.on('data', read)
|
|
})
|
|
}
|
|
}
|
|
|
|
// A private disposable cluster: never reads backend/.env or the application DB.
|
|
const directory = await mkdtemp(join(tmpdir(), 'mm-mcp-test-'))
|
|
const listener = createServer()
|
|
await new Promise(resolve => listener.listen(0, '127.0.0.1', resolve))
|
|
const port = listener.address().port
|
|
await new Promise(resolve => listener.close(resolve))
|
|
const password = randomBytes(24).toString('hex')
|
|
const postgres = new EmbeddedPostgres({ databaseDir: join(directory, 'pg'), port, user: 'mcp_test', password,
|
|
persistent: true, createPostgresUser: false, initdbFlags: ['--encoding=UTF8'], postgresFlags: ['-h', '127.0.0.1'],
|
|
onLog: () => {}, onError: () => {} })
|
|
let exitCode = 1
|
|
let vrfChildrenExitConfirmed = true
|
|
try {
|
|
await postgres.initialise()
|
|
await postgres.start()
|
|
const binaries = await import(`@embedded-postgres/${process.platform === 'win32' ? 'windows' : process.platform}-${process.arch}`)
|
|
const testPath = [process.env.MMAPP_PG_CLIENT_BIN, dirname(binaries.postgres), process.env.PATH ?? process.env.Path ?? ''].filter(Boolean).join(delimiter)
|
|
if (!profilesOnly && (process.argv.includes('--restore') || process.env.MMAPP_PG_CLIENT_BIN)) {
|
|
for (const command of ['pg_dump', 'pg_restore']) await new Promise((resolve, reject) => {
|
|
execFile(command, ['--version'], { env: { ...process.env, PATH: testPath }, windowsHide: true, timeout: 5000, maxBuffer: 4096 }, error => {
|
|
if (error) reject(new Error(`Restore acceptance requires working ${command}; set MMAPP_PG_CLIENT_BIN to the PostgreSQL client bin directory`))
|
|
else resolve()
|
|
})
|
|
})
|
|
console.log('PostgreSQL restore client tools preflight PASS')
|
|
}
|
|
if (regressionOnly) console.log('Selected regression only: primary integration and terminal restore are not run')
|
|
if (profilesOnly) console.log('Profiles-only regression matrix: primary integration NOT RUN; terminal restore NOT RUN; full acceptance is not claimed')
|
|
const result = regressionOnly || profilesOnly ? 0 : await new Promise((resolve, reject) => {
|
|
const child = spawn(process.execPath, pollMemory ? ['--max-old-space-size=192', '--max-semi-space-size=16', fileURLToPath(new URL('../dist-mcp-memory/services/server-poll-memory.owned.test.js', import.meta.url))] : ['--import', 'tsx', principalSecuritySource ? 'src/modules/mcp/principal-security-source.owned.test.ts' : pollJournalSnapshot ? 'src/services/server-poll-journal-snapshot.owned.test.ts' : pollTerminalArchive ? 'src/services/server-poll-terminal-archive.owned.test.ts' : pollArchiveSchema ? 'src/db/server-poll-terminal-archives.sql.test.ts' : telemetrySettingsConfiguration ? 'src/modules/mcp/telemetry-settings-configuration.owned.test.ts' : routingReservationSchema ? 'src/db/routing-reservation-schema.owned.test.ts' : routingForwardRounds ? 'src/modules/mcp/routing-network-forward-rounds.owned.test.ts' : flowActiveServices ? 'src/services/traffic-flow-active-services.owned.test.ts' : flowActiveRebuild ? 'src/services/traffic-flow-active-rebuild.owned.test.ts' : flowQuality ? 'src/services/traffic-flow-quality.owned.test.ts' : flowWorkerIpc ? 'src/services/traffic-flow-worker-ipc.owned.test.ts' : manualUptime ? 'src/modules/mcp/manual-uptime-http.test.ts' : manualPingGroup ? 'src/modules/mcp/manual-ping-group-http.test.ts' : manualTraffic ? 'src/modules/mcp/manual-traffic-http.test.ts' : manualApiPing ? 'src/modules/mcp/manual-api-ping-http.test.ts' : simpleSpeedChr ? 'src/modules/mcp/simple-speed-chr.test.ts' : simpleSpeed ? 'src/modules/mcp/simple-speed-http.test.ts' : externalPeerMetadata ? 'src/services/bandwidth-external-peer-metadata.sql.test.ts' : operatorPeerMetadata ? 'src/services/bandwidth-operator-metadata.sql.test.ts' : publicRegistryMetadata ? 'src/services/bandwidth-public-registry.sql.test.ts' : operatorDockerSql ? 'src/services/bandwidth-operator-docker-stop.sql.test.ts' : probeOperationRetirement ? 'src/services/server-probe-operation-retirement.owned.test.ts' : ordinaryOperationRetirement ? 'src/modules/mcp/ordinary-operation-retirement.owned.test.ts' : pollOperationRetirement ? 'src/services/server-poll-operation-retirement.owned.test.ts' : mcpOperationOrigin ? 'src/modules/mcp/operation-execution-origin.sql.test.ts' : mcpSpeedOriginal ? 'src/modules/mcp/speed-bandwidth-original.sql.test.ts' : routerConfigurationGuard ? 'src/services/router-configuration-guard.sql.test.ts' : scheduledSpeedOriginal ? 'src/services/bandwidth-scheduled-speed-original.sql.test.ts' : bandwidthSpeedWorkflow ? 'src/services/bandwidth-speed-workflow.sql.test.ts' : restSpeedOriginal ? 'src/services/bandwidth-rest-speed-original.sql.test.ts' : operationLocks ? 'src/services/operation-config-lock-lease.sql.test.ts' : serviceExecutionOrigin ? 'src/modules/mcp/service-execution-origin.sql.test.ts' : bandwidthNodeSource ? 'src/services/bandwidth-node-source.sql.test.ts' : bandwidthExternalRegistry ? 'src/services/bandwidth-external-node-registry.sql.test.ts' : bandwidthNodeRegistry ? 'src/services/bandwidth-node-registry.sql.test.ts' : bandwidthControlSource ? 'src/services/bandwidth-control-source.sql.test.ts' : bandwidthAdmission ? 'src/services/bandwidth-admission.sql.test.ts' : serverPollStorageFresh ? 'src/services/server-poll-storage-fresh.sql.test.ts' : serverPollStorage ? 'src/services/server-poll-storage.sql.test.ts' : probeStorageFresh ? 'src/services/server-probe-storage-fresh.sql.test.ts' : probeLegacyOrphans ? 'src/services/server-probe-legacy-orphans.sql.test.ts' : diagnosticCancelHost ? 'src/modules/mcp/diagnostic-cancellation-storage.sql.test.ts' : ipsecExportHttp ? 'src/modules/mcp/ipsec-existing-certificate-export-http.sql.test.ts' : ipsecExportJournal ? 'src/services/ipsec-existing-certificate-export-rest-journal.sql.test.ts' : migrationDataInventory ? 'src/db/migration-data-inventory.sql.test.ts' : probeStorageHistory ? 'src/services/server-probe-storage-history.sql.test.ts' : probeStorageJournal ? 'src/services/server-probe-storage-journal.sql.test.ts' : controlledSchemaReference ? 'src/db/controlled-schema-reference.sql.test.ts' : controlledMigrations ? 'src/db/controlled-migrations.sql.test.ts' : databaseSchemaControl ? 'src/db/database-schema-control.sql.test.ts' : migrationSchemaInventory ? 'src/db/migration-schema-inventory.sql.test.ts' : routingNetworkNative ? 'src/modules/mcp/routing-network-native.sql.test.ts' : routingReservationRuntime ? 'src/modules/mcp/routing-reservation-runtime.sql.test.ts' : routingReservations ? 'src/modules/mcp/routing-reservation.sql.test.ts' : collectorPartitionWriters ? 'src/services/collector-partition-writes.sql.test.ts' : serverPollDurable ? 'src/services/server-poll-durable-session.sql.test.ts' : routingRecoveryAuthority ? 'src/modules/mcp/routing-recovery-authority.sql.test.ts' : legacyFlowRebuild ? 'src/test/legacy-flow-rebuild-sql.ts' : probeJournal ? 'src/services/server-probe-journal.sql.test.ts' : flowHostKeys ? 'src/modules/mcp/flow-host-keys-http.test.ts' : flowRebuildMcp ? 'src/modules/mcp/flow-facts-rebuild-http.test.ts' : flowRebuild ? 'src/test/flow-facts-rebuild-sql.ts' : flowWrites ? 'src/services/traffic-flow-write-transaction.pg.test.ts' : nativeConservation ? 'src/modules/mcp/native-conservation-sql.test.ts' : nativeCreateId ? 'src/modules/mcp/native-create-id-http.test.ts' : ipsecAdapters ? "src/modules/mcp/ipsec-adapters-http.test.ts" : recoveryMaintenance ? "src/modules/mcp/recovery-maintenance-http.test.ts" : scopedCheckpointAdapters ? "src/modules/mcp/scoped-checkpoint-adapters-http.test.ts" : wireguardTransfer ? 'src/modules/mcp/wireguard-transfer-http.test.ts' : interfaceEventsCompatibility ? 'src/modules/mcp/interface-events-compatibility-http.test.ts' : scopedRoutingDiagnostics ? 'src/modules/mcp/scoped-routing-diagnostics-http.test.ts' : applicationAdapters ? 'src/modules/mcp/application-adapters-http.test.ts' : greRevision ? 'src/modules/mcp/gre-revision-http.test.ts' : chrGreRevisionRecovery ? 'src/modules/mcp/chr-gre-revision-recovery.test.ts' : chrGreRevision ? 'src/modules/mcp/chr-gre-revision.test.ts' : chrLegacyOspf ? 'src/modules/mcp/chr-ospf-legacy.test.ts' : chrFilters ? 'src/modules/mcp/chr-filter-write.test.ts' : chrGreMutation ? 'src/modules/mcp/chr-gre-mutation.test.ts' : chrFirewallRestore ? 'src/modules/mcp/chr-firewall-restore.test.ts' : chrAddress ? 'src/modules/mcp/chr-address-list.test.ts' : chrFirewallWrite ? 'src/modules/mcp/chr-firewall-write.test.ts' : chrVpn ? 'src/modules/mcp/chr-vpn-catalog.test.ts' : chrFirewallMove ? 'src/modules/mcp/chr-firewall-move.test.ts' : chrRecursive ? 'src/modules/mcp/chr-recursive-restore.test.ts' : chrIdentity ? 'src/modules/mcp/chr-ospf-identity-readonly.test.ts' : chrRead ? 'src/modules/mcp/chr-readonly-acceptance.test.ts' : chr ? 'src/modules/mcp/chr-acceptance.test.ts' : 'src/modules/mcp/integration.test.ts'], {
|
|
cwd: pollMemory ? directory : new URL('../', import.meta.url), stdio: 'inherit', env: { ...(pollMemory ? pollMemoryEnvironment : process.env),
|
|
...(routingOriginalEffects ? { MMAPP_OWN_ROUTING_ORIGINAL_EFFECTS: 'true' } : {}),
|
|
DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres`,
|
|
DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false',
|
|
MCP_STATE_DIR: join(directory, 'state'), AUTH_REQUIRED: 'true', AUTH_JWT_SECRET: 'mcp-integration-test-only', MMAPP_TEST_WG_EXPORT_ONLY: String(wireguardExport),
|
|
MCP_PUBLIC_URL: 'http://localhost:8000/mcp', NODE_ENV: 'test', PATH: testPath, NODE_OPTIONS: pollMemory ? '' : process.env.NODE_OPTIONS, MMAPP_OWN_PRINCIPAL_SECURITY_SOURCE: String(principalSecuritySource), MMAPP_OWN_POLL_JOURNAL_SNAPSHOT: String(pollJournalSnapshot), MMAPP_OWN_POLL_MEMORY: String(pollMemory), MMAPP_OWN_POLL_BOOTSTRAP: String(pollMemoryBootstrap), MMAPP_OWN_POLL_COST_DIAGNOSTICS: String(pollMemoryCost), MMAPP_OWN_POLL_ARCHIVE_CLAIM_LOSS: String(pollArchiveClaimLoss), MMAPP_OWN_POLL_ARCHIVE_HISTORY: String(pollArchiveHistory), MMAPP_OWN_POLL_ARCHIVE_COLD: String(pollArchiveCold), MMAPP_OWN_POLL_ARCHIVE_LOST_ACK: String(pollArchiveLostAck), MMAPP_OWN_POLL_TERMINAL_ARCHIVE: String(pollTerminalArchive), MMAPP_OWN_POLL_ARCHIVE_SCHEMA: String(pollArchiveSchema), MMAPP_OWN_TELEMETRY_SETTINGS_CONFIGURATION: String(telemetrySettingsConfiguration), MMAPP_OWN_ROUTING_RESERVATION_SCHEMA: String(routingReservationSchema), MMAPP_OWN_ROUTING_FORWARD_ROUNDS: String(routingForwardRounds), MMAPP_OWN_FLOW_ACTIVE_SERVICES: String(flowActiveServices), MMAPP_OWN_FLOW_ACTIVE_REBUILD: String(flowActiveRebuild), MMAPP_OWN_FLOW_QUALITY: String(flowQuality), MMAPP_OWN_FLOW_WORKER_IPC: String(flowWorkerIpc), MMAPP_OWN_MANUAL_UPTIME: String(manualUptime), MMAPP_OWN_MANUAL_PING_GROUP: String(manualPingGroup), MMAPP_OWN_MANUAL_TRAFFIC: String(manualTraffic), MMAPP_OWN_MANUAL_API_PING: String(manualApiPing), MMAPP_OWN_SIMPLE_SPEED: String(simpleSpeed), MMAPP_OWN_SIMPLE_SPEED_CHR: String(simpleSpeedChr), MMAPP_OWN_DIAGNOSTIC_CANCEL_HOST: String(diagnosticCancelHost), MMAPP_OWN_OPERATOR_DOCKER_SQL: String(operatorDockerSql), MMAPP_OWN_PUBLIC_REGISTRY_METADATA: String(publicRegistryMetadata), MMAPP_OWN_OPERATOR_PEER_METADATA: String(operatorPeerMetadata), MMAPP_OWN_EXTERNAL_PEER_METADATA: String(externalPeerMetadata), MMAPP_OWN_BANDWIDTH_EXTERNAL_REGISTRY: String(externalPeerMetadata || operatorPeerMetadata || publicRegistryMetadata || operatorDockerSql || mcpSpeedOriginal || bandwidthSpeedWorkflow || bandwidthExternalRegistry), MMAPP_OWN_BANDWIDTH_SPEED_WORKFLOW: String(bandwidthSpeedWorkflow), MMAPP_OWN_REST_SPEED_ORIGINAL: String(restSpeedOriginal), MMAPP_OWN_MCP_OPERATION_ORIGIN: String(mcpOperationOrigin), MMAPP_OWN_PROBE_OPERATION_RETIREMENT: String(probeOperationRetirement), MMAPP_OWN_MCP_SPEED_ORIGINAL: String(mcpSpeedOriginal), MMAPP_OWN_SCHEDULED_SPEED_ORIGINAL: String(scheduledSpeedOriginal), MMAPP_TEST_ROUTER_GUARD_OWNED: String(routerConfigurationGuard), MMAPP_TEST_ROUTER_GUARD_CLUSTER_DISPOSABLE: String(routerConfigurationGuard), MMAPP_TEST_ROUTER_GUARD_ADMIN_URL: routerConfigurationGuard ? `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres` : '', MMAPP_OWN_BANDWIDTH_ADMISSION: String(externalPeerMetadata || operatorPeerMetadata || publicRegistryMetadata || operatorDockerSql || mcpOperationOrigin || mcpSpeedOriginal || scheduledSpeedOriginal || bandwidthSpeedWorkflow || restSpeedOriginal || bandwidthExternalRegistry || operationLocks || serviceExecutionOrigin || bandwidthAdmission || bandwidthControlSource || bandwidthNodeRegistry || bandwidthNodeSource), MMAPP_OWN_BANDWIDTH_RESTORE: String((bandwidthAdmission || bandwidthControlSource || bandwidthNodeRegistry || bandwidthNodeSource) && process.argv.includes('--restore')), MMAPP_OWN_IPSEC_EXPORT_HTTP: String(ipsecExportHttp), MMAPP_OWN_IPSEC_EXPORT_JOURNAL: String(ipsecExportJournal), MMAPP_OWN_SQL_DB: 'postgres', MMAPP_OWN_PROBE_LEGACY_ORPHANS: String(probeLegacyOrphans), MMAPP_OWN_PROBE_STORAGE_HISTORY: String(probeStorageHistory), MMAPP_OWN_PROBE_STORAGE_FRESH: String(probeStorageFresh), MMAPP_OWN_PROBE_STORAGE_JOURNAL: String(probeStorageJournal || probeStorageFresh), MMAPP_OWN_CONTROLLED_SCHEMA_REFERENCE: String(controlledSchemaReference), MMAPP_OWN_CONTROLLED_MIGRATIONS: String(controlledMigrations), MMAPP_OWN_DATABASE_SCHEMA_CONTROL: String(databaseSchemaControl), MMAPP_OWN_MIGRATION_DATA_INVENTORY: String(migrationDataInventory), MMAPP_OWN_MIGRATION_SCHEMA_INVENTORY: String(migrationSchemaInventory), MMAPP_OWN_ROUTING_NETWORK_NATIVE: String(routingNetworkNative), MMAPP_OWN_ROUTING_RESERVATIONS: String(routingReservations || routingReservationRuntime), MMAPP_OWN_COLLECTOR_PARTITION_WRITERS: String(collectorPartitionWriters), MMAPP_OWN_SERVER_POLL_STORAGE_FRESH: String(serverPollStorageFresh), MMAPP_OWN_SERVER_POLL_STORAGE: String(serverPollStorage), MMAPP_OWN_SERVER_POLL_DURABLE: String(serverPollDurable), MMAPP_OWN_ROUTING_RECOVERY_AUTHORITY: String(routingRecoveryAuthority), MMAPP_OWN_LEGACY_FLOW_REBUILD: String(legacyFlowRebuild), MMAPP_OWN_PROBE_JOURNAL: String(probeJournal), MMAPP_MODULE_COMPLETION_ONLY: String(moduleCompletion), MMAPP_MODULE_COMPLETION_TARGET: completionTarget, MMAPP_OWN_FLOW_HOST_KEYS: String(flowHostKeys), MMAPP_OWN_MCP_FLOW_REBUILD: String(flowRebuildMcp), MMAPP_OWN_FLOW_WRITES: String(flowWrites), MMAPP_OWN_FLOW_REBUILD: String(flowRebuild) },
|
|
})
|
|
child.once('error', reject); child.once('exit', code => resolve(code ?? 1))
|
|
})
|
|
exitCode = result
|
|
if (result === 0 && !regressionOnly && !profilesOnly && !pollMemory && !principalSecuritySource && !pollJournalSnapshot && !pollArchiveSchema && !telemetrySettingsConfiguration && !routingReservationSchema && !routingForwardRounds && !flowActiveServices && !flowActiveRebuild && !flowQuality && !flowWorkerIpc && !manualUptime && !manualPingGroup && !manualTraffic && !manualApiPing && !simpleSpeed && !simpleSpeedChr && !externalPeerMetadata && !operatorPeerMetadata && !publicRegistryMetadata && !operatorDockerSql && !mcpOperationOrigin && !mcpSpeedOriginal && !routerConfigurationGuard && !scheduledSpeedOriginal && !bandwidthSpeedWorkflow && !restSpeedOriginal && !operationLocks && !serviceExecutionOrigin && !bandwidthNodeSource && !bandwidthNodeRegistry && !bandwidthExternalRegistry && !bandwidthControlSource && !bandwidthAdmission && !probeLegacyOrphans && !probeStorageJournal && !probeStorageHistory && !probeJournal && !chr && !flowWrites && !flowRebuild && !flowRebuildMcp && (process.argv.includes('--restore') || process.env.MMAPP_PG_CLIENT_BIN)) {
|
|
exitCode = await new Promise((resolve, reject) => {
|
|
const child = spawn(process.execPath, ['--import', 'tsx', 'src/modules/mcp/database-restore.test.ts'], {
|
|
cwd: new URL('../', import.meta.url), stdio: 'inherit', env: { ...process.env,
|
|
DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres`,
|
|
DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false',
|
|
MCP_STATE_DIR: join(directory, 'state'), AUTH_REQUIRED: 'true', AUTH_JWT_SECRET: 'mcp-integration-test-only',
|
|
MCP_PUBLIC_URL: 'http://localhost:8000/mcp', NODE_ENV: 'test', PATH: testPath,
|
|
MMAPP_OWN_SQL_DB: 'postgres', MMAPP_OWN_TERMINAL_RESTORE: 'true', MMAPP_OWN_TERMINAL_DATA_EQUIVALENCE: String(migrationDataInventory) },
|
|
})
|
|
child.once('error', reject); child.once('exit', code => resolve(code ?? 1))
|
|
})
|
|
}
|
|
else if (result === 0 && pollArchiveSchema) console.log('Poll archive schema: owned nonempty40 preservation, numbered41 and structural refusal guards; no positive MCP archive claim')
|
|
else if (result === 0 && telemetrySettingsConfiguration) console.log('Telemetry settings: genuine MCP/SQL configuration binding, collector metadata tolerated; no native or external sources')
|
|
else if (result === 0 && routingReservationSchema) console.log('Routing reservation numbered0040: ownSQL fresh/legacy/manual preservation; no READY, backfill, capabilities or public native activation')
|
|
else if (result === 0 && routingOriginalEffects) console.log('Routing original effects: approved manual revision 2 and original effects checked against disposable PostgreSQL and synthetic RouterOS HTTP')
|
|
else if (result === 0 && routingForwardRounds) console.log('Routing forward rounds: genuine approved running CONFIG_APPLIED, shared cumulative native budget; logs/security/autoRecovery remain unaccepted')
|
|
else if (result === 0 && flowActiveServices) console.log('Flow active settings/purge: production services and main Worker; disposable SQL/localhost only')
|
|
else if (result === 0 && flowActiveRebuild) console.log('Flow active rebuild: production shared service and genuine Worker drain; disposable SQL/localhost only')
|
|
else if (result === 0 && flowQuality) console.log('Flow quality: production engine and genuine receipt SQL, explicit COMMIT ACK fault on owned cluster only; no CHR/whole-installation RAM claim')
|
|
else if (result === 0 && flowWorkerIpc) console.log('Flow worker IPC: production main/Worker lifecycle, localhost UDP, owned PostgreSQL only; real CHR and concurrent-spawn acceptance remain separate')
|
|
else if (result === 0 && manualUptime) console.log('Manual uptime: full resources then ping, actual shared service and deferred alerts; owned PostgreSQL/localhost only')
|
|
else if (result === 0 && manualPingGroup) console.log('Manual Ping group: existing normalization/mutex/samples/conditional global alerts; owned PostgreSQL/localhost only')
|
|
else if (result === 0 && manualTraffic) console.log('Manual traffic: full scheduler/events/settings/retention/alerts shared by REST and MCP; owned PostgreSQL/localhost only')
|
|
else if (result === 0 && manualApiPing) console.log('Manual API Ping: ordinary global collector with alerts hook, own PostgreSQL and localhost only')
|
|
else if (result === 0 && simpleSpeed) console.log('Simple RouterOS speed: public MCP/REST, ordinary shared service, own PostgreSQL and localhost RouterOS only')
|
|
else if (result === 0 && simpleSpeedChr) console.log('Simple RouterOS speed: own PostgreSQL, real two-CHR bounded test and ordinary MCP approval; no router configuration changes')
|
|
else if (result === 0 && externalPeerMetadata) console.log('Guarded peer sources: actual managed/external SQL-owner and localhost license composition; Q/catalog attestation synthetic, full operator window remains open')
|
|
else if (result === 0 && operatorPeerMetadata) console.log('Operator peer metadata: actual managed endpoint SQL and genuine localhost license origin; synthetic Q, external metadata and full operator window remain open')
|
|
else if (result === 0 && publicRegistryMetadata) console.log('Public registry metadata: actual owned PostgreSQL and same physical lease; no secret/Q/native/write authority or backend-window acceptance')
|
|
else if (result === 0 && operatorDockerSql) console.log('Operator Docker SQL: actual owned PostgreSQL with mocked Docker HTTP only; not a real Docker/backend-window acceptance')
|
|
else if (result === 0 && ordinaryOperationRetirement) console.log('Ordinary operation retirement: owned actual logs-settings apply and worker')
|
|
else if (result === 0 && pollOperationRetirement) console.log('Poll operation retirement: owned authenticated historical fixtures and current reader/GC')
|
|
else if (result === 0 && probeOperationRetirement) console.log('Diagnostic retirement: actual owned worker tick, PostgreSQL and product read/replay; no live scheduling')
|
|
else if (result === 0 && mcpOperationOrigin) console.log('MCP operation root: owned PostgreSQL ordinary runner provenance; no restore/recovery, global writer activation, CHR or deployment')
|
|
else if (result === 0 && mcpSpeedOriginal) console.log('MCP speed: genuine trusted service context with real connection/grant/SQL, host receipt and localhost native; synthetic Q/mapping; not a public MCP runner/action acceptance')
|
|
else if (result === 0 && routerConfigurationGuard) console.log('Router configuration guard: dedicated owned databases/roles and localhost native fixture; no application migration, production activation or real CHR')
|
|
else if (result === 0 && scheduledSpeedOriginal) console.log('Scheduled speed original: genuine fixed-job scheduler authority, actual owned SQL and localhost read-only TCP; no legacy collector, native bandwidth, history or runtime activation')
|
|
else if (result === 0 && bandwidthSpeedWorkflow) console.log('Whole speed workflow: actual REST/JWT, signed v2 control SQL, native fixture HTTP and history; synthetic Q/mapping; no runtime activation or real CHR')
|
|
else if (result === 0 && restSpeedOriginal) console.log('REST speed original profile: owned application SQL and localhost read-only TCP; no bandwidth POST, history, runtime activation or real CHR')
|
|
else if (result === 0 && operationLocks) console.log('Operation lock profile: owned PostgreSQL/localhost fixtures; no terminal restore or real CHR')
|
|
else if (result === 0 && serviceExecutionOrigin) console.log('Service origin profile: owned SQL only; no terminal restore or native networking')
|
|
else if (result === 0 && (bandwidthAdmission || bandwidthControlSource || bandwidthNodeRegistry || bandwidthExternalRegistry || bandwidthNodeSource)) console.log('Bandwidth proposal profile: dedicated owned data round-trip only; no normal enrollment or production restore claim')
|
|
else if (result === 0 && (probeLegacyOrphans || probeStorageJournal || probeStorageHistory || probeJournal)) console.log('Legacy-only profile: positive current-version terminal restore belongs to --probe-storage-fresh; no migration marker fabricated')
|
|
else if (result === 0 && profilesOnly) console.log(profilesGroup ? 'Profiles-only fixed group: ' + profilesGroup + '; partial matrix on its own fresh database' : 'Profiles-only: running the unchanged complete regression list plus mandatory test:logs:pg on one fresh owned database')
|
|
else if (result === 0 && serverPollStorageFresh && process.env.MMAPP_OWN_SERVER_POLL_SETTINGS_EPOCH === 'true') console.log('Targeted settings epoch upgrade and actual pg_dump/restore accepted; full primary/poll-storage terminal restore not run')
|
|
else if (result === 0 && !chr && !flowWrites && !flowRebuild && !flowRebuildMcp) console.log('Terminal restore not run: use --restore with PostgreSQL client tools on PATH, or set MMAPP_PG_CLIENT_BIN')
|
|
if (exitCode === 0 && (serverPollStorage || serverPollStorageFresh) && (process.argv.includes('--restore') || process.env.MMAPP_PG_CLIENT_BIN)) {
|
|
exitCode = await new Promise((resolve, reject) => {
|
|
const child = spawn(process.execPath, ['--import', 'tsx', 'src/services/server-poll-storage-restore.sql.test.ts'], {
|
|
cwd: new URL('../', import.meta.url), stdio: 'inherit', env: { ...process.env,
|
|
DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/postgres`,
|
|
DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false',
|
|
MCP_STATE_DIR: join(directory, 'state'), AUTH_REQUIRED: 'true', AUTH_JWT_SECRET: 'mcp-integration-test-only',
|
|
NODE_ENV: 'test', PATH: testPath, MMAPP_OWN_SERVER_POLL_STORAGE_RESTORE: 'true' },
|
|
})
|
|
child.once('error', reject); child.once('exit', code => resolve(code ?? 1))
|
|
})
|
|
}
|
|
if (exitCode === 0 && process.argv.includes('--all')) {
|
|
if (!process.env.npm_execpath) throw new Error('Run --all through npm run test:mcp:pg:all')
|
|
const database = 'mm_accept_166_' + Date.now()
|
|
await postgres.createDatabase(database)
|
|
const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'))
|
|
let profiles = packageJson.scripts['test:all'].split(/\s*&&\s*/).map(command => command.replace('npm run ', ''))
|
|
if (process.argv.includes('--remaining')) profiles = profiles.slice(profiles.indexOf('test:traffic-flow'))
|
|
const selected = process.argv.find(value => value.startsWith('--profile='))?.slice('--profile='.length)
|
|
if (selected) {
|
|
if (![...profiles, 'test:logs:pg', 'test:vrf:production'].includes(selected)) throw new Error('Unknown regression profile')
|
|
profiles = [selected]
|
|
}
|
|
const failures = []
|
|
const requiredProfiles = regressionProfiles(profiles, selected, profilesGroup)
|
|
for (const script of requiredProfiles) {
|
|
if (script === 'test:vrf:production') {
|
|
vrfChildrenExitConfirmed = false
|
|
const receipt = await runOwnedVrfProductionProfile({ directory, database, databaseUrl: `postgresql://mcp_test:${password}@127.0.0.1:${port}/${database}` })
|
|
vrfChildrenExitConfirmed = receipt.childExitConfirmed
|
|
if (!receipt.accepted) failures.push(script)
|
|
if (!vrfChildrenExitConfirmed) break
|
|
continue
|
|
}
|
|
const status = await new Promise((resolve, reject) => {
|
|
const child = spawn(process.execPath, [process.env.npm_execpath, 'run', script], {
|
|
cwd: new URL('../', import.meta.url), stdio: 'inherit', env: { ...process.env,
|
|
DATABASE_URL: `postgresql://mcp_test:${password}@127.0.0.1:${port}/${database}`,
|
|
DATABASE_PATH: join(directory, 'no-legacy-database.sqlite'), SQLITE_IMPORT_FULL_HISTORY: 'false',
|
|
MMAPP_OWN_SQL_DB: database, MCP_STATE_DIR: join(directory, 'regression-state'),
|
|
REQUIRE_TEST_POSTGRES: '1',
|
|
LOGS_PERFORMANCE: process.argv.includes('--performance') ? '1' : '0',
|
|
AUTH_REQUIRED: 'false', NODE_ENV: 'test' },
|
|
})
|
|
child.once('error', reject); child.once('exit', code => resolve(code ?? 1))
|
|
})
|
|
if (status !== 0) failures.push(script)
|
|
}
|
|
exitCode = failures.length ? 1 : 0
|
|
console.log('Regression failed profiles:', failures.length ? failures.join(', ') : 'none')
|
|
if (profilesOnly) console.log('Profiles-only matrix result:', exitCode === 0 ? 'PASS' : 'FAIL', 'profiles=' + requiredProfiles.length, ...(profilesGroup ? ['group=' + profilesGroup, 'completeMatrix=false'] : []), 'primaryIntegration=NOT_RUN terminalRestore=NOT_RUN fullAcceptance=false')
|
|
}
|
|
} catch (error) {
|
|
exitCode = 1
|
|
console.error(error)
|
|
} finally {
|
|
await postgres.stop()
|
|
const rel = relative(resolve(tmpdir()), resolve(directory))
|
|
if (!rel || rel.startsWith('..') || isAbsolute(rel) || !rel.startsWith('mm-mcp-test-')) throw new Error('Unsafe test cleanup path')
|
|
if (vrfChildrenExitConfirmed) await rm(directory, { recursive: true, force: true, maxRetries: 10, retryDelay: 250 })
|
|
else console.error('VRF child exit unconfirmed; own test directory retained')
|
|
process.exitCode = exitCode
|
|
}
|
|
// embedded-postgres installs a beforeExit hook that otherwise forces exit(0).
|
|
process.exit(exitCode)
|