# Offline contract test: no Docker daemon or production access needed. $ErrorActionPreference = 'Stop' $repoRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent $output = Join-Path $repoRoot 'artifacts/backend-baseline/offline-test.json' $mockState = @{ Calls = [Collections.Generic.List[object]]::new(); EmptyStats = $false } function docker { param([Parameter(ValueFromRemainingArguments = $true)][string[]]$DockerArgs) $mockState.Calls.Add($DockerArgs) $global:LASTEXITCODE = 0 switch ($DockerArgs[0]) { 'compose' { if ($DockerArgs -contains 'config') { '{"services":{"api":{"image":"example/api:test","environment":{"PASSWORD":"MUST_NOT_LEAK"},"command":"MUST_NOT_LEAK","deploy":{"resources":{"limits":{"memory":"280M","cpus":"0.85"}}}}}}' } else { 'aaaaaaaaaaaa'; 'bbbbbbbbbbbb' } } 'info' { '{"server_version":"test","os_type":"linux","cpus":2,"memory_bytes":1073741824}' } 'inspect' { '{"id":"' + $DockerArgs[-1] + '","image_id":"sha256:test","running":true,"memory_limit_bytes":293601280,"oom_killed":false,"restart_count":0}' } 'stats' { if ($mockState.EmptyStats) { return } '{"id":"aaaaaaaaaaaa","cpu_percent":"1.0%","memory_usage":"20MiB / 280MiB"}' '{"id":"bbbbbbbbbbbb","cpu_percent":"2.0%","memory_usage":"30MiB / 280MiB"}' } default { throw 'unexpected Docker operation' } } } & (Join-Path $repoRoot 'scripts/collect-backend-baseline.ps1') -OutputPath $output -Samples 1 $raw = Get-Content -LiteralPath $output -Raw $result = $raw | ConvertFrom-Json if ($result.status -ne 'collected') { throw 'collector did not succeed' } if ($result.containers.Count -ne 2 -or $result.samples[0].containers.Count -ne 2) { throw 'NDJSON multi-container stats were lost' } if ($raw.Contains('MUST_NOT_LEAK') -or $raw.Contains('PASSWORD')) { throw 'raw Compose secrets leaked' } if ($result.configured_services[0].memory_limit -ne '280M') { throw 'effective resource limit missing' } if ($mockState.Calls.Count -eq 0) { throw 'Docker mock was not exercised' } foreach ($call in $mockState.Calls) { if ($call[0] -notin @('compose', 'info', 'inspect', 'stats')) { throw 'unexpected operation' } if ($call[0] -eq 'compose' -and -not ($call -contains 'config' -or $call -contains 'ps')) { throw 'mutating Compose operation' } } $mockState.EmptyStats = $true & (Join-Path $repoRoot 'scripts/collect-backend-baseline.ps1') -OutputPath $output -Samples 1 if ($LASTEXITCODE -ne 2) { throw 'missing stats must exit 2' } $partial = Get-Content -LiteralPath $output -Raw | ConvertFrom-Json if ($partial.status -ne 'partial' -or $partial.samples[0].complete -ne $false) { throw 'empty stats reported as complete' } Write-Output 'PASS: multi-container snapshot, resource projection, secret exclusion, read-only operations, incomplete stats detection' exit 0