/** Stores FlowNode with write deferred */ void cacheNode(@Nonnull FlowNode node) { try { getStorage().storeNode(node, true); } catch (IOException ioe) { LOGGER.log(Level.WARNING, "Attempt to persist triggered IOException for node "+node.getId(), ioe); } }
static void assertBaseStorageType(FlowExecution exec, Class<? extends FlowNodeStorage> storageClass) throws Exception { if (exec instanceof CpsFlowExecution) { FlowNodeStorage store = ((CpsFlowExecution) exec).getStorage(); if (store instanceof CpsFlowExecution.TimingFlowNodeStorage) { Field f = CpsFlowExecution.TimingFlowNodeStorage.class.getDeclaredField("delegate"); f.setAccessible(true); FlowNodeStorage delegateStore = (FlowNodeStorage)(f.get(store)); Assert.assertEquals(storageClass.toString(), delegateStore.getClass().toString()); } } }
/** Invoke me to toggle autopersist back on for steps that delay it. */ public static void maybeAutoPersistNode(@Nonnull FlowNode node) { try { FlowExecution exec = node.getExecution(); if (exec instanceof CpsFlowExecution) { if (exec.getDurabilityHint().isPersistWithEveryStep()) { FlowNodeStorage exc = ((CpsFlowExecution) exec).getStorage(); exc.autopersist(node); } } } catch (IOException ioe) { LOGGER.log(Level.WARNING, "Attempt to persist triggered IOException for node "+node.getId(), ioe); } }
@Override public void onSuccess(CpsThreadGroup result) { try { // TODO keep track of whether the program was saved anyway after saveState was called but before now, and do not bother resaving it in that case if (result.getExecution().getDurabilityHint().isPersistWithEveryStep()) { result.getExecution().getStorage().flush(); result.saveProgram(); } f.set(null); } catch (Exception x) { f.setException(x); } } @Override public void onFailure(Throwable t) {
FlowNodeStorage storage = getStorage(); if (storage != null) { try { // Node storage must be flushed first so program can be restored
/** * Like {@link #saveProgram()} but will not fail. * @param enteringQuietState True if we're moving to quiet state - pausing or quieting down and need to write the program. */ @CpsVmThreadOnly void saveProgramIfPossible(boolean enteringQuietState) { if (this.getExecution() != null && (this.getExecution().getDurabilityHint().isPersistWithEveryStep() || enteringQuietState)) { try { // Program may depend on flownodes being saved, so save nodes FlowNodeStorage storage = this.execution.getStorage(); if (storage != null) { storage.flush(); } } catch (IOException ioe) { LOGGER.log(Level.WARNING, "Error persisting FlowNode storage before saving program", ioe); } try { saveProgram(); } catch (IOException x) { LOGGER.log(WARNING, "program state save failed", x); } } }
this.getStorage().flush(); } catch (IOException ioe) { LOGGER.log(Level.WARNING, "Error flushing FlowNodeStorage to disk at end of run", ioe);
@Override public void evaluate() throws Throwable { Jenkins jenkins = story.j.jenkins; WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, jobName, FlowDurabilityHint.MAX_SURVIVABILITY); FlowExecution exec = run.getExecution(); if (exec instanceof CpsFlowExecution) { assert ((CpsFlowExecution) exec).getStorage().isPersistedFully(); } logStart[0] = JenkinsRule.getLog(run); } });
@Override public void evaluate() throws Throwable { Jenkins jenkins = story.j.jenkins; WorkflowRun run = createAndRunBasicJob(story.j.jenkins, jobName, FlowDurabilityHint.MAX_SURVIVABILITY); FlowExecution exec = run.getExecution(); if (exec instanceof CpsFlowExecution) { assert ((CpsFlowExecution) exec).getStorage().isPersistedFully(); } logStart[0] = JenkinsRule.getLog(run); } });
if (!(execution instanceof CpsFlowExecution) || !(((CpsFlowExecution)execution).getStorage() instanceof SimpleXStreamFlowNodeStorage)) { return; // Test is unfortunately coupled to the implementation -- otherwise it will simply hit caches SimpleXStreamFlowNodeStorage storage = (SimpleXStreamFlowNodeStorage)(((CpsFlowExecution)execution).getStorage()); Method getFileM = SimpleXStreamFlowNodeStorage.class.getDeclaredMethod("getNodeFile", String.class); getFileM.setAccessible(true);
@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); } });
/** 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); }
@Override public void evaluate() throws Throwable { Jenkins jenkins = story.j.jenkins; WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, jobName, FlowDurabilityHint.MAX_SURVIVABILITY); run.getParent().setResumeBlocked(false); 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); run.getParent().setResumeBlocked(true); } });