@@ -19,32 +19,24 @@ function Fail-Test([string]$desc) { Write-Host " FAIL $desc"; $script:fail++ }
1919
2020# Runs the binary with $binArgs. Returns ([string] output, [int] exitCode).
2121# exitCode is -99 on timeout. $captureStderr controls whether stderr is merged.
22+ # Uses Start-Job + & operator so the process inherits a proper console context,
23+ # matching how the "Full CLI output" step runs the binary directly.
2224function invoke_bin ([string []]$binArgs , [bool ]$captureStderr = $true ) {
23- $tmpOut = New-TemporaryFile
24- $tmpErr = New-TemporaryFile
25- try {
26- $proc = Start-Process `
27- - FilePath $script :BIN `
28- - ArgumentList $binArgs `
29- - NoNewWindow `
30- - PassThru `
31- - RedirectStandardOutput $tmpOut.FullName `
32- - RedirectStandardError $tmpErr.FullName
33-
34- $finished = $proc.WaitForExit ($script :TIMEOUT_SECS * 1000 )
35- if (-not $finished ) {
36- $proc.Kill ()
37- return $null , -99
38- }
39-
40- $out = (Get-Content $tmpOut.FullName - Raw) ?? " "
41- if ($captureStderr ) {
42- $out += (Get-Content $tmpErr.FullName - Raw) ?? " "
43- }
44- return $out.TrimEnd (), $proc.ExitCode
45- } finally {
46- Remove-Item $tmpOut.FullName , $tmpErr.FullName - Force - ErrorAction SilentlyContinue
25+ $job = Start-Job - ScriptBlock {
26+ param ($bin , $args , $captureErr )
27+ $out = if ($captureErr ) { & $bin @args 2>&1 } else { & $bin @args }
28+ [PSCustomObject ]@ { Output = ($out -join " `n " ); ExitCode = $LASTEXITCODE }
29+ } - ArgumentList $script :BIN , $binArgs , $captureStderr
30+
31+ if ($job | Wait-Job - Timeout $script :TIMEOUT_SECS ) {
32+ $result = Receive-Job $job
33+ Remove-Job $job - Force
34+ return ($result ?.Output ?? " " ), ($result ?.ExitCode ?? 0 )
4735 }
36+
37+ Stop-Job $job
38+ Remove-Job $job - Force
39+ return $null , -99
4840}
4941
5042function check ([string ]$desc , [string []]$binArgs ) {
@@ -83,50 +75,55 @@ function range_out([string]$desc, [int]$lo, [int]$hi, [string[]]$binArgs) {
8375Write-Host " === vmaware CLI tests ==="
8476Write-Host " "
8577
86- # --- exit codes ---
78+ # exit codes (cheap flags only — no full detection scan)
8779Write-Host " exit codes"
8880check " --help exits 0" @ (" --help" )
8981check " --version exits 0" @ (" --version" )
9082check " --brand-list exits 0" @ (" --brand-list" )
91- check " --detect exits 0" @ (" --detect" )
92- check " --percent exits 0" @ (" --percent" )
93- check " --brand exits 0" @ (" --brand" )
94- check " --type exits 0" @ (" --type" )
95- check " --conclusion exits 0" @ (" --conclusion" )
9683check " --number exits 0" @ (" --number" )
97-
98- $out , $code = invoke_bin @ (" --stdout" )
99- if ($code -eq -99 ) { Fail- Test " --stdout exits 0 or 1 (timeout after ${TIMEOUT_SECS} s)" }
100- elseif ($code -le 1 ) { ok " --stdout exits 0 or 1" }
101- else { Fail- Test " --stdout exits 0 or 1" }
102-
10384check_fails " unknown arg exits non-zero" @ (" --this-arg-does-not-exist" )
10485
105- # --- short-flag aliases ---
86+ # short-flag aliases (cheap flags only)
10687Write-Host " "
10788Write-Host " short flag aliases"
10889check " -h exits 0" @ (" -h" )
10990check " -v exits 0" @ (" -v" )
110- check " -a exits 0" @ (" -a" , " --detect" )
111- check " -d exits 0" @ (" -d" )
112- check " -b exits 0" @ (" -b" )
113- check " -p exits 0" @ (" -p" )
114- check " -c exits 0" @ (" -c" )
11591check " -n exits 0" @ (" -n" )
116- check " -t exits 0" @ (" -t" )
11792check " -l exits 0" @ (" -l" )
11893
119- # --- output format ---
94+ # output format + exit codes for full-scan flags (one scan per flag)
12095Write-Host " "
12196Write-Host " output format"
12297match_out " --detect outputs 0 or 1" ' ^[01]$' @ (" --detect" )
12398range_out " --percent outputs 0-100" 0 100 @ (" --percent" )
12499match_out " --number outputs a positive int" ' ^[1-9][0-9]*$' @ (" --number" )
100+
101+ $out , $code = invoke_bin @ (" --stdout" )
102+ if ($code -eq -99 ) { Fail- Test " --stdout exits 0 or 1 (timeout after ${TIMEOUT_SECS} s)" }
103+ elseif ($code -le 1 ) { ok " --stdout exits 0 or 1" }
104+ else { Fail- Test " --stdout exits 0 or 1" }
105+
125106match_out " --brand outputs a non-empty line" ' .' @ (" --brand" )
126107match_out " --type outputs a non-empty line" ' .' @ (" --type" )
127108match_out " --conclusion outputs a sentence" ' .' @ (" --conclusion" )
128109
129- # --- no-ansi strips escape codes ---
110+ # short-flag aliases for full-scan flags (reuse match_out to avoid duplicate scans)
111+ Write-Host " "
112+ Write-Host " short flag aliases (full-scan)"
113+ match_out " -d outputs 0 or 1" ' ^[01]$' @ (" -d" )
114+ match_out " -b outputs a non-empty line" ' .' @ (" -b" )
115+ match_out " -p outputs 0-100" ' ^[0-9]+$' @ (" -p" )
116+ match_out " -c outputs a sentence" ' .' @ (" -c" )
117+ match_out " -t outputs a non-empty line" ' .' @ (" -t" )
118+
119+ $out , $code = invoke_bin @ (" -s" )
120+ if ($code -eq -99 ) { Fail- Test " -s exits 0 or 1 (timeout after ${TIMEOUT_SECS} s)" }
121+ elseif ($code -le 1 ) { ok " -s exits 0 or 1" }
122+ else { Fail- Test " -s exits 0 or 1" }
123+
124+ check " -a exits 0" @ (" -a" , " --detect" )
125+
126+ # no-ansi strips escape codes
130127Write-Host " "
131128Write-Host " no-ansi"
132129$ansiOut , $_ = invoke_bin @ (" --no-ansi" )
@@ -136,7 +133,7 @@ if ($ansiOut -match '\x1B\[') {
136133 ok " --no-ansi output contains no ANSI escape codes"
137134}
138135
139- # --- technique count ---
136+ # technique count
140137Write-Host " "
141138Write-Host " technique count"
142139$nOut , $_ = invoke_bin @ (" --number" ) $false
@@ -147,14 +144,14 @@ if ($n -match '^\d+$' -and [int]$n -gt 10) {
147144 Fail- Test " --number returned unexpected value: $n "
148145}
149146
150- # --- mutual exclusion ---
147+ # mutual exclusion
151148Write-Host " "
152149Write-Host " mutual exclusion"
153150check_fails " --detect + --brand rejected" @ (" --detect" , " --brand" )
154151check_fails " --percent + --brand rejected" @ (" --percent" , " --brand" )
155152check_fails " --stdout + --detect rejected" @ (" --stdout" , " --detect" )
156153
157- # --- -- disable: valid names ---
154+ # --disable: valid names
158155Write-Host " "
159156Write-Host " --disable (valid names)"
160157check " --disable single name works" @ (" --disable" , " HYPERVISOR_BIT" , " --detect" )
@@ -168,13 +165,13 @@ check "--disable HYPERVISOR_HOOK works" @("--disable", "HYPERVISOR_HOO
168165check " --disable SINGLE_STEP works" @ (" --disable" , " SINGLE_STEP" , " --detect" )
169166check " --disable DBVM works" @ (" --disable" , " DBVM" , " --detect" )
170167
171- # --- -- disable: invalid names ---
168+ # --disable: invalid names
172169Write-Host " "
173170Write-Host " --disable (invalid names)"
174171check_fails " --disable bogus name fails" @ (" --disable" , " NOT_A_REAL_TECHNIQUE" , " --detect" )
175172check_fails " --disable MULTIPLE (setting) fails" @ (" --disable" , " MULTIPLE" , " --detect" )
176173
177- # --- -- disable reflected in general output ---
174+ # --disable reflected in general output
178175Write-Host " "
179176Write-Host " --disable reflected in general output"
180177$disOut , $_ = invoke_bin @ (" --no-ansi" , " --disable" , " HYPERVISOR_BIT" )
@@ -184,7 +181,7 @@ if ($disOut -match "Skipped CPUID hypervisor bit") {
184181 Fail- Test " --disable HYPERVISOR_BIT not reflected in general output"
185182}
186183
187- # --- -- high-threshold ---
184+ # --high-threshold
188185Write-Host " "
189186Write-Host " --high-threshold"
190187$pNOut , $_ = invoke_bin @ (" --percent" ) $false
@@ -197,18 +194,18 @@ if ($pN -ge $pH) {
197194 Fail- Test " --high-threshold produced higher percentage ($pN -> $pH )"
198195}
199196
200- # --- -- all ---
197+ # --all
201198Write-Host " "
202199Write-Host " --all"
203200check " --all --detect exits 0" @ (" --all" , " --detect" )
204201check " --all --percent exits 0" @ (" --all" , " --percent" )
205202
206- # --- -- dynamic ---
203+ # --dynamic
207204Write-Host " "
208205Write-Host " --dynamic"
209206check " --dynamic --conclusion exits 0" @ (" --dynamic" , " --conclusion" )
210207
211- # --- -- json ---
208+ # --json
212209Write-Host " "
213210Write-Host " --json"
214211$tmpJson = [System.IO.Path ]::GetTempFileName() + " .json"
@@ -234,7 +231,7 @@ try {
234231 if (Test-Path $tmpJson ) { Remove-Item $tmpJson - Force }
235232}
236233
237- # --- -- brand-list ---
234+ # --brand-list
238235Write-Host " "
239236Write-Host " --brand-list"
240237$blOut , $_ = invoke_bin @ (" --brand-list" ) $false
@@ -246,7 +243,7 @@ if ($count -gt 5) {
246243 Fail- Test " --brand-list returned too few entries ($count lines)"
247244}
248245
249- # --- summary ---
246+ # summary
250247Write-Host " "
251248Write-Host " ==========================="
252249Write-Host " Passed: $ ( $script :pass ) "
0 commit comments