From 4459da7db7bca4d5e7cea899ba65a3202dd2ecd4 Mon Sep 17 00:00:00 2001 From: monluk <82778113+monluk@users.noreply.github.com> Date: Mon, 11 Dec 2023 21:03:21 +0100 Subject: [PATCH] [JENKINS-69751] Add sorting for blocked projects (#69) * Add sorting for blocked projects * [JENKINS-69751]: Wrote a test for AdvancedQueueSorter.sortBlockedItems(List blockedItems) * Format sources before merge with master * Format source files before merge * Remove unused imports * Do not lose icon impl * Do not lose spotbugs exclusions --------- Co-authored-by: Mark Waite Co-authored-by: Simon Sohrt --- .../sorter/AdvancedQueueSorter.java | 28 +++++++---- .../test/SortBlockedItemsTest.java | 47 +++++++++++++++++++ ...ns.advancedqueue.PriorityConfiguration.xml | 27 +++++++++++ ...ancedqueue.PrioritySorterConfiguration.xml | 8 ++++ 4 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 src/test/java/jenkins/advancedqueue/test/SortBlockedItemsTest.java create mode 100644 src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PriorityConfiguration.xml create mode 100644 src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PrioritySorterConfiguration.xml diff --git a/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java b/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java index f25ea2bc..dfe810cf 100644 --- a/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java +++ b/src/main/java/jenkins/advancedqueue/sorter/AdvancedQueueSorter.java @@ -69,10 +69,8 @@ public int compare(BuildableItem o1, BuildableItem o2) { LOGGER.info("Initialized the QueueSorter with " + items.size() + " Buildable Items"); } - @Override - public void sortBuildableItems(List items) { - - Collections.sort(items, (BuildableItem o1, BuildableItem o2) -> { + public void sortNotWaitingItems(List items) { + Collections.sort(items, (Comparator) (o1, o2) -> { ItemInfo item1 = QueueItemCache.get().getItem(o1.getId()); ItemInfo item2 = QueueItemCache.get().getItem(o2.getId()); if (item1 == null || item2 == null) { @@ -87,22 +85,22 @@ public void sortBuildableItems(List items) { 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 + LOGGER.log(Level.FINE, "Sorted {0} {1}s with Min Weight {2} and Max Weight {3}", new Object[] { + items.size(), items.get(0).getClass().getName(), minWeight, maxWeight }); } // if (items.size() > 0 && LOGGER.isLoggable(Level.FINER)) { - StringBuilder queueStr = new StringBuilder("Queue:\n" + StringBuilder queueStr = new StringBuilder(items.get(0).getClass().getName()); + queueStr.append(" Queue:\n" + "+----------------------------------------------------------------------+\n" + "| Item Id | Job Name | Priority | Weight |\n" + "+----------------------------------------------------------------------+\n"); - for (BuildableItem item : items) { + for (Queue.NotWaitingItem 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()); + jobName = jobName.substring(0, 9) + "..." + jobName.substring(jobName.length() - 9); } queueStr.append(String.format( "| %10d | %20s | %8d | %20.5f |%n", @@ -113,6 +111,16 @@ public void sortBuildableItems(List items) { } } + @Override + public void sortBuildableItems(List items) { + sortNotWaitingItems(items); + } + + @Override + public void sortBlockedItems(List blockedItems) { + sortNotWaitingItems(blockedItems); + } + public void onNewItem(@NonNull Item item) { final SorterStrategy prioritySorterStrategy = PrioritySorterConfiguration.get().getStrategy(); diff --git a/src/test/java/jenkins/advancedqueue/test/SortBlockedItemsTest.java b/src/test/java/jenkins/advancedqueue/test/SortBlockedItemsTest.java new file mode 100644 index 00000000..ed3d97d1 --- /dev/null +++ b/src/test/java/jenkins/advancedqueue/test/SortBlockedItemsTest.java @@ -0,0 +1,47 @@ +package jenkins.advancedqueue.test; + +import hudson.model.FreeStyleProject; +import hudson.model.Queue; +import hudson.tasks.BuildTrigger; +import jenkins.advancedqueue.testutil.ExpectedItem; +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; + +public class SortBlockedItemsTest { + + @Rule + public JenkinsRule j = new JenkinsRule(); + + @Test + @LocalData + public void blockedItemsAreSortedByPriority() throws Exception { + // Priority value is configured in jenkins.advancedqueue.PrioritySorterConfiguration. Value is 2. + FreeStyleProject upstreamProject = j.createFreeStyleProject("upstreamProject"); + // Priority value is configured in jenkins.advancedqueue.PrioritySorterConfiguration. Value is 1. + FreeStyleProject downstreamProject = j.createFreeStyleProject("downstreamProject"); + upstreamProject.setBlockBuildWhenDownstreamBuilding(true); + downstreamProject.setBlockBuildWhenUpstreamBuilding(true); + upstreamProject.getPublishersList().add(new BuildTrigger(downstreamProject.getName(), true)); + // Expected build sequence: downstreamProject#1 -> upstreamProject#1 -> downstreamProject#2 + TestRunListener.init( + new ExpectedItem(downstreamProject.getName(), 1), + new ExpectedItem(upstreamProject.getName(), 2), + new ExpectedItem(downstreamProject.getName(), 1)); + + j.jenkins.rebuildDependencyGraph(); + + // Locking makes sure that the queue sees both builds at the same time even though upstreamProject entered the + // queue first + Queue.withLock(() -> { + j.jenkins.getQueue().schedule2(upstreamProject, 0); + j.jenkins.getQueue().schedule2(downstreamProject, 0); + j.jenkins.getQueue().maintain(); + }); + j.waitUntilNoActivity(); + + TestRunListener.assertStartedItems(); + } +} diff --git a/src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PriorityConfiguration.xml b/src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PriorityConfiguration.xml new file mode 100644 index 00000000..d1a28e69 --- /dev/null +++ b/src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PriorityConfiguration.xml @@ -0,0 +1,27 @@ + + + + + 0 + 2 + All + false + true + upstreamProject + false + + + + + 1 + 1 + All + false + true + downstreamProject + false + + + + + \ No newline at end of file diff --git a/src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PrioritySorterConfiguration.xml b/src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PrioritySorterConfiguration.xml new file mode 100644 index 00000000..d4e20a42 --- /dev/null +++ b/src/test/resources/jenkins/advancedqueue/test/SortBlockedItemsTest/jenkins.advancedqueue.PrioritySorterConfiguration.xml @@ -0,0 +1,8 @@ + + + true + > + 2 + 1 + + \ No newline at end of file