@Override public void evaluate() throws Throwable { WorkflowRun b = rr.j.jenkins.getItemByFullName("p", WorkflowJob.class).getLastBuild(); SemaphoreStep.success("C-one/1", null); SemaphoreStep.success("C-two/1", null); rr.j.waitForMessage("running C-style loop on two", b); SemaphoreStep.waitForStart("new-one/1", b); rr.j.waitForMessage("running new-style loop on one", b); } });
@Override public void evaluate() throws Throwable { WorkflowRun b = rr.j.jenkins.getItemByFullName("p", WorkflowJob.class).getLastBuild(); SemaphoreStep.success("C-one/1", null); SemaphoreStep.success("C-two/1", null); rr.j.waitForMessage("running flattened loop on two -> 2", b); SemaphoreStep.waitForStart("new-one/1", b); rr.j.waitForMessage("running new-style loop on one -> 1", b); } });
@Override public void evaluate() throws Throwable { WorkflowRun b = rr.j.jenkins.getItemByFullName("p", WorkflowJob.class).getLastBuild(); SemaphoreStep.success("C-one/1", null); SemaphoreStep.success("C-two/1", null); rr.j.waitForMessage("running flattened loop on two -> 2", b); SemaphoreStep.waitForStart("new-one/1", b); rr.j.waitForMessage("running new-style loop on one -> 1", b); } });
@Override public void evaluate() throws Throwable { Logger LOGGER = Logger.getLogger("org.jenkinsci.plugins.workflow"); LOGGER.setLevel(Level.FINE); Handler handler = new ConsoleHandler(); handler.setLevel(Level.ALL); LOGGER.addHandler(handler); WorkflowJob p = story.j.jenkins.getItemByFullName("p", WorkflowJob.class); WorkflowRun b = p.getLastBuild(); assertTrue(b.isBuilding()); story.j.waitForMessage("Cannot restore BadThing", b); b.getExecutor().interrupt(); story.j.assertBuildStatus(Result.ABORTED, story.j.waitForCompletion(b)); } });
@Test public void parallelTest() throws Exception { WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("node {\n" + "echo 'First message'\n" + "parallel( a: { syncnonblocking 'wait0'; echo 'a branch'; }, b: { semaphore 'wait1'; echo 'b branch'; } )\n" + "echo 'Second message'\n" + "}", true)); WorkflowRun b = p.scheduleBuild2(0).getStartCondition().get(); SynchronousNonBlockingStep.waitForStart("wait0", b); SemaphoreStep.success("wait1/1", null); // Wait for "b" branch to print its message j.waitForMessage("b branch", b); System.out.println("b branch finishes"); // Check that "a" branch is effectively blocked j.assertLogNotContains("a branch", b); // Notify "a" branch System.out.println("Continue on wait0"); SynchronousNonBlockingStep.notify("wait0"); // Wait for "a" branch to finish j.waitForMessage("a branch", b); j.waitForCompletion(b); }
@Override public void evaluate() throws Throwable { WorkflowJob p = rr.j.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( "def arr = []; arr += 'one'; arr += 'two'\n" + "for (int i = 0; i < arr.size(); i++) {def elt = arr[i]; echo \"running C-style loop on ${elt}\"; semaphore \"C-${elt}\"}\n" + "for (def elt : arr) {echo \"running new-style loop on ${elt}\"; semaphore \"new-${elt}\"}" , true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("C-one/1", b); rr.j.waitForMessage("running C-style loop on one", b); } });
@Override public void evaluate() throws Throwable { WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("dynamicEnv {echo \"initially ${env.DYNVAR}\"; semaphore 'wait'; echo \"subsequently ${env.DYNVAR}\"}", true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("wait/1", b); story.j.waitForMessage("initially one", b); } });
@Override public void evaluate() throws Throwable { WorkflowJob p = rr.j.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( "def map = [one: 1, two: 2]\n" + "@NonCPS def entrySet(m) {m.collect {k, v -> [key: k, value: v]}}; for (def e in entrySet(map)) {echo \"running flattened loop on ${e.key} -> ${e.value}\"; semaphore \"C-${e.key}\"}\n" + "for (def e : map.entrySet()) {echo \"running new-style loop on ${e.key} -> ${e.value}\"; semaphore \"new-${e.key}\"}" , true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("C-one/1", b); rr.j.waitForMessage("running flattened loop on one -> 1", b); } });
@Override public void evaluate() throws Throwable { assertEquals(JenkinsRule.DummySecurityRealm.class, jenkins().getSecurityRealm().getClass()); rebuildContext(story.j); assertThatWorkflowIsSuspended(); story.j.waitForMessage("again running as someone", b); CheckAuth.finish(true); story.j.assertLogContains("finally running as someone", story.j.assertBuildStatusSuccess(story.j.waitForCompletion(b))); } });
@Override public void evaluate() throws Throwable { WorkflowJob p = rr.j.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( "def map = new TreeMap<String,Integer>()\n" + "map.put('one', 1)\n" + "map.put('two', 2)\n" + "@NonCPS def entrySet(m) {m.collect {k, v -> [key: k, value: v]}}; for (def e in entrySet(map)) {echo \"running flattened loop on ${e.key} -> ${e.value}\"; semaphore \"C-${e.key}\"}\n" + "map.each { e -> echo \"running new-style loop on ${e.key} -> ${e.value}\"; semaphore \"new-${e.key}\"}" , false)); // sandbox is false to allow new TreeMap WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("C-one/1", b); rr.j.waitForMessage("running flattened loop on one -> 1", b); } });
@Test public void nativeMethods() throws Exception { p.setDefinition(new CpsFlowDefinition( "@NonCPS def untransformed() {Thread.sleep(Long.MAX_VALUE)}\n" + "def helper() {echo 'sleeping'; /* flush output */ sleep 1; untransformed()}\n" + "helper()", false)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); CpsFlowExecution e = (CpsFlowExecution) b.getExecutionPromise().get(); j.waitForMessage("sleeping", b); do { // wait for the CPS VM to be busy (opposite of waitForSuspension) Thread.sleep(100); } while (!e.blocksRestart()); CpsThreadDump td = e.getThreadDump(); td.print(System.out); assertStackTrace(td.getThreads().get(0), // TODO would like to see untransformed and Thread.sleep here "WorkflowScript.helper(WorkflowScript:2)", "WorkflowScript.run(WorkflowScript:3)"); b.doKill(); }
@Test public void stop() throws Exception { WorkflowJob p = r.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("unkillable()", true)); final WorkflowRun b = p.scheduleBuild2(0).waitForStart(); r.waitForMessage("unkillable", b); try (ACLContext context = ACL.as(Jenkins.ANONYMOUS)) { b.getExecutor().interrupt(); }; r.waitForCompletion(b); r.assertBuildStatus(Result.ABORTED, b); InterruptedBuildAction iba = b.getAction(InterruptedBuildAction.class); assertNotNull(iba); List<CauseOfInterruption> causes = iba.getCauses(); assertEquals(1, causes.size()); assertEquals(CauseOfInterruption.UserInterruption.class, causes.get(0).getClass()); r.waitForMessage("Finished: ABORTED", b); // TODO JENKINS-46076 WorkflowRun.isBuilding() can go to false before .finish has completed r.assertLogContains("never going to stop", b); r.assertLogNotContains("\tat ", b); }
j.waitForMessage("Test Sync Message", b);
@Test public void interruptedTest() throws Exception { WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("node {\n" + "echo 'First message'\n" + "try { syncnonblocking 'wait' } catch(InterruptedException e) { echo 'Interrupted!' }\n" + "echo 'Second message'\n" + "}", true)); WorkflowRun b = p.scheduleBuild2(0).getStartCondition().get(); // Wait for syncnonblocking to be started System.out.println("Waiting to syncnonblocking to start..."); SynchronousNonBlockingStep.waitForStart("wait", b); // At this point syncnonblocking is waiting for an interruption // Let's force a call to stop. This will try to send an interruption to the run Thread b.getExecutor().interrupt(); System.out.println("Looking for interruption received log message"); j.waitForMessage("Interrupted!", b); j.waitForCompletion(b); j.assertBuildStatus(Result.ABORTED, b); // Also check that timeouts produce the right status. p.setDefinition(new CpsFlowDefinition("timeout(time: 1, unit: 'SECONDS') {syncnonblocking 'wait2'}", true)); j.assertLogContains(new TimeoutStepExecution.ExceededTimeout().getShortDescription(), j.assertBuildStatus(Result.ABORTED, p.scheduleBuild2(0))); }
@Override public void evaluate() throws Throwable { jenkins().setSecurityRealm(story.j.createDummySecurityRealm()); jenkins().save(); QueueItemAuthenticatorConfiguration.get().getAuthenticators().add(new MockQueueItemAuthenticator(Collections.singletonMap("demo", User.getById("someone", true).impersonate()))); p = jenkins().createProject(WorkflowJob.class, "demo"); p.setDefinition(new CpsFlowDefinition("checkAuth()", false)); ScriptApproval.get().preapproveAll(); startBuilding(); waitForWorkflowToSuspend(); assertTrue(b.isBuilding()); story.j.waitForMessage("running as someone", b); CheckAuth.finish(false); waitForWorkflowToSuspend(); assertTrue(b.isBuilding()); story.j.waitForMessage("still running as someone", 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))); }); }
@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 getContainerLogWithRestart() 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("getContainerLogWithRestart.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.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("INFO: Handshaking", b); r.assertLogContains("INFO: Connected", b); }); } }
@Override public void evaluate() throws Throwable { WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("parallel a: {def r = semaphore 'a'; echo r}, b: {semaphore 'b'}", true)); WorkflowRun b1 = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("a/1", b1); SemaphoreStep.waitForStart("b/1", b1); b1.getExecutor().interrupt(); story.j.assertBuildStatus(Result.ABORTED, story.j.waitForCompletion(b1)); story.j.assertLogContains("Failed in branch a", b1); story.j.assertLogContains("Failed in branch b", b1); WorkflowRun b2 = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("a/2", b2); SemaphoreStep.waitForStart("b/2", b2); SemaphoreStep.success("a/2", "finished branch a"); story.j.waitForMessage("finished branch a", b2); b2.getExecutor().interrupt(); story.j.assertBuildStatus(Result.ABORTED, story.j.waitForCompletion(b2)); story.j.assertLogNotContains("Failed in branch a", b2); story.j.assertLogContains("Failed in branch b", b2); } });
story.j.waitForMessage("before", b); SemaphoreStep.success("one/1", null);