Skip to content

Commit

Permalink
JENKINS-22751 refined status resolving of QUEUED
Browse files Browse the repository at this point in the history
  • Loading branch information
patbos committed Apr 25, 2014
1 parent b9a16f5 commit 96a583d
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 38 deletions.
25 changes: 4 additions & 21 deletions src/main/java/se/diabol/jenkins/pipeline/domain/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.ItemGroup;
import hudson.util.RunList;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
Expand Down Expand Up @@ -126,9 +125,9 @@ public static Task getPrototypeTask(AbstractProject project) {

public Task getLatestTask(ItemGroup context, AbstractBuild firstBuild) {
AbstractProject<?, ?> project = getProject(this, context);
AbstractBuild build = match(project.getBuilds(), firstBuild);
AbstractBuild build = BuildUtil.match(project.getBuilds(), firstBuild);

Status taskStatus = SimpleStatus.resolveStatus(project, build);
Status taskStatus = SimpleStatus.resolveStatus(project, build, firstBuild);
String taskLink;
if (build == null || taskStatus.isIdle() || taskStatus.isQueued()) {
taskLink = this.getLink();
Expand All @@ -146,9 +145,9 @@ public Task getLatestTask(ItemGroup context, AbstractBuild firstBuild) {

public Task getAggregatedTask(AbstractBuild versionBuild, ItemGroup context) {
AbstractProject<?, ?> taskProject = getProject(this, context);
AbstractBuild currentBuild = match(taskProject.getBuilds(), versionBuild);
AbstractBuild currentBuild = BuildUtil.match(taskProject.getBuilds(), versionBuild);
if (currentBuild != null) {
Status taskStatus = SimpleStatus.resolveStatus(taskProject, currentBuild);
Status taskStatus = SimpleStatus.resolveStatus(taskProject, currentBuild, null);
String taskLink = Util.fixNull(Jenkins.getInstance().getRootUrl()) + currentBuild.getUrl();
if (taskStatus.isRunning()) {
taskLink = Util.fixNull(Jenkins.getInstance().getRootUrl()) + currentBuild.getUrl() + "console";
Expand All @@ -163,22 +162,6 @@ private AbstractProject getProject(Task task, ItemGroup context) {
return ProjectUtil.getProject(task.getId(), context);
}


/**
* Returns the build for a projects that has been triggered by the supplied upstream project.
*/
private AbstractBuild match(RunList<? extends AbstractBuild> runList, AbstractBuild firstBuild) {
if (firstBuild != null) {
for (AbstractBuild currentBuild : runList) {
if (firstBuild.equals(BuildUtil.getFirstUpstreamBuild(currentBuild, firstBuild.getProject()))) {
return currentBuild;
}
}
}
return null;
}


@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Task{");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@
*/
package se.diabol.jenkins.pipeline.domain.status;

import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Cause;
import hudson.model.Result;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import se.diabol.jenkins.pipeline.domain.AbstractItem;
import se.diabol.jenkins.pipeline.util.BuildUtil;
import se.diabol.jenkins.pipeline.util.PipelineUtils;
import se.diabol.jenkins.pipeline.util.ProjectUtil;

import java.util.List;

import static java.lang.Math.round;
import static java.lang.System.currentTimeMillis;
Expand Down Expand Up @@ -106,9 +112,9 @@ public boolean isDisabled() {
return DISABLED.equals(type);
}

public static Status resolveStatus(AbstractProject project, AbstractBuild build) {
public static Status resolveStatus(AbstractProject project, AbstractBuild build, AbstractBuild firstBuild) {
if (build == null) {
if (project.isInQueue()) {
if (ProjectUtil.isQueued(project, firstBuild)) {
return StatusFactory.queued(project.getQueueItem().getInQueueSince());
} else if (project.isDisabled()) {
return StatusFactory.disabled();
Expand Down Expand Up @@ -145,7 +151,6 @@ public static Status resolveStatus(AbstractProject project, AbstractBuild build)
}



@Override
public String toString() {
return String.valueOf(type);
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/se/diabol/jenkins/pipeline/util/BuildUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import hudson.model.AbstractProject;
import hudson.model.Cause;
import hudson.model.CauseAction;
import hudson.util.RunList;

import java.util.List;

Expand Down Expand Up @@ -73,4 +74,19 @@ public static AbstractBuild getFirstUpstreamBuild(AbstractBuild build, AbstractP
return build;
}

/**
* Returns the build for a projects that has been triggered by the supplied upstream project.
*/
public static AbstractBuild match(RunList<? extends AbstractBuild> runList, AbstractBuild firstBuild) {
if (firstBuild != null) {
for (AbstractBuild currentBuild : runList) {
if (firstBuild.equals(BuildUtil.getFirstUpstreamBuild(currentBuild, firstBuild.getProject()))) {
return currentBuild;
}
}
}
return null;
}


}
29 changes: 26 additions & 3 deletions src/main/java/se/diabol/jenkins/pipeline/util/ProjectUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
package se.diabol.jenkins.pipeline.util;

import hudson.Util;
import hudson.model.AbstractProject;
import hudson.model.ItemGroup;
import hudson.model.TopLevelItem;
import hudson.model.*;
import hudson.plugins.parameterizedtrigger.BlockableBuildTriggerConfig;
import hudson.plugins.parameterizedtrigger.SubProjectsAction;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import se.diabol.jenkins.pipeline.domain.status.StatusFactory;

import java.util.*;
import java.util.logging.Level;
Expand Down Expand Up @@ -143,4 +142,28 @@ public static Map<String, AbstractProject> getProjects(String regExp) {
}
}

public static boolean isQueued(AbstractProject project, AbstractBuild firstBuild) {
if (project.isInQueue()) {
if (firstBuild == null) {
return true;
} else {
List<Cause.UpstreamCause> causes = Util.filter(project.getQueueItem().getCauses(), Cause.UpstreamCause.class);
List<AbstractProject<?,?>> upstreamProjects = project.getUpstreamProjects();
for (AbstractProject<?, ?> upstreamProject : upstreamProjects) {
AbstractBuild upstreamBuild = BuildUtil.match(upstreamProject.getBuilds(), firstBuild);
if (upstreamBuild != null) {
for (Cause.UpstreamCause upstreamCause : causes) {
if (upstreamBuild.getNumber() == upstreamCause.getUpstreamBuild() && upstreamProject.getName().equals(upstreamCause.getUpstreamProject())) {
return true;
}

}
}
}
return false;
}
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
*/
package se.diabol.jenkins.pipeline.domain.status;

import au.com.centrumsystems.hudson.plugin.buildpipeline.BuildPipelineView;
import au.com.centrumsystems.hudson.plugin.buildpipeline.DownstreamProjectGridBuilder;
import au.com.centrumsystems.hudson.plugin.buildpipeline.trigger.BuildPipelineTrigger;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
Expand All @@ -29,9 +32,11 @@
import org.jvnet.hudson.test.*;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import se.diabol.jenkins.pipeline.domain.Pipeline;

import java.io.IOException;
import java.util.Calendar;
import java.util.List;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
Expand All @@ -45,7 +50,7 @@ public class SimpleStatusTest {
@Test
public void testResolveStatusIdle() throws Exception {
FreeStyleProject project = jenkins.createFreeStyleProject();
Status status = SimpleStatus.resolveStatus(project, null);
Status status = SimpleStatus.resolveStatus(project, null, null);
assertTrue(status.isIdle());
assertEquals("IDLE", status.toString());
assertEquals(-1, status.getLastActivity());
Expand All @@ -58,7 +63,7 @@ public void testResolveStatusIdle() throws Exception {
public void testResolveStatusDisabled() throws Exception {
FreeStyleProject project = jenkins.createFreeStyleProject();
project.makeDisabled(true);
Status status = SimpleStatus.resolveStatus(project, null);
Status status = SimpleStatus.resolveStatus(project, null, null);
assertTrue(status.isDisabled());
assertEquals("DISABLED", status.toString());
assertEquals(-1, status.getLastActivity());
Expand All @@ -72,7 +77,7 @@ public void testResolveStatusSuccess() throws Exception {
FreeStyleProject project = jenkins.createFreeStyleProject();
jenkins.buildAndAssertSuccess(project);
jenkins.waitUntilNoActivity();
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild());
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null);
assertTrue(status.isSuccess());
assertEquals("SUCCESS", status.toString());
assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity());
Expand All @@ -87,7 +92,7 @@ public void testResolveStatusFailure() throws Exception {
project.getBuildersList().add(new FailureBuilder());
project.scheduleBuild2(0);
jenkins.waitUntilNoActivity();
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild());
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null);
assertTrue(status.isFailed());
assertEquals("FAILED", status.toString());
assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity());
Expand All @@ -103,7 +108,7 @@ public void testResolveStatusUnstable() throws Exception {
project.getBuildersList().add(new UnstableBuilder());
project.scheduleBuild2(0);
jenkins.waitUntilNoActivity();
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild());
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null);
assertTrue(status.isUnstable());
assertEquals("UNSTABLE", status.toString());
assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity());
Expand All @@ -120,7 +125,7 @@ public void testResolveStatusAborted() throws Exception {
project.getBuildersList().add(new MockBuilder(Result.ABORTED));
project.scheduleBuild2(0);
jenkins.waitUntilNoActivity();
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild());
Status status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null);
assertTrue(status.isCancelled());
assertEquals("CANCELLED", status.toString());
assertEquals(project.getLastBuild().getTimeInMillis(), status.getLastActivity());
Expand All @@ -137,7 +142,7 @@ public void testResolveStatusNotBuilt() throws Exception {
project.scheduleBuild2(0);
jenkins.waitUntilNoActivity();
try {
SimpleStatus.resolveStatus(project, project.getLastBuild());
SimpleStatus.resolveStatus(project, project.getLastBuild(), null);
fail("Should throw exception here");
} catch (IllegalStateException e) {
}
Expand All @@ -148,13 +153,13 @@ public void testResolveStatusNotBuilt() throws Exception {
public void testResolveStatusQueued() throws Exception {
FreeStyleProject project = jenkins.createFreeStyleProject();
project.scheduleBuild2(2);
Status status = SimpleStatus.resolveStatus(project, null);
Status status = SimpleStatus.resolveStatus(project, null, null);
assertTrue(status.isQueued());
assertFalse(status.isRunning());
assertTrue(status.getType().equals(StatusType.QUEUED));
assertEquals("QUEUED", status.toString());
jenkins.waitUntilNoActivity();
status = SimpleStatus.resolveStatus(project, project.getLastBuild());
status = SimpleStatus.resolveStatus(project, project.getLastBuild(), null);
assertTrue(status.isSuccess());
assertTrue(status.getType().equals(StatusType.SUCCESS));
assertEquals(project.getLastBuild().getDuration(), status.getDuration());
Expand All @@ -177,7 +182,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,

project.scheduleBuild2(0);
buildStarted.block(); // wait for the build to really start
Status status = SimpleStatus.resolveStatus(project, project.getFirstBuild());
Status status = SimpleStatus.resolveStatus(project, project.getFirstBuild(), null);
jenkins.waitUntilNoActivity();
assertTrue(status.isRunning());
assertNotNull(status.getTimestamp());
Expand All @@ -200,7 +205,40 @@ public void testBuildingProgressGreaterThanEstimated() {
Mockito.when(build.getTimestamp()).thenReturn(calendar);
Mockito.when(build.getEstimatedDuration()).thenReturn(10l);

assertEquals(99, ((Running)SimpleStatus.resolveStatus(null, build)).getPercentage());
assertEquals(99, ((Running) SimpleStatus.resolveStatus(null, build, null)).getPercentage());

}

@Test
public void testCheckThatAllOnlyQueuedBuildIsResolvedAsQueued() throws Exception {
FreeStyleProject project1 = jenkins.createFreeStyleProject("project1");
jenkins.createFreeStyleProject("project2");
project1.getPublishersList().add(new BuildPipelineTrigger("project2", null));

jenkins.getInstance().rebuildDependencyGraph();
Pipeline pipeline = Pipeline.extractPipeline("name", project1);
jenkins.buildAndAssertSuccess(project1);
jenkins.buildAndAssertSuccess(project1);
jenkins.waitUntilNoActivity();

List<Pipeline> pipelines = pipeline.createPipelineLatest(2, jenkins.getInstance());
assertEquals(2, pipelines.size());
assertEquals(StatusType.IDLE, pipelines.get(0).getStages().get(1).getTasks().get(0).getStatus().getType());
assertEquals(StatusType.IDLE, pipelines.get(1).getStages().get(1).getTasks().get(0).getStatus().getType());

BuildPipelineView view = new BuildPipelineView("", "", new DownstreamProjectGridBuilder("project1"), "0", false, "");
project1.setQuietPeriod(3);
view.triggerManualBuild(1, "project2", "project1");
pipelines = pipeline.createPipelineLatest(2, jenkins.getInstance());
assertEquals(2, pipelines.size());
assertEquals(StatusType.IDLE, pipelines.get(0).getStages().get(1).getTasks().get(0).getStatus().getType());
assertEquals(StatusType.QUEUED, pipelines.get(1).getStages().get(1).getTasks().get(0).getStatus().getType());

jenkins.waitUntilNoActivity();
pipelines = pipeline.createPipelineLatest(2, jenkins.getInstance());
assertEquals(2, pipelines.size());
assertEquals(StatusType.IDLE, pipelines.get(0).getStages().get(1).getTasks().get(0).getStatus().getType());
assertEquals(StatusType.SUCCESS, pipelines.get(1).getStages().get(1).getTasks().get(0).getStatus().getType());

}

Expand Down

0 comments on commit 96a583d

Please sign in to comment.