← 最新论文
💻 computer science

Cross-Project Flakiness: A Case Study of the OpenStack Ecosystem

本文对 OpenStack 生态系统进行了一项实证研究,揭示跨项目测试的不稳定性影响了其 649 个项目中的 55%,显著增加了审查时间和计算成本,同时挑战了单元测试不受此类广泛不稳定性影响这一假设。

原作者: Tao Xiao, Dong Wang, Shane McIntosh, Hideaki Hata, Yasutaka Kamei

发布于 2026-05-29
📖 1 分钟阅读☕ 轻松阅读

原作者: Tao Xiao, Dong Wang, Shane McIntosh, Hideaki Hata, Yasutaka Kamei

原始论文采用 CC BY 4.0 许可(http://creativecommons.org/licenses/by/4.0/)。 这是对下方论文的AI生成解释。它不是由作者撰写或认可的。如需技术准确性,请参阅原始论文。 阅读完整免责声明

想象一下,你是一支庞大的全球施工队的一员,正在建造一座名为OpenStack的巨型、复杂的“云城”。这座城市并非由一人建成,而是由数千名工人(开发者)在数百个不同的“街区”(项目,如 Cinder、Glance 和 Nova)中协作完成。为了确保城市不会崩塌,每当有人添加一块新砖或更换一根管道时,他们都会运行一系列自动化的“安全检查”(测试)。

理想情况下,这些安全检查应像完美的交通信号灯:绿色表示“通行,变更是安全的”,红色表示“停止,存在问题”。

但有时,交通灯会闪烁。它会无缘无故地变,当你再次检查时又变绿,接着又变。在软件世界中,这被称为"不稳定性"(Flakiness)。它就像一个“情绪化”的测试——即使代码没有任何更改,它也不知道自己是在通过还是失败。

本文是一篇侦探故事,讲述这种“情绪化”行为如何蔓延至整个 OpenStack 城市,而不仅仅局限于某一个街区。

他们发现的两大问题

研究人员发现了这种“情绪化”行为造成麻烦的两种具体方式:

1. “传染性”故障(跨项目不稳定性)
想象一个特定的安全检查(测试),本应验证门锁是否正常工作。在这座城市中,同一个门锁检查被用于Cinder街区、Glance街区和Nova街区。

  • 问题:该门锁检查是“情绪化”的。它在所有三个街区中都会随机失败。
  • 影响:由于这些街区共享这一项测试,单个故障测试会同时阻碍多个地方的进展。研究人员发现,OpenStack 中55% 的街区都受到这些传染性故障的影响。这就像一颗坏苹果烂掉了整桶苹果,但这颗“苹果”实际上是一个被所有人使用的测试。

2. “挑三拣四”的故障(不一致的不稳定性)
现在,想象同一个门锁检查被用于Cinder街区和Nova街区。

  • 问题:在Cinder中,该测试完全可靠(始终为绿色)。但在Nova中,完全相同的测试却“情绪化”(在红色和绿色之间闪烁)。
  • 影响:这令人困惑!这意味着测试本身没有损坏;是Nova中的环境导致了问题。这就像一辆车在你家车道上能完美启动,但每次在朋友家尝试启动时都会熄火。研究人员发现了超过 1,100 个这种“挑三拣四”的故障。

大惊喜:连“单元测试”也“生病”了

通常,开发者将单元测试视为软件世界的“显微镜”。它们在真空中观察代码的微小、孤立部分(如单个函数)。由于它们不与外部世界交互,本应是最稳定、最可预测的测试。

论文的惊人发现
研究人员发现,70% 的这类“显微镜”测试实际上卷入了“传染性”故障。

  • 类比:这就像发现固定你烤面包机的微小、孤立螺丝,竟然是导致整个厨房电路短路的原因。我们曾假设这些小型测试是安全且孤立的,但在一个巨大的生态系统中,它们深度互联,能够将不稳定性传播到各处。

为什么会发生这种情况?(原因)

团队深入日志,试图找出为什么测试在某些地方表现异常,而在其他地方却正常。他们发现了三个主要罪魁祸首:

  1. “竞态条件”(占 89% 的杀手):这是最常见的原因。想象两名工人在完全相同的毫秒内试图抓取同一把工具。有时工人 A 拿到了;有时工人 B 拿到了。如果测试试图获取一个已被其他事物占用的资源(如服务器或文件),它就会失败;如果获取成功,它就通过。这种随机性被称为“竞态条件”。
  2. 配置不匹配:这就像试图用来自一个国家的食谱,搭配另一个国家的食材来烤蛋糕。测试期望特定的设置(如特定版本的库或特定的服务器速度),但环境却不匹配。
  3. 依赖问题:一个街区可能已经更新了他们的“电网”(软件库),而邻近城镇尚未更新。测试在已更新的城镇中运行正常,但在旧的城镇中却失败。

“观望”策略的代价

当测试失败时,OpenStack 的标准反应是:“哦,这一定是个故障。让我们再运行一次(重新检查)并等待。”

  • 代价:研究人员计算出,这种“重新检查并等待”的习惯浪费了1,156 天的计算时间和金钱。
  • 类比:这就像一名交警看到红灯,假设传感器坏了,于是挥手让车辆通过,然后再次检查,再次挥手放行。这浪费了燃料(计算资源),并延误了每个人的通勤(代码审查)。

工人们怎么说?(开发者反馈)

研究人员向实际的建造者(开发者)询问了此事。

  • 挫败感:许多开发者感到无助。他们说:“我是新人,不知道该问谁,所以我只是不断点击‘重新检查’,直到它通过为止。”
  • 现实:他们承认,修复这些问题很困难,因为这需要与多个团队沟通。如果Nova中的测试因Cinder中的问题而失败,Nova的开发者必须等待Cinder团队来修复。
  • 工具缺口:他们提到,虽然存在辅助工具,但这些工具经常失效或被弃用,因为没有人有时间维护它们。他们需要一名专职的“机械师”来维护 CI 系统,而不仅仅是兼职志愿者。

结论

论文总结道,在一个庞大且互联的软件生态系统中,你不能将测试视为孤立的岛屿。

  • 对于开发者:停止仅仅“重新检查”和等待。即使测试失败似乎与你的代码无关,也要调查为什么它会失败。
  • 对于团队负责人:你需要标准化所有街区的测试运行方式。如果一个城镇使用特定工具,所有人都应该使用。你还需要集中跟踪这些故障,以便每个人都知道哪些“螺丝”松动了。
  • 对于未来:我们需要更好的工具来自动告诉我们为什么测试不稳定(例如,“它失败是因为服务器宕机了”,而不仅仅是“它失败了”)。

简而言之,该论文认为,为了保持 OpenStack 城市的顺畅运行,我们必须停止将测试失败视为随机的坏运气,而是将其视为影响整个城市的系统性协调问题。

您所在领域的论文太多了?

获取与您研究关键词匹配的最新论文每日摘要——附技术摘要,使用您的语言。

试用 Digest →