diff --git a/localstack-core/localstack/services/events/rule.py b/localstack-core/localstack/services/events/rule.py index f8c540221a803..576cfc36e781c 100644 --- a/localstack-core/localstack/services/events/rule.py +++ b/localstack-core/localstack/services/events/rule.py @@ -24,7 +24,29 @@ TARGET_ID_REGEX = re.compile(r"^[\.\-_A-Za-z0-9]+$") TARGET_ARN_REGEX = re.compile(r"arn:[\d\w:\-/]*") -RULE_SCHEDULE_CRON_REGEX = re.compile(r"^cron\(.*\)") +CRON_REGEX = ( # borrowed from https://regex101.com/r/I80Eu0/1 + r"^(?:cron[(](?:(?:(?:[0-5]?[0-9])|[*])(?:(?:[-](?:(?:[0-5]?[0-9])|[*]))|(?:[/][0-9]+))?" + r"(?:[,](?:(?:[0-5]?[0-9])|[*])(?:(?:[-](?:(?:[0-5]?[0-9])|[*]))|(?:[/][0-9]+))?)*)[ ]+" + r"(?:(?:(?:[0-2]?[0-9])|[*])(?:(?:[-](?:(?:[0-2]?[0-9])|[*]))|(?:[/][0-9]+))?" + r"(?:[,](?:(?:[0-2]?[0-9])|[*])(?:(?:[-](?:(?:[0-2]?[0-9])|[*]))|(?:[/][0-9]+))?)*)[ ]+" + r"(?:(?:[?][ ]+(?:(?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[*])" + r"(?:(?:[-](?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[*])(?:[/][0-9]+)?)|" + r"(?:[/][0-9]+))?(?:[,](?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[*])" + r"(?:(?:[-](?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[*])(?:[/][0-9]+)?)|" + r"(?:[/][0-9]+))?)*)[ ]+(?:(?:(?:[1-7]|(?:SUN|MON|TUE|WED|THU|FRI|SAT))[#][0-5])|" + r"(?:(?:(?:(?:[1-7]|(?:SUN|MON|TUE|WED|THU|FRI|SAT))L?)|[L*])(?:(?:[-](?:(?:(?:[1-7]|" + r"(?:SUN|MON|TUE|WED|THU|FRI|SAT))L?)|[L*]))|(?:[/][0-9]+))?(?:[,](?:(?:(?:[1-7]|" + r"(?:SUN|MON|TUE|WED|THU|FRI|SAT))L?)|[L*])(?:(?:[-](?:(?:(?:[1-7]|(?:SUN|MON|TUE|WED|THU|FRI|SAT))L?)|" + r"[L*]))|(?:[/][0-9]+))?)*)))|(?:(?:(?:(?:(?:[1-3]?[0-9])W?)|LW|[L*])(?:(?:[-](?:(?:(?:[1-3]?[0-9])W?)|" + r"LW|[L*]))|(?:[/][0-9]+))?(?:[,](?:(?:(?:[1-3]?[0-9])W?)|LW|[L*])(?:(?:[-](?:(?:(?:[1-3]?[0-9])W?)|" + r"LW|[L*]))|(?:[/][0-9]+))?)*)[ ]+(?:(?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|" + r"[*])(?:(?:[-](?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[*])(?:[/][0-9]+)?)|" + r"(?:[/][0-9]+))?(?:[,](?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[*])" + r"(?:(?:[-](?:(?:[1]?[0-9])|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[*])(?:[/][0-9]+)?)|" + r"(?:[/][0-9]+))?)*)[ ]+[?]))[ ]+(?:(?:(?:[12][0-9]{3})|[*])(?:(?:[-](?:(?:[12][0-9]{3})|[*]))|" + r"(?:[/][0-9]+))?(?:[,](?:(?:[12][0-9]{3})|[*])(?:(?:[-](?:(?:[12][0-9]{3})|[*]))|(?:[/][0-9]+))?)*)[)])$" +) +RULE_SCHEDULE_CRON_REGEX = re.compile(CRON_REGEX) RULE_SCHEDULE_RATE_REGEX = re.compile(r"^rate\(\d*\s(minute|minutes|hour|hours|day|days)\)") diff --git a/localstack-core/localstack/services/events/utils.py b/localstack-core/localstack/services/events/utils.py index 54e5bbd2ec675..36258ac668acb 100644 --- a/localstack-core/localstack/services/events/utils.py +++ b/localstack-core/localstack/services/events/utils.py @@ -40,7 +40,7 @@ ARCHIVE_NAME_ARN_PATTERN = re.compile( rf"{ARN_PARTITION_REGEX}:events:[a-z0-9-]+:\d{{12}}:archive/(?P.+)$" ) -CONNCTION_NAME_ARN_PATTERN = re.compile( +CONNECTION_NAME_ARN_PATTERN = re.compile( rf"{ARN_PARTITION_REGEX}:events:[a-z0-9-]+:\d{{12}}:connection/(?P[^/]+)/(?P[^/]+)$" ) @@ -98,7 +98,7 @@ def extract_event_bus_name( def extract_connection_name( connection_arn: ConnectionArn, ) -> ConnectionName: - match = CONNCTION_NAME_ARN_PATTERN.match(connection_arn) + match = CONNECTION_NAME_ARN_PATTERN.match(connection_arn) if not match: raise ValidationException( f"Parameter {connection_arn} is not valid. Reason: Provided Arn is not in correct format." diff --git a/tests/aws/services/events/test_events_schedule.py b/tests/aws/services/events/test_events_schedule.py index f46972b0b8fb5..8247dc03f5235 100644 --- a/tests/aws/services/events/test_events_schedule.py +++ b/tests/aws/services/events/test_events_schedule.py @@ -279,6 +279,13 @@ class TestScheduleCron: @pytest.mark.parametrize( "schedule_cron", [ + "cron(0 2 ? * SAT *)", # Run at 2:00 am every Saturday + "cron(0 12 * * ? *)", # Run at 12:00 pm every day + "cron(5,35 14 * * ? *)", # Run at 2:05 pm and 2:35 pm every day + "cron(15 10 ? * 6L 2002-2005)", # Run at 10:15 am on the last Friday of every month during the years 2002-2005 + "cron(0 2 ? * SAT#3 *)", # Run at 2:00 am on the third Saturday of every month + "cron(* * ? * SAT#3 *)", # Run every minute on the third Saturday of every month + "cron(0/5 5 ? JAN 1-5 2022)", # RUN every 5 minutes on the first 5 days of January 2022 "cron(0 10 * * ? *)", # Run at 10:00 am every day "cron(15 12 * * ? *)", # Run at 12:15 pm every day "cron(0 18 ? * MON-FRI *)", # Run at 6:00 pm every Monday through Friday @@ -302,6 +309,23 @@ def tests_put_rule_with_schedule_cron( response = aws_client.events.list_rules(NamePrefix=rule_name) snapshot.match("list-rules", response) + @markers.aws.validated + @pytest.mark.parametrize( + "schedule_cron", + [ + "cron(7 20 * * NOT *)", + "cron(INVALID)", + "cron(0 dummy ? * MON-FRI *)", + "cron(71 8 1 * ? *)", + ], + ) + def tests_put_rule_with_invalid_schedule_cron(self, schedule_cron, events_put_rule, snapshot): + rule_name = f"rule-{short_uid()}" + + with pytest.raises(ClientError) as e: + events_put_rule(Name=rule_name, ScheduleExpression=schedule_cron) + snapshot.match("invalid-put-rule", e.value.response) + @markers.aws.validated @pytest.mark.skip("Flaky, target time can be 1min off message time") def test_schedule_cron_target_sqs( diff --git a/tests/aws/services/events/test_events_schedule.snapshot.json b/tests/aws/services/events/test_events_schedule.snapshot.json index b0d4073fce6c5..9c769130f00fc 100644 --- a/tests/aws/services/events/test_events_schedule.snapshot.json +++ b/tests/aws/services/events/test_events_schedule.snapshot.json @@ -146,7 +146,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 10 * * ? *)]": { - "recorded-date": "14-05-2024, 15:43:09", + "recorded-date": "21-01-2025, 17:46:05", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -173,7 +173,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 12 * * ? *)]": { - "recorded-date": "14-05-2024, 15:43:09", + "recorded-date": "21-01-2025, 17:46:05", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -200,7 +200,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 18 ? * MON-FRI *)]": { - "recorded-date": "14-05-2024, 15:43:10", + "recorded-date": "21-01-2025, 17:46:06", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -227,7 +227,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 8 1 * ? *)]": { - "recorded-date": "14-05-2024, 15:43:11", + "recorded-date": "21-01-2025, 17:46:06", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -254,7 +254,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/15 * * * ? *)]": { - "recorded-date": "14-05-2024, 15:43:12", + "recorded-date": "21-01-2025, 17:46:07", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -281,7 +281,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/10 * ? * MON-FRI *)]": { - "recorded-date": "14-05-2024, 15:43:12", + "recorded-date": "21-01-2025, 17:46:07", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -308,7 +308,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 8-17 ? * MON-FRI *)]": { - "recorded-date": "14-05-2024, 15:43:13", + "recorded-date": "21-01-2025, 17:46:08", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -335,7 +335,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 20-23 ? * MON-FRI *)]": { - "recorded-date": "14-05-2024, 15:43:14", + "recorded-date": "21-01-2025, 17:46:08", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -362,7 +362,7 @@ } }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 0-2 ? * MON-FRI *)]": { - "recorded-date": "14-05-2024, 15:43:14", + "recorded-date": "21-01-2025, 17:46:09", "recorded-content": { "put-rule": { "RuleArn": "arn::events::111111111111:rule/", @@ -417,5 +417,254 @@ } ] } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(INVALID)]": { + "recorded-date": "21-01-2025, 17:46:10", + "recorded-content": { + "invalid-put-rule": { + "Error": { + "Code": "ValidationException", + "Message": "Parameter ScheduleExpression is not valid." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(0 dummy ? * MON-FRI *)]": { + "recorded-date": "21-01-2025, 17:46:11", + "recorded-content": { + "invalid-put-rule": { + "Error": { + "Code": "ValidationException", + "Message": "Parameter ScheduleExpression is not valid." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT *)]": { + "recorded-date": "21-01-2025, 17:46:01", + "recorded-content": { + "put-rule": { + "RuleArn": "arn::events::111111111111:rule/", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-rules": { + "Rules": [ + { + "Arn": "arn::events::111111111111:rule/", + "EventBusName": "default", + "Name": "", + "ScheduleExpression": "cron(0 2 ? * SAT *)", + "State": "ENABLED" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 12 * * ? *)]": { + "recorded-date": "21-01-2025, 17:46:01", + "recorded-content": { + "put-rule": { + "RuleArn": "arn::events::111111111111:rule/", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-rules": { + "Rules": [ + { + "Arn": "arn::events::111111111111:rule/", + "EventBusName": "default", + "Name": "", + "ScheduleExpression": "cron(0 12 * * ? *)", + "State": "ENABLED" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(5,35 14 * * ? *)]": { + "recorded-date": "21-01-2025, 17:46:02", + "recorded-content": { + "put-rule": { + "RuleArn": "arn::events::111111111111:rule/", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-rules": { + "Rules": [ + { + "Arn": "arn::events::111111111111:rule/", + "EventBusName": "default", + "Name": "", + "ScheduleExpression": "cron(5,35 14 * * ? *)", + "State": "ENABLED" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 10 ? * 6L 2002-2005)]": { + "recorded-date": "21-01-2025, 17:46:02", + "recorded-content": { + "put-rule": { + "RuleArn": "arn::events::111111111111:rule/", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-rules": { + "Rules": [ + { + "Arn": "arn::events::111111111111:rule/", + "EventBusName": "default", + "Name": "", + "ScheduleExpression": "cron(15 10 ? * 6L 2002-2005)", + "State": "ENABLED" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT#3 *)]": { + "recorded-date": "21-01-2025, 17:46:03", + "recorded-content": { + "put-rule": { + "RuleArn": "arn::events::111111111111:rule/", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-rules": { + "Rules": [ + { + "Arn": "arn::events::111111111111:rule/", + "EventBusName": "default", + "Name": "", + "ScheduleExpression": "cron(0 2 ? * SAT#3 *)", + "State": "ENABLED" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(* * ? * SAT#3 *)]": { + "recorded-date": "21-01-2025, 17:46:03", + "recorded-content": { + "put-rule": { + "RuleArn": "arn::events::111111111111:rule/", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-rules": { + "Rules": [ + { + "Arn": "arn::events::111111111111:rule/", + "EventBusName": "default", + "Name": "", + "ScheduleExpression": "cron(* * ? * SAT#3 *)", + "State": "ENABLED" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 5 ? JAN 1-5 2022)]": { + "recorded-date": "21-01-2025, 17:46:04", + "recorded-content": { + "put-rule": { + "RuleArn": "arn::events::111111111111:rule/", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "list-rules": { + "Rules": [ + { + "Arn": "arn::events::111111111111:rule/", + "EventBusName": "default", + "Name": "", + "ScheduleExpression": "cron(0/5 5 ? JAN 1-5 2022)", + "State": "ENABLED" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(7 20 * * NOT *)]": { + "recorded-date": "21-01-2025, 17:46:09", + "recorded-content": { + "invalid-put-rule": { + "Error": { + "Code": "ValidationException", + "Message": "Parameter ScheduleExpression is not valid." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(71 8 1 * ? *)]": { + "recorded-date": "21-01-2025, 17:46:11", + "recorded-content": { + "invalid-put-rule": { + "Error": { + "Code": "ValidationException", + "Message": "Parameter ScheduleExpression is not valid." + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 400 + } + } + } } } diff --git a/tests/aws/services/events/test_events_schedule.validation.json b/tests/aws/services/events/test_events_schedule.validation.json index a21ca78f556dd..43d029ba622ab 100644 --- a/tests/aws/services/events/test_events_schedule.validation.json +++ b/tests/aws/services/events/test_events_schedule.validation.json @@ -2,35 +2,68 @@ "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::test_schedule_cron_target_sqs": { "last_validated_date": "2024-05-15T10:58:53+00:00" }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(0 dummy ? * MON-FRI *)]": { + "last_validated_date": "2025-01-21T17:46:11+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(7 20 * * NOT *)]": { + "last_validated_date": "2025-01-21T17:46:09+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(71 8 1 * ? *)]": { + "last_validated_date": "2025-01-21T17:46:11+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_invalid_schedule_cron[cron(INVALID)]": { + "last_validated_date": "2025-01-21T17:46:10+00:00" + }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron": { "last_validated_date": "2024-05-14T14:50:51+00:00" }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(* * ? * SAT#3 *)]": { + "last_validated_date": "2025-01-21T17:46:03+00:00" + }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 10 * * ? *)]": { - "last_validated_date": "2024-05-14T15:43:09+00:00" + "last_validated_date": "2025-01-21T17:46:05+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 12 * * ? *)]": { + "last_validated_date": "2025-01-21T17:46:01+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 18 ? * MON-FRI *)]": { - "last_validated_date": "2024-05-14T15:43:10+00:00" + "last_validated_date": "2025-01-21T17:46:06+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT *)]": { + "last_validated_date": "2025-01-21T17:46:01+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 2 ? * SAT#3 *)]": { + "last_validated_date": "2025-01-21T17:46:03+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0 8 1 * ? *)]": { - "last_validated_date": "2024-05-14T15:43:11+00:00" + "last_validated_date": "2025-01-21T17:46:06+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/10 * ? * MON-FRI *)]": { - "last_validated_date": "2024-05-14T15:43:12+00:00" + "last_validated_date": "2025-01-21T17:46:07+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/15 * * * ? *)]": { - "last_validated_date": "2024-05-14T15:43:12+00:00" + "last_validated_date": "2025-01-21T17:46:07+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 0-2 ? * MON-FRI *)]": { - "last_validated_date": "2024-05-14T15:43:14+00:00" + "last_validated_date": "2025-01-21T17:46:09+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/30 20-23 ? * MON-FRI *)]": { - "last_validated_date": "2024-05-14T15:43:14+00:00" + "last_validated_date": "2025-01-21T17:46:08+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 5 ? JAN 1-5 2022)]": { + "last_validated_date": "2025-01-21T17:46:04+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(0/5 8-17 ? * MON-FRI *)]": { - "last_validated_date": "2024-05-14T15:43:13+00:00" + "last_validated_date": "2025-01-21T17:46:08+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 10 ? * 6L 2002-2005)]": { + "last_validated_date": "2025-01-21T17:46:02+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(15 12 * * ? *)]": { - "last_validated_date": "2024-05-14T15:43:09+00:00" + "last_validated_date": "2025-01-21T17:46:05+00:00" + }, + "tests/aws/services/events/test_events_schedule.py::TestScheduleCron::tests_put_rule_with_schedule_cron[cron(5,35 14 * * ? *)]": { + "last_validated_date": "2025-01-21T17:46:02+00:00" }, "tests/aws/services/events/test_events_schedule.py::TestScheduleRate::test_put_rule_with_invalid_schedule_rate[ rate(10 minutes)]": { "last_validated_date": "2024-05-14T11:27:18+00:00"