Search in sources :

Example 6 with DepthFirstScanner

use of org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner in project blueocean-plugin by jenkinsci.

the class PipelineNodeGraphVisitor method getPipelineNodeSteps.

@Override
public List<BluePipelineStep> getPipelineNodeSteps(final String nodeId, Link parent) {
    FlowExecution execution = run.getExecution();
    if (execution == null) {
        logger.debug(String.format("Pipeline %s, runid %s  has null execution", run.getParent().getName(), run.getId()));
        return Collections.emptyList();
    }
    DepthFirstScanner depthFirstScanner = new DepthFirstScanner();
    // If blocked scope, get the end node
    FlowNode n = depthFirstScanner.findFirstMatch(execution.getCurrentHeads(), input -> (input != null && input.getId().equals(nodeId) && (PipelineNodeUtil.isStage(input) || PipelineNodeUtil.isParallelBranch(input))));
    if (n == null) {
        // if no node found or the node is not stage or parallel we return empty steps
        return Collections.emptyList();
    }
    PipelineStepVisitor visitor = new PipelineStepVisitor(run, n);
    ForkScanner.visitSimpleChunks(execution.getCurrentHeads(), visitor, new StageChunkFinder());
    return visitor.getSteps().stream().map(node -> new PipelineStepImpl(node, parent)).collect(Collectors.toList());
}
Also used : DepthFirstScanner(org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner) Arrays(java.util.Arrays) InputAction(org.jenkinsci.plugins.workflow.support.steps.input.InputAction) LoggerFactory(org.slf4j.LoggerFactory) LabelAction(org.jenkinsci.plugins.workflow.actions.LabelAction) StringUtils(org.apache.commons.lang3.StringUtils) GenericStatus(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.GenericStatus) MemoryFlowChunk(org.jenkinsci.plugins.workflow.graphanalysis.MemoryFlowChunk) Map(java.util.Map) ExecutionModelAction(org.jenkinsci.plugins.pipeline.modeldefinition.actions.ExecutionModelAction) FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) BluePipelineNode(io.jenkins.blueocean.rest.model.BluePipelineNode) Action(hudson.model.Action) Collection(java.util.Collection) Set(java.util.Set) Collectors(java.util.stream.Collectors) StepStartNode(org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode) List(java.util.List) PauseAction(org.jenkinsci.plugins.workflow.support.actions.PauseAction) Optional(java.util.Optional) FlowStartNode(org.jenkinsci.plugins.workflow.graph.FlowStartNode) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) Link(io.jenkins.blueocean.rest.hal.Link) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) TimingAction(org.jenkinsci.plugins.workflow.actions.TimingAction) HashMap(java.util.HashMap) Stack(java.util.Stack) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) TimingInfo(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.TimingInfo) BlockEndNode(org.jenkinsci.plugins.workflow.graph.BlockEndNode) StandardChunkVisitor(org.jenkinsci.plugins.workflow.graphanalysis.StandardChunkVisitor) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) StageChunkFinder(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StageChunkFinder) StatusAndTiming(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StatusAndTiming) BluePipelineStep(io.jenkins.blueocean.rest.model.BluePipelineStep) BlueRun(io.jenkins.blueocean.rest.model.BlueRun) NotExecutedNodeAction(org.jenkinsci.plugins.workflow.actions.NotExecutedNodeAction) IOException(java.io.IOException) ForkScanner(org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) ArrayDeque(java.util.ArrayDeque) Comparator(java.util.Comparator) CheckForNull(javax.annotation.CheckForNull) Collections(java.util.Collections) StageChunkFinder(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StageChunkFinder) FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) DepthFirstScanner(org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 7 with DepthFirstScanner

use of org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner in project workflow-cps-plugin by jenkinsci.

the class FlowDurabilityTest method verifySucceededCleanly.

static void verifySucceededCleanly(Jenkins j, WorkflowRun run) throws Exception {
    Assert.assertEquals(Result.SUCCESS, run.getResult());
    int outputHash = run.getLog().hashCode();
    FlowExecution exec = run.getExecution();
    verifyCompletedCleanly(j, run);
    // Confirm the flow graph is fully navigable and contains the heads with appropriate ending
    DepthFirstScanner scan = new DepthFirstScanner();
    List<FlowNode> allNodes = scan.allNodes(exec);
    FlowNode endNode = exec.getCurrentHeads().get(0);
    Assert.assertEquals(FlowEndNode.class, endNode.getClass());
    assert allNodes.contains(endNode);
    Assert.assertEquals(8, allNodes.size());
    // Graph structure assertions
    Assert.assertEquals(2, scan.filteredNodes(endNode, (Predicate) (Predicates.instanceOf(StepStartNode.class))).size());
    Assert.assertEquals(2, scan.filteredNodes(endNode, (Predicate) (Predicates.instanceOf(StepEndNode.class))).size());
    Assert.assertEquals(1, scan.filteredNodes(endNode, (Predicate) (Predicates.instanceOf(FlowStartNode.class))).size());
    Predicate<FlowNode> sleepOrSemaphoreMatch = Predicates.or(new NodeStepNamePredicate(StepDescriptor.byFunctionName("semaphore").getId()), new NodeStepNamePredicate(StepDescriptor.byFunctionName("sleep").getId()));
    Assert.assertEquals(1, scan.filteredNodes(endNode, sleepOrSemaphoreMatch).size());
    Assert.assertEquals(1, scan.filteredNodes(endNode, new NodeStepNamePredicate(StepDescriptor.byFunctionName("echo").getId())).size());
    for (FlowNode node : (List<FlowNode>) (scan.filteredNodes(endNode, (Predicate) (Predicates.instanceOf(StepNode.class))))) {
        Assert.assertNotNull("Node: " + node.toString() + " does not have a TimingAction", node.getAction(TimingAction.class));
    }
    assertHasTimingAction(run.getExecution());
}
Also used : FlowStartNode(org.jenkinsci.plugins.workflow.graph.FlowStartNode) StepStartNode(org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode) TimingAction(org.jenkinsci.plugins.workflow.actions.TimingAction) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) NodeStepNamePredicate(org.jenkinsci.plugins.workflow.graphanalysis.NodeStepNamePredicate) FlowDurabilityHint(org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint) DepthFirstScanner(org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner) StepNode(org.jenkinsci.plugins.workflow.cps.nodes.StepNode) FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) List(java.util.List) ArrayList(java.util.ArrayList) CopyOnWriteList(hudson.util.CopyOnWriteList) FlowExecutionList(org.jenkinsci.plugins.workflow.flow.FlowExecutionList) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 8 with DepthFirstScanner

use of org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner in project workflow-cps-plugin by jenkinsci.

the class FlowDurabilityTest method testResumeBlocked.

@Test
public void testResumeBlocked() throws Exception {
    final String jobName = "survivesEverything";
    final String[] logStart = new String[1];
    final List<FlowNode> nodesOut = new ArrayList<FlowNode>();
    story.addStepWithDirtyShutdown(new Statement() {

        @Override
        public void evaluate() throws Throwable {
            Jenkins jenkins = story.j.jenkins;
            WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, jobName, FlowDurabilityHint.MAX_SURVIVABILITY);
            run.getParent().setResumeBlocked(true);
            FlowExecution exec = run.getExecution();
            if (exec instanceof CpsFlowExecution) {
                assert ((CpsFlowExecution) exec).getStorage().isPersistedFully();
            }
            logStart[0] = JenkinsRule.getLog(run);
            nodesOut.addAll(new DepthFirstScanner().allNodes(run.getExecution()));
            nodesOut.sort(FlowScanningUtils.ID_ORDER_COMPARATOR);
        }
    });
    story.addStep(new Statement() {

        @Override
        public void evaluate() throws Throwable {
            WorkflowRun run = story.j.jenkins.getItemByFullName(jobName, WorkflowJob.class).getLastBuild();
            verifyFailedCleanly(story.j.jenkins, run);
            assertIncludesNodes(nodesOut, run);
        }
    });
}
Also used : Statement(org.junit.runners.model.Statement) ArrayList(java.util.ArrayList) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) DepthFirstScanner(org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner) Jenkins(jenkins.model.Jenkins) FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) Test(org.junit.Test)

Example 9 with DepthFirstScanner

use of org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner in project workflow-cps-plugin by jenkinsci.

the class FlowDurabilityTest method fuzzTimingDurable.

/**
 * Test interrupting build by randomly dying at unpredictable times.
 */
@Test
// Too long to run as part of main suite
@Ignore
@TimedRepeatRule.RepeatForTime(repeatMillis = 170_000)
public void fuzzTimingDurable() throws Exception {
    final String jobName = "NestedParallelDurableJob";
    final String[] logStart = new String[1];
    final List<FlowNode> nodesOut = new ArrayList<FlowNode>();
    // Create thread that eventually interrupts Jenkins with a hard shutdown at a random time interval
    story.addStepWithDirtyShutdown(new Statement() {

        @Override
        public void evaluate() throws Throwable {
            Jenkins jenkins = story.j.jenkins;
            WorkflowJob job = jenkins.getItemByFullName(jobName, WorkflowJob.class);
            if (job == null) {
                // Job may already have been created
                job = jenkins.createProject(WorkflowJob.class, jobName);
                FlowDurabilityHint hint = FlowDurabilityHint.MAX_SURVIVABILITY;
                TestDurabilityHintProvider provider = Jenkins.getInstance().getExtensionList(TestDurabilityHintProvider.class).get(0);
                provider.registerHint(job.getFullName(), hint);
                job.setDefinition(new CpsFlowDefinition("echo 'first'\n" + "def steps = [:]\n" + "steps['1'] = {\n" + "    echo 'do 1 stuff'\n" + "}\n" + "steps['2'] = {\n" + "    echo '2a'\n" + "    echo '2b'\n" + "    def nested = [:]\n" + "    nested['2-1'] = {\n" + "        echo 'do 2-1'\n" + "    } \n" + "    nested['2-2'] = {\n" + "        sleep 1\n" + "        echo '2 section 2'\n" + "    }\n" + "    parallel nested\n" + "}\n" + "parallel steps\n" + "echo 'final'"));
            }
            story.j.buildAndAssertSuccess(job);
            long millisDuration = job.getLastBuild().getDuration();
            int time = new Random().nextInt((int) millisDuration);
            WorkflowRun run = job.scheduleBuild2(0).getStartCondition().get();
            Thread.sleep(time);
            logStart[0] = JenkinsRule.getLog(run);
            nodesOut.clear();
            nodesOut.addAll(new DepthFirstScanner().allNodes(run.getExecution()));
            nodesOut.sort(FlowScanningUtils.ID_ORDER_COMPARATOR);
        }
    });
    story.addStep(new Statement() {

        @Override
        public void evaluate() throws Throwable {
            WorkflowRun run = story.j.jenkins.getItemByFullName(jobName, WorkflowJob.class).getLastBuild();
            if (run.isBuilding()) {
                story.j.waitForCompletion(run);
                Assert.assertEquals(Result.SUCCESS, run.getResult());
            } else {
                verifyCompletedCleanly(story.j.jenkins, run);
            }
            assertIncludesNodes(nodesOut, run);
            story.j.assertLogContains(logStart[0], run);
        }
    });
}
Also used : Statement(org.junit.runners.model.Statement) ArrayList(java.util.ArrayList) FlowDurabilityHint(org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) DepthFirstScanner(org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner) Jenkins(jenkins.model.Jenkins) Random(java.util.Random) TestDurabilityHintProvider(org.jenkinsci.plugins.workflow.TestDurabilityHintProvider) WorkflowJob(org.jenkinsci.plugins.workflow.job.WorkflowJob) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 10 with DepthFirstScanner

use of org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner in project workflow-cps-plugin by jenkinsci.

the class FlowDurabilityTest method assertIncludesNodes.

/**
 * Verify that we retain and flowgraph start with the included nodes, which must be in sorted order
 */
void assertIncludesNodes(List<FlowNode> prefixNodes, WorkflowRun run) throws Exception {
    List<FlowNode> nodes = new DepthFirstScanner().allNodes(run.getExecution());
    nodes.sort(FlowScanningUtils.ID_ORDER_COMPARATOR);
    // Make sure we have the starting nodes at least
    assert prefixNodes.size() <= nodes.size();
    for (int i = 0; i < prefixNodes.size(); i++) {
        try {
            FlowNode match = prefixNodes.get(i);
            FlowNode after = nodes.get(i);
            Assert.assertEquals(match.getDisplayFunctionName(), after.getDisplayFunctionName());
        } catch (Exception ex) {
            throw new Exception("Error with flownode at index=" + i, ex);
        }
    }
}
Also used : FlowDurabilityHint(org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint) TimeoutException(java.util.concurrent.TimeoutException) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) DepthFirstScanner(org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner)

Aggregations

FlowNode (org.jenkinsci.plugins.workflow.graph.FlowNode)12 DepthFirstScanner (org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner)12 WorkflowRun (org.jenkinsci.plugins.workflow.job.WorkflowRun)9 Test (org.junit.Test)8 ArrayList (java.util.ArrayList)6 WorkflowJob (org.jenkinsci.plugins.workflow.job.WorkflowJob)5 Predicate (com.google.common.base.Predicate)4 ConfigFileBuildWrapper (org.jenkinsci.plugins.configfiles.buildwrapper.ConfigFileBuildWrapper)4 CpsFlowDefinition (org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition)4 FlowExecution (org.jenkinsci.plugins.workflow.flow.FlowExecution)4 NodeStepTypePredicate (org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate)4 FlowDurabilityHint (org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint)3 Statement (org.junit.runners.model.Statement)3 Action (hudson.model.Action)2 List (java.util.List)2 Jenkins (jenkins.model.Jenkins)2 Ignore (org.junit.Ignore)2 Issue (org.jvnet.hudson.test.Issue)2 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1 XmlFile (hudson.XmlFile)1