mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 21:50:44 +00:00
阶段1 网络加速 - 发现隧道在跑 QUIC(ExecStart 丢了 --protocol http2), 实测 QUIC 可用率 48% vs HTTP/2 80%+,是重大性能回退。 恢复后公网延迟从 4141ms 降到 690ms(快 6 倍),可用率 92%。 - 优选 IP 结论:无效。hosts 覆盖确实生效了(日志里连的就是指定 IP), 但落点仍是 lax —— 运营商把所有 Cloudflare anycast 都路由到美西。 已清掉这段无效配置。 - BBR 不可用:设备是自定义内核 6.4.0-rc4-jsbsbxjxh66, 没编 tcp_bbr 模块也没配置项。改用 cubic + 调优: TCP 缓冲 4MB、tcp_fastopen=3、tcp_slow_start_after_idle=0 (长轮询场景关键)、tcp_tw_reuse=1。 阶段2 官网重做 - 拆出独立模块 relay/landing.py(relay.py 已两千多行, 再塞 HTML 没法看) - 信息结构参考成熟产品站:吸顶导航 / Hero / 九宫格功能 / 三步上手 / 下载 / FAQ / 页脚 - 保持白色简洁:底白、浅灰面板、细边框、大量留白 - logo 用内联 SVG(ICO 放 img 里实测是破图) - 管理入口从官网移除(管理不对外开放) 过程中被自己的测试抓到两个 bug: - 模块叫 site.py 会和 Python 标准库重名,import site 拿到的是标准库 - _logo() 里把 % 格式化和字符串拼接混用,直接抛 TypeError
503 lines
23 KiB
PowerShell
503 lines
23 KiB
PowerShell
# 局域网遥控 全量验证脚本
|
||
#
|
||
# 依次执行:
|
||
# 0. 清理上一次测试可能残留的进程(否则发现端口会被抢占,导致假失败)
|
||
# 1. Python 被控端协议回归(含屏幕镜像/截屏)
|
||
# 2. 手表屏幕布局适配核算(490x602)
|
||
# 3. 屏幕共享可见提示(真实界面 + Win32 窗口枚举)
|
||
# 4. 小窗口 / 无托盘 / 后台常驻 / 双启动找回窗口
|
||
# 5. Java 协议层编译
|
||
# 6. Java <-> 桩服务端(含帧流、截屏、自动发现、单播探测)
|
||
# 7. Java <-> 打包后的 EXE 端到端
|
||
#
|
||
# 用法: powershell -ExecutionPolicy Bypass -File _tests\verify_all.ps1
|
||
|
||
$ErrorActionPreference = "Continue"
|
||
$root = Split-Path -Parent $PSScriptRoot
|
||
$tc = Join-Path $root "..\starklink\toolchain"
|
||
$jdk = Join-Path $tc "jdk17"
|
||
$java = Join-Path $jdk "bin\java.exe"
|
||
$javac= Join-Path $jdk "bin\javac.exe"
|
||
$out = Join-Path $root "_tests\out_java"
|
||
$exe = Join-Path $root "dist_exe\ykxmz\ykxmz.exe"
|
||
$androidJar = Join-Path $tc "android-sdk\platforms\android-34\android.jar"
|
||
|
||
$script:results = @()
|
||
|
||
function Record($name, $ok) {
|
||
$script:results += [pscustomobject]@{ 项目 = $name; 结果 = $(if ($ok) { "PASS" } else { "FAIL" }) }
|
||
}
|
||
|
||
function Banner($text) {
|
||
Write-Host ""
|
||
Write-Host ("=" * 70) -ForegroundColor DarkCyan
|
||
Write-Host " $text" -ForegroundColor Cyan
|
||
Write-Host ("=" * 70) -ForegroundColor DarkCyan
|
||
}
|
||
|
||
function Show-Fails($lines) {
|
||
# 失败的阶段光看最后几行没用,得把 [FAIL] 打出来
|
||
$fails = $lines | Select-String -Pattern '\[FAIL\]'
|
||
if ($fails) {
|
||
$fails | Select-Object -First 8 | ForEach-Object {
|
||
Write-Host " $($_.Line.Trim())" -ForegroundColor Red
|
||
}
|
||
}
|
||
$lines | Select-Object -Last 1 | ForEach-Object {
|
||
Write-Host " $($_.Trim())"
|
||
}
|
||
}
|
||
|
||
function Close-TestWindows {
|
||
# 测试会弹真实的 Tk 窗口(首次设置、投图、屏幕共享提示…)。
|
||
# 正常路径下测试自己会关;但用例失败/超时时进程还挂着,
|
||
# 窗口就留在屏幕上不走了。这里统一收尾。
|
||
$closed = 0
|
||
Get-Process python, pythonw -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.Id -ne $PID } |
|
||
ForEach-Object {
|
||
$line = (Get-CimInstance Win32_Process -Filter "ProcessId=$($_.Id)" -ErrorAction SilentlyContinue).CommandLine
|
||
if ($line -and ($line -match '_tests' -or $line -match 'run_agent' `
|
||
-or $line -match 'relay\.py')) {
|
||
# 先好好关主窗口
|
||
try { $_.CloseMainWindow() | Out-Null } catch { }
|
||
Start-Sleep -Milliseconds 250
|
||
if (-not $_.HasExited) {
|
||
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
|
||
}
|
||
$closed++
|
||
}
|
||
}
|
||
|
||
# 被控端自己(测试起过 ykxmz.exe)
|
||
Get-Process ykxmz -ErrorAction SilentlyContinue | ForEach-Object {
|
||
try { $_.CloseMainWindow() | Out-Null } catch { }
|
||
Start-Sleep -Milliseconds 250
|
||
if (-not $_.HasExited) {
|
||
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
|
||
}
|
||
$closed++
|
||
}
|
||
|
||
# Java 测试进程
|
||
Get-Process java -ErrorAction SilentlyContinue | ForEach-Object {
|
||
$line = (Get-CimInstance Win32_Process -Filter "ProcessId=$($_.Id)" -ErrorAction SilentlyContinue).CommandLine
|
||
if ($line -and ($line -match 'JavaClientTest' -or $line -match 'JavaRelayTest')) {
|
||
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
|
||
$closed++
|
||
}
|
||
}
|
||
|
||
if ($closed -gt 0) {
|
||
Write-Host " 关了 $closed 个测试进程/窗口" -ForegroundColor DarkGray
|
||
}
|
||
Start-Sleep -Milliseconds 400
|
||
}
|
||
|
||
function Stop-Strays {
|
||
Get-Process ykxmz -ErrorAction SilentlyContinue |
|
||
ForEach-Object { Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue }
|
||
|
||
# 各测试会临时起 relay.py / stub / java。
|
||
# 只清 run_agent/run_stub 是不够的 —— 漏掉的 relay.py 如果没及时退出,
|
||
# 端口就占着,下一个测试起不来,报出"假失败"
|
||
# (实测:chunked 单跑 9/9、协议单跑 69/69,套件里却 FAIL)。
|
||
Get-Process python, pythonw -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.Id -ne $PID } |
|
||
ForEach-Object {
|
||
$line = (Get-CimInstance Win32_Process -Filter "ProcessId=$($_.Id)" -ErrorAction SilentlyContinue).CommandLine
|
||
if ($line -and ($line -match 'run_agent' -or $line -match 'run_stub' `
|
||
-or $line -match 'relay\.py' -or $line -match '_tests')) {
|
||
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
|
||
}
|
||
}
|
||
|
||
# Java 测试进程(JavaClientTest / JavaRelayTest)
|
||
Get-Process java -ErrorAction SilentlyContinue |
|
||
ForEach-Object {
|
||
$line = (Get-CimInstance Win32_Process -Filter "ProcessId=$($_.Id)" -ErrorAction SilentlyContinue).CommandLine
|
||
if ($line -and ($line -match 'JavaClientTest' -or $line -match 'JavaRelayTest')) {
|
||
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
|
||
}
|
||
}
|
||
|
||
# 等到关键端口真的空出来(最多 6 秒),别让下一个测试撞上
|
||
for ($i = 0; $i -lt 12; $i++) {
|
||
$busy = $false
|
||
foreach ($p in 8765, 8766, 8799, 8130, 8140) {
|
||
if (Get-NetTCPConnection -LocalPort $p -State Listen -ErrorAction SilentlyContinue) {
|
||
$busy = $true
|
||
}
|
||
if (Get-NetUDPEndpoint -LocalPort $p -ErrorAction SilentlyContinue) {
|
||
$busy = $true
|
||
}
|
||
}
|
||
if (-not $busy) { break }
|
||
Start-Sleep -Milliseconds 500
|
||
}
|
||
Start-Sleep -Milliseconds 300
|
||
}
|
||
|
||
# ---------------------------------------------------------------- 0
|
||
Banner "0/7 清理残留进程与端口"
|
||
Stop-Strays
|
||
$busy = @()
|
||
foreach ($p in 8765, 8766, 8799, 8801, 8803, 8805) {
|
||
if (Get-NetUDPEndpoint -LocalPort $p -ErrorAction SilentlyContinue) { $busy += "UDP $p" }
|
||
if (Get-NetTCPConnection -LocalPort $p -State Listen -ErrorAction SilentlyContinue) { $busy += "TCP $p" }
|
||
}
|
||
if ($busy.Count -eq 0) {
|
||
Write-Host "端口干净" -ForegroundColor Green
|
||
} else {
|
||
Write-Host ("仍被占用: " + ($busy -join ", ")) -ForegroundColor Yellow
|
||
}
|
||
|
||
# ---------------------------------------------------------------- 0a
|
||
# 清掉上一次测试留在 received 里的文件。
|
||
# 不清的话会越攒越多,把 file_list 的前 100 个窗口挤满,
|
||
# 导致"看不到刚上传的文件"这类假失败(真踩过:攒到 116 个)。
|
||
$receivedDir = Join-Path $root "_tests\received"
|
||
if (Test-Path $receivedDir) {
|
||
$old = (Get-ChildItem $receivedDir -File -ErrorAction SilentlyContinue).Count
|
||
if ($old -gt 0) {
|
||
Get-ChildItem $receivedDir -File | Remove-Item -Force -ErrorAction SilentlyContinue
|
||
Write-Host " 清掉上次测试残留的 $old 个文件" -ForegroundColor DarkGray
|
||
}
|
||
}
|
||
|
||
# ---------------------------------------------------------------- 0
|
||
# 编码审计放最前面:编码错了后面全白搭
|
||
Banner "0/7 编码审计(BOM / 行尾 / 乱码)"
|
||
& python (Join-Path $root "_tests\audit_encoding.py") *> (Join-Path $env:TEMP "lr_enc.txt")
|
||
$encCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_enc.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
Record "编码审计" ($encCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1
|
||
Banner "1/7 Python 被控端协议回归"
|
||
& python (Join-Path $root "_tests\test_agent_protocol.py") 2>&1 | Select-Object -Last 4
|
||
Record "Python 被控端协议回归" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1b
|
||
Banner "1b/7 防火墙阻止规则检测(真机连不上的根因)"
|
||
& python (Join-Path $root "_tests\test_firewall.py") 2>&1 | Select-Object -Last 3
|
||
Record "防火墙阻止规则检测" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1c
|
||
Banner "1c/7 连不上?-> 电脑打开网络自检(UDP 链路)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_selfcheck.py") *> (Join-Path $env:TEMP "lr_sc.txt")
|
||
$scCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_sc.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 2
|
||
Record "自检请求链路" ($scCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1e
|
||
Banner "1e/7 新增功能(电量/磁盘/性能/进程/剪贴板历史/安全边界)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_new_features.py") *> (Join-Path $env:TEMP "lr_feat.txt")
|
||
$featCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_feat.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 2
|
||
Record "新增功能" ($featCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1f
|
||
Banner "1f/7 电脑功能注册表(39 个功能 + 安全边界 + 可配置)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_features.py") *> (Join-Path $env:TEMP "lr_feats.txt")
|
||
$featsCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_feats.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 2
|
||
Record "电脑功能注册表" ($featsCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1g
|
||
Banner "1g/7 功能模糊测试(105 个功能 × 空参数 / 垃圾参数 / 越权路径)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\fuzz_features.py") *> (Join-Path $env:TEMP "lr_fuzz.txt")
|
||
$fuzzCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_fuzz.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
Record "功能模糊测试" ($fuzzCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1h
|
||
Banner "1h/7 端到端(打包后的 EXE:配对 / 功能列表 / 越权 / 防爆破)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_e2e_features.py") *> (Join-Path $env:TEMP "lr_e2e.txt")
|
||
$e2eCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_e2e.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
Record "端到端(打包 EXE)" ($e2eCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1i
|
||
Banner "1i/7 静默模式(0 窗口 / 无终端 / 认证仍生效)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_silent_mode.py") *> (Join-Path $env:TEMP "lr_silent.txt")
|
||
$silentCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_silent.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
Record "静默模式" ($silentCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1j
|
||
Banner "1j/7 配一次→零窗口(令牌重连,全程无窗口)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_pair_once_flow.py") *> (Join-Path $env:TEMP "lr_flow.txt")
|
||
$flowCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_flow.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
Record "配一次→零窗口" ($flowCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1k
|
||
Banner "1k/7 首次安装设置窗口(出现一次,之后不再出现)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_first_run_setup.py") *> (Join-Path $env:TEMP "lr_setup.txt")
|
||
$setupCode2 = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_setup.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
Record "首次设置窗口" ($setupCode2 -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1l
|
||
Banner "1l/7 开机零窗口(照注册表里的自启命令真跑一遍)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_boot_silent.py") *> (Join-Path $env:TEMP "lr_boot.txt")
|
||
$bootCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_boot.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
Record "开机零窗口" ($bootCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 2
|
||
Banner "2/7 手表屏幕布局适配核算 (490x602)"
|
||
& python (Join-Path $root "_tests\check_layout.py") 2>&1 | Select-Object -Last 3
|
||
Record "手表布局适配" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 1z
|
||
Banner "1z/7 手表分页完整性(防白屏:方法定义了必须被调用)"
|
||
& python (Join-Path $root "_tests\test_no_orphan_methods.py") 2>&1 |
|
||
Select-Object -Last 6
|
||
Record "手表分页完整性" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 2a2
|
||
Banner "2a2/7 APK 内容(诊断已合并进主程序)"
|
||
& python (Join-Path $root "_tests\test_apk_contents.py") *> (Join-Path $env:TEMP "lr_apk.txt")
|
||
$apkCode = $LASTEXITCODE
|
||
Get-Content (Join-Path $env:TEMP "lr_apk.txt") -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 2
|
||
Record "APK 内容" ($apkCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 2a
|
||
Banner "2a/7 网络调优(MTU 修复)"
|
||
# 这是可用率从 48% 提到 100% 的关键,而且容易被后人误改
|
||
# (比如"顺手把接口 MTU 也降一点" —— 实测那样会掉到 50%)。
|
||
& python (Join-Path $root "_tests\test_net_tune.py") 2>&1 |
|
||
Select-Object -Last 4
|
||
Record "网络调优(MTU)" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 2b
|
||
Banner "2b/7 投图显示方式(屏幕中间 / 全屏 / 自定义大小)"
|
||
Stop-Strays
|
||
$imgLog = Join-Path $env:TEMP "lr_imgmode.txt"
|
||
& python (Join-Path $root "_tests\test_image_modes.py") *> $imgLog
|
||
$imgCode = $LASTEXITCODE
|
||
if ($imgCode -eq 0) {
|
||
Get-Content $imgLog -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Select-Object -Last 3
|
||
} else {
|
||
Write-Host "失败输出:" -ForegroundColor Red
|
||
Get-Content $imgLog -Encoding UTF8 -ErrorAction SilentlyContinue |
|
||
Where-Object { $_ -match "FAIL|通过|Traceback|Error" }
|
||
}
|
||
Record "投图显示方式" ($imgCode -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 3
|
||
Banner "3/7 屏幕共享可见提示(真实界面 + Win32 窗口枚举)"
|
||
Stop-Strays
|
||
& python (Join-Path $root "_tests\test_indicator_visible.py") 2>&1 | Select-Object -Last 3
|
||
Record "屏幕共享强制提示" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 2b
|
||
Banner "2b/7 中转 chunked 请求体(防连接错位)"
|
||
# Cloudflare 转发时可能用 Transfer-Encoding: chunked。
|
||
# 中转原来只读 Content-Length,残留的 "0\r\n\r\n" 会被当成下一个请求行,
|
||
# 报 "Bad request syntax ('0')",整条连接错位 -> 隧道大面积 502。
|
||
$stageOut = & python (Join-Path $root "_tests\test_chunked_body.py") 2>&1
|
||
Show-Fails $stageOut
|
||
Record "中转 chunked 请求体" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 3a
|
||
Banner "3a/7 局域网直连路径(不经中转)"
|
||
# 手表和电脑同一个 WiFi 时走这条:UDP 广播找到电脑 + TCP 直连。
|
||
# 这条路径完全不碰中转,所以单独盯一下。
|
||
$stageOut = & python (Join-Path $root "_tests\test_lan_path.py") 2>&1
|
||
Show-Fails $stageOut
|
||
Record "局域网直连路径" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 3b
|
||
Banner "3b/7 Python 静态检查(pyflakes)"
|
||
# 这一层能抓到"运行到某行才炸"的问题。
|
||
# 踩过的坑:check_code_available() 用了没导入的 DEFAULT_RELAY_URL,
|
||
# 结果装到最后一步弹 NameError —— 而回归全绿、编码审计也过。
|
||
$stageOut = & python (Join-Path $root "_tests\audit_python_names.py") 2>&1
|
||
Show-Fails $stageOut
|
||
Record "Python 静态检查" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 3b2
|
||
Banner "3b2/7 管理页网络体检"
|
||
# 用户看到"连不上"时最需要知道:隧道几条连接、公网通不通、延迟多少。
|
||
# 中转和 cloudflared 同机,能直接读它的指标。
|
||
$stageOut = & python (Join-Path $root "_tests\test_admin_netcheck.py") 2>&1
|
||
Show-Fails $stageOut
|
||
Record "管理页网络体检" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 3c
|
||
Banner "3c/7 中转管理端批量删除"
|
||
$stageOut = & python (Join-Path $root "_tests\test_admin_batch_delete.py") 2>&1
|
||
Show-Fails $stageOut
|
||
Record "中转批量删除" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 3d
|
||
Banner "3d/7 管理页 JS 合法性(防幽灵按键)"
|
||
# 管理页的 JS 是拼出来的,字符串里混进真换行会让整段脚本报错,
|
||
# 按钮点了没反应。这个阶段逐字符扫描验证。
|
||
$stageOut = & python (Join-Path $root "_tests\test_admin_js.py") 2>&1
|
||
Show-Fails $stageOut
|
||
Record "管理页 JS 合法性" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 4b
|
||
Banner "4b/7 手表 Activity 骨架(防白屏)"
|
||
# onCreate 被删掉过一次:照样编译通过,但打开就是白屏。
|
||
# 这一阶段专门断言生命周期骨架完整。
|
||
$stageOut = & python (Join-Path $root "_tests\test_watch_skeleton.py") 2>&1
|
||
Show-Fails $stageOut
|
||
Record "手表 Activity 骨架" ($LASTEXITCODE -eq 0)
|
||
|
||
# ---------------------------------------------------------------- 4c
|
||
Banner "4c/7 编译整个手表 App(含界面代码)"
|
||
# 这一步不能省:只编协议层的话,MainActivity.java 里的错误
|
||
# 根本检查不到 —— 改界面时删坏过字段声明,协议层照样通过,
|
||
# 回归全绿,结果 APK 编不出来。用 android.jar 做 classpath 编全量。
|
||
if (-not (Test-Path $androidJar)) {
|
||
Write-Host "找不到 android.jar: $androidJar" -ForegroundColor Red
|
||
Record "手表 App 整体编译" $false
|
||
} else {
|
||
$appOut = Join-Path $root "_tests\out_app"
|
||
if (Test-Path $appOut) { Remove-Item -Recurse -Force $appOut }
|
||
New-Item -ItemType Directory -Force -Path $appOut | Out-Null
|
||
|
||
$appSrcs = Get-ChildItem (Join-Path $root "android\src") -Recurse -Filter "*.java" |
|
||
ForEach-Object { $_.FullName }
|
||
|
||
$env:JAVA_TOOL_OPTIONS = "-Duser.language=en -Duser.country=US"
|
||
& $javac --release 8 -encoding UTF-8 -cp $androidJar -d $appOut $appSrcs 2>&1 |
|
||
Select-String -Pattern "error" | Select-Object -First 8 | ForEach-Object { Write-Host " $_" }
|
||
$appOk = ($LASTEXITCODE -eq 0)
|
||
$env:JAVA_TOOL_OPTIONS = ""
|
||
|
||
Write-Host $(if ($appOk) { " App 编译通过" } else { " App 编译失败" })
|
||
Record "手表 App 整体编译" $appOk
|
||
}
|
||
|
||
# ---------------------------------------------------------------- 5
|
||
Banner "5/7 编译 Java 协议层"
|
||
if (Test-Path $out) { Remove-Item -Recurse -Force $out }
|
||
New-Item -ItemType Directory -Force -Path $out | Out-Null
|
||
# Transport / RelayTransport 是跨网络用的:把"怎么传字节"抽出来,
|
||
# 这样 RemoteClient 的协议逻辑不用改就能走中转。
|
||
& $javac --release 8 -encoding UTF-8 -d $out `
|
||
(Join-Path $root "android\src\com\lanremote\watch\Json.java") `
|
||
(Join-Path $root "android\src\com\lanremote\watch\B64.java") `
|
||
(Join-Path $root "android\src\com\lanremote\watch\DiscoveryCore.java") `
|
||
(Join-Path $root "android\src\com\lanremote\watch\Transport.java") `
|
||
(Join-Path $root "android\src\com\lanremote\watch\RelayTransport.java") `
|
||
(Join-Path $root "android\src\com\lanremote\watch\TlsCompat.java") `
|
||
(Join-Path $root "android\src\com\lanremote\watch\RemoteClient.java") `
|
||
(Join-Path $root "_tests\java\JavaClientTest.java") 2>&1 | Out-Null
|
||
$compiled = ($LASTEXITCODE -eq 0)
|
||
Write-Host $(if ($compiled) { "编译通过" } else { "编译失败" })
|
||
Record "Java 协议层编译" $compiled
|
||
if (-not $compiled) { return }
|
||
|
||
# ---------------------------------------------------------------- 6
|
||
Banner "6/7 Java <-> 桩服务端 跨语言联调"
|
||
Stop-Strays
|
||
$stubData = Join-Path $root "_tests\_stubdata"
|
||
Remove-Item -Recurse -Force $stubData -ErrorAction SilentlyContinue
|
||
$codeFile = Join-Path $env:TEMP "lr_verify_code.txt"
|
||
Remove-Item -Force $codeFile -ErrorAction SilentlyContinue
|
||
|
||
$stub = Start-Process -FilePath "python" `
|
||
-ArgumentList "_tests\run_stub_server.py", "--port", "8799",
|
||
"--code-file", $codeFile, "--data-dir", $stubData `
|
||
-WorkingDirectory $root -PassThru -WindowStyle Hidden `
|
||
-RedirectStandardOutput (Join-Path $env:TEMP "lr_verify_stub.txt") `
|
||
-RedirectStandardError (Join-Path $env:TEMP "lr_verify_stub_err.txt")
|
||
|
||
$deadline = (Get-Date).AddSeconds(25)
|
||
while (-not (Test-Path $codeFile) -and (Get-Date) -lt $deadline) { Start-Sleep -Milliseconds 300 }
|
||
if (-not (Test-Path $codeFile)) {
|
||
Write-Host "桩服务端未就绪" -ForegroundColor Red
|
||
Get-Content (Join-Path $env:TEMP "lr_verify_stub_err.txt") -ErrorAction SilentlyContinue
|
||
Stop-Process -Id $stub.Id -Force -ErrorAction SilentlyContinue
|
||
Record "Java <-> 桩服务端" $false
|
||
} else {
|
||
& $java "-Dfile.encoding=UTF-8" -cp $out JavaClientTest "127.0.0.1" 8799 "246813" "stub" 2>&1 |
|
||
Select-Object -Last 4
|
||
Record "Java <-> 桩服务端" ($LASTEXITCODE -eq 0)
|
||
Stop-Process -Id $stub.Id -Force -ErrorAction SilentlyContinue
|
||
}
|
||
|
||
# ---------------------------------------------------------------- 7
|
||
Banner "7/7 Java <-> 打包后的 EXE 端到端联调"
|
||
Stop-Strays
|
||
if (-not (Test-Path $exe)) {
|
||
Write-Host "未找到打包后的 EXE: $exe" -ForegroundColor Yellow
|
||
Write-Host "请先运行: powershell -File windows\build_exe.ps1" -ForegroundColor Yellow
|
||
Record "Java <-> 打包 EXE" $false
|
||
} else {
|
||
$appDir = Split-Path -Parent $exe
|
||
Remove-Item -Recurse -Force (Join-Path $appDir "data"), (Join-Path $appDir "received") -ErrorAction SilentlyContinue
|
||
|
||
# --add-device:静默运行 + 开放配对(默认流程会弹设置窗口,测试会卡住)
|
||
$proc = Start-Process -FilePath $exe -ArgumentList "--port", "8801", "--add-device", "10" -PassThru
|
||
Start-Sleep -Seconds 7
|
||
$settings = Join-Path $appDir "data\settings.json"
|
||
$deadline = (Get-Date).AddSeconds(25)
|
||
while (-not (Test-Path $settings) -and (Get-Date) -lt $deadline) { Start-Sleep -Milliseconds 400 }
|
||
|
||
if (-not (Test-Path $settings)) {
|
||
Write-Host "EXE 未生成配置,启动失败" -ForegroundColor Red
|
||
Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
|
||
Record "Java <-> 打包 EXE" $false
|
||
} else {
|
||
$cfg = Get-Content $settings -Raw | ConvertFrom-Json
|
||
$cfg.image_timeout = 4
|
||
$cfg | ConvertTo-Json | Set-Content $settings -Encoding UTF8
|
||
Write-Host "EXE 配对码: $($cfg.pairing_code)"
|
||
|
||
& $java "-Dfile.encoding=UTF-8" -cp $out JavaClientTest "127.0.0.1" 8801 $cfg.pairing_code "real" 2>&1 |
|
||
Select-Object -Last 4
|
||
Record "Java <-> 打包 EXE" ($LASTEXITCODE -eq 0)
|
||
Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
|
||
Start-Sleep -Seconds 1
|
||
|
||
Write-Host "`nEXE 接收到的文件:"
|
||
Get-ChildItem (Join-Path $appDir "received") -ErrorAction SilentlyContinue |
|
||
ForEach-Object { Write-Host (" {0,8:N0} B {1}" -f $_.Length, $_.Name) }
|
||
}
|
||
}
|
||
|
||
Stop-Strays
|
||
|
||
# ---------------------------------------------------------------- 汇总
|
||
# 收尾:把测试过程中弹出来的窗口关掉(用户要求)
|
||
Close-TestWindows
|
||
|
||
Banner "验证汇总"
|
||
$script:results | Format-Table -AutoSize
|
||
$failed = ($script:results | Where-Object { $_.结果 -eq "FAIL" }).Count
|
||
if ($failed -eq 0) {
|
||
Write-Host "全部通过" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "$failed 项失败" -ForegroundColor Red
|
||
}
|
||
exit $failed
|