Files
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

190 lines
8.7 KiB
PowerShell
Raw Permalink 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
network-e2e — 网络端到端测试(docs/RE/test-cases/network-e2e.md)
.DESCRIPTION
场景 N-A(netman 全链路,首启调度):
firstInit="0\n0" 首启,挂 e1000(net0) + virtio-net(net1) 双网卡。
DSK 首启链 mouseInit → netman → FirstInit,netman 读取 conf.conf(mode=dhcp),
在 index=0 的 e1000 上执行 DHCP DISCOVER/OFFER/REQUEST/ACK → ARP 网关 → DNS example.com。
断言锚点(netman log_hex 为 16 位定宽小写十六进制,同行输出):
[virtio_net] selftest PASS: RX path ok (stage3 驱动自测,真实 slirp 后端 DHCP OFFER)
[netman] netdev_count=0x0000000000000002 (e1000 + virtio_net 双设备)
[netman] DHCP OFFER ip= / DHCP ACK, leased ip= / DHCP final rc=0x0...0
[netman] ARP: gateway resolved / ARP final rc=0x0...0
[netman] DNS example.com= / DNS final rc=0x0...0
[netman] network final rc=0x0000000000000000
netman 之后停在 FirstInit 向导即杀会话(向导自动化由 boot-regression B1 覆盖)。
场景 N-B(curl.elf 主机侧端到端,dev_mode shell):
firstInit="1\n1" → shell dev_tests → 交互 `curl`(PATH → /bin/CURL.ELF)。
主机侧 Start-TestHttpServer 监听 127.0.0.1:8000,guest 输入
`http://10.0.2.2:8000/` 经 slirp 网关访问主机服务;
断言主机侧 HTTP 服务器日志收到 "GET / HTTP/1.0"(端到端最强证据),
guest 侧断言 [curl] boot / [curl] exit / [shell] path: tool returned。
响应体只写帧缓冲(无串口),标 MANUAL。
退出码:全部通过 0,任一 FAIL 1。
#>
param(
[switch]$Build,
[string[]]$Scenarios = @('NA', 'NB')
)
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'lib\QemuTest.ps1')
Initialize-QemuTest -Build:$Build
$result = New-TestCaseResult 'network-e2e'
# ----------------------------------------------------------------
function Invoke-ScenarioNA {
Write-Host "`n--- N-A netman 全链路 (首启, e1000 + virtio-net 双网卡) ---"
Set-DeshabFirstInit -First 0 -DevMode 0
# run_qemu.bat 默认仅 e1000;追加第二网卡 virtio-net-pci 挂独立 slirp 后端 net1。
$s = Start-QemuSession -Name 'nete2e-na' -MonitorPort 45506 -ExtraArgs @(
'-netdev', 'user,id=net1',
'-device', 'virtio-net-pci,netdev=net1'
)
try {
$hit = Wait-QemuLog -Session $s -Patterns @(
'[netman] network final rc=',
'[netman] DHCP: no OFFER received',
'[netman] ARP: timeout',
'[netman] DNS: timeout',
'[PANIC]'
) -TimeoutSeconds 240
Start-Sleep -Seconds 2
$log = Read-QemuLogText $s.LogPath
$result.LogPath = $s.LogPath
# ---- N1/N2: 双网卡驱动与设备注册 ----
Assert-QemuLog $result $log -Ordered @(
'[e1000] netdev registered, index=0x0000000000000000',
'[virtio_net] netdev registered, index=',
'[virtio_net] selftest: TX path ok',
'[virtio_net] selftest: DHCP OFFER yiaddr=',
'[virtio_net] selftest PASS: RX path ok'
)
# ---- netman 全链路(N3 DHCP / N4 ARP / N5 DNS) ----
Assert-QemuLog $result $log -Ordered @(
'[DSK] loading netman',
'[netman] boot',
'[netman] netdev_count=0x0000000000000002',
'[netman] DHCP: sending DISCOVER',
'[netman] DHCP OFFER ip=',
'[netman] DHCP: sending REQUEST',
'[netman] DHCP ACK, leased ip=',
'[netman] DHCP final rc=0x0000000000000000',
'[netman] ARP: gateway resolved',
'[netman] ARP final rc=0x0000000000000000',
'[netman] DNS example.com=',
'[netman] DNS final rc=0x0000000000000000',
'[netman] network final rc=0x0000000000000000'
) -MustNotContain @(
'[PANIC]',
'[netman] DHCP: no OFFER received',
'[netman] ARP: timeout',
'[netman] DNS: timeout'
)
if ($hit -eq '[netman] network final rc=') {
Add-TestCheck $result 'N-A: netman DHCP+ARP+DNS 全链路 rc=0' 'PASS'
} else {
Add-TestCheck $result 'N-A: netman DHCP+ARP+DNS 全链路 rc=0' 'FAIL' "hit=$hit"
}
Add-TestNote $result 'N-A: netman 仅首启调度;后续 FirstInit 向导自动化由 boot-regression.ps1 B1 覆盖,本场景断言后即结束会话'
} finally {
Stop-QemuSession $s
}
}
# ----------------------------------------------------------------
function Invoke-ScenarioNB {
Write-Host "`n--- N-B curl.elf 主机侧端到端 (dev_mode shell → http://10.0.2.2:8000/) ---"
Set-DeshabFirstInit -First 1 -DevMode 1
Set-DeshabAutoexec -Lines @('ver', 'exit')
$httpLog = Join-Path $script:TestWorkDir 'nete2e-http-requests.log'
$httpJob = Start-TestHttpServer -Port 8000 -LogPath $httpLog
$s = Start-QemuSession -Name 'nete2e-nb' -MonitorPort 45506
try {
$hit = Wait-QemuLog -Session $s -Patterns @('=== 自动测试完成 ===', '[PANIC]') -TimeoutSeconds 240
if ($hit -ne '=== 自动测试完成 ===') {
$result.LogPath = $s.LogPath
Add-TestCheck $result 'N-B: shell dev_tests 完成' 'FAIL' "hit=$hit"
return
}
Add-TestCheck $result 'N-B: shell dev_tests 完成' 'PASS'
# --- 启动 curl 工具(PATH → /bin/CURL.ELF) ---
Start-Sleep -Seconds 1
Send-QemuText -Session $s -Text 'curl' -Enter
$h = Wait-QemuLog -Session $s -Patterns @('[curl] boot') -TimeoutSeconds 60
if (-not $h) { Add-TestCheck $result 'N-B: curl.elf PATH 加载启动' 'FAIL' 'missing [curl] boot'; return }
Add-TestCheck $result 'N-B: curl.elf PATH 加载启动' 'PASS'
# --- 输入 URL:经 slirp 网关 10.0.2.2 访问主机 127.0.0.1:8000 ---
Start-Sleep -Milliseconds 800
Send-QemuText -Session $s -Text 'http://10.0.2.2:8000/' -Enter -DelayMs 110
# 主机侧端到端证据:HTTP 服务器收到 guest 的 GET 请求
$deadline = (Get-Date).AddSeconds(45)
$hostGot = $false
while ((Get-Date) -lt $deadline) {
if ((Test-Path $httpLog) -and ((Get-Content $httpLog -Raw -ErrorAction SilentlyContinue) -match 'GET / HTTP/1\.0')) {
$hostGot = $true; break
}
Start-Sleep -Milliseconds 800
}
if ($hostGot) {
Add-TestCheck $result 'N-B: 主机 HTTP 服务器收到 guest GET /(TCP+IP+ETH 全链路)' 'PASS'
} else {
Add-TestCheck $result 'N-B: 主机 HTTP 服务器收到 guest GET /(TCP+IP+ETH 全链路)' 'FAIL' 'no request logged by host http server within 45s'
}
# --- Esc 退出 curl 返回 shell ---
Start-Sleep -Seconds 2
Send-QemuKeys -Session $s -Keys @('esc')
$h2 = Wait-QemuLog -Session $s -Patterns @('[curl] exit') -TimeoutSeconds 30
$logc = Read-QemuLogText $s.LogPath
if ($h2 -and $logc.Contains('[shell] path: tool returned')) {
Add-TestCheck $result 'N-B: curl Esc 退出返回 shell' 'PASS'
} else {
Add-TestCheck $result 'N-B: curl Esc 退出返回 shell' 'FAIL' 'missing [curl] exit / tool returned'
}
# --- Esc 回 DSK → cmd → desktop ---
Send-QemuKeys -Session $s -Keys @('esc')
$h3 = Wait-QemuLog -Session $s -Patterns @('desktop ready') -TimeoutSeconds 150
$log = Read-QemuLogText $s.LogPath
$result.LogPath = $s.LogPath
Assert-QemuLog $result $log -MustNotContain @('[PANIC]')
if ($h3) { Add-TestCheck $result 'N-B: Esc → cmd → desktop ready' 'PASS' }
else { Add-TestCheck $result 'N-B: Esc → cmd → desktop ready' 'FAIL' 'no desktop ready' }
Add-TestCheck $result 'N-B: HTTP 200 响应体与 DESHAB-NET-E2E-MARKER 渲染' 'MANUAL' 'curl 响应输出仅帧缓冲(无串口锚点);主机服务器固定回复 marker 页面,可 screendump 人工核对'
Add-TestNote $result 'N6/N11 ping 链路:由 userapps-matrix.ps1 交互阶段覆盖(ping 工具 10.0.2.2 四报文)'
Add-TestNote $result 'N7/N9 外网访问:依赖主机联网,不在自动化断言范围(文档标 🔶)'
} finally {
Stop-QemuSession $s
Stop-TestHttpServer $httpJob
}
}
# ----------------------------------------------------------------
try {
foreach ($sc in $Scenarios) {
switch ($sc.ToUpper()) {
'NA' { Invoke-ScenarioNA }
'NB' { Invoke-ScenarioNB }
default { Add-TestNote $result "未知场景 $sc,跳过" }
}
}
} finally {
Restore-DeshabScenario
}
Write-TestCaseResult $result
if ($result.Status -eq 'FAIL') { exit 1 } else { exit 0 }