Browse Source

Watcher: Improve error messages for CronEvalTool (#32800)

CronEvalTool prints an error only for cron expressions that result in
no upcoming time events.

If a cron expression results in less than the specified count
(default 10) time events, now all the coming times are printed
without displaying error message.

Closes #32735
lipsill 7 years ago
parent
commit
f84ed14294

+ 7 - 3
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/trigger/schedule/tool/CronEvalTool.java

@@ -61,14 +61,18 @@ public class CronEvalTool extends LoggingAwareCommand {
 
         Cron cron = new Cron(expression);
         long time = date.getMillis();
+
         for (int i = 0; i < count; i++) {
             long prevTime = time;
             time = cron.getNextValidTimeAfter(time);
             if (time < 0) {
-                throw new UserException(ExitCodes.OK, (i + 1) + ".\t Could not compute future times since ["
-                    + formatter.print(prevTime) + "] " + "(perhaps the cron expression only points to times in the past?)");
+                if (i == 0) {
+                    throw new UserException(ExitCodes.OK, "Could not compute future times since ["
+                            + formatter.print(prevTime) + "] " + "(perhaps the cron expression only points to times in the past?)");
+                }
+                break;
             }
-            terminal.println((i+1) + ".\t" + formatter.print(time));
+            terminal.println((i + 1) + ".\t" + formatter.print(time));
         }
     }
 }

+ 29 - 1
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/trigger/schedule/tool/CronEvalToolTests.java

@@ -8,6 +8,13 @@ package org.elasticsearch.xpack.watcher.trigger.schedule.tool;
 import org.elasticsearch.cli.Command;
 import org.elasticsearch.cli.CommandTestCase;
 
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+
 public class CronEvalToolTests extends CommandTestCase {
     @Override
     protected Command newCommand() {
@@ -18,6 +25,27 @@ public class CronEvalToolTests extends CommandTestCase {
         String countOption = randomBoolean() ? "-c" : "--count";
         int count = randomIntBetween(1, 100);
         String output = execute(countOption, Integer.toString(count), "0 0 0 1-6 * ?");
-        assertTrue(output, output.contains("Here are the next " + count + " times this cron expression will trigger"));
+        assertThat(output, containsString("Here are the next " + count + " times this cron expression will trigger"));
+    }
+
+    public void testGetNextValidTimes() throws Exception {
+        final int year = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT).get(Calendar.YEAR) + 1;
+        {
+            String output = execute("0 3 23 8 9 ? " + year);
+            assertThat(output, containsString("Here are the next 10 times this cron expression will trigger:"));
+            assertThat(output, not(containsString("ERROR")));
+            assertThat(output, not(containsString("2.\t")));
+        }
+        {
+            String output = execute("0 3 23 */4 9 ? " + year);
+            assertThat(output, containsString("Here are the next 10 times this cron expression will trigger:"));
+            assertThat(output, not(containsString("ERROR")));
+        }
+        {
+            Exception expectThrows = expectThrows(Exception.class, () -> execute("0 3 23 */4 9 ? 2017"));
+            String message = expectThrows.getMessage();
+            assertThat(message, containsString("Could not compute future times since"));
+            assertThat(message, containsString("(perhaps the cron expression only points to times in the past?)"));
+        }
     }
 }