Skip to content
Permalink
Browse files

[FIXED JENKINS-15747] Avoid recording too many upstream causes at any…

… depth.
  • Loading branch information
jglick committed Feb 1, 2013
1 parent 9e58d94 commit d506b32f1fbaab6fd055cd5c430c764dc887e8f4
Showing with 41 additions and 3 deletions.
  1. +3 −0 changelog.html
  2. +13 −3 core/src/main/java/hudson/model/Cause.java
  3. +25 −0 test/src/test/java/hudson/model/CauseTest.java
@@ -67,6 +67,9 @@
<li class=bug>
Plugin icons in the sidebar were not being properly cached.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16530">issue 16530</a>)
<li class='major bug'>
Broadly as well as deeply nested build causes overwhelmed the UI after 1.482.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15747">issue 15747</a>)
<li class=bug>
API typo <code>DependecyDeclarer</code> corrected.
<li class=bug>
@@ -34,6 +34,7 @@
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;

/**
@@ -106,6 +107,10 @@ public String getShortDescription() {
* Maximum depth of transitive upstream causes we want to record.
*/
private static final int MAX_DEPTH = 10;
/**
* Maximum number of transitive upstream causes we want to record.
*/
private static final int MAX_LEAF = 25;
private String upstreamProject, upstreamUrl;
private int upstreamBuild;
/**
@@ -128,8 +133,9 @@ public UpstreamCause(Run<?, ?> up) {
upstreamProject = up.getParent().getFullName();
upstreamUrl = up.getParent().getUrl();
upstreamCauses = new ArrayList<Cause>();
AtomicInteger leaf = new AtomicInteger(MAX_LEAF);
for (Cause c : up.getCauses()) {
upstreamCauses.add(trim(c, MAX_DEPTH));
upstreamCauses.add(trim(c, MAX_DEPTH, leaf));
}
}

@@ -140,15 +146,19 @@ private UpstreamCause(String upstreamProject, int upstreamBuild, String upstream
this.upstreamCauses = upstreamCauses;
}

private @Nonnull Cause trim(@Nonnull Cause c, int depth) {
private @Nonnull Cause trim(@Nonnull Cause c, int depth, AtomicInteger leaf) {
if (!(c instanceof UpstreamCause)) {
return c;
}
UpstreamCause uc = (UpstreamCause) c;
List<Cause> cs = new ArrayList<Cause>();
if (depth > 0) {
for (Cause c2 : uc.upstreamCauses) {
cs.add(trim(c2, depth - 1));
if (leaf.decrementAndGet() > 0) {
cs.add(trim(c2, depth - 1, leaf));
} else {
cs.add(new DeeplyNestedUpstreamCause());
}
}
} else {
cs.add(new DeeplyNestedUpstreamCause());
@@ -26,6 +26,8 @@

import hudson.XmlFile;
import java.io.File;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
@@ -54,4 +56,27 @@
assertFalse("too big:\n" + buildXml, buildXml.contains("<upstreamBuild>1</upstreamBuild>"));
}

@Bug(15747)
@Test public void broadlyNestedCauses() throws Exception {
FreeStyleProject a = j.createFreeStyleProject("a");
FreeStyleProject b = j.createFreeStyleProject("b");
FreeStyleProject c = j.createFreeStyleProject("c");
Run<?,?> last = null;
for (int i = 1; i <= 10; i++) {
Cause cause = last == null ? null : new Cause.UpstreamCause(last);
Future<? extends Run<?,?>> next1 = a.scheduleBuild2(0, cause);
a.scheduleBuild2(0, cause);
cause = new Cause.UpstreamCause(next1.get());
Future<? extends Run<?,?>> next2 = b.scheduleBuild2(0, cause);
b.scheduleBuild2(0, cause);
cause = new Cause.UpstreamCause(next2.get());
Future<? extends Run<?,?>> next3 = c.scheduleBuild2(0, cause);
c.scheduleBuild2(0, cause);
last = next3.get();
}
int count = new XmlFile(Run.XSTREAM, new File(last.getRootDir(), "build.xml")).asString().split(Pattern.quote("<hudson.model.Cause_-UpstreamCause")).length;
assertFalse("too big at " + count, count > 100);
//j.interactiveBreak();
}

}

0 comments on commit d506b32

Please sign in to comment.
You can’t perform that action at this time.