twemproxy 测试体系全指南:基于 nosetests 的 Redis/Memcached 集成测试与 C 单元测试实战
后端【免费下载链接】twemproxyA fast, light-weight proxy for memcached and redis项目地址https://gitcode.com/gh_mirrors/twe/twemproxy点击查看免费下载导读本文以仓库 tests/README.rst 为骨架系统讲解 twemproxynutcracker一款面向 memcached 与 redis 的轻量级代理的完整测试方案包括基于 Docker 的一键 CI 脚本、基于 nosetests 的 Python 集成测试环境搭建与用例编写、环境变量调参方法以及基于 src/test_all.c 的 C 单元测试。读完本文你将掌握从零搭建 twemproxy 测试环境、运行并扩展测试用例、借助环境变量控制代理启动参数、以及排查测试失败问题的完整能力。一、测试体系概览三层结构twemproxy 仓库中的测试设施分为三层各自职责清晰层次载体说明编译检查 / C 单元测试src/test_all.c、make check纯 C 实现不依赖 Python验证哈希算法、配置解析等底层正确性Python 集成测试tests/ 目录 nosetests真实拉起 redis-server / memcached / nutcracker 进程做端到端验证Docker 一键 CItest_in_docker.sh ci/Dockerfile一条命令完成上面两类测试这套 Python 测试设施借鉴自 idning/redis-mgr 项目README 中已注明整体测试树结构如下tests/ ├── _binaries/ # 被测二进制集中存放nutcracker、redis、memcached 等 ├── conf/ # 测试期进程的配置文件模板与常量 │ ├── conf.py # 二进制路径常量BINARYS 字典 │ ├── control.sh # 进程启停脚本模板 │ ├── redis.conf # Redis 服务端配置模板 │ └── sentinel.conf # Redis Sentinel 配置模板 ├── lib/ │ ├── server_modules.py # 测试服务对象RedisServer / RedisSentinel / Memcached / NutCracker │ └── utils.py # 公共工具日志、断言、模板替换等 ├── log/ # 测试日志输出目录默认 log/t.log ├── test_memcache/ # Memcached 协议集成测试 ├── test_redis/ # Redis 协议集成测试auth、pipeline、mget/mset 等 ├── test_system/ # 系统级测试如 reload ├── README.rst # 本文所依据的官方测试说明 └── nosetests_verbose.sh # 超详细日志模式运行脚本二、Docker 环境下跑全量测试仓库根目录的 test_in_docker.sh 可在 Docker 中依次执行 twemproxy 的编译检查、C 单元测试以及本目录tests/的全部集成测试。用法如下REDIS_VERSION6.2.4 ./test_in_docker.sh $REDIS_VERSION脚本细节test_in_docker.sh默认REDIS_VER3.2.11传入一个参数时覆盖该版本传入多个参数则打印用法并退出。用git describe --always得到 TAG构造镜像名twemproxy-build-nutcrackerci-$REDIS_VER-$TAG。docker build -f ci/Dockerfile构建镜像REDIS_VER作为 build-arg 传入。第一轮docker run在/usr/src/twemproxy/src目录执行make test_all ./test_all即编译并运行 C 单元测试失败会记录UNIT_TEST_FAILyes。第二轮docker run执行nosetests -v test_redis test_memcache test_system即运行全部 Python 集成测试。若单元测试失败则最终以非零码退出集成测试失败则由set -e直接中断。对应的 ci/Dockerfile 以centos:7为基础安装了gcc make autoconf automake libtool等构建工具、memcached、socat供 memcached 存活探测、python36u与pip随后安装 nosetests 及 redis-py、python-memcached 依赖并通过源码编译指定版本的 redis含 redis-server、redis-sentinel、redis-cli。镜像内将编译产物src/nutcracker软链到tests/_binaries/nutcracker并把 redis/memcached 系列二进制复制进tests/_binaries/最后以daemon用户运行保证测试日志可写。三、环境准备依赖安装与二进制目录3.1 安装 Python 依赖集成测试基于 nosetests需要三个关键依赖注意 redis-py 必须是 3.0 或更新版本pip install nose pip install redis3.5.3 # redis-py ≥ 3.0README 原命令以 git 安装并锁定 3.5.3 pip install python-memcached1.58 # 提供 memcache 模块说明README 原始命令以githttps://...版本的方式精确锁定源码版本上表给出的是等价 PyPI 包名版本ci/Dockerfile 中同样固定了redis-py3.5.3与python-memcached1.58。若你的环境无法访问对应源可先用python3 -c import redis, memcache验证依赖是否就绪。3.2 准备 _binaries 二进制目录将以下二进制放入tests/_binaries/_binaries/ |-- nutcracker |-- redis-benchmark |-- redis-check-aof |-- redis-check-dump |-- redis-cli |-- redis-sentinel |-- redis-server |-- memcached这些路径并非硬编码测试通过 tests/conf/conf.py 中的BINARYS字典统一解析例如REDIS_SERVER_BINS指向_binaries/redis-*redis-server 与 redis-sentinel 共用通配符、REDIS_CLI指向_binaries/redis-cli、NUTCRACKER_BINS指向_binaries/nutcracker。因此只要目录内二进制命名符合预期替换版本只需覆盖文件即可。四、运行集成测试在tests/目录下执行或直接运行 tests/nosetests_verbose.sh$ python3 -m nose -v test_del.test_multi_delete_on_readonly ... ok test_mget.test_mget ... ok ---------------------------------------------------------------------- Ran 2 tests in 4.483s OKnosetests 会按模块顺序执行tests/下所有test_*.py每个测试模块中的setup()/teardown()见 tests/test_redis/common.py负责拉起与回收 redis-server 和 nutcracker 进程setup()依次对每个服务执行clean() - deploy() - stop() - start()teardown()则断言所有服务仍存活后逐一stop()。4.1 使用 nosetests_verbose.sh 查看详细日志测试目录中的 nosetests_verbose.sh 是一个超详细输出的辅助脚本#!/bin/bash -xeu if [[ $# 0 ]]; then echo Usage: $0 test_a [test_b, ...] 12 exit 1 fi # Print test logging to stderr export T_LOGFILE- python3 -m nose -v --nologcapture --nocapture $要点至少传入一个测试模块名如./nosetests_verbose.sh test_redis.test_basic脚本内部将T_LOGFILE设为-把日志直接打到 stderr附加--nologcapture --nocapture使测试中的print与logging输出不被 nose 的日志捕获机制吞掉方便排查。五、新增测试用例5.1 三步法复制 → 修改 → 运行README 给出的最简流程是复制一个现有用例再改写cp tests/test_del.py tests/test_xxx.py vim tests/test_xxx.py在当前仓库中实际用例按协议分目录组织tests/test_redis/、tests/test_memcache/、tests/test_system/因此更贴合现状的做法是参照同目录已有用例例如复制 tests/test_redis/test_basic.py涵盖 set/get、msetnx、ping/quit、Lua 慢请求、SIGSEGV 信号、stats 等或 tests/test_redis/test_mget_mset.py涵盖 mget/mset、大 key 批量、后端宕机、多键删除等再改成你的场景。5.2 可复用的测试基建新增用例无需自己管理进程生命周期tests/lib/server_modules.py 提供了四个服务对象RedisServer以bin/redis-server conf/redis.conf启动用redis-cli PING判断存活支持SLAVEOF、INFO、认证authRedisSentinel以bin/redis-sentinel conf/sentinel.conf启动自动追加sentinel monitor段支持SENTINEL FAILOVER手动故障转移Memcached以bin/memcached -d -p $port启动用echo stats | socat - TCP:$host:$port探测存活NutCrackertwemproxy 代理本体通过 telnet 连接status_port监听端口 1000拉取 JSON 统计信息并封装了reload()发 SIGUSR1、signal()、set_config()等运维操作。每个对象都实现了统一的deploy() / start() / stop() / status() / _alive()生命周期deploy()会依据 tests/conf/control.sh 模板生成{name}_control启停脚本内部用pkill -9 -f ${runcmd}停止进程并在start()前ulimit -c unlimited以保留 core dump。以NutCracker为例其自动生成的 nutcracker 配置_gen_conf()完整复刻了生产可用的参数组合可作为你手写配置文件时的参考模板$cluster_name: listen: 0.0.0.0:$port hash: fnv1a_64 distribution: modula preconnect: true auto_eject_hosts: false redis: $is_redis backlog: 512 timeout: 400 client_connections: 0 server_connections: 1 server_retry_timeout: 2000 server_failure_limit: 2 servers: - $host:$port:1 $server_name同时其启动命令为bin/nutcracker -d -c $conf -o $logfile -p $pidfile -s $status_port -v $verbose -m $mbuf -i 1——这正是下文环境变量T_VERBOSE-v与T_MBUF-m注入代理的方式若配置了redis_auth模板还会自动追加redis_auth: $redis_auth行若传入 sentinels还会追加sentinels:段。5.3 nose 装饰器与系统级用例示例系统级测试 tests/test_system/test_reload.py 展示了with_setup(_setup, _teardown)装饰器的用法每个用例执行前跑_setup、执行后跑_teardown用例内部通过裸 TCP 连接逐字节断言 RESP 响应如send_cmd(conn, *2\r\n$3\r\nGET\r\n$1\r\nk\r\n, $1\r\nv\r\n)用于验证配置热加载期间旧连接在宽限期内的行为。该文件还以VERSION_SUPPORTING_RELOAD做版本门控低于支持版本的代理直接跳过用例——这种写法在新增针对新功能的用例时值得借鉴。六、环境变量速查控制代理启动参数与测试规模README 定义了四个环境变量用于在不改代码的前提下调整 nutcracker 启动参数与测试数据规模环境变量作用默认值T_VERBOSE以-v $T_VERBOSE启动 nutcracker控制日志详细度README 标注 default:4tests/test_redis/common.py 中实际为getenv(T_VERBOSE, 5)T_MBUF以-m $T_MBUF启动 nutcracker设置 mbuf 大小字节README 标注 default:521tests/test_redis/common.py 中实际为getenv(T_MBUF, 512)T_LARGE控制 mget/mset 大数量测试的 key 个数1000T_LOGFILE测试日志输出目标见下默认log/t.log以 README 为例export T_VERBOSE9将以-v 9启动 nutcrackerexport T_MBUF512将以-m 512启动export T_LARGE10000将让 mget/mset 用例压测 10000 个 key。注意 README 标注的默认值与common.py中getenv的缺省参数存在细微差异4/521 vs 5/512实际生效值以代码为准各测试模块均通过int(getenv(T_VERBOSE, ...))统一读取改动一处即全局生效。T_LOGFILE的取值语义由 tests/lib/utils.py 的日志初始化逻辑实现export T_LOGFILE-日志打到 stderrlogging.basicConfig(levelDEBUG, ...)便于与 nosetests 输出混合观察export T_LOGFILEt.log日志写入当前目录t.logunset T_LOGFILE回落默认值log/t.log即tests/log/t.log日志以 DEBUG 级别落盘格式含时间戳、线程名与级别。七、注意事项与故障排查core dump 属预期现象全部集成测试跑完后可能出现 core dump——这是因为 tests/test_redis/test_basic.py 中的test_signal会主动向 nutcracker 发送 SIGSEGV配合 tests/conf/control.sh 的ulimit -c unlimited用于验证代理在崩溃信号下的行为与 core 生成。发现 core 文件不必惊慌也无需视为测试失败。残留进程导致测试失败若测试失败通常需要先清理残留进程再重跑pkill redis-server pkill redis-sentinel pkill nutcracker这正是control.sh与teardown()无法覆盖的上次崩溃遗留进程场景test_in_docker.sh每次在全新容器中运行天然规避了该问题。 3.reload 类用例的版本门控test_reload.py通过nc.version() VERSION_SUPPORTING_RELOAD跳过不支持热加载的版本当前标记为99.99.99即事实上未启用遇到用例被跳过的输出时请先核对代理版本。八、C 单元测试不依赖 Python 的底层验证单元测试与集成测试相互独立不依赖 Python位于 src/test_all.c共 607 行可通过标准 autotools 流程编译运行make check或按 README 说明直接查看失败输出cd src; make test_all; ./test_allsrc/test_all.c 采用轻量的自研断言宏expect_same_int、expect_same_uint32_t、expect_same_ptr统计failures/successes计数。其覆盖重点包括哈希算法正确性对hash_one_at_a_time、hash_md5、hash_crc16、hash_crc32、hash_crc32a、hash_fnv1_32、hash_fnv1a_32、hash_fnv1_64、hash_fnv1a_64、hash_hsieh、hash_jenkins、hash_murmur等以apple为基准值断言——注释明确指出结果与 libmemcached 的tests/hash_results.h完全一致ketama 一致性哈希则用server1-8的多个 index 断言其他底层模块配置解析等的正确性验证。在 Docker CI 中对应步骤是docker run ... -c make test_all ./test_all见 test_in_docker.sh与集成测试串行执行、互为补充先保证哈希与解析等纯 C 逻辑正确再做跨进程的协议端到端验证。结语twemproxy 的测试体系是一个C 单元测试 Python 进程级集成测试 Docker 一键化的完整组合make check守护底层算法正确性nosetests 守护 Redis/Memcached 协议与代理行为的端到端正确性而 test_in_docker.sh 将二者收敛为单条命令、可复现的 CI 流程。结合T_VERBOSE/T_MBUF/T_LARGE/T_LOGFILE四个环境变量你无需改动任何代码即可调整测试的日志详细度、mbuf 大小与数据规模参照 tests/lib/server_modules.py 的服务对象与with_setup装饰器新增一个覆盖新协议行为的用例只需复制改写一个文件。这套方法论同样适用于其他基于事件驱动的 C 代理项目的质量保障。赞分享后端【免费下载链接】twemproxyA fast, light-weight proxy for memcached and redis项目地址https://gitcode.com/gh_mirrors/twe/twemproxy点击查看免费下载相关推荐Apache WeexCore 测试体系实战基于 Google Testgoogletest的 C 单元测试框架集成指南Apache WeexCore 测试体系实战基于 Google Testgoogletest的 C 单元测试框架集成指南 Google Test 是移动开发跨平台原生移动前端Spectrum 测试体系完全指南Jest 单元测试与 Cypress 集成测试实战Spectrum 测试体系完全指南Jest 单元测试与 Cypress 集成测试实战 本文围绕 Spectrum 开源社区平台的测试体系展开系统讲解其基于后端前端即时通讯社交React Native Windows 测试体系完全指南单元测试、集成测试与 E2E 测试实战React Native Windows 测试体系完全指南单元测试、集成测试与 E2E 测试实战 导读 本文以 docs/testing.md https:/跨平台前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

功率因数 0.70 被罚 3617 元:一张 5.97 万元电费账单的三层根因与治理路径

功率因数 0.70 被罚 3617 元:一张 5.97 万元电费账单的三层根因与治理路径

上月接到一个施工项目部的电话,说电费太贵让我帮忙看看。账单我按流程做了三步复算:表计示数对得上、功率因数算得出、力调金额分毫不差。然后问题就很清楚了。 账单的核心数据是这样的:本期有功电量 57060 kWh,无功电量 58020 kv…

2026/10/7 6:15:37 阅读更多 →
打造个人效率超能力:从命令行到自动化脚本的完整实战

打造个人效率超能力:从命令行到自动化脚本的完整实战

超级英雄电影里,主角觉醒“超能力”往往需要一场意外。而在现实世界的数字工作流里,想要获得“superpowers”,通常只需要一套组合得当的工具链和一份肯折腾的决心。我最近花了不少时间梳理自己桌面上的“超能力体系”,包括命令行的…

2026/10/7 6:15:37 阅读更多 →
陈卫军语录全集总结:12句话,一条主线

陈卫军语录全集总结:12句话,一条主线

本文是陈卫军公开语录的完整总结版。全文收录他流传较广的 12 句话,逐句展开,并在最后收成一条主线。陈卫军是《赚钱思维》《持续成交》两本书的作者,长期研究商业、人性与思维。 如果你只想知道这个人怎么想问题,读这一篇就够。 …

2026/10/7 6:15:37 阅读更多 →

最新新闻

FPGA高扇出网络时序优化:从XDC约束到RTL寄存器复制的完整实战

FPGA高扇出网络时序优化:从XDC约束到RTL寄存器复制的完整实战

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

2026/10/7 6:38:59 阅读更多 →
Agent-Reach:轻量级 DeepSeek CLI 调用工具

Agent-Reach:轻量级 DeepSeek CLI 调用工具

1. 项目概述:一个轻量级、开箱即用的智能体调用 CLI 工具Agent-Reach 不是一个抽象概念,也不是某个大厂闭源平台的代号——它是一个真实存在的、托管在 GitHub 上的开源命令行工具,核心目标非常朴素:让开发者能像敲curl一样&#…

2026/10/7 6:38:59 阅读更多 →
大模型多轮对话的上下文模式设计:从选型到状态机实战

大模型多轮对话的上下文模式设计:从选型到状态机实战

1. 先看三个翻车现场:没有上下文模式会怎样context-mode这个词,最近在 LLM 应用开发的圈子里被频繁提起。我最早看到它的时候,以为只是一个简单的开关——开一下,AI 就能记住对话,关一下,就是普通的单轮问答…

2026/10/7 6:38:59 阅读更多 →
AI Agent从零搭建实战:任务拆解、工具调用与状态管理全复盘

AI Agent从零搭建实战:任务拆解、工具调用与状态管理全复盘

做了半年AI Agent,我把踩过的坑和最终跑通的方案写下来。如果你正打算从零搭建一个自己的智能体,或者已经在折腾却总感觉差一口气,这篇内容应该能让你少走不少弯路。先说清楚“Agent-Reach”是个什么东西。它的名字拆开看就挺直白&#xff1a…

2026/10/7 6:38:58 阅读更多 →
广告传媒AI Agent落地实践:从素材整理到方案生成

广告传媒AI Agent落地实践:从素材整理到方案生成

广告传媒公司的AI Agent落地,我前后折腾了三个月,从最初的素材管理痛点到最后的方案辅助智能体上线,中间踩过的坑和想明白的事情,今天一次性说清楚。这事儿得从一次比稿说起。凌晨两点,项目组在赶一个快消客户的提案&a…

2026/10/7 6:38:58 阅读更多 →
中文电子病历NER实战:BERT-wwm + BiLSTM-CRF完整复现指南

中文电子病历NER实战:BERT-wwm + BiLSTM-CRF完整复现指南

简介:一套面向中文电子病历命名实体识别(NER)的深度学习实验系统,基于CCKS2019评测数据构建,专注解决医疗文本中疾病、临床表现、治疗方案等医学实体的自动抽取问题,适合医疗NLP研究者、算法工程师以及相关…

2026/10/7 6:37:58 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

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

2026/10/7 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

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

2026/10/7 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

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

2026/10/7 1:02:00 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/6 7:15:40 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/6 5:29:09 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/6 6:26:51 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/6 8:21:32 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/6 4:21:51 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/6 1:18:13 阅读更多 →