在Google Test执行后,Jenkins Build Script退出

das*_*aze 7 qt googletest jenkins

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

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

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

构建任务如下:

建立

cd $WORKSPACE/projectfiles/QMake
sh createbin.sh
Run Code Online (Sandbox Code Playgroud)

测试

cd $WORKSPACE/bin
./Application --gtest_output=xml
Run Code Online (Sandbox Code Playgroud)

覆盖率报告

cd $WORKSPACE/projectfiles/QMake/out
gcovr -x -o coverage.xml
Run Code Online (Sandbox Code Playgroud)

现在,echo正确打印第一个构建任务echo的末尾,但是在第二个构建任务的末尾则没有.因此,即使Google Test输出可见,第三个构建任务也不会运行.我想也许问题是某些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
Run Code Online (Sandbox Code Playgroud)

Sla*_*lav 25

通常,如果一个构建步骤失败,则不会执行其余构建步骤.

请注意日志中的这一行:

[VG5] $ /bin/sh -xe
Run Code Online (Sandbox Code Playgroud)

-x使外壳执行之前在控制台打印每个命令.
-e错误使得外壳退出,如果任何命令失败.

在这种情况下,"失败"将是来自任何单个命令的返回码不为0.
您可以直接在计算机上运行此方法来验证这一点:

./Application --gtest_output=xml
echo $?
Run Code Online (Sandbox Code Playgroud)

如果echo $?显示0,则表示上一个命令成功完成.如果它显示任何其他内容,则表示上一个命令(来自./Application)的错误代码,并且Jenkins将其视为此类.

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

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

但是,脚本(Build Step)的总体结果是最后一个命令的退出代码.因为在你的OP中,你在脚本中只有2个命令,而最后一个命令失败,它会导致整个脚本(Build Step)被认为是失败的,尽管+x你已经添加了.请注意,如果您添加一个echo作为第3个命令,这实际上可以工作,因为最后一个脚本命令(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
Run Code Online (Sandbox Code Playgroud)

脚本中发生了三件事:

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

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

  3. 最后,现在有适当的错误处理结果./Application.如果结果不是0,那么我们表明它已经失败,否则我们表明它已经过去了.注意,这是因为最后一个命令不是(可能)失败./Application,而是echo来自if-else的任何一种可能性,脚本的整体结果(Built Step)将成功(即0),并且下一个Build Step将被执行.

顺便说一句,你可以将所有3个构建步骤放在一个构建步骤中,并进行适当的错误处理.

是的......这个答案可能比需要的时间长一些,但我想让你了解Jenkins和shell如何处理退出代码.