【问题标题】:How to run the gem5 unit tests?如何运行 gem5 单元测试?
【发布时间】:2018-09-11 16:00:21
【问题描述】:

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

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

【问题讨论】:

    标签: gem5


    【解决方案1】:

    单元与回归测试

    gem5 有两种测试:

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

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

    回归测试

    2019 年回归测试

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

    在发送补丁之前,你基本上想运行:

    cd tests
    ./main.py run -j `nproc` -t `nproc`
    

    这将:

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

    通过将tests/ 目录作为参数传递,您可以在不使用cd 的情况下实现与上一个命令相同的效果:

    ./main.py run -j `nproc` -t `nproc` tests
    

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

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

    Stdout 包含表单的明确结果输出:

    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
    

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

    tests/.testing-results/
    

    例如:

    .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/
    

    虽然我们在那里只看到一些最小的 stdout/stderr 输出,甚至没有显示 gem5 标准输出。然而,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
    

    所以您可以删除 -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
    

    每个测试都被分类为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
    

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

    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
    

    现在您可以使用--uid 运行一个测试:

    ./main.py run -j `nproc` -t `nproc` --isa ARM --uid SuiteUID:tests/gem5/cpu_tests/test.py:cpu_test_AtomicSimpleCPU_FloatMM-ARM
    

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

    然后,当您运行测试时,其中任何一个都失败了,而您只想运行失败的那个,测试失败会给您这样一行:

    Test: cpu_test_DerivO3CPU_FloatMM-ARM-opt Passed
    

    仅运行测试的唯一方法是在./main.py list 的输出中为该字符串输入grep,因为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
    

    例如,它将构建放置在 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
    

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

    2019 回归测试自定义二进制下载导向器

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

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

    2019 年之前的回归测试

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

    测试直接使用scons 运行。

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

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

    ./util/regress -n --builds X86,ARM quick
    

    除了quick 之外的其他选项是longall 以同时执行longquick

    使用-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 
    

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

    所以请注意这两者如何:

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

    或者获取命令为所有拱门运行所有测试:

    ./util/regress -n all
    

    然后,如果您只想运行其中一种类型的测试,例如quick X86 可以复制粘贴 scons 仅用于该测试:

    scons --ignore-style build/X86/tests/opt/quick/se
    

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

    scons --ignore-style /any/path/that/you/want/build/X86/tests/opt/quick/se
    

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

    ./util/regress --build-dir /any/path/that/you/want all
    

    另一方面,启动 Linux 的测试需要在 M5_PATH 中具有特定名称的 Linux 映像,这也很烦人。

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

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

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

    例如,我们有:

    scons --ignore-style build/X86/tests/opt/quick/se
    

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

    quick/se/00.hello/ref/x86/linux/simple-atomic/
    

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

    scons build/X86/tests/opt/quick/se/00.hello/x86/linux/simple-atomic
    

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

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

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

    例如:

    scons --ignore-style build/X86/tests/opt/quick/se
    

    输出:

    Running test in /any/path/that/you/want/build/ARM/tests/opt/quick/se/00.hello/arm/linux/simple-atomic.
    

    和文件:

    /any/path/that/you/want/build/ARM/tests/opt/quick/se/00.hello/arm/linux/simple-atomic
    

    包含:

    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
    

    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
    

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

    要真正重新运行测试,必须先清除上次运行生成的统计信息,然后再重新运行:

    rm -rf build/ARM/tests/opt/quick/fs/10.linux-boot/arm/linux/realview-simple-atomic
    

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

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

    scons --ignore-style build/X86/tests/opt/quick/se |& grep -E '^\*\*\*\*\* '
    

    其中包含三种类型的结果:PASSSEDCHANGEDFAILED

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

    请注意,目前大多数测试都依赖于SPEC2000,除非您有权访问此非免费基准测试,否则它们会失败...

    单元测试

    单元测试,它编译为将可执行文件与gem5 分开,并且只测试一小部分代码。

    目前有两种类型的测试:

    • UnitTest:旧且已弃用,应转换为GTest

    • GTest: 新的和好的。使用Google Test

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

      src/base/cprintf.cc
      src/base/cprintf.hh
      src/base/cprintftest.cc
      

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

    scons build/ARM/unittests.opt
    

    示例输出摘录:

    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.
    

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

    scons build/ARM/base/cprintf.test.opt
    ./build/ARM/base/cprintf.test.opt
    

    列出测试文件中可用的测试函数,并只运行其中一个:

    ./build/ARM/base/cprintftest.opt --gtest_list_tests
    ./build/ARM/base/cprintftest.opt SpecialFormatting
    

    于 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 中提到的那样,在https://jenkins.gem5.org/job/Nightly/ 处添加了运行长回归的 Jenkins

    2019 年 CI

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

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

    例如: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 不是周期精确的系统模拟器,因此绝对值或 小的变化通常没有意义。

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

    这个误差范围是多少,我不知道。

    【讨论】:

      猜你喜欢
      • 2018-01-12
      • 1970-01-01
      • 2011-04-24
      • 2010-11-16
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多