Search in sources :

Example 1 with FlowNode

use of org.jenkinsci.plugins.workflow.graph.FlowNode in project blueocean-plugin by jenkinsci.

the class PipelineNodeGraphVisitor method parallelStart.

@Override
public void parallelStart(@Nonnull FlowNode parallelStartNode, @Nonnull FlowNode branchNode, @Nonnull ForkScanner scanner) {
    if (isNodeVisitorDumpEnabled) {
        dump(String.format("parallelStart=> id: %s, name: %s, function: %s", parallelStartNode.getId(), parallelStartNode.getDisplayName(), parallelStartNode.getDisplayFunctionName()));
        dump(String.format("\tbranch=> id: %s, name: %s, function: %s", branchNode.getId(), branchNode.getDisplayName(), branchNode.getDisplayFunctionName()));
    }
    if (nestedbranches.size() != parallelBranchEndNodes.size()) {
        logger.error(String.format("nestedBranches size: %s not equal to parallelBranchEndNodes: %s", nestedbranches.size(), parallelBranchEndNodes.size()));
        return;
    }
    while (!nestedbranches.empty() && !parallelBranchEndNodes.empty()) {
        FlowNode branchStartNode = nestedbranches.pop();
        FlowNode endNode = parallelBranchEndNodes.pop();
        TimingInfo times;
        NodeRunStatus status;
        if (endNode != null) {
            times = StatusAndTiming.computeChunkTiming(run, chunk.getPauseTimeMillis(), branchStartNode, endNode, chunk.getNodeAfter());
            if (endNode instanceof StepAtomNode) {
                if (PipelineNodeUtil.isPausedForInputStep((StepAtomNode) endNode, inputAction)) {
                    status = new NodeRunStatus(BlueRun.BlueRunResult.UNKNOWN, BlueRun.BlueRunState.PAUSED);
                } else {
                    status = new NodeRunStatus(endNode);
                }
            } else {
                GenericStatus genericStatus = StatusAndTiming.computeChunkStatus(run, parallelStartNode, branchStartNode, endNode, parallelEnd);
                status = new NodeRunStatus(genericStatus);
            }
        } else {
            times = new TimingInfo(TimingAction.getStartTime(branchStartNode) + System.currentTimeMillis(), chunk.getPauseTimeMillis(), TimingAction.getStartTime(branchStartNode));
            status = new NodeRunStatus(BlueRun.BlueRunResult.UNKNOWN, BlueRun.BlueRunState.RUNNING);
        }
        FlowNodeWrapper branch = new FlowNodeWrapper(branchStartNode, status, times, run);
        if (nextStage != null) {
            branch.addEdge(nextStage.getId());
        }
        parallelBranches.push(branch);
    }
    FlowNodeWrapper[] sortedBranches = parallelBranches.toArray(new FlowNodeWrapper[parallelBranches.size()]);
    Arrays.sort(sortedBranches, new Comparator<FlowNodeWrapper>() {

        @Override
        public int compare(FlowNodeWrapper o1, FlowNodeWrapper o2) {
            return o1.getDisplayName().compareTo(o2.getDisplayName());
        }
    });
    parallelBranches.clear();
    for (int i = 0; i < sortedBranches.length; i++) {
        parallelBranches.push(sortedBranches[i]);
    }
    for (FlowNodeWrapper p : parallelBranches) {
        nodes.push(p);
        nodeMap.put(p.getId(), p);
    }
    //reset parallelEnd node for next parallel block
    this.parallelEnd = null;
}
Also used : GenericStatus(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.GenericStatus) TimingInfo(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.TimingInfo) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 2 with FlowNode

use of org.jenkinsci.plugins.workflow.graph.FlowNode in project blueocean-plugin by jenkinsci.

the class PipelineNodeGraphVisitor method getPipelineNodeSteps.

@Override
public List<BluePipelineStep> getPipelineNodeSteps(final String nodeId, Link parent) {
    DepthFirstScanner depthFirstScanner = new DepthFirstScanner();
    if (run.getExecution() == null) {
        logger.debug(String.format("Pipeline %s, runid %s  has null execution", run.getParent().getName(), run.getId()));
        return Collections.emptyList();
    }
    //If blocked scope, get the end node
    FlowNode n = depthFirstScanner.findFirstMatch(run.getExecution().getCurrentHeads(), new Predicate<FlowNode>() {

        @Override
        public boolean apply(@Nullable FlowNode input) {
            return (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(run.getExecution().getCurrentHeads(), visitor, new StageChunkFinder());
    List<BluePipelineStep> steps = new ArrayList<>();
    for (FlowNodeWrapper node : visitor.getSteps()) {
        steps.add(new PipelineStepImpl(node, parent));
    }
    return steps;
}
Also used : StageChunkFinder(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StageChunkFinder) ArrayList(java.util.ArrayList) BluePipelineStep(io.jenkins.blueocean.rest.model.BluePipelineStep) DepthFirstScanner(org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 3 with FlowNode

use of org.jenkinsci.plugins.workflow.graph.FlowNode in project blueocean-plugin by jenkinsci.

the class PipelineStepVisitor method handleChunkDone.

@Override
protected void handleChunkDone(@Nonnull MemoryFlowChunk chunk) {
    if (stageStepsCollectionCompleted) {
        //if its completed no further action
        return;
    }
    if (node != null && chunk.getFirstNode().equals(node)) {
        stageStepsCollectionCompleted = true;
        inStageScope = false;
        try {
            final String cause = PipelineNodeUtil.getCauseOfBlockage(chunk.getFirstNode(), agentNode, run);
            if (cause != null) {
                //Now add a step that indicates bloackage cause
                FlowNode step = new AtomNode(chunk.getFirstNode().getExecution(), UUID.randomUUID().toString(), chunk.getFirstNode()) {

                    @Override
                    protected String getTypeDisplayName() {
                        return cause;
                    }
                };
                FlowNodeWrapper stepNode = new FlowNodeWrapper(step, new NodeRunStatus(BlueRun.BlueRunResult.UNKNOWN, BlueRun.BlueRunState.QUEUED), new TimingInfo(), run);
                steps.push(stepNode);
                stepMap.put(step.getId(), stepNode);
            }
        } catch (IOException | InterruptedException e) {
            //log the error but don't fail. This is better as in worst case all we will lose is blockage cause of a node.
            logger.error(String.format("Error trying to get blockage status of pipeline: %s, runId: %s node block: %s. %s", run.getParent().getFullName(), run.getId(), agentNode, e.getMessage()), e);
        }
    }
    if (node != null && PipelineNodeUtil.isStage(node) && !inStageScope && !chunk.getFirstNode().equals(node)) {
        resetSteps();
    }
}
Also used : TimingInfo(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.TimingInfo) IOException(java.io.IOException) AtomNode(org.jenkinsci.plugins.workflow.graph.AtomNode) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 4 with FlowNode

use of org.jenkinsci.plugins.workflow.graph.FlowNode in project blueocean-plugin by jenkinsci.

the class PipelineStepVisitor method atomNode.

@Override
public void atomNode(@CheckForNull FlowNode before, @Nonnull FlowNode atomNode, @CheckForNull FlowNode after, @Nonnull ForkScanner scan) {
    if (stageStepsCollectionCompleted && !PipelineNodeUtil.isSyntheticStage(currentStage)) {
        return;
    }
    if (atomNode instanceof StepEndNode) {
        this.closestEndNode = (StepEndNode) atomNode;
    }
    if (atomNode instanceof StepAtomNode && !PipelineNodeUtil.isSkippedStage(currentStage)) {
        //if skipped stage, we don't collect its steps
        long pause = PauseAction.getPauseDuration(atomNode);
        chunk.setPauseTimeMillis(chunk.getPauseTimeMillis() + pause);
        TimingInfo times = StatusAndTiming.computeChunkTiming(run, pause, atomNode, atomNode, after);
        if (times == null) {
            times = new TimingInfo();
        }
        NodeRunStatus status;
        InputStep inputStep = null;
        if (PipelineNodeUtil.isPausedForInputStep((StepAtomNode) atomNode, inputAction)) {
            status = new NodeRunStatus(BlueRun.BlueRunResult.UNKNOWN, BlueRun.BlueRunState.PAUSED);
            try {
                for (InputStepExecution execution : inputAction.getExecutions()) {
                    FlowNode node = execution.getContext().get(FlowNode.class);
                    if (node != null && node.equals(atomNode)) {
                        inputStep = execution.getInput();
                        break;
                    }
                }
            } catch (IOException | InterruptedException | TimeoutException e) {
                logger.error("Error getting FlowNode from execution context: " + e.getMessage(), e);
            }
        } else {
            status = new NodeRunStatus(atomNode);
        }
        FlowNodeWrapper node = new FlowNodeWrapper(atomNode, status, times, inputStep, run);
        if (PipelineNodeUtil.isPreSyntheticStage(currentStage)) {
            preSteps.add(node);
        } else if (PipelineNodeUtil.isPostSyntheticStage(currentStage)) {
            postSteps.add(node);
        } else {
            if (!steps.contains(node)) {
                steps.push(node);
            }
        }
        stepMap.put(node.getId(), node);
        //If there is closest block boundary, we capture it's error to the last step encountered and prepare for next block.
        if (closestEndNode != null && closestEndNode.getError() != null) {
            node.setBlockErrorAction(closestEndNode.getError());
            //prepare for next block
            closestEndNode = null;
        }
    }
}
Also used : TimingInfo(org.jenkinsci.plugins.workflow.pipelinegraphanalysis.TimingInfo) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) IOException(java.io.IOException) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) InputStepExecution(org.jenkinsci.plugins.workflow.support.steps.input.InputStepExecution) InputStep(org.jenkinsci.plugins.workflow.support.steps.input.InputStep) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) TimeoutException(java.util.concurrent.TimeoutException)

Example 5 with FlowNode

use of org.jenkinsci.plugins.workflow.graph.FlowNode in project blueocean-plugin by jenkinsci.

the class PipelineNodeTest method declarativeSyntheticSteps.

@Test
public void declarativeSyntheticSteps() throws Exception {
    setupScm("pipeline {\n" + "    agent any\n" + "    stages {\n" + "        stage(\"build\") {\n" + "            steps{\n" + "              sh 'echo \"Start Build\"'\n" + "              echo 'End Build'\n" + "            }\n" + "        }\n" + "        stage(\"deploy\") {\n" + "            steps{\n" + "              sh 'echo \"Start Deploy\"'\n" + "              sh 'echo \"Deploying...\"'\n" + "              sh 'echo \"End Deploy\"'\n" + "            }           \n" + "        }\n" + "    }\n" + "    post {\n" + "        failure {\n" + "            echo \"failed\"\n" + "        }\n" + "        success {\n" + "            echo \"success\"\n" + "        }\n" + "    }\n" + "}");
    WorkflowMultiBranchProject mp = j.jenkins.createProject(WorkflowMultiBranchProject.class, "p");
    mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false)));
    for (SCMSource source : mp.getSCMSources()) {
        assertEquals(mp, source.getOwner());
    }
    mp.scheduleBuild2(0).getFuture().get();
    j.waitUntilNoActivity();
    WorkflowJob p = scheduleAndFindBranchProject(mp, "master");
    j.waitUntilNoActivity();
    WorkflowRun b1 = p.getLastBuild();
    Assert.assertEquals(Result.SUCCESS, b1.getResult());
    List<FlowNode> stages = getStages(NodeGraphBuilder.NodeGraphBuilderFactory.getInstance(b1));
    Assert.assertEquals(2, stages.size());
    Assert.assertEquals("build", stages.get(0).getDisplayName());
    Assert.assertEquals("deploy", stages.get(1).getDisplayName());
    List<Map> resp = get("/organizations/jenkins/pipelines/p/pipelines/master/runs/" + b1.getId() + "/nodes/", List.class);
    Assert.assertEquals(2, resp.size());
    Assert.assertEquals("build", resp.get(0).get("displayName"));
    Assert.assertEquals("deploy", resp.get(1).get("displayName"));
    resp = get("/organizations/jenkins/pipelines/p/pipelines/master/runs/" + b1.getId() + "/steps/", List.class);
    Assert.assertEquals(7, resp.size());
    resp = get("/organizations/jenkins/pipelines/p/pipelines/master/runs/" + b1.getId() + "/nodes/" + stages.get(0).getId() + "/steps/", List.class);
    Assert.assertEquals(3, resp.size());
    resp = get("/organizations/jenkins/pipelines/p/pipelines/master/runs/" + b1.getId() + "/nodes/" + stages.get(1).getId() + "/steps/", List.class);
    Assert.assertEquals(4, resp.size());
}
Also used : WorkflowMultiBranchProject(org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject) RunList(hudson.util.RunList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) GitSCMSource(jenkins.plugins.git.GitSCMSource) SCMSource(jenkins.scm.api.SCMSource) GitSCMSource(jenkins.plugins.git.GitSCMSource) BranchSource(jenkins.branch.BranchSource) WorkflowJob(org.jenkinsci.plugins.workflow.job.WorkflowJob) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) Test(org.junit.Test)

Aggregations

FlowNode (org.jenkinsci.plugins.workflow.graph.FlowNode)22 WorkflowRun (org.jenkinsci.plugins.workflow.job.WorkflowRun)14 WorkflowJob (org.jenkinsci.plugins.workflow.job.WorkflowJob)13 Test (org.junit.Test)13 ImmutableMap (com.google.common.collect.ImmutableMap)12 Map (java.util.Map)12 CpsFlowDefinition (org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition)11 ImmutableList (com.google.common.collect.ImmutableList)9 RunList (hudson.util.RunList)9 List (java.util.List)9 StepAtomNode (org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode)4 TimingInfo (org.jenkinsci.plugins.workflow.pipelinegraphanalysis.TimingInfo)4 FlowGraphTable (org.jenkinsci.plugins.workflow.support.visualization.table.FlowGraphTable)4 BlueRun (io.jenkins.blueocean.rest.model.BlueRun)3 BluePipelineStep (io.jenkins.blueocean.rest.model.BluePipelineStep)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 BranchSource (jenkins.branch.BranchSource)2 GitSCMSource (jenkins.plugins.git.GitSCMSource)2 SCMSource (jenkins.scm.api.SCMSource)2