This commit is contained in:
xyou
2026-07-31 13:53:49 +08:00
parent 5ea84fac97
commit f52157b7af
241 changed files with 26843 additions and 8155 deletions
+167
View File
@@ -0,0 +1,167 @@
#requires -Version 5.1
<#
.SYNOPSIS
linux-compat — UTSM+Linux 双内核兼容层端到端(docs/RE/test-cases/linux-compat.md)
.DESCRIPTION
动态检测 VMM/Linux guest 可用性,自动分流两条验证路径:
路径 A(guest VMX 可用,真机/KVM):
[UTSM] VMM init ok → VMM self-test PASS → bzImage 解析 → IPC shm →
vmlaunch → Linux version → initramfs init → daemon park →
[LNXC] service ready → DSK → shell dev_tests → dsl 命令实测
路径 B(QEMU WHPX/TCG 无 nested VMX —— 本环境预期路径):
[UTSM] VMM unavailable → Linux loader 跳过 → DSK 正常启动不崩溃 →
shell 收到 linux_compat 服务表 → dsl 报告运行态不可用 → desktop。
A5.1~A5.12 标记 SKIP(环境限制,非产品缺陷)。
依据 ISO/run_qemu.bat 说明:WHPX 下 VMXON 会触发致命 hypervisor exit,
因此框架默认 -cpu qemu64,-vmx 关闭 guest VMX CPUID,UTSM 走优雅降级。
若未来 WHPX/KVM 支持 nested VMX,可用 -Cpu 'max' 复测路径 A。
退出码:全部通过 0,任一 FAIL 1。
#>
param(
[switch]$Build,
[string]$Cpu = ''
)
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'lib\QemuTest.ps1')
Initialize-QemuTest -Build:$Build
$result = New-TestCaseResult 'linux-compat'
Set-DeshabFirstInit -First 1 -DevMode 1
Set-DeshabAutoexec -Lines @('ver', 'exit')
$s = Start-QemuSession -Name 'linux-compat' -Cpu $Cpu
try {
# ---- 分流点:VMM 自检通过 还是 VMM 不可用 ----
$fork = Wait-QemuLog -Session $s -Patterns @(
'[UTSM] VMM self-test PASS',
'[UTSM] VMM unavailable'
) -TimeoutSeconds 180
if ($fork -eq '[UTSM] VMM self-test PASS') {
# ================= 路径 A:VMX 可用,完整双内核流程 =================
Write-Host "`n--- 路径 A: guest VMX 可用,验证完整 Linux 兼容层 ---"
$hit = Wait-QemuLog -Session $s -Patterns @('=== 自动测试完成 ===', '[PANIC]') -TimeoutSeconds 300
$log = Read-QemuLogText $s.LogPath
$result.LogPath = $s.LogPath
# A5.1 ~ A5.7 启动链
Assert-QemuLog $result $log -Ordered @(
'[UTSM] VMM init ok',
'[UTSM] VMM self-test PASS',
'[LINUX] found bzImage module:',
'[UTSM] Linux loader init ok',
'[UTSM] IPC shm init ok',
'[VMM] launching guest',
'Linux version',
'[utsm-linux] init started',
'[LINUX] guest parked (daemon ready)',
'[LNXC] service ready',
'[DSK] boot',
'[shell] linux_compat service ok'
) -MustNotContain @('[PANIC]')
if (-not $hit -or $hit -eq '[PANIC]') {
Add-TestCheck $result 'A5.7: DSK/shell 接管' 'FAIL' 'dev_tests did not complete'
} else {
Add-TestCheck $result 'A5.7: DSK/shell 接管' 'PASS'
}
# A5.8 ~ A5.12 shell dsl 交互(dev_mode 串口镜像开启)
if ($hit -eq '=== 自动测试完成 ===') {
Start-Sleep -Seconds 1
Send-QemuText -Session $s -Text 'dsl' -Enter
$h1 = Wait-QemuLog -Session $s -Patterns @('Linux 兼容层已就绪') -TimeoutSeconds 60
if ($h1) { Add-TestCheck $result 'A5.8: dsl 状态查询' 'PASS' }
else { Add-TestCheck $result 'A5.8: dsl 状态查询' 'FAIL' 'missing 兼容层已就绪' }
Send-QemuText -Session $s -Text 'dsl ls' -Enter
$h2 = Wait-QemuLog -Session $s -Patterns @('bin', 'etc', 'deshab#') -TimeoutSeconds 60
if ($h2) { Add-TestCheck $result 'A5.9: dsl ls 目录列表' 'PASS' }
else { Add-TestCheck $result 'A5.9: dsl ls 目录列表' 'FAIL' 'no listing output' }
Send-QemuText -Session $s -Text 'dsl uname -a' -Enter
$h3 = Wait-QemuLog -Session $s -Patterns @('Linux') -TimeoutSeconds 60
if ($h3) { Add-TestCheck $result 'A5.10: dsl uname -a' 'PASS' }
else { Add-TestCheck $result 'A5.10: dsl uname -a' 'FAIL' 'no uname output' }
Send-QemuText -Session $s -Text 'dsl nosuchprog' -Enter
$h4 = Wait-QemuLog -Session $s -Patterns @('deshab# ') -TimeoutSeconds 60
Start-Sleep -Seconds 1
$log2 = Read-QemuLogText $s.LogPath
if ($h4 -and -not $log2.Contains('[PANIC]')) {
Add-TestCheck $result 'A5.12: dsl 错误路径不崩溃' 'PASS'
} else {
Add-TestCheck $result 'A5.12: dsl 错误路径不崩溃' 'FAIL' 'shell did not recover'
}
Send-QemuKeys -Session $s -Keys @('esc')
$h5 = Wait-QemuLog -Session $s -Patterns @('desktop ready') -TimeoutSeconds 150
if ($h5) { Add-TestCheck $result 'A5.x: Esc 后到 desktop' 'PASS' }
else { Add-TestCheck $result 'A5.x: Esc 后到 desktop' 'FAIL' 'no desktop ready' }
}
Add-TestNote $result '路径 A 执行:guest VMX 可用(真机/KVM 环境)'
}
elseif ($fork -eq '[UTSM] VMM unavailable') {
# ================= 路径 B:无 nested VMX,优雅降级 =================
Write-Host "`n--- 路径 B: guest 无 VMX(QEMU 预期),验证优雅降级 ---"
$hit = Wait-QemuLog -Session $s -Patterns @('=== 自动测试完成 ===', '[PANIC]') -TimeoutSeconds 240
$log = Read-QemuLogText $s.LogPath
$result.LogPath = $s.LogPath
# 降级锚点 + 系统继续正常启动
Assert-QemuLog $result $log -MustContain @('[UTSM] VMM unavailable')
Assert-QemuLog $result $log -Ordered @(
'[UTSM] SELFTEST PASS',
'[UTSM] VMM unavailable',
'[DSK] boot',
'[DSK] dev_mode=1 (developer auto-test)',
'[shell] boot',
'[shell] linux_compat service ok'
) -MustNotContain @('[PANIC]')
if ($hit -eq '=== 自动测试完成 ===') {
Add-TestCheck $result '降级路径: dev_tests 完成(Linux 缺失不阻塞启动)' 'PASS'
} else {
Add-TestCheck $result '降级路径: dev_tests 完成(Linux 缺失不阻塞启动)' 'FAIL' "hit=$hit"
}
# dsl 运行态不可用报告(服务表已传递,is_available()=0)
if ($hit -eq '=== 自动测试完成 ===') {
Start-Sleep -Seconds 1
Send-QemuText -Session $s -Text 'dsl' -Enter
$h = Wait-QemuLog -Session $s -Patterns @('linux_compat: not initialized') -TimeoutSeconds 40
if ($h) { Add-TestCheck $result '降级路径: dsl 报告运行态不可用' 'PASS' }
else { Add-TestCheck $result '降级路径: dsl 报告运行态不可用' 'FAIL' 'missing linux_compat: not initialized' }
Send-QemuKeys -Session $s -Keys @('esc')
$h2 = Wait-QemuLog -Session $s -Patterns @('desktop ready') -TimeoutSeconds 150
if ($h2) { Add-TestCheck $result '降级路径: Esc 后经 cmd 到 desktop' 'PASS' }
else { Add-TestCheck $result '降级路径: Esc 后经 cmd 到 desktop' 'FAIL' 'no desktop ready' }
}
# A5.1~A5.12 环境性跳过
foreach ($t in @('A5.1 VMM self-test', 'A5.2 bzImage 加载', 'A5.3 EPT+vmlaunch',
'A5.4 Linux 内核启动', 'A5.5 init 脚本', 'A5.6 daemon park',
'A5.8 dsl 状态就绪', 'A5.9 dsl ls', 'A5.10 dsl uname',
'A5.11 dsl cat hostname', 'A5.12 dsl 错误路径')) {
Add-TestCheck $result $t 'SKIP' 'QEMU WHPX/TCG 无 nested VMX(见 run_qemu.bat 注释),需真机或 KVM 复测'
}
Add-TestCheck $result 'A5.7: Linux 缺失时 DSK 正常接管' 'PASS'
Add-TestNote $result '路径 B 执行:QEMU 无 nested VMX,Linux guest 不可用属预期环境限制'
Add-TestNote $result '如需完整验证:真机(VT-x)或 Linux KVM (-enable-kvm -cpu host) 下以 -Cpu max 重跑'
}
else {
$result.LogPath = $s.LogPath
Add-TestCheck $result 'VMM 分流探测' 'FAIL' 'neither VMM self-test PASS nor VMM unavailable within 180s'
}
} finally {
Stop-QemuSession $s
Restore-DeshabScenario
}
Write-TestCaseResult $result
if ($result.Status -eq 'FAIL') { exit 1 } else { exit 0 }