Skip to content

Commit 84c7f20

Browse files
authored
Add ability to run several cron expressions at the same time (#105)
* Add ability to run several cron expressions at the same time * Fix test ordering issue Co-authored-by: res0nance <[email protected]>
1 parent e5793de commit 84c7f20

5 files changed

Lines changed: 67 additions & 37 deletions

File tree

src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabList.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.ArrayList;
77
import java.util.Calendar;
88
import java.util.List;
9+
import java.util.stream.Collectors;
910

1011
import antlr.ANTLRException;
1112

@@ -52,12 +53,8 @@ public static ParameterizedCronTabList create(String cronTabSpecification, Hash
5253
return new ParameterizedCronTabList(result);
5354
}
5455

55-
public ParameterizedCronTab check(Calendar calendar) {
56-
for (ParameterizedCronTab tab : cronTabs) {
57-
if (tab.check(calendar))
58-
return tab;
59-
}
60-
return null;
56+
public List<ParameterizedCronTab> check(Calendar calendar) {
57+
return cronTabs.stream().filter(tab -> tab.check(calendar)).collect(Collectors.toList());
6158
}
6259

6360
public String checkSanity() {

src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedTimerTrigger.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ private List<ParameterValue> configurePropertyValues(Map<String, String> paramet
7878

7979
public void checkCronTabsAndRun(Calendar calendar) {
8080
LOGGER.fine("checking and maybe running at " + calendar);
81-
ParameterizedCronTab cronTab = cronTabList.check(calendar);
81+
List<ParameterizedCronTab> cronTabs = cronTabList.check(calendar);
8282

83-
if (cronTab != null) {
83+
cronTabs.forEach(cronTab -> {
8484
Map<String, String> parameterValues = cronTab.getParameterValues();
8585
ParametersAction parametersAction = new ParametersAction(configurePropertyValues(parameterValues));
8686
assert job != null : "job must not be null, if this was 'started'";
@@ -89,7 +89,7 @@ public void checkCronTabsAndRun(Calendar calendar) {
8989
} else if (job instanceof WorkflowJob) {
9090
((WorkflowJob) job).scheduleBuild2(0, causeAction(parameterValues), parametersAction);
9191
}
92-
}
92+
});
9393
}
9494

9595
private CauseAction causeAction(Map<String, String> parameterValues) {

src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabListTest.java

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package org.jenkinsci.plugins.parameterizedscheduler;
22

3+
import static org.hamcrest.MatcherAssert.assertThat;
4+
import static org.hamcrest.Matchers.empty;
5+
import static org.hamcrest.Matchers.is;
36
import static org.junit.Assert.assertEquals;
4-
import static org.junit.Assert.assertNotNull;
57
import static org.junit.Assert.assertNull;
68
import static org.junit.Assert.assertSame;
79
import static org.junit.Assert.assertTrue;
810

911
import java.util.Arrays;
1012
import java.util.Collections;
1113
import java.util.GregorianCalendar;
14+
import java.util.List;
1215
import java.util.Map;
1316

1417
import antlr.ANTLRException;
@@ -29,44 +32,59 @@ public class ParameterizedCronTabListTest {
2932
public void create() throws Exception {
3033
ParameterizedCronTabList testObject = ParameterizedCronTabList.create("* * * * *%foo=bar");
3134
assertTrue(testObject.checkSanity(), testObject.checkSanity().startsWith("Do you really mean \"every minute\""));
32-
ParameterizedCronTab actualCronTab = testObject.check(new GregorianCalendar());
33-
assertNotNull(actualCronTab);
35+
List<ParameterizedCronTab> actualCronTabs = testObject.check(new GregorianCalendar());
36+
assertThat(actualCronTabs.size(), is(1));
37+
assertEquals(Collections.singletonMap("foo", "bar"), actualCronTabs.get(0).getParameterValues());
38+
}
3439

35-
assertEquals(Collections.singletonMap("foo", "bar"), actualCronTab.getParameterValues());
40+
@Test
41+
public void createMultiple() throws Exception {
42+
ParameterizedCronTabList testObject = ParameterizedCronTabList.create("* * * * *%foo=bar\n*/1 * * * *%bar=bar");
43+
assertTrue(testObject.checkSanity(), testObject.checkSanity().startsWith("Do you really mean \"every minute\""));
44+
List<ParameterizedCronTab> actualCronTabs = testObject.check(new GregorianCalendar());
45+
assertThat(actualCronTabs.size(), is(2));
46+
assertEquals(Collections.singletonMap("foo", "bar"), actualCronTabs.get(0).getParameterValues());
47+
assertEquals(Collections.singletonMap("bar", "bar"), actualCronTabs.get(1).getParameterValues());
3648
}
3749

3850
@Test
3951
public void check_Delegates_ReturnsNull() {
4052
ParameterizedCronTabList testObject = new ParameterizedCronTabList(Arrays.asList(mockParameterizedCronTab,
4153
mockParameterizedCronTabToo));
4254
GregorianCalendar testCalendar = new GregorianCalendar();
43-
44-
assertNull(testObject.check(testCalendar));
55+
List<ParameterizedCronTab> tabList = testObject.check(testCalendar);
56+
assertThat(tabList, is(empty()));
4557

4658
Mockito.verify(mockParameterizedCronTab).check(testCalendar);
4759
Mockito.verify(mockParameterizedCronTabToo).check(testCalendar);
4860
}
4961

5062
@Test
51-
public void check_Delegates_ReturnsSame_EarlyExit() {
63+
public void check_Delegates_ReturnsSame() {
5264
ParameterizedCronTabList testObject = new ParameterizedCronTabList(Arrays.asList(mockParameterizedCronTab,
5365
mockParameterizedCronTabToo));
5466
GregorianCalendar testCalendar = new GregorianCalendar();
5567

5668
Mockito.when(mockParameterizedCronTab.check(testCalendar)).thenReturn(true);
57-
assertSame(mockParameterizedCronTab, testObject.check(testCalendar));
58-
59-
Mockito.verifyNoInteractions(mockParameterizedCronTabToo);
69+
Mockito.when(mockParameterizedCronTabToo.check(testCalendar)).thenReturn(false);
70+
List<ParameterizedCronTab> tabList = testObject.check(testCalendar);
71+
assertThat(tabList.size(), is(1));
72+
assertSame(mockParameterizedCronTab, tabList.get(0));
6073
}
6174

6275
@Test
63-
public void check_Delegates_ReturnsSame() {
76+
public void check_Delegates_ReturnsBoth() {
6477
ParameterizedCronTabList testObject = new ParameterizedCronTabList(Arrays.asList(mockParameterizedCronTab,
6578
mockParameterizedCronTabToo));
6679
GregorianCalendar testCalendar = new GregorianCalendar();
6780

81+
Mockito.when(mockParameterizedCronTab.check(testCalendar)).thenReturn(true);
6882
Mockito.when(mockParameterizedCronTabToo.check(testCalendar)).thenReturn(true);
69-
assertSame(mockParameterizedCronTabToo, testObject.check(testCalendar));
83+
List<ParameterizedCronTab> tabList = testObject.check(testCalendar);
84+
assertThat(tabList.size(), is(2));
85+
86+
assertSame(mockParameterizedCronTab, tabList.get(0));
87+
assertSame(mockParameterizedCronTabToo, tabList.get(1));
7088
}
7189

7290
@Test
@@ -106,11 +124,11 @@ public void checkSanity_Delegates_ReturnsSame() {
106124
public void create_with_timezone() throws Exception {
107125
ParameterizedCronTabList testObject = ParameterizedCronTabList.create("TZ=Australia/Sydney \n * * * * *%foo=bar");
108126
assertTrue(testObject.checkSanity(), testObject.checkSanity().startsWith("Do you really mean \"every minute\""));
109-
ParameterizedCronTab actualCronTab = testObject.check(new GregorianCalendar());
110-
assertNotNull(actualCronTab);
127+
List<ParameterizedCronTab> actualCronTabs = testObject.check(new GregorianCalendar());
128+
assertThat(actualCronTabs.size(), is(1));
111129

112130
Map<String, String> expected = Collections.singletonMap("foo", "bar");
113-
assertEquals(expected, actualCronTab.getParameterValues());
131+
assertEquals(expected, actualCronTabs.get(0).getParameterValues());
114132
}
115133

116134
@Test(expected = ANTLRException.class)

src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabTest.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,15 @@ public void param_value_with_percent_sign() throws Exception {
4949
Map<String, String> parameters = Maps.newHashMap();
5050
parameters.put("one", "onevalue");
5151
parameters.put("two", "10%");
52-
CronTab testCronTab = new CronTab("* * * * *");
53-
ParameterizedCronTab testObject = new ParameterizedCronTab(testCronTab, parameters);
5452

5553
ParameterizedCronTab parameterizedCronTab = ParameterizedCronTab.create(line, 1, Hash.from(line), null);
5654
assertEquals(parameters, parameterizedCronTab.getParameterValues());
57-
5855
}
5956

6057
@Test
6158
public void with_no_params_separator() throws Exception {
6259
String line = "* * * * *";
6360
Map<String, String> parameters = Maps.newHashMap();
64-
CronTab testCronTab = new CronTab("* * * * *");
65-
ParameterizedCronTab testObject = new ParameterizedCronTab(testCronTab, parameters);
6661
ParameterizedCronTab parameterizedCronTab = ParameterizedCronTab.create(line, 1, Hash.from(line), null);
6762
assertEquals(parameters, parameterizedCronTab.getParameterValues());
6863
}

src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedSchedulerTest.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121
import javax.annotation.CheckForNull;
2222
import javax.annotation.Nonnull;
2323

24+
import java.util.ArrayList;
25+
import java.util.List;
26+
2427
import static org.hamcrest.MatcherAssert.assertThat;
28+
import static org.hamcrest.Matchers.containsInAnyOrder;
2529
import static org.hamcrest.Matchers.is;
2630
import static org.hamcrest.Matchers.not;
2731
import static org.hamcrest.Matchers.notNullValue;
@@ -37,14 +41,18 @@ public void freestyle() throws Exception {
3741
FreeStyleProject p = r.createFreeStyleProject();
3842
p.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("foo", "lol")));
3943
assertThat(p.getLastCompletedBuild(), is(nullValue()));
40-
Trigger<Job> t = new ParameterizedTimerTrigger("* * * * *%foo=bar");
44+
Trigger<Job> t = new ParameterizedTimerTrigger("* * * * *%foo=bar\n*/1 * * * *%foo=boo");
4145
t.start(p, true);
4246
p.addTrigger(t);
4347
new Cron().doRun();
4448
assertThat(p.isInQueue(), is(true));
4549
r.waitUntilNoActivity();
4650
assertThat(p.getLastCompletedBuild(), is(notNullValue()));
47-
assertThat((String) p.getLastCompletedBuild().getAction(ParametersAction.class).getParameter("foo").getValue(), is("bar"));
51+
List<String> values = new ArrayList<>();
52+
for (int i = 1; i < 3; ++i) {
53+
values.add((String) p.getBuildByNumber(i).getAction(ParametersAction.class).getParameter("foo").getValue());
54+
}
55+
assertThat(values, containsInAnyOrder("bar", "boo"));
4856
}
4957

5058
@Test
@@ -53,13 +61,17 @@ public void pipeline() throws Exception {
5361
p.setDefinition(new CpsFlowDefinition("", true));
5462
WorkflowRun wfr = p.scheduleBuild2(0).get();
5563
p.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("foo", "lol")));
56-
Trigger<Job> t = new ParameterizedTimerTrigger("* * * * *%foo=bar");
64+
Trigger<Job> t = new ParameterizedTimerTrigger("* * * * *%foo=bar\n*/1 * * * *%foo=boo");
5765
t.start(p, true);
5866
p.addTrigger(t);
5967
new Cron().doRun();
6068
r.waitUntilNoActivity();
6169
assertThat(p.getLastCompletedBuild(), is(not(wfr)));
62-
assertThat((String) p.getLastCompletedBuild().getAction(ParametersAction.class).getParameter("foo").getValue(), is("bar"));
70+
List<String> values = new ArrayList<>();
71+
for (int i = 2; i < 4; ++i) {
72+
values.add((String) p.getBuildByNumber(i).getAction(ParametersAction.class).getParameter("foo").getValue());
73+
}
74+
assertThat(values, containsInAnyOrder("bar", "boo"));
6375
}
6476

6577
@Test
@@ -70,14 +82,18 @@ public void scripted() throws Exception {
7082
" string(name: 'foo', defaultValue: 'lol')\n" +
7183
" ]),\n" +
7284
" pipelineTriggers([\n" +
73-
" parameterizedCron('* * * * *%foo=bar')\n" +
85+
" parameterizedCron('* * * * *%foo=bar\\n*/1 * * * *%foo=boo')\n" +
7486
" ])\n" +
7587
"])", true));
7688
WorkflowRun wfr = r.buildAndAssertSuccess(p);
7789
new Cron().doRun();
7890
r.waitUntilNoActivity();
7991
assertThat(p.getLastCompletedBuild(), is(not(wfr)));
80-
assertThat((String) p.getLastCompletedBuild().getAction(ParametersAction.class).getParameter("foo").getValue(), is("bar"));
92+
List<String> values = new ArrayList<>();
93+
for (int i = 2; i < 4; ++i) {
94+
values.add((String) p.getBuildByNumber(i).getAction(ParametersAction.class).getParameter("foo").getValue());
95+
}
96+
assertThat(values, containsInAnyOrder("bar", "boo"));
8197
}
8298

8399
@Test
@@ -89,7 +105,7 @@ public void declarative() throws Exception {
89105
" string(name: 'foo', defaultValue: 'lol')\n" +
90106
" }\n" +
91107
" triggers {\n" +
92-
" parameterizedCron('* * * * *%foo=bar')\n" +
108+
" parameterizedCron('* * * * *%foo=bar\\n*/1 * * * *%foo=boo')\n" +
93109
" }\n" +
94110
" stages {\n" +
95111
" stage('Test') {\n" +
@@ -103,7 +119,11 @@ public void declarative() throws Exception {
103119
new Cron().doRun();
104120
r.waitUntilNoActivity();
105121
assertThat(p.getLastCompletedBuild(), is(not(wfr)));
106-
assertThat((String) p.getLastCompletedBuild().getAction(ParametersAction.class).getParameter("foo").getValue(), is("bar"));
122+
List<String> values = new ArrayList<>();
123+
for (int i = 2; i < 4; ++i) {
124+
values.add((String) p.getBuildByNumber(i).getAction(ParametersAction.class).getParameter("foo").getValue());
125+
}
126+
assertThat(values, containsInAnyOrder("bar", "boo"));
107127
}
108128

109129
@Test

0 commit comments

Comments
 (0)