【问题标题】:Jenkins Build Script exits after Google Test execution执行 Google 测试后,Jenkins 构建脚本退出
【发布时间】:2023-03-06 21:50:01
【问题描述】:

我正在通过 Jenkins 构建一个 Qt GUI 应用程序。我添加了 3 个构建步骤:

  • 构建测试可执行文件
  • 运行测试可执行文件
  • 使用 gcovr 编译覆盖率报告

由于某种原因,用于运行测试可执行文件的 shell 任务在执行后停止。即使是简单的echo 也不会运行。测试使用 Google Test 编写并输出 xUnit XML 文件,这些文件在构建后进行分析。 一些测试启动应用程序用户界面,所以我安装了 jenkins xvnc 插件来让它们运行。

构建任务如下:

构建

cd $WORKSPACE/projectfiles/QMake
sh createbin.sh

测试

cd $WORKSPACE/bin
./Application --gtest_output=xml

覆盖率报告

cd $WORKSPACE/projectfiles/QMake/out
gcovr -x -o coverage.xml

现在,第一个构建任务末尾的 echo 已正确打印,但第二个构建任务末尾的 echo 则不正确。因此,第三个构建任务甚至没有运行,尽管 Google 测试输出是可见的。我认为问题可能在于某些 Google 测试失败,但为什么脚本会因为测试失败而停止执行?

也许有人可以提示我为什么第二个任务停止。

编辑

控制台输出如下所示:

Updating svn://repo/ to revision '2012-11-15T06:43:15.228 -0800'
At revision 2053
no change for svn://repo/ since the previous build
Starting xvnc
[VG5] $ vncserver :10

New 'ubuntu:10 (jenkins)' desktop is ubuntu:10

Starting applications specified in /var/lib/jenkins/.vnc/xstartup
Log file is /var/lib/jenkins/.vnc/ubuntu:10.log

[VG5] $ /bin/sh -xe /tmp/hudson7777833632767565513.sh
+ cd /var/lib/jenkins/workspace/projectfiles/QMake
+ sh createbin.sh
... Compiler output ...
+ echo Build Done
Build Done
[VG5] $ /bin/sh -xe /tmp/hudson4729703161621217344.sh
+ cd /var/lib/jenkins/workspace/VG5/bin
+ ./Application --gtest_output=xml
Xlib:  extension "XInputExtension" missing on display ":10".
[==========] Running 29 tests from 8 test cases.
... Test output ...
 3 FAILED TESTS
Build step 'Execute shell' marked build as failure
Terminating xvnc.
$ vncserver -kill :10
Killing Xvnc4 process ID 1953
Recording test results
Skipping Cobertura coverage report as build was not UNSTABLE or better ...
Finished: FAILURE

【问题讨论】:

    标签: qt jenkins googletest


    【解决方案1】:

    一般情况下,如果一个Build Step失败,其余的都不会执行。

    注意日志中的这一行:

    [VG5] $ /bin/sh -xe
    

    -x 使 shell 在执行前在控制台中打印每个命令。
    如果任何命令失败,-e 会使 shell 退出并出错。

    在这种情况下,“失败”将是任何单个命令的返回码不为 0。
    您可以通过直接在机器上运行来验证这一点:

    ./Application --gtest_output=xml
    echo $?
    

    如果echo $?显示为0,则表示上一条命令成功完成。如果它显示其他任何内容,则表示来自上一个命令(来自 ./Application)的错误代码,Jenkins 会这样处理。

    现在,这里有几件事情在起作用。首先,如果一个命令失败(默认行为),您的第二个构建步骤(本质上是一个临时 shell 脚本 /tmp/hudson4729703161621217344.sh)设置为失败。当构建步骤失败时,Jenkins 将停止并导致整个作业失败。

    您可以通过将set +e 添加到第二个构建步骤的顶部来修复此特定行为。这不会导致脚本(构建步骤)由于个别命令失败而失败(它会显示命令错误,然后继续)。

    但是,脚本(构建步骤)的总体结果是最后一个命令的退出代码。由于在您的 OP 中,脚本中只有 2 个命令,最后一个命令失败,因此尽管您添加了 +x,但它会导致整个脚本(构建步骤)被视为失败。请注意,如果您将 echo 添加为第三条命令,这实际上会起作用,因为最后一个脚本命令 (echo) 是成功的,但是这种“解决方法”不是您所需要的。

    您需要在脚本中添加适当的错误处理。考虑一下:

    set +e
    cd $WORKSPACE/bin && ./Application --gtest_output=xml
    if ! [ $? -eq 0 ]; then
        echo "Tests failed, however we are continuing"
    else
        echo "All tests passed"
    fi
    

    脚本中发生了三件事:

    1. 首先,我们告诉 shell 不要在个别命令失败时退出

    2. 然后我在第二行添加了基本的错误处理。 && 的意思是“如果之前的 cd 成功,则执行 ./Application 如果并且仅 - 如果之前的 cd 成功。你永远不知道,也许 bin 文件夹丢失了,或者其他任何可能发生的事情。顺便说一句,&& 内部工作同一个错误码等于0的原则

    3. 最后,现在对./Application 的结果进行了适当的错误处理。如果结果不是 0,那么我们表明它失败了,否则我们表明它通过了。请注意,这是因为最后一个命令不是(可能)失败的./Application,而是来自任一 if-else 可能性的echo,因此脚本(构建步骤)的总体结果将是成功的(即 0),并执行下一个构建步骤。

    顺便说一句,您也可以通过适当的错误处理将所有 3 个构建步骤放入一个构建步骤中。

    是的...这个答案可能比要求的要长一点,但我希望您了解 Jenkins 和 shell 如何处理退出代码。

    【讨论】:

    • 很好的答案,我真的没有想到每个可能的命令都可以停止脚本的可能性。谢谢!
    • @zeflasher,你总是可以给我一个赏金的答案;)
    猜你喜欢
    • 2019-06-23
    • 1970-01-01
    • 2015-10-31
    • 2021-01-24
    • 2012-12-12
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 2012-05-29
    相关资源
    最近更新 更多