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

fixing up the semantics and adding a test.

上级 a3489b5b
...@@ -29,15 +29,16 @@ import hudson.matrix.listeners.MatrixBuildListener; ...@@ -29,15 +29,16 @@ import hudson.matrix.listeners.MatrixBuildListener;
import hudson.model.AbstractBuild; import hudson.model.AbstractBuild;
import hudson.model.AbstractProject; import hudson.model.AbstractProject;
import hudson.model.BuildListener; import hudson.model.BuildListener;
import hudson.model.Cause.UpstreamCause;
import hudson.model.Executor; import hudson.model.Executor;
import hudson.model.Fingerprint; import hudson.model.Fingerprint;
import jenkins.model.Jenkins;
import hudson.model.JobProperty;
import hudson.model.ParametersAction; import hudson.model.ParametersAction;
import hudson.model.Queue; import hudson.model.Queue;
import hudson.model.Result; import hudson.model.Result;
import hudson.model.Cause.UpstreamCause; import jenkins.model.Jenkins;
import hudson.tasks.Publisher; import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
...@@ -45,13 +46,10 @@ import java.io.PrintStream; ...@@ -45,13 +46,10 @@ import java.io.PrintStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.TreeSet; import java.util.TreeSet;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
/** /**
* Build of {@link MatrixProject}. * Build of {@link MatrixProject}.
...@@ -263,9 +261,9 @@ public class MatrixBuild extends AbstractBuild<MatrixProject,MatrixBuild> { ...@@ -263,9 +261,9 @@ public class MatrixBuild extends AbstractBuild<MatrixProject,MatrixBuild> {
return Result.FAILURE; return Result.FAILURE;
MatrixConfigurationSorter sorter = p.getSorter(); MatrixConfigurationSorter sorter = p.getSorter();
if(p.getSorter()!=null){ if (sorter != null) {
touchStoneConfigurations = new TreeSet<MatrixConfiguration>(touchStoneConfigurations); touchStoneConfigurations = createTreeSet(touchStoneConfigurations, sorter);
delayedConfigurations = new TreeSet<MatrixConfiguration>(delayedConfigurations); delayedConfigurations = createTreeSet(delayedConfigurations,sorter);
} }
try { try {
...@@ -401,6 +399,12 @@ public class MatrixBuild extends AbstractBuild<MatrixProject,MatrixBuild> { ...@@ -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 * A private exception to help maintain the correct control flow after extracting the 'waitForCompletion' method
*/ */
......
...@@ -56,7 +56,7 @@ import java.util.Map; ...@@ -56,7 +56,7 @@ import java.util.Map;
* *
* @author Kohsuke Kawaguchi * @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. * The actual value combination.
*/ */
...@@ -290,19 +290,6 @@ public class MatrixConfiguration extends Project<MatrixConfiguration,MatrixRun> ...@@ -290,19 +290,6 @@ public class MatrixConfiguration extends Project<MatrixConfiguration,MatrixRun>
throw new UnsupportedOperationException(); 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 * Returns true if this configuration is a configuration
* currently in use today (as opposed to the ones that are * currently in use today (as opposed to the ones that are
......
...@@ -154,7 +154,10 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im ...@@ -154,7 +154,10 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
super(parent, 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; return sorter;
} }
...@@ -586,12 +589,18 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im ...@@ -586,12 +589,18 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
checkAxisNames(newAxes); checkAxisNames(newAxes);
this.axes = new AxisList(newAxes.toList()); this.axes = new AxisList(newAxes.toList());
runSequentially = json.optBoolean("runSequentially");
// set sorter if any sorter is chosen // set sorter if any sorter is chosen
if (runSequentially) {
MatrixConfigurationSorter s = req.bindJSON(MatrixConfigurationSorter.class,json.optJSONObject("sorter")); MatrixConfigurationSorter s = req.bindJSON(MatrixConfigurationSorter.class,json.optJSONObject("sorter"));
s.validate(this); if (s!=null) s.validate(this);
if (s instanceof NoopMatrixConfigurationSorter) s=null;
setSorter(s); setSorter(s);
} else {
setSorter(null);
}
runSequentially = json.has("runSequentially");
buildWrappers.rebuild(req, json, BuildWrappers.getFor(this)); buildWrappers.rebuild(req, json, BuildWrappers.getFor(this));
builders.rebuildHetero(req, json, Builder.all(), "builder"); 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. ...@@ -59,11 +59,11 @@ THE SOFTWARE.
addCaption="${%Add axis}"/> addCaption="${%Add axis}"/>
</f:block> </f:block>
<j:if test="${(descriptor.sorterDescriptors().size() > 0)}"> <f:optionalBlock field="runSequentially" title="${%Run each configuration sequentially}" inline="true">
<f:dropdownDescriptorSelector title="${%Execution order of builds}" field="sorter" /> <j:if test="${descriptor.sorterDescriptors.size() gt 1}">
<f:dropdownDescriptorSelector title="${%Execution order of builds}" field="sorter"/>
</j:if> </j:if>
</f:optionalBlock>
<f:optionalBlock field="runSequentially" title="${%Run each configuration sequentially}"/>
<f:optionalBlock name="hasCombinationFilter" title="${%Combination Filter}" checked="${!empty(it.combinationFilter)}" <f:optionalBlock name="hasCombinationFilter" title="${%Combination Filter}" checked="${!empty(it.combinationFilter)}"
help="/help/matrix/combinationfilter.html"> 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.
先完成此消息的编辑!
想要评论请 注册