Skip to content

Commit 1b5aed9

Browse files
committed
when locking resources about to be unlocked, honor the requested quantity
1 parent b7182cd commit 1b5aed9

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/main/java/org/jenkins/plugins/lockableresources/LockableResourcesManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ public synchronized Set<LockableResource> checkResourcesAvailability(List<Lockab
671671

672672
for (Map.Entry<List<LockableResource>, Integer> entry : allCandidates.entrySet()) {
673673
List<LockableResource> candidates = entry.getKey();
674+
int requiredAmount = entry.getValue();
674675

675676
// start with an empty set of selected resources
676677
List<LockableResource> selected = new ArrayList<LockableResource>();
@@ -679,6 +680,9 @@ public synchronized Set<LockableResource> checkResourcesAvailability(List<Lockab
679680
// Determine if these resources can be reused
680681
if (lockedResourcesAboutToBeUnlocked != null) {
681682
for (LockableResource candidate : candidates) {
683+
if (selected.size() >= requiredAmount) {
684+
break;
685+
}
682686
if (lockedResourcesAboutToBeUnlocked.contains(candidate.getName())) {
683687
selected.add(candidate);
684688
}

src/test/java/org/jenkins/plugins/lockableresources/LockStepTest.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,63 @@ public void evaluate() throws Throwable {
189189
});
190190
}
191191

192+
@Test
193+
public void lockOrderLabelQuantityFreedResources() {
194+
story.addStep(new Statement() {
195+
@Override
196+
public void evaluate() throws Throwable {
197+
LockableResourcesManager.get().createResourceWithLabel("resource1", "label1");
198+
LockableResourcesManager.get().createResourceWithLabel("resource2", "label1");
199+
LockableResourcesManager.get().createResourceWithLabel("resource3", "label1");
200+
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p");
201+
p.setDefinition(new CpsFlowDefinition(
202+
"lock(label: 'label1') {\n" +
203+
" semaphore 'wait-inside'\n" +
204+
"}\n" +
205+
"echo 'Finish'"
206+
));
207+
WorkflowRun b1 = p.scheduleBuild2(0).waitForStart();
208+
SemaphoreStep.waitForStart("wait-inside/1", b1);
209+
210+
WorkflowJob p2 = story.j.jenkins.createProject(WorkflowJob.class, "p2");
211+
p2.setDefinition(new CpsFlowDefinition(
212+
"lock(label: 'label1', quantity: 2) {\n" +
213+
" semaphore 'wait-inside-quantity2'\n" +
214+
"}\n" +
215+
"echo 'Finish'"
216+
));
217+
WorkflowRun b2 = p2.scheduleBuild2(0).waitForStart();
218+
// Ensure that b2 reaches the lock before b3
219+
story.j.waitForMessage("[Label: label1, Quantity: 2] is locked, waiting...", b2);
220+
story.j.waitForMessage("Found 0 available resource(s). Waiting for correct amount: 2.", b2);
221+
222+
WorkflowJob p3 = story.j.jenkins.createProject(WorkflowJob.class, "p3");
223+
p3.setDefinition(new CpsFlowDefinition(
224+
"lock(label: 'label1', quantity: 1) {\n" +
225+
" semaphore 'wait-inside-quantity1'\n" +
226+
"}\n" +
227+
"echo 'Finish'"
228+
));
229+
WorkflowRun b3 = p3.scheduleBuild2(0).waitForStart();
230+
story.j.waitForMessage("[Label: label1, Quantity: 1] is locked, waiting...", b3);
231+
story.j.waitForMessage("Found 0 available resource(s). Waiting for correct amount: 1.", b3);
232+
233+
// Unlock Label: label1
234+
SemaphoreStep.success("wait-inside/1", null);
235+
story.j.waitForMessage("Lock released on resource [Label: label1]", b1);
236+
237+
// Both get their lock
238+
story.j.waitForMessage("Lock acquired on [Label: label1, Quantity: 2]", b2);
239+
story.j.waitForMessage("Lock acquired on [Label: label1, Quantity: 1]", b3);
240+
241+
SemaphoreStep.success("wait-inside-quantity2/1", null);
242+
SemaphoreStep.success("wait-inside-quantity1/1", null);
243+
story.j.waitForMessage("Finish", b2);
244+
story.j.waitForMessage("Finish", b3);
245+
}
246+
});
247+
}
248+
192249
@Test
193250
public void lockOrder() {
194251
story.addStep(new Statement() {

0 commit comments

Comments
 (0)