Nicolas,

Do you have a recommendation on how I can accomplish the goal at hand?  
Otherwise, I see no other option but to try Marc's groovy script.

Thanks.

On Jan 10, 2014, at 2:51 AM, nicolas de loof <[email protected]> wrote:

> I don't recommend such a fully programmatic approach, build-flow is designed 
> as a DSL, admittedly not constrained to just supported keywords (because I 
> didn't know how to do this when I started this plugin) but clearly not 
> supposed to be used to create such a groovy script.
> 
> 
> 2014/1/10 Marc MacIntyre <[email protected]>
> 
> You are overthinking it :)  The trick is to grab the return value from the 
> build() call and check the result of that, then explicitly set the failure 
> state of the buildflow.
> 
> This is what I'm doing; it's more solution than you need, but it solves your 
> problem.  
> 
> This buildflow takes a map of jobs and the pass criteria, and fires 
> everything off in parallel.  If you want to retry on failures, that's 
> supported, and/or you can start several in parallel and pass if some portion 
> of them pass.  We use job names as the map key, so if you want to start 
> multiple runs of a particular job with different params, you'll need to 
> modify the script somewhat.
> 
> def createBuildClosure(String jn, Map args, int retryCount = 0) {
>     // This indirection is needed to force a clone of args, so it's out of 
> scope and gets 
>     // re-bound to the closure each time - otherwise jenkins will deduplicate 
> our builds.
>     def ags = args.clone()
>     ags.put("_dedup", java.lang.System.nanoTime())
>     if (retryCount) {
>         return { retry(retryCount) {build(ags, jn)} }
>     } else {
>         return {build(ags, jn)}
>     }
> }
> 
> def startParallelRuns(Map buildsToRun) {
>     def m = [:]
>     buildsToRun.each {
>         jobName, params  ->
>             def maxFailures = params.get("maxFailures", 0)
>             def retryCount = params.get("retryCount", 0)
>             println "Running "+jobName+" "+params.count+" times (max failures 
> "+maxFailures+")"
>             for (int idx = 0; idx < params.count; idx++) {
>                 m.put(jobName+"_"+idx, createBuildClosure(jobName, 
> params.args, retryCount))
>             }
>     }
> 
>     ignore(FAILURE) {
>         join = parallel(m)
>     }
> 
>     results = [:]
>     // process the results by job name
>     buildsToRun.each {
>         jobName, params  ->
>             def passcount = 0
>             def maxFailures = params.get("maxFailures", 0)
>             for (int idx = 0; idx < params.count; idx++) {
>                 run = join[jobName+"_"+idx]
>                 if (run.result == SUCCESS) { passcount += 1}
>             }
>             result = (params.count - passcount) > maxFailures ? FAILURE : 
> SUCCESS
>             println ""+result+": "+jobName+": "+passcount+"/"+params.count+" 
> passed (Max failures: "+maxFailures+")"
>             results[jobName] = result
>     }
>     return results
> }
> 
> build_params = params.clone()
> 
> // Modify your build params here
> build_params.put('UPSTREAM_JOB', build.project.name)
> 
> buildsToRun = [
>   job1: [count: 1, maxFailures: 0, args: build_params, retryCount: 2],
>   job2: [count: 1, maxFailures: 0, args: build_params],
>   job3: [count: 1, maxFailures: 0, args: build_params],
>   jobX: [count: 2, maxFailures: 0, args: build_params],
>   jobY: [count: 1, maxFailures: 0, args: build_params],
> ]
> 
> 
> results = startParallelRuns(buildsToRun)
> build.state.result = results.any { job, result -> result == FAILURE} ? 
> FAILURE : SUCCESS
> 
> 
> 
> On Thu, Jan 9, 2014 at 8:22 PM, silver <[email protected]> wrote:
> Sorry for any confusion.  The line: ”println(“There were “+FailuresPresent+" 
> test(s) that failed”);" is outside of the if statement resulting in the 
> example output at the end of this message.
> 
> On Jan 9, 2014, at 9:55 PM, silver <[email protected]> wrote:
> 
> > When I run jobs in parallel, the Build Flow fails or passes as I’d expect.  
> > Example:
> >
> > parallel (
> > { build(job1) },
> > { build(job2) },
> > { build(job3) },
> > )
> >
> > All of the jobs are started and if they all pass, the Build Flow passes.  
> > If one fails, the Build Flow fails.
> >
> > What I’d like to do is to run jobs sequentially, ignoring a failure *for 
> > that moment* but at the end, fail or pass the Build Flow as a whole.  Using 
> > “ignore(FAILURE)" doesn’t give me what I want because it will ignore a 
> > failure and pass the Build Flow regardless:
> >
> > ignore(FAILURE) {build(job1)}
> > ignore(FAILURE) {build(job2)}
> > ignore(FAILURE) {build(job3)}
> >
> > If they all fail, the Build Flow still passes because failures are ignored. 
> >  But I really need ALL of the jobs to run no matter the outcome of the 
> > other jobs, and the Build Flow to pass/fail, depending on each outcome.
> >
> > Therefore, I have tried something like this (which I thought I got to 
> > actually work at one point but I can’t get it to work again!?!  The closest 
> > I can get is explained further down.):
> >
> > FailuresPresent = 0;
> > try {
> >  build(job1)
> > }catch(e) {
> >  FailuresPresent = FailuresPresent++;
> > }
> > try {
> >  build(job2)
> > }catch(e) {
> >  FailuresPresent = FailuresPresent++;
> > }
> > try {
> >  build(job3)
> > }catch(e) {
> >  FailuresPresent = FailuresPresent++;
> > }
> > if ( FailuresPresent>0) {
> >  println(“There were “+FailuresPresent+" test(s) that failed”);
> >  throw new Exception("FAILED!”);
> > }else {
> >  println "Tests PASSED!";
> > }
> >
> > But the Build Flow will still stop immediately after a failed job (I don’t 
> > see my println at the end).  If I use an ignore(FAILURE) wrapper, then the 
> > “catch” is ignored and the Build Flow passes.
> >
> > I am not using guard/rescue because I don’t need the FailuresPresent to 
> > increment every time, only when there is a failure (or do I?  Guard/Rescue 
> > is like try/finally, not a try/catch.)
> >
> > None of my jobs are dependent on another, I just want them all grouped 
> > together and to run sequentially in a single Build Flow if possible.  
> > Running them in parallel maxes out my resources (not Jenkins but my 
> > Selenium hub).
> >
> > If I wrap the above jobs in a parallel statement, it seems to gives the 
> > appearance of it finishing to completion (my print statement at the end is 
> > seen) but the Build Flow doesn’t run the other jobs.
> >
> > This is the output with the entire try/catch/builds wrapped in a parallel 
> > statement (notice job2 and job3 aren’t run but my println at the end is 
> > seen:
> >
> > parallel {
> >    Schedule job job1
> >    Build job1 #34 started
> >    job1 #34 completed  : UNSTABLE
> > }
> > There were 0 test(s) that failed
> > Tests PASSED!
> >
> > Suggestions?  I hope I’m over-thinking this.
> >
> > Thanks.
> 
> 
> 
> 
> -- 
> Marc MacIntyre
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to