Tomassi D A, Dmeiri N, Wang Y, 等. Bugswarm: 通过挖掘和持续增长的数据集实现可重复的故障和修复 [C]//2019 IEEE/ACM 第 41 届国际软件工程会议 (ICSE). IEEE, 2019: 339-349.
错误检测、定位和修复技术对软件质量保障至关重要,但目前难以评估这些技术的扩展性、适用性和有效性。构建和维护大型、多样化、真实的缺陷和修复数据集通常十分困难且成本高昂。然而,随着持续集成(Continuous Integration,CI)方法的应用,比如 TRAVIS-CI,这些问题有望得到解决。这些 CI 工具具有高度的可配置性,能够在定制容器内运行,从而帮助我们建立更大的缺陷数据集。通过识别并存档失败和成功的测试案例,这些容器可以提供可重复构建和测试的保障。不过,为了发挥这些技术的实际价值,还需要克服一些限制。为此,我们提出了工具 Bugswarm,它可以创建一系列可扩展、多样化的、真实且持续增长的缺陷和修复数据集。Bugswarm 已经为 Java 和 Python 语言收集了 3,091 组失败-成功版本对,并将其封装在完全可重复的容器中。此外,该工具还可以定期运行以检测新的失败-成功对,从而不断扩展数据集。
软件缺陷对社会经济、出行安全和生活质量有重要影响。发现和修复这些缺陷需要耗费大量的时间和资金。通过对现有缺陷及其修复方法的研究,可以提高在新版本中解决问题的效率。一些软件工程领域(如程序分析、测试和自动程序修复)致力于开发工具、模型和方法来寻找并修复缺陷。理想情况下,这些技术应该在真实的最新缺陷数据集上进行评估,以便用户更好地了解其性能。这些数据集应包含失败和成功的版本,具体分为触发程序失效的测试集和修复缺陷的补丁。这样,研究人员可以深入评估缺陷检测、定位和修复技术的有效性。因此,研究进展与包含失败和成功对的高质量数据集密切相关。
对于包含失败和成功对的数据集,有以下几点值得注意的特性:(1)可扩展性:需要足够的数据以支持工具评估的统计意义;(2)多样性:数据应具有足够的变化,涵盖项目规模、成熟度、范围、语言、缺陷严重性等因素;(3)真实性:能够反映实际修复过程中的真实操作;(4)实时性:数据集应不断更新,与语言、平台、库和软件功能的变化保持同步;(5)可复现性:缺陷数据应持久可复现,以支持长期的构建和行为复现。
一些人工汇总的数据集(如西门子测试集、SIR 存储库、Defects4J)提供了软件制品集合,用于支持程序分析和测试技术的受控实验。但这些数据集是人工策划的,规模和多样性有限。而一些小型的学生作业可能无法反映真实的技术表现。尽管这些数据集可能通过手动插入缺陷来生成,但它们依赖于特定版本的库和操作系统,难以保证长期的可复现性。
为了应对这些挑战,我们利用基于云的持续集成(Continuous Integration,CI)技术,特别是 DevOps 和开源软件(OSS)主导的创新,来创建大规模、多样化、真实且可持久复现的缺陷数据集。通过 CI 服务,我们可以自动捕获开源项目中的失败和成功对,并在容器中自动重现这些对。这不仅减少了人工干预的需求,还能提供最新的数据集。
现代开源软件开发中的 CI 服务提供了支持工具和数据的生态系统,有助于 Bugswarm 的创建。本节描述了这一生态系统的关键组成部分,并给出一个示例。
(1)Git 和 GitHub。Git 对现代软件开发至关重要,每个项目都有一个存储库,每次更改都通过提交进行,每个提交都有一个唯一的标识符。GitHub 是一个基于 Web 的 Git 存储库托管服务。
(2)Travis-CI 持续集成。Travis-CI 是与 GitHub 集成的、最流行的基于云的 CI 服务,可以自动构建和测试提交。用户可以通过.travis.yml 文件配置 Travis,并指定测试项目的环境。
(3)Docker。Docker 是一种轻量级虚拟机服务,提供应用程序隔离、不变性和自定义。用户可以将应用程序打包成一个不变的、独立的、持久的 Docker 镜像,并在任何支持的平台上运行。
项目的构建历史记录指所有触发的 Travis-CI 构建。一个构建可能包含多个作业,例如,Python 项目的构建可能包含单独的作业,并使用不同的版本进行测试。
提交对是指两个 Git 提交,每个提交在相同的构建历史中触发了 Travis-CI 构建。标准的提交对包括一个失败的提交和一个成功的修复提交。术语构建和作业对分别指来自项目构建历史的 Travis-CI 构建或作业。
在用户试图持续自动地挖掘 Travis-CI 数据时,工具基础架构旨在解决一些特定的挑战。每个情况的解决方案如下:
(1)提交恢复:需要找到触发时的提交; (2)镜像恢复:原则上 Travis-CI 会创建并保留 Docker 镜像,以重新创建构建和测试事件; (3)运行时恢复:构建特定的项目版本通常需要满足对工具、库和框架的大量软件依赖; (4)日志分析:一旦作业被恢复,Bugswarm 将尝试从日志中确定缺陷的确切性质。
PAIRMINER 从项目的 Git 存储库中提取并建立历史记录,以获取一组失败-成功作业对。PAIRMINER 将 GitHub 块作为输入,并为每个作业的父版本生成一组缺陷传递作业对,并用触发提交信息进行注释。PAIRMINER 算法包括(1)将项目的构建历史线性化;(2)提取失败-成功构建对;(3)将提交分配给每个对;(4)从每个失败-成功构建对中提取作业对。
PAIRMINER 鉴定的相关对必须组装到可复现的容器中。对于管道中的每个作业,PAIRFILTER 检查是否可以获得这些必需信息。如果 PAIRMINER 认为项目形状可恢复,PAIRFILTER 将检索作业的原始 Travis-CI 日志并提取有关执行环境的信息。
REPRODUCER 首先需要检查每个作业是否可以持久复现。这需要以下步骤:(1)生成作业脚本,travis-build 从 .travis.yml 文件生成 Shell 脚本,以运行 Travis-CI 作业;(2)匹配环境,为了匹配原始作业的运行时环境,REPRODUCER 从 Travis-CI 公开可用的 Docker 镜像集中选择;(3)还原项目,对于项目历史记录还原,REPRODUCER 提交克隆项目并重置其形状;(4)复现作业,REPRODUCER 创建一个新的 Docker 镜像,运行生成的作业脚本,并将生成的输入流保存在日志文件中。
ANALYZER 解析 Travis-CI 构建日志以了解构建状态以及回归测试用例集的运行结果。如果测试失败,ANALYZER 还将检索其名称。构建日志的格式因具体的构建系统和测试框架而异,因此解析器必须与每个构建和测试框架对应。对于 Java,我们支持最流行的构建系统 Maven、Gradle 和 Ant 以及测试框架 JUnit 和 TestNG。对于 Python,我们支持最受欢迎的测试框架 unittest、unittest2、nose 和 pytest。
本文介绍了 Bugswarm,这是一种利用 CI 来挖掘和复现实现开发中真实的失败-成功对的方法。通过 Bugswarm,我们创建了一个大规模、多样化、真实且可持久复现的缺陷数据集。Bugswarm 包含了 3,091 组 Java 和 Python 的失败-成功版本对,据我们所知,这是目前最大且持续增长的缺陷数据集。