diff --git a/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java b/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java index 1aea2847..a3a448cf 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java @@ -368,14 +368,19 @@ private static final class ParallelResumer { LOGGER.log(Level.WARNING, "Could not look up FlowNode for " + se + " so it will not be resumed", x); } } - for (FlowNode n : nodes.keySet()) { - LinearBlockHoppingScanner scanner = new LinearBlockHoppingScanner(); - scanner.setup(n); - for (FlowNode parent : scanner) { - if (parent != n && nodes.containsKey(parent)) { - enclosing.put(n, parent); - break; + for (Map.Entry entry : nodes.entrySet()) { + FlowNode n = entry.getKey(); + try { + LinearBlockHoppingScanner scanner = new LinearBlockHoppingScanner(); + scanner.setup(n); + for (FlowNode parent : scanner) { + if (parent != n && nodes.containsKey(parent)) { + enclosing.put(n, parent); + break; + } } + } catch (Exception x) { + LOGGER.log(Level.WARNING, x, () -> "Unable to compute enclosing blocks for " + n + ", so " + entry.getValue() + " might not resume successfully"); } } } diff --git a/src/main/java/org/jenkinsci/plugins/workflow/graph/StandardGraphLookupView.java b/src/main/java/org/jenkinsci/plugins/workflow/graph/StandardGraphLookupView.java index e721410a..98de089c 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/graph/StandardGraphLookupView.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/graph/StandardGraphLookupView.java @@ -11,7 +11,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** @@ -119,8 +121,11 @@ BlockEndNode bruteForceScanForEnd(@NonNull BlockStartNode start) { /** Do a brute-force scan for the enclosing blocks **/ BlockStartNode bruteForceScanForEnclosingBlock(@NonNull final FlowNode node) { FlowNode current = node; - + Set visited = new HashSet<>(); while (!(current instanceof FlowStartNode)) { // Hunt back for enclosing blocks, a potentially expensive operation + if (!visited.add(current.getId())) { + throw new IllegalStateException("Cycle in flow graph for " + node.getExecution() + " involving " + current); + } if (current instanceof BlockEndNode) { // Hop over the block to the start BlockStartNode start = ((BlockEndNode) current).getStartNode(); diff --git a/src/main/java/org/jenkinsci/plugins/workflow/graphanalysis/LinearBlockHoppingScanner.java b/src/main/java/org/jenkinsci/plugins/workflow/graphanalysis/LinearBlockHoppingScanner.java index 970a0b54..73720a4e 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/graphanalysis/LinearBlockHoppingScanner.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/graphanalysis/LinearBlockHoppingScanner.java @@ -32,8 +32,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; import net.jcip.annotations.NotThreadSafe; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -85,9 +87,12 @@ protected void setHeads(@NonNull Collection heads) { @CheckForNull protected FlowNode jumpBlockScan(@CheckForNull FlowNode node, @NonNull Collection blacklistNodes) { FlowNode candidate = node; - + Set visited = new HashSet<>(); // Find the first candidate node preceding a block... and filtering by blacklist while (candidate instanceof BlockEndNode) { + if (!visited.add(candidate.getId())) { + throw new IllegalStateException("Cycle in flow graph for " + candidate.getExecution() + " involving " + candidate); + } candidate = ((BlockEndNode) candidate).getStartNode(); if (blacklistNodes.contains(candidate)) { return null; diff --git a/src/test/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest.java b/src/test/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest.java index 9b9ee501..9952dadf 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest.java @@ -41,11 +41,14 @@ import java.io.Serializable; import java.lang.ref.WeakReference; import java.util.Collections; +import java.util.Objects; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.stream.Collectors; import jenkins.model.Jenkins; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; @@ -65,6 +68,7 @@ import org.jvnet.hudson.test.JenkinsSessionRule; import org.jvnet.hudson.test.MemoryAssert; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.recipes.LocalData; import org.kohsuke.stapler.DataBoundConstructor; public class FlowExecutionListTest { @@ -164,6 +168,35 @@ public class FlowExecutionListTest { }); } + @LocalData + @Test public void resumeStepExecutionsWithCorruptFlowGraphWithCycle() throws Throwable { + // LocalData created using the following snippet while the build was waiting in the _second_ sleep, except + // for build.xml, which was captured during the sleep step. The StepEndNode for the stage was then adjusted to + // have its startId point to the timeout step's StepStartNode, creating a loop. + /* + sessions.then(r -> { + var stuck = r.createProject(WorkflowJob.class); + stuck.setDefinition(new CpsFlowDefinition("stage('stage') { sleep 30 }; timeout(time: 10) { sleep 30 }", true)); + var b = stuck.scheduleBuild2(0).waitForStart(); + System.out.println(b.getRootDir()); + r.waitForCompletion(b); + }); + */ + logging.capture(50); + sessions.then(r -> { + var p = r.jenkins.getItemByFullName("test0", WorkflowJob.class); + var b = p.getBuildByNumber(1); + r.waitForCompletion(b); + assertThat(logging.getMessages(), hasItem(containsString("Unable to compute enclosing blocks"))); + var loggedExceptions = logging.getRecords().stream() + .map(LogRecord::getThrown) + .filter(Objects::nonNull) + .map(Throwable::toString) + .collect(Collectors.toList()); + assertThat(loggedExceptions, hasItem(containsString("Cycle in flow graph"))); + }); + } + @Test public void stepExecutionIteratorDoesNotLeakBuildsWhenOneIsStuck() throws Throwable { sessions.then(r -> { var notStuck = r.createProject(WorkflowJob.class, "not-stuck"); diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/build.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/build.xml new file mode 100644 index 00000000..d2b7e367 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/build.xml @@ -0,0 +1,46 @@ + + + 1 + 1722979974600 + 1722979974615 + 0 + UTF-8 + false + + SUCCESS + + + MAX_SURVIVABILITY + + + flowNode + 101709541 + + + classLoad + 124446251 + + + run + 200459289 + + + parse + 166818958 + + + saveProgram + 57936125 + + + + true + 5 + 1:5 + 2 + false + false + + false + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/log b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/log new file mode 100644 index 00000000..f8c5883d --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/log @@ -0,0 +1,13 @@ +Started +ha:////4LSn6sjy3SQJvLr4M0Jcw5zYiu9jzzxAhCQhf5ciKGcGAAAAoh+LCAAAAAAAAP9tjTEOwjAQBM8BClpKHuFItIiK1krDC0x8GCfWnbEdkooX8TX+gCESFVvtrLSa5wtWKcKBo5UdUu8otU4GP9jS5Mixv3geZcdn2TIl9igbHBs2eJyx4YwwR1SwULBGaj0nRzbDRnX6rmuvydanHMu2V1A5c4MHCFXMWcf8hSnC9jqYxPTz/BXAFEIGsfuclm8zQVqFvQAAAA==[Pipeline] Start of Pipeline +ha:////4FLPcBhXXN+T+Uy5Bq+9NjiuG45smS/CK+MQ8sUKcTBsAAAApR+LCAAAAAAAAP9tjTEOwjAUQ3+KOrAycohUghExsUZZOEFIQkgb/d8mKe3EibgadyBQiQlLlmxL1nu+oE4RjhQdby12HpP2vA+jK4lPFLtroIm3dOGaMFGwXNpJkrGnpUrKFhaxClYC1hZ1oOTRZdiIVt1VExS65pxj2Q4CKm8GeAAThZxVzN8yR9jeRpMIf5y/AJj7DGxXvP/86jduZBmjwAAAAA==[Pipeline] stage +ha:////4MPOLP4Go7JuW3NkAKhksIfyE+NroTrcISNM8xfRFLQ8AAAApR+LCAAAAAAAAP9tjTEOwjAUQ3+KOrAycoh0gA0xsUZZOEFIQkgb/d8mKe3EibgadyBQiQlLlmxL1nu+oE4RjhQdby12HpP2vA+jK4lPFLtroIm3dOGaMFGwXNpJkrGnpUrKFhaxClYC1hZ1oOTRZdiIVt1VExS65pxj2Q4CKm8GeAAThZxVzN8yR9jeRpMIf5y/AJj7DGxXvP/86jfoP95RwAAAAA==[Pipeline] { (stage) +ha:////4E53KhegWm+s/q0TJkIC5MI9kTq62Eqnzz2Qdi1URRTJAAAAoh+LCAAAAAAAAP9tjTEOAiEURD9rLGwtPQTbaGWsbAmNJ0AWEZb8zwLrbuWJvJp3kLiJlZNMMm+a93rDOic4UbLcG+wdZu14DKOti0+U+lugiXu6ck2YKRguzSSpM+cFJRUDS1gDKwEbgzpQdmgLbIVXD9UGhba9lFS/o4DGdQM8gYlqLiqVL8wJdvexy4Q/z18BzLEA29ce4gdpL1fxvAAAAA==[Pipeline] sleep +Sleeping for 30 sec +ha:////4G8hLCAAqKEvMe92YhTNPJa4MSOZpWK2lhgTDgEHbCXUAAAAoh+LCAAAAAAAAP9tjTEOAiEURD9rLGwtPQTbGBtjZUtoPAGyiLDkfxZYdytP5NW8g8RNrJxkknnTvNcb1jnBiZLl3mDvMGvHYxhtXXyi1N8CTdzTlWvCTMFwaSZJnTkvKKkYWMIaWAnYGNSBskNbYCu8eqg2KLTtpaT6HQU0rhvgCUxUc1GpfGFOsLuPXSb8ef4KYI6xADvU7j8OXFZ7vAAAAA==[Pipeline] } +ha:////4AnScT3OQumBbV+luAyxvhEcCl/8MozDCcq/aC6iNLpjAAAAox+LCAAAAAAAAP9tjTEOAiEURD9rLGwtPQRbWFgYK1tC4wmQRYQl/7PAult5Iq/mHSRuYuUkk8yb5r3esM4JTpQs9wZ7h1k7HsNo6+ITpf4WaOKerlwTZgqGSzNJ6sx5QUnFwBLWwErAxqAOlB3aAlvh1UO1QaFtLyXV7yigcd0AT2CimotK5Qtzgt197DLhz/NXAHOMBdihdv8BHeBS2LwAAAA=[Pipeline] // stage +ha:////4PTj6M4JscP6Gdk49EfTAaLMCwLZYd9IOq+brFvOiJPAAAAAph+LCAAAAAAAAP9tjUEKwjAURH8qXbh16SFScCWIK7chG08QkxjThv/bJLVdeSKv5h2MFlw5MDAzMLznC+oU4UjR8dZi5zFpz/swupL4RLG7Bpp4SxeuCRMFy6WdJBl7WqqkbGERq2AlYG1RB0oeXYaNaNVdNUGha845lu0goPJmgAcwUchZxfwtc4TtbTSJ8Mf5C4C5z8B2xfvPr34DrZTeycAAAAA=[Pipeline] timeout +Timeout set to expire in 10 min +ha:////4M9FYx/jFzgoF1Ji4m6uzCtxEvJBQzBzYoKBBTbKepUTAAAApR+LCAAAAAAAAP9tjTEOwjAUQ3+KOrAycoh0BSEm1igLJwhJCGmj/9skpZ04EVfjDgQqMWHJkm3Jes8X1CnCkaLjrcXOY9Ke92F0JfGJYncNNPGWLlwTJgqWSztJMva0VEnZwiJWwUrA2qIOlDy6DBvRqrtqgkLXnHMs20FA5c0AD2CikLOK+VvmCNvbaBLhj/MXAHOfge2K959f/QbB16AVwAAAAA==[Pipeline] { +ha:////4O/MG/IybiYM4oG30m877qNjUwTyRLwWY87qTVAOsZwoAAAAoh+LCAAAAAAAAP9tjTEOwjAQBDdBFLSUPMKBEiEqWisNLzCJMU6su2BfSCpexNf4AxGRqNhqZ5p5vbFMEUeOTjWWWk+p8qoLvZueGji218CDaviiKqbEwarSDiXX9jRjyWIxL8ux0FhZqgInT06w1o15mCIYcsVZ4uQOGrmv73gi01NZTJQvjBGbW18npl/nbwBjJ8j2gny37T6VOYoyvQAAAA==[Pipeline] sleep +Sleeping for 30 sec diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/log-index b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/log-index new file mode 100644 index 00000000..bfafbf78 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/log-index @@ -0,0 +1,5 @@ +1232 5 +1252 +2157 8 +2189 +2789 10 diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/program.dat b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/program.dat new file mode 100644 index 00000000..aeae086b Binary files /dev/null and b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/program.dat differ diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/10.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/10.xml new file mode 100644 index 00000000..2f9ecb73 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/10.xml @@ -0,0 +1,26 @@ + + + + + 9 + + 10 + org.jenkinsci.plugins.workflow.steps.SleepStep + + + + + + time + 30 + + + + true + + + 1722980005296 + + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/2.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/2.xml new file mode 100644 index 00000000..213232ad --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/2.xml @@ -0,0 +1,12 @@ + + + + + 2 + + + + 1722979974868 + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/3.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/3.xml new file mode 100644 index 00000000..ff65b2ee --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/3.xml @@ -0,0 +1,26 @@ + + + + + 2 + + 3 + org.jenkinsci.plugins.workflow.support.steps.StageStep + + + + + + + name + stage + + + + true + + + 1722979974972 + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/4.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/4.xml new file mode 100644 index 00000000..0f422ed2 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/4.xml @@ -0,0 +1,19 @@ + + + + + 3 + + 4 + org.jenkinsci.plugins.workflow.support.steps.StageStep + + + + + stage + + + 1722979974988 + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/5.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/5.xml new file mode 100644 index 00000000..5dcd2edd --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/5.xml @@ -0,0 +1,26 @@ + + + + + 4 + + 5 + org.jenkinsci.plugins.workflow.steps.SleepStep + + + + + + time + 30 + + + + true + + + 1722979975077 + + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/6.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/6.xml new file mode 100644 index 00000000..967f277a --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/6.xml @@ -0,0 +1,16 @@ + + + + + 5 + + 6 + 4 + + + + + 1722980005117 + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/7.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/7.xml new file mode 100644 index 00000000..3625f1ef --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/7.xml @@ -0,0 +1,15 @@ + + + + + 6 + + 7 + 8 + + + + 1722980005177 + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/8.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/8.xml new file mode 100644 index 00000000..ea60fd6d --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/8.xml @@ -0,0 +1,26 @@ + + + + + 7 + + 8 + org.jenkinsci.plugins.workflow.steps.TimeoutStep + + + + + + + time + 10 + + + + true + + + 1722980005227 + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/9.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/9.xml new file mode 100644 index 00000000..a5767ab8 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/1/workflow/9.xml @@ -0,0 +1,16 @@ + + + + + 8 + + 9 + org.jenkinsci.plugins.workflow.steps.TimeoutStep + + + + + 1722980005244 + + + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/legacyIds b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/builds/legacyIds new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/config.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/config.xml new file mode 100644 index 00000000..826019f9 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/config.xml @@ -0,0 +1,11 @@ + + + false + + + + true + + + false + \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/nextBuildNumber b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/nextBuildNumber new file mode 100644 index 00000000..0cfbf088 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/jobs/test0/nextBuildNumber @@ -0,0 +1 @@ +2 diff --git a/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/org.jenkinsci.plugins.workflow.flow.FlowExecutionList.xml b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/org.jenkinsci.plugins.workflow.flow.FlowExecutionList.xml new file mode 100644 index 00000000..56b066fd --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/workflow/flow/FlowExecutionListTest/resumeStepExecutionsWithCorruptFlowGraphWithCycle/org.jenkinsci.plugins.workflow.flow.FlowExecutionList.xml @@ -0,0 +1,7 @@ + + + + test0 + 1 + + \ No newline at end of file