Skip to content

Latest commit

 

History

History
98 lines (75 loc) · 12.7 KB

File metadata and controls

98 lines (75 loc) · 12.7 KB

产品需求文档(PRD):mc-testkit

需求的单一真源(WHAT / WHY),也是产品的需求登记册 + 路线图。每个需求在 §4 加一行 FR(带优先级/期 + 状态),交付即标版本。单功能详细规格放 docs/specs/,PRD 只保留"一行 FR + 期 + 状态"的索引级。

1. 背景与目标

一个团队常同时维护多个 Bukkit 系插件,其中需要端到端验证的,各自手搓了一套 E2E:起真实服务端、拉机器人入服、驱动场景、判定结果——做法五花八门、大量重复、难统一维护,踩过的坑(代理下机器人协议版本、paper-global 代理在线模式、BungeeCord 后端配置、数据源/Redis 注入)在每个项目里重复踩。

mc-testkit 提供统一的「全平台 E2E 编排」Gradle 插件 + 配套脚手架模板:让任意插件用声明式 DSL 拉起真实「代理 + 后端」拓扑、用机器人驱动端到端场景、判定结果并干净收尾。一句话价值:把各插件重复的 E2E 编排沉淀成一处可复用、可维护、契约固化的工具。

非目标

  • 不替消费项目编写具体业务场景与断言(场景逻辑天然项目特定,框架只提供骨架与编排)。
  • 本期不发布共享 Kotlin 桩基类库、不发布共享 npm 机器人包(避免从单一用例过早抽象,留待第 2 个真实消费者验证后再抽,见 ADR-0002)。
  • 不取代单元测试框架(JUnit / MockBukkit 等仍是单元/集成测试的职责)。
  • 不驱动真实游戏客户端(Fabric/Forge mod 客户端);客户端行为由 mineflayer 机器人模拟。
  • 不支持 Spigot/Bukkit/Sponge 后端(不列入计划,见 ADR-0003)。

2. 角色

  • 插件开发者(消费方):在自己插件仓库应用本插件,声明拓扑与场景,跑 E2E。
  • CI:以一条命令跑 E2E,用退出码反映 PASS/FAIL。
  • 框架维护者:维护编排插件与模板,修一处环境契约让所有消费项目受益。

3. 用户故事

  • 作为插件开发者,我希望用一段 DSL 声明「代理 + 后端」拓扑并 ./gradlew 跑通一个购买 E2E,以便不必每个项目重搓编排。
  • 作为插件开发者,我希望照抄 template/ 就有桩插件 + 机器人骨架,以便快速加自己的场景。
  • 作为 CI,我希望一条 Gradle 命令跑完 E2E 并以退出码反映 PASS/FAIL,失败有可定位的日志与结果文件。
  • 作为框架维护者,我希望环境契约(机器人协议版本、代理在线模式、BungeeCord 后端配置、数据源/Redis 注入)固化在一处,改一次全项目生效。

4. 功能需求(FR)

编号 需求 优先级 状态
FR-01 Gradle 插件骨架:top.wcpe.mc-testkit(java-gradle-plugin + kotlin-dsl)、mcTestkit { } DSL 扩展、发布到 maven.wcpe.top P1 已交付@v0.1.0
FR-02 内置下载与运行:插件自实现下载并运行 Paper/Folia 后端与 Velocity/Waterfall/BungeeCord 代理(内置自实现,不外挂第三方下载库,见 ADR-0001) P1 已交付@v0.1.0
FR-03 声明式拓扑 DSL:声明「单后端」或「代理 + N 后端」节点、端口与路由 P1 已交付@v0.1.0
FR-04 任务自动编排:prepare / 启动机器人 / runServer / proxy / cluster / verify / 缓存回写 P1 已交付@v0.1.0
FR-05 固化环境契约:经代理固定机器人协议版本、paper-global 代理在线模式、BungeeCord 后端配置、依赖数据源/Redis 注入校验 P1 已交付@v0.1.0
FR-06 机器人驱动 + 结果判定:启动机器人进程、机器人↔桩控制协议、读结果文件判 PASS/FAIL P1 已交付@v0.1.0
FR-07 template/ 脚手架:桩插件骨架 + mineflayer 机器人内核 + 一个示例场景 + 复制说明 P1 已交付@v0.1.0
FR-08 以首个接入的真实插件项目作消费者验证:迁移其编排到本插件,跑通 smoke 与「经 Waterfall 代理购买」 P1 已交付@v0.1.0
FR-09 抽出可发布的共享桩基类库 / 机器人包(第 2 个消费者验证后) P2 计划
FR-10 多后端集群编排:声明「N 后端(同 data-group)+ 代理」拓扑,机器人经代理在后端间 /server 切换,桩跨服判定一致性(扩展 scenario 块 backends(...),见 ADR-0008) P3 已交付@v0.1.0
FR-11 压测编排:N 服 × M bot 钉服持续随机动作(N-listener 代理或直连),每服桩收集各 bot E2E_STRESS_RESULT 聚合判定;业务不变量(不超卖)由消费方桩查共享 DB 断言(扩展 scenario 块 stress{} + 规模 env,见 ADR-0008) P3 已交付@v0.1.0
FR-12 每后端身份注入:编排起每个后端时下发本后端声明名 env MC_TESTKIT_E2E_BACKEND_NAME(与下发给 bot 的 CLUSTER_BACKENDS 同源、有序对应),消费方据此 per-backend 派生身份(如各服不同 server-id);编排只负责告诉每个后端「它是谁」,不规定怎么用(见 docs/specs/fr-12-per-backend-identity.md) P1 已交付@v0.2.0
FR-13 测试环境默认 peaceful 难度:最小 server.properties 默认写 difficulty=peaceful 保护测试玩家不被怪物/环境杀;消费方服务端模板已设 difficulty 则保留其值(不覆盖) P2 已交付@v0.2.0
FR-14 桩兼容更新版 Kotlin 编译的被测插件 API:template/harness-Xskip-metadata-version-check,使桩能 compileOnly 引用「元数据版本高于本工程编译器可读上限」的被测插件类(仅编译期跳过,运行期字节码仍兼容) P2 已交付@v0.2.0
FR-15 集群代理崩溃接管 fallback:集群代理 listener priorities 改为全部后端有序列表(首个仍为默认服 + force_default_server,其余作 fallback),默认后端宕机时 bot 重连经代理回退到下一个存活后端,支撑「崩溃接管」类 E2E(某后端崩溃 → bot 落存活后端、由其在归属租约 TTL 过期后接管上线);正常 /server 切换与 force_default_server 落默认服不受影响(集群编排加法增强,见 ADR-0008) P3 已交付@v0.2.1
FR-16 单场景多 bot:一个 scenario { } 可驱动多个 bot——异质(多个具名 bot("角色") { } 各有 username/action/env)与同质批量bot { count = N } 复制 N 份、各唯一 username、经 BOT_INDEX(1..N)区分);用于集群(多 bot 各自经代理 /server 切)与单后端(多 bot 直连,可分角色)。复用既有 env(BOT_USERNAME/BOT_ACTION/BOT_INDEX/CLUSTER_BACKENDS)与任务名(声明多 bot 时 e2e<Key>/Cluster/launch<Key>Bot 起多个进程),与压测 FR-11「同质钉服」划清边界、随场景结束全部回收;结果仍由桩按 username/index 聚合(扩展 scenario 的 bot 声明,见 ADR-0009) P3 已交付@v0.2.2
FR-17 持久开启·单后端手测:新增 serve { } DSL 块声明持久目标,复用拓扑起后端(+可选经代理)、注入被测/依赖插件并挂住等真人客户端连入手测;不下发场景、不判 PASS/FAIL,手动停(Ctrl+C / stop 任务)按 pid 干净收尾(见 docs/specs/fr-17-persistent-serve.md,ADR-0011) P3 已交付@v0.4.0
FR-18 持久开启·集群拓扑手测:serve { } 支持多后端 + 代理整套挂起,真人经代理 /server 跨服手测、人眼复现跨服 bug;停后全部后端 + 代理收尾干净、端口不漏(见 docs/specs/fr-18-cluster-serve.md,ADR-0011) P3 已交付@v0.4.0
FR-19 持久模式可选并起 bot(人机混场):serve { } 可选起场景 bot 把环境驱到某状态但按结果文件收尾,挂住让真人同时连入同测;停时 bot + 后端 + 代理全收尾(见 docs/specs/fr-19-bot-mixed-serve.md,ADR-0011) P3 已交付@v0.4.0
FR-20 节点运行时注入:保持 dependencies { } 仅注入后端,为 backend / proxy 增加每节点 env 与模板目录、为 proxy 增加专属插件注入,并覆盖 v0.4.2 全部 E2E / serve 启动路径;以真实 BungeeCord 下游消费、旧 DSL 兼容且不引入 provide 为交付门禁(见 docs/specs/fr-20-node-runtime-injection.md) P1 已交付@v0.5.0
FR-21 多版本服务端拉起适配:增强 mc-testkit 支持 8 个代表版本(1.7.10 / 1.8.8 / 1.12.2 / 1.16.5 / 1.17.1 / 1.19.4 / 1.20.1 / 1.21.1)的 Paper 服务端拉起 + bot 协议支持——ServerProperties.versionAwareOverrides(版本感知键过滤 + level-type 转换)、PaperConfigAdapter(按版本生成 paper.yml / paper-global.yml / 跳过)、JavaRuntimeSelectorMC_TESTKIT_JAVA_HOME_<版本段> 覆盖 + JAVA_HOME 回退)、MinecraftVersionGroup(版本段分组查询)、bot 版本范围校验(1.7.10 跳过 bot + 告警,1.8.8+ 正常) P2 已交付@v0.6.0

状态取值:计划 / 开发中 / 已交付@vX.Y.Z。优先级:P1(MVP 或阻断真实消费者接入的关键项) / P2 / P3。 标 已交付 有门:该 FR 的 §6 / spec 验收标准全部满足、对应测试 / 实机验收通过后,才由 sdd-release-version 在发版时统一标 已交付@vX.Y.Z,过程中不得自行预标。

5. 非功能需求(NFR)

  • 可移植:不写死本机绝对路径;服务端/代理 jar 经内置下载模块下载或环境变量提供;他人/CI 拉下即可用。
  • 幂等可重跑:运行目录可清理重建;下载产物缓存复用,避免反复下载。
  • 收尾干净:后台进程(代理、集群后端、机器人)必被收尾杀掉,不残留占端口。
  • 可观测:中文分级日志;结果文件 + 各服/各机器人日志可定位失败原因。
  • 离线/CI 友好:关键 jar 可缓存或经环境变量覆盖,支持无网/弱网环境。
  • 正确性优先:编排不得让"未真正完成"的测试报成功(结果以桩写出的结果文件为权威)。
  • 消费端兼容性:插件构件可被 K1(Gradle 8.x / Kotlin 1.9)与 K2(Gradle 9.x / Kotlin 2.x)的项目消费——Kotlin 语言/API 版本锁 1.9,构建脚本 KTS、实现纯 Kotlin(见 ADR-0005)。

6. 验收标准

  • 首个接入项目接入本插件后,e2eSmoke 与「经 Waterfall 代理购买」场景均 PASS(实机维度,需用户在备齐依赖库/服务端模板/数据库/Redis 的环境确认通过)。
  • 插件应用后配置期任务图无环、任务名稳定、缺依赖时报中文明确错误。
  • 一个全新项目按 template/ 照抄,能在较短时间内(手动验收)跑通一个最小购买场景。
  • 后台进程在任务结束/失败后均被收尾,端口释放、无残留(实机维度,需确认)。
  • 集群/压测下各后端经 MC_TESTKIT_E2E_BACKEND_NAME 收到各自声明名,消费方据此派生不同 server-id(FR-12);smoke 结果含 backendName=s1、集群到达服结果含其服名(已自举验证),下游跨服一致性 / 转服不丢数据断言由消费方桩查共享 DB 自证(实机维度,需用户确认)。
  • FR-20 以真实 BungeeCord 消费验证为交付门禁:下游代理插件经代理节点专属声明成功加载,backend / proxy 每节点 env 与模板分别生效;旧 DSL 与 dependencies { } 仅后端注入语义不回归;公共 DSL / 任务不引入 provideBeacon 真实消费与完整构建已确认)。

7. 分期(路线)

各期只描述主题 / 目标;具体哪个 FR 属于哪期,以 §4 FR 表的优先级列为唯一来源。

  • 第一期(MVP):把核心立起来——Gradle 编排插件(Paper/Folia 后端 + Velocity/Waterfall/BungeeCord 代理)+ 脚手架模板,以首个接入项目跑通。
  • 第二期:在第 2 个真实消费者验证后抽出可发布的共享桩 / 机器人库。
  • 第三期:完善——更多拓扑形态、并发压测沉淀、持久手测/沙盒模式(serve)、文档与示例丰富。

期是粗粒度路线图横轴,数量很少;一期含很多 FR、跨很多版本。某期是否完成看 §4 表里该期 FR 状态是否都 已交付

8. 术语表

  • 后端(backend):承载游戏逻辑的服务端(Paper/Folia)。
  • 代理(proxy):玩家入口、转发到后端的代理(Velocity/Waterfall/BungeeCord)。
  • 拓扑(topology):一次测试里代理与后端的组合与路由关系。
  • 桩插件(harness):装进被测后端、装备玩家/驱动场景/判定结果的测试用服务端插件。
  • 机器人(bot):基于 mineflayer 的 Node 程序,模拟真实玩家入服驱动场景。
  • 场景(scenario):一次端到端用例(如「购买成功」「购买中退出」「持续压测」)。
  • 控制协议:机器人与桩之间的约定消息(如 E2E_READY / E2E_STRESS_RESULT)。