8

我正在通过 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第一个构建任务末尾的 an 已正确打印,但echo第二个构建任务末尾的 an 未正确打印。因此,第三个构建任务甚至没有运行,尽管 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
4

1 回答 1

28

通常,如果一个Build Step失败,其余的将不会被执行。

请注意日志中的这一行:

[VG5] $ /bin/sh -xe

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

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

./Application --gtest_output=xml
echo $?

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

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

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

但是,脚本(构建步骤)的总体结果是最后一个命令的退出代码。由于在您的 OP 中,脚本中只有 2 个命令,并且最后一个命令失败,因此尽管+x您已添加,但它会导致整个脚本(构建步骤)被视为失败。请注意,如果您将 an 添加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. 然后我在第二行添加了基本的错误处理。&&意思是“仅当前一个成功时才执行。你永远不知道,也许 bin 文件夹丢失了,或者其他任何可能发生的事情。顺便说一句,./Application内部工作在相同的错误代码上等于 0 原则cd&&

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

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

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

于 2012-11-15T19:21:24.103 回答