From 6394b9866bf93af23d0f9515dc802b7afc551537 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Sun, 21 Feb 2016 22:44:14 -0500 Subject: [PATCH 01/27] Fixing throttle based on parameter examination --- pom.xml | 166 ++++++++++-------- .../throttleconcurrents/Messages.properties | 1 + .../ThrottleJobProperty/config.jelly | 12 ++ src/main/resources/index.jelly | 1 + .../ThrottleIntegrationTest.java | 43 +++-- .../ThrottleQueueTaskDispatcherTest.java | 6 +- 6 files changed, 131 insertions(+), 98 deletions(-) diff --git a/pom.xml b/pom.xml index 84f54aa3..920c7742 100644 --- a/pom.xml +++ b/pom.xml @@ -21,91 +21,102 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - - 4.0.0 - - org.jenkins-ci.plugins - plugin - 1.424 - + + 4.0.0 - throttle-concurrents - hpi - Jenkins Throttle Concurrent Builds Plug-in - 1.8.5-SNAPSHOT - http://wiki.jenkins-ci.org/display/JENKINS/Throttle+Concurrent+Builds+Plugin - Plugin to throttle the number of concurrent builds of a single job per node. - - - - MIT license - All source code is under the MIT license. - - + + org.jenkins-ci.plugins + plugin + 1.596.1 + - - - - - org.apache.maven.plugins - maven-enforcer-plugin - 1.0-beta-1 - - - - - - maven-compiler-plugin - - 1.6 - 1.6 - - - - org.apache.maven.plugins - maven-release-plugin - - deploy - - - - + throttle-concurrents + hpi + Jenkins Throttle Concurrent Builds Plug-in + 1.8.5-SNAPSHOT + http://wiki.jenkins-ci.org/display/JENKINS/Throttle+Concurrent+Builds+Plugin + Plugin to throttle the number of concurrent builds of a single job per node. - - - abayer - Andrew Bayer - andrew.bayer@gmail.com - -8 - - - oleg_nenashev - Oleg Nenashev - o.v.nenashev@gmail.com - +3 - - + + + MIT license + All source code is under the MIT license. + + - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - + + + abayer + Andrew Bayer + andrew.bayer@gmail.com + -8 + + + oleg_nenashev + Oleg Nenashev + o.v.nenashev@gmail.com + +3 + + - - scm:git:git://github.com/jenkinsci/throttle-concurrent-builds-plugin.git - scm:git:git@github.com:jenkinsci/throttle-concurrent-builds-plugin.git - http://github.com/jenkinsci/throttle-concurrents-plugin - + + scm:git:git://github.com/jenkinsci/throttle-concurrent-builds-plugin.git + scm:git:git@github.com:jenkinsci/throttle-concurrent-builds-plugin.git + + http://github.com/jenkinsci/throttle-concurrents-plugin + + + + UTF-8 + 1.7 + 1.7 + + + + + + maven-clean-plugin + ${maven-clean-plugin.version} + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${compileSource} + ${compileTarget} + false + false + + + + + + + org.apache.maven.plugins + maven-release-plugin + + deploy + + + + + + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + repo.jenkins-ci.org http://repo.jenkins-ci.org/public/ + com.google.code.findbugs @@ -113,6 +124,17 @@ THE SOFTWARE. 2.0.1 jar + + org.jenkins-ci.plugins + matrix-project + 1.6 + + + org.jenkins-ci + htmlunit + 2.6-jenkins-6 + test + diff --git a/src/main/resources/hudson/plugins/throttleconcurrents/Messages.properties b/src/main/resources/hudson/plugins/throttleconcurrents/Messages.properties index 949b92e3..98caeb7d 100644 --- a/src/main/resources/hudson/plugins/throttleconcurrents/Messages.properties +++ b/src/main/resources/hudson/plugins/throttleconcurrents/Messages.properties @@ -1,5 +1,6 @@ ThrottleQueueTaskDispatcher.MaxCapacityOnNode=Already running {0} builds on node ThrottleQueueTaskDispatcher.MaxCapacityTotal=Already running {0} builds across all nodes ThrottleQueueTaskDispatcher.BuildPending=A build is pending launch +ThrottleQueueTaskDispatcher.OnlyOneWithMatchingParameters=A build with matching parameters is already running ThrottleMatrixProjectOptions.DisplayName=Additional options for Matrix projects \ No newline at end of file diff --git a/src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/config.jelly b/src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/config.jelly index e18c2cf3..042b5b48 100644 --- a/src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/config.jelly +++ b/src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/config.jelly @@ -20,6 +20,18 @@ field="maxConcurrentPerNode"> + + + + + + + diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly index 80496c8b..656d7c9c 100644 --- a/src/main/resources/index.jelly +++ b/src/main/resources/index.jelly @@ -1,3 +1,4 @@ + - - 4.0.0 + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 1.596.1 + - - org.jenkins-ci.plugins - plugin - 1.596.1 - + throttle-concurrents + hpi + Jenkins Throttle Concurrent Builds Plug-in + 1.8.5-SNAPSHOT + http://wiki.jenkins-ci.org/display/JENKINS/Throttle+Concurrent+Builds+Plugin + Plugin to throttle the number of concurrent builds of a single job per node. - throttle-concurrents - hpi - Jenkins Throttle Concurrent Builds Plug-in - 1.8.5-SNAPSHOT - http://wiki.jenkins-ci.org/display/JENKINS/Throttle+Concurrent+Builds+Plugin - Plugin to throttle the number of concurrent builds of a single job per node. - - - - MIT license - All source code is under the MIT license. - - - - - - abayer - Andrew Bayer - andrew.bayer@gmail.com - -8 - - - oleg_nenashev - Oleg Nenashev - o.v.nenashev@gmail.com - +3 - - - balldarrens - Darren Ball - balldarrens@gmail.com - -5 - - - - - scm:git:git://github.com/jenkinsci/throttle-concurrent-builds-plugin.git - scm:git:git@github.com:jenkinsci/throttle-concurrent-builds-plugin.git - - http://github.com/jenkinsci/throttle-concurrents-plugin - + + + MIT license + All source code is under the MIT license. + + @@ -80,6 +50,7 @@ THE SOFTWARE. 1.7 + @@ -110,19 +81,41 @@ THE SOFTWARE. - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - + + + abayer + Andrew Bayer + andrew.bayer@gmail.com + -8 + + + oleg_nenashev + Oleg Nenashev + o.v.nenashev@gmail.com + +3 + + + + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + + + + scm:git:git://github.com/jenkinsci/throttle-concurrent-builds-plugin.git + scm:git:git@github.com:jenkinsci/throttle-concurrent-builds-plugin.git + http://github.com/jenkinsci/throttle-concurrents-plugin + + + repo.jenkins-ci.org http://repo.jenkins-ci.org/public/ - com.google.code.findbugs From e85f7cbe46767b4f5e94ddb4a5132f2ccdc3a71b Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 15:04:19 -0500 Subject: [PATCH 06/27] Adding previous property logic --- .../ThrottleJobProperty.java | 118 ++++++++++++------ .../help-limitOneJobWithMatchingParams.html | 6 + .../ThrottleIntegrationTest.java | 4 + .../ThrottleJobPropertyTest.java | 15 ++- 4 files changed, 103 insertions(+), 40 deletions(-) create mode 100644 src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/help-limitOneJobWithMatchingParams.html diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java index 98a8c193..69131ed3 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java @@ -16,6 +16,7 @@ import hudson.matrix.MatrixBuild; import hudson.matrix.MatrixProject; +import java.util.Arrays; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -36,29 +37,35 @@ public class ThrottleJobProperty extends JobProperty> { // Moving category to categories, to support, well, multiple categories per job. @Deprecated transient String category; - + private Integer maxConcurrentPerNode; private Integer maxConcurrentTotal; private List categories; private boolean throttleEnabled; private String throttleOption; + private boolean limitOneJobWithMatchingParams; private transient boolean throttleConfiguration; private @CheckForNull ThrottleMatrixProjectOptions matrixOptions; + private String paramsToUseForLimit; + private transient List paramsToCompare; + /** * Store a config version so we're able to migrate config on various * functionality upgrades. */ private Long configVersion; - + @DataBoundConstructor public ThrottleJobProperty(Integer maxConcurrentPerNode, Integer maxConcurrentTotal, List categories, boolean throttleEnabled, String throttleOption, + boolean limitOneJobWithMatchingParams, + String paramsToUseForLimit, @CheckForNull ThrottleMatrixProjectOptions matrixOptions - ) { + ) { this.maxConcurrentPerNode = maxConcurrentPerNode == null ? 0 : maxConcurrentPerNode; this.maxConcurrentTotal = maxConcurrentTotal == null ? 0 : maxConcurrentTotal; this.categories = categories == null ? @@ -66,9 +73,22 @@ public ThrottleJobProperty(Integer maxConcurrentPerNode, new CopyOnWriteArrayList(categories); this.throttleEnabled = throttleEnabled; this.throttleOption = throttleOption; + this.limitOneJobWithMatchingParams = limitOneJobWithMatchingParams; this.matrixOptions = matrixOptions; - } + this.paramsToUseForLimit = paramsToUseForLimit; + if ((this.paramsToUseForLimit != null)) { + if ((this.paramsToUseForLimit.length() > 0)) { + this.paramsToCompare = Arrays.asList(this.paramsToUseForLimit.split(",")); + } + else { + this.paramsToCompare = new ArrayList(); + } + } + else { + this.paramsToCompare = new ArrayList(); + } + } /** * Migrates deprecated/obsolete data @@ -95,20 +115,21 @@ public Object readResolve() { maxConcurrentTotal = 0; } } + configVersion = 1L; - + // Handle the throttleConfiguration in custom builds (not released) if (throttleConfiguration && matrixOptions == null) { matrixOptions = new ThrottleMatrixProjectOptions(false, true); } - + return this; } @Override protected void setOwner(Job owner) { super.setOwner(owner); if (throttleEnabled && categories != null) { - DescriptorImpl descriptor = (DescriptorImpl) getDescriptor(); + DescriptorImpl descriptor = (DescriptorImpl) getDescriptor(); synchronized (descriptor.propertiesByCategoryLock) { for (String c : categories) { Map properties = descriptor.propertiesByCategory.get(c); @@ -126,56 +147,81 @@ public boolean getThrottleEnabled() { return throttleEnabled; } + public boolean isLimitOneJobWithMatchingParams() { + return limitOneJobWithMatchingParams; + } + public String getThrottleOption() { return throttleOption; } - + public List getCategories() { return categories; } - + public Integer getMaxConcurrentPerNode() { if (maxConcurrentPerNode == null) maxConcurrentPerNode = 0; - + return maxConcurrentPerNode; } public Integer getMaxConcurrentTotal() { if (maxConcurrentTotal == null) maxConcurrentTotal = 0; - + return maxConcurrentTotal; } + public String getParamsToUseForLimit() { + return paramsToUseForLimit; + } + @CheckForNull public ThrottleMatrixProjectOptions getMatrixOptions() { return matrixOptions; } - + /** * Check if the build throttles {@link MatrixBuild}s. */ public boolean isThrottleMatrixBuilds() { - return matrixOptions != null - ? matrixOptions.isThrottleMatrixBuilds() + return matrixOptions != null + ? matrixOptions.isThrottleMatrixBuilds() : ThrottleMatrixProjectOptions.DEFAULT.isThrottleMatrixBuilds(); } - + /** * Check if the build throttles {@link MatrixConfiguration}s. */ public boolean isThrottleMatrixConfigurations() { - return matrixOptions != null - ? matrixOptions.isThrottleMatrixConfigurations() + return matrixOptions != null + ? matrixOptions.isThrottleMatrixConfigurations() : ThrottleMatrixProjectOptions.DEFAULT.isThrottleMatrixConfigurations(); } + public List getParamsToCompare() { + if (paramsToCompare == null) { + if ((paramsToUseForLimit != null)) { + if ((paramsToUseForLimit.length() > 0)) { + paramsToCompare = Arrays.asList(paramsToUseForLimit.split(",")); + } + else { + paramsToCompare = new ArrayList(); + } + } + else { + paramsToCompare = new ArrayList(); + } + } + return paramsToCompare; + } + static List getCategoryTasks(String category) { assert category != null && !category.equals(""); List categoryTasks = new ArrayList(); Collection properties; - DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class); + DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class); synchronized (descriptor.propertiesByCategoryLock) { Map _properties = descriptor.propertiesByCategory.get(category); properties = _properties != null ? new ArrayList(_properties.keySet()) : Collections.emptySet(); @@ -198,6 +244,7 @@ static List getCategoryTasks(String category) { } return categoryTasks; } + private static Item getItem(ItemGroup group, String name) { if (group instanceof Jenkins) { return ((Jenkins) group).getItemMap().get(name); @@ -205,14 +252,14 @@ private static Item getItem(ItemGroup group, String name) { return group.getItem(name); } } - + @Extension public static final class DescriptorImpl extends JobPropertyDescriptor { private List categories; - + /** Map from category names, to properties including that category. */ - private transient Map> propertiesByCategory - = new HashMap>(); + private transient Map> propertiesByCategory + = new HashMap>(); /** A sync object for {@link #propertiesByCategory} */ private final transient Object propertiesByCategoryLock = new Object(); @@ -235,13 +282,13 @@ public DescriptorImpl() { public String getDisplayName() { return "Throttle Concurrent Builds"; } - + @Override @SuppressWarnings("rawtypes") public boolean isApplicable(Class jobType) { return Job.class.isAssignableFrom(jobType) && Queue.Task.class.isAssignableFrom(jobType); } - + public boolean isMatrixProject(Job job) { return job instanceof MatrixProject; } @@ -279,10 +326,9 @@ public FormValidation doCheckMaxConcurrentTotal(@QueryParameter String value) { return checkNullOrInt(value); } - public ThrottleCategory getCategoryByName(String categoryName) { ThrottleCategory category = null; - + for (ThrottleCategory tc : categories) { if (tc.getCategoryName().equals(categoryName)) { category = tc; @@ -295,7 +341,7 @@ public ThrottleCategory getCategoryByName(String categoryName) { public void setCategories(List categories) { this.categories = new CopyOnWriteArrayList(categories); } - + public List getCategories() { if (categories == null) { categories = new CopyOnWriteArrayList(); @@ -308,14 +354,14 @@ public ListBoxModel doFillCategoryItems() { ListBoxModel m = new ListBoxModel(); m.add("(none)", ""); - + for (ThrottleCategory tc : getCategories()) { m.add(tc.getCategoryName()); } return m; } - + } public static final class ThrottleCategory extends AbstractDescribableImpl { @@ -333,20 +379,20 @@ public ThrottleCategory(String categoryName, this.maxConcurrentTotal = maxConcurrentTotal == null ? 0 : maxConcurrentTotal; this.categoryName = categoryName; this.nodeLabeledPairs = - nodeLabeledPairs == null ? new ArrayList() : nodeLabeledPairs; + nodeLabeledPairs == null ? new ArrayList() : nodeLabeledPairs; } - + public Integer getMaxConcurrentPerNode() { if (maxConcurrentPerNode == null) maxConcurrentPerNode = 0; - + return maxConcurrentPerNode; } - + public Integer getMaxConcurrentTotal() { if (maxConcurrentTotal == null) maxConcurrentTotal = 0; - + return maxConcurrentTotal; } @@ -360,7 +406,7 @@ public List getNodeLabeledPairs() { return nodeLabeledPairs; } - + @Extension public static class DescriptorImpl extends Descriptor { @Override @@ -382,7 +428,7 @@ public NodeLabeledPair(String throttledNodeLabel, Integer maxConcurrentPerNodeLabeled) { this.throttledNodeLabel = throttledNodeLabel == null ? new String() : throttledNodeLabel; this.maxConcurrentPerNodeLabeled = - maxConcurrentPerNodeLabeled == null ? new Integer(0) : maxConcurrentPerNodeLabeled; + maxConcurrentPerNodeLabeled == null ? new Integer(0) : maxConcurrentPerNodeLabeled; } public String getThrottledNodeLabel() { diff --git a/src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/help-limitOneJobWithMatchingParams.html b/src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/help-limitOneJobWithMatchingParams.html new file mode 100644 index 00000000..973eab0c --- /dev/null +++ b/src/main/resources/hudson/plugins/throttleconcurrents/ThrottleJobProperty/help-limitOneJobWithMatchingParams.html @@ -0,0 +1,6 @@ +
+

If this box is checked, only one instance of the job with matching parameters will be allowed to run at a given time. + Other instances of this job with different parameters will be allowed to run concurrently.

+

Optionally, provide a comma-separated list of parameters to use when comparing jobs. If blank, all parameters + must match for a job to be limited to one running instance.

+
diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java index e6efeb26..56cb18f2 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java @@ -123,6 +123,8 @@ public void testThrottlingWithCategory() throws Exception { Arrays.asList(category), // categories true, // throttleEnabled "category", // throttleOption + false, + null, ThrottleMatrixProjectOptions.DEFAULT )); p1.getBuildersList().add(new SleepBuilder(SLEEP_TIME)); @@ -135,6 +137,8 @@ public void testThrottlingWithCategory() throws Exception { Arrays.asList(category), // categories true, // throttleEnabled "category", // throttleOption + false, + null, ThrottleMatrixProjectOptions.DEFAULT )); p2.getBuildersList().add(new SleepBuilder(SLEEP_TIME)); diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java index ec532db8..09a7cd4f 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java @@ -22,11 +22,11 @@ public void testGetCategoryProjects() throws Exception { String alpha = "alpha", beta = "beta", gamma = "gamma"; // category names FreeStyleProject p1 = createFreeStyleProject("p1"); FreeStyleProject p2 = createFreeStyleProject("p2"); - p2.addProperty(new ThrottleJobProperty(1, 1, Arrays.asList(alpha), false, THROTTLE_OPTION_CATEGORY, ThrottleMatrixProjectOptions.DEFAULT)); + p2.addProperty(new ThrottleJobProperty(1, 1, Arrays.asList(alpha), false, THROTTLE_OPTION_CATEGORY, false, "", ThrottleMatrixProjectOptions.DEFAULT)); FreeStyleProject p3 = createFreeStyleProject("p3"); - p3.addProperty(new ThrottleJobProperty(1, 1, Arrays.asList(alpha, beta), true, THROTTLE_OPTION_CATEGORY, ThrottleMatrixProjectOptions.DEFAULT)); + p3.addProperty(new ThrottleJobProperty(1, 1, Arrays.asList(alpha, beta), true, THROTTLE_OPTION_CATEGORY, false, "", ThrottleMatrixProjectOptions.DEFAULT)); FreeStyleProject p4 = createFreeStyleProject("p4"); - p4.addProperty(new ThrottleJobProperty(1, 1, Arrays.asList(beta, gamma), true, THROTTLE_OPTION_CATEGORY, ThrottleMatrixProjectOptions.DEFAULT)); + p4.addProperty(new ThrottleJobProperty(1, 1, Arrays.asList(beta, gamma), true, THROTTLE_OPTION_CATEGORY, false, "", ThrottleMatrixProjectOptions.DEFAULT)); // TODO when core dep ≥1.480.3, add cloudbees-folder as a test dependency so we can check jobs inside folders assertProjects(alpha, p3); assertProjects(beta, p3, p4); @@ -45,7 +45,7 @@ public void testGetCategoryProjects() throws Exception { public void testToString_withNulls(){ - ThrottleJobProperty tjp = new ThrottleJobProperty(0,0, null, false, null, ThrottleMatrixProjectOptions.DEFAULT); + ThrottleJobProperty tjp = new ThrottleJobProperty(0,0, null, false, null, false, "", ThrottleMatrixProjectOptions.DEFAULT); assertNotNull(tjp.toString()); } @@ -55,10 +55,13 @@ public void testThrottleJob_constructor_should_store_arguments() { List expectedCategories = Collections.emptyList(); boolean expectedThrottleEnabled = anyBoolean(); String expectedThrottleOption = anyString(); + boolean expectedLimitOneJobWithMatchingParams = anyBoolean(); + String expectedParamsToUseForLimit = anyString(); ThrottleJobProperty property = new ThrottleJobProperty(expectedMaxConcurrentPerNode, expectedMaxConcurrentTotal, expectedCategories, expectedThrottleEnabled, expectedThrottleOption, + expectedLimitOneJobWithMatchingParams, expectedParamsToUseForLimit, ThrottleMatrixProjectOptions.DEFAULT); assertEquals(expectedMaxConcurrentPerNode, property.getMaxConcurrentPerNode()); @@ -80,6 +83,8 @@ public void testThrottleJob_should_copy_categories_to_concurrency_safe_list() { unsafeList, anyBoolean(), "throttle_option", + anyBoolean(), + anyString(), ThrottleMatrixProjectOptions.DEFAULT); List storedCategories = property.getCategories(); @@ -95,6 +100,8 @@ public void testThrottleJob_constructor_handles_null_categories(){ null, anyBoolean(), "throttle_option", + anyBoolean(), + anyString(), ThrottleMatrixProjectOptions.DEFAULT); assertEquals(Collections.emptyList(), property.getCategories()); From f29281e0e81b66d06328a47a8719858a8cb0558f Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 19:21:26 -0500 Subject: [PATCH 07/27] Adding previous property logic --- .../ThrottleQueueTaskDispatcher.java | 152 +++++++++++++++--- 1 file changed, 131 insertions(+), 21 deletions(-) diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java index a0440387..43364aa4 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java @@ -3,6 +3,8 @@ import hudson.Extension; import hudson.matrix.MatrixConfiguration; import hudson.matrix.MatrixProject; +import hudson.model.AbstractProject; +import hudson.model.ParameterValue; import hudson.model.Computer; import hudson.model.Executor; import hudson.model.Hudson; @@ -10,10 +12,15 @@ import hudson.model.Node; import hudson.model.Queue; import hudson.model.Queue.Task; +import hudson.model.queue.WorkUnit; import hudson.model.labels.LabelAtom; import hudson.model.queue.CauseOfBlockage; import hudson.model.queue.QueueTaskDispatcher; +import hudson.model.Action; +import hudson.model.ParametersAction; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Set; import java.util.logging.Level; @@ -26,9 +33,9 @@ public class ThrottleQueueTaskDispatcher extends QueueTaskDispatcher { @Override public CauseOfBlockage canTake(Node node, Task task) { - + ThrottleJobProperty tjp = getThrottleJobProperty(task); - + // Handle multi-configuration filters if (!shouldBeThrottled(task, tjp)) { return null; @@ -92,35 +99,38 @@ else if (tjp.getThrottleOption().equals("category")) { public CauseOfBlockage canRun(Queue.Item item) { ThrottleJobProperty tjp = getThrottleJobProperty(item.task); if (tjp!=null && tjp.getThrottleEnabled()) { + if (tjp.isLimitOneJobWithMatchingParams() && isAnotherBuildWithSameParametersRunningOnAnyNode(item)) { + return CauseOfBlockage.fromMessage(Messages._ThrottleQueueTaskDispatcher_OnlyOneWithMatchingParameters()); + } return canRun(item.task, tjp); } return null; } - + @Nonnull private ThrottleMatrixProjectOptions getMatrixOptions(Task task) { ThrottleJobProperty tjp = getThrottleJobProperty(task); - if (tjp == null) return ThrottleMatrixProjectOptions.DEFAULT; + if (tjp == null) return ThrottleMatrixProjectOptions.DEFAULT; ThrottleMatrixProjectOptions matrixOptions = tjp.getMatrixOptions(); return matrixOptions != null ? matrixOptions : ThrottleMatrixProjectOptions.DEFAULT; } - + private boolean shouldBeThrottled(@Nonnull Task task, @CheckForNull ThrottleJobProperty tjp) { - if (tjp == null) return false; - if (!tjp.getThrottleEnabled()) return false; - - // Handle matrix options - ThrottleMatrixProjectOptions matrixOptions = tjp.getMatrixOptions(); - if (matrixOptions == null) matrixOptions = ThrottleMatrixProjectOptions.DEFAULT; - if (!matrixOptions.isThrottleMatrixConfigurations() && task instanceof MatrixConfiguration) { + if (tjp == null) return false; + if (!tjp.getThrottleEnabled()) return false; + + // Handle matrix options + ThrottleMatrixProjectOptions matrixOptions = tjp.getMatrixOptions(); + if (matrixOptions == null) matrixOptions = ThrottleMatrixProjectOptions.DEFAULT; + if (!matrixOptions.isThrottleMatrixConfigurations() && task instanceof MatrixConfiguration) { return false; - } - if (!matrixOptions.isThrottleMatrixBuilds()&& task instanceof MatrixProject) { + } + if (!matrixOptions.isThrottleMatrixBuilds()&& task instanceof MatrixProject) { return false; - } - - // Allow throttling by default - return true; + } + + // Allow throttling by default + return true; } public CauseOfBlockage canRun(Task task, ThrottleJobProperty tjp) { @@ -149,7 +159,7 @@ else if (tjp.getThrottleOption().equals("category")) { List categoryTasks = ThrottleJobProperty.getCategoryTasks(catNm); ThrottleJobProperty.ThrottleCategory category = - ((ThrottleJobProperty.DescriptorImpl)tjp.getDescriptor()).getCategoryByName(catNm); + ((ThrottleJobProperty.DescriptorImpl)tjp.getDescriptor()).getCategoryByName(catNm); // Double check category itself isn't null if (category != null) { @@ -178,6 +188,106 @@ else if (tjp.getThrottleOption().equals("category")) { return null; } + private boolean isAnotherBuildWithSameParametersRunningOnAnyNode(Queue.Item item) { + if (isAnotherBuildWithSameParametersRunningOnNode(Hudson.getInstance(), item)) { + return true; + } + + for (Node node : Hudson.getInstance().getNodes()) { + if (isAnotherBuildWithSameParametersRunningOnNode(node, item)) { + return true; + } + } + return false; + } + + private boolean isAnotherBuildWithSameParametersRunningOnNode(Node node, Queue.Item item) { + ThrottleJobProperty tjp = getThrottleJobProperty(item.task); + Computer computer = node.toComputer(); + List paramsToCompare = tjp.getParamsToCompare(); + List itemParams = getParametersFromQueueItem(item); + + if (paramsToCompare.size() > 0) { + itemParams = doFilterParams(paramsToCompare, itemParams); + } + + if (computer != null) { + for (Executor exec : computer.getExecutors()) { + if (item != null && item.task != null) { + // TODO: refactor into a nameEquals helper method + if (exec.getCurrentExecutable() != null && + exec.getCurrentExecutable().getParent() != null && + exec.getCurrentExecutable().getParent().getOwnerTask() != null && + exec.getCurrentExecutable().getParent().getOwnerTask().getName().equals(item.task.getDisplayName())) { + List executingUnitParams = getParametersFromWorkUnit(exec.getCurrentWorkUnit()); + executingUnitParams = doFilterParams(paramsToCompare, executingUnitParams); + + if (executingUnitParams.containsAll(itemParams)) { + LOGGER.log(Level.FINE, "build (" + exec.getCurrentWorkUnit() + + ") with identical parameters (" + + executingUnitParams + ") is already running."); + return true; + } + } + } + } + } + return false; + } + + /** + * Filter job parameters to only include parameters used for throttling + * @param params + * @param OriginalParams + * @return + */ + private List doFilterParams(List params, List OriginalParams) { + if (params.isEmpty()) { + return OriginalParams; + } + + List newParams = new ArrayList(); + + for (ParameterValue p : OriginalParams) { + if (params.contains(p.getName())) { + newParams.add(p); + } + } + return newParams; + } + + public List getParametersFromWorkUnit(WorkUnit unit) { + List paramsList = new ArrayList(); + + if (unit != null && unit.context != null && unit.context.actions != null) { + List actions = unit.context.actions; + for (Action action : actions) { + if (action instanceof ParametersAction) { + ParametersAction params = (ParametersAction) action; + if (params != null) { + paramsList = params.getParameters(); + } + } + } + } + return paramsList; + } + + public List getParametersFromQueueItem(Queue.Item item) { + List paramsList; + + ParametersAction params = item.getAction(ParametersAction.class); + if (params != null) { + paramsList = params.getParameters(); + } + else + { + paramsList = new ArrayList(); + } + return paramsList; + } + + @CheckForNull private ThrottleJobProperty getThrottleJobProperty(Task task) { if (task instanceof Job) { @@ -228,7 +338,7 @@ private int buildsOfProjectOnAllNodes(Task task) { private int buildsOnExecutor(Task task, Executor exec) { int runCount = 0; if (exec.getCurrentExecutable() != null - && task.equals(exec.getCurrentExecutable().getParent())) { + && task.equals(exec.getCurrentExecutable().getParent())) { runCount++; } @@ -243,7 +353,7 @@ private int buildsOnExecutor(Task task, Executor exec) { * @author marco.miller@ericsson.com */ private int getMaxConcurrentPerNodeBasedOnMatchingLabels( - Node node, ThrottleJobProperty.ThrottleCategory category, int maxConcurrentPerNode) + Node node, ThrottleJobProperty.ThrottleCategory category, int maxConcurrentPerNode) { List nodeLabeledPairs = category.getNodeLabeledPairs(); int maxConcurrentPerNodeLabeledIfMatch = maxConcurrentPerNode; From 3502248941100cb279f02863d031275f1e8c677e Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 19:48:58 -0500 Subject: [PATCH 08/27] Restoring whitespace --- .../ThrottleJobProperty.java | 16 +++++----- .../ThrottleMatrixProjectOptions.java | 3 +- .../ThrottleQueueTaskDispatcher.java | 31 ++++++++++--------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java index 69131ed3..acac2062 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java @@ -1,5 +1,5 @@ package hudson.plugins.throttleconcurrents; - +// @formatter:off import hudson.Extension; import hudson.matrix.MatrixConfiguration; import hudson.model.AbstractDescribableImpl; @@ -65,7 +65,7 @@ public ThrottleJobProperty(Integer maxConcurrentPerNode, boolean limitOneJobWithMatchingParams, String paramsToUseForLimit, @CheckForNull ThrottleMatrixProjectOptions matrixOptions - ) { + ) { this.maxConcurrentPerNode = maxConcurrentPerNode == null ? 0 : maxConcurrentPerNode; this.maxConcurrentTotal = maxConcurrentTotal == null ? 0 : maxConcurrentTotal; this.categories = categories == null ? @@ -87,9 +87,9 @@ public ThrottleJobProperty(Integer maxConcurrentPerNode, else { this.paramsToCompare = new ArrayList(); } - } + /** * Migrates deprecated/obsolete data */ @@ -115,7 +115,6 @@ public Object readResolve() { maxConcurrentTotal = 0; } } - configVersion = 1L; // Handle the throttleConfiguration in custom builds (not released) @@ -244,7 +243,6 @@ static List getCategoryTasks(String category) { } return categoryTasks; } - private static Item getItem(ItemGroup group, String name) { if (group instanceof Jenkins) { return ((Jenkins) group).getItemMap().get(name); @@ -259,7 +257,7 @@ public static final class DescriptorImpl extends JobPropertyDescriptor { /** Map from category names, to properties including that category. */ private transient Map> propertiesByCategory - = new HashMap>(); + = new HashMap>(); /** A sync object for {@link #propertiesByCategory} */ private final transient Object propertiesByCategoryLock = new Object(); @@ -326,6 +324,7 @@ public FormValidation doCheckMaxConcurrentTotal(@QueryParameter String value) { return checkNullOrInt(value); } + public ThrottleCategory getCategoryByName(String categoryName) { ThrottleCategory category = null; @@ -379,7 +378,7 @@ public ThrottleCategory(String categoryName, this.maxConcurrentTotal = maxConcurrentTotal == null ? 0 : maxConcurrentTotal; this.categoryName = categoryName; this.nodeLabeledPairs = - nodeLabeledPairs == null ? new ArrayList() : nodeLabeledPairs; + nodeLabeledPairs == null ? new ArrayList() : nodeLabeledPairs; } public Integer getMaxConcurrentPerNode() { @@ -428,7 +427,7 @@ public NodeLabeledPair(String throttledNodeLabel, Integer maxConcurrentPerNodeLabeled) { this.throttledNodeLabel = throttledNodeLabel == null ? new String() : throttledNodeLabel; this.maxConcurrentPerNodeLabeled = - maxConcurrentPerNodeLabeled == null ? new Integer(0) : maxConcurrentPerNodeLabeled; + maxConcurrentPerNodeLabeled == null ? new Integer(0) : maxConcurrentPerNodeLabeled; } public String getThrottledNodeLabel() { @@ -454,3 +453,4 @@ public String getDisplayName() { } } } +// @formatter:on \ No newline at end of file diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java index e0cb062a..a01053bc 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java @@ -23,7 +23,7 @@ */ package hudson.plugins.throttleconcurrents; - +// @formatter:off import hudson.Extension; import hudson.matrix.MatrixBuild; import hudson.matrix.MatrixConfiguration; @@ -86,3 +86,4 @@ public ThrottleMatrixProjectOptions getDefaults() { } } } +// @formatter:on \ No newline at end of file diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java index 43364aa4..a7c047f8 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java @@ -1,5 +1,5 @@ package hudson.plugins.throttleconcurrents; - +// @formatter:off import hudson.Extension; import hudson.matrix.MatrixConfiguration; import hudson.matrix.MatrixProject; @@ -116,21 +116,21 @@ private ThrottleMatrixProjectOptions getMatrixOptions(Task task) { } private boolean shouldBeThrottled(@Nonnull Task task, @CheckForNull ThrottleJobProperty tjp) { - if (tjp == null) return false; - if (!tjp.getThrottleEnabled()) return false; + if (tjp == null) return false; + if (!tjp.getThrottleEnabled()) return false; - // Handle matrix options - ThrottleMatrixProjectOptions matrixOptions = tjp.getMatrixOptions(); - if (matrixOptions == null) matrixOptions = ThrottleMatrixProjectOptions.DEFAULT; - if (!matrixOptions.isThrottleMatrixConfigurations() && task instanceof MatrixConfiguration) { + // Handle matrix options + ThrottleMatrixProjectOptions matrixOptions = tjp.getMatrixOptions(); + if (matrixOptions == null) matrixOptions = ThrottleMatrixProjectOptions.DEFAULT; + if (!matrixOptions.isThrottleMatrixConfigurations() && task instanceof MatrixConfiguration) { return false; - } - if (!matrixOptions.isThrottleMatrixBuilds()&& task instanceof MatrixProject) { + } + if (!matrixOptions.isThrottleMatrixBuilds()&& task instanceof MatrixProject) { return false; - } + } - // Allow throttling by default - return true; + // Allow throttling by default + return true; } public CauseOfBlockage canRun(Task task, ThrottleJobProperty tjp) { @@ -159,7 +159,7 @@ else if (tjp.getThrottleOption().equals("category")) { List categoryTasks = ThrottleJobProperty.getCategoryTasks(catNm); ThrottleJobProperty.ThrottleCategory category = - ((ThrottleJobProperty.DescriptorImpl)tjp.getDescriptor()).getCategoryByName(catNm); + ((ThrottleJobProperty.DescriptorImpl)tjp.getDescriptor()).getCategoryByName(catNm); // Double check category itself isn't null if (category != null) { @@ -338,7 +338,7 @@ private int buildsOfProjectOnAllNodes(Task task) { private int buildsOnExecutor(Task task, Executor exec) { int runCount = 0; if (exec.getCurrentExecutable() != null - && task.equals(exec.getCurrentExecutable().getParent())) { + && task.equals(exec.getCurrentExecutable().getParent())) { runCount++; } @@ -353,7 +353,7 @@ private int buildsOnExecutor(Task task, Executor exec) { * @author marco.miller@ericsson.com */ private int getMaxConcurrentPerNodeBasedOnMatchingLabels( - Node node, ThrottleJobProperty.ThrottleCategory category, int maxConcurrentPerNode) + Node node, ThrottleJobProperty.ThrottleCategory category, int maxConcurrentPerNode) { List nodeLabeledPairs = category.getNodeLabeledPairs(); int maxConcurrentPerNodeLabeledIfMatch = maxConcurrentPerNode; @@ -382,3 +382,4 @@ private int getMaxConcurrentPerNodeBasedOnMatchingLabels( private static final Logger LOGGER = Logger.getLogger(ThrottleQueueTaskDispatcher.class.getName()); } +// @formatter:on \ No newline at end of file From 8569c5f004e69d94730010d2021cecd376aa63cc Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 19:52:30 -0500 Subject: [PATCH 09/27] Restoring whitespace - tests --- pom.xml | 5 +++-- .../plugins/throttleconcurrents/ThrottleCategoryTest.java | 3 ++- .../plugins/throttleconcurrents/ThrottleIntegrationTest.java | 3 ++- .../plugins/throttleconcurrents/ThrottleJobPropertyTest.java | 3 ++- .../throttleconcurrents/ThrottleQueueTaskDispatcherTest.java | 2 ++ 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index e079e772..d38909ee 100644 --- a/pom.xml +++ b/pom.xml @@ -1,3 +1,4 @@ + \ No newline at end of file diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java index d0488566..e9bfcc32 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java @@ -15,7 +15,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package hudson.plugins.throttleconcurrents; - +// @formatter:off import static org.junit.Assert.*; import java.util.List; @@ -60,3 +60,4 @@ public void shouldGetNonEmptyNodeLabeledPairsListThatWasSet() expectedMax, actualMax); } } +// @formatter:on \ No newline at end of file diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java index 56cb18f2..bb0e08ab 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - +// @formatter:off package hudson.plugins.throttleconcurrents; import hudson.EnvVars; @@ -152,3 +152,4 @@ public void testThrottlingWithCategory() throws Exception { assertEquals(1, waterMark.getExecutorWaterMark()); } } +// @formatter:on \ No newline at end of file diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java index 09a7cd4f..654ec18a 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java @@ -1,5 +1,5 @@ package hudson.plugins.throttleconcurrents; - +// @formatter:off import hudson.model.AbstractProject; import hudson.model.FreeStyleProject; import hudson.model.Job; @@ -166,3 +166,4 @@ private int anyInt() { } } +// @formatter:on \ No newline at end of file diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java index d317f977..1f4d547d 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java @@ -14,6 +14,7 @@ * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +// @formatter:off package hudson.plugins.throttleconcurrents; import com.gargoylesoftware.htmlunit.html.HtmlButton; @@ -407,3 +408,4 @@ private HtmlPage getLoggerPage(String logger) return createWebClient().getPage(url); } } +// @formatter:on \ No newline at end of file From c7f5f5cace858124f1cad2fe5f9d43b50e6f45c8 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 20:01:47 -0500 Subject: [PATCH 10/27] Restoring whitespace - ThrottleProperty.java --- .../hudson/plugins/throttleconcurrents/ThrottleJobProperty.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java index acac2062..1accda13 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java @@ -453,4 +453,3 @@ public String getDisplayName() { } } } -// @formatter:on \ No newline at end of file From 8af5067478067116e4985a9f18a97d87d2d2d11c Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 20:08:06 -0500 Subject: [PATCH 11/27] Restoring whitespace - ThrottleProperty.java --- .../ThrottleJobProperty.java | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java index 1accda13..ff97d6d9 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleJobProperty.java @@ -1,5 +1,5 @@ package hudson.plugins.throttleconcurrents; -// @formatter:off + import hudson.Extension; import hudson.matrix.MatrixConfiguration; import hudson.model.AbstractDescribableImpl; @@ -37,7 +37,7 @@ public class ThrottleJobProperty extends JobProperty> { // Moving category to categories, to support, well, multiple categories per job. @Deprecated transient String category; - + private Integer maxConcurrentPerNode; private Integer maxConcurrentTotal; private List categories; @@ -55,7 +55,7 @@ public class ThrottleJobProperty extends JobProperty> { * functionality upgrades. */ private Long configVersion; - + @DataBoundConstructor public ThrottleJobProperty(Integer maxConcurrentPerNode, Integer maxConcurrentTotal, @@ -116,19 +116,19 @@ public Object readResolve() { } } configVersion = 1L; - + // Handle the throttleConfiguration in custom builds (not released) if (throttleConfiguration && matrixOptions == null) { matrixOptions = new ThrottleMatrixProjectOptions(false, true); } - + return this; } @Override protected void setOwner(Job owner) { super.setOwner(owner); if (throttleEnabled && categories != null) { - DescriptorImpl descriptor = (DescriptorImpl) getDescriptor(); + DescriptorImpl descriptor = (DescriptorImpl) getDescriptor(); synchronized (descriptor.propertiesByCategoryLock) { for (String c : categories) { Map properties = descriptor.propertiesByCategory.get(c); @@ -153,22 +153,22 @@ public boolean isLimitOneJobWithMatchingParams() { public String getThrottleOption() { return throttleOption; } - + public List getCategories() { return categories; } - + public Integer getMaxConcurrentPerNode() { if (maxConcurrentPerNode == null) maxConcurrentPerNode = 0; - + return maxConcurrentPerNode; } public Integer getMaxConcurrentTotal() { if (maxConcurrentTotal == null) maxConcurrentTotal = 0; - + return maxConcurrentTotal; } @@ -180,22 +180,22 @@ public String getParamsToUseForLimit() { public ThrottleMatrixProjectOptions getMatrixOptions() { return matrixOptions; } - + /** * Check if the build throttles {@link MatrixBuild}s. */ public boolean isThrottleMatrixBuilds() { - return matrixOptions != null - ? matrixOptions.isThrottleMatrixBuilds() + return matrixOptions != null + ? matrixOptions.isThrottleMatrixBuilds() : ThrottleMatrixProjectOptions.DEFAULT.isThrottleMatrixBuilds(); } - + /** * Check if the build throttles {@link MatrixConfiguration}s. */ public boolean isThrottleMatrixConfigurations() { - return matrixOptions != null - ? matrixOptions.isThrottleMatrixConfigurations() + return matrixOptions != null + ? matrixOptions.isThrottleMatrixConfigurations() : ThrottleMatrixProjectOptions.DEFAULT.isThrottleMatrixConfigurations(); } @@ -220,7 +220,7 @@ static List getCategoryTasks(String category) { assert category != null && !category.equals(""); List categoryTasks = new ArrayList(); Collection properties; - DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class); + DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class); synchronized (descriptor.propertiesByCategoryLock) { Map _properties = descriptor.propertiesByCategory.get(category); properties = _properties != null ? new ArrayList(_properties.keySet()) : Collections.emptySet(); @@ -250,13 +250,13 @@ private static Item getItem(ItemGroup group, String name) { return group.getItem(name); } } - + @Extension public static final class DescriptorImpl extends JobPropertyDescriptor { private List categories; - + /** Map from category names, to properties including that category. */ - private transient Map> propertiesByCategory + private transient Map> propertiesByCategory = new HashMap>(); /** A sync object for {@link #propertiesByCategory} */ private final transient Object propertiesByCategoryLock = new Object(); @@ -280,13 +280,13 @@ public DescriptorImpl() { public String getDisplayName() { return "Throttle Concurrent Builds"; } - + @Override @SuppressWarnings("rawtypes") public boolean isApplicable(Class jobType) { return Job.class.isAssignableFrom(jobType) && Queue.Task.class.isAssignableFrom(jobType); } - + public boolean isMatrixProject(Job job) { return job instanceof MatrixProject; } @@ -324,10 +324,10 @@ public FormValidation doCheckMaxConcurrentTotal(@QueryParameter String value) { return checkNullOrInt(value); } - + public ThrottleCategory getCategoryByName(String categoryName) { ThrottleCategory category = null; - + for (ThrottleCategory tc : categories) { if (tc.getCategoryName().equals(categoryName)) { category = tc; @@ -340,7 +340,7 @@ public ThrottleCategory getCategoryByName(String categoryName) { public void setCategories(List categories) { this.categories = new CopyOnWriteArrayList(categories); } - + public List getCategories() { if (categories == null) { categories = new CopyOnWriteArrayList(); @@ -353,14 +353,14 @@ public ListBoxModel doFillCategoryItems() { ListBoxModel m = new ListBoxModel(); m.add("(none)", ""); - + for (ThrottleCategory tc : getCategories()) { m.add(tc.getCategoryName()); } return m; } - + } public static final class ThrottleCategory extends AbstractDescribableImpl { @@ -380,18 +380,18 @@ public ThrottleCategory(String categoryName, this.nodeLabeledPairs = nodeLabeledPairs == null ? new ArrayList() : nodeLabeledPairs; } - + public Integer getMaxConcurrentPerNode() { if (maxConcurrentPerNode == null) maxConcurrentPerNode = 0; - + return maxConcurrentPerNode; } - + public Integer getMaxConcurrentTotal() { if (maxConcurrentTotal == null) maxConcurrentTotal = 0; - + return maxConcurrentTotal; } @@ -405,7 +405,7 @@ public List getNodeLabeledPairs() { return nodeLabeledPairs; } - + @Extension public static class DescriptorImpl extends Descriptor { @Override From 99278101cdaab21ecfde37fd21c30cba6428e26d Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 20:09:17 -0500 Subject: [PATCH 12/27] Restoring whitespace - ThrottleMatrixProjectOptions.java --- .../throttleconcurrents/ThrottleMatrixProjectOptions.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java index a01053bc..e0cb062a 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleMatrixProjectOptions.java @@ -23,7 +23,7 @@ */ package hudson.plugins.throttleconcurrents; -// @formatter:off + import hudson.Extension; import hudson.matrix.MatrixBuild; import hudson.matrix.MatrixConfiguration; @@ -86,4 +86,3 @@ public ThrottleMatrixProjectOptions getDefaults() { } } } -// @formatter:on \ No newline at end of file From c187ec9bb59e2b4e45401b616550f127f208bcc0 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 20:11:37 -0500 Subject: [PATCH 13/27] Restoring whitespace - ThrottleQueueTaskDispatcher.java --- .../ThrottleQueueTaskDispatcher.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java index a7c047f8..15a88eea 100644 --- a/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java +++ b/src/main/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcher.java @@ -1,5 +1,5 @@ package hudson.plugins.throttleconcurrents; -// @formatter:off + import hudson.Extension; import hudson.matrix.MatrixConfiguration; import hudson.matrix.MatrixProject; @@ -33,9 +33,9 @@ public class ThrottleQueueTaskDispatcher extends QueueTaskDispatcher { @Override public CauseOfBlockage canTake(Node node, Task task) { - + ThrottleJobProperty tjp = getThrottleJobProperty(task); - + // Handle multi-configuration filters if (!shouldBeThrottled(task, tjp)) { return null; @@ -106,29 +106,29 @@ public CauseOfBlockage canRun(Queue.Item item) { } return null; } - + @Nonnull private ThrottleMatrixProjectOptions getMatrixOptions(Task task) { ThrottleJobProperty tjp = getThrottleJobProperty(task); - if (tjp == null) return ThrottleMatrixProjectOptions.DEFAULT; + if (tjp == null) return ThrottleMatrixProjectOptions.DEFAULT; ThrottleMatrixProjectOptions matrixOptions = tjp.getMatrixOptions(); return matrixOptions != null ? matrixOptions : ThrottleMatrixProjectOptions.DEFAULT; } - + private boolean shouldBeThrottled(@Nonnull Task task, @CheckForNull ThrottleJobProperty tjp) { if (tjp == null) return false; if (!tjp.getThrottleEnabled()) return false; - + // Handle matrix options ThrottleMatrixProjectOptions matrixOptions = tjp.getMatrixOptions(); if (matrixOptions == null) matrixOptions = ThrottleMatrixProjectOptions.DEFAULT; if (!matrixOptions.isThrottleMatrixConfigurations() && task instanceof MatrixConfiguration) { return false; - } + } if (!matrixOptions.isThrottleMatrixBuilds()&& task instanceof MatrixProject) { return false; } - + // Allow throttling by default return true; } @@ -382,4 +382,3 @@ private int getMaxConcurrentPerNodeBasedOnMatchingLabels( private static final Logger LOGGER = Logger.getLogger(ThrottleQueueTaskDispatcher.class.getName()); } -// @formatter:on \ No newline at end of file From 4416d5d6ac79940c489970d1faf0c22c54515d32 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 21:16:30 -0500 Subject: [PATCH 14/27] Restoring whitespace - ThrottleIntegrationTest.java --- .../ThrottleIntegrationTest.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java index bb0e08ab..09ace0b0 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleIntegrationTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2016 IKEDA Yasuyuki - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -// @formatter:off + package hudson.plugins.throttleconcurrents; import hudson.EnvVars; @@ -48,7 +48,7 @@ public class ThrottleIntegrationTest extends HudsonTestCase { private int executorNum = 2; private ExecutorWaterMarkRetentionStrategy waterMark; private DumbSlave slave = null; - + /** * Overrides to modify the number of executor. */ @@ -70,7 +70,7 @@ public DumbSlave createSlave(String nodeName, String labels, EnvVars env) throws return slave; } } - + /** * sets up slave and waterMark. */ @@ -79,31 +79,31 @@ private void setupSlave() throws Exception { waterMark = new ExecutorWaterMarkRetentionStrategy(slave.getRetentionStrategy()); slave.setRetentionStrategy(waterMark); } - + public void testNoThrottling() throws Exception { setupSlave(); - + FreeStyleProject p1 = createFreeStyleProject(); p1.setAssignedNode(slave); p1.getBuildersList().add(new SleepBuilder(SLEEP_TIME)); - + FreeStyleProject p2 = createFreeStyleProject(); p2.setAssignedNode(slave); p2.getBuildersList().add(new SleepBuilder(SLEEP_TIME)); - + p1.scheduleBuild2(0); p2.scheduleBuild2(0); - + waitUntilNoActivity(); - + // not throttled, and builds run concurrently. assertEquals(2, waterMark.getExecutorWaterMark()); } - + public void testThrottlingWithCategory() throws Exception { setupSlave(); final String category = "category"; - + ThrottleJobProperty.DescriptorImpl descriptor = (ThrottleJobProperty.DescriptorImpl)jenkins.getDescriptor(ThrottleJobProperty.class); descriptor.setCategories(Arrays.asList( @@ -114,7 +114,7 @@ public void testThrottlingWithCategory() throws Exception { Collections.emptyList() ) )); - + FreeStyleProject p1 = createFreeStyleProject(); p1.setAssignedNode(slave); p1.addProperty(new ThrottleJobProperty( @@ -128,7 +128,7 @@ public void testThrottlingWithCategory() throws Exception { ThrottleMatrixProjectOptions.DEFAULT )); p1.getBuildersList().add(new SleepBuilder(SLEEP_TIME)); - + FreeStyleProject p2 = createFreeStyleProject(); p2.setAssignedNode(slave); p2.addProperty(new ThrottleJobProperty( @@ -142,14 +142,13 @@ public void testThrottlingWithCategory() throws Exception { ThrottleMatrixProjectOptions.DEFAULT )); p2.getBuildersList().add(new SleepBuilder(SLEEP_TIME)); - + p1.scheduleBuild2(0); p2.scheduleBuild2(0); - + waitUntilNoActivity(); - + // throttled, and only one build runs at the same time. assertEquals(1, waterMark.getExecutorWaterMark()); } } -// @formatter:on \ No newline at end of file From 0f9777f76bb34a5f4ec5144ced4815259a9230b7 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 21:18:33 -0500 Subject: [PATCH 15/27] Restoring whitespace - ThrottleJobPropertyTest.java --- .../plugins/throttleconcurrents/ThrottleJobPropertyTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java index 654ec18a..09a7cd4f 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleJobPropertyTest.java @@ -1,5 +1,5 @@ package hudson.plugins.throttleconcurrents; -// @formatter:off + import hudson.model.AbstractProject; import hudson.model.FreeStyleProject; import hudson.model.Job; @@ -166,4 +166,3 @@ private int anyInt() { } } -// @formatter:on \ No newline at end of file From 74e251aeb4a3243c93a98a9be5aedb9f8431a861 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 21:20:05 -0500 Subject: [PATCH 16/27] Restoring whitespace - ThrottleQueueTaskDispatcherTest.java --- .../throttleconcurrents/ThrottleQueueTaskDispatcherTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java index 1f4d547d..d317f977 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleQueueTaskDispatcherTest.java @@ -14,7 +14,6 @@ * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -// @formatter:off package hudson.plugins.throttleconcurrents; import com.gargoylesoftware.htmlunit.html.HtmlButton; @@ -408,4 +407,3 @@ private HtmlPage getLoggerPage(String logger) return createWebClient().getPage(url); } } -// @formatter:on \ No newline at end of file From f2039ed4410164be5b1bded59ad532bd4bd452e4 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 21:21:16 -0500 Subject: [PATCH 17/27] Restoring whitespace - ThrottleCategoryTest.java --- .../plugins/throttleconcurrents/ThrottleCategoryTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java index e9bfcc32..d0488566 100644 --- a/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java +++ b/src/test/java/hudson/plugins/throttleconcurrents/ThrottleCategoryTest.java @@ -15,7 +15,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package hudson.plugins.throttleconcurrents; -// @formatter:off + import static org.junit.Assert.*; import java.util.List; @@ -60,4 +60,3 @@ public void shouldGetNonEmptyNodeLabeledPairsListThatWasSet() expectedMax, actualMax); } } -// @formatter:on \ No newline at end of file From 0194eaaabf9a2194a5c0bc16b3846548606d7b6c Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 21:37:23 -0500 Subject: [PATCH 18/27] Re-organize pom for easier review. --- pom.xml | 70 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index d38909ee..674b655d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,3 @@ - UTF-8 1.7 1.7 - - - - - - - maven-clean-plugin - ${maven-clean-plugin.version} - - - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${compileSource} - ${compileTarget} - false - false - - - - - - - org.apache.maven.plugins - maven-release-plugin - - deploy - - - - + + + + + + maven-clean-plugin + ${maven-clean-plugin.version} + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${compileSource} + ${compileTarget}} + false + false + + + + + + + org.apache.maven.plugins + maven-release-plugin + + deploy + + + + @@ -136,5 +134,5 @@ THE SOFTWARE. test
-
- \ No newline at end of file +
+ From b988253e8f7b12a608aac2e759b863fea80594b9 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 21:43:53 -0500 Subject: [PATCH 19/27] Adding contributors to pom --- pom.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 674b655d..5d591902 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,14 @@ THE SOFTWARE. +3 - + + + + Darren Ball + balldarrens@gmail.com + + + repo.jenkins-ci.org From 6c033fa13068315a9215fee193d783e05541c341 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 21:46:25 -0500 Subject: [PATCH 20/27] Whitespace --- pom.xml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 5d591902..9346a474 100644 --- a/pom.xml +++ b/pom.xml @@ -43,12 +43,11 @@ THE SOFTWARE. - - - UTF-8 - 1.7 - 1.7 - + + UTF-8 + 1.7 + 1.7 + From e505a081b326caefb89e9906a505a58e2babb495 Mon Sep 17 00:00:00 2001 From: Darren Ball Date: Mon, 22 Feb 2016 22:01:11 -0500 Subject: [PATCH 21/27] Removing extra jelly. --- src/main/resources/index.jelly | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly index 656d7c9c..80496c8b 100644 --- a/src/main/resources/index.jelly +++ b/src/main/resources/index.jelly @@ -1,4 +1,3 @@ -