在Jenkins构建后的Groovy脚本中,是否有一种方法可以使Computer.waitUntilOnline
函数在一段时间后超时?
我们对嵌入式设备进行测试,而我们的jenkins奴隶是连接到某些硬件设置的笔记本电脑。在某些情况下,我们需要使用繁琐的构建后脚本重新启动计算机,然后等待计算机再次联机。但是,有时这些机器不会再次联机,我们的常规脚本会无限期地等待。
waitUntilOnline
函数可以引发InterruptedException,但是from what I can tell您需要运行多个线程才能触发该异常。运行多个线程只是为了触发超时,这似乎是错误的处理方式。
我还发现some information是使用timeout
的。这是针对Jenkins Pipelines的,因此我不确定我是否可以在构建后的Groovy中使用它,而且我还没有使其工作。我尝试了各种组合,包括:
timeout(20)
{
computer.waitUntilOnline()
}
和
timeout(20)
{
waitUntil{
try {
computer.waitUntilOnline()
}catch (exception){
manager.listener.logger.println("caught exception!");
}
}
}
但是所有人似乎都抛出了这样的异常:
groovy.lang.MissingMethodException: No signature of method: Script1.timeout() is applicable for argument types: (java.lang.Integer, Script1$_rebootAndWait_closure1) values: [20, Script1$_rebootAndWait_closure1@7b6564fc]
任何建议都值得赞赏。
编辑:
我也尝试过this question中提到的@groovy.transform.TimedInterrupt
批注,但结果却很奇怪。
当我运行简单的循环示例时,我得到了预期的结果:它为i打印了一些值。但是,如果我尝试将其与重新启动计算机结合使用,就像这样:
import hudson.util.RemotingDiagnostics
def runCmd(computer, cmd)
{
def channel = computer.getChannel()
str = RemotingDiagnostics.executeGroovy( """
p = '$cmd'.execute()
p.waitFor()
p.in.text
""", channel )
}
@groovy.transform.TimedInterrupt( 3L )
def loopy()
{
int i = 0
try {
while( true ) {
i++
}
}
catch( e ) {
manager.listener.logger.println("i is "+i);
}
}
def rebootAndWait(computer)
{
manager.listener.logger.println("about to loopy : " +computer.name);
cmd = 'shutdown /r /t 10 /c "Restarting after Jenkins test completed"'
// cmd = "cmd.exe /c echo loopy test > c:\\\\Users\\\\frederikvs\\\\fvs_test.txt"
runCmd(computer, cmd)
// eventually we want to wait here for the computer to come back online, but for now we'll just have loopy
loopy();
}
rebootAndWait(manager.build.getBuiltOn().toComputer())
我得到怪异的结果:有时我得到的期望值是i的值,有时我会遇到未捕获的异常:
java.util.concurrent.TimeoutException: Execution timed out after 3 units. Start time: Fri Aug 17 10:48:07 CEST 2018
at sun.reflect.GeneratedConstructorAccessor5665.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:247)
at Script1.loopy(Script1.groovy)
at Script1.rebootAndWait(Script1.groovy:47)
at Script1$rebootAndWait.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
at Script1.run(Script1.groovy:51)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:585)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:623)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:594)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:343)
at org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder.perform(GroovyPostbuildRecorder.java:380)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
at hudson.model.Build$BuildExecution.post2(Build.java:186)
at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
at hudson.model.Run.execute(Run.java:1819)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:429)
关键在于:是否获得i的值,还是获得异常,似乎取决于上一个运行。
如果我多次使用reboot命令运行它,我总是会遇到异常。如果我多次使用echo命令(当前已注释掉)运行它,则始终可以获得打印i的预期结果。 但是,如果我使用重新启动命令运行它,然后将其切换到echo命令并运行几次,第一次使用echo将给出异常,此后它将给出i的值。 而且,如果我从echo命令切换到reboot命令,则第一次重新启动也可以(打印i的值),然后再开始给出异常。
我不太了解前一次运行如何影响当前运行的超时...
再次感谢您的任何投入!