我正在通过Jenkins构建Qt GUI应用程序。我添加了3个构建步骤:
由于某种原因,运行测试可执行文件的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 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
答案 0 :(得分:25)
通常,如果一个构建步骤失败,则不会执行其余步骤。
请注意日志中的这一行:
[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
添加到第二个Build Step的顶部来修复此特定行为。这不会导致脚本(Build Step)因单个命令失败而失败(它将显示命令错误,并继续)。
但是,脚本(Build Step)的总体结果是最后一个命令的退出代码。因为在您的OP中,脚本中只有2个命令,而最后一个命令失败,尽管您添加了+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
剧本中发生了三件事:
首先,我们告诉shell不要在单个命令失败时退出
然后我在第二行添加了基本的错误处理。如果前一个&&
成功,则./Application
表示“只执行cd
。您永远不会知道,bin文件夹可能丢失,或者其他任何事情都可能发生.BTW, &&
内部使用相同的错误代码等于0原则
最后,对./Application
的结果进行了正确的错误处理。如果结果不是0,那么我们表明它已经失败,否则我们表明它已经过去了。注意,这是因为最后一个命令不是(可能)失败的./Application
,而是来自if-else可能的echo
,脚本的整体结果(Built Step)将成功(即0),将执行下一个构建步骤。
是的......这个答案可能比需要的时间长一些,但我想让你了解Jenkins和shell如何对待退出代码。