Files
Deshab-OS/tests/qemu/Run-All.ps1
T
xyou a26866e339 feat: B7 APIC/IOAPIC接管 + NVMe写路径 + virtio_net virtqueue + PE兼容层修复 + QEMU测试套件全自动化
中断路由 (B7):
- apic.drv: LAPIC enable + IOAPIC重定向表编程(MADT ISO感知) + apic_route/apic_route_legacy/apic_diag开关
- UTSM: LAPIC EOI钩子(register_apic_eoi, ABI尾部追加) + IDT 0-255全覆盖 + spurious 0xFF特判
- FUCK: apic_route=0默认PIC(零回归) / =1 IOAPIC->LAPIC接管(失败完整降级) / legacy放开IRQ1/12/11

存储:
- nvme.drv: 写路径 + PRP list + 读回校验 + MSI/MSI-X中断驱动(nvme_msi开关, 回退纯轮询)
- build.ps1: apic.drv纳入构建(原为预置二进制)

网络:
- virtio_net: virtqueue RX/TX + netdev注册 + DHCP自测(slirp真实OFFER)

PE兼容层:
- pe_shim: guest->host指针转换(g_emu_mem_base + gp()) + shim fn32列补齐
- gen_pe.py: PE32+ RVA偏置修复(BUG-004) + cmd.exe生成
- desktop_app.h: da_mouse_poll先判AUX位 + da_mouse_init冲刷残留(BUG-003/008)
- shell: Ctrl修饰键跟踪(BUG-001) + g_run_image扩至1MB(BUG-002)

QEMU测试套件:
- 9用例全自动化(Run-All.ps1): boot-regression/driver-matrix/linux-compat/pe-compat/deaicup-e2e/userapps-matrix/network-e2e/performance-baseline/x86emu32-coverage
- QemuTest.ps1公共库: 串口断言/monitor sendkey/screendump/HTTP服务器/并发隔离

文档:
- CLAUDE.md: APIC/IOAPIC能力 + kernel_api暴露 + IRQ后端升级状态
- LESSONS_LEARNED.md: B7 LAPIC/IOAPIC经验教训(2条)
- Bug记录.txt: BUG-20260801-001~008 + BUG-20260803-009(9条)
- test-cases/*.md: 全部补充自动化脚本小节
- 桌面设计.md: .lnk快捷方式 + LINUXAPP.CNF Linux应用图标
- 系统开发策划.md: NVMe/virtio_net标完成 + B2/B7标已解决 + M2进度列
2026-08-04 18:08:08 +08:00

116 lines
4.7 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#requires -Version 5.1
<#
.SYNOPSIS
Run-All — Deshab QEMU 自动化测试套件总运行器
.DESCRIPTION
顺序执行 tests/qemu 下全部 9 个用例脚本,每用例独立 powershell 子进程
(独立 QEMU 会话 + firstInit/AUTOEXEC 场景隔离),汇总 PASS/FAIL/耗时。
用例顺序(依赖与耗时综合考虑,快用例靠后):
1. boot-regression.ps1 B1 首启向导 / B2 正常 / B3 dev_mode / B4 无盘 / B5 无 NIC
2. driver-matrix.ps1 16 清单驱动加载矩阵 + NVMe 写路径回归
3. linux-compat.ps1 VMM 分流(QEMU 走 VMM unavailable 优雅降级路径)
4. pe-compat.ps1 PE32+ 原生 + PE32 x86emu32 + 错误路径
5. deaicup-e2e.ps1 Deaicup GUI PE 端到端(首帧像素/键鼠消息/Esc 退出链)
6. userapps-matrix.ps1 shell dev_tests + ping/editor/fileman/browser 工具链
7. network-e2e.ps1 N-A netman 全链路 + N-B curl 主机侧端到端
8. performance-baseline.ps1
启动阶段墙上计时 → .build_tmp/perf_baseline.json
9. x86emu32-coverage.ps1 x86emu32 静态枚举 + hello32 动态解释执行
.PARAMETER Only
只跑指定用例(逗号分隔的脚本基名,大小写不敏感):
.\Run-All.ps1 -Only network-e2e,x86emu32-coverage
.PARAMETER Build
先执行一次 build.ps1(全量编译+打包镜像)再跑用例。
.NOTES
退出码:全部用例 PASS → 0;任一 FAIL → 1。
每用例完整输出存档 .build_tmp\tests\runall\<case>.log。
#>
param(
[string[]]$Only = @(),
[switch]$Build
)
$ErrorActionPreference = 'Stop'
$suiteRoot = $PSScriptRoot
$repoRoot = [System.IO.Path]::GetFullPath((Join-Path $suiteRoot '..\..'))
$outDir = Join-Path $repoRoot '.build_tmp\tests\runall'
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
# ---- 跑前清理:只杀本套件历史会话残留的 QEMU(-name deshabtest- 标记)。
# 绝不全局清理——可能有其他代理/人工在并发跑 QEMU(如 monitor 45454 的调试会话)。
# 本套件所有会话默认 -snapshot(镜像只读),无需靠杀进程解决镜像锁。 ----
. (Join-Path $suiteRoot 'lib\QemuTest.ps1')
Stop-ResidualQemu
# ---- 可选:先构建一次 ----
if ($Build) {
Write-Host '[runall] running build.ps1 ...'
& powershell -ExecutionPolicy Bypass -File (Join-Path $repoRoot 'build.ps1')
if ($LASTEXITCODE -ne 0) { Write-Host "[runall] build.ps1 FAILED (exit $LASTEXITCODE)"; exit 1 }
}
$cases = @(
'boot-regression',
'driver-matrix',
'linux-compat',
'pe-compat',
'deaicup-e2e',
'userapps-matrix',
'network-e2e',
'performance-baseline',
'x86emu32-coverage'
)
if ($Only.Count -gt 0) {
# -File 调用下逗号列表常作为单个字符串传入,统一按逗号再切一次
$want = @($Only | ForEach-Object { $_ -split ',' } | ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ })
$cases = @($cases | Where-Object { $want -contains $_.ToLower() })
if ($cases.Count -eq 0) { Write-Host "[runall] -Only 过滤后无用例可跑: $($Only -join ',')"; exit 1 }
}
$rows = New-Object System.Collections.ArrayList
$suiteStart = Get-Date
foreach ($case in $cases) {
$script = Join-Path $suiteRoot "$case.ps1"
$log = Join-Path $outDir "$case.log"
Write-Host ''
Write-Host ("================ [runall] {0} ================" -f $case)
$t0 = Get-Date
& powershell -ExecutionPolicy Bypass -File $script 2>&1 | Tee-Object -FilePath $log | Out-Host
$rc = $LASTEXITCODE
$dur = [math]::Round(((Get-Date) - $t0).TotalSeconds, 1)
$outText = ''
if (Test-Path $log) { $outText = Get-Content $log -Raw }
$manualCount = ([regex]::Matches($outText, '\[MANUAL\]')).Count
$skipCount = ([regex]::Matches($outText, '\[SKIP\]')).Count
$status = 'PASS'
if ($rc -ne 0) { $status = 'FAIL' }
[void]$rows.Add([pscustomobject]@{
Case = $case
Status = $status
Duration = "${dur}s"
Manual = $manualCount
Skip = $skipCount
ExitCode = $rc
Log = $log
})
}
# ---- 汇总表 ----
$totalDur = [math]::Round(((Get-Date) - $suiteStart).TotalMinutes, 1)
Write-Host ''
Write-Host ("================ 测试套件汇总 ({0} min) ================" -f $totalDur)
$rows | Format-Table Case, Status, Duration, Manual, Skip, ExitCode -AutoSize | Out-Host
$failCount = @($rows | Where-Object { $_.Status -eq 'FAIL' }).Count
$passCount = @($rows | Where-Object { $_.Status -eq 'PASS' }).Count
Write-Host ("PASS: {0} FAIL: {1} TOTAL: {2}" -f $passCount, $failCount, $rows.Count)
Write-Host ("日志目录: {0}" -f $outDir)
if ($failCount -gt 0) { exit 1 } else { exit 0 }