Files
agentmc/run_tests.sh
JianFeeeee 8b1fc9289d Fabric 加载器路线跑通并落地验证(launcher="fabric",6/6 绿)
上个会话把 `launcher="fabric"` 写进了后端,却**没有留下任何可重跑的验证** ——
「经加载器能起来」这件事只活在对话里。本次把它变成可复算的。

## 机制(路线 C,不是 LOADERS.md 原来写的 A/B)

A/B 都假设「游戏由 Loader 起」。但 `Knot.init()` 是 public 的:它做完
「发现 mod → 建 KnotClassLoader → 应用 mixin → invokeEntrypoints(preLaunch)」
后**返回**,不进入官方主循环(那在 GameProvider.launch())。
⇒ `knot.loadIntoTarget("McfoldRenderServer")` 把我们的服务端注入同一个
KnotClassLoader —— **mod 生态与我们的控制权同时拿到,不必把服务改写成 mod**。

## 主要改动

### ① `RenderBackend._fabric_classpath()` —— 组装从用户手里移到后端

两个变换是实测必需、且用户不该自己拼的机械操作:
  - 剔除 1.20.1 自带的 asm(9.2 与 9.6 两版并存)—— 否则 Knot.<clinit> 抛
    "duplicate ASM classes found on classpath"
  - 追加 Fabric 的 8 个库(asm×5 / sponge-mixin / intermediary / fabric-loader)

库来源改为内容根 `.mcfold/fabric/`(原在 /tmp/fab,tmpfs 且违反版本隔离)。
实测 67 条 → 去 7 asm + 加 8 fabric = 68 条。

### ② `tests/test_loader_render.py`(新增,6 项)

  ✓ 启动架构与世代正交(动态子类,不写 N 个类)
  ✓ 两个架构可枚举
  ✓ classpath 组装(67→68:去 7 asm,加 8 fabric)
  ✓ 非 asm 库原样保留(去 asm 是外科手术,不是重写)
  ✓ **Fabric 加载器真启动并渲染**(KnotClassLoader / chunks=10..25 / colors=4391..4547)
  ✓ **Fabric 拒绝不兼容 mod** ← 反向对照:缺 fabric-api 的 Explorify 被拒

最后一条是**两条路线的可判差异**:零加载器是「无脑注册」,不知道 mod 要
fabric-api;Fabric 会。没有它,"加载器真的介入了"这句话就没有反面证据。

### ③ `run_tests.sh` —— 慢套件改为列表驱动 + 全跳过不再报绿

- SLOW 列表含 test_render_bridge / test_loader_render(默认不跑)
- ★ 全部跳过的套件**不算绿**:报"跳过 N 项"而非计入通过数 ——
  否则"没测"会被读成"测过了"。

## 验证

  ./run_tests.sh               → 62 项(2 个慢套件标 ⊘)
  ./run_tests.sh --with-render → **76 项全绿**
    (62 单元 + test_render_bridge 8 + test_loader_render 6)

## 仍未做

  Iris 光影真实加载(加载器已通,未验过一次 shader pack)
  forge / neoforge 后端(gen_1_20 / gen_1_21 均待设计)
2026-09-26 07:12:41 +08:00

52 lines
1.9 KiB
Bash
Executable File
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.

#!/usr/bin/env bash
# 统一测试入口。
#
# ./run_tests.sh 纯 Python 单元测试(秒级)
# ./run_tests.sh --with-render 额外跑渲染联测(需 Java + Xvfb,约 6 分钟)
#
# 渲染联测需要:
# MCFOLD_RENDER_CLASSPATH 含 client-named.jar 与 McfoldRenderServer.class
# MCFOLD_NATIVES_DIR lwjgl natives(**.so 必须平铺**,不能带包路径)
# DISPLAY 指向可用的 X(Xvfb 即可)
# (加载器联测另需 .mcfold/fabric/ 与已编译的 LoaderBoot.class)
# 缺任一项会**跳过而非失败**(不误报)。
cd "$(dirname "$0")"
WITH_RENDER=0
[ "${1:-}" = "--with-render" ] && WITH_RENDER=1
# 需要 JVM/Xvfb 的套件(默认不跑,跑一次约数分钟)
SLOW="test_render_bridge.py test_loader_render.py"
total=0; fail=0
for t in tests/test_*.py; do
name=$(basename "$t")
if [ $WITH_RENDER -eq 0 ] && [[ " $SLOW " == *" $name "* ]]; then
printf ' %-24s ⊘ 跳过(用 --with-render 启用)\n' "$name"
continue
fi
out=$(python3 "$t" 2>&1)
if echo "$out" | grep -qE "全部通过|通过$"; then
n=$(echo "$out" | grep -c "^ ✓")
skipped=$(echo "$out" | grep -c "^ - 跳过")
total=$((total+n))
# ★ 全跳过的套件不算绿:它对环境一无所知,报绿等于把"没测"说成"测过了"
if [ "$n" -eq 0 ] && [ "$skipped" -gt 0 ]; then
printf ' %-24s ⊘ 全部跳过(%d 项;环境未就绪)\n' "$name" "$skipped"
elif [ "$skipped" -gt 0 ]; then
printf ' %-24s ✓ %2d 项(%d 项跳过)\n' "$name" "$n" "$skipped"
else
printf ' %-24s ✓ %2d 项\n' "$name" "$n"
fi
else
fail=$((fail+1))
printf ' %-24s ✗ 失败\n' "$name"
echo "$out" | tail -6 | sed 's/^/ /'
fi
done
echo
if [ $fail -eq 0 ]; then
echo "全部通过:$total 项,0 失败"
else
echo "失败 $fail 个套件(共 $total 项通过)"; exit 1
fi