Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #44 from jglick/orphaned-job-running-build-JENKINS…
…-25240

[JENKINS-25240] Do not delete branch projects with running builds
  • Loading branch information
jglick committed Mar 18, 2016
2 parents 8df445a + e0388ac commit 39ad520
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 12 deletions.
Expand Up @@ -40,9 +40,6 @@
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.FINER;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;

Expand All @@ -54,11 +51,6 @@
*/
public class DefaultOrphanedItemStrategy extends OrphanedItemStrategy {

/**
* Our logger
*/
private static final Logger LOGGER = Logger.getLogger(DefaultOrphanedItemStrategy.class.getName());

/**
* Should old branches be removed at all
*/
Expand Down Expand Up @@ -187,8 +179,8 @@ private static long lastBuildTime(TopLevelItem item) {
@Override
public <I extends TopLevelItem> Collection<I> orphanedItems(ComputedFolder<I> owner, Collection<I> orphaned, TaskListener listener) throws IOException, InterruptedException {
List<I> toRemove = new ArrayList<I>();
LOGGER.log(FINE, "Running the dead item cleanup for {0}", owner.getFullName());
if (pruneDeadBranches && (numToKeep != -1 || daysToKeep != -1)) {
listener.getLogger().printf("Evaluating orphaned items in %s%n", owner.getFullDisplayName());
List<I> candidates = new ArrayList<I>(orphaned);
Collections.sort(candidates, new Comparator<I>() {
@Override
Expand All @@ -199,15 +191,34 @@ public int compare(I i1, I i2) {
return (ms2 < ms1) ? -1 : ((ms2 == ms1) ? 0 : 1); // TODO Java 7+: Long.compare(ms2, ms1);
}
});
for (Iterator<I> iterator = candidates.iterator(); iterator.hasNext();) {
I item = iterator.next();
if (item instanceof Job) {
// Enumerating all builds is inefficient. But we will most likely delete this job anyway,
// which will have a cost proportional to the number of builds just to delete those files.
for (Run<?,?> build : ((Job<?,?>) item).getBuilds()) {
if (build.isBuilding()) {
listener.getLogger().printf("Will not remove %s as build #%d is still in progress%n", item.getDisplayName(), build.getNumber());
iterator.remove();
}
String whyKeepLog = build.getWhyKeepLog();
if (whyKeepLog != null) {
listener.getLogger().printf("Will not remove %s as build #%d is marked to not be removed: %s%n", item.getDisplayName(), build.getNumber(), whyKeepLog);
iterator.remove();
}
}
}
}
int count = 0;
if (numToKeep != -1) {
for (Iterator<I> iterator = candidates.iterator(); iterator.hasNext(); ) {
I item = iterator.next();
count++;
if (count <= numToKeep) {
listener.getLogger().printf("Will not remove %s as it is only #%d in the list%n", item.getDisplayName(), count);
continue;
}
LOGGER.log(FINER, "{0} is to be removed", item.getFullName());
listener.getLogger().printf("Will remove %s as it is #%d in the list%n", item.getDisplayName(), count);
toRemove.add(item);
iterator.remove();
}
Expand All @@ -217,10 +228,10 @@ public int compare(I i1, I i2) {
cal.add(Calendar.DAY_OF_YEAR, -daysToKeep);
for (I item : candidates) {
if (lastBuildTime(item) > cal.getTimeInMillis()) {
LOGGER.log(FINER, "{0} is not GC-ed because it is still new", item.getFullName());
listener.getLogger().printf("Will not remove %s because it is new%n", item.getDisplayName());
continue;
}
LOGGER.log(FINER, "{0} is to be removed", item.getFullName());
listener.getLogger().printf("Will remove %s as it is too old%n", item.getDisplayName());
toRemove.add(item);
}
}
Expand Down
Expand Up @@ -24,8 +24,10 @@
package com.cloudbees.hudson.plugins.folder.computed;

import com.cloudbees.hudson.plugins.folder.AbstractFolderDescriptor;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.ItemGroup;
import hudson.model.Result;
import hudson.model.TaskListener;
import hudson.model.TopLevelItem;
import java.io.IOException;
Expand All @@ -42,6 +44,7 @@
import org.junit.Rule;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.SleepBuilder;
import org.jvnet.hudson.test.TestExtension;

public class ComputedFolderTest {
Expand Down Expand Up @@ -79,6 +82,34 @@ public void duplicateEntries() throws Exception {
assertEquals("{A=updated in round #5, B=created in round #5, C=updated in round #5, D=created in round #5}", descriptions.toString());
}

@Issue("JENKINS-25240")
@Test
public void runningBuild() throws Exception {
SampleComputedFolder d = r.jenkins.createProject(SampleComputedFolder.class, "d");
d.kids.addAll(Arrays.asList("A", "B"));
d.recompute();
d.assertItemNames(1, "A", "B");
d.getItem("B").getBuildersList().add(new SleepBuilder(Long.MAX_VALUE));
FreeStyleBuild b1 = d.getItem("B").scheduleBuild2(0).getStartCondition().get();
d.kids.remove("B");
d.recompute();
d.assertItemNames(2, "A", "B");
assertTrue(b1.isBuilding());
b1.doStop();
r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b1));
d.recompute();
d.assertItemNames(3, "A");
FreeStyleBuild a1 = d.getItem("A").scheduleBuild2(0).get();
FreeStyleBuild a2 = d.getItem("A").scheduleBuild2(0).get();
a1.keepLog(true);
d.kids.remove("A");
d.recompute();
d.assertItemNames(4, "A");
a1.keepLog(false);
d.recompute();
d.assertItemNames(5);
}

@SuppressWarnings({"unchecked", "rawtypes"})
public static class SampleComputedFolder extends ComputedFolder<FreeStyleProject> {

Expand Down

0 comments on commit 39ad520

Please sign in to comment.