Page 63 - 《软件学报》2025年第7期
P. 63
2984 软件学报 2025 年第 36 卷第 7 期
标待测系统的一些特征信息来缩小探索空间, 提高测试效率. 因此一些测试工具提供高度可扩展的测试框架, 允许
用户使用特定领域语言 (DSL), 根据用户自己对待测分布式系统的理解, 定义待测系统所要注入的系统故障以及
对应的探索策略.
Jepsen [58] 作为业界广泛使用的分布式系统故障注入测试工具, 以其灵活的框架设计和全面的 API 接口, 赋予
了测试人员高度自定义故障注入策略的能力, 以满足不同分布式系统测试的复杂需求. 通过编写 Clojure 语言的代
码脚本及相应配置文件, 测试工程师可以详细指定欲模拟的故障类型、注入时机、持续时长及其影响范围, 从而
准确模拟出网络分区、节点故障、消息丢失等一系列真实世界中可能遇到的故障场景. 这种方法不仅使测试过程
更加灵活和定制化, 还能够针对特定的系统特性和预期的故障场景进行深入测试, 有效地揭示潜在的系统缺陷和
弱点. Jepsen 的高效测试能力被广泛应用于各类分布式系统, 尤其是分布式数据库的深入测试, 成功揭示了许多关
键的系统代码缺陷.
而考虑到部分系统缺陷是由多种故障组合发生事触发的, 针对多个故障的组合空间输入庞大挑战, Joshi 等
人 [96] 提出了 PreFail, 一个可编程的故障注入工具. PreFail 需要测试人员能够编写特定的故障组合策略, 以缓解
多个故障组合带来的输入空间庞大问题. 为了实现可编程性, PreFail 采用了机制和策略分离的经典原则, 将故障
注入框架解耦为两部分: 故障注入引擎和注入驱动程序. 故障注入引擎负责在被测系统中注入故障, 而注入驱动
程序则根据测试人员指定的策略决定故障注入的位置. PreFail 对引擎和驱动程序进行了抽象描述, 包括故障注
入点、故障执行任务以及测试环境配置等. 测试人员可以使用这些抽象在他们的策略中进行快速建模, 有效应
对多个故障组合的复杂测试需求.
3.1.4.3 反馈引导故障序列
虽然人工定义的模型可以有效缩小探索空间、提高测试效率, 但这种方法通常需要耗费大量人力资源, 且构
建的模型难以在不同系统间迁移应用. 为解决这一问题, 一些分布式系统的故障注入工具引入了自动化探索策略.
它们将每次测试中触发的一系列故障视为故障序列, 并自动生成这些序列作为测试输入. 这些工具在测试过程中
实时收集并分析系统的反馈信息, 根据反馈动态调整故障序列的生成, 以更有效地扩展测试状态空间, 从而发现更
多潜在问题和缺陷.
故障注入工具 FATE [97] 在 2011 年首次引入暴力搜索方法来探索故障序列空间. 传统暴力搜索通过系统地枚
举所有可能的故障组合, 逐步增加故障序列的复杂性. 为优化效率, FATE 将搜索空间分为前缀和后缀两部分: 前
缀是固定的操作步骤, 后缀则是故障注入点和恢复操作的组合, 从而有效减少了组合数量. 此外, FATE 引入了工
作流模型技术, 动态识别关键路径和节点, 优先测试关键故障序列, 最大化测试覆盖率并提升效率. FATE 在 HDFS
和 ZooKeeper 等分布式系统上进行了多重故障测试, 探索了超过 40 000 个故障场景, 发现了 67 个鲁棒性缺陷.
尽管优化后的暴力搜索在分布式系统缺陷发现上取得了一定成果, 但对于需要更长故障路径的深层缺陷, 其
效果有限, 因为生成长路径的故障组合序列消耗大量资源. 为提升测试效率, Gao 等人 [79] 开发了 CrashFuzz, 一款基
于代码覆盖率引导的故障注入工具. CrashFuzz 通过将执行路径上的故障点按顺序排列, 并以二进制方式标记其激
活状态, 形成表示故障序列的二进制字符串. 初始阶段所有故障点均未激活, 生成序列<000…0>并放入种子池. 随
后, 通过变异种子池中的序列生成新的故障序列, 并根据代码覆盖率提升情况选择保留新种子序列. 通过这种启发
式搜索, CrashFuzz 不仅提升了缺陷挖掘效率和代码覆盖率, 还在 HDFS 和 ZooKeeper 等分布式系统中发现了 4 个
新的鲁棒性缺陷.
尽管基于代码覆盖率的反馈机制提升了测试覆盖率, 但在故障注入测试中, 这种方法未必高效, 因为其核心是
检测分布式系统的故障处理逻辑, 而非其他业务逻辑. 仅依赖代码覆盖率可能导致大量与故障处理无关的代码被
探索, 降低了效率. 为解决这一问题, Mallory [77] 测试工具在系统中插入探针, 实时捕捉关键事件信息, 如消息传递
和节点状态变化, 构建 happen-before 图以描述事件间的因果关系. 基于该图, Mallory 识别可能导致系统缺陷的事
件顺序, 并采用 Q-learning 强化学习优化故障输入序列. 成功触发新系统行为的序列获得正向奖励, 反之则获得负
向奖励. 通过迭代, Mallory 逐步识别最可能触发缺陷的故障序列, 提升了测试生成的质量. Chronos [21] 认为在分布
式系统中深层路径的故障处理逻辑, 通常因较少激活而更有可能隐藏缺陷. Chronos 实时计算执行路径上故障点

