Log PowerShell stdout in Windows tests

This commit is contained in:
Esdras Renan 2025-10-20 22:15:15 -03:00
parent 6234924878
commit 8312330c2e

View file

@ -699,28 +699,22 @@ fn collect_windows_extended() -> serde_json::Value {
} }
fn parse_powershell_json(bytes: &[u8]) -> Option<serde_json::Value> { fn parse_powershell_json(bytes: &[u8]) -> Option<serde_json::Value> {
if bytes.is_empty() { let text = decode_powershell_text(bytes)?;
if text.is_empty() {
return None; return None;
} }
if bytes.starts_with(&[0xFF, 0xFE]) { match serde_json::from_str::<serde_json::Value>(&text) {
return parse_utf16_le_bytes(&bytes[2..]); Ok(value) => Some(value),
} Err(err) => {
if bytes.len() >= 2 && bytes[1] == 0 { if cfg!(test) {
if let Some(val) = parse_utf16_le_bytes(bytes) { let preview = text.chars().take(512).collect::<String>();
return Some(val); eprintln!(
"[collect_windows_extended] falha ao interpretar JSON: {err}; amostra: {preview}"
);
}
None
} }
} }
if bytes.contains(&0) {
if let Some(val) = parse_utf16_le_bytes(bytes) {
return Some(val);
}
}
let text = std::str::from_utf8(bytes).ok()?;
let trimmed = text.trim();
if trimmed.is_empty() {
return None;
}
serde_json::from_str(trimmed).ok()
} }
fn decode_powershell_text(bytes: &[u8]) -> Option<String> { fn decode_powershell_text(bytes: &[u8]) -> Option<String> {
@ -740,7 +734,12 @@ fn collect_windows_extended() -> serde_json::Value {
return Some(s); return Some(s);
} }
} }
std::str::from_utf8(bytes).map(|s| s.to_string()).ok() let text = std::str::from_utf8(bytes).ok()?.trim().to_string();
if text.is_empty() {
None
} else {
Some(text)
}
} }
fn decode_utf16_le_to_string(bytes: &[u8]) -> Option<String> { fn decode_utf16_le_to_string(bytes: &[u8]) -> Option<String> {
@ -751,9 +750,13 @@ fn collect_windows_extended() -> serde_json::Value {
.chunks_exact(2) .chunks_exact(2)
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]])) .map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
.collect(); .collect();
String::from_utf16(&utf16) let text = String::from_utf16(&utf16).ok()?;
.ok() let trimmed = text.trim();
.map(|s| s.trim().to_string()) if trimmed.is_empty() {
None
} else {
Some(trimmed.to_string())
}
} }
fn encode_ps_script(script: &str) -> String { fn encode_ps_script(script: &str) -> String {
@ -781,15 +784,23 @@ fn collect_windows_extended() -> serde_json::Value {
.arg(encoded) .arg(encoded)
.output() .output()
.ok()?; .ok()?;
if out.stdout.is_empty() { let stdout_text = decode_powershell_text(&out.stdout);
if cfg!(test) && !out.stderr.is_empty() { if cfg!(test) {
if let Some(ref txt) = stdout_text {
let preview = txt.chars().take(512).collect::<String>();
eprintln!("[collect_windows_extended] stdout `{cmd}` => {preview}");
} else {
eprintln!("[collect_windows_extended] stdout `{cmd}` => <vazio>");
}
if !out.stderr.is_empty() {
if let Some(err) = decode_powershell_text(&out.stderr) { if let Some(err) = decode_powershell_text(&out.stderr) {
eprintln!("[collect_windows_extended] PowerShell stderr for `{cmd}`: {err}"); eprintln!("[collect_windows_extended] stderr `{cmd}` => {err}");
} else {
eprintln!("[collect_windows_extended] stderr `{cmd}` => <binário>");
} }
} }
return None;
} }
parse_powershell_json(&out.stdout) stdout_text.and_then(|text| serde_json::from_str::<serde_json::Value>(&text).ok())
} }
let software = ps(r#"@(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'; Get-ItemProperty 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*') | Where-Object { $_.DisplayName } | Select-Object DisplayName, DisplayVersion, Publisher"#) let software = ps(r#"@(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'; Get-ItemProperty 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*') | Where-Object { $_.DisplayName } | Select-Object DisplayName, DisplayVersion, Publisher"#)