diff --git a/.mvn_exec_spotless b/.mvn_exec_spotless new file mode 100644 index 00000000..e69de29b diff --git a/pom.xml b/pom.xml index 677f73d1..6459315c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,197 +1,172 @@ - 4.0.0 - - org.jenkins-ci.plugins - plugin - 4.58 - - - - 4.1.1 - -SNAPSHOT - jenkinsci/priority-sorter-plugin - 2.361.4 - 6.55.0 - Max - Low - - PrioritySorter - ${revision}${changelist} - hpi - Jenkins Priority Sorter Plugin - https://github.com/jenkinsci/priority-sorter-plugin + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.59 + + - - - MIT - https://opensource.org/licenses/MIT - - Copyright 2020- Frank Ittermann. All rights reserved. - Copyright 2013- Magnus Sandberg. All rights reserved. - Copyright 2010- Brad Larson. All rights reserved. - - - + PrioritySorter + ${revision}${changelist} + hpi + Jenkins Priority Sorter Plugin + https://github.com/jenkinsci/priority-sorter-plugin - - - markewaite - Mark Waite - mark.earl.waite@gmail.com - - maintainer - - America/Denver - - + + + MIT + https://opensource.org/licenses/MIT + Copyright 2020- Frank Ittermann. All rights reserved. Copyright 2013- Magnus Sandberg. All rights reserved. Copyright 2010- Brad Larson. All rights reserved. + + - - - - io.jenkins.tools.bom - bom-2.361.x - 1981.v17df70e84a_a_1 - import - pom - - - + + + markewaite + Mark Waite + mark.earl.waite@gmail.com + + maintainer + + America/Denver + + - - - - - com.diffplug.spotless - spotless-maven-plugin - 2.35.0 - - - - - - - - - - - - - - check - - - - - - org.apache.maven.plugins - maven-pmd-plugin - 3.20.0 - - - net.sourceforge.pmd - pmd-core - ${pmdVersion} - - - net.sourceforge.pmd - pmd-java - ${pmdVersion} - - - - - - - - org.apache.maven.plugins - maven-pmd-plugin - 3.20.0 - - - - cpd-check - - - - - - + + scm:git:https://github.com/${gitHubRepo}.git + scm:git:git@github.com:${gitHubRepo}.git + ${scmTag} + https://github.com/${gitHubRepo} + - - - io.jenkins.plugins - ionicons-api - - - org.jenkins-ci.plugins - matrix-project - true - - - org.jenkins-ci.plugins - cloudbees-folder - true - - - com.synopsys.arc.jenkinsci.plugins - job-restrictions - 0.8 - true - - - org.jenkins-ci.plugins.workflow - workflow-durable-task-step - true - - - org.jenkins-ci.plugins - structs - true - - - org.jenkins-ci.plugins - script-security - true - - - org.jenkins-ci.plugins - sectioned-view - 1.25 - test - - - org.jenkins-ci.plugins - nested-view - 1.29 - test - - - org.jenkins-ci.plugins - credentials - test - - + + 4.1.1 + -SNAPSHOT + jenkinsci/priority-sorter-plugin + 2.361.4 + 6.55.0 + Max + Low + - - - repo.jenkins-ci.org - https://repo.jenkins-ci.org/public/ - - + + + + io.jenkins.tools.bom + bom-2.361.x + 1981.v17df70e84a_a_1 + pom + import + + + - - - repo.jenkins-ci.org - https://repo.jenkins-ci.org/public/ - - + + + com.synopsys.arc.jenkinsci.plugins + job-restrictions + 0.8 + true + + + io.jenkins.plugins + ionicons-api + + + org.jenkins-ci.plugins + cloudbees-folder + true + + + org.jenkins-ci.plugins + matrix-project + true + + + org.jenkins-ci.plugins + script-security + true + + + org.jenkins-ci.plugins + structs + true + + + org.jenkins-ci.plugins.workflow + workflow-durable-task-step + true + + + org.jenkins-ci.plugins + credentials + test + + + org.jenkins-ci.plugins + nested-view + 1.29 + test + + + org.jenkins-ci.plugins + sectioned-view + 1.25 + test + + - - scm:git:https://github.com/${gitHubRepo}.git - scm:git:git@github.com:${gitHubRepo}.git - https://github.com/${gitHubRepo} - ${scmTag} - + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.20.0 + + + net.sourceforge.pmd + pmd-core + ${pmdVersion} + + + net.sourceforge.pmd + pmd-java + ${pmdVersion} + + + + + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.20.0 + + + + cpd-check + + + + + + diff --git a/src/main/java/jenkins/advancedqueue/DecisionLogger.java b/src/main/java/jenkins/advancedqueue/DecisionLogger.java index 736f69ac..1defb71d 100644 --- a/src/main/java/jenkins/advancedqueue/DecisionLogger.java +++ b/src/main/java/jenkins/advancedqueue/DecisionLogger.java @@ -29,6 +29,5 @@ */ public interface DecisionLogger { - DecisionLogger addDecisionLog(int indent, String log); - + DecisionLogger addDecisionLog(int indent, String log); } diff --git a/src/main/java/jenkins/advancedqueue/ItemTransitionLogger.java b/src/main/java/jenkins/advancedqueue/ItemTransitionLogger.java index e179fabd..347e7177 100644 --- a/src/main/java/jenkins/advancedqueue/ItemTransitionLogger.java +++ b/src/main/java/jenkins/advancedqueue/ItemTransitionLogger.java @@ -24,10 +24,8 @@ package jenkins.advancedqueue; import edu.umd.cs.findbugs.annotations.NonNull; - import java.util.logging.Level; import java.util.logging.Logger; - import jenkins.advancedqueue.sorter.ItemInfo; /** @@ -36,30 +34,29 @@ */ public class ItemTransitionLogger { - private final static Logger LOGGER = Logger.getLogger("PrioritySorter.Queue.Items"); - - static public void logNewItem(@NonNull ItemInfo info) { - if (LOGGER.isLoggable(Level.FINER)) { - LOGGER.finer("New Item: " + info.toString() + "\n" + info.getDescisionLog()); - } else { - LOGGER.fine("New Item: " + info.toString()); - } - } + private static final Logger LOGGER = Logger.getLogger("PrioritySorter.Queue.Items"); - static public void logBlockedItem(@NonNull ItemInfo info) { - LOGGER.fine("Blocking: " + info.toString()); - } + public static void logNewItem(@NonNull ItemInfo info) { + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.finer("New Item: " + info.toString() + "\n" + info.getDescisionLog()); + } else { + LOGGER.fine("New Item: " + info.toString()); + } + } - static public void logBuilableItem(@NonNull ItemInfo info) { - LOGGER.fine("Buildable: " + info.toString()); - } + public static void logBlockedItem(@NonNull ItemInfo info) { + LOGGER.fine("Blocking: " + info.toString()); + } - static public void logStartedItem(@NonNull ItemInfo info) { - LOGGER.fine("Starting: " + info.toString()); - } + public static void logBuilableItem(@NonNull ItemInfo info) { + LOGGER.fine("Buildable: " + info.toString()); + } - static public void logCanceledItem(@NonNull ItemInfo info) { - LOGGER.fine("Canceling: " + info.toString()); - } + public static void logStartedItem(@NonNull ItemInfo info) { + LOGGER.fine("Starting: " + info.toString()); + } + public static void logCanceledItem(@NonNull ItemInfo info) { + LOGGER.fine("Canceling: " + info.toString()); + } } diff --git a/src/main/java/jenkins/advancedqueue/JobGroup.java b/src/main/java/jenkins/advancedqueue/JobGroup.java index de5a6efd..57daa583 100644 --- a/src/main/java/jenkins/advancedqueue/JobGroup.java +++ b/src/main/java/jenkins/advancedqueue/JobGroup.java @@ -25,17 +25,13 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; - import java.util.ArrayList; import java.util.List; - import jenkins.advancedqueue.jobinclusion.JobInclusionStrategy; import jenkins.advancedqueue.jobinclusion.strategy.ViewBasedJobInclusionStrategy; - import jenkins.advancedqueue.priority.PriorityStrategy; import net.sf.json.JSONArray; import net.sf.json.JSONObject; - import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; @@ -48,77 +44,76 @@ */ public class JobGroup { - public static class PriorityStrategyHolder { - private int id = 0; - private PriorityStrategy priorityStrategy; - - public PriorityStrategyHolder() { - } - - @DataBoundConstructor - public PriorityStrategyHolder(int id, PriorityStrategy priorityStrategy) { - this.id = id; - this.priorityStrategy = priorityStrategy; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public PriorityStrategy getPriorityStrategy() { - return priorityStrategy; - } - - public void setPriorityStrategy(PriorityStrategy priorityStrategy) { - this.priorityStrategy = priorityStrategy; - } - - } - - private int id = 0; - private int priority = 2; - /** - * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy} - */ - @Deprecated - private String view = null; - private JobInclusionStrategy jobGroupStrategy = null; - private String description = ""; - - private boolean runExclusive = false; - /** - * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy} - */ - @Deprecated - private boolean useJobFilter = false; - /** - * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy} - */ - @Deprecated - private String jobPattern = ".*"; - private boolean usePriorityStrategies; - private List priorityStrategies = new ArrayList(); - - private JobGroup() { - } - - /** - * @return the id - */ - public int getId() { - return id; - } - - /** - * @param id the id to set - */ - public void setId(int id) { - this.id = id; - } + public static class PriorityStrategyHolder { + private int id = 0; + private PriorityStrategy priorityStrategy; + + public PriorityStrategyHolder() {} + + @DataBoundConstructor + public PriorityStrategyHolder(int id, PriorityStrategy priorityStrategy) { + this.id = id; + this.priorityStrategy = priorityStrategy; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public PriorityStrategy getPriorityStrategy() { + return priorityStrategy; + } + + public void setPriorityStrategy(PriorityStrategy priorityStrategy) { + this.priorityStrategy = priorityStrategy; + } + } + + private int id = 0; + private int priority = 2; + /** + * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy} + */ + @Deprecated + private String view = null; + + private JobInclusionStrategy jobGroupStrategy = null; + private String description = ""; + + private boolean runExclusive = false; + /** + * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy} + */ + @Deprecated + private boolean useJobFilter = false; + /** + * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy} + */ + @Deprecated + private String jobPattern = ".*"; + + private boolean usePriorityStrategies; + private List priorityStrategies = new ArrayList(); + + private JobGroup() {} + + /** + * @return the id + */ + public int getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(int id) { + this.id = id; + } public @NonNull String getDescription() { return hudson.Util.fixNull(description); @@ -128,121 +123,122 @@ public void setDescription(String description) { this.description = description; } - /** - * @return the priority - */ - public int getPriority() { - return priority; - } - - /** - * @return the viewName or null if the strategy is not {@link jenkins.advancedqueue.jobinclusion.strategy.ViewBasedJobInclusionStrategy} - * - * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy}, will return the view - */ - @Deprecated - @CheckForNull - public String getView() { - if(jobGroupStrategy instanceof ViewBasedJobInclusionStrategy) { - return ((ViewBasedJobInclusionStrategy) jobGroupStrategy).getViewName(); - } - return null; - } - - /** - * @param priority the priority to set - */ - public void setPriority(int priority) { - this.priority = priority; - } - - public JobInclusionStrategy getJobGroupStrategy() { - // Convert from 2.x - if(jobGroupStrategy == null && view != null) { - ViewBasedJobInclusionStrategy.JobPattern pattern = new ViewBasedJobInclusionStrategy.JobPattern(jobPattern); - jobGroupStrategy = new ViewBasedJobInclusionStrategy(view, useJobFilter == false ? null : pattern); - } - return jobGroupStrategy; - } - - public void setJobGroupStrategy(JobInclusionStrategy jobGroupStrategy) { - this.view = null; - this.jobGroupStrategy = jobGroupStrategy; - } - - public boolean isRunExclusive() { - return runExclusive; - } - - public void setRunExclusive(boolean runExclusive) { - this.runExclusive = runExclusive; - } - - public boolean isUsePriorityStrategies() { - return usePriorityStrategies; - } - - public void setUsePriorityStrategies(boolean usePriorityStrategies) { - this.usePriorityStrategies = usePriorityStrategies; - } - - public List getPriorityStrategies() { - return priorityStrategies; - } - - public void setPriorityStrategies(List priorityStrategies) { - this.priorityStrategies = priorityStrategies; - } - - /** - * Creates a Job Group from JSON object. - * - * @param jobGroupObject JSON object with class description - * @param id ID of the item to be created - * @return created group - */ - // TODO: replace by DataBound Constructor - public static JobGroup newInstance(StaplerRequest req, JSONObject jobGroupObject, int id) { - JobGroup jobGroup = new JobGroup(); - jobGroup.setId(id); - jobGroup.setDescription(jobGroupObject.getString("description")); - jobGroup.setPriority(jobGroupObject.getInt("priority")); - JSONObject jsonObjectJobGroupStrategy = jobGroupObject.getJSONObject("jobGroupStrategy"); - JobInclusionStrategy jobGroupStrategy = req.bindJSON(Class.class, JobInclusionStrategy.class, jsonObjectJobGroupStrategy); - jobGroup.setJobGroupStrategy(jobGroupStrategy); - jobGroup.setRunExclusive(Boolean.parseBoolean(jobGroupObject.getString("runExclusive"))); - /* - jobGroup.setUseJobFilter(jobGroupObject.has("useJobFilter")); - if (jobGroup.isUseJobFilter()) { - JSONObject jsonObject = jobGroupObject.getJSONObject("useJobFilter"); - jobGroup.setJobPattern(jsonObject.getString("jobPattern")); - // Disable the filter if the pattern is invalid - try { - Pattern.compile(jobGroup.getJobPattern()); - } catch (PatternSyntaxException e) { - jobGroup.setUseJobFilter(false); - } - } - */ - // - jobGroup.setUsePriorityStrategies(jobGroupObject.has("usePriorityStrategies")); - if (jobGroup.isUsePriorityStrategies()) { - JSONObject jsonObject = jobGroupObject.getJSONObject("usePriorityStrategies"); - if (jsonObject.has("holder")) { - JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("holder")); - int psid = 0; - for (Object object : jsonArray) { - PriorityStrategyHolder holder = new JobGroup.PriorityStrategyHolder(); - holder.setId(psid++); - PriorityStrategy strategy = req.bindJSON(Class.class, PriorityStrategy.class, object); - holder.setPriorityStrategy(strategy); - jobGroup.priorityStrategies.add(holder); - } - } - if (jobGroup.priorityStrategies.isEmpty()) { - jobGroup.setUsePriorityStrategies(false); - } - } - return jobGroup; - } + /** + * @return the priority + */ + public int getPriority() { + return priority; + } + + /** + * @return the viewName or null if the strategy is not {@link jenkins.advancedqueue.jobinclusion.strategy.ViewBasedJobInclusionStrategy} + * + * @deprecated Used in 2.x now replaced with dynamic {@link JobGroup#jobGroupStrategy}, will return the view + */ + @Deprecated + @CheckForNull + public String getView() { + if (jobGroupStrategy instanceof ViewBasedJobInclusionStrategy) { + return ((ViewBasedJobInclusionStrategy) jobGroupStrategy).getViewName(); + } + return null; + } + + /** + * @param priority the priority to set + */ + public void setPriority(int priority) { + this.priority = priority; + } + + public JobInclusionStrategy getJobGroupStrategy() { + // Convert from 2.x + if (jobGroupStrategy == null && view != null) { + ViewBasedJobInclusionStrategy.JobPattern pattern = new ViewBasedJobInclusionStrategy.JobPattern(jobPattern); + jobGroupStrategy = new ViewBasedJobInclusionStrategy(view, useJobFilter == false ? null : pattern); + } + return jobGroupStrategy; + } + + public void setJobGroupStrategy(JobInclusionStrategy jobGroupStrategy) { + this.view = null; + this.jobGroupStrategy = jobGroupStrategy; + } + + public boolean isRunExclusive() { + return runExclusive; + } + + public void setRunExclusive(boolean runExclusive) { + this.runExclusive = runExclusive; + } + + public boolean isUsePriorityStrategies() { + return usePriorityStrategies; + } + + public void setUsePriorityStrategies(boolean usePriorityStrategies) { + this.usePriorityStrategies = usePriorityStrategies; + } + + public List getPriorityStrategies() { + return priorityStrategies; + } + + public void setPriorityStrategies(List priorityStrategies) { + this.priorityStrategies = priorityStrategies; + } + + /** + * Creates a Job Group from JSON object. + * + * @param jobGroupObject JSON object with class description + * @param id ID of the item to be created + * @return created group + */ + // TODO: replace by DataBound Constructor + public static JobGroup newInstance(StaplerRequest req, JSONObject jobGroupObject, int id) { + JobGroup jobGroup = new JobGroup(); + jobGroup.setId(id); + jobGroup.setDescription(jobGroupObject.getString("description")); + jobGroup.setPriority(jobGroupObject.getInt("priority")); + JSONObject jsonObjectJobGroupStrategy = jobGroupObject.getJSONObject("jobGroupStrategy"); + JobInclusionStrategy jobGroupStrategy = + req.bindJSON(Class.class, JobInclusionStrategy.class, jsonObjectJobGroupStrategy); + jobGroup.setJobGroupStrategy(jobGroupStrategy); + jobGroup.setRunExclusive(Boolean.parseBoolean(jobGroupObject.getString("runExclusive"))); + /* + jobGroup.setUseJobFilter(jobGroupObject.has("useJobFilter")); + if (jobGroup.isUseJobFilter()) { + JSONObject jsonObject = jobGroupObject.getJSONObject("useJobFilter"); + jobGroup.setJobPattern(jsonObject.getString("jobPattern")); + // Disable the filter if the pattern is invalid + try { + Pattern.compile(jobGroup.getJobPattern()); + } catch (PatternSyntaxException e) { + jobGroup.setUseJobFilter(false); + } + } + */ + // + jobGroup.setUsePriorityStrategies(jobGroupObject.has("usePriorityStrategies")); + if (jobGroup.isUsePriorityStrategies()) { + JSONObject jsonObject = jobGroupObject.getJSONObject("usePriorityStrategies"); + if (jsonObject.has("holder")) { + JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("holder")); + int psid = 0; + for (Object object : jsonArray) { + PriorityStrategyHolder holder = new JobGroup.PriorityStrategyHolder(); + holder.setId(psid++); + PriorityStrategy strategy = req.bindJSON(Class.class, PriorityStrategy.class, object); + holder.setPriorityStrategy(strategy); + jobGroup.priorityStrategies.add(holder); + } + } + if (jobGroup.priorityStrategies.isEmpty()) { + jobGroup.setUsePriorityStrategies(false); + } + } + return jobGroup; + } } diff --git a/src/main/java/jenkins/advancedqueue/PriorityCalculationsUtil.java b/src/main/java/jenkins/advancedqueue/PriorityCalculationsUtil.java index e1272a1c..85481e96 100644 --- a/src/main/java/jenkins/advancedqueue/PriorityCalculationsUtil.java +++ b/src/main/java/jenkins/advancedqueue/PriorityCalculationsUtil.java @@ -2,21 +2,20 @@ public class PriorityCalculationsUtil { - static private int PRIORITY_USE_DEFAULT_PRIORITY = -1; + private static int PRIORITY_USE_DEFAULT_PRIORITY = -1; - static public int getUseDefaultPriorityPriority() { - return PRIORITY_USE_DEFAULT_PRIORITY; - } - - static public int scale(int oldmax, int newmax, int value) { - if (value == PRIORITY_USE_DEFAULT_PRIORITY) { - return PRIORITY_USE_DEFAULT_PRIORITY; - } - float p = ((float) (value - 1) / (float) (oldmax - 1)); - if (p <= 0.5) { - return (int) (Math.floor(p * (newmax - 1))) + 1; - } - return (int) (Math.ceil(p * (newmax - 1))) + 1; - } + public static int getUseDefaultPriorityPriority() { + return PRIORITY_USE_DEFAULT_PRIORITY; + } + public static int scale(int oldmax, int newmax, int value) { + if (value == PRIORITY_USE_DEFAULT_PRIORITY) { + return PRIORITY_USE_DEFAULT_PRIORITY; + } + float p = ((float) (value - 1) / (float) (oldmax - 1)); + if (p <= 0.5) { + return (int) (Math.floor(p * (newmax - 1))) + 1; + } + return (int) (Math.ceil(p * (newmax - 1))) + 1; + } } diff --git a/src/main/java/jenkins/advancedqueue/PriorityConfiguration.java b/src/main/java/jenkins/advancedqueue/PriorityConfiguration.java index eda7b7cb..8431a77c 100644 --- a/src/main/java/jenkins/advancedqueue/PriorityConfiguration.java +++ b/src/main/java/jenkins/advancedqueue/PriorityConfiguration.java @@ -25,7 +25,6 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; - import hudson.DescriptorExtensionList; import hudson.Extension; import hudson.ExtensionList; @@ -37,12 +36,11 @@ import hudson.model.Queue; import hudson.model.RootAction; import hudson.model.TopLevelItem; -import hudson.model.ViewGroup; import hudson.model.View; +import hudson.model.ViewGroup; import hudson.security.ACL; import hudson.util.FormValidation; import hudson.util.ListBoxModel; - import java.io.IOException; import java.util.Collection; import java.util.Collections; @@ -53,15 +51,12 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; - import javax.servlet.ServletException; - import jenkins.advancedqueue.jobinclusion.JobInclusionStrategy; import jenkins.advancedqueue.priority.PriorityStrategy; import jenkins.model.Jenkins; import net.sf.json.JSONArray; import net.sf.json.JSONObject; - import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.jenkins.ui.icon.IconSpec; @@ -75,229 +70,244 @@ * @since 2.0 */ @Extension -public class PriorityConfiguration extends Descriptor implements RootAction, IconSpec, Describable { - - private final static Logger LOGGER = Logger.getLogger(PriorityConfiguration.class.getName()); - - transient private Map id2jobGroup; - transient private PriorityConfigurationMatrixHelper priorityConfigurationMatrixHelper; - transient private PriorityConfigurationPlaceholderTaskHelper placeholderTaskHelper = new PriorityConfigurationPlaceholderTaskHelper(); - private List jobGroups; - - public PriorityConfiguration() { - super(PriorityConfiguration.class); - jobGroups = new LinkedList(); - load(); - // - Collections.sort(jobGroups, (JobGroup o1, JobGroup o2) -> o1.getId() - o2.getId()); - // - id2jobGroup = new HashMap(); - for (JobGroup jobGroup : jobGroups) { - id2jobGroup.put(jobGroup.getId(), jobGroup); - Collections.sort(jobGroup.getPriorityStrategies(), (JobGroup.PriorityStrategyHolder o1, JobGroup.PriorityStrategyHolder o2) -> o1.getId() - o2.getId()); - } - // - Plugin plugin = Jenkins.get().getPlugin("matrix-project"); - if(plugin == null || !plugin.getWrapper().isEnabled()){ - priorityConfigurationMatrixHelper = null; - } else { - priorityConfigurationMatrixHelper = new PriorityConfigurationMatrixHelper(); - } - } - - @Override - public String getIconFileName() { - return null; - } - - @Override - public String getIconClassName() { - if (!checkActive()) { - return null; - } - - return "symbol-swap-vertical-outline plugin-ionicons-api"; - } - - @Override - public String getDisplayName() { - return Messages.PriorityConfiguration_displayName(); - } - - public String getUrlName() { - if (!checkActive()) { - return null; - } - return "advanced-build-queue"; - } - - private boolean checkActive() { - PrioritySorterConfiguration configuration = PrioritySorterConfiguration.get(); - if (configuration.getOnlyAdminsMayEditPriorityConfiguration()) { - return Jenkins.get().getACL().hasPermission(Jenkins.ADMINISTER); - } - return true; - } - - public List getJobGroups() { - return jobGroups; - } - - public JobGroup getJobGroup(int id) { - return id2jobGroup.get(id); - } - - public ExtensionList> getPriorityStrategyDescriptors() { - return PriorityStrategy.all(); - } - - public DescriptorExtensionList> getJobInclusionStrategyDescriptors() { - return JobInclusionStrategy.all(); - } - - - public ListBoxModel getPriorities() { - ListBoxModel items = PrioritySorterConfiguration.get().doGetPriorityItems(); - return items; - } - - public void doPriorityConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - jobGroups = new LinkedList(); - id2jobGroup = new HashMap(); - // - String parameter = req.getParameter("json"); - JSONObject jobGroupsObject = JSONObject.fromObject(parameter); - JSONArray jsonArray = JSONArray.fromObject(jobGroupsObject.get("jobGroup")); - int id = 0; - for (Object object : jsonArray) { - JSONObject jobGroupObject = JSONObject.fromObject(object); - if (jobGroupObject.isEmpty()) { - break; - } - JobGroup jobGroup = JobGroup.newInstance(req, jobGroupObject, id++); - jobGroups.add(jobGroup); - id2jobGroup.put(jobGroup.getId(), jobGroup); - } - save(); - rsp.sendRedirect(Jenkins.get().getRootUrl()); - } - - public Descriptor getDescriptor() { - return this; - } - - public FormValidation doCheckJobPattern(@QueryParameter String value) throws IOException, ServletException { - if (value.length() > 0) { - try { - Pattern.compile(value); - } catch (PatternSyntaxException e) { - return FormValidation.warning("The expression is not valid, please enter a valid expression."); - } - } - return FormValidation.ok(); - } - - public PriorityConfigurationCallback getPriority(Queue.Item item, PriorityConfigurationCallback priorityCallback) { - SecurityContext saveCtx = ACL.impersonate(ACL.SYSTEM); - try { - return getPriorityInternal(item, priorityCallback); - } finally { - SecurityContextHolder.setContext(saveCtx); - } - } - - private PriorityConfigurationCallback getPriorityInternal(Queue.Item item, PriorityConfigurationCallback priorityCallback) { - if (placeholderTaskHelper.isPlaceholderTask(item.task)) { - return placeholderTaskHelper.getPriority((ExecutorStepExecution.PlaceholderTask) item.task, priorityCallback); - } - - if (!(item.task instanceof Job)) { - // Not a job generally this mean that this is a lightweight task so - // priority doesn't really matter - returning default priority - priorityCallback.addDecisionLog(0, "Queue.Item is not a Job - Assigning global default priority"); - return priorityCallback.setPrioritySelection(PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); - } - - Job job = (Job) item.task; - - if (priorityConfigurationMatrixHelper != null && priorityConfigurationMatrixHelper.isMatrixConfiguration(job)) { - return priorityConfigurationMatrixHelper.getPriority((MatrixConfiguration) job, priorityCallback); - } - - // - JobGroup jobGroup = getJobGroup(priorityCallback, job); - if (jobGroup != null) { - return getPriorityForJobGroup(priorityCallback, jobGroup, item); - } - // - priorityCallback.addDecisionLog(0, "Assigning global default priority"); - return priorityCallback.setPrioritySelection(PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); - } - - @CheckForNull - public JobGroup getJobGroup(@NonNull PriorityConfigurationCallback priorityCallback, @NonNull Job job) { - if (!(job instanceof TopLevelItem)) { - priorityCallback.addDecisionLog(0, "Job is not a TopLevelItem [" + job.getClass().getName() + "] ..."); - return null; - } - for (JobGroup jobGroup : jobGroups) { - priorityCallback.addDecisionLog(0, "Evaluating JobGroup [" + jobGroup.getId() + "] ..."); - if (jobGroup.getJobGroupStrategy().contains(priorityCallback, job)) { - return jobGroup; - } - } - return null; - } - - private boolean isJobInView(Job job, View view) { - if(view instanceof ViewGroup) { - return isJobInViewGroup(job, (ViewGroup) view); - } else { - return view.contains((TopLevelItem) job); - } - } - - private boolean isJobInViewGroup(Job job, ViewGroup viewGroup) { - Collection views = viewGroup.getViews(); - for (View view : views) { - if(isJobInView(job, view)) { - return true; - } - } - return false; - } - - private PriorityConfigurationCallback getPriorityForJobGroup(PriorityConfigurationCallback priorityCallback, JobGroup jobGroup, Queue.Item item) { - int priority = jobGroup.getPriority(); - PriorityStrategy reason = null; - if (jobGroup.isUsePriorityStrategies()) { - priorityCallback.addDecisionLog(2, "Evaluating strategies ..."); - List priorityStrategies = jobGroup.getPriorityStrategies(); - for (JobGroup.PriorityStrategyHolder priorityStrategy : priorityStrategies) { - PriorityStrategy strategy = priorityStrategy.getPriorityStrategy(); - priorityCallback.addDecisionLog(3, "Evaluating strategy [" + strategy.getDescriptor().getDisplayName() + "] ..."); - if (strategy.isApplicable(item)) { - priorityCallback.addDecisionLog(4, "Strategy is applicable"); - int foundPriority = strategy.getPriority(item); - if (foundPriority > 0 && foundPriority <= PrioritySorterConfiguration.get().getStrategy().getNumberOfPriorities()) { - priority = foundPriority; - reason = strategy; - break; - } - } - } - } - if (reason == null) { - priorityCallback.addDecisionLog(2, "No applicable strategy - Using JobGroup default"); - } - if (priority == PriorityCalculationsUtil.getUseDefaultPriorityPriority()) { - priority = PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); - } - return priorityCallback.setPrioritySelection(priority, jobGroup.getId(), reason); - } - - static public PriorityConfiguration get() { - return (PriorityConfiguration) Jenkins.get().getDescriptor(PriorityConfiguration.class); - } - +public class PriorityConfiguration extends Descriptor + implements RootAction, IconSpec, Describable { + + private static final Logger LOGGER = Logger.getLogger(PriorityConfiguration.class.getName()); + + private transient Map id2jobGroup; + private transient PriorityConfigurationMatrixHelper priorityConfigurationMatrixHelper; + private transient PriorityConfigurationPlaceholderTaskHelper placeholderTaskHelper = + new PriorityConfigurationPlaceholderTaskHelper(); + private List jobGroups; + + public PriorityConfiguration() { + super(PriorityConfiguration.class); + jobGroups = new LinkedList(); + load(); + // + Collections.sort(jobGroups, (JobGroup o1, JobGroup o2) -> o1.getId() - o2.getId()); + // + id2jobGroup = new HashMap(); + for (JobGroup jobGroup : jobGroups) { + id2jobGroup.put(jobGroup.getId(), jobGroup); + Collections.sort( + jobGroup.getPriorityStrategies(), + (JobGroup.PriorityStrategyHolder o1, JobGroup.PriorityStrategyHolder o2) -> + o1.getId() - o2.getId()); + } + // + Plugin plugin = Jenkins.get().getPlugin("matrix-project"); + if (plugin == null || !plugin.getWrapper().isEnabled()) { + priorityConfigurationMatrixHelper = null; + } else { + priorityConfigurationMatrixHelper = new PriorityConfigurationMatrixHelper(); + } + } + + @Override + public String getIconFileName() { + return null; + } + + @Override + public String getIconClassName() { + if (!checkActive()) { + return null; + } + + return "symbol-swap-vertical-outline plugin-ionicons-api"; + } + + @Override + public String getDisplayName() { + return Messages.PriorityConfiguration_displayName(); + } + + public String getUrlName() { + if (!checkActive()) { + return null; + } + return "advanced-build-queue"; + } + + private boolean checkActive() { + PrioritySorterConfiguration configuration = PrioritySorterConfiguration.get(); + if (configuration.getOnlyAdminsMayEditPriorityConfiguration()) { + return Jenkins.get().getACL().hasPermission(Jenkins.ADMINISTER); + } + return true; + } + + public List getJobGroups() { + return jobGroups; + } + + public JobGroup getJobGroup(int id) { + return id2jobGroup.get(id); + } + + public ExtensionList> getPriorityStrategyDescriptors() { + return PriorityStrategy.all(); + } + + public DescriptorExtensionList> + getJobInclusionStrategyDescriptors() { + return JobInclusionStrategy.all(); + } + + public ListBoxModel getPriorities() { + ListBoxModel items = PrioritySorterConfiguration.get().doGetPriorityItems(); + return items; + } + + public void doPriorityConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + jobGroups = new LinkedList(); + id2jobGroup = new HashMap(); + // + String parameter = req.getParameter("json"); + JSONObject jobGroupsObject = JSONObject.fromObject(parameter); + JSONArray jsonArray = JSONArray.fromObject(jobGroupsObject.get("jobGroup")); + int id = 0; + for (Object object : jsonArray) { + JSONObject jobGroupObject = JSONObject.fromObject(object); + if (jobGroupObject.isEmpty()) { + break; + } + JobGroup jobGroup = JobGroup.newInstance(req, jobGroupObject, id++); + jobGroups.add(jobGroup); + id2jobGroup.put(jobGroup.getId(), jobGroup); + } + save(); + rsp.sendRedirect(Jenkins.get().getRootUrl()); + } + + public Descriptor getDescriptor() { + return this; + } + + public FormValidation doCheckJobPattern(@QueryParameter String value) throws IOException, ServletException { + if (value.length() > 0) { + try { + Pattern.compile(value); + } catch (PatternSyntaxException e) { + return FormValidation.warning("The expression is not valid, please enter a valid expression."); + } + } + return FormValidation.ok(); + } + + public PriorityConfigurationCallback getPriority(Queue.Item item, PriorityConfigurationCallback priorityCallback) { + SecurityContext saveCtx = ACL.impersonate(ACL.SYSTEM); + try { + return getPriorityInternal(item, priorityCallback); + } finally { + SecurityContextHolder.setContext(saveCtx); + } + } + + private PriorityConfigurationCallback getPriorityInternal( + Queue.Item item, PriorityConfigurationCallback priorityCallback) { + if (placeholderTaskHelper.isPlaceholderTask(item.task)) { + return placeholderTaskHelper.getPriority( + (ExecutorStepExecution.PlaceholderTask) item.task, priorityCallback); + } + + if (!(item.task instanceof Job)) { + // Not a job generally this mean that this is a lightweight task so + // priority doesn't really matter - returning default priority + priorityCallback.addDecisionLog(0, "Queue.Item is not a Job - Assigning global default priority"); + return priorityCallback.setPrioritySelection( + PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); + } + + Job job = (Job) item.task; + + if (priorityConfigurationMatrixHelper != null && priorityConfigurationMatrixHelper.isMatrixConfiguration(job)) { + return priorityConfigurationMatrixHelper.getPriority((MatrixConfiguration) job, priorityCallback); + } + + // + JobGroup jobGroup = getJobGroup(priorityCallback, job); + if (jobGroup != null) { + return getPriorityForJobGroup(priorityCallback, jobGroup, item); + } + // + priorityCallback.addDecisionLog(0, "Assigning global default priority"); + return priorityCallback.setPrioritySelection( + PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); + } + + @CheckForNull + public JobGroup getJobGroup(@NonNull PriorityConfigurationCallback priorityCallback, @NonNull Job job) { + if (!(job instanceof TopLevelItem)) { + priorityCallback.addDecisionLog( + 0, "Job is not a TopLevelItem [" + job.getClass().getName() + "] ..."); + return null; + } + for (JobGroup jobGroup : jobGroups) { + priorityCallback.addDecisionLog(0, "Evaluating JobGroup [" + jobGroup.getId() + "] ..."); + if (jobGroup.getJobGroupStrategy().contains(priorityCallback, job)) { + return jobGroup; + } + } + return null; + } + + private boolean isJobInView(Job job, View view) { + if (view instanceof ViewGroup) { + return isJobInViewGroup(job, (ViewGroup) view); + } else { + return view.contains((TopLevelItem) job); + } + } + + private boolean isJobInViewGroup(Job job, ViewGroup viewGroup) { + Collection views = viewGroup.getViews(); + for (View view : views) { + if (isJobInView(job, view)) { + return true; + } + } + return false; + } + + private PriorityConfigurationCallback getPriorityForJobGroup( + PriorityConfigurationCallback priorityCallback, JobGroup jobGroup, Queue.Item item) { + int priority = jobGroup.getPriority(); + PriorityStrategy reason = null; + if (jobGroup.isUsePriorityStrategies()) { + priorityCallback.addDecisionLog(2, "Evaluating strategies ..."); + List priorityStrategies = jobGroup.getPriorityStrategies(); + for (JobGroup.PriorityStrategyHolder priorityStrategy : priorityStrategies) { + PriorityStrategy strategy = priorityStrategy.getPriorityStrategy(); + priorityCallback.addDecisionLog( + 3, "Evaluating strategy [" + strategy.getDescriptor().getDisplayName() + "] ..."); + if (strategy.isApplicable(item)) { + priorityCallback.addDecisionLog(4, "Strategy is applicable"); + int foundPriority = strategy.getPriority(item); + if (foundPriority > 0 + && foundPriority + <= PrioritySorterConfiguration.get() + .getStrategy() + .getNumberOfPriorities()) { + priority = foundPriority; + reason = strategy; + break; + } + } + } + } + if (reason == null) { + priorityCallback.addDecisionLog(2, "No applicable strategy - Using JobGroup default"); + } + if (priority == PriorityCalculationsUtil.getUseDefaultPriorityPriority()) { + priority = PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); + } + return priorityCallback.setPrioritySelection(priority, jobGroup.getId(), reason); + } + + public static PriorityConfiguration get() { + return (PriorityConfiguration) Jenkins.get().getDescriptor(PriorityConfiguration.class); + } } diff --git a/src/main/java/jenkins/advancedqueue/PriorityConfigurationCallback.java b/src/main/java/jenkins/advancedqueue/PriorityConfigurationCallback.java index 753501c5..e45bf908 100644 --- a/src/main/java/jenkins/advancedqueue/PriorityConfigurationCallback.java +++ b/src/main/java/jenkins/advancedqueue/PriorityConfigurationCallback.java @@ -4,10 +4,10 @@ public interface PriorityConfigurationCallback extends DecisionLogger { - PriorityConfigurationCallback setPrioritySelection(int priority); + PriorityConfigurationCallback setPrioritySelection(int priority); - PriorityConfigurationCallback setPrioritySelection(int priority, int jobGroupId, PriorityStrategy reason); - - PriorityConfigurationCallback setPrioritySelection(int priority, long sortAsInQueueSince, int jobGroupId, PriorityStrategy reason); + PriorityConfigurationCallback setPrioritySelection(int priority, int jobGroupId, PriorityStrategy reason); + PriorityConfigurationCallback setPrioritySelection( + int priority, long sortAsInQueueSince, int jobGroupId, PriorityStrategy reason); } diff --git a/src/main/java/jenkins/advancedqueue/PriorityConfigurationMatrixHelper.java b/src/main/java/jenkins/advancedqueue/PriorityConfigurationMatrixHelper.java index 7c1abae0..6b23a546 100644 --- a/src/main/java/jenkins/advancedqueue/PriorityConfigurationMatrixHelper.java +++ b/src/main/java/jenkins/advancedqueue/PriorityConfigurationMatrixHelper.java @@ -1,36 +1,35 @@ package jenkins.advancedqueue; -import jenkins.advancedqueue.sorter.ItemInfo; -import jenkins.advancedqueue.sorter.QueueItemCache; import hudson.matrix.MatrixConfiguration; import hudson.matrix.MatrixProject; import hudson.model.Job; +import jenkins.advancedqueue.sorter.ItemInfo; +import jenkins.advancedqueue.sorter.QueueItemCache; class PriorityConfigurationMatrixHelper { - boolean isMatrixConfiguration(Job job) { - return job instanceof MatrixConfiguration; - } - - PriorityConfigurationCallback getPriority(MatrixConfiguration matrixConfiguration, - PriorityConfigurationCallback priorityCallback) { - // [JENKINS-8597] - // For MatrixConfiguration use the latest assigned Priority from the - // MatrixProject - MatrixProject matrixProject = matrixConfiguration.getParent(); - priorityCallback.addDecisionLog(0, "Job is MatrixConfiguration [" + matrixProject.getName() + "] ..."); - ItemInfo itemInfo = QueueItemCache.get().getItem(matrixProject.getName()); - // Can be null (for example) at startup when the MatrixBuild got - // lost (was running at restart) - if (itemInfo != null) { - priorityCallback.addDecisionLog(0, "MatrixProject found in cache, using priority from queue-item [" - + itemInfo.getItemId() + "]"); - return priorityCallback.setPrioritySelection(itemInfo.getPriority(), itemInfo.getJobGroupId(), - itemInfo.getPriorityStrategy()); - } - priorityCallback.addDecisionLog(0, "MatrixProject not found in cache, assigning global default priority"); - return priorityCallback.setPrioritySelection(PrioritySorterConfiguration.get().getStrategy() - .getDefaultPriority()); + boolean isMatrixConfiguration(Job job) { + return job instanceof MatrixConfiguration; + } - } + PriorityConfigurationCallback getPriority( + MatrixConfiguration matrixConfiguration, PriorityConfigurationCallback priorityCallback) { + // [JENKINS-8597] + // For MatrixConfiguration use the latest assigned Priority from the + // MatrixProject + MatrixProject matrixProject = matrixConfiguration.getParent(); + priorityCallback.addDecisionLog(0, "Job is MatrixConfiguration [" + matrixProject.getName() + "] ..."); + ItemInfo itemInfo = QueueItemCache.get().getItem(matrixProject.getName()); + // Can be null (for example) at startup when the MatrixBuild got + // lost (was running at restart) + if (itemInfo != null) { + priorityCallback.addDecisionLog( + 0, "MatrixProject found in cache, using priority from queue-item [" + itemInfo.getItemId() + "]"); + return priorityCallback.setPrioritySelection( + itemInfo.getPriority(), itemInfo.getJobGroupId(), itemInfo.getPriorityStrategy()); + } + priorityCallback.addDecisionLog(0, "MatrixProject not found in cache, assigning global default priority"); + return priorityCallback.setPrioritySelection( + PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); + } } diff --git a/src/main/java/jenkins/advancedqueue/PriorityConfigurationPlaceholderTaskHelper.java b/src/main/java/jenkins/advancedqueue/PriorityConfigurationPlaceholderTaskHelper.java index 9a479f67..73f23a78 100644 --- a/src/main/java/jenkins/advancedqueue/PriorityConfigurationPlaceholderTaskHelper.java +++ b/src/main/java/jenkins/advancedqueue/PriorityConfigurationPlaceholderTaskHelper.java @@ -1,7 +1,6 @@ package jenkins.advancedqueue; import edu.umd.cs.findbugs.annotations.NonNull; - import hudson.Plugin; import hudson.model.Job; import hudson.model.Queue; @@ -16,13 +15,15 @@ class PriorityConfigurationPlaceholderTaskHelper { private static final Logger LOGGER = Logger.getLogger(PriorityConfigurationPlaceholderTaskHelper.class.getName()); - - boolean isPlaceholderTask(Queue.Task task) { - return isPlaceholderTaskUsed() && task instanceof ExecutorStepExecution.PlaceholderTask; - } + + boolean isPlaceholderTask(Queue.Task task) { + return isPlaceholderTaskUsed() && task instanceof ExecutorStepExecution.PlaceholderTask; + } @NonNull - PriorityConfigurationCallback getPriority(@NonNull ExecutorStepExecution.PlaceholderTask task, @NonNull PriorityConfigurationCallback priorityCallback) { + PriorityConfigurationCallback getPriority( + @NonNull ExecutorStepExecution.PlaceholderTask task, + @NonNull PriorityConfigurationCallback priorityCallback) { Queue.Task ownerTask = task.getOwnerTask(); if (ownerTask instanceof Job) { Job job = (Job) ownerTask; @@ -30,26 +31,30 @@ PriorityConfigurationCallback getPriority(@NonNull ExecutorStepExecution.Placeho if (itemInfo != null) { priorityCallback.setPrioritySelection(itemInfo.getPriority()); } else { - if (PrioritySorterConfiguration.get() != null && PrioritySorterConfiguration.get().getStrategy() != null) { - priorityCallback.setPrioritySelection(PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); - } else { - priorityCallback.setPrioritySelection(MultiBucketStrategy.DEFAULT_PRIORITY); - } + if (PrioritySorterConfiguration.get() != null + && PrioritySorterConfiguration.get().getStrategy() != null) { + priorityCallback.setPrioritySelection( + PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); + } else { + priorityCallback.setPrioritySelection(MultiBucketStrategy.DEFAULT_PRIORITY); + } } } else { if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.log(Level.FINE, "Cannot determine priority of the Pipeline Placeholder Task {0}. Its owner task {1} is not a Job (type is {2}). " + - "Custom priority will not be set", + LOGGER.log( + Level.FINE, + "Cannot determine priority of the Pipeline Placeholder Task {0}. Its owner task {1} is not a Job (type is {2}). " + + "Custom priority will not be set", new Object[] {task, ownerTask, ownerTask.getClass()}); } - priorityCallback.setPrioritySelection(PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); + priorityCallback.setPrioritySelection( + PrioritySorterConfiguration.get().getStrategy().getDefaultPriority()); } return priorityCallback; } - static boolean isPlaceholderTaskUsed() { - Plugin plugin = Jenkins.get().getPlugin("workflow-durable-task-step"); - return plugin != null && plugin.getWrapper().isActive(); - } - + static boolean isPlaceholderTaskUsed() { + Plugin plugin = Jenkins.get().getPlugin("workflow-durable-task-step"); + return plugin != null && plugin.getWrapper().isActive(); + } } diff --git a/src/main/java/jenkins/advancedqueue/PrioritySorterConfiguration.java b/src/main/java/jenkins/advancedqueue/PrioritySorterConfiguration.java index a99f6b33..12305264 100644 --- a/src/main/java/jenkins/advancedqueue/PrioritySorterConfiguration.java +++ b/src/main/java/jenkins/advancedqueue/PrioritySorterConfiguration.java @@ -30,12 +30,10 @@ import hudson.security.ACLContext; import hudson.util.FormValidation; import hudson.util.ListBoxModel; - import java.io.IOException; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - import jenkins.advancedqueue.JobGroup.PriorityStrategyHolder; import jenkins.advancedqueue.priority.strategy.PriorityJobProperty; import jenkins.advancedqueue.sorter.SorterStrategy; @@ -46,7 +44,6 @@ import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; import net.sf.json.JSONObject; - import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; @@ -57,135 +54,135 @@ @Extension public class PrioritySorterConfiguration extends GlobalConfiguration { - private final static Logger LOGGER = Logger.getLogger(PrioritySorterConfiguration.class.getName()); - private final static SorterStrategy DEFAULT_STRATEGY = new AbsoluteStrategy( - MultiBucketStrategy.DEFAULT_PRIORITIES_NUMBER, MultiBucketStrategy.DEFAULT_PRIORITY); - - /** - * @deprecated used in 2.x - replaces with XXX - */ - @Deprecated - private boolean allowPriorityOnJobs; - - private boolean onlyAdminsMayEditPriorityConfiguration = false; - - private SorterStrategy strategy; - - public PrioritySorterConfiguration() { - } - - public static void init() { - PrioritySorterConfiguration prioritySorterConfiguration = PrioritySorterConfiguration.get(); - // Make sure default is good for updating from legacy - prioritySorterConfiguration.strategy = DEFAULT_STRATEGY; // TODO: replace with class ref - prioritySorterConfiguration.allowPriorityOnJobs = false; - prioritySorterConfiguration.load(); - } - - @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { - - int prevNumberOfPriorities = strategy.getNumberOfPriorities(); - strategy = req.bindJSON(SorterStrategy.class, json.getJSONObject("strategy")); - int newNumberOfPriorities = strategy.getNumberOfPriorities(); - - FormValidation numberOfPrioritiesCheck = doCheckNumberOfPriorities(String.valueOf(newNumberOfPriorities)); - if (numberOfPrioritiesCheck.kind != FormValidation.Kind.OK) { - throw new FormException(numberOfPrioritiesCheck.getMessage(), "numberOfPriorities"); - } - // - onlyAdminsMayEditPriorityConfiguration = json.getBoolean("onlyAdminsMayEditPriorityConfiguration"); - // - updatePriorities(prevNumberOfPriorities); - // - save(); - return true; - } - - public boolean getOnlyAdminsMayEditPriorityConfiguration() { - return onlyAdminsMayEditPriorityConfiguration; - } - - public SorterStrategy getStrategy() { - return strategy; - } - - public ListBoxModel doFillStrategyItems() { - ListBoxModel strategies = new ListBoxModel(); - List values = SorterStrategy.getAllSorterStrategies(); - for (SorterStrategyDescriptor sorterStrategy : values) { - strategies.add(sorterStrategy.getDisplayName(), sorterStrategy.getKey()); - } - return strategies; - } - - public ListBoxModel doGetPriorityItems() { - ListBoxModel items = PrioritySorterUtil.fillPriorityItems(strategy.getNumberOfPriorities()); - items.add( - 0, - new ListBoxModel.Option(Messages.Use_default_priority(), String.valueOf(PriorityCalculationsUtil - .getUseDefaultPriorityPriority()))); - return items; - } - - public FormValidation doCheckNumberOfPriorities(@QueryParameter String value) { - if (value.length() == 0) { - return FormValidation.error(Messages.PrioritySorterConfiguration_enterValueRequestMessage()); - } - try { - int intValue = Integer.parseInt(value); - if (intValue <= 0) { - return FormValidation.error(Messages.PrioritySorterConfiguration_enterValueRequestMessage()); - } - } catch (NumberFormatException e) { - return FormValidation.error(Messages.PrioritySorterConfiguration_enterValueRequestMessage()); - } - return FormValidation.ok(); - } - - @SuppressFBWarnings(value="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE",justification="try with resources checks null") - private void updatePriorities(int prevNumberOfPriorities) { - // Shouldn't really by a permission problem when getting here but - // to be on the safe side - try(ACLContext saveCtx = ACL.as(ACL.SYSTEM)) { - @SuppressWarnings("rawtypes") - List allJobs = Jenkins.get().getAllItems(Job.class); - for (Job job : allJobs) { - try { - // Scale any priority on the Job - PriorityJobProperty priorityProperty = job - .getProperty(PriorityJobProperty.class); - if (priorityProperty != null && priorityProperty.getUseJobPriority()) { - int newPriority = PriorityCalculationsUtil.scale(prevNumberOfPriorities, - strategy.getNumberOfPriorities(), priorityProperty.priority); + private static final Logger LOGGER = Logger.getLogger(PrioritySorterConfiguration.class.getName()); + private static final SorterStrategy DEFAULT_STRATEGY = + new AbsoluteStrategy(MultiBucketStrategy.DEFAULT_PRIORITIES_NUMBER, MultiBucketStrategy.DEFAULT_PRIORITY); + + /** + * @deprecated used in 2.x - replaces with XXX + */ + @Deprecated + private boolean allowPriorityOnJobs; + + private boolean onlyAdminsMayEditPriorityConfiguration = false; + + private SorterStrategy strategy; + + public PrioritySorterConfiguration() {} + + public static void init() { + PrioritySorterConfiguration prioritySorterConfiguration = PrioritySorterConfiguration.get(); + // Make sure default is good for updating from legacy + prioritySorterConfiguration.strategy = DEFAULT_STRATEGY; // TODO: replace with class ref + prioritySorterConfiguration.allowPriorityOnJobs = false; + prioritySorterConfiguration.load(); + } + + @Override + public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + + int prevNumberOfPriorities = strategy.getNumberOfPriorities(); + strategy = req.bindJSON(SorterStrategy.class, json.getJSONObject("strategy")); + int newNumberOfPriorities = strategy.getNumberOfPriorities(); + + FormValidation numberOfPrioritiesCheck = doCheckNumberOfPriorities(String.valueOf(newNumberOfPriorities)); + if (numberOfPrioritiesCheck.kind != FormValidation.Kind.OK) { + throw new FormException(numberOfPrioritiesCheck.getMessage(), "numberOfPriorities"); + } + // + onlyAdminsMayEditPriorityConfiguration = json.getBoolean("onlyAdminsMayEditPriorityConfiguration"); + // + updatePriorities(prevNumberOfPriorities); + // + save(); + return true; + } + + public boolean getOnlyAdminsMayEditPriorityConfiguration() { + return onlyAdminsMayEditPriorityConfiguration; + } + + public SorterStrategy getStrategy() { + return strategy; + } + + public ListBoxModel doFillStrategyItems() { + ListBoxModel strategies = new ListBoxModel(); + List values = SorterStrategy.getAllSorterStrategies(); + for (SorterStrategyDescriptor sorterStrategy : values) { + strategies.add(sorterStrategy.getDisplayName(), sorterStrategy.getKey()); + } + return strategies; + } + + public ListBoxModel doGetPriorityItems() { + ListBoxModel items = PrioritySorterUtil.fillPriorityItems(strategy.getNumberOfPriorities()); + items.add( + 0, + new ListBoxModel.Option( + Messages.Use_default_priority(), + String.valueOf(PriorityCalculationsUtil.getUseDefaultPriorityPriority()))); + return items; + } + + public FormValidation doCheckNumberOfPriorities(@QueryParameter String value) { + if (value.length() == 0) { + return FormValidation.error(Messages.PrioritySorterConfiguration_enterValueRequestMessage()); + } + try { + int intValue = Integer.parseInt(value); + if (intValue <= 0) { + return FormValidation.error(Messages.PrioritySorterConfiguration_enterValueRequestMessage()); + } + } catch (NumberFormatException e) { + return FormValidation.error(Messages.PrioritySorterConfiguration_enterValueRequestMessage()); + } + return FormValidation.ok(); + } + + @SuppressFBWarnings( + value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", + justification = "try with resources checks null") + private void updatePriorities(int prevNumberOfPriorities) { + // Shouldn't really by a permission problem when getting here but + // to be on the safe side + try (ACLContext saveCtx = ACL.as(ACL.SYSTEM)) { + @SuppressWarnings("rawtypes") + List allJobs = Jenkins.get().getAllItems(Job.class); + for (Job job : allJobs) { + try { + // Scale any priority on the Job + PriorityJobProperty priorityProperty = job.getProperty(PriorityJobProperty.class); + if (priorityProperty != null && priorityProperty.getUseJobPriority()) { + int newPriority = PriorityCalculationsUtil.scale( + prevNumberOfPriorities, strategy.getNumberOfPriorities(), priorityProperty.priority); if (newPriority != priorityProperty.getPriority()) { job.removeProperty(priorityProperty); - job.addProperty(new PriorityJobProperty(priorityProperty.getUseJobPriority(), - newPriority)); + job.addProperty(new PriorityJobProperty(priorityProperty.getUseJobPriority(), newPriority)); job.save(); } - } - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to update Advanced Job Priority To {0}", job.getName()); - } - } - // - List jobGroups = PriorityConfiguration.get().getJobGroups(); - for (JobGroup jobGroup : jobGroups) { - jobGroup.setPriority(PriorityCalculationsUtil.scale(prevNumberOfPriorities, - strategy.getNumberOfPriorities(), jobGroup.getPriority())); - List priorityStrategies = jobGroup.getPriorityStrategies(); - for (PriorityStrategyHolder priorityStrategyHolder : priorityStrategies) { - priorityStrategyHolder.getPriorityStrategy().numberPrioritiesUpdates(prevNumberOfPriorities, - strategy.getNumberOfPriorities()); - } - } - PriorityConfiguration.get().save(); - } - } - - static public PrioritySorterConfiguration get() { - return (PrioritySorterConfiguration) Jenkins.get().getDescriptor(PrioritySorterConfiguration.class); - } - + } + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Failed to update Advanced Job Priority To {0}", job.getName()); + } + } + // + List jobGroups = PriorityConfiguration.get().getJobGroups(); + for (JobGroup jobGroup : jobGroups) { + jobGroup.setPriority(PriorityCalculationsUtil.scale( + prevNumberOfPriorities, strategy.getNumberOfPriorities(), jobGroup.getPriority())); + List priorityStrategies = jobGroup.getPriorityStrategies(); + for (PriorityStrategyHolder priorityStrategyHolder : priorityStrategies) { + priorityStrategyHolder + .getPriorityStrategy() + .numberPrioritiesUpdates(prevNumberOfPriorities, strategy.getNumberOfPriorities()); + } + } + PriorityConfiguration.get().save(); + } + } + + public static PrioritySorterConfiguration get() { + return (PrioritySorterConfiguration) Jenkins.get().getDescriptor(PrioritySorterConfiguration.class); + } } diff --git a/src/main/java/jenkins/advancedqueue/PrioritySorterJobColumn.java b/src/main/java/jenkins/advancedqueue/PrioritySorterJobColumn.java index eebcb0ae..a935f153 100644 --- a/src/main/java/jenkins/advancedqueue/PrioritySorterJobColumn.java +++ b/src/main/java/jenkins/advancedqueue/PrioritySorterJobColumn.java @@ -27,7 +27,6 @@ import hudson.views.ListViewColumnDescriptor; import jenkins.advancedqueue.sorter.ItemInfo; import jenkins.advancedqueue.sorter.QueueItemCache; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -35,30 +34,29 @@ * for the job and is an easy way to compare the priorities of many jobs. */ public class PrioritySorterJobColumn extends ListViewColumn { - - @DataBoundConstructor - public PrioritySorterJobColumn() { - } - public String getPriority(final Job job) { - ItemInfo itemInfo = QueueItemCache.get().getItem(job.getName()); - if(itemInfo == null) { - return "Pending"; // You need to run a Job - } - return Integer.toString(itemInfo.getPriority()); - } + @DataBoundConstructor + public PrioritySorterJobColumn() {} + + public String getPriority(final Job job) { + ItemInfo itemInfo = QueueItemCache.get().getItem(job.getName()); + if (itemInfo == null) { + return "Pending"; // You need to run a Job + } + return Integer.toString(itemInfo.getPriority()); + } - @Extension - public static class DescriptorImpl extends ListViewColumnDescriptor { + @Extension + public static class DescriptorImpl extends ListViewColumnDescriptor { - @Override - public String getDisplayName() { - return "Priority Value"; - } + @Override + public String getDisplayName() { + return "Priority Value"; + } - @Override - public boolean shownByDefault() { - return false; - } - } + @Override + public boolean shownByDefault() { + return false; + } + } } diff --git a/src/main/java/jenkins/advancedqueue/PrioritySorterPlugin.java b/src/main/java/jenkins/advancedqueue/PrioritySorterPlugin.java index cd0d2c52..7b4c11d4 100644 --- a/src/main/java/jenkins/advancedqueue/PrioritySorterPlugin.java +++ b/src/main/java/jenkins/advancedqueue/PrioritySorterPlugin.java @@ -23,50 +23,50 @@ */ package jenkins.advancedqueue; +import static hudson.init.InitMilestone.EXTENSIONS_AUGMENTED; import static hudson.init.InitMilestone.JOB_LOADED; import static hudson.init.InitMilestone.PLUGINS_STARTED; -import static hudson.init.InitMilestone.EXTENSIONS_AUGMENTED; + import hudson.Plugin; import hudson.init.Initializer; import hudson.model.Items; - import java.util.logging.Logger; - import jenkins.advancedqueue.priority.strategy.PriorityJobProperty; import jenkins.advancedqueue.sorter.AdvancedQueueSorter; /** * Plugin is the staring point of the Priority Sorter Plugin. - * + * * Used to make sure that the data is initialized at startup. - * + * * @author Magnus Sandberg * @since 2.3 */ public class PrioritySorterPlugin extends Plugin { - private final static Logger LOGGER = Logger.getLogger(PrioritySorterPlugin.class.getName()); + private static final Logger LOGGER = Logger.getLogger(PrioritySorterPlugin.class.getName()); - @Initializer(before=PLUGINS_STARTED) - public static void addAliases() { - // Moved in 3.0 when JobPropertyStrategy was added - Items.XSTREAM2.addCompatibilityAlias("jenkins.advancedqueue.AdvancedQueueSorterJobProperty", PriorityJobProperty.class); - // moved in 3.0 everything in hudson.* is deprecated - Items.XSTREAM2.addCompatibilityAlias("hudson.queueSorter.PrioritySorterJobColumn", PrioritySorterJobColumn.class); - } - - @Initializer(after = EXTENSIONS_AUGMENTED) - public static void init1() { - // Check for any Legacy Configuration and init the Configuration - LOGGER.info("Configuring the Priority Sorter ..."); - PrioritySorterConfiguration.init(); - } + @Initializer(before = PLUGINS_STARTED) + public static void addAliases() { + // Moved in 3.0 when JobPropertyStrategy was added + Items.XSTREAM2.addCompatibilityAlias( + "jenkins.advancedqueue.AdvancedQueueSorterJobProperty", PriorityJobProperty.class); + // moved in 3.0 everything in hudson.* is deprecated + Items.XSTREAM2.addCompatibilityAlias( + "hudson.queueSorter.PrioritySorterJobColumn", PrioritySorterJobColumn.class); + } - @Initializer(after = JOB_LOADED) - public static void init2() { - // Init the Queue and sort the loaded Queue items - LOGGER.info("Sorting existing Queue ..."); - AdvancedQueueSorter.init(); - } + @Initializer(after = EXTENSIONS_AUGMENTED) + public static void init1() { + // Check for any Legacy Configuration and init the Configuration + LOGGER.info("Configuring the Priority Sorter ..."); + PrioritySorterConfiguration.init(); + } + @Initializer(after = JOB_LOADED) + public static void init2() { + // Init the Queue and sort the loaded Queue items + LOGGER.info("Sorting existing Queue ..."); + AdvancedQueueSorter.init(); + } } diff --git a/src/main/java/jenkins/advancedqueue/RunExclusiveThrottler.java b/src/main/java/jenkins/advancedqueue/RunExclusiveThrottler.java index e955dd1a..696f8577 100644 --- a/src/main/java/jenkins/advancedqueue/RunExclusiveThrottler.java +++ b/src/main/java/jenkins/advancedqueue/RunExclusiveThrottler.java @@ -1,7 +1,6 @@ package jenkins.advancedqueue; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - import hudson.Extension; import hudson.model.Queue.Item; import hudson.model.Run; @@ -9,84 +8,81 @@ import hudson.model.listeners.RunListener; import hudson.model.queue.CauseOfBlockage; import hudson.model.queue.QueueTaskDispatcher; - import java.util.ArrayList; import java.util.Collections; import java.util.List; - import jenkins.advancedqueue.priority.PriorityStrategy; import jenkins.advancedqueue.sorter.QueueItemCache; public class RunExclusiveThrottler { - static private List exclusiveJobs = Collections.synchronizedList(new ArrayList()); - @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Low risk") - static private int exclusiveJobGroupId = -1; - @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Low risk") - static private String exclusiveJobName = ""; - - static PriorityConfigurationCallback dummyCallback = new PriorityConfigurationCallback() { - - public PriorityConfigurationCallback setPrioritySelection(int priority, int jobGroupId, PriorityStrategy reason) { - return this; - } - - public PriorityConfigurationCallback setPrioritySelection(int priority) { - return this; - } - - public PriorityConfigurationCallback addDecisionLog(int indent, String log) { - return this; - } - - public PriorityConfigurationCallback setPrioritySelection(int priority, long sortAsInQueueSince, - int jobGroupId, PriorityStrategy reason) { - return this; - } - }; - - @Extension - static public class RunExclusiveRunListener extends RunListener { - - @Override - public void onStarted(Run r, TaskListener listener) { - JobGroup jobGroup = PriorityConfiguration.get().getJobGroup(dummyCallback, r.getParent()); - if (jobGroup != null && jobGroup.isRunExclusive()) { - exclusiveJobGroupId = jobGroup.getId(); - exclusiveJobName = r.getParent().getName(); - exclusiveJobs.add(exclusiveJobName); - } - } - - @Override - public void onCompleted(Run r, TaskListener listener) { - exclusiveJobs.remove(r.getParent().getName()); - } - - } - - private static class RunExclusiveMode extends CauseOfBlockage { - - @Override - public String getShortDescription() { - return "Run Exclusive (" + exclusiveJobName + ")"; - } - - } - - @Extension - static public class RunExclusiveDispatcher extends QueueTaskDispatcher { - - @Override - public CauseOfBlockage canRun(Item item) { - if (exclusiveJobs.size() > 0) { - if (QueueItemCache.get().getItem(item.getId()).getJobGroupId() != exclusiveJobGroupId) { - return new RunExclusiveMode(); - } - } - return null; - } - - } - + private static List exclusiveJobs = Collections.synchronizedList(new ArrayList()); + + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Low risk") + private static int exclusiveJobGroupId = -1; + + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Low risk") + private static String exclusiveJobName = ""; + + static PriorityConfigurationCallback dummyCallback = new PriorityConfigurationCallback() { + + public PriorityConfigurationCallback setPrioritySelection( + int priority, int jobGroupId, PriorityStrategy reason) { + return this; + } + + public PriorityConfigurationCallback setPrioritySelection(int priority) { + return this; + } + + public PriorityConfigurationCallback addDecisionLog(int indent, String log) { + return this; + } + + public PriorityConfigurationCallback setPrioritySelection( + int priority, long sortAsInQueueSince, int jobGroupId, PriorityStrategy reason) { + return this; + } + }; + + @Extension + public static class RunExclusiveRunListener extends RunListener { + + @Override + public void onStarted(Run r, TaskListener listener) { + JobGroup jobGroup = PriorityConfiguration.get().getJobGroup(dummyCallback, r.getParent()); + if (jobGroup != null && jobGroup.isRunExclusive()) { + exclusiveJobGroupId = jobGroup.getId(); + exclusiveJobName = r.getParent().getName(); + exclusiveJobs.add(exclusiveJobName); + } + } + + @Override + public void onCompleted(Run r, TaskListener listener) { + exclusiveJobs.remove(r.getParent().getName()); + } + } + + private static class RunExclusiveMode extends CauseOfBlockage { + + @Override + public String getShortDescription() { + return "Run Exclusive (" + exclusiveJobName + ")"; + } + } + + @Extension + public static class RunExclusiveDispatcher extends QueueTaskDispatcher { + + @Override + public CauseOfBlockage canRun(Item item) { + if (exclusiveJobs.size() > 0) { + if (QueueItemCache.get().getItem(item.getId()).getJobGroupId() != exclusiveJobGroupId) { + return new RunExclusiveMode(); + } + } + return null; + } + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/JobInclusionStrategy.java b/src/main/java/jenkins/advancedqueue/jobinclusion/JobInclusionStrategy.java index 8cd81a42..e32d93d3 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/JobInclusionStrategy.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/JobInclusionStrategy.java @@ -37,30 +37,30 @@ */ public abstract class JobInclusionStrategy implements ExtensionPoint, Describable { - static public class AbstractJobInclusionStrategyDescriptor extends Descriptor { + public static class AbstractJobInclusionStrategyDescriptor + extends Descriptor { - private final String displayName; + private final String displayName; - protected AbstractJobInclusionStrategyDescriptor(String displayName) { - this.displayName = displayName; - } + protected AbstractJobInclusionStrategyDescriptor(String displayName) { + this.displayName = displayName; + } - @Override - public String getDisplayName() { - return displayName; - } + @Override + public String getDisplayName() { + return displayName; + } + } + ; - }; + @SuppressWarnings("unchecked") + public Descriptor getDescriptor() { + return Jenkins.get().getDescriptor(this.getClass()); + } - @SuppressWarnings("unchecked") - public Descriptor getDescriptor() { - return Jenkins.get().getDescriptor(this.getClass()); - } - - abstract public boolean contains(DecisionLogger decisionLogger, Job job); - - public static DescriptorExtensionList> all() { - return Jenkins.get().getDescriptorList(JobInclusionStrategy.class); - } + public abstract boolean contains(DecisionLogger decisionLogger, Job job); + public static DescriptorExtensionList> all() { + return Jenkins.get().getDescriptorList(JobInclusionStrategy.class); + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/AllJobsJobInclusionStrategy.java b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/AllJobsJobInclusionStrategy.java index 1a3151e4..f5f8fbdf 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/AllJobsJobInclusionStrategy.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/AllJobsJobInclusionStrategy.java @@ -28,7 +28,6 @@ import jenkins.advancedqueue.DecisionLogger; import jenkins.advancedqueue.Messages; import jenkins.advancedqueue.jobinclusion.JobInclusionStrategy; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -37,21 +36,21 @@ */ public class AllJobsJobInclusionStrategy extends JobInclusionStrategy { - @Extension - static public class AllJobsJobInclusionStrategyDescriptor extends - AbstractJobInclusionStrategyDescriptor { + @Extension + public static class AllJobsJobInclusionStrategyDescriptor + extends AbstractJobInclusionStrategyDescriptor { - public AllJobsJobInclusionStrategyDescriptor() { - super(Messages.All_jobs()); - } - }; + public AllJobsJobInclusionStrategyDescriptor() { + super(Messages.All_jobs()); + } + } + ; - @DataBoundConstructor - public AllJobsJobInclusionStrategy() { - } + @DataBoundConstructor + public AllJobsJobInclusionStrategy() {} - @Override - public boolean contains(DecisionLogger decisionLogger, Job job) { - return true; - } + @Override + public boolean contains(DecisionLogger decisionLogger, Job job) { + return true; + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderBasedJobInclusionStrategy.java b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderBasedJobInclusionStrategy.java index f1212b72..afd99044 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderBasedJobInclusionStrategy.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderBasedJobInclusionStrategy.java @@ -23,59 +23,55 @@ */ package jenkins.advancedqueue.jobinclusion.strategy; +import com.cloudbees.hudson.plugins.folder.Folder; import hudson.Extension; import hudson.model.Job; import hudson.util.ListBoxModel; - import java.util.List; - import jenkins.advancedqueue.DecisionLogger; import jenkins.advancedqueue.Messages; import jenkins.advancedqueue.jobinclusion.JobInclusionStrategy; import jenkins.model.Jenkins; - import org.kohsuke.stapler.DataBoundConstructor; -import com.cloudbees.hudson.plugins.folder.Folder; - /** * @author Magnus Sandberg * @since 3.0 */ public class FolderBasedJobInclusionStrategy extends JobInclusionStrategy { - @Extension(optional = true) - static public class FolderBasedJobInclusionStrategyDescriptor extends - AbstractJobInclusionStrategyDescriptor { - - public FolderBasedJobInclusionStrategyDescriptor() { - super(Messages.Jobs_included_in_folder()); - } + @Extension(optional = true) + public static class FolderBasedJobInclusionStrategyDescriptor + extends AbstractJobInclusionStrategyDescriptor { - public ListBoxModel getListFolderItems() { - ListBoxModel items = new ListBoxModel(); - List folders = Jenkins.get().getAllItems(Folder.class); - for (Folder folder : folders) { - items.add(folder.getFullName(), folder.getFullName()); - } - return items; - } + public FolderBasedJobInclusionStrategyDescriptor() { + super(Messages.Jobs_included_in_folder()); + } - }; + public ListBoxModel getListFolderItems() { + ListBoxModel items = new ListBoxModel(); + List folders = Jenkins.get().getAllItems(Folder.class); + for (Folder folder : folders) { + items.add(folder.getFullName(), folder.getFullName()); + } + return items; + } + } + ; - private String folderName; + private String folderName; - @DataBoundConstructor - public FolderBasedJobInclusionStrategy(String folderName) { - this.folderName = folderName; - } + @DataBoundConstructor + public FolderBasedJobInclusionStrategy(String folderName) { + this.folderName = folderName; + } - public String getFolderName() { - return folderName; - } + public String getFolderName() { + return folderName; + } - @Override - public boolean contains(DecisionLogger decisionLogger, Job job) { - return job.getFullName().startsWith(folderName); - } + @Override + public boolean contains(DecisionLogger decisionLogger, Job job) { + return job.getFullName().startsWith(folderName); + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderPropertyLoader.java b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderPropertyLoader.java index 6d5701ff..501fc9ce 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderPropertyLoader.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/FolderPropertyLoader.java @@ -26,48 +26,47 @@ import com.cloudbees.hudson.plugins.folder.AbstractFolder; import com.cloudbees.hudson.plugins.folder.AbstractFolderProperty; import com.cloudbees.hudson.plugins.folder.AbstractFolderPropertyDescriptor; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.ItemGroup; import hudson.model.Job; import hudson.model.TopLevelItem; import hudson.util.DescribableList; import jenkins.advancedqueue.DecisionLogger; -import edu.umd.cs.findbugs.annotations.CheckForNull; - /** * @author Magnus Sandberg * @since 3.0 */ public class FolderPropertyLoader { - @CheckForNull - static public String getJobGroupName(DecisionLogger decisionLogger, Job job) { - ItemGroup parent = job.getParent(); - decisionLogger.addDecisionLog(2, "Checking for Cloudbees Folder inclusion ..."); - while(parent != null) { - if(parent instanceof AbstractFolder) { - AbstractFolder folder = (AbstractFolder) parent; - decisionLogger.addDecisionLog(3, "Evaluating Folder [" + folder.getFullName() + "] ..."); - DescribableList,AbstractFolderPropertyDescriptor> properties = folder.getProperties(); - for(AbstractFolderProperty property : properties) { - if(property instanceof JobInclusionFolderProperty) { - JobInclusionFolderProperty incProperty = (JobInclusionFolderProperty) property; - if(incProperty.isUseJobGroup()) { - String name = incProperty.getJobGroupName(); - decisionLogger.addDecisionLog(4, "JobGroup is enabled, with JobGroup [" + name + "] ..."); - return name; - } - } - } - } - if(parent instanceof TopLevelItem) { - parent = ((TopLevelItem) parent).getParent(); - } else { - parent = null; - } - } - decisionLogger.addDecisionLog(2, "No match ..."); - return null; - } - + @CheckForNull + public static String getJobGroupName(DecisionLogger decisionLogger, Job job) { + ItemGroup parent = job.getParent(); + decisionLogger.addDecisionLog(2, "Checking for Cloudbees Folder inclusion ..."); + while (parent != null) { + if (parent instanceof AbstractFolder) { + AbstractFolder folder = (AbstractFolder) parent; + decisionLogger.addDecisionLog(3, "Evaluating Folder [" + folder.getFullName() + "] ..."); + DescribableList, AbstractFolderPropertyDescriptor> properties = + folder.getProperties(); + for (AbstractFolderProperty property : properties) { + if (property instanceof JobInclusionFolderProperty) { + JobInclusionFolderProperty incProperty = (JobInclusionFolderProperty) property; + if (incProperty.isUseJobGroup()) { + String name = incProperty.getJobGroupName(); + decisionLogger.addDecisionLog(4, "JobGroup is enabled, with JobGroup [" + name + "] ..."); + return name; + } + } + } + } + if (parent instanceof TopLevelItem) { + parent = ((TopLevelItem) parent).getParent(); + } else { + parent = null; + } + } + decisionLogger.addDecisionLog(2, "No match ..."); + return null; + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionFolderProperty.java b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionFolderProperty.java index c68b823d..19c83389 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionFolderProperty.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionFolderProperty.java @@ -23,60 +23,56 @@ */ package jenkins.advancedqueue.jobinclusion.strategy; +import com.cloudbees.hudson.plugins.folder.Folder; +import com.cloudbees.hudson.plugins.folder.FolderProperty; +import com.cloudbees.hudson.plugins.folder.FolderPropertyDescriptor; import hudson.Extension; import hudson.util.ListBoxModel; - import org.kohsuke.stapler.DataBoundConstructor; -import com.cloudbees.hudson.plugins.folder.FolderProperty; -import com.cloudbees.hudson.plugins.folder.FolderPropertyDescriptor; -import com.cloudbees.hudson.plugins.folder.Folder; - /** * @author Magnus Sandberg * @since 3.0 */ public class JobInclusionFolderProperty extends FolderProperty { - private boolean useJobGroup; + private boolean useJobGroup; - private String jobGroupName; + private String jobGroupName; - @DataBoundConstructor - public JobInclusionFolderProperty(Boolean useJobGroup, String jobGroupName) { - this.useJobGroup = useJobGroup; - this.jobGroupName = jobGroupName; - } + @DataBoundConstructor + public JobInclusionFolderProperty(Boolean useJobGroup, String jobGroupName) { + this.useJobGroup = useJobGroup; + this.jobGroupName = jobGroupName; + } - public String getJobGroupName() { - return jobGroupName; - } - - public boolean isUseJobGroup() { - return useJobGroup; - } + public String getJobGroupName() { + return jobGroupName; + } + public boolean isUseJobGroup() { + return useJobGroup; + } - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } - @Extension(optional = true) - public static final class DescriptorImpl extends FolderPropertyDescriptor { - - @Override - public String getDisplayName() { - return "XXX"; - } + @Extension(optional = true) + public static final class DescriptorImpl extends FolderPropertyDescriptor { - public ListBoxModel getJobGroups() { - return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups(); - } + @Override + public String getDisplayName() { + return "XXX"; + } - public boolean isUsed() { - return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups().size() > 0; - } - } + public ListBoxModel getJobGroups() { + return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups(); + } + public boolean isUsed() { + return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups().size() > 0; + } + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionJobProperty.java b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionJobProperty.java index e6780a7b..da8a5b5c 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionJobProperty.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/JobInclusionJobProperty.java @@ -28,7 +28,6 @@ import hudson.model.JobProperty; import hudson.model.JobPropertyDescriptor; import hudson.util.ListBoxModel; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -37,45 +36,43 @@ */ public class JobInclusionJobProperty extends JobProperty> { - private boolean useJobGroup; + private boolean useJobGroup; - private String jobGroupName; + private String jobGroupName; - @DataBoundConstructor - public JobInclusionJobProperty(Boolean useJobGroup, String jobGroupName) { - this.useJobGroup = useJobGroup; - this.jobGroupName = jobGroupName; - } + @DataBoundConstructor + public JobInclusionJobProperty(Boolean useJobGroup, String jobGroupName) { + this.useJobGroup = useJobGroup; + this.jobGroupName = jobGroupName; + } - public String getJobGroupName() { - return jobGroupName; - } - - public boolean isUseJobGroup() { - return useJobGroup; - } + public String getJobGroupName() { + return jobGroupName; + } + public boolean isUseJobGroup() { + return useJobGroup; + } - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } - @Extension - public static final class DescriptorImpl extends JobPropertyDescriptor { - - @Override - public String getDisplayName() { - return "XXX"; - } + @Extension + public static final class DescriptorImpl extends JobPropertyDescriptor { - public ListBoxModel getJobGroups() { - return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups(); - } + @Override + public String getDisplayName() { + return "XXX"; + } - public boolean isUsed() { - return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups().size() > 0; - } - } + public ListBoxModel getJobGroups() { + return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups(); + } + public boolean isUsed() { + return PropertyBasedJobInclusionStrategy.getPropertyBasesJobGroups().size() > 0; + } + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/PropertyBasedJobInclusionStrategy.java b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/PropertyBasedJobInclusionStrategy.java index f10acf6c..80465fa3 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/PropertyBasedJobInclusionStrategy.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/PropertyBasedJobInclusionStrategy.java @@ -28,15 +28,12 @@ import hudson.model.Descriptor; import hudson.model.Job; import hudson.util.ListBoxModel; - import java.util.List; - import jenkins.advancedqueue.DecisionLogger; import jenkins.advancedqueue.JobGroup; import jenkins.advancedqueue.PriorityConfiguration; import jenkins.advancedqueue.jobinclusion.JobInclusionStrategy; import jenkins.model.Jenkins; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -45,82 +42,81 @@ */ public class PropertyBasedJobInclusionStrategy extends JobInclusionStrategy { - @Extension - static public class PropertyBasedJobInclusionStrategyDescriptor extends Descriptor { - - private boolean cloudbeesFolders = true; - - @Override - public String getDisplayName() { - if (cloudbeesFolders) { - return Messages.Jobs_and_Folders_marked_for_inclusion(); - } else { - return Messages.Jobs_marked_for_inclusion(); - } - } - - public PropertyBasedJobInclusionStrategyDescriptor() { - Plugin plugin = Jenkins.get().getPlugin("cloudbees-folder"); - if(plugin == null || !plugin.getWrapper().isEnabled()){ - cloudbeesFolders = false; - } - } - - }; - - private String name; - - @DataBoundConstructor - public PropertyBasedJobInclusionStrategy(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public boolean contains(DecisionLogger decisionLogger, Job job) { - JobInclusionJobProperty property = job.getProperty(JobInclusionJobProperty.class); - decisionLogger.addDecisionLog(2, "Checking for Job Property inclusion for [" + name + "]..."); - if (property != null && property.isUseJobGroup()) { - decisionLogger.addDecisionLog(3, "JobGroup is enabled on job, with JobGroup [" + property.getJobGroupName() - + "] ..."); - boolean match = name.equals(property.getJobGroupName()); - if (match) { - decisionLogger.addDecisionLog(3, "Job is included in JobGroup ..."); - } else { - decisionLogger.addDecisionLog(3, "Job is not included in JobGroup ..."); - } - return match; - } - if (((PropertyBasedJobInclusionStrategyDescriptor) getDescriptor()).cloudbeesFolders) { - String jobViewName = FolderPropertyLoader.getJobGroupName(decisionLogger, job); - if (jobViewName == null) { - return false; - } - boolean match = name.equals(jobViewName); - if (match) { - decisionLogger.addDecisionLog(4, "Job is included in JobGroup ..."); - } else { - decisionLogger.addDecisionLog(4, "Job is not included in JobGroup ..."); - } - return match; - } else { - return false; - } - } - - public static ListBoxModel getPropertyBasesJobGroups() { - List jobGroups = PriorityConfiguration.get().getJobGroups(); - ListBoxModel strategies = new ListBoxModel(); - for (JobGroup jobGroup : jobGroups) { - JobInclusionStrategy inclusionStrategy = jobGroup.getJobGroupStrategy(); - if (inclusionStrategy instanceof PropertyBasedJobInclusionStrategy) { - strategies.add(((PropertyBasedJobInclusionStrategy) inclusionStrategy).getName()); - } - } - return strategies; - } - + @Extension + public static class PropertyBasedJobInclusionStrategyDescriptor extends Descriptor { + + private boolean cloudbeesFolders = true; + + @Override + public String getDisplayName() { + if (cloudbeesFolders) { + return Messages.Jobs_and_Folders_marked_for_inclusion(); + } else { + return Messages.Jobs_marked_for_inclusion(); + } + } + + public PropertyBasedJobInclusionStrategyDescriptor() { + Plugin plugin = Jenkins.get().getPlugin("cloudbees-folder"); + if (plugin == null || !plugin.getWrapper().isEnabled()) { + cloudbeesFolders = false; + } + } + } + ; + + private String name; + + @DataBoundConstructor + public PropertyBasedJobInclusionStrategy(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public boolean contains(DecisionLogger decisionLogger, Job job) { + JobInclusionJobProperty property = job.getProperty(JobInclusionJobProperty.class); + decisionLogger.addDecisionLog(2, "Checking for Job Property inclusion for [" + name + "]..."); + if (property != null && property.isUseJobGroup()) { + decisionLogger.addDecisionLog( + 3, "JobGroup is enabled on job, with JobGroup [" + property.getJobGroupName() + "] ..."); + boolean match = name.equals(property.getJobGroupName()); + if (match) { + decisionLogger.addDecisionLog(3, "Job is included in JobGroup ..."); + } else { + decisionLogger.addDecisionLog(3, "Job is not included in JobGroup ..."); + } + return match; + } + if (((PropertyBasedJobInclusionStrategyDescriptor) getDescriptor()).cloudbeesFolders) { + String jobViewName = FolderPropertyLoader.getJobGroupName(decisionLogger, job); + if (jobViewName == null) { + return false; + } + boolean match = name.equals(jobViewName); + if (match) { + decisionLogger.addDecisionLog(4, "Job is included in JobGroup ..."); + } else { + decisionLogger.addDecisionLog(4, "Job is not included in JobGroup ..."); + } + return match; + } else { + return false; + } + } + + public static ListBoxModel getPropertyBasesJobGroups() { + List jobGroups = PriorityConfiguration.get().getJobGroups(); + ListBoxModel strategies = new ListBoxModel(); + for (JobGroup jobGroup : jobGroups) { + JobInclusionStrategy inclusionStrategy = jobGroup.getJobGroupStrategy(); + if (inclusionStrategy instanceof PropertyBasedJobInclusionStrategy) { + strategies.add(((PropertyBasedJobInclusionStrategy) inclusionStrategy).getName()); + } + } + return strategies; + } } diff --git a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/ViewBasedJobInclusionStrategy.java b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/ViewBasedJobInclusionStrategy.java index 1fed76dc..e41b81f0 100644 --- a/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/ViewBasedJobInclusionStrategy.java +++ b/src/main/java/jenkins/advancedqueue/jobinclusion/strategy/ViewBasedJobInclusionStrategy.java @@ -30,17 +30,14 @@ import hudson.model.ViewGroup; import hudson.util.FormValidation; import hudson.util.ListBoxModel; - import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; - import jenkins.advancedqueue.DecisionLogger; import jenkins.advancedqueue.jobinclusion.JobInclusionStrategy; import jenkins.model.Jenkins; - import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -50,37 +47,36 @@ */ public class ViewBasedJobInclusionStrategy extends JobInclusionStrategy { - private final static Logger LOGGER = Logger.getLogger(ViewBasedJobInclusionStrategy.class.getName()); - - @Extension - static public class ViewBasedJobInclusionStrategyDescriptor extends - AbstractJobInclusionStrategyDescriptor { - - public ViewBasedJobInclusionStrategyDescriptor() { - super(Messages.Jobs_included_in_a_view()); - } - - public ListBoxModel getListViewItems() { - ListBoxModel items = new ListBoxModel(); - Collection views = Jenkins.get().getViews(); - addViews("", items, views); - return items; - } - - - private void addViews(String parent, ListBoxModel items, Collection views) { - for (View view : views) { - items.add(parent + view.getDisplayName(), parent + view.getViewName()); - if(view instanceof ViewGroup) { - addViews(parent + view.getDisplayName() + "/", items, ((ViewGroup) view).getViews()); - } - } - } - - public FormValidation doCheckJobPattern(@QueryParameter String jobPattern) { - if(jobPattern.isEmpty()) { - return FormValidation.ok(Messages.Empty_pattern_matches_all_jobs()); - } + private static final Logger LOGGER = Logger.getLogger(ViewBasedJobInclusionStrategy.class.getName()); + + @Extension + public static class ViewBasedJobInclusionStrategyDescriptor + extends AbstractJobInclusionStrategyDescriptor { + + public ViewBasedJobInclusionStrategyDescriptor() { + super(Messages.Jobs_included_in_a_view()); + } + + public ListBoxModel getListViewItems() { + ListBoxModel items = new ListBoxModel(); + Collection views = Jenkins.get().getViews(); + addViews("", items, views); + return items; + } + + private void addViews(String parent, ListBoxModel items, Collection views) { + for (View view : views) { + items.add(parent + view.getDisplayName(), parent + view.getViewName()); + if (view instanceof ViewGroup) { + addViews(parent + view.getDisplayName() + "/", items, ((ViewGroup) view).getViews()); + } + } + } + + public FormValidation doCheckJobPattern(@QueryParameter String jobPattern) { + if (jobPattern.isEmpty()) { + return FormValidation.ok(Messages.Empty_pattern_matches_all_jobs()); + } try { Pattern.compile(jobPattern); } catch (PatternSyntaxException exception) { @@ -88,125 +84,123 @@ public FormValidation doCheckJobPattern(@QueryParameter String jobPattern) { } return FormValidation.ok(Messages.Pattern_is_valid()); } - - }; - - static public class JobPattern { - private String jobPattern; - - @DataBoundConstructor - public JobPattern(String jobPattern) { - this.jobPattern = jobPattern; - } - - } - - private String viewName; - - private boolean useJobFilter = false; - - private String jobPattern = ".*"; - - @DataBoundConstructor - public ViewBasedJobInclusionStrategy(String viewName, JobPattern jobFilter) { - this.viewName = viewName; - this.useJobFilter = (jobFilter != null); - if (this.useJobFilter) { - if (jobFilter != null) { - this.jobPattern = jobFilter.jobPattern; - } else { - LOGGER.log(Level.SEVERE, "Ignoring null job filter for view ''{0}''", viewName); - } - } - } - - public String getViewName() { - return viewName; - } - - public boolean isUseJobFilter() { - return useJobFilter; - } - - public String getJobPattern() { - return jobPattern; - } - - private View getView() { - String[] nestedViewNames = this.viewName.split("/"); - final Jenkins jenkins = Jenkins.get(); - View view = jenkins.getView(nestedViewNames[0]); - if(null == view) { - LOGGER.log(Level.SEVERE, "Configured View does not exist ''{0}'' using primary view", viewName); - return jenkins.getPrimaryView(); - } - for(int i = 1; i < nestedViewNames.length; i++) { - if (!(view instanceof ViewGroup)) { - LOGGER.log(Level.SEVERE, "View is not a ViewGroup ''{0}'', using primary view", viewName); - return jenkins.getPrimaryView(); - } - view = ((ViewGroup) view).getView(nestedViewNames[i]); - if(null == view) { - LOGGER.log(Level.SEVERE, "Configured View does not exist ''{0}'' using primary view", viewName); - return jenkins.getPrimaryView(); - } - } - return view; - } - - @Override - public boolean contains(DecisionLogger decisionLogger, Job job) { - if (isJobInView(job, getView())) { - if (!isUseJobFilter() || getJobPattern().trim().isEmpty()) { - decisionLogger.addDecisionLog(2, "Not using filter ..."); - return true; - } else { - decisionLogger.addDecisionLog(2, "Using filter ..."); - // So filtering is on - use the priority if there's - // a match - try { - if (job.getName().matches(getJobPattern())) { - decisionLogger.addDecisionLog(3, "Job is matching the filter ..."); - return true; - } else { - decisionLogger.addDecisionLog(3, "Job is not matching the filter ..."); - return false; - } - } catch (PatternSyntaxException e) { - // If the pattern is broken treat this a non - // match - decisionLogger.addDecisionLog(3, "Filter has syntax error"); - return false; - } - } - } - return false; - } - - private boolean isJobInView(Job job, View view) { - // First do a simple test using contains - if(view.contains((TopLevelItem) job)) { - return true; - } - // Then try to get the Items (Sectioned View) - if(view.getItems().contains(job)) { - return true; - } - // Then try to iterate over the ViewGroup (Nested View) - if(view instanceof ViewGroup) { - return isJobInViewGroup(job, (ViewGroup) view); - } - return false; - } - - private boolean isJobInViewGroup(Job job, ViewGroup viewGroup) { - Collection views = viewGroup.getViews(); - for (View view : views) { - if(isJobInView(job, view)) { - return true; - } - } - return false; - } + } + ; + + public static class JobPattern { + private String jobPattern; + + @DataBoundConstructor + public JobPattern(String jobPattern) { + this.jobPattern = jobPattern; + } + } + + private String viewName; + private boolean useJobFilter = false; + + private String jobPattern = ".*"; + + @DataBoundConstructor + public ViewBasedJobInclusionStrategy(String viewName, JobPattern jobFilter) { + this.viewName = viewName; + this.useJobFilter = (jobFilter != null); + if (this.useJobFilter) { + if (jobFilter != null) { + this.jobPattern = jobFilter.jobPattern; + } else { + LOGGER.log(Level.SEVERE, "Ignoring null job filter for view ''{0}''", viewName); + } + } + } + + public String getViewName() { + return viewName; + } + + public boolean isUseJobFilter() { + return useJobFilter; + } + + public String getJobPattern() { + return jobPattern; + } + + private View getView() { + String[] nestedViewNames = this.viewName.split("/"); + final Jenkins jenkins = Jenkins.get(); + View view = jenkins.getView(nestedViewNames[0]); + if (null == view) { + LOGGER.log(Level.SEVERE, "Configured View does not exist ''{0}'' using primary view", viewName); + return jenkins.getPrimaryView(); + } + for (int i = 1; i < nestedViewNames.length; i++) { + if (!(view instanceof ViewGroup)) { + LOGGER.log(Level.SEVERE, "View is not a ViewGroup ''{0}'', using primary view", viewName); + return jenkins.getPrimaryView(); + } + view = ((ViewGroup) view).getView(nestedViewNames[i]); + if (null == view) { + LOGGER.log(Level.SEVERE, "Configured View does not exist ''{0}'' using primary view", viewName); + return jenkins.getPrimaryView(); + } + } + return view; + } + + @Override + public boolean contains(DecisionLogger decisionLogger, Job job) { + if (isJobInView(job, getView())) { + if (!isUseJobFilter() || getJobPattern().trim().isEmpty()) { + decisionLogger.addDecisionLog(2, "Not using filter ..."); + return true; + } else { + decisionLogger.addDecisionLog(2, "Using filter ..."); + // So filtering is on - use the priority if there's + // a match + try { + if (job.getName().matches(getJobPattern())) { + decisionLogger.addDecisionLog(3, "Job is matching the filter ..."); + return true; + } else { + decisionLogger.addDecisionLog(3, "Job is not matching the filter ..."); + return false; + } + } catch (PatternSyntaxException e) { + // If the pattern is broken treat this a non + // match + decisionLogger.addDecisionLog(3, "Filter has syntax error"); + return false; + } + } + } + return false; + } + + private boolean isJobInView(Job job, View view) { + // First do a simple test using contains + if (view.contains((TopLevelItem) job)) { + return true; + } + // Then try to get the Items (Sectioned View) + if (view.getItems().contains(job)) { + return true; + } + // Then try to iterate over the ViewGroup (Nested View) + if (view instanceof ViewGroup) { + return isJobInViewGroup(job, (ViewGroup) view); + } + return false; + } + + private boolean isJobInViewGroup(Job job, ViewGroup viewGroup) { + Collection views = viewGroup.getViews(); + for (View view : views) { + if (isJobInView(job, view)) { + return true; + } + } + return false; + } } diff --git a/src/main/java/jenkins/advancedqueue/jobrestrictions/PrioritySorterRestriction.java b/src/main/java/jenkins/advancedqueue/jobrestrictions/PrioritySorterRestriction.java index fae82948..04020e04 100644 --- a/src/main/java/jenkins/advancedqueue/jobrestrictions/PrioritySorterRestriction.java +++ b/src/main/java/jenkins/advancedqueue/jobrestrictions/PrioritySorterRestriction.java @@ -23,101 +23,97 @@ */ package jenkins.advancedqueue.jobrestrictions; +import com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestriction; +import com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestrictionDescriptor; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -import java.util.logging.Logger; - import hudson.Extension; import hudson.model.Queue.BuildableItem; import hudson.model.Run; import hudson.util.ListBoxModel; +import java.util.logging.Logger; import jenkins.advancedqueue.Messages; import jenkins.advancedqueue.PrioritySorterConfiguration; import jenkins.advancedqueue.sorter.ItemInfo; import jenkins.advancedqueue.sorter.QueueItemCache; import jenkins.advancedqueue.util.PrioritySorterUtil; - import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; -import com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestriction; -import com.synopsys.arc.jenkinsci.plugins.jobrestrictions.restrictions.JobRestrictionDescriptor; - /** * Extends the {@link JobRestriction} from Job Restrictions Plugin - * making it possible to restrict Node usage based on priority. - * + * making it possible to restrict Node usage based on priority. + * * @author Magnus Sandberg * @since 3.3 */ -@SuppressFBWarnings(value="SE_NO_SERIALVERSIONID", - justification="Common usage in Jenkins to not include SE_NO_SERIALVERSIONID") +@SuppressFBWarnings( + value = "SE_NO_SERIALVERSIONID", + justification = "Common usage in Jenkins to not include SE_NO_SERIALVERSIONID") public class PrioritySorterRestriction extends JobRestriction { - - private final static Logger LOGGER = Logger.getLogger(PrioritySorterRestriction.class.getName()); - - @Extension(optional = true) - public static class DescriptorImpl extends JobRestrictionDescriptor { - - @Override - public String getDisplayName() { - return Messages.Priority_from_prioritySorter(); - } - - public ListBoxModel doFillFromPriorityItems() { - return PrioritySorterUtil.fillPriorityItems(PrioritySorterConfiguration.get().getStrategy() - .getNumberOfPriorities()); - } - - public ListBoxModel doFillToPriorityItems() { - return PrioritySorterUtil.fillPriorityItems(PrioritySorterConfiguration.get().getStrategy() - .getNumberOfPriorities()); - } - - public ListBoxModel doUpdateFromPriorityItems(@QueryParameter("value") String strValue) { - int value = 1; - try { - value = Integer.parseInt(strValue); - } catch (NumberFormatException e) { - // Use default value - } - return PrioritySorterUtil.fillPriorityItems(value, PrioritySorterConfiguration.get() - .getStrategy().getNumberOfPriorities()); - } - - } - - private int fromPriority; - - private int toPriority; - - public int getFromPriority() { - return fromPriority; - } - - public int getToPriority() { - return toPriority; - } - - @DataBoundConstructor - public PrioritySorterRestriction(int fromPriority, int toPriority) { - this.fromPriority = fromPriority; - this.toPriority = toPriority; - } - - @Override - public boolean canTake(BuildableItem buildableItem) { - ItemInfo item = QueueItemCache.get().getItem(buildableItem.getId()); - if(item == null) { - LOGGER.warning("Missing ItemInfo for [" + buildableItem.task.getDisplayName() + "] allowing execution."); - return true; - } - int priority = item.getPriority(); - return priority >= fromPriority && priority <= toPriority; - } - @Override - public boolean canTake(Run run) { - return true; - } + private static final Logger LOGGER = Logger.getLogger(PrioritySorterRestriction.class.getName()); + + @Extension(optional = true) + public static class DescriptorImpl extends JobRestrictionDescriptor { + + @Override + public String getDisplayName() { + return Messages.Priority_from_prioritySorter(); + } + + public ListBoxModel doFillFromPriorityItems() { + return PrioritySorterUtil.fillPriorityItems( + PrioritySorterConfiguration.get().getStrategy().getNumberOfPriorities()); + } + + public ListBoxModel doFillToPriorityItems() { + return PrioritySorterUtil.fillPriorityItems( + PrioritySorterConfiguration.get().getStrategy().getNumberOfPriorities()); + } + + public ListBoxModel doUpdateFromPriorityItems(@QueryParameter("value") String strValue) { + int value = 1; + try { + value = Integer.parseInt(strValue); + } catch (NumberFormatException e) { + // Use default value + } + return PrioritySorterUtil.fillPriorityItems( + value, PrioritySorterConfiguration.get().getStrategy().getNumberOfPriorities()); + } + } + + private int fromPriority; + + private int toPriority; + + public int getFromPriority() { + return fromPriority; + } + + public int getToPriority() { + return toPriority; + } + + @DataBoundConstructor + public PrioritySorterRestriction(int fromPriority, int toPriority) { + this.fromPriority = fromPriority; + this.toPriority = toPriority; + } + + @Override + public boolean canTake(BuildableItem buildableItem) { + ItemInfo item = QueueItemCache.get().getItem(buildableItem.getId()); + if (item == null) { + LOGGER.warning("Missing ItemInfo for [" + buildableItem.task.getDisplayName() + "] allowing execution."); + return true; + } + int priority = item.getPriority(); + return priority >= fromPriority && priority <= toPriority; + } + + @Override + public boolean canTake(Run run) { + return true; + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/PriorityStrategy.java b/src/main/java/jenkins/advancedqueue/priority/PriorityStrategy.java index a65c5ca1..882d850b 100644 --- a/src/main/java/jenkins/advancedqueue/priority/PriorityStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/PriorityStrategy.java @@ -38,31 +38,30 @@ */ public abstract class PriorityStrategy implements ExtensionPoint, Describable { - /** - * Method that checks if strategy can assign a priority to the provided {@link Item} - * - * The caller guaranties that the {@link Item#task} is a {@link Job} - * - * @param item the {@link Item} to check - * @return true if the {@link PriorityStrategy} is applicable else false - */ - abstract public boolean isApplicable(Queue.Item item); + /** + * Method that checks if strategy can assign a priority to the provided {@link Item} + * + * The caller guaranties that the {@link Item#task} is a {@link Job} + * + * @param item the {@link Item} to check + * @return true if the {@link PriorityStrategy} is applicable else false + */ + public abstract boolean isApplicable(Queue.Item item); - /** - * Method that that return the priority that should be used for this {@link Item}, this method is only called id - * {@link PriorityStrategy#isApplicable(Queue.Item)} returned true - * - * The caller garanties that the {@link Item#task} is a {@link Job} - * - * @param item the {@link Item} to check - * @return the priority to be used by the provided {@link Item} - */ - abstract public int getPriority(Queue.Item item); + /** + * Method that that return the priority that should be used for this {@link Item}, this method is only called id + * {@link PriorityStrategy#isApplicable(Queue.Item)} returned true + * + * The caller garanties that the {@link Item#task} is a {@link Job} + * + * @param item the {@link Item} to check + * @return the priority to be used by the provided {@link Item} + */ + public abstract int getPriority(Queue.Item item); - abstract public void numberPrioritiesUpdates(int oldNumberOfPriorities, int newNumberOfPriorities); - - public static DescriptorExtensionList> all() { - return Jenkins.get().getDescriptorList(PriorityStrategy.class); - } + public abstract void numberPrioritiesUpdates(int oldNumberOfPriorities, int newNumberOfPriorities); + public static DescriptorExtensionList> all() { + return Jenkins.get().getDescriptorList(PriorityStrategy.class); + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractDynamicPriorityStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractDynamicPriorityStrategy.java index 86bfaaba..66d36fca 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractDynamicPriorityStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractDynamicPriorityStrategy.java @@ -4,31 +4,30 @@ import jenkins.advancedqueue.priority.PriorityStrategy; import jenkins.model.Jenkins; -abstract public class AbstractDynamicPriorityStrategy extends PriorityStrategy { +public abstract class AbstractDynamicPriorityStrategy extends PriorityStrategy { - static public class AbstractDynamicPriorityStrategyDescriptor extends Descriptor { + public static class AbstractDynamicPriorityStrategyDescriptor extends Descriptor { - private final String displayName; + private final String displayName; - protected AbstractDynamicPriorityStrategyDescriptor(String displayName) { - this.displayName = displayName; - } + protected AbstractDynamicPriorityStrategyDescriptor(String displayName) { + this.displayName = displayName; + } - @Override - public String getDisplayName() { - return displayName; - } + @Override + public String getDisplayName() { + return displayName; + } + } + ; - }; - - @SuppressWarnings("unchecked") - public Descriptor getDescriptor() { - return Jenkins.get().getDescriptor(this.getClass()); - } - - @Override - public void numberPrioritiesUpdates(int oldNumberOfPriorities, int newNumberOfPriorities) { - // ignore as we do not store/control the priority - } + @SuppressWarnings("unchecked") + public Descriptor getDescriptor() { + return Jenkins.get().getDescriptor(this.getClass()); + } + @Override + public void numberPrioritiesUpdates(int oldNumberOfPriorities, int newNumberOfPriorities) { + // ignore as we do not store/control the priority + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractStaticPriorityStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractStaticPriorityStrategy.java index b4fe20bd..acae224c 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractStaticPriorityStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/AbstractStaticPriorityStrategy.java @@ -8,52 +8,50 @@ import jenkins.advancedqueue.priority.PriorityStrategy; import jenkins.model.Jenkins; -abstract public class AbstractStaticPriorityStrategy extends PriorityStrategy { +public abstract class AbstractStaticPriorityStrategy extends PriorityStrategy { - static public class AbstractStaticPriorityStrategyDescriptor extends Descriptor { + public static class AbstractStaticPriorityStrategyDescriptor extends Descriptor { - private final String displayName; + private final String displayName; - protected AbstractStaticPriorityStrategyDescriptor(String displayName) { - this.displayName = displayName; - } + protected AbstractStaticPriorityStrategyDescriptor(String displayName) { + this.displayName = displayName; + } - public ListBoxModel getPriorities() { - ListBoxModel items = PrioritySorterConfiguration.get().doGetPriorityItems(); - return items; - } + public ListBoxModel getPriorities() { + ListBoxModel items = PrioritySorterConfiguration.get().doGetPriorityItems(); + return items; + } - @Override - public String getDisplayName() { - return displayName; - } + @Override + public String getDisplayName() { + return displayName; + } + } + ; - }; + @SuppressWarnings("unchecked") + public Descriptor getDescriptor() { + return Jenkins.get().getDescriptor(this.getClass()); + } - @SuppressWarnings("unchecked") - public Descriptor getDescriptor() { - return Jenkins.get().getDescriptor(this.getClass()); - } + private int priority; - private int priority; + @Override + public void numberPrioritiesUpdates(int oldNumberOfPriorities, int newNumberOfPriorities) { + priority = PriorityCalculationsUtil.scale(oldNumberOfPriorities, newNumberOfPriorities, priority); + } - @Override - public void numberPrioritiesUpdates(int oldNumberOfPriorities, int newNumberOfPriorities) { - priority = PriorityCalculationsUtil.scale(oldNumberOfPriorities, newNumberOfPriorities, priority); + public int getPriority() { + return priority; + } - } - - public int getPriority() { - return priority; - } - - public void setPriority(int priority) { - this.priority = priority; - } - - @Override - public int getPriority(Queue.Item item) { - return priority; - } + public void setPriority(int priority) { + this.priority = priority; + } + @Override + public int getPriority(Queue.Item item) { + return priority; + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/BuildParameterStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/BuildParameterStrategy.java index 0d288a40..44443077 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/BuildParameterStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/BuildParameterStrategy.java @@ -25,17 +25,13 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; - import hudson.Extension; import hudson.model.ParametersAction; import hudson.model.Queue; import hudson.model.StringParameterValue; - import java.util.List; - import jenkins.advancedqueue.Messages; import jenkins.advancedqueue.PrioritySorterConfiguration; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -44,58 +40,59 @@ */ public class BuildParameterStrategy extends AbstractDynamicPriorityStrategy { - @Extension - static public class BuildParameterStrategyDescriptor extends AbstractDynamicPriorityStrategyDescriptor { + @Extension + public static class BuildParameterStrategyDescriptor extends AbstractDynamicPriorityStrategyDescriptor { - public BuildParameterStrategyDescriptor() { - super(Messages.Use_Priority_from_Build_Parameter()); - } - }; + public BuildParameterStrategyDescriptor() { + super(Messages.Use_Priority_from_Build_Parameter()); + } + } + ; - private final String parameterName; + private final String parameterName; - @DataBoundConstructor - public BuildParameterStrategy(String parameterName) { - this.parameterName = parameterName; - } + @DataBoundConstructor + public BuildParameterStrategy(String parameterName) { + this.parameterName = parameterName; + } - public String getParameterName() { - return parameterName; - } + public String getParameterName() { + return parameterName; + } - @CheckForNull - private Integer getPriorityInternal(@NonNull Queue.Item item) { - List actions = item.getActions(ParametersAction.class); - for (ParametersAction action : actions) { - StringParameterValue parameterValue = (StringParameterValue) action.getParameter(parameterName); - if (parameterValue != null) { - String value = parameterValue.getValue(); - if (value == null) { - // continue since we cannot take this value - continue; - } - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - // continue - } - } - } - return null; - } + @CheckForNull + private Integer getPriorityInternal(@NonNull Queue.Item item) { + List actions = item.getActions(ParametersAction.class); + for (ParametersAction action : actions) { + StringParameterValue parameterValue = (StringParameterValue) action.getParameter(parameterName); + if (parameterValue != null) { + String value = parameterValue.getValue(); + if (value == null) { + // continue since we cannot take this value + continue; + } + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + // continue + } + } + } + return null; + } - /** - * Gets priority of the queue item. - * @param item Queue item - * @return Priority if it can be determined. Default priority otherwise - */ - public int getPriority(@NonNull Queue.Item item) { - final Integer p = getPriorityInternal(item); - return p != null ? p : PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); - } + /** + * Gets priority of the queue item. + * @param item Queue item + * @return Priority if it can be determined. Default priority otherwise + */ + public int getPriority(@NonNull Queue.Item item) { + final Integer p = getPriorityInternal(item); + return p != null ? p : PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); + } - @Override - public boolean isApplicable(@NonNull Queue.Item item) { - return getPriorityInternal(item) != null; - } + @Override + public boolean isApplicable(@NonNull Queue.Item item) { + return getPriorityInternal(item) != null; + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/CLICauseStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/CLICauseStrategy.java index 9b4f76c9..ab546b71 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/CLICauseStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/CLICauseStrategy.java @@ -27,9 +27,7 @@ import hudson.cli.BuildCommand.CLICause; import hudson.model.Cause; import hudson.model.Queue; - import java.util.List; - import jenkins.advancedqueue.Messages; import org.kohsuke.stapler.DataBoundConstructor; @@ -39,29 +37,27 @@ */ public class CLICauseStrategy extends AbstractStaticPriorityStrategy { - @Extension - public static class UserIdCauseStrategyDescriptor extends AbstractStaticPriorityStrategyDescriptor { - - public UserIdCauseStrategyDescriptor() { - super(Messages.Job_triggered_from_CLI()); - } - - } - - @DataBoundConstructor - public CLICauseStrategy(int priority) { - setPriority(priority); - } - - @Override - public boolean isApplicable(Queue.Item item) { - List causes = item.getCauses(); - for (Cause cause : causes) { - if (cause.getClass() == CLICause.class) { - return true; - } - } - return false; - } - + @Extension + public static class UserIdCauseStrategyDescriptor extends AbstractStaticPriorityStrategyDescriptor { + + public UserIdCauseStrategyDescriptor() { + super(Messages.Job_triggered_from_CLI()); + } + } + + @DataBoundConstructor + public CLICauseStrategy(int priority) { + setPriority(priority); + } + + @Override + public boolean isApplicable(Queue.Item item) { + List causes = item.getCauses(); + for (Cause cause : causes) { + if (cause.getClass() == CLICause.class) { + return true; + } + } + return false; + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/HealthStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/HealthStrategy.java index 9516627d..456b93f1 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/HealthStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/HealthStrategy.java @@ -26,7 +26,6 @@ import hudson.Extension; import hudson.model.Job; import hudson.model.Queue; - import jenkins.advancedqueue.Messages; import org.kohsuke.stapler.DataBoundConstructor; @@ -36,69 +35,67 @@ */ public class HealthStrategy extends AbstractStaticPriorityStrategy { - @Extension - public static class HealthStrategyDescriptor extends AbstractStaticPriorityStrategyDescriptor { - - public HealthStrategyDescriptor() { - super(Messages.Using_the_jobs_health()); - } - - } + @Extension + public static class HealthStrategyDescriptor extends AbstractStaticPriorityStrategyDescriptor { - private String selection; + public HealthStrategyDescriptor() { + super(Messages.Using_the_jobs_health()); + } + } - private String health; + private String selection; - @DataBoundConstructor - public HealthStrategy(int priority, String selection, String health) { - setPriority(priority); - this.selection = selection; - this.health = health; - } + private String health; - public String getSelection() { - return selection; - } + @DataBoundConstructor + public HealthStrategy(int priority, String selection, String health) { + setPriority(priority); + this.selection = selection; + this.health = health; + } - public String getHealth() { - return health; - } + public String getSelection() { + return selection; + } - @Override - public boolean isApplicable(Queue.Item item) { - Job job = (Job) item.task; - if(!job.getBuilds().iterator().hasNext()) { - return false; - } - int score = job.getBuildHealth().getScore(); - int scoreOver = 0; - int scoreUnder = 100; - if("HEALTH_OVER_80".equals(health)) { - scoreOver = 80; - scoreUnder = 100; - } else if("HEALTH_61_TO_80".equals(health)) { - scoreOver = 61; - scoreUnder = 80; - } else if("HEALTH_41_TO_60".equals(health)) { - scoreOver = 41; - scoreUnder = 60; - } else if("HEALTH_21_TO_40".equals(health)) { - scoreOver = 21; - scoreUnder = 40; - } else if("HEALTH_0_TO_20".equals(health)) { - scoreOver = 0; - scoreUnder = 20; - } - if("SAME".equals(selection)) { - return score >= scoreOver && score <= scoreUnder; - } - if("BETTER".equals(selection)) { - return score >= scoreOver; - } - if("WORSE".equals(selection)) { - return score <= scoreUnder; - } - return false; - } + public String getHealth() { + return health; + } + @Override + public boolean isApplicable(Queue.Item item) { + Job job = (Job) item.task; + if (!job.getBuilds().iterator().hasNext()) { + return false; + } + int score = job.getBuildHealth().getScore(); + int scoreOver = 0; + int scoreUnder = 100; + if ("HEALTH_OVER_80".equals(health)) { + scoreOver = 80; + scoreUnder = 100; + } else if ("HEALTH_61_TO_80".equals(health)) { + scoreOver = 61; + scoreUnder = 80; + } else if ("HEALTH_41_TO_60".equals(health)) { + scoreOver = 41; + scoreUnder = 60; + } else if ("HEALTH_21_TO_40".equals(health)) { + scoreOver = 21; + scoreUnder = 40; + } else if ("HEALTH_0_TO_20".equals(health)) { + scoreOver = 0; + scoreUnder = 20; + } + if ("SAME".equals(selection)) { + return score >= scoreOver && score <= scoreUnder; + } + if ("BETTER".equals(selection)) { + return score >= scoreOver; + } + if ("WORSE".equals(selection)) { + return score <= scoreUnder; + } + return false; + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/JobPropertyStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/JobPropertyStrategy.java index b5eb5b18..f3b7fe3b 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/JobPropertyStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/JobPropertyStrategy.java @@ -24,15 +24,12 @@ package jenkins.advancedqueue.priority.strategy; import edu.umd.cs.findbugs.annotations.CheckForNull; - import hudson.Extension; import hudson.model.Job; import hudson.model.Queue; import hudson.model.Queue.Item; - import jenkins.advancedqueue.Messages; import jenkins.advancedqueue.PrioritySorterConfiguration; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -41,40 +38,37 @@ */ public class JobPropertyStrategy extends AbstractDynamicPriorityStrategy { - @Extension - public static class UserIdCauseStrategyDescriptor extends AbstractDynamicPriorityStrategyDescriptor { - - public UserIdCauseStrategyDescriptor() { - super(Messages.Take_the_priority_from_property_on_the_job()); - } + @Extension + public static class UserIdCauseStrategyDescriptor extends AbstractDynamicPriorityStrategyDescriptor { - } + public UserIdCauseStrategyDescriptor() { + super(Messages.Take_the_priority_from_property_on_the_job()); + } + } - @DataBoundConstructor - public JobPropertyStrategy() { - } - - @CheckForNull - private Integer getPriorityInternal(Queue.Item item) { - if(item.task instanceof Job) { - Job job = (Job) item.task; - PriorityJobProperty priorityProperty = job.getProperty(PriorityJobProperty.class); - if (priorityProperty != null && priorityProperty.getUseJobPriority()) { - return priorityProperty.priority; - } - } - return null; - } + @DataBoundConstructor + public JobPropertyStrategy() {} - @Override - public boolean isApplicable(Queue.Item item) { - return getPriorityInternal(item) != null; - } + @CheckForNull + private Integer getPriorityInternal(Queue.Item item) { + if (item.task instanceof Job) { + Job job = (Job) item.task; + PriorityJobProperty priorityProperty = job.getProperty(PriorityJobProperty.class); + if (priorityProperty != null && priorityProperty.getUseJobPriority()) { + return priorityProperty.priority; + } + } + return null; + } - @Override - public int getPriority(Item item) { - final Integer p = getPriorityInternal(item); - return p != null ? p : PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); - } + @Override + public boolean isApplicable(Queue.Item item) { + return getPriorityInternal(item) != null; + } + @Override + public int getPriority(Item item) { + final Integer p = getPriorityInternal(item); + return p != null ? p : PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/PriorityJobProperty.java b/src/main/java/jenkins/advancedqueue/priority/strategy/PriorityJobProperty.java index 0b7e7ae7..3ceef741 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/PriorityJobProperty.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/PriorityJobProperty.java @@ -30,10 +30,8 @@ import hudson.model.JobProperty; import hudson.model.JobPropertyDescriptor; import hudson.util.ListBoxModel; - import java.util.List; import java.util.logging.Logger; - import jenkins.advancedqueue.JobGroup; import jenkins.advancedqueue.JobGroup.PriorityStrategyHolder; import jenkins.advancedqueue.Messages; @@ -42,7 +40,6 @@ import jenkins.advancedqueue.PrioritySorterConfiguration; import jenkins.advancedqueue.priority.PriorityStrategy; import net.sf.json.JSONObject; - import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; @@ -52,88 +49,89 @@ */ public class PriorityJobProperty extends JobProperty> { - private final static Logger LOGGER = Logger.getLogger(PriorityJobProperty.class.getName()); - - public final boolean useJobPriority; - public final int priority; - - @Override - public JobProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { - return super.reconfigure(req, form); - } - - @DataBoundConstructor - public PriorityJobProperty(boolean useJobPriority, int priority) { - this.useJobPriority = useJobPriority; - this.priority = priority; - } - - public int getPriority() { - return priority; - } - - public boolean getUseJobPriority() { - return useJobPriority; - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl) super.getDescriptor(); - } - - @Extension - public static final class DescriptorImpl extends JobPropertyDescriptor { - @SuppressFBWarnings(value="SIC_INNER_SHOULD_BE_STATIC_ANON", justification="Commont pattern in Jenkins") - private PriorityConfigurationCallback dummyCallback = new PriorityConfigurationCallback() { - - @Override - public PriorityConfigurationCallback setPrioritySelection(int priority, int jobGroupId, PriorityStrategy reason) { - return this; - } - - @Override - public PriorityConfigurationCallback setPrioritySelection(int priority) { - return this; - } - - @Override - public PriorityConfigurationCallback addDecisionLog(int indent, String log) { - return this; - } - - @Override - public PriorityConfigurationCallback setPrioritySelection(int priority, long sortAsInQueueSince, - int jobGroupId, PriorityStrategy reason) { - return this; - } - }; - - @Override - public String getDisplayName() { - return Messages.AdvancedQueueSorterJobProperty_displayName(); - } - - public int getDefault() { - return PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); - } - - public ListBoxModel getPriorities() { - ListBoxModel items = PrioritySorterConfiguration.get().doGetPriorityItems(); - return items; - } - - public boolean isUsed(Job owner) { - PriorityConfiguration configuration = PriorityConfiguration.get(); - JobGroup jobGroup = configuration.getJobGroup(dummyCallback, owner); - if(jobGroup != null && jobGroup.isUsePriorityStrategies()) { - List priorityStrategies = jobGroup.getPriorityStrategies(); - for (PriorityStrategyHolder priorityStrategyHolder : priorityStrategies) { - if(priorityStrategyHolder.getPriorityStrategy() instanceof JobPropertyStrategy) { - return true; - } - } - } - return false; - } - } + private static final Logger LOGGER = Logger.getLogger(PriorityJobProperty.class.getName()); + + public final boolean useJobPriority; + public final int priority; + + @Override + public JobProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { + return super.reconfigure(req, form); + } + + @DataBoundConstructor + public PriorityJobProperty(boolean useJobPriority, int priority) { + this.useJobPriority = useJobPriority; + this.priority = priority; + } + + public int getPriority() { + return priority; + } + + public boolean getUseJobPriority() { + return useJobPriority; + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Extension + public static final class DescriptorImpl extends JobPropertyDescriptor { + @SuppressFBWarnings(value = "SIC_INNER_SHOULD_BE_STATIC_ANON", justification = "Commont pattern in Jenkins") + private PriorityConfigurationCallback dummyCallback = new PriorityConfigurationCallback() { + + @Override + public PriorityConfigurationCallback setPrioritySelection( + int priority, int jobGroupId, PriorityStrategy reason) { + return this; + } + + @Override + public PriorityConfigurationCallback setPrioritySelection(int priority) { + return this; + } + + @Override + public PriorityConfigurationCallback addDecisionLog(int indent, String log) { + return this; + } + + @Override + public PriorityConfigurationCallback setPrioritySelection( + int priority, long sortAsInQueueSince, int jobGroupId, PriorityStrategy reason) { + return this; + } + }; + + @Override + public String getDisplayName() { + return Messages.AdvancedQueueSorterJobProperty_displayName(); + } + + public int getDefault() { + return PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); + } + + public ListBoxModel getPriorities() { + ListBoxModel items = PrioritySorterConfiguration.get().doGetPriorityItems(); + return items; + } + + public boolean isUsed(Job owner) { + PriorityConfiguration configuration = PriorityConfiguration.get(); + JobGroup jobGroup = configuration.getJobGroup(dummyCallback, owner); + if (jobGroup != null && jobGroup.isUsePriorityStrategies()) { + List priorityStrategies = jobGroup.getPriorityStrategies(); + for (PriorityStrategyHolder priorityStrategyHolder : priorityStrategies) { + if (priorityStrategyHolder.getPriorityStrategy() instanceof JobPropertyStrategy) { + return true; + } + } + } + return false; + } + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/UpstreamCauseStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/UpstreamCauseStrategy.java index 23c0a7be..bb7c2ffb 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/UpstreamCauseStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/UpstreamCauseStrategy.java @@ -25,19 +25,15 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; - import hudson.Extension; import hudson.model.Cause; import hudson.model.Cause.UpstreamCause; import hudson.model.Queue; - import java.util.List; - import jenkins.advancedqueue.Messages; import jenkins.advancedqueue.PrioritySorterConfiguration; import jenkins.advancedqueue.sorter.ItemInfo; import jenkins.advancedqueue.sorter.StartedJobItemCache; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -46,47 +42,47 @@ */ public class UpstreamCauseStrategy extends AbstractDynamicPriorityStrategy { - @Extension - static public class BuildParameterStrategyDescriptor extends AbstractDynamicPriorityStrategyDescriptor { - public BuildParameterStrategyDescriptor() { - super(Messages.Job_triggered_by_a_upstream_build()); - } - }; + @Extension + public static class BuildParameterStrategyDescriptor extends AbstractDynamicPriorityStrategyDescriptor { + public BuildParameterStrategyDescriptor() { + super(Messages.Job_triggered_by_a_upstream_build()); + } + } + ; + + @DataBoundConstructor + public UpstreamCauseStrategy() {} - @DataBoundConstructor - public UpstreamCauseStrategy() { - } + @CheckForNull + private UpstreamCause getUpstreamCause(@NonNull Queue.Item item) { + List causes = item.getCauses(); + for (Cause cause : causes) { + if (cause.getClass() == UpstreamCause.class) { + return (UpstreamCause) cause; + } + } + return null; + } - @CheckForNull - private UpstreamCause getUpstreamCause(@NonNull Queue.Item item) { - List causes = item.getCauses(); - for (Cause cause : causes) { - if (cause.getClass() == UpstreamCause.class) { - return (UpstreamCause) cause; - } - } - return null; - } + public int getPriority(Queue.Item item) { + UpstreamCause upstreamCause = getUpstreamCause(item); + if (upstreamCause == null) { + // Cannot determine + return PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); + } - public int getPriority(Queue.Item item) { - UpstreamCause upstreamCause = getUpstreamCause(item); - if (upstreamCause == null) { - // Cannot determine - return PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); - } - - String upstreamProject = upstreamCause.getUpstreamProject(); - int upstreamBuildId = upstreamCause.getUpstreamBuild(); - ItemInfo upstreamItem = StartedJobItemCache.get().getStartedItem(upstreamProject, upstreamBuildId); - // Upstream Item being null should be very very rare - if (upstreamItem != null) { - return upstreamItem.getPriority(); - } - return PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); - } + String upstreamProject = upstreamCause.getUpstreamProject(); + int upstreamBuildId = upstreamCause.getUpstreamBuild(); + ItemInfo upstreamItem = StartedJobItemCache.get().getStartedItem(upstreamProject, upstreamBuildId); + // Upstream Item being null should be very very rare + if (upstreamItem != null) { + return upstreamItem.getPriority(); + } + return PrioritySorterConfiguration.get().getStrategy().getDefaultPriority(); + } - @Override - public boolean isApplicable(Queue.Item item) { - return getUpstreamCause(item) != null; - } + @Override + public boolean isApplicable(Queue.Item item) { + return getUpstreamCause(item) != null; + } } diff --git a/src/main/java/jenkins/advancedqueue/priority/strategy/UserIdCauseStrategy.java b/src/main/java/jenkins/advancedqueue/priority/strategy/UserIdCauseStrategy.java index 6bea0c32..2b108936 100644 --- a/src/main/java/jenkins/advancedqueue/priority/strategy/UserIdCauseStrategy.java +++ b/src/main/java/jenkins/advancedqueue/priority/strategy/UserIdCauseStrategy.java @@ -27,9 +27,7 @@ import hudson.model.Cause; import hudson.model.Cause.UserIdCause; import hudson.model.Queue; - import java.util.List; - import jenkins.advancedqueue.Messages; import org.kohsuke.stapler.DataBoundConstructor; @@ -39,29 +37,27 @@ */ public class UserIdCauseStrategy extends AbstractStaticPriorityStrategy { - @Extension - public static class UserIdCauseStrategyDescriptor extends AbstractStaticPriorityStrategyDescriptor { - - public UserIdCauseStrategyDescriptor() { - super(Messages.Job_triggered_by_a_user()); - } - - } - - @DataBoundConstructor - public UserIdCauseStrategy(int priority) { - setPriority(priority); - } - - @Override - public boolean isApplicable(Queue.Item item) { - List causes = item.getCauses(); - for (Cause cause : causes) { - if (cause.getClass() == UserIdCause.class) { - return true; - } - } - return false; - } - + @Extension + public static class UserIdCauseStrategyDescriptor extends AbstractStaticPriorityStrategyDescriptor { + + public UserIdCauseStrategyDescriptor() { + super(Messages.Job_triggered_by_a_user()); + } + } + + @DataBoundConstructor + public UserIdCauseStrategy(int priority) { + setPriority(priority); + } + + @Override + public boolean isApplicable(Queue.Item item) { + List causes = item.getCauses(); + for (Cause cause : causes) { + if (cause.getClass() == UserIdCause.class) { + return true; + } + } + return false; + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java b/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java index 31fb7d42..f25ea2bc 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java +++ b/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java @@ -23,24 +23,22 @@ */ package jenkins.advancedqueue.sorter; -import edu.umd.cs.findbugs.annotations.NonNull; +import static jenkins.advancedqueue.ItemTransitionLogger.*; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.model.Queue; import hudson.model.Queue.BuildableItem; import hudson.model.Queue.Item; import hudson.model.Queue.LeftItem; import hudson.model.queue.QueueSorter; - import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - import jenkins.advancedqueue.PriorityConfiguration; import jenkins.advancedqueue.PrioritySorterConfiguration; -import static jenkins.advancedqueue.ItemTransitionLogger.*; /** * @author Magnus Sandberg @@ -49,101 +47,107 @@ @Extension public class AdvancedQueueSorter extends QueueSorter { - private final static Logger LOGGER = Logger.getLogger("PrioritySorter.Queue.Sorter"); - - public AdvancedQueueSorter() { - } + private static final Logger LOGGER = Logger.getLogger("PrioritySorter.Queue.Sorter"); - static public void init() { - List items = Queue.getInstance().getBuildableItems(); - // Sort the queue in the order the items entered the queue - // so that onNewItem() happens in the correct order below - Collections.sort(items, new Comparator() { - public int compare(BuildableItem o1, BuildableItem o2) { - return (int) (o1.getInQueueSince() - o2.getInQueueSince()); - } - }); - AdvancedQueueSorter advancedQueueSorter = AdvancedQueueSorter.get(); - for (BuildableItem item : items) { - advancedQueueSorter.onNewItem(item); - // Listener called before we get here so make sure we mark buildable - QueueItemCache.get().getItem(item.getId()).setBuildable(); - } - LOGGER.info("Initialized the QueueSorter with " + items.size() + " Buildable Items"); - } + public AdvancedQueueSorter() {} - @Override - public void sortBuildableItems(List items) { + public static void init() { + List items = Queue.getInstance().getBuildableItems(); + // Sort the queue in the order the items entered the queue + // so that onNewItem() happens in the correct order below + Collections.sort(items, new Comparator() { + public int compare(BuildableItem o1, BuildableItem o2) { + return (int) (o1.getInQueueSince() - o2.getInQueueSince()); + } + }); + AdvancedQueueSorter advancedQueueSorter = AdvancedQueueSorter.get(); + for (BuildableItem item : items) { + advancedQueueSorter.onNewItem(item); + // Listener called before we get here so make sure we mark buildable + QueueItemCache.get().getItem(item.getId()).setBuildable(); + } + LOGGER.info("Initialized the QueueSorter with " + items.size() + " Buildable Items"); + } - Collections.sort(items, (BuildableItem o1, BuildableItem o2) -> { - ItemInfo item1 = QueueItemCache.get().getItem(o1.getId()); - ItemInfo item2 = QueueItemCache.get().getItem(o2.getId()); - if(item1 == null || item2 == null) { - LOGGER.warning("Requested to sort unknown items, sorting on queue-time only."); - return Long.compare(o1.getInQueueSince(), o2.getInQueueSince()); - } - return item1.compareTo(item2); - }); - // - if (items.size() > 0 && LOGGER.isLoggable(Level.FINE)) { - float minWeight = QueueItemCache.get().getItem(items.get(0).getId()).getWeight(); - float maxWeight = QueueItemCache.get().getItem(items.get(items.size() - 1).getId()).getWeight(); - LOGGER.log(Level.FINE, "Sorted {0} Buildable Items with Min Weight {1} and Max Weight {2}", new Object[] { - items.size(), minWeight, maxWeight }); - } - // - if (items.size() > 0 && LOGGER.isLoggable(Level.FINER)) { - StringBuilder queueStr = new StringBuilder("Queue:\n" - + "+----------------------------------------------------------------------+\n" - + "| Item Id | Job Name | Priority | Weight |\n" - + "+----------------------------------------------------------------------+\n"); - for (BuildableItem item : items) { - ItemInfo itemInfo = QueueItemCache.get().getItem(item.getId()); - String jobName = itemInfo.getJobName(); - if (jobName.length() > 21) { - jobName = jobName.substring(0, 9) + "..." - + jobName.substring(jobName.length() - 9, jobName.length()); - } - queueStr.append(String.format("| %10d | %20s | %8d | %20.5f |%n", item.getId(), jobName, - itemInfo.getPriority(), itemInfo.getWeight())); + @Override + public void sortBuildableItems(List items) { - } - queueStr.append("+----------------------------------------------------------------------+"); - LOGGER.log(Level.FINER, queueStr.toString()); - } - } + Collections.sort(items, (BuildableItem o1, BuildableItem o2) -> { + ItemInfo item1 = QueueItemCache.get().getItem(o1.getId()); + ItemInfo item2 = QueueItemCache.get().getItem(o2.getId()); + if (item1 == null || item2 == null) { + LOGGER.warning("Requested to sort unknown items, sorting on queue-time only."); + return Long.compare(o1.getInQueueSince(), o2.getInQueueSince()); + } + return item1.compareTo(item2); + }); + // + if (items.size() > 0 && LOGGER.isLoggable(Level.FINE)) { + float minWeight = QueueItemCache.get().getItem(items.get(0).getId()).getWeight(); + float maxWeight = QueueItemCache.get() + .getItem(items.get(items.size() - 1).getId()) + .getWeight(); + LOGGER.log(Level.FINE, "Sorted {0} Buildable Items with Min Weight {1} and Max Weight {2}", new Object[] { + items.size(), minWeight, maxWeight + }); + } + // + if (items.size() > 0 && LOGGER.isLoggable(Level.FINER)) { + StringBuilder queueStr = new StringBuilder("Queue:\n" + + "+----------------------------------------------------------------------+\n" + + "| Item Id | Job Name | Priority | Weight |\n" + + "+----------------------------------------------------------------------+\n"); + for (BuildableItem item : items) { + ItemInfo itemInfo = QueueItemCache.get().getItem(item.getId()); + String jobName = itemInfo.getJobName(); + if (jobName.length() > 21) { + jobName = + jobName.substring(0, 9) + "..." + jobName.substring(jobName.length() - 9, jobName.length()); + } + queueStr.append(String.format( + "| %10d | %20s | %8d | %20.5f |%n", + item.getId(), jobName, itemInfo.getPriority(), itemInfo.getWeight())); + } + queueStr.append("+----------------------------------------------------------------------+"); + LOGGER.log(Level.FINER, queueStr.toString()); + } + } - public void onNewItem(@NonNull Item item) { - final SorterStrategy prioritySorterStrategy = PrioritySorterConfiguration.get().getStrategy(); - ItemInfo itemInfo = new ItemInfo(item); - PriorityConfiguration.get().getPriority(item, itemInfo); - prioritySorterStrategy.onNewItem(item, itemInfo); - QueueItemCache.get().addItem(itemInfo); - logNewItem(itemInfo); - } + public void onNewItem(@NonNull Item item) { + final SorterStrategy prioritySorterStrategy = + PrioritySorterConfiguration.get().getStrategy(); + ItemInfo itemInfo = new ItemInfo(item); + PriorityConfiguration.get().getPriority(item, itemInfo); + prioritySorterStrategy.onNewItem(item, itemInfo); + QueueItemCache.get().addItem(itemInfo); + logNewItem(itemInfo); + } - public void onLeft(@NonNull LeftItem li) { - ItemInfo itemInfo = QueueItemCache.get().removeItem(li.getId()); - if (itemInfo == null) { - LOGGER.log(Level.WARNING, "Received the onLeft() notification for the item from outside the QueueItemCache: {0}. " + - "Cannot process this item, Priority Sorter Strategy will not be invoked", li); - return; - } - - final SorterStrategy prioritySorterStrategy = PrioritySorterConfiguration.get().getStrategy(); - if (li.isCancelled()) { - prioritySorterStrategy.onCanceledItem(li); - logCanceledItem(itemInfo); - } else { - Float weight = itemInfo.getWeight(); - StartedJobItemCache.get().addItem(itemInfo, li.outcome.getPrimaryWorkUnit()); - prioritySorterStrategy.onStartedItem(li, weight); - logStartedItem(itemInfo); - } - } + public void onLeft(@NonNull LeftItem li) { + ItemInfo itemInfo = QueueItemCache.get().removeItem(li.getId()); + if (itemInfo == null) { + LOGGER.log( + Level.WARNING, + "Received the onLeft() notification for the item from outside the QueueItemCache: {0}. " + + "Cannot process this item, Priority Sorter Strategy will not be invoked", + li); + return; + } - static public AdvancedQueueSorter get() { - return QueueSorter.all().get(AdvancedQueueSorter.class); - } + final SorterStrategy prioritySorterStrategy = + PrioritySorterConfiguration.get().getStrategy(); + if (li.isCancelled()) { + prioritySorterStrategy.onCanceledItem(li); + logCanceledItem(itemInfo); + } else { + Float weight = itemInfo.getWeight(); + StartedJobItemCache.get().addItem(itemInfo, li.outcome.getPrimaryWorkUnit()); + prioritySorterStrategy.onStartedItem(li, weight); + logStartedItem(itemInfo); + } + } + public static AdvancedQueueSorter get() { + return QueueSorter.all().get(AdvancedQueueSorter.class); + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorterQueueListener.java b/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorterQueueListener.java index 7507a198..a60e5706 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorterQueueListener.java +++ b/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorterQueueListener.java @@ -23,14 +23,13 @@ */ package jenkins.advancedqueue.sorter; -import java.util.logging.Logger; - import hudson.Extension; import hudson.model.Queue.BlockedItem; import hudson.model.Queue.BuildableItem; import hudson.model.Queue.LeftItem; import hudson.model.Queue.WaitingItem; import hudson.model.queue.QueueListener; +import java.util.logging.Logger; /** * @author Magnus Sandberg @@ -39,38 +38,39 @@ @Extension public class AdvancedQueueSorterQueueListener extends QueueListener { - private final static Logger LOGGER = Logger.getLogger(AdvancedQueueSorterQueueListener.class.getName()); - - @Override - public void onEnterWaiting(WaitingItem wi) { - AdvancedQueueSorter.get().onNewItem(wi); - } + private static final Logger LOGGER = Logger.getLogger(AdvancedQueueSorterQueueListener.class.getName()); - @Override - public void onLeft(LeftItem li) { - AdvancedQueueSorter.get().onLeft(li); - } + @Override + public void onEnterWaiting(WaitingItem wi) { + AdvancedQueueSorter.get().onNewItem(wi); + } - @Override - public void onEnterBuildable(BuildableItem bi) { - ItemInfo item = QueueItemCache.get().getItem(bi.getId()); - // Null at startup - onEnterWaiting not called during startup (?) - if (item == null) { - LOGGER.warning("onEnterBuilding() called without prior call to onEnterWaiting() for '" + bi.task.getDisplayName() + "'"); - AdvancedQueueSorter.get().onNewItem(bi); - } - QueueItemCache.get().getItem(bi.getId()).setBuildable(); - } + @Override + public void onLeft(LeftItem li) { + AdvancedQueueSorter.get().onLeft(li); + } - @Override - public void onEnterBlocked(BlockedItem bi) { - ItemInfo item = QueueItemCache.get().getItem(bi.getId()); - // Null at startup - onEnterWaiting not called during startup (?) - if (item == null) { - LOGGER.warning("onEnterBlocked() called without prior call to onEnterWaiting() for '" + bi.task.getDisplayName() + "'"); - AdvancedQueueSorter.get().onNewItem(bi); - } - QueueItemCache.get().getItem(bi.getId()).setBlocked(); - } + @Override + public void onEnterBuildable(BuildableItem bi) { + ItemInfo item = QueueItemCache.get().getItem(bi.getId()); + // Null at startup - onEnterWaiting not called during startup (?) + if (item == null) { + LOGGER.warning("onEnterBuilding() called without prior call to onEnterWaiting() for '" + + bi.task.getDisplayName() + "'"); + AdvancedQueueSorter.get().onNewItem(bi); + } + QueueItemCache.get().getItem(bi.getId()).setBuildable(); + } + @Override + public void onEnterBlocked(BlockedItem bi) { + ItemInfo item = QueueItemCache.get().getItem(bi.getId()); + // Null at startup - onEnterWaiting not called during startup (?) + if (item == null) { + LOGGER.warning("onEnterBlocked() called without prior call to onEnterWaiting() for '" + + bi.task.getDisplayName() + "'"); + AdvancedQueueSorter.get().onNewItem(bi); + } + QueueItemCache.get().getItem(bi.getId()).setBlocked(); + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/ItemInfo.java b/src/main/java/jenkins/advancedqueue/sorter/ItemInfo.java index e54a86fd..fdc3a7e4 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/ItemInfo.java +++ b/src/main/java/jenkins/advancedqueue/sorter/ItemInfo.java @@ -26,169 +26,180 @@ import static jenkins.advancedqueue.ItemTransitionLogger.logBlockedItem; import static jenkins.advancedqueue.ItemTransitionLogger.logBuilableItem; +import hudson.model.Queue.Item; import java.util.ArrayList; import java.util.List; import java.util.Objects; - -import hudson.model.Queue.Item; import jenkins.advancedqueue.DecisionLogger; import jenkins.advancedqueue.PriorityConfigurationCallback; import jenkins.advancedqueue.priority.PriorityStrategy; /** * Used to store info about a Queue.Item and related information calculated by the Plugin - * + * * @author Magnus Sandberg * @since 2.3 */ -public class ItemInfo implements PriorityConfigurationCallback, DecisionLogger, SorterStrategyCallback, Comparable { - - private long itemId; - - private long inQueueSince; - - private Long sortAsInQueueSince = null; - - private int jobGroupId; - - private PriorityStrategy priorityStrategy; - - private String jobName; - - private float weight; - - private int priority; - - private ItemStatus itemStatus; - - private List decisionLog = new ArrayList(10); - - ItemInfo(Item item) { - this.itemId = item.getId(); - this.inQueueSince = item.getInQueueSince(); - this.jobName = item.task.getName(); - this.itemStatus = ItemStatus.WAITING; - } - - public PriorityConfigurationCallback setPrioritySelection(int priority, int jobGroupId, PriorityStrategy reason) { - this.priority = priority; - this.jobGroupId = jobGroupId; - this.priorityStrategy = reason; - return this; - } - - public PriorityConfigurationCallback setPrioritySelection(int priority, long sortAsInQueueSince, int jobGroupId, PriorityStrategy reason) { - this.priority = priority; - this.sortAsInQueueSince = sortAsInQueueSince; - this.jobGroupId = jobGroupId; - this.priorityStrategy = reason; - return this; - } - - public PriorityConfigurationCallback addDecisionLog(int indent, String log) { - this.decisionLog.add(String.format("%"+ ((indent + 1) * 2) + "s%s", "", log)); - return this; - } - - public PriorityConfigurationCallback setPrioritySelection(int priority) { - setPrioritySelection(priority, -1, null); - return this; - } - - public SorterStrategyCallback setWeightSelection(float weight) { - this.weight = weight; - return this; - } - - public void setBuildable() { - itemStatus = ItemStatus.BUILDABLE; - logBuilableItem(this); - } - - public void setBlocked() { - itemStatus = ItemStatus.BLOCKED; - logBlockedItem(this); - } - - public long getItemId() { - return itemId; - } - - public long getInQueueSince() { - return inQueueSince; - } - - public long getSortableInQueueSince() { - if(sortAsInQueueSince != null) { - return sortAsInQueueSince; - } - return inQueueSince; - } - - public int getJobGroupId() { - return jobGroupId; - } - - public PriorityStrategy getPriorityStrategy() { - return priorityStrategy; - } - - public String getJobName() { - return jobName; - } - - public float getWeight() { - return weight; - } - - public int getPriority() { - return priority; - } - - public ItemStatus getItemStatus() { - return itemStatus; - } - - public int compareTo(ItemInfo o) { - if(this.getWeight() == o.getWeight()) { - if(this.getSortableInQueueSince() == o.getSortableInQueueSince()) { - return Long.compare(this.getItemId(), o.getItemId()); - } - return Long.compare(this.getSortableInQueueSince(), o.getSortableInQueueSince()); - } - return Float.compare(this.getWeight(), o.getWeight()); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ItemInfo) { - ItemInfo itemInfo = (ItemInfo) obj; - return compareTo(itemInfo) == 0; - } - return false; - } - - @Override - public int hashCode() { - return Objects.hash(itemId, inQueueSince, sortAsInQueueSince, jobGroupId, priorityStrategy, jobName, weight, priority, itemStatus, decisionLog); - } - - @Override - public String toString() { - String reason = ""; - if(priorityStrategy != null) { - reason = priorityStrategy.getDescriptor().getDisplayName(); - } - return String.format("Id: %s, JobName: %s, jobGroupId: %s, reason: %s, priority: %s, weight: %s, status: %s", itemId, - jobName, jobGroupId, reason, priority, weight, itemStatus); - } - - public String getDescisionLog() { - StringBuilder buffer = new StringBuilder(); - for (String log : decisionLog) { - buffer.append(log).append("\n"); - } - return buffer.toString(); - } +public class ItemInfo + implements PriorityConfigurationCallback, DecisionLogger, SorterStrategyCallback, Comparable { + + private long itemId; + + private long inQueueSince; + + private Long sortAsInQueueSince = null; + + private int jobGroupId; + + private PriorityStrategy priorityStrategy; + + private String jobName; + private float weight; + + private int priority; + + private ItemStatus itemStatus; + + private List decisionLog = new ArrayList(10); + + ItemInfo(Item item) { + this.itemId = item.getId(); + this.inQueueSince = item.getInQueueSince(); + this.jobName = item.task.getName(); + this.itemStatus = ItemStatus.WAITING; + } + + public PriorityConfigurationCallback setPrioritySelection(int priority, int jobGroupId, PriorityStrategy reason) { + this.priority = priority; + this.jobGroupId = jobGroupId; + this.priorityStrategy = reason; + return this; + } + + public PriorityConfigurationCallback setPrioritySelection( + int priority, long sortAsInQueueSince, int jobGroupId, PriorityStrategy reason) { + this.priority = priority; + this.sortAsInQueueSince = sortAsInQueueSince; + this.jobGroupId = jobGroupId; + this.priorityStrategy = reason; + return this; + } + + public PriorityConfigurationCallback addDecisionLog(int indent, String log) { + this.decisionLog.add(String.format("%" + ((indent + 1) * 2) + "s%s", "", log)); + return this; + } + + public PriorityConfigurationCallback setPrioritySelection(int priority) { + setPrioritySelection(priority, -1, null); + return this; + } + + public SorterStrategyCallback setWeightSelection(float weight) { + this.weight = weight; + return this; + } + + public void setBuildable() { + itemStatus = ItemStatus.BUILDABLE; + logBuilableItem(this); + } + + public void setBlocked() { + itemStatus = ItemStatus.BLOCKED; + logBlockedItem(this); + } + + public long getItemId() { + return itemId; + } + + public long getInQueueSince() { + return inQueueSince; + } + + public long getSortableInQueueSince() { + if (sortAsInQueueSince != null) { + return sortAsInQueueSince; + } + return inQueueSince; + } + + public int getJobGroupId() { + return jobGroupId; + } + + public PriorityStrategy getPriorityStrategy() { + return priorityStrategy; + } + + public String getJobName() { + return jobName; + } + + public float getWeight() { + return weight; + } + + public int getPriority() { + return priority; + } + + public ItemStatus getItemStatus() { + return itemStatus; + } + + public int compareTo(ItemInfo o) { + if (this.getWeight() == o.getWeight()) { + if (this.getSortableInQueueSince() == o.getSortableInQueueSince()) { + return Long.compare(this.getItemId(), o.getItemId()); + } + return Long.compare(this.getSortableInQueueSince(), o.getSortableInQueueSince()); + } + return Float.compare(this.getWeight(), o.getWeight()); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ItemInfo) { + ItemInfo itemInfo = (ItemInfo) obj; + return compareTo(itemInfo) == 0; + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash( + itemId, + inQueueSince, + sortAsInQueueSince, + jobGroupId, + priorityStrategy, + jobName, + weight, + priority, + itemStatus, + decisionLog); + } + + @Override + public String toString() { + String reason = ""; + if (priorityStrategy != null) { + reason = priorityStrategy.getDescriptor().getDisplayName(); + } + return String.format( + "Id: %s, JobName: %s, jobGroupId: %s, reason: %s, priority: %s, weight: %s, status: %s", + itemId, jobName, jobGroupId, reason, priority, weight, itemStatus); + } + + public String getDescisionLog() { + StringBuilder buffer = new StringBuilder(); + for (String log : decisionLog) { + buffer.append(log).append("\n"); + } + return buffer.toString(); + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/ItemStatus.java b/src/main/java/jenkins/advancedqueue/sorter/ItemStatus.java index 3f17c2d5..27db6595 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/ItemStatus.java +++ b/src/main/java/jenkins/advancedqueue/sorter/ItemStatus.java @@ -23,15 +23,14 @@ */ package jenkins.advancedqueue.sorter; -/** +/** * Statuses for Build in the the queue, used to track status in ItemInfo - * + * * @author Magnus Sandberg * @since 2.3 */ public enum ItemStatus { - - WAITING, - BUILDABLE, - BLOCKED + WAITING, + BUILDABLE, + BLOCKED } diff --git a/src/main/java/jenkins/advancedqueue/sorter/QueueItemCache.java b/src/main/java/jenkins/advancedqueue/sorter/QueueItemCache.java index de5e1b50..5a78e432 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/QueueItemCache.java +++ b/src/main/java/jenkins/advancedqueue/sorter/QueueItemCache.java @@ -24,10 +24,8 @@ package jenkins.advancedqueue.sorter; import edu.umd.cs.findbugs.annotations.CheckForNull; - import hudson.model.Queue.BlockedItem; import hudson.model.Queue.BuildableItem; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -39,87 +37,86 @@ * Keeps track of the Queue.Items seen by the Sorter. Uses a WeakHash to store the entries that have * left the queue, this can be used by Strategies that needs this info but still minimizes the need * to lookup the data again from Jenkins Core. - * + * * @author Magnus Sandberg * @since 2.3 */ public class QueueItemCache { - private final static Logger LOGGER = Logger.getLogger(QueueItemCache.class.getName()); - - static private QueueItemCache queueItemCache = null; - - static { - queueItemCache = new QueueItemCache(); - } - - static public QueueItemCache get() { - return queueItemCache; - } - - // Keeps track of all items currently in the queue - private Map item2info = new HashMap<>(); - // Keeps track of the last started item of the Job - private Map jobName2info = new HashMap<>(); - - private QueueItemCache() { - } - - public synchronized ItemInfo getItem(long itemId) { - return item2info.get(itemId); - } - - /** - * Gets the Item for and itemId/queueId - * - * @param itemId the id of a Job currently in the queue - * @return the {@link ItemInfo} for the provided id or null if the id is not in the - * queue - */ - @Deprecated - synchronized public ItemInfo getItem(Integer itemId) { - return item2info.get(itemId.longValue()); - } - - /** - * Get the ItemInfo for the last knows start of this Job Name - * - * @param jobName a name of a Job - * @return the {@link ItemInfo} for the last know start of the Job. - * Can be {@code null} if job didn't run yet - */ - @CheckForNull - synchronized public ItemInfo getItem(String jobName) { - return jobName2info.get(jobName); - } - - synchronized public ItemInfo addItem(ItemInfo itemInfo) { - long itemId = itemInfo.getItemId(); - item2info.put(itemId, itemInfo); - jobName2info.put(itemInfo.getJobName(), itemInfo); - return itemInfo; - } - - @CheckForNull - @Deprecated - synchronized public ItemInfo removeItem(Integer itemId) { - return item2info.remove(itemId.longValue()); - } - - @CheckForNull - public synchronized ItemInfo removeItem(long itemId) { - return item2info.remove(itemId); - } - - /** - * This method will return a sorted list of all known and active {@link ItemInfo}s this will - * include Items mapped to {@link BuildableItem}s as well as {@link BlockedItem}s - * - * @return the sorted list of all {@link ItemInfo}s - */ - synchronized public List getSortedList() { - ArrayList list = new ArrayList(item2info.values()); - Collections.sort(list); - return Collections.unmodifiableList(list); - } + private static final Logger LOGGER = Logger.getLogger(QueueItemCache.class.getName()); + + private static QueueItemCache queueItemCache = null; + + static { + queueItemCache = new QueueItemCache(); + } + + public static QueueItemCache get() { + return queueItemCache; + } + + // Keeps track of all items currently in the queue + private Map item2info = new HashMap<>(); + // Keeps track of the last started item of the Job + private Map jobName2info = new HashMap<>(); + + private QueueItemCache() {} + + public synchronized ItemInfo getItem(long itemId) { + return item2info.get(itemId); + } + + /** + * Gets the Item for and itemId/queueId + * + * @param itemId the id of a Job currently in the queue + * @return the {@link ItemInfo} for the provided id or null if the id is not in the + * queue + */ + @Deprecated + public synchronized ItemInfo getItem(Integer itemId) { + return item2info.get(itemId.longValue()); + } + + /** + * Get the ItemInfo for the last knows start of this Job Name + * + * @param jobName a name of a Job + * @return the {@link ItemInfo} for the last know start of the Job. + * Can be {@code null} if job didn't run yet + */ + @CheckForNull + public synchronized ItemInfo getItem(String jobName) { + return jobName2info.get(jobName); + } + + public synchronized ItemInfo addItem(ItemInfo itemInfo) { + long itemId = itemInfo.getItemId(); + item2info.put(itemId, itemInfo); + jobName2info.put(itemInfo.getJobName(), itemInfo); + return itemInfo; + } + + @CheckForNull + @Deprecated + public synchronized ItemInfo removeItem(Integer itemId) { + return item2info.remove(itemId.longValue()); + } + + @CheckForNull + public synchronized ItemInfo removeItem(long itemId) { + return item2info.remove(itemId); + } + + /** + * This method will return a sorted list of all known and active {@link ItemInfo}s this will + * include Items mapped to {@link BuildableItem}s as well as {@link BlockedItem}s + * + * @return the sorted list of all {@link ItemInfo}s + */ + public synchronized List getSortedList() { + ArrayList list = new ArrayList(item2info.values()); + Collections.sort(list); + return Collections.unmodifiableList(list); + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/SorterStrategy.java b/src/main/java/jenkins/advancedqueue/sorter/SorterStrategy.java index 79bf63d9..b06c7e2e 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/SorterStrategy.java +++ b/src/main/java/jenkins/advancedqueue/sorter/SorterStrategy.java @@ -25,16 +25,13 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; - import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Describable; import hudson.model.Queue; import hudson.model.Queue.LeftItem; - import java.util.ArrayList; import java.util.List; - import jenkins.model.Jenkins; /** @@ -43,83 +40,82 @@ */ public abstract class SorterStrategy implements ExtensionPoint, Describable { - public SorterStrategyDescriptor getDescriptor() { - return (SorterStrategyDescriptor) Jenkins.get().getDescriptorOrDie(getClass()); - } + public SorterStrategyDescriptor getDescriptor() { + return (SorterStrategyDescriptor) Jenkins.get().getDescriptorOrDie(getClass()); + } - /** - * Called when a new {@link hudson.model.Item} enters the queue. - * - * @param item the {@link hudson.model.Queue.WaitingItem} or {@link hudson.model.BuildableItem} that - * enters the queue - * @param weightCallback the callback holds the priority to use anded the called method must set - * the weight before returning - * @return the {@link SorterStrategyCallback} provided to the call must be returned - */ - public abstract SorterStrategyCallback onNewItem(@NonNull Queue.Item item, SorterStrategyCallback weightCallback); + /** + * Called when a new {@link hudson.model.Item} enters the queue. + * + * @param item the {@link hudson.model.Queue.WaitingItem} or {@link hudson.model.BuildableItem} that + * enters the queue + * @param weightCallback the callback holds the priority to use anded the called method must set + * the weight before returning + * @return the {@link SorterStrategyCallback} provided to the call must be returned + */ + public abstract SorterStrategyCallback onNewItem(@NonNull Queue.Item item, SorterStrategyCallback weightCallback); - /** - * Called when a {@link hudson.model.Item} leaves the queue and it is started. - * - * @param item the {@link hudson.model.Queue.LeftItem} - * @param weight the weight assigned when the item entered the queue - */ - public void onStartedItem(@NonNull LeftItem item, float weight) { - } + /** + * Called when a {@link hudson.model.Item} leaves the queue and it is started. + * + * @param item the {@link hudson.model.Queue.LeftItem} + * @param weight the weight assigned when the item entered the queue + */ + public void onStartedItem(@NonNull LeftItem item, float weight) {} - /** - * Called when a {@link hudson.model.Item} leaves the queue and it is canceled. - */ - public void onCanceledItem(@NonNull LeftItem item) { - }; + /** + * Called when a {@link hudson.model.Item} leaves the queue and it is canceled. + */ + public void onCanceledItem(@NonNull LeftItem item) {} + ; - /** - * Gets number of priority buckets to be used. - * - */ - public abstract int getNumberOfPriorities(); + /** + * Gets number of priority buckets to be used. + * + */ + public abstract int getNumberOfPriorities(); - /** - * Gets a default priority bucket to be used. - * - */ - public abstract int getDefaultPriority(); + /** + * Gets a default priority bucket to be used. + * + */ + public abstract int getDefaultPriority(); - public static List getAllSorterStrategies() { - ExtensionList all = all(); - ArrayList strategies = new ArrayList(all.size()); - for (SorterStrategy prioritySorterStrategy : all) { - strategies.add(prioritySorterStrategy.getDescriptor()); - } - return strategies; - } + public static List getAllSorterStrategies() { + ExtensionList all = all(); + ArrayList strategies = new ArrayList(all.size()); + for (SorterStrategy prioritySorterStrategy : all) { + strategies.add(prioritySorterStrategy.getDescriptor()); + } + return strategies; + } - @CheckForNull - public static SorterStrategyDescriptor getSorterStrategy(String key) { - List allSorterStrategies = getAllSorterStrategies(); - for (SorterStrategyDescriptor sorterStrategy : allSorterStrategies) { - if (key.equals(sorterStrategy.getKey())) { - return sorterStrategy; - } - } - return null; - } + @CheckForNull + public static SorterStrategyDescriptor getSorterStrategy(String key) { + List allSorterStrategies = getAllSorterStrategies(); + for (SorterStrategyDescriptor sorterStrategy : allSorterStrategies) { + if (key.equals(sorterStrategy.getKey())) { + return sorterStrategy; + } + } + return null; + } - @CheckForNull - public static SorterStrategy getPrioritySorterStrategy(SorterStrategyDescriptor sorterStrategy) { - ExtensionList all = all(); - for (SorterStrategy prioritySorterStrategy : all) { - if (prioritySorterStrategy.getDescriptor().getKey().equals(sorterStrategy.getKey())) { - return prioritySorterStrategy; - } - } - return null; - } + @CheckForNull + public static SorterStrategy getPrioritySorterStrategy(SorterStrategyDescriptor sorterStrategy) { + ExtensionList all = all(); + for (SorterStrategy prioritySorterStrategy : all) { + if (prioritySorterStrategy.getDescriptor().getKey().equals(sorterStrategy.getKey())) { + return prioritySorterStrategy; + } + } + return null; + } - /** - * All registered {@link SorterStrategy}s. - */ - public static ExtensionList all() { - return Jenkins.get().getExtensionList(SorterStrategy.class); - } + /** + * All registered {@link SorterStrategy}s. + */ + public static ExtensionList all() { + return Jenkins.get().getExtensionList(SorterStrategy.class); + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyCallback.java b/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyCallback.java index bf1ca408..f60a94a3 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyCallback.java +++ b/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyCallback.java @@ -2,7 +2,7 @@ public interface SorterStrategyCallback { - int getPriority(); - - SorterStrategyCallback setWeightSelection(float weight); + int getPriority(); + + SorterStrategyCallback setWeightSelection(float weight); } diff --git a/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyDescriptor.java b/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyDescriptor.java index 21845611..0cc83dee 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyDescriptor.java +++ b/src/main/java/jenkins/advancedqueue/sorter/SorterStrategyDescriptor.java @@ -27,19 +27,19 @@ /** * Implements descriptor for {@link SorterStrategy}. - * + * * @author Oleg Nenashev * @since 2.0 */ public abstract class SorterStrategyDescriptor extends Descriptor { - /** - * Returns a short name of strategy, which can be used as a unique id. - * - * @return Short name of the sorter strategy. - */ - public abstract String getShortName(); + /** + * Returns a short name of strategy, which can be used as a unique id. + * + * @return Short name of the sorter strategy. + */ + public abstract String getShortName(); - public String getKey() { - return getShortName(); - } + public String getKey() { + return getShortName(); + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/StartedJobItemCache.java b/src/main/java/jenkins/advancedqueue/sorter/StartedJobItemCache.java index 5bd5956f..8ec891e1 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/StartedJobItemCache.java +++ b/src/main/java/jenkins/advancedqueue/sorter/StartedJobItemCache.java @@ -23,19 +23,16 @@ */ package jenkins.advancedqueue.sorter; -import edu.umd.cs.findbugs.annotations.CheckForNull; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.concurrent.TimeUnit; - import com.google.common.base.Objects; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; - -import hudson.model.Run; +import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.model.Queue.Executable; +import hudson.model.Run; import hudson.model.queue.WorkUnit; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.concurrent.TimeUnit; /** * Keeps track of the Queue.Items seen by the Sorter, but removed from the queue @@ -46,110 +43,109 @@ */ public class StartedJobItemCache { - private static final int RETENTION_COUNT = 10000; - private static final int RETENTION_TIME_HOURS = 12; - - private static StartedJobItemCache startedJobItemCache = null; - - static { - startedJobItemCache = new StartedJobItemCache(); - } - - public static StartedJobItemCache get() { - return startedJobItemCache; - } - - private static class PendingItem { - final long startTime; - final ItemInfo itemInfo; - final WorkUnit workUnit; - - public PendingItem(final ItemInfo itemInfo, final WorkUnit workUnit) { - this.startTime = System.currentTimeMillis(); - this.itemInfo = itemInfo; - this.workUnit = workUnit; - } - } - - private static class StartedItem { - final String projectName; - final int buildNumber; - - public StartedItem(final String projectName, final int buildNumber) { - this.projectName = projectName; - this.buildNumber = buildNumber; - } - - @Override - public int hashCode() { - return Objects.hashCode(projectName, buildNumber); - } - - @Override - public boolean equals(final Object obj) { - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final StartedItem other = (StartedItem) obj; - return Objects.equal(this.projectName, other.projectName) && this.buildNumber == other.buildNumber; - } - } - - private final LinkedList pendingItems = new LinkedList(); - - private final Cache startedItems = CacheBuilder.newBuilder() - .expireAfterWrite(RETENTION_TIME_HOURS, TimeUnit.HOURS).maximumSize(RETENTION_COUNT).build(); - - private StartedJobItemCache() { - } - - /** - * Gets the Item for a started job, already removed from the queue - * - * @param projectName - * the project name - * @param buildNumber - * the build number - * @return the {@link ItemInfo} for the provided id or null if - * projectName/buildNumber combination is unknown - */ - public synchronized @CheckForNull ItemInfo getStartedItem(final String projectName, final int buildNumber) { - maintainCache(); - return startedItems.getIfPresent(new StartedItem(projectName, buildNumber)); - } - - public synchronized void addItem(final ItemInfo itemInfo, final WorkUnit primaryWorkUnit) { - pendingItems.addLast(new PendingItem(itemInfo, primaryWorkUnit)); - maintainCache(); - } - - private void maintainCache() { - // Collect job information from pending items to drop WorkUnit reference - - for (final Iterator it = pendingItems.iterator(); it.hasNext();) { - final PendingItem pi = it.next(); - final Executable e = pi.workUnit.getExecutable(); - - if (e instanceof Run) { - startedItems.put(new StartedItem(pi.itemInfo.getJobName(), ((Run) e).getNumber()), pi.itemInfo); - it.remove(); - } - } - - // Cleanup pendingItems - - if (pendingItems.size() > RETENTION_COUNT) { - pendingItems.subList(0, pendingItems.size() - RETENTION_COUNT).clear(); - } - - for (final Iterator it = pendingItems.iterator(); it.hasNext();) { - final PendingItem pi = it.next(); - if (pi.startTime < System.currentTimeMillis() - RETENTION_TIME_HOURS * 60 * 60 * 1000) { - it.remove(); - } else { - break; - } - } - } + private static final int RETENTION_COUNT = 10000; + private static final int RETENTION_TIME_HOURS = 12; + + private static StartedJobItemCache startedJobItemCache = null; + + static { + startedJobItemCache = new StartedJobItemCache(); + } + + public static StartedJobItemCache get() { + return startedJobItemCache; + } + + private static class PendingItem { + final long startTime; + final ItemInfo itemInfo; + final WorkUnit workUnit; + + public PendingItem(final ItemInfo itemInfo, final WorkUnit workUnit) { + this.startTime = System.currentTimeMillis(); + this.itemInfo = itemInfo; + this.workUnit = workUnit; + } + } + + private static class StartedItem { + final String projectName; + final int buildNumber; + + public StartedItem(final String projectName, final int buildNumber) { + this.projectName = projectName; + this.buildNumber = buildNumber; + } + + @Override + public int hashCode() { + return Objects.hashCode(projectName, buildNumber); + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + final StartedItem other = (StartedItem) obj; + return Objects.equal(this.projectName, other.projectName) && this.buildNumber == other.buildNumber; + } + } + + private final LinkedList pendingItems = new LinkedList(); + + private final Cache startedItems = CacheBuilder.newBuilder() + .expireAfterWrite(RETENTION_TIME_HOURS, TimeUnit.HOURS) + .maximumSize(RETENTION_COUNT) + .build(); + + private StartedJobItemCache() {} + + /** + * Gets the Item for a started job, already removed from the queue + * + * @param projectName + * the project name + * @param buildNumber + * the build number + * @return the {@link ItemInfo} for the provided id or null if + * projectName/buildNumber combination is unknown + */ + public synchronized @CheckForNull ItemInfo getStartedItem(final String projectName, final int buildNumber) { + maintainCache(); + return startedItems.getIfPresent(new StartedItem(projectName, buildNumber)); + } + + public synchronized void addItem(final ItemInfo itemInfo, final WorkUnit primaryWorkUnit) { + pendingItems.addLast(new PendingItem(itemInfo, primaryWorkUnit)); + maintainCache(); + } + + private void maintainCache() { + // Collect job information from pending items to drop WorkUnit reference + + for (final Iterator it = pendingItems.iterator(); it.hasNext(); ) { + final PendingItem pi = it.next(); + final Executable e = pi.workUnit.getExecutable(); + + if (e instanceof Run) { + startedItems.put(new StartedItem(pi.itemInfo.getJobName(), ((Run) e).getNumber()), pi.itemInfo); + it.remove(); + } + } + + // Cleanup pendingItems + + if (pendingItems.size() > RETENTION_COUNT) { + pendingItems.subList(0, pendingItems.size() - RETENTION_COUNT).clear(); + } + + for (final Iterator it = pendingItems.iterator(); it.hasNext(); ) { + final PendingItem pi = it.next(); + if (pi.startTime < System.currentTimeMillis() - RETENTION_TIME_HOURS * 60 * 60 * 1000) { + it.remove(); + } else { + break; + } + } + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/strategy/AbsoluteStrategy.java b/src/main/java/jenkins/advancedqueue/sorter/strategy/AbsoluteStrategy.java index 3dad20dd..91cc0b43 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/strategy/AbsoluteStrategy.java +++ b/src/main/java/jenkins/advancedqueue/sorter/strategy/AbsoluteStrategy.java @@ -27,7 +27,6 @@ import hudson.model.Queue; import jenkins.advancedqueue.sorter.SorterStrategyCallback; import jenkins.advancedqueue.strategy.Messages; - import org.kohsuke.stapler.DataBoundConstructor; /** @@ -36,30 +35,29 @@ */ public class AbsoluteStrategy extends MultiBucketStrategy { - public AbsoluteStrategy() { - } + public AbsoluteStrategy() {} - @DataBoundConstructor - public AbsoluteStrategy(int numberOfPriorities, int defaultPriority) { - super(numberOfPriorities, defaultPriority); - } + @DataBoundConstructor + public AbsoluteStrategy(int numberOfPriorities, int defaultPriority) { + super(numberOfPriorities, defaultPriority); + } - @Override - public SorterStrategyCallback onNewItem(Queue.Item item, SorterStrategyCallback weightCallback) { - return weightCallback.setWeightSelection(weightCallback.getPriority()); - } + @Override + public SorterStrategyCallback onNewItem(Queue.Item item, SorterStrategyCallback weightCallback) { + return weightCallback.setWeightSelection(weightCallback.getPriority()); + } - @Extension - public static class DescriptorImpl extends MultiBucketStrategyDescriptor { + @Extension + public static class DescriptorImpl extends MultiBucketStrategyDescriptor { - @Override - public String getDisplayName() { - return Messages.SorterStrategy_ABSOLUTE_displayName(); - } + @Override + public String getDisplayName() { + return Messages.SorterStrategy_ABSOLUTE_displayName(); + } - @Override - public String getShortName() { - return Messages.SorterStrategy_ABSOLUTE_shortName(); - } - } + @Override + public String getShortName() { + return Messages.SorterStrategy_ABSOLUTE_shortName(); + } + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/strategy/FQBaseStrategy.java b/src/main/java/jenkins/advancedqueue/sorter/strategy/FQBaseStrategy.java index a7f3149e..808eccd2 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/strategy/FQBaseStrategy.java +++ b/src/main/java/jenkins/advancedqueue/sorter/strategy/FQBaseStrategy.java @@ -26,10 +26,8 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.Queue; import hudson.model.Queue.LeftItem; - import java.util.HashMap; import java.util.Map; - import jenkins.advancedqueue.sorter.SorterStrategyCallback; /** @@ -37,59 +35,58 @@ * @author Magnus Sandberg * @since 2.0 */ -abstract public class FQBaseStrategy extends MultiBucketStrategy { - // The equivalent of a packet size for a network scheduler. - static final protected float MIN_STEP_SIZE = 0.00001F; - // Keeps track on the last assigned weight for a given priority - static final Map prio2weight = new HashMap(); - static final private float MIN_STARTED_WEIGHT = 1F; - // Keeps track on the max weight of started jobs - static float maxStartedWeight = MIN_STARTED_WEIGHT; +public abstract class FQBaseStrategy extends MultiBucketStrategy { + // The equivalent of a packet size for a network scheduler. + protected static final float MIN_STEP_SIZE = 0.00001F; + // Keeps track on the last assigned weight for a given priority + static final Map prio2weight = new HashMap(); + private static final float MIN_STARTED_WEIGHT = 1F; + // Keeps track on the max weight of started jobs + static float maxStartedWeight = MIN_STARTED_WEIGHT; - public FQBaseStrategy() { - } + public FQBaseStrategy() {} - public FQBaseStrategy(int numberOfPriorities, int defaultPriority) { - super(numberOfPriorities, defaultPriority); - } + public FQBaseStrategy(int numberOfPriorities, int defaultPriority) { + super(numberOfPriorities, defaultPriority); + } - @Override - @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") - public void onStartedItem(LeftItem item, float weight) { - maxStartedWeight = Math.max(maxStartedWeight, weight); - } + @Override + @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") + public void onStartedItem(LeftItem item, float weight) { + maxStartedWeight = Math.max(maxStartedWeight, weight); + } - public SorterStrategyCallback onNewItem(Queue.Item item, SorterStrategyCallback weightCallback) { - int priority = weightCallback.getPriority(); - float minimumWeightToAssign = getMinimumWeightToAssign(priority); - float weightToUse = getWeightToUse(priority, minimumWeightToAssign); - prio2weight.put(priority, weightToUse); - return weightCallback.setWeightSelection(weightToUse); - } + public SorterStrategyCallback onNewItem(Queue.Item item, SorterStrategyCallback weightCallback) { + int priority = weightCallback.getPriority(); + float minimumWeightToAssign = getMinimumWeightToAssign(priority); + float weightToUse = getWeightToUse(priority, minimumWeightToAssign); + prio2weight.put(priority, weightToUse); + return weightCallback.setWeightSelection(weightToUse); + } - protected float getMinimumWeightToAssign(int priority) { - Float minWeight = prio2weight.get(priority); - if (minWeight == null) { - return maxStartedWeight; - } - return Math.max(maxStartedWeight, minWeight); - } + protected float getMinimumWeightToAssign(int priority) { + Float minWeight = prio2weight.get(priority); + if (minWeight == null) { + return maxStartedWeight; + } + return Math.max(maxStartedWeight, minWeight); + } - @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") - protected float getWeightToUse(int priority, float minimumWeightToAssign) { - float weight = minimumWeightToAssign * (1F + getStepSize(priority)); - // Protect us from values going through the roof if we run for a very - // long time - // This below might leave some jobs in the queue with very large weight - // this probably improbable to happen so let's do it like this for now - // ... - if (Float.POSITIVE_INFINITY == weight) { - maxStartedWeight = MIN_STARTED_WEIGHT; - prio2weight.clear(); - return MIN_STARTED_WEIGHT; - } - return weight; - } + @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") + protected float getWeightToUse(int priority, float minimumWeightToAssign) { + float weight = minimumWeightToAssign * (1F + getStepSize(priority)); + // Protect us from values going through the roof if we run for a very + // long time + // This below might leave some jobs in the queue with very large weight + // this probably improbable to happen so let's do it like this for now + // ... + if (Float.POSITIVE_INFINITY == weight) { + maxStartedWeight = MIN_STARTED_WEIGHT; + prio2weight.clear(); + return MIN_STARTED_WEIGHT; + } + return weight; + } - abstract float getStepSize(int priority); + abstract float getStepSize(int priority); } diff --git a/src/main/java/jenkins/advancedqueue/sorter/strategy/FQStrategy.java b/src/main/java/jenkins/advancedqueue/sorter/strategy/FQStrategy.java index f122a255..d6d53d9f 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/strategy/FQStrategy.java +++ b/src/main/java/jenkins/advancedqueue/sorter/strategy/FQStrategy.java @@ -33,36 +33,35 @@ */ public class FQStrategy extends FQBaseStrategy { - FQStrategy() { - } + FQStrategy() {} - @DataBoundConstructor - public FQStrategy(int numberOfPriorities, int defaultPriority) { - super(numberOfPriorities, defaultPriority); - } + @DataBoundConstructor + public FQStrategy(int numberOfPriorities, int defaultPriority) { + super(numberOfPriorities, defaultPriority); + } - @Override - float getStepSize(int priority) { - // If FQ each priority is equally important - // so we basically assign priorities in - // with round-robin - // - // The step-size for the priority is same for all priorities - float stepSize = MIN_STEP_SIZE; - return stepSize; - } + @Override + float getStepSize(int priority) { + // If FQ each priority is equally important + // so we basically assign priorities in + // with round-robin + // + // The step-size for the priority is same for all priorities + float stepSize = MIN_STEP_SIZE; + return stepSize; + } - @Extension - public static class DescriptorImpl extends MultiBucketStrategyDescriptor { + @Extension + public static class DescriptorImpl extends MultiBucketStrategyDescriptor { - @Override - public String getDisplayName() { - return Messages.SorterStrategy_FQ_displayName(); - } + @Override + public String getDisplayName() { + return Messages.SorterStrategy_FQ_displayName(); + } - @Override - public String getShortName() { - return Messages.SorterStrategy_FQ_shortName(); - } - } + @Override + public String getShortName() { + return Messages.SorterStrategy_FQ_shortName(); + } + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/strategy/MultiBucketStrategy.java b/src/main/java/jenkins/advancedqueue/sorter/strategy/MultiBucketStrategy.java index 0dcf4c7e..b9a34e62 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/strategy/MultiBucketStrategy.java +++ b/src/main/java/jenkins/advancedqueue/sorter/strategy/MultiBucketStrategy.java @@ -24,113 +24,108 @@ package jenkins.advancedqueue.sorter.strategy; import edu.umd.cs.findbugs.annotations.CheckForNull; - import hudson.util.ListBoxModel; - import java.io.IOException; - import javax.servlet.ServletException; - import jenkins.advancedqueue.PrioritySorterConfiguration; import jenkins.advancedqueue.sorter.SorterStrategy; import jenkins.advancedqueue.sorter.SorterStrategyDescriptor; - import org.kohsuke.stapler.QueryParameter; /** * Implements a strategy with multiple buckets. - * + * * @author Oleg Nenashev * @since 2.0 */ public abstract class MultiBucketStrategy extends SorterStrategy { - public static final int DEFAULT_PRIORITIES_NUMBER = 5; - public static final int DEFAULT_PRIORITY = 3; - - private final int numberOfPriorities; - private final int defaultPriority; - - public MultiBucketStrategy() { - this(DEFAULT_PRIORITIES_NUMBER, DEFAULT_PRIORITY); - } - - public MultiBucketStrategy(int numberOfPriorities, int defaultPriority) { - this.numberOfPriorities = numberOfPriorities; - this.defaultPriority = defaultPriority; - } - - @Override - public final int getNumberOfPriorities() { - return numberOfPriorities; - } - - @Override - public final int getDefaultPriority() { - return defaultPriority; - } - - public ListBoxModel doFillDefaultPriorityItems() { - // TODO: replace by dynamic retrieval - throw new RuntimeException(); - } - - public abstract static class MultiBucketStrategyDescriptor extends SorterStrategyDescriptor { - - public ListBoxModel doUpdateDefaultPriorityItems(@QueryParameter("value") String strValue) { - int value = DEFAULT_PRIORITY; - try { - value = Integer.parseInt(strValue); - } catch (NumberFormatException e) { - // Use default value - } - ListBoxModel items = internalFillDefaultPriorityItems(value); - return items; - } - - public ListBoxModel doDefaultPriority(@QueryParameter("value") String value) throws IOException, - ServletException { - return doUpdateDefaultPriorityItems(value); - } - - private ListBoxModel internalFillDefaultPriorityItems(int value) { - ListBoxModel items = new ListBoxModel(); - for (int i = 1; i <= value; i++) { - items.add(String.valueOf(i)); - } - return items; - } - - @CheckForNull - private MultiBucketStrategy getStrategy() { - SorterStrategy strategy = PrioritySorterConfiguration.get().getStrategy(); - if (strategy == null || !(strategy instanceof MultiBucketStrategy)) { - return null; - } - return (MultiBucketStrategy) strategy; - } - - public ListBoxModel doFillDefaultPriorityItems() { - MultiBucketStrategy strategy = getStrategy(); - if (strategy == null) { - return internalFillDefaultPriorityItems(DEFAULT_PRIORITIES_NUMBER); - } - return internalFillDefaultPriorityItems(strategy.getNumberOfPriorities()); - } - - public int getDefaultPrioritiesNumber() { - MultiBucketStrategy strategy = getStrategy(); - if (strategy == null) { - return DEFAULT_PRIORITIES_NUMBER; - } - return strategy.getNumberOfPriorities(); - } - - public int getDefaultPriority() { - MultiBucketStrategy strategy = getStrategy(); - if (strategy == null) { - return DEFAULT_PRIORITY; - } - return strategy.getDefaultPriority(); - } - } + public static final int DEFAULT_PRIORITIES_NUMBER = 5; + public static final int DEFAULT_PRIORITY = 3; + + private final int numberOfPriorities; + private final int defaultPriority; + + public MultiBucketStrategy() { + this(DEFAULT_PRIORITIES_NUMBER, DEFAULT_PRIORITY); + } + + public MultiBucketStrategy(int numberOfPriorities, int defaultPriority) { + this.numberOfPriorities = numberOfPriorities; + this.defaultPriority = defaultPriority; + } + + @Override + public final int getNumberOfPriorities() { + return numberOfPriorities; + } + + @Override + public final int getDefaultPriority() { + return defaultPriority; + } + + public ListBoxModel doFillDefaultPriorityItems() { + // TODO: replace by dynamic retrieval + throw new RuntimeException(); + } + + public abstract static class MultiBucketStrategyDescriptor extends SorterStrategyDescriptor { + + public ListBoxModel doUpdateDefaultPriorityItems(@QueryParameter("value") String strValue) { + int value = DEFAULT_PRIORITY; + try { + value = Integer.parseInt(strValue); + } catch (NumberFormatException e) { + // Use default value + } + ListBoxModel items = internalFillDefaultPriorityItems(value); + return items; + } + + public ListBoxModel doDefaultPriority(@QueryParameter("value") String value) + throws IOException, ServletException { + return doUpdateDefaultPriorityItems(value); + } + + private ListBoxModel internalFillDefaultPriorityItems(int value) { + ListBoxModel items = new ListBoxModel(); + for (int i = 1; i <= value; i++) { + items.add(String.valueOf(i)); + } + return items; + } + + @CheckForNull + private MultiBucketStrategy getStrategy() { + SorterStrategy strategy = PrioritySorterConfiguration.get().getStrategy(); + if (strategy == null || !(strategy instanceof MultiBucketStrategy)) { + return null; + } + return (MultiBucketStrategy) strategy; + } + + public ListBoxModel doFillDefaultPriorityItems() { + MultiBucketStrategy strategy = getStrategy(); + if (strategy == null) { + return internalFillDefaultPriorityItems(DEFAULT_PRIORITIES_NUMBER); + } + return internalFillDefaultPriorityItems(strategy.getNumberOfPriorities()); + } + + public int getDefaultPrioritiesNumber() { + MultiBucketStrategy strategy = getStrategy(); + if (strategy == null) { + return DEFAULT_PRIORITIES_NUMBER; + } + return strategy.getNumberOfPriorities(); + } + + public int getDefaultPriority() { + MultiBucketStrategy strategy = getStrategy(); + if (strategy == null) { + return DEFAULT_PRIORITY; + } + return strategy.getDefaultPriority(); + } + } } diff --git a/src/main/java/jenkins/advancedqueue/sorter/strategy/WFQStrategy.java b/src/main/java/jenkins/advancedqueue/sorter/strategy/WFQStrategy.java index 9dc257d5..ecd6c442 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/strategy/WFQStrategy.java +++ b/src/main/java/jenkins/advancedqueue/sorter/strategy/WFQStrategy.java @@ -33,35 +33,34 @@ */ public class WFQStrategy extends FQBaseStrategy { - public WFQStrategy() { - } + public WFQStrategy() {} - @DataBoundConstructor - public WFQStrategy(int numberOfPriorities, int defaultPriority) { - super(numberOfPriorities, defaultPriority); - } + @DataBoundConstructor + public WFQStrategy(int numberOfPriorities, int defaultPriority) { + super(numberOfPriorities, defaultPriority); + } - @Override - float getStepSize(int priority) { - // If WFQ a lower priority is more important than a higher priority - // so we must step higher priorities faster than lower ones - // - // The step-size for the priority is dependent on its priority - float stepSize = MIN_STEP_SIZE * (float) priority; - return stepSize; - } + @Override + float getStepSize(int priority) { + // If WFQ a lower priority is more important than a higher priority + // so we must step higher priorities faster than lower ones + // + // The step-size for the priority is dependent on its priority + float stepSize = MIN_STEP_SIZE * (float) priority; + return stepSize; + } - @Extension - public static class DescriptorImpl extends MultiBucketStrategyDescriptor { + @Extension + public static class DescriptorImpl extends MultiBucketStrategyDescriptor { - @Override - public String getDisplayName() { - return Messages.SorterStrategy_WFQ_displayName(); - } + @Override + public String getDisplayName() { + return Messages.SorterStrategy_WFQ_displayName(); + } - @Override - public String getShortName() { - return Messages.SorterStrategy_WFQ_shortName(); - } - } + @Override + public String getShortName() { + return Messages.SorterStrategy_WFQ_shortName(); + } + } } diff --git a/src/main/java/jenkins/advancedqueue/util/PrioritySorterUtil.java b/src/main/java/jenkins/advancedqueue/util/PrioritySorterUtil.java index 23f690fe..4937e21c 100644 --- a/src/main/java/jenkins/advancedqueue/util/PrioritySorterUtil.java +++ b/src/main/java/jenkins/advancedqueue/util/PrioritySorterUtil.java @@ -3,17 +3,16 @@ import hudson.util.ListBoxModel; public class PrioritySorterUtil { - - static public ListBoxModel fillPriorityItems(int to) { - return fillPriorityItems(1, to); - } - static public ListBoxModel fillPriorityItems(int from, int to) { - ListBoxModel items = new ListBoxModel(); - for (int i = from; i <= to; i++) { - items.add(String.valueOf(i)); - } - return items; - } + public static ListBoxModel fillPriorityItems(int to) { + return fillPriorityItems(1, to); + } + public static ListBoxModel fillPriorityItems(int from, int to) { + ListBoxModel items = new ListBoxModel(); + for (int i = from; i <= to; i++) { + items.add(String.valueOf(i)); + } + return items; + } } diff --git a/src/test/java/jenkins/advancedqueue/PriorityCalculationsUtilTest.java b/src/test/java/jenkins/advancedqueue/PriorityCalculationsUtilTest.java index 52e5bf31..4dc10ced 100644 --- a/src/test/java/jenkins/advancedqueue/PriorityCalculationsUtilTest.java +++ b/src/test/java/jenkins/advancedqueue/PriorityCalculationsUtilTest.java @@ -5,26 +5,24 @@ public class PriorityCalculationsUtilTest { - @Test - public void testScale() { - Assert.assertEquals(10, PriorityCalculationsUtil.scale(100, 10, 100)); - Assert.assertEquals(1, PriorityCalculationsUtil.scale(100, 10, 9)); - Assert.assertEquals(5, PriorityCalculationsUtil.scale(100, 10, 50)); - Assert.assertEquals(8, PriorityCalculationsUtil.scale(100, 10, 75)); + @Test + public void testScale() { + Assert.assertEquals(10, PriorityCalculationsUtil.scale(100, 10, 100)); + Assert.assertEquals(1, PriorityCalculationsUtil.scale(100, 10, 9)); + Assert.assertEquals(5, PriorityCalculationsUtil.scale(100, 10, 50)); + Assert.assertEquals(8, PriorityCalculationsUtil.scale(100, 10, 75)); - Assert.assertEquals(1, PriorityCalculationsUtil.scale(5, 10, 1)); - Assert.assertEquals(3, PriorityCalculationsUtil.scale(5, 10, 2)); - Assert.assertEquals(5, PriorityCalculationsUtil.scale(5, 10, 3)); - Assert.assertEquals(8, PriorityCalculationsUtil.scale(5, 10, 4)); - Assert.assertEquals(10, PriorityCalculationsUtil.scale(5, 10, 5)); - } - - @Test - public void testScaleUseDefaultPriority() { - Assert.assertEquals(PriorityCalculationsUtil - .getUseDefaultPriorityPriority(), PriorityCalculationsUtil - .scale(5, 10, PriorityCalculationsUtil - .getUseDefaultPriorityPriority())); - } + Assert.assertEquals(1, PriorityCalculationsUtil.scale(5, 10, 1)); + Assert.assertEquals(3, PriorityCalculationsUtil.scale(5, 10, 2)); + Assert.assertEquals(5, PriorityCalculationsUtil.scale(5, 10, 3)); + Assert.assertEquals(8, PriorityCalculationsUtil.scale(5, 10, 4)); + Assert.assertEquals(10, PriorityCalculationsUtil.scale(5, 10, 5)); + } + @Test + public void testScaleUseDefaultPriority() { + Assert.assertEquals( + PriorityCalculationsUtil.getUseDefaultPriorityPriority(), + PriorityCalculationsUtil.scale(5, 10, PriorityCalculationsUtil.getUseDefaultPriorityPriority())); + } } diff --git a/src/test/java/jenkins/advancedqueue/sorter/strategy/FQStrategyTest.java b/src/test/java/jenkins/advancedqueue/sorter/strategy/FQStrategyTest.java index 0108299e..148c204a 100644 --- a/src/test/java/jenkins/advancedqueue/sorter/strategy/FQStrategyTest.java +++ b/src/test/java/jenkins/advancedqueue/sorter/strategy/FQStrategyTest.java @@ -5,29 +5,31 @@ public class FQStrategyTest { - @Test - public void testStepSize() { - Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(1), 0F); - Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(2), 0F); - Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(3), 0F); - Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(4), 0F); - } + @Test + public void testStepSize() { + Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(1), 0F); + Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(2), 0F); + Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(3), 0F); + Assert.assertEquals(FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getStepSize(4), 0F); + } - @Test - public void testGetWeightToUse() { - Assert.assertEquals(1.00000F + FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getWeightToUse(1, 1.00000F), 0F); - Assert.assertEquals(1.00001F + FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getWeightToUse(1, 1.00001F), 0F); - Assert.assertEquals(1F, new FQStrategy().getWeightToUse(1, Float.MAX_VALUE), 0F); - assertIncreasingWeight(1F); - assertIncreasingWeight(100000F); - } + @Test + public void testGetWeightToUse() { + Assert.assertEquals(1.00000F + FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getWeightToUse(1, 1.00000F), 0F); + Assert.assertEquals(1.00001F + FQBaseStrategy.MIN_STEP_SIZE, new FQStrategy().getWeightToUse(1, 1.00001F), 0F); + Assert.assertEquals(1F, new FQStrategy().getWeightToUse(1, Float.MAX_VALUE), 0F); + assertIncreasingWeight(1F); + assertIncreasingWeight(100000F); + } - private void assertIncreasingWeight(float initialWeight) { - float previousWeight = initialWeight; - for (int i = 0; i < 10; ++i) { - float newWeight = new FQStrategy().getWeightToUse(1, previousWeight); - Assert.assertTrue(String.format("New weight %s should be greater than previous weight %s", newWeight, previousWeight), newWeight > previousWeight); - previousWeight = newWeight; - } - } + private void assertIncreasingWeight(float initialWeight) { + float previousWeight = initialWeight; + for (int i = 0; i < 10; ++i) { + float newWeight = new FQStrategy().getWeightToUse(1, previousWeight); + Assert.assertTrue( + String.format("New weight %s should be greater than previous weight %s", newWeight, previousWeight), + newWeight > previousWeight); + previousWeight = newWeight; + } + } } diff --git a/src/test/java/jenkins/advancedqueue/sorter/strategy/WFQStrategyTest.java b/src/test/java/jenkins/advancedqueue/sorter/strategy/WFQStrategyTest.java index c5153deb..888e8a27 100644 --- a/src/test/java/jenkins/advancedqueue/sorter/strategy/WFQStrategyTest.java +++ b/src/test/java/jenkins/advancedqueue/sorter/strategy/WFQStrategyTest.java @@ -5,21 +5,21 @@ public class WFQStrategyTest { - @Test - public void testStepSize() { - Assert.assertEquals(1 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(1), 0F); - Assert.assertEquals(2 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(2), 0F); - Assert.assertEquals(3 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(3), 0F); - Assert.assertEquals(4 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(4), 0F); - } - - - @Test - public void testGetWeightToUse() { - Assert.assertEquals(1.00000F + FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(1, 1.00000F), 0F); - Assert.assertEquals(1.00001F + FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(1, 1.00001F), 0F); - Assert.assertEquals(1.00000F + 2*FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(2, 1.00000F), 0F); - Assert.assertEquals(1.00001F + 2*FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(2, 1.00001F), 0F); - } - + @Test + public void testStepSize() { + Assert.assertEquals(1 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(1), 0F); + Assert.assertEquals(2 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(2), 0F); + Assert.assertEquals(3 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(3), 0F); + Assert.assertEquals(4 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getStepSize(4), 0F); + } + + @Test + public void testGetWeightToUse() { + Assert.assertEquals(1.00000F + FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(1, 1.00000F), 0F); + Assert.assertEquals(1.00001F + FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(1, 1.00001F), 0F); + Assert.assertEquals( + 1.00000F + 2 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(2, 1.00000F), 0F); + Assert.assertEquals( + 1.00001F + 2 * FQBaseStrategy.MIN_STEP_SIZE, new WFQStrategy().getWeightToUse(2, 1.00001F), 0F); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/BasicTest.java b/src/test/java/jenkins/advancedqueue/test/BasicTest.java index 97fa0bd5..3c9ed5bf 100644 --- a/src/test/java/jenkins/advancedqueue/test/BasicTest.java +++ b/src/test/java/jenkins/advancedqueue/test/BasicTest.java @@ -4,7 +4,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -12,26 +11,26 @@ public class BasicTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Rule + public JenkinsRule j = new JenkinsRule(); + + private JobHelper jobHelper = new JobHelper(j); - private JobHelper jobHelper = new JobHelper(j); - - @Test - @LocalData - public void simple_two_jobs_with_basic_configuration() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 9), new ExpectedItem("Job 1", 9)); - jobHelper.scheduleProjects(new UserIdCause(), new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void simple_two_jobs_with_basic_configuration() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 9), new ExpectedItem("Job 1", 9)); + jobHelper.scheduleProjects(new UserIdCause(), new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } - @Test - @LocalData - public void simple_with_basic_configuration() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 9)); - jobHelper.scheduleProjects(new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void simple_with_basic_configuration() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 9)); + jobHelper.scheduleProjects(new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/JobPatternGroupTest.java b/src/test/java/jenkins/advancedqueue/test/JobPatternGroupTest.java index c3bbc1d0..40c2f76f 100644 --- a/src/test/java/jenkins/advancedqueue/test/JobPatternGroupTest.java +++ b/src/test/java/jenkins/advancedqueue/test/JobPatternGroupTest.java @@ -4,7 +4,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -12,37 +11,41 @@ public class JobPatternGroupTest { - @Rule - public JenkinsRule j = new JenkinsRule(); - - private JobHelper jobHelper = new JobHelper(j); - - @Test - @LocalData - public void test_job_pattern_1() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 3)); - jobHelper.scheduleProjects(new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } - - @Test - @LocalData - public void test_job_pattern_2() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 3), new ExpectedItem("Job 1", 9)); - jobHelper.scheduleProjects(new UserIdCause(), new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } - - @Test - @LocalData - public void test_job_pattern_3() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 3), new ExpectedItem("Job 3", 3), new ExpectedItem("Job 1", 9), - new ExpectedItem("Job 2", 9)); - jobHelper.scheduleProjects(new UserIdCause(), new UserIdCause(), new UserIdCause(), new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } - + @Rule + public JenkinsRule j = new JenkinsRule(); + + private JobHelper jobHelper = new JobHelper(j); + + @Test + @LocalData + public void test_job_pattern_1() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 3)); + jobHelper.scheduleProjects(new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } + + @Test + @LocalData + public void test_job_pattern_2() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 3), new ExpectedItem("Job 1", 9)); + jobHelper.scheduleProjects(new UserIdCause(), new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } + + @Test + @LocalData + public void test_job_pattern_3() throws Exception { + TestRunListener.init( + new ExpectedItem("Job 0", 3), + new ExpectedItem("Job 3", 3), + new ExpectedItem("Job 1", 9), + new ExpectedItem("Job 2", 9)); + jobHelper + .scheduleProjects(new UserIdCause(), new UserIdCause(), new UserIdCause(), new UserIdCause()) + .go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/MatrixTest.java b/src/test/java/jenkins/advancedqueue/test/MatrixTest.java index 99099e84..719dc99b 100644 --- a/src/test/java/jenkins/advancedqueue/test/MatrixTest.java +++ b/src/test/java/jenkins/advancedqueue/test/MatrixTest.java @@ -5,7 +5,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -13,61 +12,68 @@ public class MatrixTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Rule + public JenkinsRule j = new JenkinsRule(); - private JobHelper jobHelper = new JobHelper(j); + private JobHelper jobHelper = new JobHelper(j); - @Test - @LocalData - public void simple_matrix_with_no_configuration() throws Exception { - TestRunListener.init( - new ExpectedItem("Matrix 0", 1), - new ExpectedItem("0A1=0A.", 1), new ExpectedItem("0A1=0A.", 1) - ); - jobHelper.scheduleMatrixProjects(new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void simple_matrix_with_no_configuration() throws Exception { + TestRunListener.init( + new ExpectedItem("Matrix 0", 1), new ExpectedItem("0A1=0A.", 1), new ExpectedItem("0A1=0A.", 1)); + jobHelper.scheduleMatrixProjects(new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } - @Test - @LocalData - public void simple_two_matrix_with_no_configuration() throws Exception { - TestRunListener.init( - new ExpectedItem("Matrix 0", 1), new ExpectedItem("Matrix 1", 1), - new ExpectedItem("0A1=0A.", 1), new ExpectedItem("0A1=0A.", 1), - new ExpectedItem("1A1=1A.", 1), new ExpectedItem("1A1=1A.", 1) - ); - jobHelper.scheduleMatrixProjects(new UserIdCause(), new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void simple_two_matrix_with_no_configuration() throws Exception { + TestRunListener.init( + new ExpectedItem("Matrix 0", 1), new ExpectedItem("Matrix 1", 1), + new ExpectedItem("0A1=0A.", 1), new ExpectedItem("0A1=0A.", 1), + new ExpectedItem("1A1=1A.", 1), new ExpectedItem("1A1=1A.", 1)); + jobHelper.scheduleMatrixProjects(new UserIdCause(), new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } - @Test - @LocalData - public void matrix_and_jobs_with_no_configuration() throws Exception { - TestRunListener.init( - new ExpectedItem("Matrix 0", 1), new ExpectedItem("Matrix 1", 5), - new ExpectedItem("0A1=0A.", 1), new ExpectedItem("0A1=0A.", 1), - new ExpectedItem("Job 0", 5), - new ExpectedItem("1A1=1A.", 5), new ExpectedItem("1A1=1A.", 5) - ); - jobHelper.scheduleProjects(new CLICause()).scheduleMatrixProjects(new UserIdCause(), new CLICause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void matrix_and_jobs_with_no_configuration() throws Exception { + TestRunListener.init( + new ExpectedItem("Matrix 0", 1), + new ExpectedItem("Matrix 1", 5), + new ExpectedItem("0A1=0A.", 1), + new ExpectedItem("0A1=0A.", 1), + new ExpectedItem("Job 0", 5), + new ExpectedItem("1A1=1A.", 5), + new ExpectedItem("1A1=1A.", 5)); + jobHelper + .scheduleProjects(new CLICause()) + .scheduleMatrixProjects(new UserIdCause(), new CLICause()) + .go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } - @Test - @LocalData - public void matrix_and_jobs_with_no_configuration_reverse() throws Exception { - TestRunListener.init( - new ExpectedItem("Matrix 0", 1), new ExpectedItem("Matrix 1", 5), - new ExpectedItem("0A1=0A.", 1), new ExpectedItem("0A1=0A.", 1), - new ExpectedItem("1A1=1A.", 5), new ExpectedItem("1A1=1A.", 5), - new ExpectedItem("Job 0", 5) - ); - jobHelper.scheduleMatrixProjects(new UserIdCause(), new CLICause()).scheduleProjects(new CLICause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void matrix_and_jobs_with_no_configuration_reverse() throws Exception { + TestRunListener.init( + new ExpectedItem("Matrix 0", 1), + new ExpectedItem("Matrix 1", 5), + new ExpectedItem("0A1=0A.", 1), + new ExpectedItem("0A1=0A.", 1), + new ExpectedItem("1A1=1A.", 5), + new ExpectedItem("1A1=1A.", 5), + new ExpectedItem("Job 0", 5)); + jobHelper + .scheduleMatrixProjects(new UserIdCause(), new CLICause()) + .scheduleProjects(new CLICause()) + .go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/MultipleMatchJobGroupTest.java b/src/test/java/jenkins/advancedqueue/test/MultipleMatchJobGroupTest.java index fb1ba1f6..cad17613 100644 --- a/src/test/java/jenkins/advancedqueue/test/MultipleMatchJobGroupTest.java +++ b/src/test/java/jenkins/advancedqueue/test/MultipleMatchJobGroupTest.java @@ -5,7 +5,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -13,20 +12,25 @@ public class MultipleMatchJobGroupTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Rule + public JenkinsRule j = new JenkinsRule(); - private JobHelper jobHelper = new JobHelper(j); + private JobHelper jobHelper = new JobHelper(j); - @Test - @LocalData - public void multiple_job_group_matches() throws Exception { - // Job 2 and 3 matches View1 and All -> View1 is before All -> priorities are 1 and 2 - // Job 0 and 1 matched only All -> priorities are 3 and 4 - TestRunListener.init(new ExpectedItem("Job 2", 1), new ExpectedItem("Job 3", 2), new ExpectedItem("Job 0", 3), - new ExpectedItem("Job 1", 4)); - jobHelper.scheduleProjects(new CLICause(), new Cause.UserIdCause(), new CLICause(), new Cause.UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void multiple_job_group_matches() throws Exception { + // Job 2 and 3 matches View1 and All -> View1 is before All -> priorities are 1 and 2 + // Job 0 and 1 matched only All -> priorities are 3 and 4 + TestRunListener.init( + new ExpectedItem("Job 2", 1), + new ExpectedItem("Job 3", 2), + new ExpectedItem("Job 0", 3), + new ExpectedItem("Job 1", 4)); + jobHelper + .scheduleProjects(new CLICause(), new Cause.UserIdCause(), new CLICause(), new Cause.UserIdCause()) + .go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/NestedViewTest.java b/src/test/java/jenkins/advancedqueue/test/NestedViewTest.java index 46f48e26..2c0d4c57 100644 --- a/src/test/java/jenkins/advancedqueue/test/NestedViewTest.java +++ b/src/test/java/jenkins/advancedqueue/test/NestedViewTest.java @@ -4,7 +4,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -12,19 +11,19 @@ public class NestedViewTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Rule + public JenkinsRule j = new JenkinsRule(); - private JobHelper jobHelper = new JobHelper(j); + private JobHelper jobHelper = new JobHelper(j); - @Test - @LocalData - public void nested_view_test() throws Exception { - // Job 0 matches "Nested View A/Nested View B" -> priority is 1 - // Job 0 matched nothing -> default priority is 9 - TestRunListener.init(new ExpectedItem("Job 0", 1), new ExpectedItem("Job 1", 9)); - jobHelper.scheduleProjects(new CLICause(), new CLICause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void nested_view_test() throws Exception { + // Job 0 matches "Nested View A/Nested View B" -> priority is 1 + // Job 0 matched nothing -> default priority is 9 + TestRunListener.init(new ExpectedItem("Job 0", 1), new ExpectedItem("Job 1", 9)); + jobHelper.scheduleProjects(new CLICause(), new CLICause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/OneJobGroupTest.java b/src/test/java/jenkins/advancedqueue/test/OneJobGroupTest.java index f00ebad9..7de18400 100644 --- a/src/test/java/jenkins/advancedqueue/test/OneJobGroupTest.java +++ b/src/test/java/jenkins/advancedqueue/test/OneJobGroupTest.java @@ -5,7 +5,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -13,56 +12,59 @@ public class OneJobGroupTest { - @Rule - public JenkinsRule j = new JenkinsRule(); - - private JobHelper jobHelper = new JobHelper(j); + @Rule + public JenkinsRule j = new JenkinsRule(); - @Test - @LocalData - public void default_job_group_priority() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 3)); - jobHelper.scheduleProjects(new Cause() { + private JobHelper jobHelper = new JobHelper(j); - @Override - public String getShortDescription() { - return "Dummy Cause"; - } - }).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void default_job_group_priority() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 3)); + jobHelper + .scheduleProjects(new Cause() { - @Test - @LocalData - public void test_UserIdCause() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 4)); - jobHelper.scheduleProjects(new Cause.UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Override + public String getShortDescription() { + return "Dummy Cause"; + } + }) + .go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } - @Test - @LocalData - public void test_CLICause() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 5)); - jobHelper.scheduleProjects(new CLICause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void test_UserIdCause() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 4)); + jobHelper.scheduleProjects(new Cause.UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } - @Test - @LocalData - public void test_multiple_strategies() throws Exception { - TestRunListener.init(new ExpectedItem("Job 2", 3), new ExpectedItem("Job 1", 4), new ExpectedItem("Job 0", 5)); - jobHelper.scheduleProjects(new CLICause(), new Cause.UserIdCause(), new Cause() { - @Override - public String getShortDescription() { - return "Dummy Cause"; - } - }).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void test_CLICause() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 5)); + jobHelper.scheduleProjects(new CLICause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } + @Test + @LocalData + public void test_multiple_strategies() throws Exception { + TestRunListener.init(new ExpectedItem("Job 2", 3), new ExpectedItem("Job 1", 4), new ExpectedItem("Job 0", 5)); + jobHelper + .scheduleProjects(new CLICause(), new Cause.UserIdCause(), new Cause() { + @Override + public String getShortDescription() { + return "Dummy Cause"; + } + }) + .go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/SectionedViewTest.java b/src/test/java/jenkins/advancedqueue/test/SectionedViewTest.java index dba2ae2f..ab7650c6 100644 --- a/src/test/java/jenkins/advancedqueue/test/SectionedViewTest.java +++ b/src/test/java/jenkins/advancedqueue/test/SectionedViewTest.java @@ -4,7 +4,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -12,20 +11,22 @@ public class SectionedViewTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Rule + public JenkinsRule j = new JenkinsRule(); - private JobHelper jobHelper = new JobHelper(j); + private JobHelper jobHelper = new JobHelper(j); - @Test - @LocalData - public void sectioned_view_test() throws Exception { - // Job 2 matches Sectioned View and All -> Sectioned View is before All -> priority is 1 - // Job 1 matches View1 and All -> View1 is before All -> priority is 2 - // Job 0 matched only All -> priority is 3 - TestRunListener.init(new ExpectedItem("Job 2", 1), new ExpectedItem("Job 1", 2), new ExpectedItem("Job 0", 3)); - jobHelper.scheduleProjects(new CLICause(), new CLICause(), new CLICause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void sectioned_view_test() throws Exception { + // Job 2 matches Sectioned View and All -> Sectioned View is before All -> priority is 1 + // Job 1 matches View1 and All -> View1 is before All -> priority is 2 + // Job 0 matched only All -> priority is 3 + TestRunListener.init(new ExpectedItem("Job 2", 1), new ExpectedItem("Job 1", 2), new ExpectedItem("Job 0", 3)); + jobHelper + .scheduleProjects(new CLICause(), new CLICause(), new CLICause()) + .go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/SimpleTest.java b/src/test/java/jenkins/advancedqueue/test/SimpleTest.java index 2610a479..003bbf78 100644 --- a/src/test/java/jenkins/advancedqueue/test/SimpleTest.java +++ b/src/test/java/jenkins/advancedqueue/test/SimpleTest.java @@ -4,7 +4,6 @@ import jenkins.advancedqueue.testutil.ExpectedItem; import jenkins.advancedqueue.testutil.JobHelper; import jenkins.advancedqueue.testutil.TestRunListener; - import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -12,27 +11,26 @@ public class SimpleTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Rule + public JenkinsRule j = new JenkinsRule(); - private JobHelper jobHelper = new JobHelper(j); - - @Test - @LocalData - public void simple_with_no_configuration() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 3)); - jobHelper.scheduleProjects(new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + private JobHelper jobHelper = new JobHelper(j); - @Test - @LocalData - public void simple_two_jobs_with_no_configuration() throws Exception { - TestRunListener.init(new ExpectedItem("Job 0", 3), new ExpectedItem("Job 1", 3)); - jobHelper.scheduleProjects(new UserIdCause(), new UserIdCause()).go(); - j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + @Test + @LocalData + public void simple_with_no_configuration() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 3)); + jobHelper.scheduleProjects(new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } + @Test + @LocalData + public void simple_two_jobs_with_no_configuration() throws Exception { + TestRunListener.init(new ExpectedItem("Job 0", 3), new ExpectedItem("Job 1", 3)); + jobHelper.scheduleProjects(new UserIdCause(), new UserIdCause()).go(); + j.waitUntilNoActivity(); + TestRunListener.assertStartedItems(); + } } diff --git a/src/test/java/jenkins/advancedqueue/test/UpstreamTest.java b/src/test/java/jenkins/advancedqueue/test/UpstreamTest.java index 0ed7f66a..8e2027f6 100644 --- a/src/test/java/jenkins/advancedqueue/test/UpstreamTest.java +++ b/src/test/java/jenkins/advancedqueue/test/UpstreamTest.java @@ -1,76 +1,77 @@ package jenkins.advancedqueue.test; import edu.umd.cs.findbugs.annotations.CheckForNull; - +import hudson.model.Cause; +import hudson.model.Cause.UpstreamCause; +import hudson.model.Cause.UserIdCause; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.Collections; import java.util.List; - +import jenkins.advancedqueue.testutil.ExpectedItem; +import jenkins.advancedqueue.testutil.JobHelper; +import jenkins.advancedqueue.testutil.TestRunListener; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.recipes.LocalData; -import hudson.model.Cause; -import hudson.model.Cause.UpstreamCause; -import hudson.model.Cause.UserIdCause; -import jenkins.advancedqueue.testutil.ExpectedItem; -import jenkins.advancedqueue.testutil.JobHelper; -import jenkins.advancedqueue.testutil.TestRunListener; - public class UpstreamTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Rule + public JenkinsRule j = new JenkinsRule(); - private final JobHelper jobHelper = new JobHelper(j); + private final JobHelper jobHelper = new JobHelper(j); - @Test - @LocalData - public void testOrphanDownstreamJob() throws Exception { - // Job 0 should run with default priority, as upstream build is unknown - TestRunListener.init(new ExpectedItem("Job 0", 5)); - jobHelper.scheduleProjects(createUpstreamCause("Job X", 987)).go(); - j.waitUntilNoActivity(); + @Test + @LocalData + public void testOrphanDownstreamJob() throws Exception { + // Job 0 should run with default priority, as upstream build is unknown + TestRunListener.init(new ExpectedItem("Job 0", 5)); + jobHelper.scheduleProjects(createUpstreamCause("Job X", 987)).go(); + j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + TestRunListener.assertStartedItems(); + } - @Test - @LocalData - public void testUserJobAndAssociatedDownstreamJob() throws Exception { - // Upstream job should run with high priority (user triggered) - TestRunListener.init(new ExpectedItem("Upstream", 1)); - jobHelper.scheduleProject("Upstream", new UserIdCause()).go(); - j.waitUntilNoActivity(); + @Test + @LocalData + public void testUserJobAndAssociatedDownstreamJob() throws Exception { + // Upstream job should run with high priority (user triggered) + TestRunListener.init(new ExpectedItem("Upstream", 1)); + jobHelper.scheduleProject("Upstream", new UserIdCause()).go(); + j.waitUntilNoActivity(); - // Downstream job 1 should run with priority of upstream job build 1 - TestRunListener.init(new ExpectedItem("Downstream1", 1)); - jobHelper.scheduleProject("Downstream1", createUpstreamCause("Upstream", 1)).go(); - j.waitUntilNoActivity(); + // Downstream job 1 should run with priority of upstream job build 1 + TestRunListener.init(new ExpectedItem("Downstream1", 1)); + jobHelper + .scheduleProject("Downstream1", createUpstreamCause("Upstream", 1)) + .go(); + j.waitUntilNoActivity(); - // Downstream job 2 should run with priority of upstream job build 2 (not present, i.e. default priority - // should be used) - TestRunListener.init(new ExpectedItem("Downstream2", 5)); - jobHelper.scheduleProject("Downstream2", createUpstreamCause("Upstream", 2)).go(); - j.waitUntilNoActivity(); + // Downstream job 2 should run with priority of upstream job build 2 (not present, i.e. default priority + // should be used) + TestRunListener.init(new ExpectedItem("Downstream2", 5)); + jobHelper + .scheduleProject("Downstream2", createUpstreamCause("Upstream", 2)) + .go(); + j.waitUntilNoActivity(); - TestRunListener.assertStartedItems(); - } + TestRunListener.assertStartedItems(); + } - @CheckForNull - private UpstreamCause createUpstreamCause(final String upstreamProject, final int upstreamBuild) throws Exception { - final Class clazz = UpstreamCause.class; - final Constructor[] constructors = clazz.getDeclaredConstructors(); + @CheckForNull + private UpstreamCause createUpstreamCause(final String upstreamProject, final int upstreamBuild) throws Exception { + final Class clazz = UpstreamCause.class; + final Constructor[] constructors = clazz.getDeclaredConstructors(); - for (final Constructor cons : constructors) { - if (Arrays.equals(cons.getParameterTypes(), - new Class[] { String.class, int.class, String.class, List.class })) { - cons.setAccessible(true); - return (UpstreamCause) cons.newInstance(upstreamProject, upstreamBuild, "url", - Collections.emptyList()); - } - } - return null; - } + for (final Constructor cons : constructors) { + if (Arrays.equals( + cons.getParameterTypes(), new Class[] {String.class, int.class, String.class, List.class})) { + cons.setAccessible(true); + return (UpstreamCause) + cons.newInstance(upstreamProject, upstreamBuild, "url", Collections.emptyList()); + } + } + return null; + } } diff --git a/src/test/java/jenkins/advancedqueue/testutil/ExpectedItem.java b/src/test/java/jenkins/advancedqueue/testutil/ExpectedItem.java index 495123d1..c207d2a0 100644 --- a/src/test/java/jenkins/advancedqueue/testutil/ExpectedItem.java +++ b/src/test/java/jenkins/advancedqueue/testutil/ExpectedItem.java @@ -1,22 +1,20 @@ package jenkins.advancedqueue.testutil; - public class ExpectedItem { - private String jobName; - private int priority; - - public ExpectedItem(String jobName, int priority) { - this.jobName = jobName; - this.priority = priority; - } + private String jobName; + private int priority; - public String getJobName() { - return jobName; - } + public ExpectedItem(String jobName, int priority) { + this.jobName = jobName; + this.priority = priority; + } - public int getPriority() { - return priority; - } + public String getJobName() { + return jobName; + } + public int getPriority() { + return priority; + } } diff --git a/src/test/java/jenkins/advancedqueue/testutil/JobHelper.java b/src/test/java/jenkins/advancedqueue/testutil/JobHelper.java index bedfa478..ebb7d5db 100644 --- a/src/test/java/jenkins/advancedqueue/testutil/JobHelper.java +++ b/src/test/java/jenkins/advancedqueue/testutil/JobHelper.java @@ -6,121 +6,118 @@ import hudson.matrix.MatrixProject; import hudson.matrix.NoopMatrixConfigurationSorter; import hudson.matrix.TextAxis; -import hudson.model.BuildListener; import hudson.model.AbstractBuild; +import hudson.model.BuildListener; import hudson.model.Cause; import hudson.model.FreeStyleProject; import hudson.tasks.Builder; - import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; - import jenkins.model.Jenkins; - import org.jvnet.hudson.test.JenkinsRule; public class JobHelper { - private final static Logger LOGGER = Logger.getLogger(JobHelper.class.getName()); - private final static int DEFAULT_QUIET_PERIOD = 0; - - public JenkinsRule j; - - public JobHelper(JenkinsRule j) { - this.j = j; - } - - static class TestBuilder extends Builder { - - private int sleepTime; - - public TestBuilder(int sleepTime) { - this.sleepTime = sleepTime; - } - - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) - throws InterruptedException, IOException { - LOGGER.info("Building: " + build.getParent().getName()); - Thread.sleep(sleepTime); - return true; - } - } - - public FreeStyleProject createProject(String name) throws Exception { - FreeStyleProject project = j.createFreeStyleProject(name); - project.getBuildersList().add(new TestBuilder(100)); - return project; - } - - public List createProjects(int numberOfProjects) throws Exception { - List projects = new ArrayList(numberOfProjects); - for (int i = 0; i < numberOfProjects; i++) { - FreeStyleProject project = j.createFreeStyleProject("Job " + i); - project.getBuildersList().add(new TestBuilder(100)); - projects.add(project); - } - return projects; - } - - private MatrixProject createMatrixProject(String name) throws IOException { - MatrixProject p = j.createProject(MatrixProject.class, name); - return p; - } - - public List createMatrixProjects(int numberOfProjects) throws Exception { - List projects = new ArrayList(numberOfProjects); - for (int i = 0; i < numberOfProjects; i++) { - MatrixProject project = createMatrixProject("Matrix " + i); - project.getBuildersList().add(new TestBuilder(100)); - AxisList axes = new AxisList(); - axes.add(new TextAxis(i + "A1", i + "A2", i + "A3")); - project.setAxes(axes); - DefaultMatrixExecutionStrategyImpl executionStrategy = (DefaultMatrixExecutionStrategyImpl) project.getExecutionStrategy(); - executionStrategy.setSorter(new NoopMatrixConfigurationSorter()); - project.setExecutionStrategy(executionStrategy); - projects.add(project); - } - return projects; - } - - public JobHelper scheduleMatrixProjects(Cause... causes) throws Exception { - List projects = createMatrixProjects(causes.length); - // Scheduling executors is zero - for (int i = 0; i < causes.length; i++) { - projects.get(i).scheduleBuild(DEFAULT_QUIET_PERIOD, causes[i]); - Thread.sleep(100); - } - return this; - } - - public JobHelper scheduleProject(String name, Cause cause) throws Exception { - FreeStyleProject project = createProject(name); - // Scheduling executors is zero - project.scheduleBuild(DEFAULT_QUIET_PERIOD, cause); - Thread.sleep(100); - return this; - } - - public JobHelper scheduleProjects(Cause... causes) throws Exception { - return scheduleProjects(DEFAULT_QUIET_PERIOD, causes); - } - - public JobHelper scheduleProjects(int quietPeriod, Cause... causes) throws Exception { - List projects = createProjects(causes.length); - // Scheduling executors is zero - for (int i = 0; i < causes.length; i++) { - projects.get(i).scheduleBuild(quietPeriod, causes[i]); - Thread.sleep(100); - } - return this; - } - - public void go() throws Exception { - // Set the executors to one and restart - Jenkins.get().setNumExecutors(1); - } - + private static final Logger LOGGER = Logger.getLogger(JobHelper.class.getName()); + private static final int DEFAULT_QUIET_PERIOD = 0; + + public JenkinsRule j; + + public JobHelper(JenkinsRule j) { + this.j = j; + } + + static class TestBuilder extends Builder { + + private int sleepTime; + + public TestBuilder(int sleepTime) { + this.sleepTime = sleepTime; + } + + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) + throws InterruptedException, IOException { + LOGGER.info("Building: " + build.getParent().getName()); + Thread.sleep(sleepTime); + return true; + } + } + + public FreeStyleProject createProject(String name) throws Exception { + FreeStyleProject project = j.createFreeStyleProject(name); + project.getBuildersList().add(new TestBuilder(100)); + return project; + } + + public List createProjects(int numberOfProjects) throws Exception { + List projects = new ArrayList(numberOfProjects); + for (int i = 0; i < numberOfProjects; i++) { + FreeStyleProject project = j.createFreeStyleProject("Job " + i); + project.getBuildersList().add(new TestBuilder(100)); + projects.add(project); + } + return projects; + } + + private MatrixProject createMatrixProject(String name) throws IOException { + MatrixProject p = j.createProject(MatrixProject.class, name); + return p; + } + + public List createMatrixProjects(int numberOfProjects) throws Exception { + List projects = new ArrayList(numberOfProjects); + for (int i = 0; i < numberOfProjects; i++) { + MatrixProject project = createMatrixProject("Matrix " + i); + project.getBuildersList().add(new TestBuilder(100)); + AxisList axes = new AxisList(); + axes.add(new TextAxis(i + "A1", i + "A2", i + "A3")); + project.setAxes(axes); + DefaultMatrixExecutionStrategyImpl executionStrategy = + (DefaultMatrixExecutionStrategyImpl) project.getExecutionStrategy(); + executionStrategy.setSorter(new NoopMatrixConfigurationSorter()); + project.setExecutionStrategy(executionStrategy); + projects.add(project); + } + return projects; + } + + public JobHelper scheduleMatrixProjects(Cause... causes) throws Exception { + List projects = createMatrixProjects(causes.length); + // Scheduling executors is zero + for (int i = 0; i < causes.length; i++) { + projects.get(i).scheduleBuild(DEFAULT_QUIET_PERIOD, causes[i]); + Thread.sleep(100); + } + return this; + } + + public JobHelper scheduleProject(String name, Cause cause) throws Exception { + FreeStyleProject project = createProject(name); + // Scheduling executors is zero + project.scheduleBuild(DEFAULT_QUIET_PERIOD, cause); + Thread.sleep(100); + return this; + } + + public JobHelper scheduleProjects(Cause... causes) throws Exception { + return scheduleProjects(DEFAULT_QUIET_PERIOD, causes); + } + + public JobHelper scheduleProjects(int quietPeriod, Cause... causes) throws Exception { + List projects = createProjects(causes.length); + // Scheduling executors is zero + for (int i = 0; i < causes.length; i++) { + projects.get(i).scheduleBuild(quietPeriod, causes[i]); + Thread.sleep(100); + } + return this; + } + + public void go() throws Exception { + // Set the executors to one and restart + Jenkins.get().setNumExecutors(1); + } } diff --git a/src/test/java/jenkins/advancedqueue/testutil/TestRunListener.java b/src/test/java/jenkins/advancedqueue/testutil/TestRunListener.java index 4354f5ee..d3dfeea7 100644 --- a/src/test/java/jenkins/advancedqueue/testutil/TestRunListener.java +++ b/src/test/java/jenkins/advancedqueue/testutil/TestRunListener.java @@ -1,53 +1,53 @@ package jenkins.advancedqueue.testutil; import hudson.Extension; -import hudson.model.TaskListener; import hudson.model.Run; +import hudson.model.TaskListener; import hudson.model.listeners.RunListener; - import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - import jenkins.advancedqueue.sorter.ItemInfo; import jenkins.advancedqueue.sorter.QueueItemCache; - import org.junit.Assert; @Extension public class TestRunListener extends RunListener { - private final static Logger LOGGER = Logger.getLogger(TestRunListener.class.getName()); - - static private List actual; - static private ExpectedItem[] expected; - - static public void init(ExpectedItem... expected) { - TestRunListener.expected = expected; - actual = new ArrayList(expected.length); - } - - @Override - public void onStarted(Run r, TaskListener listener) { - LOGGER.info("ON STARTED: " + r.getParent().getName()); - try { - ItemInfo item = QueueItemCache.get().getItem(r.getParent().getName()); - actual.add(item); - } catch (Throwable e) { - LOGGER.log(Level.INFO, "###########", e); - } - } - - static public void assertStartedItems() { - Assert.assertEquals("Wrong number of started items", expected.length, actual.size()); - for (int i = 0; i < actual.size(); i++) { - LOGGER.info("Validating Build " + i); - Assert.assertTrue("Job mismatch at position [" + i + "] expected <" + expected[i].getJobName() + "> was <" - + actual.get(i).getJobName() + ">", actual.get(i).getJobName().matches(expected[i].getJobName())); - Assert.assertEquals("Priority mismatch at position [" + i + "]", expected[i].getPriority(), actual.get(i) - .getPriority()); - } - } - + private static final Logger LOGGER = Logger.getLogger(TestRunListener.class.getName()); + + private static List actual; + private static ExpectedItem[] expected; + + public static void init(ExpectedItem... expected) { + TestRunListener.expected = expected; + actual = new ArrayList(expected.length); + } + + @Override + public void onStarted(Run r, TaskListener listener) { + LOGGER.info("ON STARTED: " + r.getParent().getName()); + try { + ItemInfo item = QueueItemCache.get().getItem(r.getParent().getName()); + actual.add(item); + } catch (Throwable e) { + LOGGER.log(Level.INFO, "###########", e); + } + } + + public static void assertStartedItems() { + Assert.assertEquals("Wrong number of started items", expected.length, actual.size()); + for (int i = 0; i < actual.size(); i++) { + LOGGER.info("Validating Build " + i); + Assert.assertTrue( + "Job mismatch at position [" + i + "] expected <" + expected[i].getJobName() + "> was <" + + actual.get(i).getJobName() + ">", + actual.get(i).getJobName().matches(expected[i].getJobName())); + Assert.assertEquals( + "Priority mismatch at position [" + i + "]", + expected[i].getPriority(), + actual.get(i).getPriority()); + } + } }