private TimingFlowNodeStorage createStorage() throws IOException { FlowNodeStorage wrappedStorage; FlowDurabilityHint hint = getDurabilityHint(); wrappedStorage = (hint.isPersistWithEveryStep()) ? new SimpleXStreamFlowNodeStorage(this, getStorageDir()) : new BulkFlowNodeStorage(this, getStorageDir()); return new TimingFlowNodeStorage(wrappedStorage); }
@Override public void evaluate() throws Throwable { WorkflowRun run = createAndRunSleeperJob(story.j.jenkins, "durableAgainstClean", FlowDurabilityHint.PERFORMANCE_OPTIMIZED); Assert.assertEquals(FlowDurabilityHint.PERFORMANCE_OPTIMIZED, run.getExecution().getDurabilityHint()); logStart[0] = JenkinsRule.getLog(run); CpsFlowExecution exec = (CpsFlowExecution)(run.getExecution()); // Ensure the storage file is unreadable try (FileChannel fis = new FileOutputStream(new File(exec.getStorageDir(), "flowNodeStore.xml")).getChannel()) { fis.truncate(5); // Leave a tiny bit just to make things more interesting } } });
@Test public void inProgressButFlowNodesLost() throws Exception { final int[] build = new int[1]; story.thenWithHardShutdown( j -> { WorkflowRun run = runBasicPauseOnInput(j, DEFAULT_JOBNAME, build); CpsFlowExecution cpsExec = (CpsFlowExecution)(run.getExecution()); FileUtils.deleteDirectory(((CpsFlowExecution)(run.getExecution())).getStorageDir()); }); story.then( j->{ WorkflowJob r = j.jenkins.getItemByFullName(DEFAULT_JOBNAME, WorkflowJob.class); WorkflowRun run = r.getBuildByNumber(build[0]); assertCompletedCleanly(run); }); }
/** Simulates something happening badly during final shutdown, which may cause build to not appear done. */ @Test public void completedFinalFlowNodeNotPersisted() throws Exception { final int[] build = new int[1]; final Result[] executionAndBuildResult = new Result[2]; story.thenWithHardShutdown( j -> { WorkflowRun run = runBasicBuild(j, DEFAULT_JOBNAME, build); String finalId = run.getExecution().getCurrentHeads().get(0).getId(); // Hack but deletes the file from disk CpsFlowExecution cpsExec = (CpsFlowExecution)(run.getExecution()); File f = new File(cpsExec.getStorageDir(), finalId+".xml"); f.delete(); executionAndBuildResult[0] = ((CpsFlowExecution)(run.getExecution())).getResult(); executionAndBuildResult[1] = run.getResult(); }); story.then(j-> { WorkflowJob r = j.jenkins.getItemByFullName(DEFAULT_JOBNAME, WorkflowJob.class); WorkflowRun run = r.getBuildByNumber(build[0]); assertCompletedCleanly(run); // assertNulledExecution(run); Assert.assertEquals(Result.SUCCESS, run.getResult()); assertResultMatchExecutionAndRun(run, executionAndBuildResult); }); } /** Perhaps there was a serialization error breaking the FlowGraph persistence for non-durable mode. */
/** Perhaps there was a serialization error breaking the FlowGraph persistence for non-durable mode. */ @Test public void completedNoNodesPersisted() throws Exception { final int[] build = new int[1]; final Result[] executionAndBuildResult = new Result[2]; story.thenWithHardShutdown( j -> { WorkflowRun run = runBasicBuild(j, DEFAULT_JOBNAME, build); FileUtils.deleteDirectory(((CpsFlowExecution)(run.getExecution())).getStorageDir()); executionAndBuildResult[0] = ((CpsFlowExecution)(run.getExecution())).getResult(); executionAndBuildResult[1] = run.getResult(); }); story.then(j-> { WorkflowJob r = j.jenkins.getItemByFullName(DEFAULT_JOBNAME, WorkflowJob.class); WorkflowRun run = r.getBuildByNumber(build[0]); assertCompletedCleanly(run); // assertNulledExecution(run); Assert.assertEquals(Result.SUCCESS, run.getResult()); assertResultMatchExecutionAndRun(run, executionAndBuildResult); }); }