Search in sources :

Example 1 with FlowEndNode

use of org.jenkinsci.plugins.workflow.graph.FlowEndNode in project workflow-cps-plugin by jenkinsci.

the class CpsFlowExecution method createPlaceholderNodes.

/**
 * In the event we're missing FlowNodes, fail-fast and create some mockup FlowNodes so we can continue.
 * This avoids nulling out all of the execution's data
 * Bypasses {@link #croak(Throwable)} and {@link #onProgramEnd(Outcome)} to guarantee a clean path.
 */
@GuardedBy("this")
void createPlaceholderNodes(Throwable failureReason) throws Exception {
    synchronized (this) {
        this.done = true;
        if (this.owner != null) {
            // Ensure that the Run is marked as completed (failed) if it isn't already so it won't show as running
            Queue.Executable ex = owner.getExecutable();
            if (ex instanceof Run) {
                Result res = ((Run) ex).getResult();
                setResult(res != null ? res : Result.FAILURE);
            }
        }
        programPromise = Futures.immediateFailedFuture(new IllegalStateException("Failed loading heads", failureReason));
        LOGGER.log(Level.INFO, "Creating placeholder flownodes for execution: " + this);
        if (this.owner != null) {
            try {
                owner.getListener().getLogger().println("Creating placeholder flownodes because failed loading originals.");
            } catch (Exception ex) {
            // It's okay to fail to log
            }
        }
        // Switch to fallback storage so we don't delete original node data
        this.storageDir = (this.storageDir != null) ? this.storageDir + "-fallback" : "workflow-fallback";
        // Empty storage
        this.storage = createStorage();
        // Clear out old start nodes and heads
        this.startNodes = new Stack<>();
        FlowHead head = new FlowHead(this);
        this.heads = new TreeMap<>();
        heads.put(head.getId(), head);
        FlowStartNode start = new FlowStartNode(this, iotaStr());
        head.newStartNode(start);
        // Create end
        FlowNode end = new FlowEndNode(this, iotaStr(), (FlowStartNode) startNodes.pop(), result, getCurrentHeads().toArray(new FlowNode[0]));
        end.addAction(new ErrorAction(failureReason));
        head.setNewHead(end);
    }
    saveOwner();
}
Also used : FlowStartNode(org.jenkinsci.plugins.workflow.graph.FlowStartNode) Run(hudson.model.Run) FlowEndNode(org.jenkinsci.plugins.workflow.graph.FlowEndNode) UsernameNotFoundException(org.acegisecurity.userdetails.UsernameNotFoundException) InterruptedIOException(java.io.InterruptedIOException) AbortException(hudson.AbortException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) FlowInterruptedException(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) Result(hudson.model.Result) ErrorAction(org.jenkinsci.plugins.workflow.actions.ErrorAction) Queue(hudson.model.Queue) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) GuardedBy(net.jcip.annotations.GuardedBy)

Example 2 with FlowEndNode

use of org.jenkinsci.plugins.workflow.graph.FlowEndNode in project workflow-cps-plugin by jenkinsci.

the class PersistenceProblemsTest method assertCompletedCleanly.

/**
 * Verifies all the assumptions about a cleanly finished build.
 */
static void assertCompletedCleanly(WorkflowRun run) throws Exception {
    while (run.isBuilding()) {
        // TODO seems to be unpredictable
        Thread.sleep(100);
    }
    Assert.assertNotNull(run.getResult());
    FlowExecution fe = run.getExecution();
    FlowExecutionList.get().forEach(f -> {
        if (fe != null && f == fe) {
            Assert.fail("FlowExecution still in FlowExecutionList!");
        }
    });
    Assert.assertTrue("Queue not empty after completion!", Queue.getInstance().isEmpty());
    if (fe instanceof CpsFlowExecution) {
        CpsFlowExecution cpsExec = (CpsFlowExecution) fe;
        Assert.assertTrue(cpsExec.isComplete());
        Assert.assertEquals(Boolean.TRUE, cpsExec.done);
        Assert.assertEquals(1, cpsExec.getCurrentHeads().size());
        Assert.assertTrue(cpsExec.isComplete());
        Assert.assertTrue(cpsExec.getCurrentHeads().get(0) instanceof FlowEndNode);
        Assert.assertTrue(cpsExec.startNodes == null || cpsExec.startNodes.isEmpty());
        while (cpsExec.blocksRestart()) {
            // TODO ditto
            Thread.sleep(100);
        }
    } else {
        System.out.println("WARNING: no FlowExecutionForBuild");
    }
}
Also used : FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) FlowEndNode(org.jenkinsci.plugins.workflow.graph.FlowEndNode)

Example 3 with FlowEndNode

use of org.jenkinsci.plugins.workflow.graph.FlowEndNode in project selenium_java by sergueik.

the class Audit2DbGraphListener method onNewHead.

@Override
public void onNewHead(FlowNode node) {
    if (!FlowEndNode.class.isInstance(node)) {
        return;
    }
    LOGGER.fine("Found the FlowEndNode.");
    FlowExecution execution = node.getExecution();
    LOGGER.fine("FlowExecution.isComplete: " + execution.isComplete());
    if (!CpsFlowExecution.class.isInstance(execution)) {
        throw new IllegalStateException("Cannot get a pipeline result from a FlowExecution that is not an instance of CpsFlowExecution: " + execution.getClass().getName());
    }
    CpsFlowExecution cpsFlowExecution = (CpsFlowExecution) execution;
    LOGGER.fine("CpsFlowExecution.result: " + cpsFlowExecution.getResult());
    BuildDetailsResolver.updateResultAndEndTime(details, cpsFlowExecution, new Date());
    LOGGER.fine("Persisting BuildDetails");
    repository.saveBuildDetails(details);
    LOGGER.fine("Audit2DbGraphListener.onNewHead(): complete");
}
Also used : CpsFlowExecution(org.jenkinsci.plugins.workflow.cps.CpsFlowExecution) FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) FlowEndNode(org.jenkinsci.plugins.workflow.graph.FlowEndNode) CpsFlowExecution(org.jenkinsci.plugins.workflow.cps.CpsFlowExecution) Date(java.util.Date)

Example 4 with FlowEndNode

use of org.jenkinsci.plugins.workflow.graph.FlowEndNode in project workflow-cps-plugin by jenkinsci.

the class CpsFlowExecution method onProgramEnd.

/**
 * Record the end of the build.  Note: we should always follow this with a call to {@link #saveOwner()} to persist the result.
 * @param outcome success; or a normal failure (uncaught exception); or a fatal error in VM machinery
 */
synchronized void onProgramEnd(Outcome outcome) {
    FlowNode head = new FlowEndNode(this, iotaStr(), (FlowStartNode) startNodes.pop(), result, getCurrentHeads().toArray(new FlowNode[0]));
    if (outcome.isFailure()) {
        head.addAction(new ErrorAction(outcome.getAbnormal()));
    }
    // shrink everything into a single new head
    try {
        if (heads != null) {
            FlowHead first = getFirstHead();
            first.setNewHead(head);
            // After setting the final head
            done = true;
            heads.clear();
            heads.put(first.getId(), first);
            String tempIotaStr = Integer.toString(this.iota.get());
            FlowHead lastHead = heads.get(first.getId());
            if (lastHead == null || lastHead.get() == null || !(lastHead.get().getId().equals(tempIotaStr))) {
                // Warning of problems with the final call to FlowHead.setNewHead
                LOGGER.log(Level.WARNING, "Invalid final head for execution " + this.owner + " with head: " + lastHead);
            }
        }
    } catch (Exception ex) {
        done = true;
        LOGGER.log(Level.WARNING, "Error trying to end execution " + this, ex);
    }
    try {
        this.getStorage().flush();
    } catch (IOException ioe) {
        LOGGER.log(Level.WARNING, "Error flushing FlowNodeStorage to disk at end of run", ioe);
    }
    this.persistedClean = Boolean.TRUE;
}
Also used : ErrorAction(org.jenkinsci.plugins.workflow.actions.ErrorAction) FlowEndNode(org.jenkinsci.plugins.workflow.graph.FlowEndNode) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) UsernameNotFoundException(org.acegisecurity.userdetails.UsernameNotFoundException) InterruptedIOException(java.io.InterruptedIOException) AbortException(hudson.AbortException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) FlowInterruptedException(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 5 with FlowEndNode

use of org.jenkinsci.plugins.workflow.graph.FlowEndNode in project workflow-cps-plugin by jenkinsci.

the class FlowDurabilityTest method verifyCompletedCleanly.

/**
 * Verifies all the universal post-build cleanup was done, regardless of pass/fail state.
 */
static void verifyCompletedCleanly(Jenkins j, WorkflowRun run) throws Exception {
    // Assert that we have the appropriate flow graph entries
    FlowExecution exec = run.getExecution();
    List<FlowNode> heads = exec.getCurrentHeads();
    Assert.assertEquals(1, heads.size());
    verifyNoTasksRunning(j);
    Assert.assertEquals(0, exec.getCurrentExecutions(false).get().size());
    if (exec instanceof CpsFlowExecution) {
        CpsFlowExecution cpsFlow = (CpsFlowExecution) exec;
        assert cpsFlow.getStorage() != null;
        Assert.assertFalse("Should always be able to retrieve script", StringUtils.isEmpty(cpsFlow.getScript()));
        Assert.assertNull("We should have no Groovy shell left or that's a memory leak", cpsFlow.getShell());
        Assert.assertNull("We should have no Groovy shell left or that's a memory leak", cpsFlow.getTrustedShell());
        Assert.assertTrue(cpsFlow.done);
        assert cpsFlow.isComplete();
        assert cpsFlow.heads.size() == 1;
        Map.Entry<Integer, FlowHead> finalHead = cpsFlow.heads.entrySet().iterator().next();
        assert finalHead.getValue().get() instanceof FlowEndNode;
        Assert.assertEquals(cpsFlow.storage.getNode(finalHead.getValue().get().getId()), finalHead.getValue().get());
    }
    verifyExecutionRemoved(run);
}
Also used : FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) FlowEndNode(org.jenkinsci.plugins.workflow.graph.FlowEndNode) Map(java.util.Map) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Aggregations

FlowEndNode (org.jenkinsci.plugins.workflow.graph.FlowEndNode)6 FlowExecution (org.jenkinsci.plugins.workflow.flow.FlowExecution)4 FlowNode (org.jenkinsci.plugins.workflow.graph.FlowNode)3 AbortException (hudson.AbortException)2 IOException (java.io.IOException)2 InterruptedIOException (java.io.InterruptedIOException)2 ExecutionException (java.util.concurrent.ExecutionException)2 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 UsernameNotFoundException (org.acegisecurity.userdetails.UsernameNotFoundException)2 ErrorAction (org.jenkinsci.plugins.workflow.actions.ErrorAction)2 FlowInterruptedException (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException)2 Queue (hudson.model.Queue)1 Result (hudson.model.Result)1 Run (hudson.model.Run)1 Date (java.util.Date)1 Map (java.util.Map)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 GuardedBy (net.jcip.annotations.GuardedBy)1 CpsFlowExecution (org.jenkinsci.plugins.workflow.cps.CpsFlowExecution)1