@Issue("JENKINS-45455") @Test public void stashWithSpecifiedPropertyValue() throws Exception { WorkflowRun r = expect("properties", "stashWithSpecifiedPropertyValue") .go(); assertFalse(StashManager.stashesOf(r).isEmpty()); WorkflowJob p = r.getParent(); assertNotNull(p); // Build 4 times to make sure get 5 total builds. for (int i = 0; i < 4; i++) { j.buildAndAssertSuccess(p); } // The first three builds shouldn't have stashes any more. assertTrue(StashManager.stashesOf(p.getBuildByNumber(1)).isEmpty()); assertTrue(StashManager.stashesOf(p.getBuildByNumber(2)).isEmpty()); assertTrue(StashManager.stashesOf(p.getBuildByNumber(3)).isEmpty()); // The last two should still have stashes assertFalse(StashManager.stashesOf(p.getBuildByNumber(4)).isEmpty()); assertFalse(StashManager.stashesOf(p.getBuildByNumber(5)).isEmpty()); }
@Override public void evaluate() throws Throwable { WorkflowJob p = story.j.jenkins.getItemByFullName("p", WorkflowJob.class); WorkflowRun b = p.getBuildByNumber(1); SemaphoreStep.success("wait/1", null); story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b)); } });
@Override public void evaluate() throws Throwable { WorkflowJob p = jenkins.getItemByFullName("p", WorkflowJob.class); WorkflowRun b = p.getBuildByNumber(1); // resume from where it left off SemaphoreStep.success("watchB/1", null); story.j.waitForCompletion(b); story.j.assertBuildStatusSuccess(b); story.j.assertLogContains("o=42", b); } });
@Override public void evaluate() throws Throwable { WorkflowJob p = jenkins.getItemByFullName("p", WorkflowJob.class); WorkflowRun b = p.getBuildByNumber(1); // resume from where it left off SemaphoreStep.success("watchA/1", null); story.j.waitForCompletion(b); story.j.assertBuildStatusSuccess(b); story.j.assertLogContains("o=42", b); } });
@Override public void evaluate() throws Throwable { WorkflowJob p = rr.j.jenkins.getItemByFullName("p", WorkflowJob.class); WorkflowRun b = p.getBuildByNumber(1); SemaphoreStep.success("wait/1", null); rr.j.assertBuildStatusSuccess(rr.j.waitForCompletion(b)); SemaphoreStep.success("wait/2", null); rr.j.buildAndAssertSuccess(p); } });
@Test /** Build okay but program fails to load */ public void inProgressButProgramLoadFailure() throws Exception { final int[] build = new int[1]; story.thenWithHardShutdown( j -> { WorkflowRun run = runBasicPauseOnInput(j, DEFAULT_JOBNAME, build); CpsFlowExecution cpsExec = (CpsFlowExecution)(run.getExecution()); cpsExec.getProgramDataFile().delete(); }); story.then( j->{ WorkflowJob r = j.jenkins.getItemByFullName(DEFAULT_JOBNAME, WorkflowJob.class); WorkflowRun run = r.getBuildByNumber(build[0]); assertCompletedCleanly(run); }); }
@Override public void evaluate() throws Throwable { WorkflowJob p = rr.j.jenkins.getItemByFullName("p", WorkflowJob.class); assertNotNull(p); WorkflowRun b = p.getBuildByNumber(1); SemaphoreStep.success("wait/1", null); rr.j.assertBuildStatusSuccess(rr.j.waitForCompletion(b)); SemaphoreStep.success("wait/2", null); rr.j.buildAndAssertSuccess(p); } });
@Issue("JENKINS-45455") @Test public void stashWithDefaultPropertyValue() throws Exception { WorkflowRun r = expect("properties", "stashWithDefaultPropertyValue") .go(); assertFalse(StashManager.stashesOf(r).isEmpty()); WorkflowJob p = r.getParent(); assertNotNull(p); j.buildAndAssertSuccess(p); // Now that we've run 11 builds, the first one shouldn't have a stash any more. assertTrue(StashManager.stashesOf(r).isEmpty()); // And build 2 should still have stashes. WorkflowRun laterRun = p.getBuildByNumber(2); assertNotNull(laterRun); assertFalse(StashManager.stashesOf(laterRun).isEmpty()); }
@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); }); }
@Test /** Build okay but then the start nodes get screwed up */ public void inProgressButStartBlocksLost() throws Exception { final int[] build = new int[1]; story.thenWithHardShutdown( j -> { WorkflowRun run = runBasicPauseOnInput(j, DEFAULT_JOBNAME, build); CpsFlowExecution cpsExec = (CpsFlowExecution)(run.getExecution()); cpsExec.startNodes.push(new FlowStartNode(cpsExec, cpsExec.iotaStr())); run.save(); }); story.then( j->{ WorkflowJob r = j.jenkins.getItemByFullName(DEFAULT_JOBNAME, WorkflowJob.class); WorkflowRun run = r.getBuildByNumber(build[0]); assertCompletedCleanly(run); }); }
@Issue("JENKINS-45455") @Test public void stashAndRestart() throws Exception { WorkflowRun original = expect(Result.FAILURE, "restart", "stashAndRestart").go(); WorkflowJob p = original.getParent(); HtmlPage redirect = restartFromStageInUI(original, "restart"); assertNotNull(redirect); assertEquals(p.getAbsoluteUrl(), redirect.getUrl().toString()); j.waitUntilNoActivity(); WorkflowRun b2 = p.getBuildByNumber(2); assertNotNull(b2); j.assertBuildStatusSuccess(b2); j.assertLogContains("Even numbered build, success", b2); j.assertLogContains("Stage \"pre-restart\" skipped due to this build restarting at stage \"restart\"", b2); j.assertLogContains("someFile is some text", b2); }
/** 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); }); }
@Override public void evaluate() throws Throwable { WorkflowJob p = jenkins.getItemByFullName("p", WorkflowJob.class); WorkflowRun b = p.getBuildByNumber(2); SemaphoreStep.success("wait/1", null); story.j.assertLogContains("a ran on value from b", story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b))); // Better case: jenkins.getWorkspaceFor(p).child("b.groovy").write("def m(a, arg) {a(\"${arg} from b\")}; this", null); p.setDefinition(new CpsFlowDefinition("def a; def b; node {a = load 'a.groovy'; b = load 'b.groovy'}; b.m(a, 'value')", true)); story.j.assertLogContains("a ran on value from b", story.j.assertBuildStatusSuccess(p.scheduleBuild2(0))); } });
@Test public void runInPodWithRestartWithMultipleContainerCalls() throws Exception { story.then(r -> { configureCloud(); r.jenkins.addNode(new DumbSlave("slave", "dummy", tmp.newFolder("remoteFS").getPath(), "1", Node.Mode.NORMAL, "", new JNLPLauncher(), RetentionStrategy.NOOP, Collections.<NodeProperty<?>>emptyList())); // TODO JENKINS-26398 clumsy WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition(loadPipelineScript("runInPodWithRestartWithMultipleContainerCalls.groovy") , true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); // we need to wait until we are sure that the sh // step has started... r.waitForMessage("+ sleep 5", b); }); story.then(r -> { WorkflowRun b = r.jenkins.getItemByFullName("p", WorkflowJob.class).getBuildByNumber(1); r.assertLogContains("finished the test!", r.assertBuildStatusSuccess(r.waitForCompletion(b))); }); }
@Test public void runInPodWithRestart() throws Exception { story.then(r -> { configureCloud(); r.jenkins.addNode(new DumbSlave("slave", "dummy", tmp.newFolder("remoteFS").getPath(), "1", Node.Mode.NORMAL, "", new JNLPLauncher(), RetentionStrategy.NOOP, Collections.<NodeProperty<?>>emptyList())); // TODO JENKINS-26398 clumsy WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition(loadPipelineScript("runInPodWithRestartWithLongSleep.groovy") , true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); // we need to wait until we are sure that the sh // step has started... r.waitForMessage("+ sleep 5", b); }); story.then(r -> { WorkflowRun b = r.jenkins.getItemByFullName("p", WorkflowJob.class).getBuildByNumber(1); r.assertLogContains("finished the test!", r.assertBuildStatusSuccess(r.waitForCompletion(b))); }); }
@Issue("JENKINS-45455") @Test public void isRestartedRunCondition() throws Exception { WorkflowRun original = expect("restart", "isRestartedRunCondition") .logContains("This shouldn't show up on second run") .logNotContains("This should only run on restart") .go(); WorkflowJob p = original.getParent(); HtmlPage redirect = restartFromStageInUI(original, "restart"); assertNotNull(redirect); assertEquals(p.getAbsoluteUrl(), redirect.getUrl().toString()); j.waitUntilNoActivity(); WorkflowRun b2 = p.getBuildByNumber(2); assertNotNull(b2); j.assertBuildStatusSuccess(b2); j.assertLogContains("This should only run on restart", b2); j.assertLogNotContains("This shouldn't show up on second run", b2); }
@Test public void inProgressNormal() throws Exception { final int[] build = new int[1]; story.then( j -> { WorkflowRun run = runBasicPauseOnInput(j, DEFAULT_JOBNAME, build); }); story.then( j->{ WorkflowJob r = j.jenkins.getItemByFullName(DEFAULT_JOBNAME, WorkflowJob.class); WorkflowRun run = r.getBuildByNumber(build[0]); assertCleanInProgress(run); InputStepExecution exec = getInputStepExecution(run, "pause"); exec.doProceedEmpty(); j.waitForCompletion(run); assertCompletedCleanly(run); Assert.assertEquals(Result.SUCCESS, run.getResult()); }); }
@Test @Ignore public void inProgressMaxPerfCleanShutdown() throws Exception { final int[] build = new int[1]; story.then( j -> { WorkflowRun run = runBasicPauseOnInput(j, DEFAULT_JOBNAME, build, FlowDurabilityHint.PERFORMANCE_OPTIMIZED); // SHOULD still save at end via persist-at-shutdown hooks }); story.then( j->{ WorkflowJob r = j.jenkins.getItemByFullName(DEFAULT_JOBNAME, WorkflowJob.class); WorkflowRun run = r.getBuildByNumber(build[0]); assertCleanInProgress(run); InputStepExecution exec = getInputStepExecution(run, "pause"); exec.doProceedEmpty(); j.waitForCompletion(run); assertCompletedCleanly(run); Assert.assertEquals(Result.SUCCESS, run.getResult()); }); }
@Issue("JENKINS-45455") @Test public void nestedStagesSkippedOnRestart() throws Exception { WorkflowRun original = expect(Result.FAILURE, "restart", "nestedStagesSkippedOnRestart").go(); WorkflowJob p = original.getParent(); HtmlPage redirect = restartFromStageInUI(original, "restart"); assertNotNull(redirect); assertEquals(p.getAbsoluteUrl(), redirect.getUrl().toString()); j.waitUntilNoActivity(); WorkflowRun b2 = p.getBuildByNumber(2); assertNotNull(b2); j.assertBuildStatusSuccess(b2); j.assertLogContains("Even numbered build, success", b2); j.assertLogContains("Stage \"parallel-pre-restart\" skipped due to this build restarting at stage \"restart\"", b2); j.assertLogContains("Stage \"first-parallel-skipped\" skipped due to this build restarting at stage \"restart\"", b2); j.assertLogContains("Stage \"second-parallel-skipped\" skipped due to this build restarting at stage \"restart\"", b2); j.assertLogContains("Stage \"sequence-pre-restart\" skipped due to this build restarting at stage \"restart\"", b2); j.assertLogContains("Stage \"first-sequence-skipped\" skipped due to this build restarting at stage \"restart\"", b2); j.assertLogContains("Stage \"second-sequence-skipped\" skipped due to this build restarting at stage \"restart\"", b2); j.assertLogContains("Made it to post-restart", b2); }
@Override public void evaluate() throws Throwable { WorkflowJob p = rr.j.jenkins.getItemByFullName("p", WorkflowJob.class); assertNotNull(p); WorkflowRun b = p.getBuildByNumber(1); SemaphoreStep.success("wait/1", null); rr.j.assertBuildStatusSuccess(rr.j.waitForCompletion(b)); rr.j.assertLogContains("[Pipeline] { (" + SyntheticStageNames.postBuild() + ")", b); FlowExecution execution = b.getExecution(); assertNotNull(execution); Collection<FlowNode> heads = execution.getCurrentHeads(); DepthFirstScanner scanner = new DepthFirstScanner(); assertNotNull(scanner.findFirstMatch(heads, null, syntheticStagePredicate(SyntheticStageNames.postBuild(), SyntheticStage.getPost()))); SemaphoreStep.success("wait/2", null); rr.j.buildAndAssertSuccess(p); } });