提交 e5e163f2 编写于 作者: K Kohsuke Kawaguchi

fixing up the semantics and adding a test.

上级 a3489b5b
......@@ -29,15 +29,16 @@ import hudson.matrix.listeners.MatrixBuildListener;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Cause.UpstreamCause;
import hudson.model.Executor;
import hudson.model.Fingerprint;
import jenkins.model.Jenkins;
import hudson.model.JobProperty;
import hudson.model.ParametersAction;
import hudson.model.Queue;
import hudson.model.Result;
import hudson.model.Cause.UpstreamCause;
import hudson.tasks.Publisher;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
import java.io.File;
import java.io.IOException;
......@@ -45,13 +46,10 @@ import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.TreeSet;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
/**
* Build of {@link MatrixProject}.
......@@ -261,11 +259,11 @@ public class MatrixBuild extends AbstractBuild<MatrixProject,MatrixBuild> {
for (MatrixAggregator a : aggregators)
if(!a.startBuild())
return Result.FAILURE;
MatrixConfigurationSorter sorter = p.getSorter();
if(p.getSorter()!=null){
touchStoneConfigurations = new TreeSet<MatrixConfiguration>(touchStoneConfigurations);
delayedConfigurations = new TreeSet<MatrixConfiguration>(delayedConfigurations);
MatrixConfigurationSorter sorter = p.getSorter();
if (sorter != null) {
touchStoneConfigurations = createTreeSet(touchStoneConfigurations, sorter);
delayedConfigurations = createTreeSet(delayedConfigurations,sorter);
}
try {
......@@ -401,6 +399,12 @@ public class MatrixBuild extends AbstractBuild<MatrixProject,MatrixBuild> {
}
}
private <T> TreeSet<T> createTreeSet(Collection<T> items, Comparator<T> sorter) {
TreeSet<T> r = new TreeSet<T>(sorter);
r.addAll(items);
return r;
}
/**
* A private exception to help maintain the correct control flow after extracting the 'waitForCompletion' method
*/
......
......@@ -56,7 +56,7 @@ import java.util.Map;
*
* @author Kohsuke Kawaguchi
*/
public class MatrixConfiguration extends Project<MatrixConfiguration,MatrixRun> implements SCMedItem, NonBlockingTask, Comparable<MatrixConfiguration> {
public class MatrixConfiguration extends Project<MatrixConfiguration,MatrixRun> implements SCMedItem, NonBlockingTask {
/**
* The actual value combination.
*/
......@@ -290,19 +290,6 @@ public class MatrixConfiguration extends Project<MatrixConfiguration,MatrixRun>
throw new UnsupportedOperationException();
}
public int compareTo(MatrixConfiguration that) {
MatrixConfigurationSorter sorter = getParent().getSorter();
try {
if (sorter != null) {
return getParent().getSorter().compare(this, that);
} else {
return getDisplayName().compareTo(((MatrixConfiguration) that).getDisplayName());
}
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
/**
* Returns true if this configuration is a configuration
* currently in use today (as opposed to the ones that are
......
......@@ -153,8 +153,11 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
public MatrixProject(ItemGroup parent, String name) {
super(parent, name);
}
public MatrixConfigurationSorter getSorter(){
/**
* @return can be null (to indicate that the configurations should be left to their natural order.)
*/
public MatrixConfigurationSorter getSorter() {
return sorter;
}
......@@ -586,12 +589,18 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
checkAxisNames(newAxes);
this.axes = new AxisList(newAxes.toList());
runSequentially = json.optBoolean("runSequentially");
// set sorter if any sorter is chosen
MatrixConfigurationSorter s = req.bindJSON(MatrixConfigurationSorter.class,json.optJSONObject("sorter"));
s.validate(this);
setSorter(s);
if (runSequentially) {
MatrixConfigurationSorter s = req.bindJSON(MatrixConfigurationSorter.class,json.optJSONObject("sorter"));
if (s!=null) s.validate(this);
if (s instanceof NoopMatrixConfigurationSorter) s=null;
setSorter(s);
} else {
setSorter(null);
}
runSequentially = json.has("runSequentially");
buildWrappers.rebuild(req, json, BuildWrappers.getFor(this));
builders.rebuildHetero(req, json, Builder.all(), "builder");
......
package hudson.matrix;
import hudson.Extension;
import hudson.util.FormValidation;
import org.kohsuke.stapler.DataBoundConstructor;
/**
* Place holder for default "do not sort" {@link MatrixConfigurationSorter}.
*
* @author Kohsuke Kawaguchi
*/
public class NoopMatrixConfigurationSorter extends MatrixConfigurationSorter {
@DataBoundConstructor
public NoopMatrixConfigurationSorter() {
}
@Override
public void validate(MatrixProject p) throws FormValidation {
// nothing
}
public int compare(MatrixConfiguration o1, MatrixConfiguration o2) {
return o1.getDisplayName().compareTo(o2.getDisplayName());
}
@Extension(ordinal=100) // this is the default
public static class DescriptorImpl extends MatrixConfigurationSorterDescriptor {
@Override
public String getDisplayName() {
return "Doesn't care";
}
}
}
......@@ -59,11 +59,11 @@ THE SOFTWARE.
addCaption="${%Add axis}"/>
</f:block>
<j:if test="${(descriptor.sorterDescriptors().size() > 0)}">
<f:dropdownDescriptorSelector title="${%Execution order of builds}" field="sorter" />
</j:if>
<f:optionalBlock field="runSequentially" title="${%Run each configuration sequentially}"/>
<f:optionalBlock field="runSequentially" title="${%Run each configuration sequentially}" inline="true">
<j:if test="${descriptor.sorterDescriptors.size() gt 1}">
<f:dropdownDescriptorSelector title="${%Execution order of builds}" field="sorter"/>
</j:if>
</f:optionalBlock>
<f:optionalBlock name="hasCombinationFilter" title="${%Combination Filter}" checked="${!empty(it.combinationFilter)}"
help="/help/matrix/combinationfilter.html">
......
package hudson.matrix;
import hudson.util.FormValidation;
import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.TestExtension;
import org.kohsuke.stapler.DataBoundConstructor;
/**
* @author Kohsuke Kawaguchi
*/
public class MatrixConfigurationSorterTest extends HudsonTestCase {
public void testConfigRoundtrip() throws Exception {
MatrixProject p = createMatrixProject();
configRoundtrip(p);
assertNull(p.getSorter());
SorterImpl before = new SorterImpl();
p.setSorter(before);
p.setRunSequentially(true);
configRoundtrip(p);
Object after = p.getSorter();
assertNotSame(before,after);
assertSame(before.getClass(),after.getClass());
}
public static class SorterImpl extends MatrixConfigurationSorter {
@DataBoundConstructor
public SorterImpl() {}
@Override
public void validate(MatrixProject p) throws FormValidation {
}
public int compare(MatrixConfiguration o1, MatrixConfiguration o2) {
return o1.getDisplayName().compareTo(o2.getDisplayName());
}
@TestExtension
public static class DescriptorImpl extends MatrixConfigurationSorterDescriptor {
@Override
public String getDisplayName() {
return "Test Sorter";
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册