PageSourceSearch

https://montplex.com/static/js/async/2805.5a8ef0ba.js

js montplex.com collected 2026-10-03 21:16:24 UTC 19,848 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkengula_website=self.webpackChunkengula_website||[]).push([["2805"],{7150:function(e,n,d){d.r(n),d.d(n,{default:()=>c});var s=d(2676),r=d(453);function i(e){let n=Object.assign({h1:"h1",a:"a",p:"p",strong:"strong",blockquote:"blockquote",code:"code",h2:"h2",table:"table",thead:"thead",tr:"tr",th:"th",tbody:"tbody",td:"td",ol:"ol",li:"li",pre:"pre",ul:"ul",h3:"h3"},(0,r.ah)(),e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"engula-clientcompat客户端兼容性测试工具",children:["Engula ClientCompat(客户端兼容性测试工具)",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#engula-clientcompat客户端兼容性测试工具",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Engula ClientCompat 是一个 Docker 可运行的客户端兼容性验证工具。它把主流 Redis 社区客户端的官方测试集打包到镜像中,用同一套测试分别验证 Redis 7.2 基线和 Engula,并生成 HTML 报告。"}),"\n",(0,s.jsxs)(n.p,{children:["这篇官网指南只介绍 ",(0,s.jsx)(n.strong,{children:"Docker 镜像 + 常用运行方式 + 报告解读"}
1),"。源码构建、客户端源码切换、长期趋势入库和 CI 深度集成等高级用法,会放在开源项目文档中维护。"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["安全提示:只有运行 ",(0,s.jsx)(n.code,{children:"jedis"}),"、",(0,s.jsx)(n.code,{children:"redis-py"}),"、",(0,s.jsx)(n.code,{children:"node-redis"})," 这类需要再次启动辅助容器的测试时,才需要把宿主机 Docker socket 挂入测试容器。这样容器可以调用宿主机 Docker daemon,请只在受控测试机中使用。"]}),"\n"]}),"\n",(0,s.jsxs)(n.h2,{id:"1-这个工具验证什么",children:["1. 这个工具验证什么",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#1-这个工具验证什么",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"客户端兼容性测试回答的问题是:现有 Redis 客户端 SDK 使用 Engula 作为服务端时,连接、命令、事务、Pipeline、Pub/Sub、Stream、TLS 等常见行为是否与 Redis 7.2 基线保持一致。"}),"\n",(0,s.jsx)(n.p,{children:"当前镜像聚焦 4 个社区客户端:"}),"\n",(0,s.jsxs)(n.table,{children:["\n",(0,s.jsxs)(n.thead,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.th,{children:"客户端"}),"\n",(0,s.jsx)(n.th,{children:"语言"}),"\n",(0,s.jsx)(n.th,{children:"默认版本"}),"\n",(0,s.jsx)(n.th,{children:"测试方式"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.tbody,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"Jedis"}),"\n",(0,s.jsx)(n.td,{children:"Java"}),"\n",(0,s.jsx)(n.td,{children:"v6.2.0"}),"\n",(0,s.jsx)(n.td,{children:"Maven / JUnit"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"redis-py"}),"\n",(0,s.jsx)(n.td,{children:"Python"}),"\n",(0,s.jsx)(n.td,{children:"master"}),"\n",(0,s.jsx)(n.td,{children:"pytest"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"go-redis"}),"\n",(0,s.jsx)(n.td,{children:"Go"}),"\n",(0,s.jsx)(n.td,{children:"v9.3.1"}),"\n",(0,s.jsx)(n.td,{children:"go test / Ginkgo"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"node-redis"}),"\n",(0,s.jsx)(n.td,{children:"Node.js"}),"\n",(0,s.jsx)(n.td,{children:"stable"}),"\n",(0,s.jsx)(n.td,{children:"npm / Mocha"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["如果您只想快速确认 Redis 命令与数据结构兼容性,优先使用 ",(0,s.jsx)(n.a,{href:"/docs/tools/kernelcompat",children:"Engula KernelCompat"}),"。如果您要做完整交付验收,使用 ",(0,s.jsx)(n.a,{href:"/docs/codeproof/usage-guide",children:"Engula CodeProof"}),"。ClientCompat 位于两者之间,专门验证真实客户端生态。"]}),"\n",(0,s.jsxs)(n.h2,{id:"2-验证原理",children:["2. 验证原理",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#2-验证原理",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"每个客户端测试都会按同一套流程运行:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"在容器内启动 Redis 7.2 作为基线服务。"}),"\n",(0,s.jsx)(n.li,{children:"使用客户端官方测试集运行一遍,记录 Redis 基线通过情况。"}),"\n",(0,s.jsx)(n.li,{children:"在相同测试环境中启动 Engula。"}),"\n",(0,s.jsx)(n.li,{children:"使用同一份客户端源码和同一版本测试集再运行一遍。"}),"\n",(0,s.jsx)(n.li,{children:"解析 JUnit、pytest、Ginkgo 或 Mocha 结果,按测试用例统计 Pass / Fail / Skip。"}),"\n",(0,s.jsxs)(n.li,{children:["生成 ",(0,s.jsx)(n.code,{children:"report.html"}),",展示 Engula 与 Redis 基线的通过率、差异用例和日志位置。"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"默认判断方式是通过率对齐 Redis 基线。报告会同时列出 Redis 基线结果和 Engula 结果,方便判断差异来自 Engula 行为、客户端测试假设,还是上游测试环境。"}),"\n",(0,s.jsxs)(n.h2,{id:"3-运行前准备",children:["3. 运行前准备",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#3-运行前准备",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"官网版使用预构建 Docker 镜像运行,不需要在主机上安装 Java、Maven、Python、Go、Node.js 或客户端源码。您只需要准备:"}),"\n",(0,s.jsxs)(n.table,{children:["\n",(0,s.jsxs)(n.thead,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.th,{children:"项目"}),"\n",(0,s.jsx)(n.th,{children:"说明"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.tbody,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"Docker"}
1),"\n",(0,s.jsxs)(n.td,{children:["主机已安装 Docker,并能执行 ",(0,s.jsx)(n.code,{children:"docker pull"})," 与 ",(0,s.jsx)(n.code,{children:"docker run"})]}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"磁盘目录"}),"\n",(0,s.jsxs)(n.td,{children:["准备一个 ",(0,s.jsx)(n.code,{children:"results/"})," 目录保存报告"]}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"CPU / 内存"}),"\n",(0,s.jsx)(n.td,{children:"建议至少 8GB 内存;完整运行 4 个客户端会比单个客户端耗时更久"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:"网络"}),"\n",(0,s.jsx)(n.td,{children:"首次运行部分客户端测试时,可能需要拉取辅助测试镜像"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"go-redis"})," 测试不需要挂载 Docker socket,适合作为第一次快速跑通验证。",(0,s.jsx)(n.code,{children:"jedis"}),"、",(0,s.jsx)(n.code,{children:"redis-py"}),"、",(0,s.jsx)(n.code,{children:"node-redis"})," 会启动辅助容器,因此需要额外挂载 Docker socket。"]}),"\n",(0,s.jsxs)(n.h2,{id:"4-拉取镜像",children:["4. 拉取镜像",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#4-拉取镜像",children:"#"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker pull registry.ap-southeast-1.aliyuncs.com/montplex/engula-client-compat:latest\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:":latest"})," 是多架构镜像,amd64 与 arm64 主机会自动拉取匹配架构。"]}),"\n",(0,s.jsxs)(n.h2,{id:"5-快速开始先跑-go-redis",children:["5. 快速开始:先跑 go-redis",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#5-快速开始先跑-go-redis",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"go-redis"})," 不需要额外挂载 Docker socket,命令最简单:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'mkdir -p results\n\ndocker run --rm \\\n  -v "$(pwd)/results:/work/results" \\\n  registry.ap-southeast-1.aliyuncs.com/montplex/engula-client-compat:latest \\\n  proof test client --sub 2.3 \\\n    --results-dir /work/results \\\n    --version engula-latest\n'})}),"\n",(0,s.jsxs)(n.p,{children:["这里的 ",(0,s.jsx)(n.code,{children:"--sub 2.3"})," 对应 go-redis,用作最小化示例。完整客户端验证可以直接运行下一节的命令。"]}),"\n",(0,s.jsxs)(n.p,{children:["运行结束后,在主机当前目录的 ",(0,s.jsx)(n.code,{children:"results/"})," 下查看报告:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"results/\n└── client-2.3-go-redis-logs/\n    └── 20260519T100000/\n        ├── main.log\n        ├── report.json\n        └── report.html\n"})}),"\n",(0,s.jsxs)(n.p,{children:["浏览器打开 ",(0,s.jsx)(n.code,{children:"report.html"})," 即可查看本次测试的通过率、失败用例和日志索引。"]}),"\n",(0,s.jsxs)(n.h2,{id:"6-运行完整客户端验证",children:["6. 运行完整客户端验证",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#6-运行完整客户端验证",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"如果要一次运行 4 个客户端,请使用带 Docker socket 的启动方式:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'mkdir -p results\n\ndocker run --rm --net host \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -v /tmp:/tmp \\\n  -v "$(pwd)/results:/work/results" \\\n  registry.ap-southeast-1.aliyuncs.com/montplex/engula-client-compat:latest \\\n  proof test client \\\n    --results-dir /work/results \\\n    --version engula-latest\n'})}),"\n",(0,s.jsx)(n.p,{children:"这条命令会按镜像内置顺序运行 Jedis、redis-py、go-redis 和 node-redis。"}),"\n",(0,s.jsx)(n.p,{children:"作为参考,在 M2 机器上完整运行一次约 38 分钟;实际耗时会受网络、辅助镜像缓存和 Docker 资源限制影响。"}),"\n",(0,s.jsx)(n.p,{children:"参数说明:"}),"\n",(0,s.jsxs)(n.table,{children:["\n",(0,s.jsxs)(n.thead,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.th,{children:"参数"}),"\n",(0,s.jsx)(n.th,{children:"作用"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.tbody,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"--net host"})}),"\n",(0,s.jsx)(n.td,{children:"让测试容器与它启动的辅助容器网络互通"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/var/run/docker.sock"})}),"\n",(0,s.jsx)(n.td,{children:"允许测试容器调用宿主机 Docker daemon"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/tmp:/tmp"})}
1),"\n",(0,s.jsx)(n.td,{children:"让辅助容器能访问测试过程中生成的临时配置"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/work/results"})}),"\n",(0,s.jsx)(n.td,{children:"容器内报告输出目录"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["如果您只运行 go-redis 示例,不需要 ",(0,s.jsx)(n.code,{children:"--net host"}),"、Docker socket 和 ",(0,s.jsx)(n.code,{children:"/tmp"})," 绑定。"]}),"\n",(0,s.jsxs)(n.h2,{id:"7-查看结果",children:["7. 查看结果",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#7-查看结果",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"完整运行后,结果目录类似:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"results/\n├── client-2.1-jedis-logs/20260519T100000/\n│   ├── main.log\n│   ├── report.json\n│   └── report.html\n├── client-2.2-redis-py-logs/20260519T100500/\n│   ├── main.log\n│   ├── report.json\n│   └── report.html\n├── client-2.3-go-redis-logs/20260519T101200/\n│   ├── main.log\n│   ├── report.json\n│   └── report.html\n├── client-2.4-node-redis-logs/20260519T102000/\n│   ├── main.log\n│   ├── report.json\n│   └── report.html\n└── engula-latest/\n    └── 20260519T103000/\n        ├── client.json\n        ├── report.json\n        └── index.html\n"})}),"\n",(0,s.jsx)(n.p,{children:"常用文件:"}),"\n",(0,s.jsxs)(n.table,{children:["\n",(0,s.jsxs)(n.thead,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.th,{children:"文件"}),"\n",(0,s.jsx)(n.th,{children:"用途"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.tbody,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"main.log"})}),"\n",(0,s.jsx)(n.td,{children:"单个客户端测试的完整运行日志"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"report.html"})}),"\n",(0,s.jsx)(n.td,{children:"单个客户端测试的 HTML 报告"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"client.json"})}),"\n",(0,s.jsx)(n.td,{children:"客户端套件汇总数据"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"index.html"})}),"\n",(0,s.jsx)(n.td,{children:"本轮客户端验证的汇总页"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"报告是静态 HTML,不依赖服务端。可以直接在浏览器打开,也可以作为 PoC 或验收材料归档。"}),"\n",(0,s.jsxs)(n.h2,{id:"8-如何解读报告",children:["8. 如何解读报告",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#8-如何解读报告",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"每个客户端报告会展示这些核心字段:"}),"\n",(0,s.jsxs)(n.table,{children:["\n",(0,s.jsxs)(n.thead,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.th,{children:"字段"}),"\n",(0,s.jsx)(n.th,{children:"含义"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.tbody,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Pass"})}),"\n",(0,s.jsx)(n.td,{children:"Engula 上通过的测试用例数"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Fail"})}),"\n",(0,s.jsx)(n.td,{children:"Engula 上失败的测试用例数"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Skip"})}),"\n",(0,s.jsx)(n.td,{children:"客户端测试集自身跳过的用例数"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Pass Rate"})}),"\n",(0,s.jsx)(n.td,{children:"Engula 的通过率"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Baseline"})}),"\n",(0,s.jsx)(n.td,{children:"同一测试集在 Redis 7.2 上的通过率"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Delta"})}),"\n",(0,s.jsx)(n.td,{children:"Engula 通过率与 Redis 基线通过率的差值"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"建议重点看三类信息:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Redis 基线是否也有失败。如果 Redis 基线失败,优先排查客户端测试环境。"}),"\n",(0,s.jsx)(n.li,{children:"Engula 独有失败用例。它们更可能代表协议、命令语义或测试假设差异。"}),"\n",(0,s.jsx)(n.li,{children:"失败用例是否来自测试框架的内部假设,例如进程路径、临时目录或辅助容器启动方式。"}),"\n"]}),"\n",(0,s.jsxs)(n.h2,{id:"9-常见问题",children:["9. 常见问题",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#9-常见问题",children:"#"})]}),"\n",(0,s.jsxs)(n.h3,{id:"是否需要先手动启动-redis-或-engula",children:["是否需要先手动启动 Redis 或 Engula?",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#是否需要先手动启动-redis-或-engula",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"不需要。工具会自动启动并管理 Redis 与 Engula 进程,测试结束后自动清理。"}),"\n",(0,s.jsxs)(n.h3,{id:"为什么有些客户端需要-docker-socket",children:["为什么有些客户端需要 Docker socket?",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#为什么有些客户端需要-docker-socket",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["部分客户端官方测试集会在测试过程中启动辅助容器,例如测试集群、代理、Sentinel 或 TLS 场景。测试容器需要通过宿主机 Docker daemon 启动这些辅助容器,因此要挂载 ",(0,s.jsx)(n.code,{children:"/var/run/docker.sock"}),"。"]}),"\n",(0,s.jsxs)(n.h3,{id:"为什么要挂载-tmptmp",children:["为什么要挂载 ",(0,s.jsx)(n.code,{children:"/tmp:/tmp"}),"?",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#为什么要挂载-tmptmp",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["部分测试会在 ",(0,s.jsx)(n.code,{children:"/tmp"})," 下生成临时配置,再把这些配置挂给辅助容器。挂载 ",(0,s.jsx)(n.code,{children:"/tmp:/tmp"})," 可以保证测试容器和宿主机 Docker daemon 看到同一条临时路径。"]}
1),"\n",(0,s.jsxs)(n.h3,{id:"首次运行较慢如何处理",children:["首次运行较慢如何处理?",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#首次运行较慢如何处理",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"首次运行可能需要拉取辅助测试镜像。建议先确认宿主机 Docker 可以正常拉取镜像,再运行完整客户端验证。只想快速确认工具链是否可用时,可以先跑 go-redis 示例。"}),"\n",(0,s.jsxs)(n.h3,{id:"这个工具和-codeproof-是什么关系",children:["这个工具和 CodeProof 是什么关系?",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#这个工具和-codeproof-是什么关系",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Engula CodeProof 是完整验证套件,覆盖兼容性、客户端、性能、稳定性、迁移、平台与高可用。ClientCompat 只保留其中的客户端验证能力,镜像和文档都更聚焦,适合单独验证客户端生态。"})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,r.ah)(),e.components);return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(i,{...e})}):i(e)}let c=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["zh%2Fdocs%2Ftools%2Fclientcompat.md"]={toc:[{text:"1. 这个工具验证什么",id:"1-这个工具验证什么",depth:2},{text:"2. 验证原理",id:"2-验证原理",depth:2},{text:"3. 运行前准备",id:"3-运行前准备",depth:2},{text:"4. 拉取镜像",id:"4-拉取镜像",depth:2},{text:"5. 快速开始:先跑 go-redis",id:"5-快速开始先跑-go-redis",depth:2},{text:"6. 运行完整客户端验证",id:"6-运行完整客户端验证",depth:2},{text:"7. 查看结果",id:"7-查看结果",depth:2},{text:"8. 如何解读报告",id:"8-如何解读报告",depth:2},{text:"9. 常见问题",id:"9-常见问题",depth:2},{text:"是否需要先手动启动 Redis 或 Engula?",id:"是否需要先手动启动-redis-或-engula",depth:3},{text:"为什么有些客户端需要 Docker socket?",id:"为什么有些客户端需要-docker-socket",depth:3},{text:"为什么要挂载 `/tmp:/tmp`?",id:"为什么要挂载-tmptmp",depth:3},{text:"首次运行较慢如何处理?",id:"首次运行较慢如何处理",depth:3},{text:"这个工具和 CodeProof 是什么关系?",id:"这个工具和-codeproof-是什么关系",depth:3}],title:"Engula ClientCompat(客户端兼容性测试工具)",headingTitle:"Engula ClientCompat(客户端兼容性测试工具)",frontmatter:{}}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.