未验证 提交 c489b07f 编写于 作者: O Oleg Nenashev 提交者: GitHub

Merge pull request #4055 from dwnusbaum/JENKINS-57805

[JENKINS-57805] Guard against exceptions thrown by implementations of Queue.Task.getAffinityKey
......@@ -36,6 +36,8 @@ import hudson.util.ConsistentHash.Hash;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Strategy that decides which {@link Task} gets run on which {@link Executor}.
......@@ -112,7 +114,15 @@ public abstract class LoadBalancer implements ExtensionPoint {
private boolean assignGreedily(Mapping m, Task task, List<ConsistentHash<ExecutorChunk>> hashes, int i) {
if (i==hashes.size()) return true; // fully assigned
String key = task.getAffinityKey() + (i>0 ? String.valueOf(i) : "");
String key;
try {
key = task.getAffinityKey();
} catch (RuntimeException e) {
LOGGER.log(Level.FINE, null, e);
// Default implementation of Queue.Task.getAffinityKey, we assume it doesn't fail.
key = task.getFullDisplayName();
}
key += i > 0 ? String.valueOf(i) : "";
for (ExecutorChunk ec : hashes.get(i).list(key)) {
// let's attempt this assignment
......@@ -167,4 +177,6 @@ public abstract class LoadBalancer implements ExtensionPoint {
};
}
private static final Logger LOGGER = Logger.getLogger(LoadBalancer.class.getName());
}
......@@ -33,6 +33,7 @@ import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlFormUtil;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.xml.XmlPage;
import hudson.ExtensionList;
import hudson.Functions;
import hudson.Launcher;
import hudson.XmlFile;
......@@ -1135,4 +1136,55 @@ public class QueueTest {
assertTrue(currentOne.getFuture().isCancelled());
}
}
@Test
@Issue("JENKINS-57805")
public void brokenAffinityKey() throws Exception {
BrokenAffinityKeyProject brokenProject = r.createProject(BrokenAffinityKeyProject.class, "broken-project");
// Before the JENKINS-57805 fix, the test times out because the `NullPointerException` repeatedly thrown from
// `BrokenAffinityKeyProject.getAffinityKey()` prevents `Queue.maintain()` from completing.
r.buildAndAssertSuccess(brokenProject);
}
public static class BrokenAffinityKeyProject extends Project<BrokenAffinityKeyProject, BrokenAffinityKeyBuild> implements TopLevelItem {
public BrokenAffinityKeyProject(ItemGroup parent, String name) {
super(parent, name);
}
@Override
public String getAffinityKey() {
throw new NullPointerException("oops!");
}
@Override
protected Class<BrokenAffinityKeyBuild> getBuildClass() {
return BrokenAffinityKeyBuild.class;
}
@Override
public TopLevelItemDescriptor getDescriptor() {
return ExtensionList.lookupSingleton(DescriptorImpl.class);
}
@TestExtension("brokenAffinityKey")
public static class DescriptorImpl extends AbstractProjectDescriptor {
@Override
public TopLevelItem newInstance(ItemGroup parent, String name) {
return new BrokenAffinityKeyProject(parent, name);
}
@Override
public String getDisplayName() {
return "Broken Affinity Key Project";
}
}
}
public static class BrokenAffinityKeyBuild extends Build<BrokenAffinityKeyProject, BrokenAffinityKeyBuild> {
public BrokenAffinityKeyBuild(BrokenAffinityKeyProject project) throws IOException {
super(project);
}
public BrokenAffinityKeyBuild(BrokenAffinityKeyProject project, File buildDir) throws IOException {
super(project, buildDir);
}
@Override
public void run() {
execute(new BuildExecution());
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册