21 KiB
原生浏览器环境:验证与手工验收
当前状态:单节点代码改造与自动检查通过;真实平台、代理、LAN 和资源验收仍须由授权操作者手工完成。 已完成 native gateway、控制面契约、runtime-use lease、Compose/P4 文档和本地单元测试;本文件只记录可复现的验收步骤,不把测试替身当作真实平台证据。 方案:变更评审;阶段:实施计划;当次记录:单节点验证记录。
1. 验证边界
- 开发者负责单元/契约检查、构建和启动可联调环境;真实功能由用户手工验证,不使用浏览器自动化或脚本代点网页。
- 读取日志、目录占用、进程/端口和系统指标可以使用命令。自动测试中的替身只证明代码行为,不能证明平台登录、监听、发送或真实代理能力。
- 默认不构建/运行 Docker;Compose 仅可作为 PostgreSQL 独立依赖。旧方式对照、资源删除和故障注入必须单独取得用户同意。
- 测试专用账号、Profile、gateway、数据目录及出口;不能强杀用户正在使用的长期账号或清空全机 Docker 资源。
- 任何结果使用“未执行 / 通过 / 失败 / 阻塞”,不得把文档中的期望填成实际结果。
- 若被测 Chrome 由用户的
chrome.service管理,验证只能通过其已开放的 CDP 连接执行只读/交互检查,不得停止、启动、替换或接管该实例;这类结果不能替代 native gateway 的 runtime 生命周期、控制面持久化和资源清理验收。
2. 前置条件和记录表
实施 P0 完成后填写,缺项不得开始破坏性操作:
| 项目 | 必填记录 |
|---|---|
| 软件基线 | Git 提交、未提交改动清单、Go/Python/Node/systemd/Xvfb/浏览器版本 |
| 机器 | 单节点控制面 C 与 native gateway G 的稳定节点 ID、IP、CPU、内存、磁盘、发行版 |
| 账号 | 专用采集账号、自有监听账号;预期平台 UID,勿记录密码/Cookie |
| 浏览器 | 原生发行物来源、许可证、校验值、支持的指纹参数和 sandbox 证据;A02 普通升级的已安装源版本/目标版本 |
| 路径 | 各机器 Profile 根目录、runtime 根目录、运行清单、日志、控制面素材目录 |
| 网络 | 单节点的 HTTP/HTTPS/SOCKS4/SOCKS5 测试出口、协议支持的认证配置、预期出口 IP、CDP 可用情况;只记录配置标识,不记录密码 |
| 操作许可 | 是否允许旧 Docker 对照、普通浏览器升级、gateway/控制面重启、任务取消、磁盘故障和测试数据删除;C02/D04 自动响应的测试策略、可控互动/接收账号及授权范围,A10 人工发送另行逐次确认 |
| 时限 | task 最大执行时间、续租间隔 20 秒、租约 60 秒、清理预算 30 秒、恢复预算 60 秒 |
| 资源预算 | 并发数 1/2、最低可用磁盘 20 GB、日志上限 1 GB;启动 p50/p95 和总内存目标,Profile 缓存预算 20 GB |
| 证据位置 | 独立于 runtime 清理目录的本地证据目录,不提交账号敏感数据 |
首轮使用并发 1 和 2、短任务正常清理预算 30 秒、服务恢复预算 60 秒。复杂平台采集的最大时长单独确定,不能因为清理预算而强行截断正常业务。
3. 开发者检查命令
以下命令是交付检查命令;执行结果另记在证据文件,不把未运行的命令当作通过。
Go
go test ./...
go vet ./...
go build -o /tmp/creatorhub-control-plane-check ./cmd/control-plane
go test -race ./...
go test -coverprofile=/tmp/creatorhub-go.cover ./...
go tool cover -func=/tmp/creatorhub-go.cover
要求:测试、vet、build、race 全部成功;单元测试覆盖率至少 65%,同时核对本次生命周期/资源归属模块,不能用高覆盖无关模块掩盖改动遗漏。自动响应须用确定性测试覆盖重启/重连后事件永久去重、原 UID 冷却保持、冷却内新事件不执行、到期只允许新事件及迟到事件不补发(AC-A9、AC-B1);P2 接入新运行身份时即通过这些检查。真实平台结果另外验收。
Python gateway
python3 -m venv .venv-gateway
.venv-gateway/bin/python -m pip install -r requirements-gateway-dev.lock
.venv-gateway/bin/python -m unittest discover -s browser_gateway -t . -p 'test_*.py'
.venv-gateway/bin/python -m coverage erase
.venv-gateway/bin/python -m coverage run --source=browser_gateway --branch \
-m unittest discover -s browser_gateway -t . -p 'test_*.py'
.venv-gateway/bin/python -m coverage report --omit='*/test_*.py' --fail-under=65
核对实际发现的测试数量;禁止跳过未安装的原生管理依赖后将结果当成全通过。用模拟子进程测试错误分支不等于真机 systemd/Xvfb 验收完成。
前端
npm --prefix web ci
npm --prefix web run test
npm --prefix web run test:coverage
npm --prefix web run build
覆盖 gateway 不可达、版本缺失、Profile 占用、开始/取消/停止、待清理错误和禁用状态。不要运行浏览器自动化命令代替本节手工验收。
配置与旧路径
docker compose config --quiet
仅在改动 Compose 时做配置校验,不执行 build/up;保留的 PostgreSQL 开发 Compose 文件也逐份验证。另行检查浏览器 runtime 路径已无 DockerClient/socket、容器/镜像/卷/网络创建、容器 wrapper 入口、旧 image 字段和“原生失败回退 Docker”;PostgreSQL 的独立部署配置不算漏删。
4. 联调启动与访问
已交付设置
- Go 使用
LISTEN_ADDR;联调须设置0.0.0.0:8082。 - Vite 当前
/api代理到127.0.0.1:8082,端口 5173。Vite 必须加--host 0.0.0.0,不能只给 localhost 地址。 - native Python gateway 使用
LISTEN_ADDR=0.0.0.0:8081,由非 root systemd user service 运行;稳定node_id从配置或主机身份加载。 scripts/dev-backend.mjs只启动 PostgreSQL 并检查NATIVE_GATEWAY_ENDPOINT,不会启动浏览器容器。
单节点执行步骤
- 按部署说明在单节点安装已确认浏览器、Xvfb 和
creatorhub-browser-gateway.service。 - 使用已有、经验证的 PostgreSQL 与凭据配置。不要重新生成现有主密钥;不要把秘密值粘贴到验收报告。
- 按交付脚本启动单节点 native gateway;在控制面登记真实地址,并核对
/v1/info返回的稳定节点身份。 - 启动控制面及前端:
# 其余数据库/凭据等必填配置由现有受控环境提供,不在命令行回显秘密。
LISTEN_ADDR=0.0.0.0:8082 go run ./cmd/control-plane
# 另一个终端
npm --prefix web run dev -- --host 0.0.0.0
命令启动后,用 ip -brief -4 addr 记录当次实际局域网 IP。用户在另一台设备访问 http://<C-IP>:5173;开发者可查看 http://<C-IP>:8082/healthz。报告列出单节点 gateway 的实际 Endpoint。
历史观察到的地址不构成可用性证据;实施当天必须重新核实 IP、监听地址和防火墙。
5. 手工功能与清理矩阵
每条记录:操作者、时间、节点、账号/任务/代次、操作、期望、实际、状态、日志/截图/资源清单位置。保留 33 项用例编号;同一用例的重启/升级、协议/认证、节点及恢复场景分别记录子项。必测子项未执行或阻塞时,不能把整个用例标为通过。
A. 正常生命周期
| ID | 手工步骤 | 通过条件 |
|---|---|---|
| A01 | 在 gateway 节点确认 Docker daemon/socket 不参与运行,创建账号环境,选择已安装 native 版本并启动 | 正确 Xvfb/浏览器就绪;未登录时可进入人工登录,不永久停在“正在启动”;无镜像下载、容器、卷或 Docker 浏览器网络操作 |
| A02 | 人工完成二维码登录,记录账号、Profile 标识和指纹;先关闭再启动,再停止并从界面普通升级至另一已安装且获准的版本后启动 | 两个子项均保持原 Profile、指纹和登录身份,无意外重新登录;升级后实际浏览器版本等于所选目标版本,不通过重建环境/重新登录冒充保持(AC-E1) |
| A03 | 浏览器停止时,从界面启动一次竞品账号采集,等待结束 | 自动创建任务 runtime,结果保存;T_cleanup 内进程、display、端口和临时文件释放 |
| A04 | 连续采集作品/评论/线索,再打开结果查看 | 数据完整且仍可读;不能因 runtime 清理丢失业务结果或已发布素材 |
| A05 | 同节点两个不同账号同时采集 | display、Profile、CDP/代理端口互不冲突;结束一个不影响另一个 |
| A06 | 同账号同时发起两个任务;另测人工登录占用该 Profile 时发起采集 | 明确排队或冲突;不出现两个浏览器打开同 Profile,不抢占登录会话 |
| A07 | 自有账号保持事件监听,另用采集账号执行并结束任务 | 监听不中断、不串 UID;采集自建资源完全释放 |
| A08 | 若批准借入长期 runtime 路径,用对应场景执行任务 | 只删除本任务页面/临时文件/引用;长期 holder 和 runtime 保留,界面如实说明借用 |
| A09 | 按下方代理矩阵分别配置四类代理及其支持的认证配置,改变代理或账号绑定后启动采集 | 每个配置下实际浏览器出口、代理版本、指纹时区/语言等正确;身份不符时拒绝动作;不能用单一无认证代理的成功代替其他配置(AC-E3) |
| A10 | 仅在用户准备真实接收账号并逐次确认时验证人工回复/私信 | 保持原有确认与身份核对;重复结果不触发重复发送,不确定状态不冒充成功 |
A02 验证的是 native 环境内的普通版本升级,不是 Profile 迁移;缺少获准版本时标为阻塞。
代理矩阵适用于 A09/B03:单节点分别列出 HTTP、HTTPS、SOCKS4、SOCKS5,按协议允许的配置验证无认证(如支持)及支持的认证方式;A09 记录成功与实际浏览器出口,B03 记录认证失败(适用时)与网络失败,均不得静默直连或轮换出口。协议本身不支持的认证项说明依据,不作为通过项;缺少测试代理、凭据或尚未实现的承诺能力标为阻塞,不能免测。证据不得包含密码/Cookie。
A10 不能由脚本自动发送,也不能因为只修改 runtime 就免除必要回归;人工逐次确认不能代替 C02/D04 的自动策略验收。
B. 全部终态与资源异常
| ID | 手工步骤/经授权的故障注入 | 通过条件 |
|---|---|---|
| B01 | 任务运行中点击取消 | 业务不永久 running;独立清理继续,T_cleanup 内完成或明确待清理 |
| B02 | 让测试任务超过已批准最大时长 | 超时可见;lease 释放,任务进程/目录回收,不能继续后台写入 |
| B03 | 按代理矩阵逐协议分别制造认证失败(协议支持时)和网络失败;另测无效浏览器路径启动 | 每个适用子项明确失败,无静默直连或出口轮换;已创建的 Xvfb/端口/临时目录逆序回收(AC-E3) |
| B04 | 经授权终止该测试 runtime 的浏览器,另测 Xvfb 退出 | 任务失败可见;其余子进程终止;其他 runtime 不受影响 |
| B05 | 对测试专用目录制造无法删除条件后结束任务 | 显示“业务结果 + 清理失败”,保留可追溯记录;恢复条件后重试只清资源,不重跑业务 |
| B06 | 测试磁盘低于启动阈值;用隔离测试盘验证写满 | 启动前拒绝或运行中明确失败;不删除登录资料/正式素材腾空间;收尾状态可靠 |
| B07 | 重复点击取消/停止/清理;再对已结束任务重复操作 | 幂等,不返回虚假的活实例;不会清掉后来启动的新代次 |
| B08 | 经授权在 gateway 内已启动、控制面尚未收到回复时中断连接 | 查询同 generation 收敛;没有重复进程、Profile 或资源分配 |
| B09 | 长任务超过十分钟,观察续租;让旧执行失去租约后恢复响应 | 当前 holder 继续有效;旧执行不得发布产物、覆盖结果或清理新执行目录 |
| B10 | 人为让任务结果保存失败或响应丢失 | 区分确定失败与结果未知;先核对数据库引用,不能误删已发布素材或盲目重试 |
C. 重启与孤儿恢复
| ID | 步骤 | 通过条件 |
|---|---|---|
| C01 | 在测试采集运行时,经授权强杀并重启 gateway | 依据 unit+节点+代次核对受管实例;过期任务回收,未过期任务恢复或明确失败;不重复启动 |
| C02 | 在已产生自动响应及冷却记录的长期监听账号上,分别重启 gateway、控制面并恢复订阅;按下方恢复子项核对 | 浏览器 Profile 不被删;代理/订阅恢复有证据,失联时间和可能遗漏可见;基线、事件去重记录与原冷却到期时间保留,旧事件不重放,迟到事件不自动补发(AC-A9、AC-B1) |
| C03 | 强杀 gateway 后暂不恢复,超过短任务的 unit 最长寿命 | 短任务整组进程退出;临时文件在 runtime 退出或后续核对时回收,不无限占用 |
| C04 | 控制面在临时素材下载、音轨提取期间被强杀,再启动 | 控制面处理自己遗留的临时文件;不会要求 gateway 删除控制面路径 |
| C05 | 旧素材执行恢复时新执行已完成,触发旧执行发布/清理 | 新正式文件与 DB 引用不变;旧执行只能清理自身未被引用的产物 |
| C06 | 经授权重启 gateway 所在测试机器 | 节点身份稳定,旧运行代次不冒充存活;过期短任务不自动重做,登录资料保留;监听恢复或明确提示 |
| C07 | 在清理目录旁放置无关文件/符号链接和另一 runtime 记录 | 无关资源不删除;未知归属有明确错误,不能按目录年龄一并清空 |
C02/D04 必测恢复子项:
- 恢复前记录已处理事件、自动动作结果和 UID 冷却原到期时间;恢复后,同一大号下该 UID 在冷却内产生新互动也不得再次触发自动动作,不因更换小号而绕过。
- 已处理旧事件即使在冷却到期后再次出现,也不能重放;到期后的新事件才可按策略响应,迟到/恢复历史事件默认只记录、不自动补发。无法确认连续性时显示缺口并重新确认边界,不能只以“监听已连接”判通过。
- 保存动作记录及可控接收端证据,确认未发生额外自动动作。真实平台由用户在已授权策略和可控互动/接收账号范围内手工制造互动,观察产品自身自动响应;不向无关用户发送,不用脚本或 Mock 冒充真实平台,也不把自动动作改成人工逐次确认。
- 旧事件重放、到期及迟到等精确边界先由确定性测试证明;真实平台无法复现的子项记为未执行,缺账号/权限/平台能力则记为阻塞,不得用离线检查替代真实证据或将整项标为通过。
C05/B09 的精确竞态先用确定性单元测试证明;真机无法可重复制造时标记该子项未执行,不能用“人工未复现”替代回归测试。测试不得添加面向生产的任意执行接口。
D. 多机控制(后续目标,全部未执行)
| ID | 步骤 | 通过条件 |
|---|---|---|
| D01 | 后续目标:两台节点各创建合法唯一环境,分别启动;停止/清理一侧并观察另一侧 | 本目标不执行;保留稳定节点和代数字段,后续目标按契约验收 |
| D02 | 后续目标:一台节点失联,另一台正常采集/续租/监听 | 本目标不执行;不得以单节点重启替代跨机证据 |
| D03 | 后续目标:带 Profile、运行实例或待清理资源时改变机器归属 | 本目标不执行;不得删除原节点资源 |
| D04 | 后续目标:跨节点恢复时旧响应/事件迟到且已有新代次 | 本目标不执行;单节点旧代次保护由 C07 和自动测试覆盖 |
| D05 | 后续目标:多节点配置不同出口并按代理矩阵核验 | 本目标不执行;单节点代理适用项在 A09/B03 验收 |
| D06 | 后续目标:另一节点未安装账号指定浏览器版本 | 本目标不执行;单节点版本缺失在 A01/B03 验收 |
抖音先完成全部适用用例;小红书按相同生命周期复验。尚未实现的平台能力记为阻塞,不用 Mock、轮询或另一平台成功代替。
6. 磁盘与性能验证
6.1 测量方法
- 固定机器、浏览器版本、指纹、账号、代理、任务内容、并发和依赖状态;除生命周期方式外尽量保持一致。不要拿不同浏览器或不同网络的结果相减。
- 冷启动指本次机器/服务启动后的第一次浏览器启动,和后续热启动分开记录;不擅自全机清理 page cache。安装或下载浏览器耗时另列,不混入日常任务启动。
- 每种方式在并发 1 下至少 20 次有效启动,并在并发 2 下至少 10 组。按相同节奏执行,遵守平台限制。遇验证码/限流单独记录,不删去异常后只展示好看的数值。
- 时间从用户启动请求被接收到 CDP+代理+账号就绪;另外记录完整任务、终止到资源清理完成耗时。不能只测进程创建或 Xvfb 启动时间。
- 内存统计整个 runtime 的浏览器子进程、Xvfb、可选桌面,以及 gateway 增量;如有获准的旧基线,旧方案也必须按完整进程树和代理增量的同一口径统计。优先使用 cgroup 峰值或一致口径的 PSS;RSS 合计会重复计算共享页,必须注明。
- 记录每轮之前、业务结束、清理完成三个时刻:活跃进程/unit、端口、runtime/Profile/日志/素材字节数。使用
ps、ss、systemctl show、du -sb等只读工具;共享内存和 X socket 也须核对。 - 原生路径连续完成至少 30 个短任务,覆盖取消和失败;再观察一轮长期监听与采集并行。平台受限时可用明确标识的本地测试页面单独测生命周期,但不得拿它替代真实平台功能验收。
建议记录 CSV:
mode,node_id,browser_version,concurrency,round,task_id,generation,start_ms,task_ms,cleanup_ms,peak_memory_bytes,tmp_bytes,profile_bytes,log_bytes,material_bytes,result,cleanup_result
p50 取中位数;p95 使用排序后第 ceil(0.95*N) 个样本并标出 N。至少做两轮实验评估噪声,既报告绝对值也报告比例。
6.2 放行标准
| 项目 | 通过条件 |
|---|---|
| 短任务进程 | 清理完成后,该代次浏览器、Xvfb、桌面及子进程数为 0;合法长期会话单独列出 |
| 临时磁盘 | 清理完成后该任务临时目录不存在或为空;重复任务不留下逐轮增长的 runtime/下载/cache/提取临时文件 |
| 显示/端口 | 本代次 display/socket/端口释放;不能误删其他合法 X server 的共享目录 |
| Profile | 账号身份/登录状态保留;经批准的缓存预算不超标。不宣称持久 Profile 必须字节不变 |
| 日志 | 达到已批准保留上限后有界,清理失败诊断可追溯;日志中无 Cookie/密码/验证码 |
| 素材 | 正式结果可访问;增长与新增业务结果匹配,不被当垃圾删除 |
| 启动与内存 | 达到 P0 批准的具体预算,相比可信旧基线的改善超过重复实验噪声;若没有改善,报告未达到性能目标,不以“取消了 Docker”判通过 |
| 故障恢复 | 在批准时间内完成清理或给出明确待处理原因;无永久失管短任务,无跨机误删 |
Docker 本身通常不是全部浏览器内存开销的来源;即使启动开销降低,Chromium 的页面和渲染进程仍可能占主要内存。实测不达标就继续定位,不承诺移除 Docker 必然显著省内存。
没有获准运行旧方式、也没有可信旧记录时:原生功能和绝对资源预算可独立验收,性能改善仍标记“缺基线,未验证”,不能填写节省百分比。
7. 日志与证据
关键节点应可关联:任务接受、使用权取得/续租、创建意图、unit 启动、显示/CDP/代理/身份就绪、业务提交、停止、删除、待清理、重试和恢复。
每条必要字段:node_id、环境/账号内部 ID、runtime_generation、任务/执行 token、阶段、耗时、结果、清理 owner 和错误;只记录内部标识,避免平台敏感数据泄漏。
每条失败证据包括:
- 节点与任务界面状态,操作时间范围。
- 控制面和对应 gateway 的关联日志。
- runtime unit/进程/端口和目录占用前后对比。
- 业务结果是否提交、清理是否完成、是否需用户介入。
- 重试后能否收敛,以及其他节点/长期账号是否保持正常。
8. 验收记录模板
提交/日期:
执行者/机器:
用例 ID / 子项(重启或升级、协议/认证/节点、恢复场景):
前置条件及授权:
操作步骤:
预期:
实际:
状态:未执行 / 通过 / 失败 / 阻塞
证据位置:
资源差异:
遗留问题/复测结果:
最终签收分别列出:代码检查、单机生命周期、短任务清理、持久登录、长期监听、多机故障、素材归属、磁盘稳定性、性能对比、各平台真实能力。只有记录充分的项目才勾选通过;失败修复后复测,真正缺少用户授权/账号/机器/发行物时明确标为阻塞。