71 lines
6.1 KiB
PowerShell
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
|