news 2026/9/13 9:37:40

如何运行 LibreChat mock e2e 套件验证真实 Redis 流存储未静默回退到内存模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何运行 LibreChat mock e2e 套件验证真实 Redis 流存储未静默回退到内存模式

如何运行 LibreChat mock e2e 套件验证真实 Redis 流存储未静默回退到内存模式

【免费下载链接】LibreChatEnhanced ChatGPT Clone: Features Agents, MCP, Skills, DeepSeek, Anthropic, AWS, OpenAI, Responses API, Azure, Groq, o1, GPT-5, Mistral, OpenRouter, Vertex AI, Gemini, Artifacts, AI model switching, message search, Code Interpreter, langchain, DALL-E-3, OpenAPI Actions, Functions, Secure Multi-User Auth, Presets, open-source for self-hosting. Active项目地址: https://gitcode.com/GitHub_Trending/li/LibreChat

LibreChat 的 mock e2e profile 默认使用进程内(in-memory)的 generation stream store:测试服务器带着e2e/config/librechat.e2e.yaml启动,并通过LIBRECHAT_TEST_RUN_HOOK注入一个进程内 fake LLM,不需要任何真实 provider 凭据。但“能跑起来”不代表流真的走了 Redis——如果 Redis 连接失败而服务器悄悄退回内存存储,浏览器场景照样能通过,测试就失去了对 Redis job store 和 pub/sub 传输的覆盖。

这篇文章的任务是:在本地用 Redis 流模式跑 LibreChat 的 mock e2e 套件,并依靠该套件内建的 fail-closed 启动检查,确认 generation job manager 没有静默回退到内存模式。适用前提是项目依赖已安装、本机有一个运行在 6379 端口的 Redis(可通过REDIS_URI覆盖)。

机制说明:Redis 模式在哪里生效、在哪里被强制验证

流模式由环境变量E2E_STREAM_STORE控制,取值逻辑在 getStreamStoreEnv 中:

  • 不设置时默认memory,此时显式置USE_REDIS=falseUSE_REDIS_STREAMS=falseUSE_REDIS_CLUSTER=false,即“内存模式明确禁用 Redis”;
  • 设为redis时,置E2E_REQUIRE_REDIS_STREAMS=trueUSE_REDIS=trueUSE_REDIS_STREAMS=trueUSE_REDIS_CLUSTER=falseREDIS_URI默认redis://127.0.0.1:6379/15(database 15),REDIS_KEY_PREFIX默认LibreChatE2E
  • 设为其他值会直接抛错Unsupported E2E_STREAM_STORE "..."

真正的“未回退”验证发生在测试服务器启动脚本 e2e/setup/start-server.js 中,只有E2E_REQUIRE_REDIS_STREAMS=true时执行:

  1. requireRedisStreams():通过@librechat/api导出的ioredisClient对 Redis 发 ping,超时 10000ms。没有配置 Redis client 时抛[e2e] Redis stream mode was required but no Redis client was configured;ping 无响应时抛[e2e] Redis did not respond within 10000ms
  2. verifyRedisStreams():在 15000ms 内轮询GenerationJobManager.isRedis,为true时打印[e2e] Verified Redis-backed generation streams并放行;到点仍为false则抛[e2e] Redis stream mode was required but the server fell back to memory,进程以退出码 1 结束(日志前缀[e2e] Failed to start test server:)。

也就是说,静默回退在 webServer 启动阶段就会让整轮 Playwright 运行失败,而不是让测试“在内存上假装通过”。

准备条件

  • Redis:在 6379 端口可连接即可([e2e/README.md](https://link.gitcode.com/i/80da4cda6c3685684a0b571bb40b5701)的表述就是 “start Redis on port 6379”)。要连别的实例或库,导出REDIS_URI;要改 key 前缀,导出E2E_REDIS_KEY_PREFIX
  • MongoDB 不是硬性前置:MONGO_URI默认mongodb://127.0.0.1:27017/LibreChat-e2e,当E2E_USE_MEMORY_MONGO为默认值auto且本地连不上时,启动脚本会自动拉起 mongodb-memory-server 并打印[e2e] Started memory MongoDB at ...(见 maybeStartMemoryMongo)。
  • 构建产物不需要手动准备:下面的e2e:mock:redis脚本内联了e2e:prepare,即 package.json 中的npm run frontend,会依次执行build:data-providerbuild:data-schemasbuild:apibuild:client-package并构建 client。首次运行耗时就在这一步。
  • 不需要 OpenAI 等真实凭据;fake model 钩子在请求发生前替换了 GRAPH。本地.env里形似凭据的变量会被启动配置抹掉,避免泄漏进测试服务器。
  • 端口占用:测试服务器默认绑定http://localhost:3080E2E_BASE_URL可覆盖),另有三个本地 fixture 服务占用 8765、8889、8890(见 playwright.config.mock.ts)。若 3080 已被普通 dev server 占用,可用E2E_BASE_URL换一个地址再运行。

运行命令

最短主路径,跑完整 mock 套件(Redis 流模式):

npm run e2e:mock:redis

它等价于:

npm run e2e:prepare && cross-env E2E_STREAM_STORE=redis playwright test --config=e2e/playwright.config.mock.ts

即先完成上述前端构建,再以E2E_STREAM_STORE=redis启动整套e2e/specs/mock/用例。Playwright 会先启动 fixture 服务与测试服务器(含前述 fail-closed 检查),再由 global setup 自动注册/登录 e2e 用户(默认testuser@example.com,见 getE2EUser),最后单 worker 串行执行全部 spec。

与 CI 一致的聚焦路径,只跑跨越流存储边界的浏览器场景:

npm run e2e:mock:redis:transport

它使用派生配置 e2e/playwright.config.redis.ts,testMatch限定 10 个 spec:completiondeferred-tools-hitlmodel-spec-iconssteeringsteering-escalationstreamingsubagent-activitythread-foldtool-approvalsusage,并把断言超时从 10s 提到 20s(该通道每个流事件都经过一次真实 Redis 往返,pause/resume 与重放路径更接近预算上限)。注意它与e2e:mock:redis的差别:前者用playwright.config.redis.ts只跑这 10 个 spec,后者用playwright.config.mock.ts跑完整套件;两者都强制 Redis 流模式。

对照组(可选分支):

npm run e2e:mock

不带E2E_STREAM_STORE时按 memory 模式运行同一套 spec,用于和 Redis 通道做行为对比。参考 e2e/README.md,Pull request CI 的做法是:memory 模式把完整套件分到 3 个 shard(如npx playwright test --config=e2e/playwright.config.mock.ts --shard=1/3),外加一条聚焦的 Redis 传输套件npm run e2e:mock:redis:transport;nightly 则在两种流模式下各跑完整套件。

redis-cluster是另一套拓扑(E2E_STREAM_STORE=redis-cluster,默认集群端点为 7001/7002/7003 三节点),本文的单机 Redis 路径不涉及它,两者不要混在同一条操作链里。

结果验证

按启动顺序核对三类信号:

  1. 启动期通过检查:服务器日志出现

    [e2e] Verified Redis-backed generation streams

    这一行是“job manager 确认运行在 Redis 上”的直接证据,出现在任何测试执行之前。

  2. fail-closed 失败信号:若出现以下任一输出,说明运行没有按 Redis 模式生效,Playwright 本轮不会开始跑用例:

    • [e2e] Redis did not respond within 10000ms(Redis 起了但 ping 超时,检查REDIS_URI指向的实例是否真的在监听);
    • [e2e] Redis stream mode was required but the server fell back to memory(ping 通过但 job manager 未切到 Redis,属于本次要捕获的静默回退,服务器直接exit(1));
    • [e2e] Redis stream mode was required but no Redis client was configured@librechat/api未导出 ioredis client,通常是依赖构建不完整,先确认e2e:prepare全链路成功)。
  3. 用例结果:启动检查通过后,以 Playwright 退出码与 HTML 报告为最终判定。报告写入e2e/playwright-report,用下面命令查看:

    npm run e2e:report

    本地运行时retries为 0(CI 下 mock 配置为 2、redis 派生配置为 3),所以本地失败即为真实失败;失败用例的 trace 保留在e2e/specs/.test-results

限制与边界

  • 验证的是“未静默回退”,不是性能:该通道不产出 Redis 与内存的耗时对比,不要用它得出吞吐结论。
  • Redis 通道的 key 前缀默认LibreChatE2E、默认落在 database 15,与生产部署的 Redis 不共用命名空间;改前缀只影响测试数据的隔离方式,不影响 fail-closed 判定本身。
  • 如果服务器日志里没有第 1 节列出的[e2e] Verified ...行,也不在失败信号之列(例如你运行的是e2e:mock而非e2e:mock:redis),那只是说明本轮走的是 memory 模式(E2E_REQUIRE_REDIS_STREAMS=false时两个检查函数直接返回),并不构成回退证据。

【免费下载链接】LibreChatEnhanced ChatGPT Clone: Features Agents, MCP, Skills, DeepSeek, Anthropic, AWS, OpenAI, Responses API, Azure, Groq, o1, GPT-5, Mistral, OpenRouter, Vertex AI, Gemini, Artifacts, AI model switching, message search, Code Interpreter, langchain, DALL-E-3, OpenAPI Actions, Functions, Secure Multi-User Auth, Presets, open-source for self-hosting. Active项目地址: https://gitcode.com/GitHub_Trending/li/LibreChat

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

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

HDMI切换器选购避坑指南:从参数陷阱到品牌梯队一次说清

/* 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 9:32:30

diagram-design:图谱即代码的工程化实践

1. 为什么“diagram-design”不是个工具名,而是一套需要重新理解的工程能力 最近在几个技术社区里反复看到这个词被当作搜索关键词刷屏: diagram-design 。它不像“React开发”或“Python爬虫”那样指向明确的技术栈,也不像“UI设计”那样有…

作者头像 李华
网站建设 2026/9/13 9:32:15

静态代码分析工具实战:从Cppcheck到SonarQube的选型与集成

/* 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 9:30:22

Java+小程序协同过滤推荐系统实战指南

简介:本资源是一套完整的基于协同过滤算法的商品推荐系统实战源码,面向Java后端开发者与微信小程序全栈学习者,解决电商场景下个性化商品推荐与移动端购物闭环构建问题。压缩包共93个文件,总计13.25MB,涵盖Java后端逻辑…

作者头像 李华
网站建设 2026/9/13 9:29:47

2026年AI设计工具:多模型协同与智能编辑技术解析

1. 2026年AI设计工具市场现状与核心需求2026年的数字内容创作领域已经全面进入AI辅助时代,桌面高清壁纸设计作为视觉内容的重要分支,其生产方式发生了革命性变化。根据最新行业调研数据,超过78%的专业设计师已将AI工具纳入标准工作流&#xf…

作者头像 李华