# -*- coding: utf-8 -*- r'''让测试知道它自己起的中转用了什么密码。 == 问题 == 密码不再硬编码之后,测试分成两边: * 测试进程:`_admin_password()` 去环境变量/文件里找 * 它启动的中转:`admin_password()` 找不到就**随机生成**一个 两边对不上 -> 登录失败 -> 所有管理接口返回 401「请先登录」。 (表现成 12 项失败,看起来像功能坏了,实际是测试环境没打通。) == 修法 == 在测试文件**模块级**(import 时)做两件事: 1. 随机生成一个本次运行专用的密码 2. 写进 os.environ["RELAY_ADMIN_PASSWORD"] 因为测试启动中转时用的是 `env = dict(os.environ)`, 这个变量会**自动传给它** —— 两边就是同一个密码了。 为什么用随机而不是写死: 写死就又变成"密码进仓库"了,白改一场。 随机的每次跑都不一样,而且不落任何文件。 ''' from __future__ import annotations import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent TARGETS = ["_tests/acceptance.py", "_tests/test_admin_batch_delete.py", "_tests/test_admin_button.py", "_tests/test_admin_device_control.py", "_tests/test_admin_js.py", "_tests/test_admin_netcheck.py", "_tests/test_relay_admin_login.py"] MARK = "# ---- 测试专用管理密码" BLOCK = ''' # ---- 测试专用管理密码 ---------------------------------------------------- # 测试要登录它自己启动的中转,但密码是那边随机的 —— 两边对不上就会 # 全部 401(表现成"功能坏了",实际是环境没打通)。 # # 这里生成一个**本次运行专用**的随机密码,写进环境变量; # 测试启动中转用的是 dict(os.environ),所以会自动传给中转。 # # 为什么不用写死的:写死就又变成"密码进仓库"了,白改一场。 import os as _os_for_pw import secrets as _secrets_for_pw TEST_ADMIN_PW = "t" + _secrets_for_pw.token_hex(12) _os_for_pw.environ["RELAY_ADMIN_PASSWORD"] = TEST_ADMIN_PW _os_for_pw.environ.setdefault("RELAY_ADMIN_USER", "xmz7891") # --------------------------------------------------------------------------- ''' def main() -> int: ok = 0 bad = 0 for rel in TARGETS: p = ROOT / rel if not p.is_file(): print(" ✗ %s 不存在" % rel) bad += 1 continue text = p.read_text(encoding="utf-8") if MARK in text: print(" • %s 已经打过补丁" % rel) ok += 1 continue # 插在 _admin_password 的定义**之前**(模块级,import 时就生效) m = re.search(r"^def _admin_password\(\)", text, re.M) if m: text = text[:m.start()] + BLOCK.strip() + "\n\n\n" + text[m.start():] else: # 没有那个 helper 的话,插在最后一个 import 之后 last_imp = 0 for mm in re.finditer(r"^(?:import |from )\S.*$", text, re.M): last_imp = mm.end() if not last_imp: print(" ✗ %s 找不到插入点" % rel) bad += 1 continue text = text[:last_imp] + "\n" + BLOCK + text[last_imp:] p.write_text(text, encoding="utf-8", newline="\n") print(" ✓ %s" % rel) ok += 1 print() print(" 改了 %d 个,失败 %d 个" % (ok, bad)) # 语法检查 print() import ast errs = [] for rel in TARGETS: p = ROOT / rel try: ast.parse(p.read_text(encoding="utf-8")) except SyntaxError as exc: errs.append("%s: %s" % (rel, exc)) if errs: print(" ✗ 语法错:") for e in errs: print(" %s" % e) return 1 print(" ✓ 语法都通过") return 0 if bad == 0 else 1 if __name__ == "__main__": sys.exit(main())