Files
MagnetismHeroes/tools/android/test-final-startup.ps1
T

71 lines
6.1 KiB
PowerShell

param([Parameter(Mandatory)][string]$EvidenceDir,[Parameter(Mandatory)][string]$HomePng,[string]$Source=(Join-Path $PSScriptRoot 'final-common.ps1'))
$ErrorActionPreference='Stop'
New-Item -ItemType Directory -Path $EvidenceDir -Force|Out-Null
$EvidenceDir=(Resolve-Path $EvidenceDir).Path
$checks=[Collections.Generic.List[object]]::new();$commands=[Collections.Generic.List[object]]::new()
function Record($Id,$Passed,$Actual){$checks.Add(@{id=$Id;passed=[bool]$Passed;actual=$Actual})}
foreach($name in @('Adb','StartHome')){
$ast=[Management.Automation.Language.Parser]::ParseFile($Source,[ref]$null,[ref]$null)
$definition=$ast.Find({param($n)$n-is[Management.Automation.Language.FunctionDefinitionAst]-and$n.Name-eq$Name},$true)
$expected=$definition.Extent.Text.Replace("function $name","function global:$name")
. ([scriptblock]::Create($expected))
Record "$name-production-body-identity" ((Get-Command $name).ScriptBlock.Ast.Extent.Text-ceq$expected) $Source
}
$adb='OfflineNative';$Serial='offline';$package='com.magnetismheroes.game';$activity="$package/activity";$remote='/offline/progress.json'
function OfflineNative {
$text=$args-join' ';$global:LASTEXITCODE=0
if($script:mode-eq'exit-control'){$global:LASTEXITCODE=$script:mockExit;return $script:mockOutput}
if($text-match'pidof'){
$script:pidCalls++
if($script:mode-eq'other-error'){$global:LASTEXITCODE=2;return ''}
if($script:mode-eq'absent'-or($script:mode-eq'eventually-ready'-and$script:pidCalls-le2)){$global:LASTEXITCODE=1;return ''}
if($script:mode-eq'empty-zero') {return ''}
if($script:mode-eq'malformed-pid') {return 'unavailable'}
return '77'
}
if($text-match'am start'){$script:starts++;if($script:mode-eq'start-error'){$global:LASTEXITCODE=1;return ''};return 'Status: ok; delivered-to-top-instance'}
if($text-match'cat '){if($script:mode-eq'save-error'){$global:LASTEXITCODE=1;return ''};if($script:mode-eq'invalid-save'){return '{}'};return '{"schemaVersion":1,"completedStageIds":[],"puzzleStates":[]}'}
return ''
}
function Step($Name,$Arguments=@(),$Delay=500){
$destination=Join-Path $EvidenceDir "$Name.png"
if($script:mode-eq'black-ui'){$image=[Drawing.Bitmap]::new(2400,1080);try{$image.Save($destination)}finally{$image.Dispose()}}else{Copy-Item -LiteralPath $HomePng -Destination $destination -Force}
}
function Start-Sleep {}
function Check($Id,$Passed,$Actual){if(!$Passed){throw "$Id : $Actual"}}
try{
$script:mode='exit-control';$script:mockOutput='';$script:mockExit=1
$rejected=$false;try{Adb @('shell','pidof',$package)|Out-Null}catch{$rejected=$_.Exception.Message-match'ADB exit 1'}
Record 'default-adb-exit1-still-rejected' ($rejected-and$commands[-1].exitCode-eq1) $commands[-1]
$errorText=$null;try{$empty=Adb @('shell','pidof',$package) -AllowMissingPid}catch{$errorText=$_.Exception.Message}
Record 'allowed-pid-absence-retains-raw-exit1' (!$errorText-and$empty-eq''-and$commands[-1].exitCode-eq1) $commands[-1]
$script:mockExit=2;$rejected=$false;try{Adb @('shell','pidof',$package) -AllowMissingPid|Out-Null}catch{$rejected=$_.Exception.Message-match'ADB exit 2'}
Record 'other-pid-error-still-rejected' ($rejected-and$commands[-1].exitCode-eq2) $commands[-1]
$script:mockExit=1
foreach($arguments in @(@('shell','wm','size'),@('shell','pidof','another.package'),@('shell','am','start','-W','-n',$activity))){
$rejected=$false;try{Adb $arguments -AllowMissingPid|Out-Null}catch{$rejected=$_.Exception.Message-match'ADB exit 1'}
Record 'missing-pid-opt-in-cannot-hide-other-command-exit1' ($rejected-and$commands[-1].exitCode-eq1) $commands[-1]
}
$script:mockOutput='pidof: error';$rejected=$false;try{Adb @('shell','pidof',$package) -AllowMissingPid|Out-Null}catch{$rejected=$_.Exception.Message-match'ADB exit 1'}
Record 'pidof-exit1-with-error-output-still-rejected' ($rejected-and$commands[-1].output-eq'pidof: error') $commands[-1]
foreach($mode in @('eventually-ready','absent','empty-zero','malformed-pid','black-ui','invalid-save','other-error','start-error','save-error')){
$script:mode=$mode;$script:pidCalls=0;$script:starts=0;$commands.Clear();$errorText=$null
try{StartHome "offline-$mode"}catch{$errorText=$_.Exception.Message}
$observationPath=Join-Path $EvidenceDir "offline-$mode-readiness.json"
$observations=if(Test-Path $observationPath){@(Get-Content $observationPath -Raw|ConvertFrom-Json)}else{@()}
if($mode-eq'eventually-ready'){
Record 'absent-pid-relaunches-and-requires-real-home-save-pid' (!$errorText-and$observations.Count-eq3-and$script:starts-eq3-and$observations[0].pid-eq''-and$observations[-1].pid-eq'77'-and$observations[-1].validAppSave-and$observations[-1].readyUi) @{observations=$observations;starts=$script:starts}
Record 'absent-pid-raw-exits-remain-in-command-evidence' (@($commands|Where-Object {$_.command-match'pidof'-and$_.exitCode-eq1}).Count-eq2) $commands.ToArray()
}elseif($mode-eq'other-error'){
Record 'startup-does-not-swallow-other-adb-error' ($errorText-match'ADB exit 2'-and$script:pidCalls-eq1) $errorText
}elseif($mode-eq'start-error'-or$mode-eq'save-error'){
Record 'startup-does-not-swallow-other-exit1' ($errorText-match'ADB exit 1') @{kind=$mode;error=$errorText}
}else{
Record 'unready-home-cannot-pass-thirty-bound' ($errorText-match'home-ready'-and$script:pidCalls-eq30-and$observations.Count-eq30) @{kind=$mode;error=$errorText;observations=$observations.Count;starts=$script:starts}
}
}
}catch{Record 'production-evaluation' $false $_.Exception.Message}
$passed=$checks.Count-gt0-and@($checks|Where-Object passed -ne $true).Count-eq0
@{passed=$passed;scope='Offline StartHome/Adb production bodies with leaf process/PNG mocks. Recorded Home PNG is real; process absence, invalid Save and black screen sequences are counterfactual, not native startup proof.';source=$Source;sourceSha256=(Get-FileHash $Source).Hash;homePng=$HomePng;homePngSha256=(Get-FileHash $HomePng).Hash;checks=$checks.ToArray()}|ConvertTo-Json -Depth 14|Set-Content (Join-Path $EvidenceDir 'startup-result.json')
if(!$passed){exit 1};exit 0