test(upserver): 归档存档迁移与玩法闭环回归工具
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
$ErrorActionPreference='Stop'
|
||||
$root='C:/projects/ft/CodexOutput/upserver'
|
||||
function Read-Backup($stamp) { Get-Content -Raw -LiteralPath "$root/KVGameplayLoopTests/backups/$stamp/102.json" | ConvertFrom-Json }
|
||||
function Changed-Keys($left,$right) {
|
||||
@(@($left.PSObject.Properties.Name)+@($right.PSObject.Properties.Name) | Sort-Object -Unique | Where-Object { $left.$_ -cne $right.$_ })
|
||||
}
|
||||
function Hash-Value([string]$value) {
|
||||
$sha=[Security.Cryptography.SHA256]::Create()
|
||||
try { [BitConverter]::ToString($sha.ComputeHash([Text.Encoding]::UTF8.GetBytes($value))).Replace('-','') } finally { $sha.Dispose() }
|
||||
}
|
||||
$before=Read-Backup '20260928T024346Z'
|
||||
$reward=Read-Backup '20260928T024903Z'
|
||||
$closed=Read-Backup '20260928T025001Z'
|
||||
$final=Read-Backup '20260928T025514Z'
|
||||
$events=@(Get-Content -LiteralPath "$root/KVGameplayLoopTests/runs/44848_639261601944579366/events.jsonl" | ForEach-Object { $_ | ConvertFrom-Json })
|
||||
$recoveryEvents=@(Get-Content -LiteralPath "$root/KVGameplayLoopTests/runs/103828_639261606481142886/events.jsonl" | ForEach-Object { $_ | ConvertFrom-Json })
|
||||
$recovered=(Get-Content -Raw -LiteralPath "$root/KVFishingRewardTests/fourth-recovered-values.json" | ConvertFrom-Json).Result | ConvertFrom-Json
|
||||
$preMain=$before.data.NewPlayerDataDic | ConvertFrom-Json
|
||||
$postMain=$final.data.NewPlayerDataDic | ConvertFrom-Json
|
||||
$preMap=$before.data.Map_5_102 | ConvertFrom-Json
|
||||
$postMap=$final.data.Map_5_102 | ConvertFrom-Json
|
||||
$rewardConfirmation=@($events | Where-Object kind -EQ 'fishing-reward-confirmed')[0]
|
||||
$presentation=@($events | Where-Object kind -EQ 'fishing-reward-presented')[0]
|
||||
$ticketMatches=@($rewardConfirmation.detail.tickets | ForEach-Object { [pscustomobject]@{key=$_.key;sequence=$_.sequence;matchesFinalServer=((Hash-Value $final.data.($_.key)) -ceq $_.valueHash)} })
|
||||
$cacheResults=@('44848_639261601944579366','103828_639261606481142886' | ForEach-Object {
|
||||
$cacheFile=Get-ChildItem -LiteralPath "$root/KVGameplayLoopTests/runs/$_/cache" -Recurse -Filter state.json
|
||||
$cache=Get-Content -Raw -LiteralPath $cacheFile.FullName | ConvertFrom-Json
|
||||
[pscustomobject]@{run=$_;pending=@($cache.pending).Count;unknown=($null -ne $cache.unknownBatch);active=($null -ne $cache.activeBatch);baselineChangedKeys=@(Changed-Keys $cache.baseline $final.data)}
|
||||
})
|
||||
$report=[ordered]@{
|
||||
phase='4C2-fourth-real-run-and-fresh-process-recovery-awaiting-independent-review'
|
||||
api=$recovered.api
|
||||
backups=@('20260928T024346Z','20260928T024903Z','20260928T025001Z','20260928T025514Z')
|
||||
countBefore=@($before.data.PSObject.Properties).Count;countAfter=@($final.data.PSObject.Properties).Count
|
||||
changedKeys=@(Changed-Keys $before.data $final.data)
|
||||
changedFishIds=@(Changed-Keys $preMap $postMap)
|
||||
fishBefore=$preMap.'10223';fishAfter=$postMap.'10223'
|
||||
mainBefore=$preMain;mainAfter=$postMain
|
||||
rewardToQuitChangedKeys=@(Changed-Keys $reward.data $closed.data)
|
||||
quitToRecoveryFinalChangedKeys=@(Changed-Keys $closed.data $final.data)
|
||||
consumeCount=@($events | Where-Object kind -EQ 'fishing-energy-applied').Count
|
||||
rewardConfirmedCount=@($events | Where-Object kind -EQ 'fishing-reward-confirmed').Count
|
||||
rewardPresentedCount=@($events | Where-Object kind -EQ 'fishing-reward-presented').Count
|
||||
confirmedBeforePresented=([DateTime]$rewardConfirmation.at -lt [DateTime]$presentation.at)
|
||||
rewardTickets=$ticketMatches
|
||||
faults=@($events | Where-Object kind -EQ 'fault').Count
|
||||
recoveryFishingEvents=@($recoveryEvents | Where-Object kind -Like 'fishing-*').Count
|
||||
recoveryWrites=@($recoveryEvents | Where-Object kind -EQ 'accepted').Count
|
||||
recovered=$recovered
|
||||
recoveredCoreEqualsFinalServer=($recovered.core -ceq $postMain.newData)
|
||||
recoveredFishRawEqualsFinalServer=($recovered.fishRaw -ceq $postMap.'10223')
|
||||
cacheResults=$cacheResults
|
||||
signupGold=16200;fishingGold=2516;totalGold=18716
|
||||
independentFormulaRecomputed=$false
|
||||
precastIndependentBackupCaptured=$false
|
||||
boundary='用户在主会话尚未完成动作前快照时手动签到并抛竿;precast/live-gates实际采样晚于扣费,不能充当动作前基线。保存完整审计和服务器前后值,交独立复核裁决证据是否充分,不自动重跑。鱼TotalNum由新进程KV有效值读回验证;活对象直接验证重量/等级/NewFish,未通过私有反射读取TotalNum。'
|
||||
}
|
||||
$report | ConvertTo-Json -Depth 20 | Set-Content -LiteralPath "$root/KVFishingRewardTests/fourth-reconciliation.json" -Encoding utf8
|
||||
$checks=@(
|
||||
$report.api -ceq 'http://s101.local:18080/'
|
||||
$report.consumeCount -eq 1
|
||||
$report.rewardConfirmedCount -eq 1
|
||||
$report.rewardPresentedCount -eq 1
|
||||
$report.confirmedBeforePresented
|
||||
$report.faults -eq 0
|
||||
$report.recoveryFishingEvents -eq 0
|
||||
$report.rewardToQuitChangedKeys.Count -eq 0
|
||||
$report.quitToRecoveryFinalChangedKeys.Count -eq 0
|
||||
$report.recoveredCoreEqualsFinalServer
|
||||
$report.recoveredFishRawEqualsFinalServer
|
||||
@($ticketMatches | Where-Object { -not $_.matchesFinalServer }).Count -eq 0
|
||||
@($cacheResults | Where-Object { $_.pending -ne 0 -or $_.unknown -or $_.active -or $_.baselineChangedKeys.Count -ne 0 }).Count -eq 0
|
||||
)
|
||||
if($checks -contains $false) { throw 'Reconciliation assertion failed; inspect fourth-reconciliation.json' }
|
||||
[pscustomobject]@{checks=$checks.Count;passed=$true;changedKeys=$report.changedKeys;changedFishIds=$report.changedFishIds;recoveryUnchanged=$true} | ConvertTo-Json -Depth 4
|
||||
Reference in New Issue
Block a user