Skip to content

Commit

Permalink
Verify fix for timing of parallels with single long steps [JENKINS-38…
Browse files Browse the repository at this point in the history
…536]
  • Loading branch information
svanoort committed Jun 5, 2017
1 parent 6386693 commit 1bcd313
Show file tree
Hide file tree
Showing 4 changed files with 431 additions and 18 deletions.
40 changes: 22 additions & 18 deletions pom.xml
Expand Up @@ -26,7 +26,6 @@
<properties>
<jenkins.version>1.642.3</jenkins.version>
<java.level>7</java.level>
<workflow.version>2.0</workflow.version>
<jackson.version>2.4.0</jackson.version>
</properties>

Expand All @@ -47,12 +46,18 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>${workflow.version}</version>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-api</artifactId>
<version>2.2</version> <!-- allows consuming the new APIs -->
<version>2.17-20170605.162008-1</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
Expand All @@ -63,24 +68,18 @@
<!-- For block-scoped stage support, input step handling -->
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>2.1</version>
<version>2.10</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-basic-steps</artifactId>
<version>${workflow.version}</version>
<version>2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<!-- Needed to detect block-scoped stages -->
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>2.1</version>
<version>2.31</version>
</dependency>
<dependency>
<!-- Block-scoped stage support -->
Expand All @@ -91,21 +90,26 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>2.1</version>
<scope>test</scope>
<classifier>tests</classifier>
<version>2.14</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-aggregator</artifactId>
<version>${workflow.version}</version>
<artifactId>workflow-support</artifactId>
<version>2.14</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-durable-task-step</artifactId>
<version>${workflow.version}</version>
<version>2.5</version>
<scope>test</scope>
</dependency>
<!--<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-aggregator</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>-->
</dependencies>
</project>
@@ -0,0 +1,30 @@
package org.jenkinsci.plugins.workflow.pipelinegraphanalysis;

import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.graphanalysis.ChunkFinder;
import org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner;
import org.jenkinsci.plugins.workflow.graphanalysis.SimpleChunkVisitor;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

/**
* For test use: a ChunkFinder that never returns chunks, to use in testing parallel handling only.
* All {@link FlowNode}s will this result in calling {@link SimpleChunkVisitor#atomNode(FlowNode, FlowNode, FlowNode, ForkScanner)}
*/
public class NoOpChunkFinder implements ChunkFinder {
@Override
public boolean isStartInsideChunk() {
return false;
}

@Override
public boolean isChunkStart(@Nonnull FlowNode current, @CheckForNull FlowNode previous) {
return false;
}

@Override
public boolean isChunkEnd(@Nonnull FlowNode current, @CheckForNull FlowNode previous) {
return false;
}
}
Expand Up @@ -33,6 +33,7 @@
import org.jenkinsci.plugins.workflow.flow.FlowExecution;
import org.jenkinsci.plugins.workflow.graph.BlockStartNode;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.support.steps.input.InputAction;
Expand Down Expand Up @@ -316,6 +317,42 @@ public void testInProgress() throws Exception {
SemaphoreStep.success("wait/1", null);
}


@Test
public void timingTest() throws Exception {
// Problem here: for runs in progress we should be using current time if they're the last run node, aka the in-progress node
String jobScript = ""+
"stage 'first'\n" +
"parallel 'long' : { sleep 10; }, \n" +
" 'short': { sleep 2; }";

// This must be amateur science fiction because the exposition for the setting goes on FOREVER
ForkScanner scan = new ForkScanner();
WorkflowJob job = j.jenkins.createProject(WorkflowJob.class, "parallelTimes");
job.setDefinition(new CpsFlowDefinition(jobScript));
WorkflowRun run = job.scheduleBuild2(0).getStartCondition().get();
Thread.sleep(4000); // Such a dirty hack, but this isn't reproducible with normal SemaphoreStep use
FlowExecution exec = run.getExecution();
List<FlowNode> heads = exec.getCurrentHeads();
Assert.assertEquals(GenericStatus.IN_PROGRESS, StatusAndTiming.computeChunkStatus(
run, null, exec.getNode("2"), heads.get(0), null));
Assert.assertEquals(GenericStatus.SUCCESS, StatusAndTiming.computeChunkStatus(
run, null, exec.getNode("2"), heads.get(1), null));
TestVisitor visitor = new TestVisitor();
scan.setup(heads);
scan.visitSimpleChunks(heads, visitor, new NoOpChunkFinder());
TestVisitor.CallEntry entry = visitor.filteredCallsByType(TestVisitor.CallType.PARALLEL_END).get(0);
FlowNode endNode = exec.getNode(entry.getNodeId().toString());
Assert.assertEquals("sleep", endNode.getDisplayFunctionName());

// Finally, the heart of the matter: test computing durations
TimingInfo times = StatusAndTiming.computeChunkTiming(run, 0, exec.getNode("2"), exec.getNode(entry.getNodeId().toString()), null);
Assert.assertTrue("Underestimated duration", times.getTotalDurationMillis() >= 3000);

j.waitForCompletion(run);
j.assertBuildStatusSuccess(run);
}

@Test
public void testInProgressParallel() throws Exception {
WorkflowJob job = j.jenkins.createProject(WorkflowJob.class, "Fails");
Expand Down

0 comments on commit 1bcd313

Please sign in to comment.