如何运行 gem5 单元测试?

Cir*_*lli 2 gem5

Gem5 在源代码树中有几个测试,并且有一些文档位于:http : //www.gem5.org/Regression_Tests但这些文档不是很清楚。

有哪些测试以及如何运行它们?

Cir*_*lli 5

单元测试与回归测试

gem5有两种测试:

  • 回归:在整个模拟器上运行一些工作负载(完整系统或系统调用仿真)
  • 单元:只测试模拟器的一小部分,而不运行整个模拟器二进制文件

我们将在这个答案中涵盖两者。

回归测试

2019年回归测试

2019 年添加了一个新的测试框架,记录在:https : //gem5.googlesource.com/public/gem5/+/master/TESTING.md

在发送补丁之前,您基本上要运行:

cd tests
./main.py run -j `nproc` -t `nproc`
Run Code Online (Sandbox Code Playgroud)

这会:

  • 为积极支持的 ISA 构建 gem5:X86、ARM、RISCV 与nproc线程由于j
  • 从 gem5.org 下载运行测试所需的二进制文件,例如http://www.gem5.org/dist/current/arm/另见:http : //gem5.org/Download目前无法下载或源树,如果git worktree周围有一堆s,那就不好了。
  • nproc由于 的线程运行快速测试-t,这应该会在几分钟内完成

您可以实现与上一个命令相同的效果,而无需cdtests/目录作为参数传递:

./main.py run -j `nproc` -t `nproc` tests
Run Code Online (Sandbox Code Playgroud)

但我希望两者都不是必需的:https : //gem5.atlassian.net/browse/GEM5-397

这正是自动化上游预提交测试正在运行的内容,可以从tests/jenkins/presubmit.sh 中看出

标准输出包含以下形式的清晰结果输出:

Test: cpu_test_DerivO3CPU_FloatMM-ARM-opt Passed                    
Test: cpu_test_DerivO3CPU_FloatMM-ARM-opt-MatchStdout Passed
Test: realview-simple-atomic-ARM-opt Failed                  
Test: realview-simple-atomic-dual-ARM-opt Failed
Run Code Online (Sandbox Code Playgroud)

有关每个测试的详细信息可以在以下位置找到:

tests/.testing-results/
Run Code Online (Sandbox Code Playgroud)

例如:

.testing-results/SuiteUID:tests-gem5-fs-linux-arm-test.py:realview-simple-atomic-ARM-opt/TestUID:tests-gem5-fs-linux-arm-test.py:realview-simple-atomic-ARM-opt:realview-simple-atomic-ARM-opt/
Run Code Online (Sandbox Code Playgroud)

虽然我们只看到一些最小的 stdout/stderr 输出,但它们甚至没有显示 gem5 stdout。然而,stderr 文件确实包含完整的命令:

CalledProcessError: Command '/path/to/gem5/build/ARM/gem5.opt -d /tmp/gem5outJtSLQ9 -re '/path/to/gem5/tests/gem5/fs/linux/arm/run.py /path/to/gem5/master/tests/configs/realview-simple-atomic.py' returned non-zero exit status 1
Run Code Online (Sandbox Code Playgroud)

所以你可以删除-d-re重新运行它以查看发生了什么,这可能很慢,但我没有看到另一种方式。

如果一个测试永远卡在运行中,你可以使用 Linux 的ps aux命令找到它的原始命令,因为每次运行都会分叉进程。

请求更容易直接从标准输出获取原始运行命令:https : //gem5.atlassian.net/browse/GEM5-627

请求正确保存标准输出:https : //gem5.atlassian.net/browse/GEM5-608

要进一步对单个 ISA 进行压力测试,您可以使用以下命令为一个 ISA 运行所有测试:

cd tests
./main.py run -j `nproc` -t `nproc` --isa ARM --length long --length quick
Run Code Online (Sandbox Code Playgroud)

每个测试都归类为longquick,并同时使用两者--length运行。

long测试通常与默认测试非常相似quick,但使用更详细因此速度较慢的模型,例如

  • tests/quick/se/10.mcf/ref/arm/linux/simple-atomic/ 使用更快的原子 CPU 很快
  • tests/long/se/10.mcf/ref/arm/linux/minor-timing/ 很长,次要 CPU 较慢

在 gem5 69930afa9b63c25baab86ff5fbe632fc02ce5369 中测试。

2019 年回归测试仅运行一项测试

列出所有可用的测试:

./main.py list --length long --length quick
Run Code Online (Sandbox Code Playgroud)

这显示了套件和测试,例如:

SuiteUID:tests/gem5/cpu_tests/test.py:cpu_test_AtomicSimpleCPU_Bubblesort-ARM-opt

TestUID:tests/gem5/cpu_tests/test.py:cpu_test_AtomicSimpleCPU_Bubblesort-ARM-opt:cpu_test_AtomicSimpleCPU_Bubblesort-ARM-opt
TestUID:tests/gem5/cpu_tests/test.py:cpu_test_AtomicSimpleCPU_Bubblesort-ARM-opt:cpu_test_AtomicSimpleCPU_Bubblesort-ARM-opt-MatchStdout
Run Code Online (Sandbox Code Playgroud)

现在你可以只运行一个测试--uid

./main.py run -j `nproc` -t `nproc` --isa ARM --uid SuiteUID:tests/gem5/cpu_tests/test.py:cpu_test_AtomicSimpleCPU_FloatMM-ARM
Run Code Online (Sandbox Code Playgroud)

有点混乱,--uid必须指向 a SuiteUID,而不是TestUID

然后,当您运行测试时,其中任何一个测试失败,而您只想运行失败的测试,测试失败会显示如下一行:

Test: cpu_test_DerivO3CPU_FloatMM-ARM-opt Passed
Run Code Online (Sandbox Code Playgroud)

并且只运行测试的唯一方法是grep在输出中的那个字符串,./main.py list因为cpu_test_DerivO3CPU_FloatMM-ARM-opt它不是一个完整的测试 ID,这很烦人。

2019 年树外回归测试

默认情况下,tests/main.py将构建gem5/build放在源树内部。可以通过--build-dir以下方式测试树外构建:

./main.py run -j `nproc` -t `nproc` --isa ARM --length quick --build-dir path/to/my/build
Run Code Online (Sandbox Code Playgroud)

例如,它将构建放入path/to/my/build/ARM/gem5.opt

如果您的构建已经完成,也可以使用--skip-build选项保存几秒钟:

./main.py run -j `nproc` -t `nproc` --isa ARM --length quick --build-dir path/to/my/build --skip-build
Run Code Online (Sandbox Code Playgroud)

但是请注意,这--skip-build也会跳过测试二进制文件的下载。TODO 补丁。

2019 回归测试自定义二进制下载目录

由于https://gem5-review.googlesource.com/c/public/gem5/+/24525您可以使用该--bin-path选项来指定测试二进制文件的下载位置,否则它们只会进入源代码树。

这允许您在一台机器的多个工作树中跨测试重用大型二进制文件,例如磁盘映像,从而节省时间和空间。

2019 年之前的回归测试

这种运行测试的方式已被弃用并将被删除。

测试直接使用scons.

但是由于测试命令有点长,甚至还有一个 in-tree 实用程序为您生成测试命令。

例如,要获取运行 X86 和 ARMquick测试的命令,请运行:

./util/regress -n --builds X86,ARM quick
Run Code Online (Sandbox Code Playgroud)

其他选项除了quicklong或者all两者都做long,并quick在同一时间。

有了-n它只是打印测试命令,没有它,实际上它运行它们。

这输出类似:

scons \
  --ignore-style \
  --no-lto \
  build/X86/gem5.debug \
  build/ARM/gem5.debug \
  build/X86/gem5.fast \
  build/ARM/gem5.fast \
  build/X86/tests/opt/quick/se \
  build/X86/tests/opt/quick/fs \
  build/ARM/tests/opt/quick/se \
  build/ARM/tests/opt/quick/fs 
Run Code Online (Sandbox Code Playgroud)

TODO:为什么它构建 gem5.debug 和 gem5.fast,然后运行/opt/测试?

所以请注意这将如何:

  • 构建 gem5 可执行文件,例如 build/X86/gem5.debug
  • 运行测试,例如 build/X86/tests/opt/quick/fs

或者获取运行所有 archs 的所有测试的命令:

./util/regress -n all
Run Code Online (Sandbox Code Playgroud)

然后,如果您只想运行这些类型的测试之一,例如quickX86测试,您可以复制粘贴scons仅用于该测试的测试:

scons --ignore-style build/X86/tests/opt/quick/se
Run Code Online (Sandbox Code Playgroud)

通过神奇地解析目标路径,使用树外构建运行测试像往常一样工作:How to build gem5 out of tree?

scons --ignore-style /any/path/that/you/want/build/X86/tests/opt/quick/se
Run Code Online (Sandbox Code Playgroud)

或者您可以将--build-dir选项传递给util/regress

./util/regress --build-dir /any/path/that/you/want all
Run Code Online (Sandbox Code Playgroud)

另一方面,启动 Linux 的测试需要一个在M5_PATH.

然而,这会非常慢,而不是您可以在每次提交后运行的东西:您更有可能只想为您感兴趣的 ISA 运行快速测试。

2019 年之前的回归测试:仅运行一项测试

如果您只是将tests源树中的路径附加到测试命令,它会运行给定目录下的所有测试。

例如,我们有:

scons --ignore-style build/X86/tests/opt/quick/se
Run Code Online (Sandbox Code Playgroud)

我们注意到tests源树中存在以下路径:

quick/se/00.hello/ref/x86/linux/simple-atomic/
Run Code Online (Sandbox Code Playgroud)

所以我们通过删除ref来按摩路径以获得最终命令:

scons build/X86/tests/opt/quick/se/00.hello/x86/linux/simple-atomic
Run Code Online (Sandbox Code Playgroud)

2019 年之前的回归测试:找出命令运行的确切 gem5 CLI

当您运行测试时,它们会将 m5out 路径输出到标准输出。

在 m5out 路径中,有一个带有模拟器标准输出的 simout,其中包含使用的完整 gem5 命令行。

例如:

scons --ignore-style build/X86/tests/opt/quick/se
Run Code Online (Sandbox Code Playgroud)

输出:

Running test in /any/path/that/you/want/build/ARM/tests/opt/quick/se/00.hello/arm/linux/simple-atomic.
Run Code Online (Sandbox Code Playgroud)

和文件:

/any/path/that/you/want/build/ARM/tests/opt/quick/se/00.hello/arm/linux/simple-atomic
Run Code Online (Sandbox Code Playgroud)

包含:

command line: /path/to/mybuild/build/ARM/gem5.opt \
  -d /path/to/mybuild/build/ARM/tests/opt/quick/fs/10.linux-boot/arm/linux/realview-simple-atomic \
  --stats-file 'text://stats.txt?desc=False' \
  -re /path/to/mysource/tests/testing/../run.py \
  quick/fs/10.linux-boot/arm/linux/realview-simple-atomic
Run Code Online (Sandbox Code Playgroud)

2019 年之前的回归测试:仅重新运行一项测试

如果您只运行两次测试,例如:

scons build/ARM/tests/opt/quick/fs/10.linux-boot/arm/linux/realview-simple-atomic
scons build/ARM/tests/opt/quick/fs/10.linux-boot/arm/linux/realview-simple-atomic
Run Code Online (Sandbox Code Playgroud)

第二次运行不会真正重新运行测试,而只是比较上一次运行的统计数据。

要真正重新运行测试,您必须在重新运行之前先清除上一次运行生成的统计信息:

rm -rf build/ARM/tests/opt/quick/fs/10.linux-boot/arm/linux/realview-simple-atomic
Run Code Online (Sandbox Code Playgroud)

2019 年之前的回归测试:获取测试结果

即使这很混乱......scons不会返回0成功和1失败,所以你必须解析日志。一种简单的查看方式:

scons --ignore-style build/X86/tests/opt/quick/se |& grep -E '^\*\*\*\*\* '
Run Code Online (Sandbox Code Playgroud)

其中包含三种类型的结果:PASSSED,CHANGEDFAILED

CHANGED 主要用于有很大差异的统计比较,但这些通常很难维护并且永久损坏,因此您应该关注 FAILED

请注意,大多数测试目前依赖于SPEC2000并且失败,除非您可以访问此非免费基准测试...

单元测试

单元测试,它编译为从 中分离出可执行文件gem5,并且只测试一小部分代码。

目前有两种类型的测试:

  • UnitTest: 旧的和不推荐使用的,应该转换为 GTest

  • GTest: 新的和好的。使用谷歌测试

    放置在他们测试的课程旁边,例如:

    src/base/cprintf.cc
    src/base/cprintf.hh
    src/base/cprintftest.cc
    
    Run Code Online (Sandbox Code Playgroud)

编译并运行所有GTest单元测试:

scons build/ARM/unittests.opt
Run Code Online (Sandbox Code Playgroud)

示例输出摘录:

build/ARM/base/cprintftest.opt --gtest_output=xml:build/ARM/unittests.opt/base/cprintftest.xml
Running main() from gtest_main.cc
[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from CPrintf
[ RUN      ] CPrintf.Misc
[       OK ] CPrintf.Misc (0 ms)
[ RUN      ] CPrintf.FloatingPoint
[       OK ] CPrintf.FloatingPoint (0 ms)
[ RUN      ] CPrintf.Types
[       OK ] CPrintf.Types (0 ms)
[ RUN      ] CPrintf.SpecialFormatting
[       OK ] CPrintf.SpecialFormatting (0 ms)
[----------] 4 tests from CPrintf (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 4 tests.
Run Code Online (Sandbox Code Playgroud)

编译并运行一个测试文件:

scons build/ARM/base/cprintf.test.opt
./build/ARM/base/cprintf.test.opt
Run Code Online (Sandbox Code Playgroud)

从测试文件中列出可用的测试函数,然后只运行其中之一:

./build/ARM/base/cprintftest.opt --gtest_list_tests
./build/ARM/base/cprintftest.opt SpecialFormatting
Run Code Online (Sandbox Code Playgroud)

2018 年 8 月在 gem5 200281b08ca21f0d2678e23063f088960d3c0819 上测试。

使用 SimObjects 进行单元测试

截至 2019 年,单元测试非常有限,因为开发人员还没有找到一种合适的方法来单独测试 SimObjects,它们构成了模拟器的大部分,并且与模拟器的其余部分紧密结合。这个未合并的补丁试图解决这个问题:https : //gem5-review.googlesource.com/c/public/gem5/+/15315

可能可以使用已经存在于树中的 Google Mock 来解决它,但尚不清楚是否有人有耐心模拟足够的 SimObject 来实际进行此类测试。

我相信唯一实用的解决方案是将所有测试嵌入到 gem5.opt 中,然后有一个--test <testname>选项可以运行测试而不是运行模拟。这样我们就可以得到一个二进制文件而不会复制二进制文件的大小,但仍然可以访问所有内容。

相关问题:https : //gem5.atlassian.net/browse/GEM5-433

持续集成

20.1 Nightlies 已启用

正如在:https ://www.gem5.org/project/2020/10/01/gem5-20-1.html 中提到的,在以下位置添加了运行长期回归的 Jenkins:https : //jenkins.gem5.org/工作/每晚/

2019 CI

2019 年 4 月左右,在维护者给出 +1 后,在每次拉取请求后运行的预提交 CI。

它使用了一个神奇的半内部 Google 提供的 Jenkins 设置,称为 Kokoro,它提供了低可见性的配置。

例如,请参见:https : //gem5-review.googlesource.com/c/public/gem5/+/18108 该服务器当前不运行 nightlies。入口点是tests/jenkins/presubmit.sh

Nightlies 刚开始被禁用。

2019 CI的环境如何?

使用树内 Docker 镜像:https : //askubuntu.com/questions/350475/how-can-i-install-gem5/1275773#1275773

2019 年之前的 CI 更新

这是一个在某处运行的服务器,它每晚运行所有拱门的快速测试并将它们张贴在开发邮件列表中,增加了那个令人愉快的列表的无尽噪音:-)

这是一个示例运行:https : //www.mail-archive.com/gem5-dev@gem5.org/msg26855.html

截至 2019 年第一季度,gem5 开发人员正在尝试设置一个自动化的魔法 Google Jenkins 来运行预提交测试,可以在以下位置找到原型链接:https : //gem5-review.googlesource.com/c/public/gem5/+/ 17456/1#message-e9dceb1d3196b49f9094a01c54b06335cea4ff88这个新设置在tests/main.py.

2019 年之前的 CI:为什么一直有这么多测试CHANGED

截至 2018 年 8 月,许多测试已经CHANGED进行了很长时间。

这是因为统计数据可能因大量复杂因素而异。其中一些可能更准确,其他人不知道,其他人只是错误。

变化发生得如此频繁,以至于开发人员没有时间正确理解和证明它们。

如果你真的关心他们为什么改变,我最好的建议是将它们一分为二。

但通常你最好的办法是在新的 gem5 版本上重新运行你的旧实验,并比较那里的所有内容。

gem5 不是周期精确的系统模拟器,因此绝对值或小的变化通常没有意义。

这也告诉我们,由于噪声太大,以小边距获得的结果通常对发表没有意义。

误差幅度是多少,我不知道。