news 2026/9/13 5:09:39

Mastra 实验 Worker E2E 测试套件解析:发布安装契约、隔离沙箱与协议验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mastra 实验 Worker E2E 测试套件解析:发布安装契约、隔离沙箱与协议验证

Mastra 实验 Worker E2E 测试套件解析:发布安装契约、隔离沙箱与协议验证

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

导读

Mastra 的experiment-workerE2E 套件(位于 e2e-tests/experiment-worker/README.md)从“隔离的客户项目”视角,验证已发布、已安装的mastra experiment build契约:构建独立产物、将产物复制到远离源码的位置、启动全新 worker 进程,并记录协议、产物、进程、服务与清理证据。读完本文,你将掌握该套件的本地命令与分层(pr/full/gated)测试策略、临时 Verdaccio 与 CI 发布型两种注册表模式、NDJSON 运行协议与 manifest 结构、隔离与所有权断言的设计思路,以及如何用它守护 Mastra 实验 Worker 的交付质量。

背景:为什么要做“已安装契约”E2E

普通单元测试在 monorepo 内运行,import解析、依赖提升、路径重写都会掩盖“真实客户安装后”才会暴露的问题。该套件的核心主张是:只在隔离的客户项目中,验证发布并安装后的产物。README 的第一段明确了整条验证链路:

  1. 从发布包安装依赖(而非 workspace 链接);
  2. 运行mastra experiment build生成独立 artifact;
  3. 把 artifact 从源码项目复制走,甚至删除源项目;
  4. 以全新 worker 进程启动 artifact,通过标准输入输出交互;
  5. 记录协议事件、产物清单、进程、服务与清理证据。

套件自身以 Vitest 驱动,工程入口在 e2e-tests/experiment-worker/package.json,运行环境为 Node,testTimeout为 90 秒、hookTimeout为 15 分钟(见 vitest.config.ts)。

本地命令与测试分层

README 给出的本地命令如下:

pnpm install --frozen-lockfile pnpm test:experiment pnpm test:full pnpm test:full:strict pnpm test:scenario -- minimal-agent pnpm test:workflow-routing

各命令的实际含义可在 package.json 中对应到具体实现:

  • pnpm test:experiment:设置MASTRA_EXPERIMENT_E2E_TIER=pr后运行vitest run,是确定性、无需凭据的 PR 门禁;
  • pnpm test:full:设置MASTRA_EXPERIMENT_E2E_TIER=full,追加包管理器、workspace、浏览器、LSP、原生依赖、Docker/Postgres、可移植性与负向边界覆盖;
  • pnpm test:full:strict:在full基础上再加MASTRA_EXPERIMENT_E2E_REQUIRE_PUBLISHED_REGISTRY=1,强制使用 CI 发布的注册表快照;
  • pnpm test:scenario -- <id>:经由 scripts/run-scenario.mjs 只跑一个 owning scenario——它会把MASTRA_EXPERIMENT_E2E_TIER默认置为full并注入MASTRA_EXPERIMENT_E2E_SCENARIO,但仍会执行注册表发布与全局 setup;
  • pnpm test:workflow-routing:使用独立的vitest.routing.config.ts跑工作流路由测试。

分层选择在 vitest.config.ts 中直接体现:prTests只含setup/harness/minimal-agent/target-process/runtime-resources/native-duckdb六个文件;fullTests再追加full-workspace-lifecyclepostgres-lifecycleproject-shapesportability-isolationinstalled-boundary-negative五个文件。测试文件清单见 tests/。

注册表模式:本地临时 Verdaccio 与 CI 发布快照

默认情况下,套件在 global setup(setup.ts)中完成四件事:构建 CLI(pnpm build:cli)、把 snapshot 包发布到临时 Verdaccio 注册表、用npm view断言mastra@mastra/core两个必发包存在、结束时清理整个运行根目录与注册表。这里借用了仓库通用的本地注册表基建 e2e-tests/_local-registry-setup/,其 Verdaccio 配置为 verdaccio.yaml。

CI 则只发布一次,并把发布产物以不可变快照形式传给各 job,通过以下环境变量交接(README 列出的完整清单):

环境变量作用
MASTRA_E2E_REGISTRY_STORAGE已发布注册表的存储目录
MASTRA_E2E_REGISTRY_CONFIGVerdaccio 配置文件路径
MASTRA_E2E_REGISTRY_TAGsnapshot 发布的 tag(CI 中为experiment-worker-ci-<run_id>-<run_attempt>
MASTRA_E2E_REGISTRY_ARTIFACT_PATH注册表快照 tar 包路径
MASTRA_E2E_REGISTRY_ARTIFACT_DIGEST快照的规范摘要(发布方计算、消费方校验)
MASTRA_E2E_REGISTRY_PORT本地起注册表时使用的端口
MASTRA_EXPERIMENT_E2E_REQUIRE_PUBLISHED_REGISTRY=1强制使用发布型注册表,禁止本地发布

发布型模式的防篡改设计(见 setup.ts):消费方先用 scripts/registry-artifact-digest.cjs 对下载的注册表快照计算摘要,与MASTRA_E2E_REGISTRY_ARTIFACT_DIGEST比对;不一致直接抛错拒绝。被复制或下载、与发布方规范摘要不一致的存储一律拒绝使用。摘要计算与校验逻辑在 helpers/registry-digest.ts。

MASTRA_EXPERIMENT_E2E_REPORT_DIR用于把 JSON、Markdown、构建日志和 NDJSON 协议转录保存到临时运行根之外,便于 CI 上传取证。PR/full 层级要求每个必跑 scenario 各产出一份 JSON 与一份 Markdown 报告,外加summary.json;只要有必跑 scenario 缺失、跳过或失败即整体失败。

CI 分层:pr / full / gated

CI 编排在 .github/workflows/e2e-experiment-worker.yml:

  • 调度:每周二 07:00 UTC(cron: '0 7 * * 2')自动运行;也支持手动workflow_dispatch,可选prfullgated分层和单个 scenario 选择器;
  • 共享不可变产物publish-experiment-worker-registryjob 先pnpm build、发布注册表、打成registry-snapshot.tar、用 registry-artifact-digest.cjs 计算摘要并上传为experiment-worker-registryartifact;full、browser、gated 各 job 都从它下载并解包校验;
  • PR 复用同一发布型契约:PR 走 .github/workflows/e2e-tests.yml,由prebuild.yml的精确路径路由(path routing)决定是否触发,从而避免无关改动白白消耗 E2E 资源;
  • gated 接口独立运行remote-sandboxobject-storereal-modelhosted-proxy四个 gated job 运行在experiment-worker-e2e-gatedGitHub Environment 中,通过 scripts/gated-interface.mjs 调用。缺少凭据时产出status: skipped、skip code 为GATED_CREDENTIALS_MISSING永远不会阻塞开源必须通过的验收;而必跑的 PR/full job 不注入任何 provider 凭据,保证 OSS 验收的确定性。

隔离与所有权:不信任源码、不共享状态

README 的“Isolation and ownership”段落总结了三条硬性约束,均有源码佐证:

  1. 依赖布局敏感的 fixture 使用独立安装根,绝不共享node_modules:materialize/install 逻辑在 helpers/materialize-project.ts 与 helpers/install-project.ts,fixtures 分别覆盖 npm、yarn(berry)、pnpm workspace 单仓、native 原生依赖、postgres 等安装形态(见 fixtures/)。
  2. 复制后的产物要检查是否残留源码 workspace 引用:helpers/copy-artifact.ts 在cp后遍历产物目录,对每个文件内容、每个符号链接目标做 POSIX/Windows/file:///URL 编码多形态的“针搜索”,发现任一源路径即抛错;测试还会删除源项目再运行协议,证明 worker 与源码完全无关。
  3. 清理断言只覆盖 harness 自己创建的资源:临时路径、进程组、端口、注册表、数据库、容器。进程组与资源追踪在 helpers/process-cleanup.ts,minimal-agent测试用expect(cleanup.remainingPaths).toEqual([])收尾(见 tests/minimal-agent.test.ts)。

边界说明:README 明确指出 Platform 的 Linux sandbox 执行不属于本 OSS 套件;托管调度与权威的 experiment/score 持久化由 Platform 负责,worker 只在不持有 Platform 凭据的前提下验证独立产物与协议边界。

协议契约:NDJSON 帧与最小环境

worker 通过 stdin/stdout 通信,协议为NDJSON,每行一个事件,事件带type与自增sequence。请求构建与响应解析全部集中在 helpers/run-protocol.ts:

  • createRunRequest()构造type: 'run'帧,含protocolVersion: '1'experimentId/jobId/idempotencyKeydeadlineAt、基于 items 规范序列化(key 排序)的 SHA-256datasetAttestation.digest、以及包含 target/dataset/scorers/limits/policies/secretReferences 的packet
  • parseProtocolOutput()要求 stdout 以换行结尾、逐行 JSON 可解析,且event.sequence必须从 0 连续递增,否则报“非协议 stdout/非连续序列”;
  • assertProtocolResult()断言事件边界:成功路径必须是accepted → run-started → (item-completed)* → terminal,失败路径首事件为accepted、末事件为terminal
  • runCancelledProtocol()spawn(非 Windows 上detached)启动 worker,在目标事件(默认run-started,可用readyWhen谓词等待在途 item 到达特定状态)后发送type: 'cancel'帧,随后期望退出码 30,并校验取消帧确已送达;
  • minimalWorkerEnvironment()只保留PATH/HOME/TMPDIR/TMP/TEMP/SystemRoot/WINDIR/NODE_OPTIONS七个白名单变量,模拟近乎裸机的最小运行环境。

对应到场景:truncated-input(截断输入应得到协议退出码、stdout 为空、stderr 有诊断)、process-cancellationsandbox-cancellation(终止一致性、后代进程被杀、取消后能再次成功)等场景定义在 scenarios/index.ts。

Manifest:产物自描述的契约载体

构建产物根目录必须包含experiment-worker-manifest.json,其结构与校验逻辑在 helpers/inspect-manifest.ts:

{ artifactVersion: 1, kind: 'mastra-experiment-worker', build: { buildId, cliVersion, createdAt }, protocol: { versions: ['1'], framing: 'ndjson', datasetCanonicalizationVersion: '1' }, launch: { executable: 'node', arguments: [...'index.mjs'], workingDirectory: '.' }, dependencies: { manifest, lockfile? }, artifact: { digestAlgorithm: 'sha256', contentDigest, excludes: [...] }, files: [{ path, sha256, type?: 'file'|'symlink', target? }] }

校验器会强制artifactVersion === 1kind === 'mastra-experiment-worker'、启动方式必须是node index.mjs且工作目录为.,并要求excludes至少声明experiment-worker-manifest.jsonnode_modules(产物不自带依赖目录)。文件清单必须按路径排序,每个文件的 SHA-256 逐一重算比对,符号链接则对链接目标求摘要,任何逃逸出产物根目录的路径都会被拒绝;最后用path\0sha256\n拼接重算contentDigest与 artifact 层摘要比对,形成文件级 + 内容级双重完整性校验。

场景矩阵:从最小 Agent 到负向边界

scenarios/index.ts 以ScenarioDefinition(id/fixture/isolationKey/tier/services/credentials/timeoutMs/assertions)声明 27 个场景,可按需归类:

  • PR 层运行时场景(runtime fixture,180s):minimal-agent(发布安装→构建→清单合法→产物搬移→源码无关→协议成功→stdout 仅协议→清理完成)、copied-artifactmocked-tool-agent(mock 工具成功/拒绝未 mock/副作用缺席/先失败后成功)、resumable-workflow(挂起恢复 + 同步/异步 scorer)、process-cancellationtruncated-input
  • PR 层资源场景(resources fixture,180s):workspace-skill-agent(workspace 继承、skill 发现与提示注入)、workspace-sandbox(文件写入、沙箱命令、skill 列表)、sandbox-cancellationpersistence-isolation(配置初始化隔离、应用存储写入、vector adapter 执行、experiment/score 记录缺席);
  • full 层资源场景workspace-owned-overrideworkspace-dynamic(并发 item、同 key 一致、异 key 隔离、清理)、workspace-search(BM25/向量/混合检索)、workspace-mounts(多挂载路由、只读挂载)、workspace-lsp(语言服务器启动/hover/关闭)、workspace-browser(惰性启动、线程触发、CLI 执行、关闭)、workspace-failures(初始化/关闭失败上报、非法配置拒绝、干净退出);
  • 服务型场景postgres(300s,需 docker + postgres,验证应用状态持久化、experiment 持久化缺席、有界关闭、连接复用、docker 清理);
  • 项目形态场景(240s):npm-minimalyarn-minimal(验证 berry 的 node_modules 布局)、pnpm-monorepo(workspace 包导入)、portability-isolation(重复构建契约稳定、易变构建元数据、并发 worker、突然终止恢复、产物不可变)、kitchen-sink(重 import 构建、选中 agent/workflow 执行、studio 不启动)、native-duckdb(240s,原生依赖声明、可移植提升布局、原生 vector 执行);
  • 负向边界场景negative-malformed-approvals(非法 pnpm 审批诊断)、negative-missing-mastranegative-import-failure(客户 import 诊断)。

报告与证据链

每个场景结束时,helpers/report.ts 按schemaVersion: 1写出<scenarioId>.json<scenarioId>.md,内容包括 tier、fixture、isolationKey、包管理器版本、注册表 tag 与 artifact 摘要、断言级passed/failed/skipped状态与证据、起止时间与耗时、诊断信息;断言证据的落盘在 helpers/assertion-evidence.ts。minimal-agent测试还会把协议 NDJSON 转录与构建日志(含 stderr)一并写入报告目录,供失败时离线排查(tests/minimal-agent.test.ts)。报告结构与断言 schema 的一致性由 tests/scenario-reporter.test.ts 守护。

实际 fixture 长什么样

以 fixtures/runtime/src/mastra/index.ts 为例,一个典型 fixture 会在不联网的前提下构造确定性模型(doGenerate/doStream返回固定 token 统计与文本)、最小 Agent、带工具的 mock 模型 Agent(奇偶调用先返回tool-calls再返回文本)、25 秒慢模型 Agent(配合取消场景)、挂起/恢复的 approval step 工作流、同步与异步 scorer,最后export const mastra = new Mastra({ agents, workflows, scorers }),并在console.error输出minimal experiment fixture initialized作为初始化标记(测试断言 stderr 包含该标记)。这也是“无需真实模型、可复现、可离线跑 PR 门禁”的关键设计。

小结

experiment-workerE2E 套件把 Mastra 实验 Worker 的交付质量拆解为四层防线:发布型注册表摘要校验保证安装源可信;隔离安装 + 产物搬移 + 源引用扫描保证 artifact 与源码解耦;NDJSON 协议 + 最小环境保证 worker 进程边界确定;pr/full/gated 分层 + 断言级报告保证 OSS 验收确定性且不阻塞凭据敏感场景。理解这套结构,无论是要扩展新的实验场景、接入新的包管理器形态,还是复现 CI 失败,都能直接定位到 scenarios/index.ts、setup.ts 与对应 helpers 完成闭环。

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 5:03:54

OpenRT框架:大模型红队测试实战指南

1. OpenRT框架概述&#xff1a;为什么大模型需要红队测试&#xff1f; 在2023年大模型爆发式增长后&#xff0c;行业逐渐意识到一个关键问题&#xff1a;这些看似智能的系统在真实场景中可能暴露出令人意外的脆弱性。OpenRT正是在这种背景下诞生的开源工具&#xff0c;它专门针…

作者头像 李华
网站建设 2026/9/13 5:02:02

Elasticsearch重建索引:字段类型变更的原理与实战路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 5:01:10

Hadoop生态完全拆解:从HDFS原理到伪分布式搭建与Zookeeper整合

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 5:00:44

Windows11 WSL2部署Openclaw接入飞书AI助手实践

1. 项目概述在Windows11环境下通过WSL2运行Openclaw并接入飞书应用&#xff0c;是一个典型的AI助手本地化部署方案。这个组合能让开发者在熟悉的Windows系统中获得接近原生Linux的开发体验&#xff0c;同时将智能助手深度集成到日常办公场景。我最近刚在团队内部完成了这套系统…

作者头像 李华
网站建设 2026/9/13 5:00:39

teamai-cli:MCP协议开发者的命令行握手接口

1. 项目概述&#xff1a;一个被误读却极具潜力的开发者工具链入口“teamai-cli”这个名字乍看像某个AI团队内部孵化的私有命令行工具&#xff0c;但结合当前全网搜索热度、npm包管理生态和CI/CD工程实践语境&#xff0c;它实际指向的是一类正在快速演进的智能体协作协议&#x…

作者头像 李华