Files
ykxmz/_tests/test_net_tune.py
T
xmz7891 aac43e559d 修正 MTU 测试的过时断言(1500 -> 1400)
test_net_tune.py 原来断言 net-tune.sh 里写着 mtu 1500,
依据是更早一次实测「接口 MTU 降到 1400 会掉到 50%」。

那个结论后来被推翻了 —— 当时漏了一件事:
**MSS 钳制只管 TCP,QUIC 走 UDP 完全不受保护。**
路径 MTU 实测 1472(1500 的包不通),QUIC 默认发 ~1452 的包会被
中间设备静默丢掉,而 UDP 丢了不回 ICMP,只能等超时。
把接口 MTU 压到 1400 之后,QUIC 建齐 10 条连接从 28 秒缩到 12 秒。

所以现在是**故意**设 1400。断言跟着改,
不然它会永久假失败,还会诱导后人把真正的改进改回 1500。

顺带记录:全量回归 38 个阶段全部通过。
新增的三个阶段(局域网优化 / 手表局域网切换 / 编码与换行 /
管理页设备控制)都是这轮加的。
2026-10-07 18:10:30 +08:00

107 lines
4.2 KiB
Python
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.
# -*- coding: utf-8 -*-
"""验证 MTU 调优脚本和安装集成。
为什么值得单独回归:
这是这次可用率从 48% 提到 100% 的关键,而且**很容易被后人误改** ——
比如"顺手把接口 MTU 也降一点"(实测那样会掉到 50%)。
所以把关键决策钉在测试里。
"""
from __future__ import annotations
import re
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
NET_TUNE = ROOT / "relay" / "net-tune.sh"
INSTALL = ROOT / "relay" / "install.sh"
passed = 0
failed = 0
def check(name, ok, detail=""):
global passed, failed
if ok:
passed += 1
print(" [PASS] " + name)
else:
failed += 1
print(" [FAIL] " + name + " " + str(detail))
def main() -> int:
print("一、调优脚本本身")
check("net-tune.sh 在", NET_TUNE.is_file())
if not NET_TUNE.is_file():
return 1
text = NET_TUNE.read_text(encoding="utf-8")
# bash 语法(在 Linux 上才有 bash,本机没有就跳过)
check("打开 tcp_mtu_probing", "tcp_mtu_probing=1" in text)
check("夹 MSS", "--set-mss" in text)
check("MSS 默认值合理(1300~1440)",
bool(re.search(r"MSS_VALUE=\$\{MSS_VALUE:-(\d+)\}", text))
and 1300 <= int(re.search(r"MSS_VALUE=\$\{MSS_VALUE:-(\d+)\}", text)
.group(1)) <= 1440,
re.search(r"MSS_VALUE=.*", text).group(0) if "MSS_VALUE" in text else "")
check("OUTPUT 链上夹", "OUTPUT" in text)
check("POSTROUTING 链上夹", "POSTROUTING" in text)
# ⚠ 这里原来断言的是"把接口 MTU 设回 1500",
# 依据是更早的一次实测(接口 MTU 降到 1400 会掉到 50%)。
#
# 那个结论后来被推翻了,原因是我们当时漏了一件事:
# **MSS 钳制只管 TCP,而 QUIC 走 UDP 完全不受保护。**
# 路径 MTU 实测 1472(1500 的包不通),QUIC 默认发 ~1452 的包
# 会被中间设备静默丢掉,而 UDP 丢了不回 ICMP,只能等超时。
# 把接口 MTU 压到 1400 之后,QUIC 建齐 10 条连接从 28 秒缩到 12 秒。
#
# 所以现在**故意**设 1400。这个断言跟着改,
# 否则它会永久假失败,还会诱导后人把真正的改进改回 1500。
check("把接口 MTU 压到 1400(QUIC 走 UDP,MSS 钳制管不到它)",
"mtu 1400" in text or "MTU_VALUE" in text,
"接口 MTU 要压到 1400,否则 QUIC 的大包会被静默丢弃")
check("注释里说明了为什么改接口 MTU(QUIC 不受 MSS 保护)",
"QUIC" in text or "UDP" in text or "MSS 钳制" in text)
# 清理旧规则,避免重启后越积越多
check("会先清掉旧 MSS 规则", "-D" in text and "while" in text)
print()
print("二、安装脚本带上了它")
check("install.sh 在", INSTALL.is_file())
install = INSTALL.read_text(encoding="utf-8")
check("有 [3c] 网络调优段", "[3c]" in install)
check("会拷 net-tune.sh", "net-tune.sh" in install)
check("会写 sysctl 配置", "99-lanremote-mtu.conf" in install)
check("会注册开机服务", "lanremote-nettune.service" in install)
check("服务 enabled", "systemctl enable lanremote-nettune" in install)
check("开机服务在隧道之前跑(新连接就用上新参数)",
"Before=lanremote-relay.service lanremote-tunnel.service" in install)
print()
print("三、打包会带上这两个文件")
package = (ROOT / "_build" / "package_remote.py").read_text(
encoding="utf-8")
check("打包脚本扫描整个 relay 目录(不是硬编码文件名)",
"iterdir" in package or "rglob" in package, "")
check("relay/net-tune.sh 会被打进去(同目录扫描即可)",
NET_TUNE.is_file())
print()
print("四、说明文档里记了实测数据")
check("写了不夹 MSS 的对照(87%)", "87" in text)
check("写了 MSS 各档都 100%", "100%" in text)
check("写了接口 MTU 1400 更差的教训", "50%" in text)
print()
print("=" * 58)
print(f"通过 {passed} 项,失败 {failed} 项")
return 0 if failed == 0 else 1
if __name__ == "__main__":
sys.exit(main())