Example #1
0
 def test_it_parses_stars(self):
     w = CronSim("* * * * *", NOW)
     self.assertEqual(w.minutes, set(range(0, 60)))
     self.assertEqual(w.hours, set(range(0, 24)))
     self.assertEqual(w.days, set(range(1, 32)))
     self.assertEqual(w.months, set(range(1, 13)))
     self.assertEqual(w.weekdays, set(range(0, 8)))
Example #2
0
    def get_grace_start(self, with_started=True):
        """ Return the datetime when the grace period starts.

        If the check is currently new, paused or down, return None.

        """

        # NEVER is a constant sentinel value (year 3000).
        # Using None instead would make the min() logic clunky.
        result = NEVER

        if self.kind == "simple" and self.status == "up":
            result = self.last_ping + self.timeout
        elif self.kind == "cron" and self.status == "up":
            # The complex case, next ping is expected based on cron schedule.
            # Don't convert to naive datetimes (and so avoid ambiguities around
            # DST transitions). cronsim will handle the timezone-aware datetimes.
            last_local = self.last_ping.astimezone(ZoneInfo(self.tz))
            result = next(CronSim(self.schedule, last_local))

        if with_started and self.last_start and self.status != "down":
            result = min(result, self.last_start)

        if result != NEVER:
            return result
Example #3
0
def validate(obj, schema, obj_name="value"):
    if schema.get("type") == "string":
        if not isinstance(obj, str):
            raise ValidationError("%s is not a string" % obj_name)
        if "minLength" in schema and len(obj) < schema["minLength"]:
            raise ValidationError("%s is too short" % obj_name)
        if "maxLength" in schema and len(obj) > schema["maxLength"]:
            raise ValidationError("%s is too long" % obj_name)
        if schema.get("format") == "cron":
            try:
                # Does it have 5 components?
                if len(obj.split()) != 5:
                    raise ValueError()

                # Does cronsim accept the schedule?
                it = CronSim(obj, datetime(2000, 1, 1))
                # Can it calculate the next datetime?
                next(it)
            except:
                raise ValidationError("%s is not a valid cron expression" %
                                      obj_name)
        if schema.get("format") == "timezone" and obj not in all_timezones:
            raise ValidationError("%s is not a valid timezone" % obj_name)

    elif schema.get("type") == "number":
        if not isinstance(obj, int):
            raise ValidationError("%s is not a number" % obj_name)
        if "minimum" in schema and obj < schema["minimum"]:
            raise ValidationError("%s is too small" % obj_name)
        if "maximum" in schema and obj > schema["maximum"]:
            raise ValidationError("%s is too large" % obj_name)

    elif schema.get("type") == "boolean":
        if not isinstance(obj, bool):
            raise ValidationError("%s is not a boolean" % obj_name)

    elif schema.get("type") == "array":
        if not isinstance(obj, list):
            raise ValidationError("%s is not an array" % obj_name)

        for v in obj:
            validate(v, schema["items"], "an item in '%s'" % obj_name)

    elif schema.get("type") == "object":
        if not isinstance(obj, dict):
            raise ValidationError("%s is not an object" % obj_name)

        properties = schema.get("properties", {})
        for key, spec in properties.items():
            if key in obj:
                validate(obj[key], spec, obj_name=key)

        for key in schema.get("required", []):
            if key not in obj:
                raise ValidationError("key %s absent in %s" % (key, obj_name))

    if "enum" in schema:
        if obj not in schema["enum"]:
            raise ValidationError("%s has unexpected value" % obj_name)
Example #4
0
    def __call__(self, value):
        # Expect 5 components-
        if len(value.split()) != 5:
            raise ValidationError(message=self.message)

        try:
            # Does cronsim accept the schedule?
            it = CronSim(value, datetime(2000, 1, 1))
            # Can it calculate the next datetime?
            next(it)
        except:
            raise ValidationError(message=self.message)
Example #5
0
    def test_it_rejects_bad_values(self):
        patterns = (
            "%s * * * *",
            "* %s * * *",
            "* * %s * *",
            "* * * %s * ",
            "* * * * %s",
            "* * * * * %s",
            "1-%s * * * *",
            "%s-60 * * * *",
            "* * * %s-DEC *",
            "* * * JAN-%s *",
            "* * * * %s-SUN",
            "* * * * MON-%s",
        )

        bad_values = ("-1", "61", "ABC", "2/", "/2", "2#", "#2", "1##1",
                      "1//2")

        for pattern, s in product(patterns, bad_values):
            with self.assertRaises(CronSimError):
                CronSim(pattern % s, NOW)
Example #6
0
 def test_it_parses_sun_tue(self):
     w = CronSim("* * * * sun-tue", NOW)
     self.assertEqual(w.weekdays, {0, 1, 2})
Example #7
0
 def test_it_parses_symbolic_month(self):
     w = CronSim("* * * JAN *", NOW)
     self.assertEqual(w.months, {1})
Example #8
0
 def test_it_parses_symbolic_weekday(self):
     w = CronSim("* * * * MON", NOW)
     self.assertEqual(w.weekdays, {1})
Example #9
0
 def test_it_parses_restricted_day_unrestricted_dow(self):
     w = CronSim("* * 1 * *", NOW)
     self.assertEqual(w.days, {1})
     self.assertEqual(w.weekdays, set())
Example #10
0
 def test_it_parses_start_with_step(self):
     w = CronSim("5/15 * * * *", NOW)
     self.assertEqual(w.minutes, {5, 20, 35, 50})
Example #11
0
 def test_it_parses_step(self):
     w = CronSim("*/15 * * * *", NOW)
     self.assertEqual(w.minutes, {0, 15, 30, 45})
Example #12
0
 def test_it_rejects_zero_step(self):
     with self.assertRaises(CronSimError):
         CronSim("*/0 * * * *", NOW)
Example #13
0
 def test_it_rejects_underscores(self):
     with self.assertRaises(CronSimError):
         CronSim("1-1_0 * * * *", NOW)
Example #14
0
 def test_it_rejects_lopsided_range(self):
     with self.assertRaises(CronSimError):
         CronSim("* * 5-1 * *", NOW)
Example #15
0
 def test_it_rejects_4_components(self):
     with self.assertRaises(CronSimError):
         CronSim("* * * *", NOW)
Example #16
0
 def test_it_parses_interval(self):
     w = CronSim("1-3 * * * *", NOW)
     self.assertEqual(w.minutes, {1, 2, 3})
Example #17
0
 def test_it_parses_two_intervals(self):
     w = CronSim("1-3,7-9 * * * *", NOW)
     self.assertEqual(w.minutes, {1, 2, 3, 7, 8, 9})
Example #18
0
 def test_it_rejects_big_nth(self):
     with self.assertRaises(CronSimError):
         CronSim("* * * * 1#6", NOW)
Example #19
0
 def test_it_parses_interval_with_step(self):
     w = CronSim("0-10/2 * * * *", NOW)
     self.assertEqual(w.minutes, {0, 2, 4, 6, 8, 10})
Example #20
0
 def test_it_handles_l(self):
     dt = next(CronSim("1 1 L * *", NOW))
     self.assertEqual(dt.isoformat(), "2020-01-31T01:01:00")
Example #21
0
 def test_it_parses_day_lowercase_l(self):
     w = CronSim("* * l * *", NOW)
     self.assertEqual(w.days, {CronSim.LAST})
Example #22
0
 def test_it_handles_nth_weekday(self):
     dt = next(CronSim("1 1 * * 1#2", NOW))
     self.assertEqual(dt.isoformat(), "2020-01-13T01:01:00")
Example #23
0
 def test_it_parses_nth_weekday(self):
     w = CronSim("* * * * 1#2", NOW)
     self.assertEqual(w.weekdays, {(1, 2)})
Example #24
0
 def test_it_parses_numbers(self):
     w = CronSim("1 * * * *", NOW)
     self.assertEqual(w.minutes, {1})
Example #25
0
 def test_it_parses_lowercase_symbolic_weekday(self):
     w = CronSim("* * * * mon", NOW)
     self.assertEqual(w.weekdays, {1})
Example #26
0
 def test_it_parses_weekday(self):
     w = CronSim("* * * * 1", NOW)
     self.assertEqual(w.weekdays, {1})
Example #27
0
 def test_it_parses_weekday_range_from_zero(self):
     w = CronSim("* * * * 0-2", NOW)
     self.assertEqual(w.weekdays, {0, 1, 2})
Example #28
0
 def test_it_handles_0_sunday(self):
     w = CronSim("* * * * 0", NOW)
     self.assertEqual(w.weekdays, {0})
Example #29
0
 def test_it_starts_weekday_step_from_zero(self):
     w = CronSim("* * * * */2", NOW)
     self.assertEqual(w.weekdays, {0, 2, 4, 6})
Example #30
0
 def test_it_parses_list(self):
     w = CronSim("1,2,3 * * * *", NOW)
     self.assertEqual(w.minutes, {1, 2, 3})