Merge remote-tracking branch 'origin/test' into dev
# Conflicts: # lastleg-service/src/main/resources/db/lastleg.sql
This commit is contained in:
+4
-3
@@ -237,18 +237,19 @@ Dry-run 只检查根 `pom.xml` 和关键回归测试文件并打印 Maven 命令
|
||||
|
||||
### 本地 MySQL 全量验收
|
||||
|
||||
正式入口是 `local-db-full-acceptance.ps1`,只允许连接本机 `127.0.0.1` 或 `localhost`,默认端口 `3306`;测试库 `8.163.30.128` 会立即以退出码 2 拒绝。脚本固定校验统一 SQL SHA-256 `00E8F9C24CE16FE6B4D2B6AF60460AE1AF1D264DFE110D4BDCE611F09EB69EAA` 和 15403 行,并静态确认中文注释升级采用校验入队、每表一次 ALTER、结构签名复核、九库覆盖断言及唯一最终 `PASS`。
|
||||
正式入口是 `local-db-full-acceptance.ps1`,只允许连接本机 `127.0.0.1` 或 `localhost`,默认端口 `3306`;任何非本机地址都会立即以退出码 2 拒绝。非 dry-run 默认连续执行两轮,每轮精确删除 12 个 `baiyue_*` 国内/海外业务库,再只执行 `deploy/sql/头程数据库统一增量-MySQL8.sql` 和 `deploy/sql/海外区域统一增量-MySQL8.sql`,最后核对两个文件的最终 `PASS` 与 12 库完整性。
|
||||
|
||||
```powershell
|
||||
.\scripts\local-db-full-acceptance.ps1 -DryRun
|
||||
.\scripts\local-db-full-acceptance.ps1
|
||||
.\scripts\local-db-full-acceptance.ps1 -Rounds 1
|
||||
```
|
||||
|
||||
Dry-run 只校验 SQL 输入并打印空库、复跑、两类 picking 旧结构、WAIT_SPLIT/IAM、海外仓旧结构、中断恢复和最终结构的执行顺序,不启动 MySQL、不写库。真实运行每阶段写入 `.codex-tmp/p23-04-acceptance/acceptance-run-*.log`,不使用 `--force`,任一 SQL 错误立即停止并透传退出码,最后执行 `verify-final.sql`。脚本不保存或传入数据库密码,使用本机默认认证环境。
|
||||
Dry-run 只校验两个统一 SQL 的入口标记,打印当前 SHA-256、行数、清理范围和执行顺序,不连接 MySQL。真实运行会先把中文文件名按原始字节暂存为英文文件名,规避 Windows MySQL 客户端的 `source` 路径问题;每轮日志写入 `.codex-tmp/local-db-full-acceptance/round-*/`。脚本不保存数据库密码,认证由本机登录配置或当前进程的 `MYSQL_PWD` 等外部方式提供。成功后保留第二轮完整初始化结果;失败时可能留下半初始化库,下次运行会先清理精确范围再重建。
|
||||
|
||||
仓库中 `phase2-test-env-acceptance.ps1`、`admin-test-env-acceptance.mjs`、`client-test-env-acceptance.mjs`、`export-center-test-env-acceptance.ps1` 等属于测试环境/API 验收脚本;它们可能读取或写入测试环境数据,不由本入口调用。`migrate-local-qualification-file.ps1`、`local-env.ps1` 等是环境/迁移辅助脚本,也不由本入口调用。
|
||||
|
||||
本入口不读取数据库凭据、不执行 MySQL、HTTP、迁移、DDL、INSERT/UPDATE/DELETE,也不启动 Nacos、Gateway 或业务服务。需要数据库矩阵时必须单独运行受控验收流程。
|
||||
本入口只操作明确指定的本机 MySQL,不访问开发或测试 HTTP 环境,不启动 Nacos、Gateway 或业务服务,也不会清理系统库或非 `baiyue_*` 数据库。
|
||||
|
||||
## 退出码
|
||||
|
||||
|
||||
@@ -3,6 +3,13 @@ import { readFileSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
|
||||
const sql = readFileSync(new URL('../../deploy/sql/头程数据库统一增量-MySQL8.sql', import.meta.url), 'utf8')
|
||||
const overseasSql = readFileSync(new URL('../../deploy/sql/海外区域统一增量-MySQL8.sql', import.meta.url), 'utf8')
|
||||
const lastlegBaseline = readFileSync(new URL('../../lastleg-service/src/main/resources/db/lastleg.sql', import.meta.url), 'utf8')
|
||||
const lastlegPermissionSeed = readFileSync(new URL('../../iam/src/main/resources/db/lastleg-permissions.sql', import.meta.url), 'utf8')
|
||||
const phase5DeliveryPermissionSeed = readFileSync(new URL('../../iam/src/main/resources/db/phase5-delivery-permissions.sql', import.meta.url), 'utf8')
|
||||
const overseasWarehousePermissions = readFileSync(new URL('../../../apps/admin-web/src/modules/overseas-warehouse/permissions.ts', import.meta.url), 'utf8')
|
||||
const overseasBusinessPermissions = readFileSync(new URL('../../../apps/admin-web/src/modules/overseas-business/permissions.ts', import.meta.url), 'utf8')
|
||||
const overseasMasterDataPermissions = readFileSync(new URL('../../../apps/admin-web/src/modules/overseas-master-data/permissions.ts', import.meta.url), 'utf8')
|
||||
const iamSeed = readFileSync(new URL('../../iam/src/main/resources/db/phase1-admin-rbac.sql', import.meta.url), 'utf8')
|
||||
const oceanBookingSchema = readFileSync(new URL('../../firstleg/src/main/resources/db/phase3-ocean-booking-schema.sql', import.meta.url), 'utf8')
|
||||
const truckAppointmentSchema = readFileSync(new URL('../../firstleg/src/main/resources/db/phase3-truck-appointment-schema.sql', import.meta.url), 'utf8')
|
||||
@@ -50,6 +57,81 @@ test('国内统一初始化支持真实空库且不越界创建海外业务库',
|
||||
)
|
||||
})
|
||||
|
||||
test('国内统一初始化在注释门禁前创建订单申报快照表', () => {
|
||||
for (const table of ['fl_order_declaration_snapshot', 'fl_order_declaration_event']) {
|
||||
const createIndex = sql.indexOf(`CREATE TABLE IF NOT EXISTS ${table} (`)
|
||||
const commentIndex = sql.indexOf(`CALL queue_table_comment('baiyue_firstleg', '${table}'`)
|
||||
assert.ok(createIndex >= 0, `missing domestic baseline table: ${table}`)
|
||||
assert.ok(commentIndex >= 0, `missing domestic table comment gate: ${table}`)
|
||||
assert.ok(createIndex < commentIndex, `${table} must exist before the table-comment gate runs`)
|
||||
}
|
||||
})
|
||||
|
||||
test('海外统一初始化内联空库基线且不依赖模块 SQL', () => {
|
||||
assert.match(overseasSql, /BEGIN INLINE EMPTY-DATABASE BASELINE: LASTLEG/)
|
||||
assert.match(overseasSql, /BEGIN INLINE EMPTY-DATABASE BASELINE: OVERSEAS WAREHOUSE/)
|
||||
assert.match(overseasSql, /CREATE DATABASE IF NOT EXISTS baiyue_lastleg/)
|
||||
assert.match(overseasSql, /CREATE DATABASE IF NOT EXISTS baiyue_lastlag_warehouse/)
|
||||
assert.match(overseasSql, /CREATE TABLE IF NOT EXISTS ll_order \(/)
|
||||
assert.match(overseasSql, /CREATE TABLE IF NOT EXISTS wh_location \(/)
|
||||
assert.ok(
|
||||
overseasSql.indexOf('CREATE TABLE IF NOT EXISTS ll_order (') <
|
||||
overseasSql.indexOf('CREATE TABLE IF NOT EXISTS ll_order_source_pallet ('),
|
||||
'll_order must exist before the source-pallet foreign key is created',
|
||||
)
|
||||
assert.ok(
|
||||
overseasSql.indexOf('CREATE DATABASE IF NOT EXISTS baiyue_lastlag_warehouse') <
|
||||
overseasSql.indexOf('CREATE TABLE IF NOT EXISTS wh_location ('),
|
||||
'the overseas warehouse schema must be selected before its baseline tables are created',
|
||||
)
|
||||
})
|
||||
|
||||
test('海外空库基线为固定平台管理员提供完整version0授权投影', () => {
|
||||
const authorityBlock = lastlegBaseline.match(
|
||||
/SET @platform_admin_overseas_authorities = JSON_ARRAY\(([\s\S]*?)\n\);/,
|
||||
)?.[1]
|
||||
assert.ok(authorityBlock, 'missing platform_admin overseas authority snapshot')
|
||||
const authorities = [...authorityBlock.matchAll(/'([^']+)'/g)].map((match) => match[1])
|
||||
assert.equal(authorities.length, 109)
|
||||
assert.equal(new Set(authorities).size, authorities.length, 'baseline authorities must not contain duplicates')
|
||||
assert.equal(authorities.filter((item) => item.startsWith('platform:finance:')).length, 34)
|
||||
assert.equal(authorities.filter((item) => item.startsWith('platform:overseas-business:')).length, 11)
|
||||
assert.equal(authorities.filter((item) => item.startsWith('platform:overseas-master-data:')).length, 15)
|
||||
assert.equal(authorities.filter((item) => item.startsWith('platform:overseas-warehouse:')).length, 49)
|
||||
for (const authority of authorities) {
|
||||
assert.ok(sql.includes(`'${authority}'`), `authority is absent from the domestic IAM baseline: ${authority}`)
|
||||
}
|
||||
for (const source of [overseasWarehousePermissions, overseasBusinessPermissions, overseasMasterDataPermissions]) {
|
||||
const declared = [...source.matchAll(/'((?:platform:overseas-warehouse|platform:overseas-business|platform:overseas-master-data):[^']+)'/g)]
|
||||
.map((match) => match[1])
|
||||
for (const authority of declared) {
|
||||
assert.ok(
|
||||
[lastlegPermissionSeed, phase5DeliveryPermissionSeed].some((seed) => seed.includes(`'${authority}'`)),
|
||||
`Admin permission is absent from the IAM source seed: ${authority}`,
|
||||
)
|
||||
assert.ok(authorities.includes(authority), `Admin permission is absent from the fixed-admin overseas snapshot: ${authority}`)
|
||||
}
|
||||
}
|
||||
for (const required of [
|
||||
'platform:overseas-warehouse:last-mile-order:list',
|
||||
'platform:overseas-warehouse:inbound-order:list',
|
||||
'platform:overseas-warehouse:dispatch:list',
|
||||
'platform:overseas-business:purchase:list',
|
||||
'platform:overseas-master-data:quote:list',
|
||||
'platform:finance:fee-source:review',
|
||||
]) assert.ok(authorities.includes(required), `missing fixed-admin overseas authority: ${required}`)
|
||||
|
||||
assert.match(lastlegBaseline, /SET @platform_admin_overseas_roles = JSON_ARRAY\('PLATFORM_ADMIN'\)/)
|
||||
assert.doesNotMatch(lastlegBaseline, /\('AUTHORIZATION','1000001',0,NULL,0,JSON_ARRAY\(\),JSON_ARRAY\(\)/)
|
||||
assert.doesNotMatch(overseasSql, /\('AUTHORIZATION','1000001',0,NULL,0,JSON_ARRAY\(\),JSON_ARRAY\(\)/)
|
||||
|
||||
const inline = overseasSql.match(
|
||||
/-- BEGIN INLINE EMPTY-DATABASE BASELINE: LASTLEG\r?\n([\s\S]*?)\r?\n\r?\n-- END INLINE EMPTY-DATABASE BASELINE: LASTLEG/,
|
||||
)?.[1]
|
||||
assert.ok(inline, 'missing inline Lastleg baseline')
|
||||
assert.equal(inline.replace(/\r\n/g, '\n').trim(), lastlegBaseline.replace(/\r\n/g, '\n').trim())
|
||||
})
|
||||
|
||||
test('国内统一初始化补齐入库费用人工调整基线字段', () => {
|
||||
assert.match(sql, /baseline_chargeable_quantity DECIMAL\(18,6\) NOT NULL/)
|
||||
assert.match(sql, /SET baseline_chargeable_quantity = chargeable_quantity[\s\S]*?WHERE baseline_chargeable_quantity IS NULL/)
|
||||
|
||||
@@ -2,92 +2,128 @@ param(
|
||||
[switch]$DryRun,
|
||||
[Alias('Host')][string]$TargetHost = '127.0.0.1',
|
||||
[int]$Port = 3306,
|
||||
[string]$InputPath,
|
||||
[string]$MysqlExe = 'C:\Program Files\MySQL\MySQL Server 8.4\bin\mysql.exe',
|
||||
[string]$User = 'root'
|
||||
[string]$User = 'root',
|
||||
[ValidateRange(1, 10)][int]$Rounds = 2
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Repo = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
||||
$Workspace = (Resolve-Path (Join-Path $Repo '..')).Path
|
||||
$Acceptance = Join-Path $Workspace '.codex-tmp\p23-04-acceptance'
|
||||
$ExpectedSha256 = '0EE13427AB60CECCEB42985CF1E78A05645C18CD9BF2886110C0AFEAF3CA7B9B'
|
||||
$ExpectedLines = 15674
|
||||
$ReportRoot = Join-Path $Workspace '.codex-tmp\local-db-full-acceptance'
|
||||
$DomesticSql = Join-Path $Repo 'deploy\sql\头程数据库统一增量-MySQL8.sql'
|
||||
$OverseasSql = Join-Path $Repo 'deploy\sql\海外区域统一增量-MySQL8.sql'
|
||||
$Schemas = @(
|
||||
'baiyue_auth', 'baiyue_iam', 'baiyue_order', 'baiyue_warehouse',
|
||||
'baiyue_firstleg', 'baiyue_file', 'baiyue_audit', 'baiyue_event_bridge',
|
||||
'baiyue_finance', 'baiyue_lastleg', 'baiyue_lastlag_warehouse',
|
||||
'baiyue_event_bridge_overseas'
|
||||
)
|
||||
|
||||
if ($TargetHost -notin @('127.0.0.1', 'localhost')) {
|
||||
[Console]::Error.WriteLine('Refusing non-local database; only 127.0.0.1 or localhost is allowed.')
|
||||
exit 2
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($InputPath)) {
|
||||
$InputPath = (Get-ChildItem (Join-Path $Repo 'deploy\sql') -Filter '*MySQL8.sql' -File |
|
||||
Where-Object { $_.Length -gt 100000 } | Select-Object -First 1).FullName
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $InputPath)) {
|
||||
[Console]::Error.WriteLine("InputPath does not exist: $InputPath")
|
||||
if (-not (Test-Path -LiteralPath $MysqlExe)) {
|
||||
[Console]::Error.WriteLine("mysql executable does not exist: $MysqlExe")
|
||||
exit 2
|
||||
}
|
||||
$actual = ((Get-FileHash -Algorithm SHA256 -LiteralPath $InputPath).Hash).Trim().ToUpperInvariant()
|
||||
$lines = [System.IO.File]::ReadAllLines($InputPath).Length
|
||||
if ($actual -ne $ExpectedSha256 -or $lines -ne $ExpectedLines) {
|
||||
[Console]::Error.WriteLine("Unified SQL snapshot mismatch: $actual/$lines")
|
||||
exit 2
|
||||
}
|
||||
$sqlText = [System.IO.File]::ReadAllText($InputPath)
|
||||
$commentGateTokens = @(
|
||||
'CREATE PROCEDURE queue_column_comment',
|
||||
'CREATE PROCEDURE apply_one_table_comments',
|
||||
'CALL apply_queued_comments();',
|
||||
'字段注释批量升级改变了结构签名',
|
||||
'存在缺失中文注释的业务表',
|
||||
'存在缺失中文注释的业务字段'
|
||||
)
|
||||
foreach ($token in $commentGateTokens) {
|
||||
if (-not $sqlText.Contains($token)) {
|
||||
[Console]::Error.WriteLine("Unified SQL comment acceptance marker missing: $token")
|
||||
foreach ($sqlFile in @($DomesticSql, $OverseasSql)) {
|
||||
if (-not (Test-Path -LiteralPath $sqlFile)) {
|
||||
[Console]::Error.WriteLine("Unified SQL does not exist: $sqlFile")
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
if ([regex]::Matches($sqlText, "SELECT 'PASS' AS migration_status").Count -ne 1) {
|
||||
[Console]::Error.WriteLine('Unified SQL must contain exactly one final PASS statement')
|
||||
|
||||
$DomesticText = [IO.File]::ReadAllText($DomesticSql)
|
||||
$OverseasText = [IO.File]::ReadAllText($OverseasSql)
|
||||
if (-not $DomesticText.Contains("SELECT 'PASS' AS migration_status")) {
|
||||
[Console]::Error.WriteLine('Domestic unified SQL is missing its final PASS statement.')
|
||||
exit 2
|
||||
}
|
||||
foreach ($marker in @(
|
||||
'-- BEGIN INLINE EMPTY-DATABASE BASELINE: LASTLEG',
|
||||
'-- BEGIN INLINE EMPTY-DATABASE BASELINE: OVERSEAS WAREHOUSE',
|
||||
"SELECT 'PASS' AS migration_status"
|
||||
)) {
|
||||
if (-not $OverseasText.Contains($marker)) {
|
||||
[Console]::Error.WriteLine("Overseas unified SQL is missing marker: $marker")
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
$sequence = @(
|
||||
'empty: base.sql', 'replay: base.sql + input.sql + input.sql',
|
||||
'smart-old: fixture-smart-old.sql', 'inbound-old: fixture-inbound-old.sql',
|
||||
'waitsplit-iam: fixture-test-shape.sql', 'overseas-old: fixture-overseas-old.sql',
|
||||
'overseas-missing-objects: fixture-overseas-missing-objects.sql',
|
||||
'interrupted-recovery: fixture-interrupted.sql', 'final-structure: verify-final.sql')
|
||||
Write-Output "SQL SHA-256: $actual / lines: $lines"
|
||||
Write-Output 'Comment gate: queued validation, per-table ALTER, signature verification, nine-schema coverage, unique PASS'
|
||||
$DomesticHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $DomesticSql).Hash
|
||||
$OverseasHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $OverseasSql).Hash
|
||||
Write-Output "Target: $TargetHost`:$Port"
|
||||
Write-Output 'Fixture order:'
|
||||
$sequence | ForEach-Object { Write-Output " $_" }
|
||||
if ($DryRun) { Write-Output 'DRY-RUN PASS (mysql not started; no database writes)'; exit 0 }
|
||||
Write-Output "Rounds: $Rounds"
|
||||
Write-Output "Domestic SQL: $DomesticHash / $([IO.File]::ReadAllLines($DomesticSql).Length) lines"
|
||||
Write-Output "Overseas SQL: $OverseasHash / $([IO.File]::ReadAllLines($OverseasSql).Length) lines"
|
||||
Write-Output "Reset scope: $($Schemas -join ', ')"
|
||||
Write-Output 'Execution order per round: clear exact schemas -> domestic unified SQL -> overseas unified SQL -> final PASS and schema checks'
|
||||
if ($DryRun) {
|
||||
Write-Output 'DRY-RUN PASS (mysql not contacted; no database writes)'
|
||||
exit 0
|
||||
}
|
||||
|
||||
$acceptanceInput = Join-Path $Acceptance 'input.sql'
|
||||
Copy-Item -LiteralPath $InputPath -Destination $acceptanceInput -Force
|
||||
$stagedHash = ((Get-FileHash -Algorithm SHA256 -LiteralPath $acceptanceInput).Hash).Trim().ToUpperInvariant()
|
||||
if ($stagedHash -ne $actual) {
|
||||
[Console]::Error.WriteLine("Failed to stage the validated unified SQL snapshot: $stagedHash")
|
||||
New-Item -ItemType Directory -Path $ReportRoot -Force | Out-Null
|
||||
$StagedDomestic = Join-Path $ReportRoot 'domestic.sql'
|
||||
$StagedOverseas = Join-Path $ReportRoot 'overseas.sql'
|
||||
Copy-Item -LiteralPath $DomesticSql -Destination $StagedDomestic -Force
|
||||
Copy-Item -LiteralPath $OverseasSql -Destination $StagedOverseas -Force
|
||||
if ((Get-FileHash -Algorithm SHA256 -LiteralPath $StagedDomestic).Hash -ne $DomesticHash -or
|
||||
(Get-FileHash -Algorithm SHA256 -LiteralPath $StagedOverseas).Hash -ne $OverseasHash) {
|
||||
[Console]::Error.WriteLine('Failed to stage byte-identical SQL files under ASCII filenames.')
|
||||
exit 2
|
||||
}
|
||||
|
||||
$run = 0
|
||||
function Invoke-Stage([string]$Name, [string]$File) {
|
||||
$script = Join-Path $Acceptance $File
|
||||
$log = Join-Path $Acceptance ("acceptance-run-{0:D2}-{1}.log" -f $script:run, $Name)
|
||||
$script:run++
|
||||
if (-not (Test-Path -LiteralPath $script)) { [Console]::Error.WriteLine("Script does not exist: $script"); return 2 }
|
||||
& $MysqlExe '--protocol=TCP' "--host=$TargetHost" "--port=$Port" "--user=$User" '--database=mysql' '--batch' ("--execute=source " + $script.Replace('\','/')) *> $log
|
||||
return $LASTEXITCODE
|
||||
$MysqlCommon = @(
|
||||
'--protocol=TCP', "--host=$TargetHost", "--port=$Port", "--user=$User",
|
||||
'--default-character-set=utf8mb4', '--batch'
|
||||
)
|
||||
& $MysqlExe @MysqlCommon '--skip-column-names' '--execute=SELECT VERSION(), @@hostname, @@port;' | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
[Console]::Error.WriteLine('Cannot connect to the local MySQL target. Configure authentication outside this script, for example with MYSQL_PWD for the current process.')
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
$calls = @(
|
||||
@('empty','base.sql'), @('replay-reset','base.sql'), @('replay-1','input.sql'), @('replay-2','input.sql'),
|
||||
@('smart-old','fixture-smart-old.sql'), @('inbound-old','fixture-inbound-old.sql'), @('waitsplit-iam','fixture-test-shape.sql'),
|
||||
@('overseas-old','fixture-overseas-old.sql'), @('overseas-missing','fixture-overseas-missing-objects.sql'),
|
||||
@('interrupted','fixture-interrupted.sql'), @('final-verify','verify-final.sql'))
|
||||
foreach ($call in $calls) { $code = Invoke-Stage $call[0] $call[1]; if ($code -ne 0) { exit $code } }
|
||||
Write-Output 'FULL LOCAL ACCEPTANCE PASS'
|
||||
$DropSql = ($Schemas | ForEach-Object { "DROP DATABASE IF EXISTS ``$_```;" }) -join ' '
|
||||
for ($round = 1; $round -le $Rounds; $round++) {
|
||||
$RoundRoot = Join-Path $ReportRoot ("round-{0}" -f $round)
|
||||
New-Item -ItemType Directory -Path $RoundRoot -Force | Out-Null
|
||||
$Stopwatch = [Diagnostics.Stopwatch]::StartNew()
|
||||
|
||||
& $MysqlExe @MysqlCommon "--execute=$DropSql" *> (Join-Path $RoundRoot '00-clear.log')
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
[Console]::Error.WriteLine("Round $round failed while clearing the exact project schemas.")
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
$DomesticLog = Join-Path $RoundRoot '10-domestic.log'
|
||||
$DomesticSource = $StagedDomestic.Replace('\', '/')
|
||||
& $MysqlExe @MysqlCommon '--database=mysql' "--execute=source $DomesticSource" *> $DomesticLog
|
||||
if ($LASTEXITCODE -ne 0 -or -not (Select-String -LiteralPath $DomesticLog -Pattern '^PASS\s+统一增量全部执行完成' -Quiet)) {
|
||||
[Console]::Error.WriteLine("Round $round domestic unified SQL failed. See $DomesticLog")
|
||||
exit $(if ($LASTEXITCODE -ne 0) { $LASTEXITCODE } else { 2 })
|
||||
}
|
||||
|
||||
$OverseasLog = Join-Path $RoundRoot '20-overseas.log'
|
||||
$OverseasSource = $StagedOverseas.Replace('\', '/')
|
||||
& $MysqlExe @MysqlCommon '--database=mysql' "--execute=source $OverseasSource" *> $OverseasLog
|
||||
if ($LASTEXITCODE -ne 0 -or -not (Select-String -LiteralPath $OverseasLog -Pattern '^PASS\s+海外财务P0费用来源字段已就绪$' -Quiet)) {
|
||||
[Console]::Error.WriteLine("Round $round overseas unified SQL failed. See $OverseasLog")
|
||||
exit $(if ($LASTEXITCODE -ne 0) { $LASTEXITCODE } else { 2 })
|
||||
}
|
||||
|
||||
$SchemaList = "'" + ($Schemas -join "','") + "'"
|
||||
$SchemaCount = (& $MysqlExe @MysqlCommon '--skip-column-names' "--execute=SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name IN ($SchemaList);").Trim()
|
||||
if ($LASTEXITCODE -ne 0 -or [int]$SchemaCount -ne $Schemas.Count) {
|
||||
[Console]::Error.WriteLine("Round $round schema verification failed: $SchemaCount/$($Schemas.Count)")
|
||||
exit 2
|
||||
}
|
||||
|
||||
$Stopwatch.Stop()
|
||||
Write-Output "ROUND $round PASS / $SchemaCount schemas / $([Math]::Round($Stopwatch.Elapsed.TotalSeconds, 1)) seconds"
|
||||
}
|
||||
|
||||
Write-Output 'FULL LOCAL TWO-REGION DATABASE ACCEPTANCE PASS'
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user