1 package com.atlassian.scheduler.core.util;
2
3 import org.junit.Test;
4
5 import java.util.regex.Matcher;
6 import java.util.regex.Pattern;
7
8 import static com.atlassian.scheduler.core.util.CronExpressionQuantizer.Randomize.ALWAYS;
9 import static com.atlassian.scheduler.core.util.CronExpressionQuantizer.Randomize.AS_NEEDED;
10 import static com.atlassian.scheduler.core.util.CronExpressionQuantizer.Randomize.NEVER;
11 import static com.atlassian.scheduler.core.util.CronExpressionQuantizer.quantizeSecondsField;
12 import static org.hamcrest.Matchers.equalTo;
13 import static org.junit.Assert.assertThat;
14 import static org.junit.Assert.fail;
15
16
17
18
19 @SuppressWarnings("ConstantConditions")
20 public class CronExpressionQuantizerTest {
21 private static final Pattern SIMPLE_SECONDS_FIELD = Pattern.compile("^([1-5]?\\d) (.*)$");
22
23
24 private static final int ATTEMPTS = 100;
25
26 @Test
27 public void testNullOrIncompleteExpression() {
28 verifyNullOrIncompleteExpression(null);
29 verifyNullOrIncompleteExpression("");
30 verifyNullOrIncompleteExpression("0");
31 verifyNullOrIncompleteExpression("a");
32 verifyNullOrIncompleteExpression("*");
33 verifyNullOrIncompleteExpression("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
34 }
35
36 @Test
37 public void testRandomizedNever() {
38 assertZeroed("x * * * * ?", NEVER);
39 assertZeroed("0 * * * * ?", NEVER);
40 assertNoChange("42 * * * * ?", NEVER);
41 assertZeroed("60 * * * * ?", NEVER);
42 assertZeroed("*/5 * * * * ?", NEVER);
43 assertZeroed("7,12 * * * * ?", NEVER);
44 assertZeroed("x * * * * ?", NEVER);
45 assertZeroed("a b c", NEVER);
46 }
47
48 @Test
49 public void testRandomizedAsNeededByNullArgument() {
50 assertRandomized("x * * * * ?", null);
51 assertNoChange("0 * * * * ?", null);
52 assertNoChange("42 * * * * ?", null);
53 assertRandomized("60 * * * * ?", null);
54 assertRandomized("*/5 * * * * ?", null);
55 assertRandomized("7,12 * * * * ?", null);
56 assertRandomized("x * * * * ?", null);
57 assertRandomized("a b c", null);
58 }
59
60 @Test
61 public void testRandomizedAsNeededByDefault() {
62 assertRandomized("x * * * * ?");
63 assertNoChange("0 * * * * ?");
64 assertNoChange("42 * * * * ?");
65 assertRandomized("60 * * * * ?");
66 assertRandomized("*/5 * * * * ?");
67 assertRandomized("7,12 * * * * ?");
68 assertRandomized("x * * * * ?");
69 assertRandomized("a b c");
70 }
71
72 @Test
73 public void testRandomizedAsNeeded() {
74 assertRandomized("x * * * * ?", AS_NEEDED);
75 assertZeroed("0 * * * * ?", AS_NEEDED);
76 assertNoChange("42 * * * * ?", AS_NEEDED);
77 assertRandomized("60 * * * * ?", AS_NEEDED);
78 assertRandomized("*/5 * * * * ?", AS_NEEDED);
79 assertRandomized("7,12 * * * * ?", AS_NEEDED);
80 assertRandomized("x * * * * ?", AS_NEEDED);
81 assertRandomized("a b c", AS_NEEDED);
82 }
83
84 @Test
85 public void testRandomizedAlways() {
86 assertRandomized("x * * * * ?", ALWAYS);
87 assertRandomized("0 * * * * ?", ALWAYS);
88 assertRandomized("42 * * * * ?", ALWAYS);
89 assertRandomized("60 * * * * ?", ALWAYS);
90 assertRandomized("*/5 * * * * ?", ALWAYS);
91 assertRandomized("7,12 * * * * ?", ALWAYS);
92 assertRandomized("x * * * * ?", ALWAYS);
93 assertRandomized("a b c", ALWAYS);
94 }
95
96
97 private static void verifyNullOrIncompleteExpression(final String cronExpression) {
98 assertNoChange(cronExpression, null);
99 assertNoChange(cronExpression, NEVER);
100 assertNoChange(cronExpression, AS_NEEDED);
101 assertNoChange(cronExpression, ALWAYS);
102 }
103
104 private static void assertRandomized(final String cronExpression) {
105 String s = null;
106 final String expectedRest = cronExpression.substring(cronExpression.indexOf(' ') + 1);
107 for (int i = 0; i < ATTEMPTS; ++i) {
108 s = quantizeSecondsField(cronExpression);
109 if (looksRandomized(expectedRest, s)) {
110 return;
111 }
112 }
113 fail("Did not get a randomized seconds field using cron expression '" + cronExpression +
114 "' with randomize=unspecified (should default to AS_NEEDED); last result was: '" + s + '\'');
115 }
116
117 private static void assertRandomized(final String cronExpression, final CronExpressionQuantizer.Randomize randomize) {
118 String s = null;
119 final String expectedRest = cronExpression.substring(cronExpression.indexOf(' ') + 1);
120 for (int i = 0; i < ATTEMPTS; ++i) {
121 s = quantizeSecondsField(cronExpression, randomize);
122 if (looksRandomized(expectedRest, s)) {
123 return;
124 }
125 }
126 fail("Did not get a randomized seconds field using cron expression '" + cronExpression +
127 "' with randomize=" + randomize + "; last result was: '" + s + '\'');
128 }
129
130 private static boolean looksRandomized(String expectedRest, String cronExpression) {
131 final Matcher matcher = SIMPLE_SECONDS_FIELD.matcher(cronExpression);
132 if (!matcher.find() || !expectedRest.equals(matcher.group(2))) {
133 return false;
134 }
135 final int seconds = Integer.parseInt(matcher.group(1));
136 return seconds > 0 && seconds <= 59 && seconds != 42;
137 }
138
139 private static void assertZeroed(final String cronExpression, final CronExpressionQuantizer.Randomize randomize) {
140 final String expectedRest = cronExpression.substring(cronExpression.indexOf(' ') + 1);
141 for (int i = 0; i < ATTEMPTS; ++i) {
142 final String s = quantizeSecondsField(cronExpression, randomize);
143 if (!looksZeroed(expectedRest, s)) {
144 fail("Did not get a zeroed seconds field using cron expression '" + cronExpression +
145 "' with randomize=" + randomize + "; attempt i=" + i + " result was: '" + s + '\'');
146 }
147 }
148 }
149
150 private static boolean looksZeroed(String expectedRest, String cronExpression) {
151 final Matcher matcher = SIMPLE_SECONDS_FIELD.matcher(cronExpression);
152 return matcher.find() && "0".equals(matcher.group(1)) && expectedRest.equals(matcher.group(2));
153 }
154
155
156 private static void assertNoChange(final String cronExpression) {
157 for (int i = 0; i < ATTEMPTS; ++i) {
158 assertThat(quantizeSecondsField(cronExpression), equalTo(cronExpression));
159 }
160 }
161
162 private static void assertNoChange(final String cronExpression, final CronExpressionQuantizer.Randomize randomize) {
163 for (int i = 0; i < ATTEMPTS; ++i) {
164 assertThat(quantizeSecondsField(cronExpression, randomize), equalTo(cronExpression));
165 }
166 }
167 }