KAZIK/tools/tests/release_smoke_check.ps1

231 lines
8.7 KiB
PowerShell

param(
[string]$Root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
)
$ErrorActionPreference = 'Stop'
function Pass($message) {
Write-Host "[OK] $message" -ForegroundColor Green
}
function Fail($message) {
throw "[FAIL] $message"
}
function Require-File($relative) {
$path = Join-Path $Root $relative
if (!(Test-Path -LiteralPath $path -PathType Leaf)) {
Fail "Missing file: $relative"
}
Pass "Found $relative"
}
Push-Location $Root
try {
if (Test-Path -LiteralPath (Join-Path $Root 'PokerGameSetup.exe')) {
Require-File 'PokerGameSetup.exe'
}
if (Test-Path -LiteralPath (Join-Path $Root 'dist\Assembler Casino.exe')) {
Require-File 'dist\Assembler Casino.exe'
} else {
Require-File 'Assembler Casino.exe'
}
if (Test-Path -LiteralPath (Join-Path $Root 'dist\Uninstall Assembler Casino.exe')) {
Require-File 'dist\Uninstall Assembler Casino.exe'
} else {
Require-File 'Uninstall Assembler Casino.exe'
}
Require-File 'bin\poker.exe'
Require-File 'assets\icons\casino.ico'
Require-File 'assets\animations\hakari_dance.ans'
Require-File 'assets\animations\dbd_hook.ans'
$dbdRelative = if (Test-Path -LiteralPath (Join-Path $Root 'tools\previews\preview_dbd_hook.bat')) { 'tools\previews\preview_dbd_hook.bat' } else { 'tools\preview_dbd_hook.bat' }
Require-File $dbdRelative
Require-File 'docs\README_RELEASE.txt'
Require-File 'docs\RELEASE_CHECKLIST.txt'
Require-File 'docs\KNOWN_LIMITATIONS.txt'
Require-File 'docs\SECURITY_NOTES.txt'
Require-File 'docs\ROADMAP.txt'
Require-File 'docs\ONLINE_RADMIN.txt'
foreach ($mambo in @(
'assets\animations\mambo1.ans',
'assets\animations\mambo2.ans',
'assets\animations\mambo3.ans',
'assets\animations\mambo4.ans'
)) {
if (Test-Path -LiteralPath (Join-Path $Root $mambo) -PathType Leaf) {
Fail "Removed MAMBO animation still exists: $mambo"
}
}
Pass 'MAMBO animation files are removed from assets'
$dbdBat = Get-Content -LiteralPath (Join-Path $Root $dbdRelative) -Raw
if ($dbdBat -match 'Clear-Host') {
Fail 'DBD helper still uses Clear-Host'
}
Pass 'DBD helper does not use Clear-Host'
$asmBytes = [IO.File]::ReadAllBytes((Join-Path $Root 'poker.asm'))
$cp1251 = [Text.Encoding]::GetEncoding(1251)
$asmText = $cp1251.GetString($asmBytes)
foreach ($needle in @(
'settingsCinematicText db "Cinematic -',
'settingsAdaptiveText db "Adaptive -',
'settingsStableText db "Stable -',
'AnimShouldDrawFrame PROC',
'AnimFrameDelay PROC',
'WriteAnimProfileFile PROC',
'SAVE_SIGN_SIZE equ 276',
'SAVE_FILE_SIZE equ 280',
'CalcSaveSignature PROC',
'mov DWORD PTR [saveBuffer+SAVE_SIGN_SIZE], eax',
'cmp charsRead, SAVE_FILE_SIZE',
'includelib ws2_32.lib',
'GameOnlineCasino PROC',
'OnlineRRSessionHost PROC',
'OnlineRRSessionClient PROC'
)) {
if ($asmText.IndexOf($needle) -lt 0) {
Fail "Missing source marker: $needle"
}
}
Pass 'Animation profile and save signature markers exist in poker.asm'
if ($asmText -match 'MAMBO|mambo|PlayMambo') {
Fail 'MAMBO markers still exist in poker.asm'
}
Pass 'MAMBO markers are removed from poker.asm'
$launcherSource = Join-Path $Root 'build\AssemblerCasinoLauncher.cs'
if (!(Test-Path -LiteralPath $launcherSource -PathType Leaf)) {
Fail 'Missing launcher source: build\AssemblerCasinoLauncher.cs'
}
$launcherText = Get-Content -LiteralPath $launcherSource -Raw -Encoding UTF8
$expectedPokerHash = $null
if ($launcherText -match 'ExpectedPokerSha256 = "([A-Fa-f0-9]{64})"') {
$expectedPokerHash = $matches[1].ToUpperInvariant()
}
if ([string]::IsNullOrWhiteSpace($expectedPokerHash)) {
Fail 'Launcher source does not contain a fixed poker.exe SHA-256 hash'
}
$pokerSha = [Security.Cryptography.SHA256]::Create()
try {
$actualPokerHash = [BitConverter]::ToString($pokerSha.ComputeHash([IO.File]::ReadAllBytes((Join-Path $Root 'bin\poker.exe')))).Replace('-', '').ToUpperInvariant()
}
finally {
$pokerSha.Dispose()
}
if ($actualPokerHash -ne $expectedPokerHash) {
Fail "Launcher poker.exe SHA-256 mismatch. Expected $expectedPokerHash, actual $actualPokerHash"
}
Pass 'Launcher poker.exe SHA-256 matches current bin\poker.exe'
$setupSource = Join-Path $Root 'build\PokerGameSetupGui.cs'
if (!(Test-Path -LiteralPath $setupSource -PathType Leaf)) {
Fail 'Missing installer source: build\PokerGameSetupGui.cs'
}
$setupSourceText = Get-Content -LiteralPath $setupSource -Raw -Encoding UTF8
$expectedHash = $null
if ($setupSourceText -match 'ExpectedPayloadSha256 = "([A-Fa-f0-9]{64})"') {
$expectedHash = $matches[1].ToUpperInvariant()
}
if ([string]::IsNullOrWhiteSpace($expectedHash)) {
Fail 'Installer source does not contain a fixed SHA-256 payload hash'
}
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
$setupPath = Join-Path $Root 'PokerGameSetup.exe'
if (Test-Path -LiteralPath $setupPath) {
$fs = [IO.File]::OpenRead($setupPath)
try {
$head = New-Object byte[] ([Math]::Min(2097152, $fs.Length))
[void]$fs.Read($head, 0, $head.Length)
$marker = [Text.Encoding]::UTF8.GetBytes('<<POKER_GAME_GUI_PAYLOAD_ZIP>>')
$idx = -1
for ($i = 0; $i -le $head.Length - $marker.Length; $i++) {
if ($head[$i] -ne $marker[0]) { continue }
$ok = $true
for ($j = 1; $j -lt $marker.Length; $j++) {
if ($head[$i + $j] -ne $marker[$j]) { $ok = $false; break }
}
if ($ok) { $idx = $i; break }
}
if ($idx -lt 0) { Fail 'Installer payload marker not found' }
$fs.Position = $idx + $marker.Length
$zipBytes = New-Object byte[] ($fs.Length - $fs.Position)
[void]$fs.Read($zipBytes, 0, $zipBytes.Length)
}
finally {
$fs.Dispose()
}
$ms = New-Object IO.MemoryStream(,$zipBytes)
$zip = New-Object IO.Compression.ZipArchive($ms, [IO.Compression.ZipArchiveMode]::Read)
try {
$names = @($zip.Entries | ForEach-Object FullName)
foreach ($entry in @(
'Assembler Casino.exe',
'Uninstall Assembler Casino.exe',
'bin/poker.exe',
'assets/icons/casino.ico',
'tools/preview_dbd_hook.bat',
'tools/release_smoke_check.ps1',
'docs/README_RELEASE.txt',
'docs/RELEASE_CHECKLIST.txt',
'docs/KNOWN_LIMITATIONS.txt',
'docs/SECURITY_NOTES.txt',
'docs/ROADMAP.txt',
'docs/ONLINE_RADMIN.txt'
)) {
if ($names -notcontains $entry) {
Fail "Installer payload missing: $entry"
}
}
if ($names -contains 'Assembler Casino.bat') {
Fail 'Installer payload still contains old Assembler Casino.bat'
}
if ($names | Where-Object { $_ -like 'tools/generated_frames/*' }) {
Fail 'Installer payload contains generated preview frames/tools'
}
foreach ($entry in @(
'assets/animations/mambo1.ans',
'assets/animations/mambo2.ans',
'assets/animations/mambo3.ans',
'assets/animations/mambo4.ans'
)) {
if ($names -contains $entry) {
Fail "Installer payload still contains removed MAMBO animation: $entry"
}
}
Pass "Installer payload OK ($($names.Count) files)"
}
finally {
$zip.Dispose()
$ms.Dispose()
}
$sha = [Security.Cryptography.SHA256]::Create()
try {
$actualHash = [BitConverter]::ToString($sha.ComputeHash($zipBytes)).Replace('-', '').ToUpperInvariant()
}
finally {
$sha.Dispose()
}
if ($actualHash -ne $expectedHash) {
Fail "Installer payload SHA-256 mismatch. Expected $expectedHash, actual $actualHash"
}
Pass 'Installer payload SHA-256 matches embedded hash'
} else {
Pass 'PokerGameSetup.exe not present (skipping installer binary payload check)'
}
Write-Host ''
Write-Host 'Release smoke check passed.' -ForegroundColor Cyan
}
finally {
Pop-Location
}