Jenkins构建脚本在Google Test执行后退出

问题描述:

我正在通过Jenkins构建一个Qt GUI应用程序。我加了3个构建步骤:Jenkins构建脚本在Google Test执行后退出

  • 构建测试可执行
  • 运行测试可执行
  • 编译具有gcovr

覆盖报告出于某种原因,运行测试可执行的壳任务执行后停止。即使是一个简单的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 

一般来说,如果一个生成步骤失败,其余的将不被执行。

重视这一行从您的日志:

[VG5] $ /bin/sh -xe 

-x使得外壳打印在执行前控制台的每个命令。
如果任何命令失败,-e会使shell退出并显示错误。

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

./Application --gtest_output=xml 
echo $? 

如果echo $?显示0时,表示前面的命令成功完成。如果它显示其他任何内容,则表示上一个命令(来自)的错误代码。/应用程序),而詹金斯就这样对待它。

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

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

但是,脚本(构建步骤)的总体结果是最后一个命令的退出代码。由于在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. 首先,我们告诉外壳不退出对各个命令

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

  3. 最后,现在对./Application的结果进行了适当的错误处理,如果结果不是0,那么表明它失败了,否则我们显示它已经通过了。不是(潜在的)失败./Application,但是既不是一个echo的如果其他的可能性,脚本(内置步骤)的总体结果将是一个成功的(即0),以及接下来的生成步骤将被执行。

顺便说一句,你可以如把你的构建步骤3的所有与正确的错误处理一个单一的生成步骤。

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

+1

优秀的答案,我真的没有想到每个可能的命令可能会停止脚本的可能性。谢谢! – dasmaze

+1

希望我可以upvote你10次。这很多! – nolazybits

+0

@zeflasher,你总是可以给我一个赏金的答案;) – Slav