- AI 应用
- 计算机视觉
- 图像处理
【免费下载链接】ComfyUI-Impact-Pack
Custom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more.
本文围绕 tests/RUN_ALL_TESTS.md 展开,完整继承其中的快速运行命令、7 个独立测试脚本及其用例规模、测试基础设施约定与日志位置,并结合仓库源码深入解析每个测试套件背后验证的 HTTP API 端点、惰性加载(on-demand loading)、循环引用防护(100 次迭代上限)与配置引号剥离等实现细节。读完本文,你可以独立完成 Impact Pack 通配符(wildcard)系统的全部回归测试,理解每个套件的通过判定标准,并能将测试脚本适配到自己的 ComfyUI 环境。
一、测试套件总览与运行环境
RUN_ALL_TESTS.md描述的是 ComfyUI-Impact-Pack 的wildcard 系统完整测试套件。套件由 7 个独立的 Bash 测试脚本组成,全部位于 tests/ 目录下,合计86 个测试用例(15+10+20+17+8+5+11),文档声明的预期结果为100% 通过率。
每个测试脚本的运行模式一致:
- 在专属端口上启动一个独立的 ComfyUI 服务(避免测试之间互相干扰);
- 生成一份指向测试通配符样本目录的
impact-pack.ini配置; - 通过 HTTP API 逐条执行测试用例并校验返回文本;
- 结束后自动清理:杀掉测试服务器进程、删除临时配置文件。
1.1 快速运行(Quick Run)
原文档给出的完整运行命令如下(注意原文中cd路径为作者本机环境,实际使用时请替换为你自己的仓库路径):
cd /mnt/teratera/git/ComfyUI/custom_nodes/comfyui-impact-pack/tests bash test_encoding.sh && \ bash test_error_handling.sh && \ bash test_edge_cases.sh && \ bash test_deep_nesting.sh && \ bash test_ondemand_loading.sh && \ bash test_config_quotes.sh && \ bash test_dynamic_prompts_full.sh echo "" echo "==========================================" echo "Test Suite Complete" echo "==========================================" echo "Total: 86 tests across 7 suites" echo ""也可以逐个独立运行:
# UTF-8 Encoding (15 tests) bash test_encoding.sh # Error Handling (10 tests) bash test_error_handling.sh # Edge Cases (20 tests) bash test_edge_cases.sh # Deep Nesting (15 tests) bash test_deep_nesting.sh # On-Demand Loading (8 tests) bash test_ondemand_loading.sh # Config Quotes (5 tests) bash test_config_quotes.sh # Dynamic Prompts Full (11 tests) bash test_dynamic_prompts_full.sh1.2 运行前提
从测试脚本源码可以看到两个必须了解的环境依赖:
脚本内
COMFYUI_DIR为硬编码路径。以 tests/test_encoding.sh 为例:PORT=8198 COMFYUI_DIR="/mnt/teratera/git/ComfyUI" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" IMPACT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" CONFIG_FILE="$IMPACT_DIR/impact-pack.ini" LOG_FILE="/tmp/encoding_test.log"IMPACT_DIR由脚本自身位置自动推导(脚本目录的上一级,即插件根目录),但COMFYUI_DIR写死为/mnt/teratera/git/ComfyUI。在其它环境运行时,需要把每个脚本里的这一行改成本机 ComfyUI 的实际路径,再执行bash run.sh --listen 127.0.0.1 --port $PORT才会指向正确的宿主程序。ComfyUI 服务必须可正常启动。每个脚本都会以
--listen 127.0.0.1 --port $PORT启动服务,并通过curl -s http://127.0.0.1:$PORT/轮询最多 60 秒等待就绪;超时则打印日志尾部并退出。
此外仓库提供了一个辅助工具 tests/restart_test_server.sh:bash restart_test_server.sh [PORT](默认 8188)会先pkill现有python.*main.py进程再重启测试服务器,并输出到/tmp/comfyui_test_${PORT}.log,适合手动调试时快速拉起服务。
二、7 个测试脚本的端口、规模与覆盖点
7 个脚本各占一个端口,从 tests/README.md 与脚本源码可汇总为如下结构(测试数量以脚本实际用例与 tests/README.md 的统计口径为准):
| 测试脚本 | 端口 | 用例数 | 验证目标 |
|---|---|---|---|
| test_encoding.sh | 8198 | 15 | UTF-8 多语言编码支持 |
| test_error_handling.sh | 8197 | 10 | 错误场景的优雅处理 |
| test_edge_cases.sh | 8196 | 20 | 边界条件与特殊字符 |
| test_deep_nesting.sh | 8194 | 17 | 7 层传递式展开、深度无关匹配 |
| test_ondemand_loading.sh | 8193 | 8 | 按需惰性加载与缓存上限 |
| test_config_quotes.sh | 8192 | 5 | 配置文件中路径引号处理 |
| test_dynamic_prompts_full.sh | 8188 | 11 | 动态提示词全功能统计验证 |
2.1 test_encoding.sh(15 个用例,端口 8198)
验证多语言文本在通配符系统中的完整保真:韩文 Hangul、Emoji、中文、阿拉伯文 RTL、数学/货币符号、混合多语言,以及 UTF-8 字符出现在动态提示词、量词(quantifier)、多选(multi-select)语法中的情况。
其判定函数 test_encoding() 通过POST /impact/wildcards发起替换请求,然后检查返回结果中是否包含非 ASCII 字节:
RESULT=$(curl -s -X POST http://127.0.0.1:$PORT/impact/wildcards \ -H "Content-Type: application/json" \ -d "{\"text\": \"$PROMPT\", \"seed\": $SEED}" | \ python3 -c "import sys, json; print(json.load(sys.stdin).get('text','ERROR'))" 2>/dev/null || echo "ERROR") # 结果中包含 [\x80-\xFF] 字节范围则 PASS:UTF-8 字符被保留 if echo "$RESULT" | grep -qP '[\x80-\xFF]'; then echo "Status: PASS - UTF-8 characters preserved"15 个用例中值得关注的提示词样例(摘自脚本):
| 用例 | 提示词 | 考察点 |
|---|---|---|
| 01 | __아름다운색__ | 韩文文件名通配符 |
| 03 | {붉은\|하얀\|노란} __아름다운색__ | 韩文动态提示词 + 通配符组合 |
| 06 | {🌸\|🌺\|🌼\|🌻\|🌷} | Emoji 动态选项 |
| 08 | Price: {\$\|€\|£\|¥\|₩} 100 | 货币符号选项 |
| 12 | 3#__아름다운색__ | 量词语法下的韩文 |
| 13 | {2\$\$, \$\$__아름다운색__\|장미\|벚꽃} | 多选取 2 项 +$$展开通配符 |
| 14 | {5::🌸\|3::장미\|2::花} | 加权选择(weight::option)混合多语言 |
2.2 test_error_handling.sh(10 个用例,端口 8197)
覆盖:不存在的通配符引用、循环引用检测(A→B→A,100 次迭代上限防止死循环)、畸形语法、深嵌套不崩溃、多重循环引用。测试样本的约定记录在 tests/wildcards/samples/README.md:例如test_circular_a.txt与test_circular_b.txt互相引用,期望系统检测环并按上限截断而不是挂起;引用__nonexistent_wildcard__时系统应优雅降级而非崩溃。
2.3 test_edge_cases.sh(20 个用例,端口 8196)
覆盖边界条件:空行/纯空白行过滤、超 1000 字符的超长行、特殊字符原样保留、大小写不敏感匹配、#注释行过滤、模式匹配(__*/name__)、量词(N#__wildcard__)以及复杂语法组合。样本文件约定见 samples README 中对test_edge_empty_lines.txt、test_edge_long_lines.txt、test_edge_special_chars.txt(含正则特殊字符、引号、HTML 转义字符)等的描述。
2.4 test_deep_nesting.sh(17 个用例,端口 8194)
验证传递式通配符展开:test_nesting_level1.txt引用 level2,level2 引用 level3……直到 level7 给出最终选项,即访问__test_nesting_level1__触发 7 层展开,最终结果必须来自 level7。用例还包括各深度(1–7 层)单独访问、混合深度组合、嵌套 + 量词/多选/加权选择,以及深度无关模式匹配__*/name__(匹配任意目录层级下同名的通配符)。
2.5 test_ondemand_loading.sh(8 个用例,端口 8193)
这是与源码中 LazyWildcardLoader 直接对应的套件。该脚本的独特之处在于:
- 每次测试修改
wildcard_cache_limit_mb后重启服务器,验证不同缓存上限下的加载策略:1MB(启用 on-demand)、10MB(渐进加载)、100MB(eager 全量缓存)、0.5MB(激进惰性)、50MB(默认均衡模式)、25MB 边界; - 运行时在
/tmp/ondemand_test_samples动态生成 50 个各含 100 行选项的大样本文件、韩文样本与 3 级嵌套目录样本; - 断言除"返回非 ERROR 文本"外,还会调用
GET /impact/wildcards/list/loaded统计实际已加载进内存的通配符数量:
# 获取已加载通配符数量 LOADED_COUNT=$(curl -s http://127.0.0.1:$PORT/impact/wildcards/list/loaded 2>/dev/null | \ python3 -c "import sys, json; print(len(json.load(sys.stdin).get('data',[])))" 2>/dev/null || echo "0")对应端点在 modules/impact/impact_server.py 中实现,返回体含data(已加载列表)、on_demand_mode(是否处于按需模式)与total_available(可发现的通配符总数)三个字段——从源码结构看,这正是测试"小缓存下只加载被访问过的文件"这一行为的关键观测口。
2.6 test_config_quotes.sh(5 个用例,端口 8192)
验证impact-pack.ini中custom_wildcards路径的引号处理:无引号、双引号、单引号、带空格路径、绝对路径。脚本每轮把不同形态的路径写进配置并重启服务器(见 test_config_format()),通过判据是返回文本既非 ERROR 且不再包含未展开的__残留:
if [ "$RESULT" != "ERROR" ] && [ -n "$RESULT" ] && ! echo "$RESULT" | grep -q "__"; then echo "Status: PASS - Path correctly handled"其实现依据在 modules/impact/config.py:配置加载时执行custom_wildcards_path = default_conf.get('custom_wildcards', '').strip('\'"')剥离首尾引号;若路径不存在则回退到插件内置的custom_wildcards/目录并打印告警。
2.7 test_dynamic_prompts_full.sh(11 个用例,端口 8188)
这是唯一不自行拉起服务器的脚本:它要求端口 8188 上已有 ComfyUI 服务在运行,否则提示手动启动(脚本 tests/test_dynamic_prompts_full.sh):
# Check server if ! curl -s http://127.0.0.1:$PORT/ > /dev/null 2>&1; then echo "Server not running on port $PORT" echo "Start server with: cd /mnt/teratera/git/ComfyUI && bash run.sh --listen 127.0.0.1 --port $PORT" exit 1 fi它同时把全部输出tee到/tmp/dynamic_prompt_full_validation.log。覆盖点分为三组:
- Multiselect(4 个):
N$$语法选取 2 项、3 项、单项、最大项,含分隔符校验; - Weighted Selection(5 个):10:1 权重比、等权、极端偏斜、多级权重、默认混合;
- Basic Selection(2 个):简单随机选择、嵌套选择;
- 每个用例执行100+ 次迭代做统计分布验证,检查重复项检测、选项数量与分隔符正确性。
三、测试基础设施的共性约定
RUN_ALL_TESTS.md的 "Test Summary" 一节对每个套件声明的五项承诺,在脚本源码中一一对应(以 tests/test_encoding.sh 为样本):
| 声明 | 实现 |
|---|---|
| 专属端口启动独立 ComfyUI 服务 | PORT=819x+bash run.sh --listen 127.0.0.1 --port $PORT > $LOG_FILE 2>&1 & |
| 配置测试通配符路径 | 生成impact-pack.ini,写入custom_wildcards = $IMPACT_DIR/tests/wildcards/samples、wildcard_cache_limit_mb = 50、dependency_version = 24、mmdet_skip = True、sam_editor_cpu = False、sam_editor_model = sam_vit_h_4b8939.pth、disable_gpu_opencv = True |
| 运行测试用例 | 封装的test_*()函数逐条curl调用 |
| 校验结果 | 按套件定制:UTF-8 字节检测 / 无__残留检测 / 非 ERROR 检测 / 加载数量统计 |
| 自动清理 | trap cleanup EXIT:pkill -f "python.*main.py.*--port $PORT"并rm -f "$CONFIG_FILE" |
另外两点实操细节:
- 启动前先
pkill同端口残留进程并sleep 2,避免端口占用; - 服务器就绪判定是 60 秒内
curl http://127.0.0.1:$PORT/成功;失败时打印tail -20日志便于定位启动错误。
四、预期结果与日志分析
文档声明全部 86 个测试应通过(100% 通过率)。7 份日志固定写入/tmp/:
| 套件 | 日志文件 |
|---|---|
| Encoding | /tmp/encoding_test.log |
| Error Handling | /tmp/error_handling_test.log |
| Edge Cases | /tmp/edge_cases_test.log |
| Deep Nesting | /tmp/deep_nesting_test.log |
| On-Demand Loading | /tmp/ondemand_test.log |
| Config Quotes | /tmp/config_quotes_test.log |
| Dynamic Prompts Full | /tmp/dynamic_prompt_full_validation.log |
失败时的排查路径:各脚本在 FAIL 分支都会给出提示(如 config quotes 套件会grep -i "custom_wildcards\|wildcard" "$LOG_FILE" | tail -5从服务器日志中提取相关行)。服务器日志记录了 Impact Pack 插件的加载告警(例如 modules/impact/config.py 中路径缺失时的custom_wildcards path not found警告),因此先看/tmp/*_test.log中的 FAIL 详情,再翻服务器日志定位插件侧错误,是标准的排障顺序。
五、测试背后的 API 与源码实现
5.1 测试打到的 HTTP 端点
所有套件统一使用 Impact Pack 在 modules/impact/impact_server.py 注册的三个端点:
POST /impact/wildcards:请求体为{"text": "...", "seed": N},服务端执行impact.wildcards.process(data['text'], data.get('seed', None))后返回{"text": 展开结果}。这是全部 7 个套件的被测主体。传入seed意味着同一种子下结果应可复现——samples README 也将 "Demonstrate deterministic behavior with same seed" 列为预期行为之一。GET /impact/wildcards/list/loaded:返回已加载通配符列表、on_demand_mode标志与total_available总数,被 on-demand 套件用于观测渐进加载。GET /impact/wildcards/refresh:调用impact.wildcards.wildcard_load()重新加载,可用于修改tests/wildcards/samples/下文件后刷新缓存。
5.2 核心展开算法(wildcards.py)
测试验证的行为全部落在 modules/impact/wildcards.py 的process(text, seed)中(实现入口):
种子初始化:
random.seed(seed)与np.random.default_rng(seed)双通道初始化,保证加权选择、多项选取在同一 seed 下确定性可复现——这解释了动态提示词套件能做 100+ 次迭代的统计分布验证。循环引用防护:展开主循环硬编码 replace_depth = 100:
replace_depth = 100 stop_unwrap = False while not stop_unwrap and replace_depth > 1: replace_depth -= 1 # prevent infinite loop每轮先做量词展开(
N#__keyword__用正则 RE_WildCardQuantifier 匹配后重复 keyword N 次),再做replace_options({...}动态提示词)与replace_wildcard(__...__通配符)两个 pass;两类替换都不再发生时stop_unwrap退出。error handling 套件验证的"100 次迭代上限防死循环"正是这一机制。加权与多选:
{weight::option}的权重在前端被解析为normalized_probabilities(实现),多选通过random_gen.choice(..., replace=False)无放回抽样;N$$/N-M$$前缀指定抽取数量,$$后可跟通配符路径展开为选项池。dynamic prompts 套件的统计验证正是针对这段逻辑。深度无关模式匹配:
__*/name__语法在 replace_wildcard 内部 特判——遍历所有 key,凡key == base_name、key 以 /base_name 结尾、key 以 base_name/ 开头或含 /base_name/者,其选项并入同一候选池随机抽取。deep nesting 套件的__*/test_pattern_match__用例即验证此路径。
5.3 On-demand 加载与缓存上限
ondemand 套件的行为依据在 wildcard_load() 的文档与实现:
- 启动时调用 calculate_directory_size() 统计
custom_wildcards目录下.txt/.yaml/.yml文件总大小(支持提前终止以加速判定); - 总大小< 上限:全量缓存模式(full cache),所有数据进内存,
/list/loaded等价于全量列表; - 总大小≥ 上限:on-demand 模式,
scan_wildcard_metadata()只登记"key → 文件路径"元数据(实现),实际数据由 LazyWildcardLoader 代理——它实现了__getitem__/__iter__/__len__/__contains__等 list 接口,首次访问时才带双重检查锁读取文件。这也解释了为什么 0.5MB 激进缓存档位下,list/loaded返回的数量远小于样本总数,而展开结果仍然正确。 - 一个源码中明确标注的限制:YAML 通配符必须预加载,因为其 key 嵌在文件内容里而非文件路径中(TXT 的 key 即相对路径)。
- 文件读取的编码策略与 encoding 套件直接相关:LazyWildcardLoader._load_txt() 先按
ISO-8859-1读取,遇到UnicodeDecodeError再回退UTF-8 + errors="ignore";同时过滤空行与#注释行——edge cases 套件中"注释行过滤、空行忽略"的用例即验证此清洗逻辑。
wildcard_cache_limit_mb的解析同样在 modules/impact/config.py:非法值会打 warning 并回退默认50MB;该配置正是 ondemand 套件每轮改写impact-pack.ini的字段。
六、实操要点与复用建议
路径适配是第一步:7 个脚本中
COMFYUI_DIR="/mnt/teratera/git/ComfyUI"均为硬编码,移植到本地环境时需逐一替换;IMPACT_DIR/CONFIG_FILE均按脚本位置自动推导,无需改动。端口互斥:8188/8192/8193/8194/8196/8197/8198 已被测试套件占用(8188 通常也是 ComfyUI 默认端口),并行跑多套件前先确认端口空闲,或按
RUN_ALL_TESTS.md的&&串行方式顺序执行。配置文件生命周期:每个脚本在插件根目录写入
impact-pack.ini,退出时删除。若测试中途被Ctrl-C打断,trap cleanup EXIT仍会执行清理;手动复测前确认该文件不存在,避免上轮配置(尤其是不同的wildcard_cache_limit_mb)残留。单条用例可脱离脚本复现:samples README 给出了标准的 curl 复现方式,例如验证 7 层嵌套:
curl -X POST http://127.0.0.1:8188/impact/wildcards \ -H "Content-Type: application/json" \ -d '{"text": "__test_nesting_level1__", "seed": 42}'量词、循环引用(
__test_circular_a__)、模式匹配(__*/test_pattern_match__)等场景同理,方便在 CI 之外做单点调试。扩展测试样本:新增通配符测试文件放入
tests/wildcards/samples/后,可通过GET /impact/wildcards/refresh热加载,无需重启服务器(on-demand 模式下新文件也会被scan/动态查找机制发现)。
小结
RUN_ALL_TESTS.md定义的这套 7 脚本、86 用例的回归体系,把 Impact Pack 通配符系统的五个关键质量维度——多语言编码保真、错误优雅降级、边界条件、深层传递展开、缓存受控的按需加载——全部锚定在可观测的 HTTP 行为上:POST /impact/wildcards的展开结果、GET /impact/wildcards/list/loaded的加载量、/tmp/下的服务器日志。结合 modules/impact/wildcards.py 中 100 次迭代防护、LazyWildcardLoader双重检查锁、__*/name__深度无关匹配与 50MB 默认缓存上限等源码实现,可以完整回答"每个测试为什么这样判定"。对于贡献者而言,跑通全部 7 个套件并保持 100% 通过,是修改 wildcard 相关代码后的基本验收动作。
延伸阅读(仓库内文档):tests/README.md(套件细节与状态清单)、tests/wildcards/samples/README.md(测试样本约定与 curl 示例)、docs/wildcards/WILDCARD_SYSTEM_PRD.md、docs/wildcards/WILDCARD_SYSTEM_DESIGN.md、docs/wildcards/WILDCARD_TESTING_GUIDE.md。
- AI 应用
- 计算机视觉
- 图像处理
【免费下载链接】ComfyUI-Impact-Pack
Custom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more.
相关推荐
ComfyUI-Impact-Pack 通配符系统测试套件实战:7 套测试脚本、端口隔离与源码级验证
ComfyUI Impact Pack 通配符系统测试套件实战:7 套测试脚本、端口隔离与源码级验证 本文为 ComfyUI Impact Pack 的 Wil
AI 应用计算机视觉图像处理ComfyUI-Impact-Pack 通配符系统测试指南:7 大测试套件、86 项行为验证与按需加载实测
ComfyUI Impact Pack 通配符系统测试指南:7 大测试套件、86 项行为验证与按需加载实测 本文基于 Wildcard System Testi
AI 应用计算机视觉图像处理RIOT 外设定时器测试应用(tests/periph/timer)深度解析:从运行方法到源码级判定逻辑
RIOT 外设定时器测试应用(tests/periph/timer)深度解析:从运行方法到源码级判定逻辑 本文以 RIOT 仓库中 tests/periph/t
物联网嵌入式操作系统实时系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考