diff --git a/localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/math_operations/math_add.py b/localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/math_operations/math_add.py index 6a8fbafd2b268..2e92c8f333009 100644 --- a/localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/math_operations/math_add.py +++ b/localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/math_operations/math_add.py @@ -1,3 +1,4 @@ +import decimal from typing import Any from localstack.services.stepfunctions.asl.component.intrinsic.argument.function_argument_list import ( @@ -15,6 +16,18 @@ from localstack.services.stepfunctions.asl.eval.environment import Environment +def _round_like_java(f: float) -> int: + # this behaves a bit weird for boundary values + # AWS stepfunctions is implemented in Java, so we need to adjust the rounding accordingly + # python by default rounds half to even + if f >= 0: + decimal.getcontext().rounding = decimal.ROUND_HALF_UP + else: + decimal.getcontext().rounding = decimal.ROUND_HALF_DOWN + d = decimal.Decimal(f) + return round(d, 0) + + class MathAdd(StatesFunction): # Returns the sum of two numbers. # @@ -47,7 +60,12 @@ def _validate_integer_value(value: Any) -> int: raise TypeError(f"Expected integer value, but got: '{value}'.") # If you specify a non-integer value for one or both the arguments, # Step Functions will round it off to the nearest integer. - return int(value) + + if isinstance(value, float): + result = _round_like_java(value) + return int(result) + + return value def _eval_body(self, env: Environment) -> None: self.arg_list.eval(env=env) diff --git a/tests/aws/services/cloudformation/api/test_changesets.py b/tests/aws/services/cloudformation/api/test_changesets.py index b794ab6e73b32..6ed704141ccc3 100644 --- a/tests/aws/services/cloudformation/api/test_changesets.py +++ b/tests/aws/services/cloudformation/api/test_changesets.py @@ -14,7 +14,7 @@ from localstack.utils.sync import ShortCircuitWaitException, poll_condition, wait_until -@markers.aws.unknown +@markers.aws.validated def test_create_change_set_without_parameters( cleanup_stacks, cleanup_changesets, is_change_set_created_and_available, aws_client ): @@ -145,17 +145,13 @@ def test_create_change_set_update_without_parameters( cleanup_stacks(stacks=[stack_id]) -@pytest.mark.skip(reason="TODO") -@markers.aws.unknown -def test_create_change_set_with_template_url(): - pass +# def test_create_change_set_with_template_url(): +# pass -@pytest.mark.xfail(reason="change set type not implemented") -@markers.aws.unknown -def test_create_change_set_create_existing( - is_stack_created, cleanup_changesets, cleanup_stacks, aws_client -): +@pytest.mark.skipif(condition=not is_aws_cloud(), reason="change set type not implemented") +@markers.aws.validated +def test_create_change_set_create_existing(cleanup_changesets, cleanup_stacks, aws_client): """tries to create an already existing stack""" stack_name = f"stack-{short_uid()}" @@ -171,12 +167,15 @@ def test_create_change_set_create_existing( ChangeSetType="CREATE", ) change_set_id = response["Id"] + aws_client.cloudformation.get_waiter("change_set_create_complete").wait( + ChangeSetName=change_set_id + ) stack_id = response["StackId"] assert change_set_id assert stack_id try: aws_client.cloudformation.execute_change_set(ChangeSetName=change_set_id) - wait_until(is_stack_created(stack_id)) + aws_client.cloudformation.get_waiter("stack_create_complete").wait(StackName=stack_id) with pytest.raises(Exception) as ex: change_set_name2 = f"change-set-{short_uid()}" @@ -192,7 +191,7 @@ def test_create_change_set_create_existing( cleanup_stacks([stack_id]) -@markers.aws.unknown +@markers.aws.validated def test_create_change_set_update_nonexisting(aws_client): stack_name = f"stack-{short_uid()}" change_set_name = f"change-set-{short_uid()}" @@ -216,14 +215,7 @@ def test_create_change_set_update_nonexisting(aws_client): assert "does not exist" in err["Message"] -@pytest.mark.skip(reason="TODO") -@markers.aws.unknown -def test_create_change_set_import(): - """test importing existing resources into a stack via the change set""" - pass # TODO - - -@markers.aws.unknown +@markers.aws.validated def test_create_change_set_invalid_params(aws_client): stack_name = f"stack-{short_uid()}" change_set_name = f"change-set-{short_uid()}" @@ -241,7 +233,7 @@ def test_create_change_set_invalid_params(aws_client): assert err["Code"] == "ValidationError" -@markers.aws.unknown +@markers.aws.validated def test_create_change_set_missing_stackname(aws_client): """in this case boto doesn't even let us send the request""" change_set_name = f"change-set-{short_uid()}" @@ -349,8 +341,11 @@ def test_describe_change_set_nonexisting(snapshot, aws_client): snapshot.match("exception", ex.value) -@pytest.mark.skip(reason="fails because of the properties mutation in the result_handler") -@markers.aws.unknown +@pytest.mark.skipif( + condition=not is_aws_cloud(), + reason="fails because of the properties mutation in the result_handler", +) +@markers.aws.validated def test_execute_change_set( is_change_set_finished, is_change_set_created_and_available, diff --git a/tests/aws/services/cloudformation/api/test_stacks.py b/tests/aws/services/cloudformation/api/test_stacks.py index 1cae29cc7d423..d002ec494df6c 100644 --- a/tests/aws/services/cloudformation/api/test_stacks.py +++ b/tests/aws/services/cloudformation/api/test_stacks.py @@ -173,7 +173,7 @@ def test_stack_update_resources( resources = aws_client.cloudformation.describe_stack_resources(StackName=stack_name) snapshot.match("stack_resources", resources) - @markers.aws.unknown + @markers.aws.needs_fixing def test_list_stack_resources_for_removed_resource(self, deploy_cfn_template, aws_client): template_path = os.path.join( os.path.dirname(__file__), "../../../templates/eventbridge_policy.yaml" @@ -212,7 +212,7 @@ def test_list_stack_resources_for_removed_resource(self, deploy_cfn_template, aw statuses = set([res["ResourceStatus"] for res in resources]) assert statuses == {"UPDATE_COMPLETE"} - @markers.aws.unknown + @markers.aws.needs_fixing def test_update_stack_with_same_template_withoutchange(self, deploy_cfn_template, aws_client): template = load_file( os.path.join(os.path.dirname(__file__), "../../../templates/fifo_queue.json") diff --git a/tests/aws/services/cloudformation/resources/test_events.py b/tests/aws/services/cloudformation/resources/test_events.py index a1b1e03920b50..6754a147c773f 100644 --- a/tests/aws/services/cloudformation/resources/test_events.py +++ b/tests/aws/services/cloudformation/resources/test_events.py @@ -10,7 +10,7 @@ LOG = logging.getLogger(__name__) -@markers.aws.unknown +@markers.aws.validated def test_eventbus_policies(deploy_cfn_template, aws_client): event_bus_name = f"event-bus-{short_uid()}" @@ -51,7 +51,7 @@ def test_eventbus_policies(deploy_cfn_template, aws_client): assert len(policy["Statement"]) == 1 -@markers.aws.unknown +@markers.aws.validated def test_eventbus_policy_statement(deploy_cfn_template, aws_client): event_bus_name = f"event-bus-{short_uid()}" statement_id = f"statement-{short_uid()}" @@ -75,7 +75,7 @@ def test_eventbus_policy_statement(deploy_cfn_template, aws_client): assert event_bus_name in statement["Resource"] -@markers.aws.unknown +@markers.aws.validated def test_event_rule_to_logs(deploy_cfn_template, aws_client): event_rule_name = f"event-rule-{short_uid()}" log_group_name = f"log-group-{short_uid()}" @@ -126,7 +126,8 @@ def test_event_rule_to_logs(deploy_cfn_template, aws_client): assert message_token in log_events["events"][0]["message"] -@markers.aws.unknown +# {"LogicalResourceId": "TestRule99A50909", "ResourceType": "AWS::Events::Rule", "ResourceStatus": "CREATE_FAILED", "ResourceStatusReason": "Parameter ScheduleExpression is not valid."} +@markers.aws.needs_fixing def test_event_rule_creation_without_target(deploy_cfn_template, aws_client): event_rule_name = f"event-rule-{short_uid()}" deploy_cfn_template( @@ -142,7 +143,7 @@ def test_event_rule_creation_without_target(deploy_cfn_template, aws_client): assert response -@markers.aws.unknown +@markers.aws.validated def test_cfn_event_bus_resource(deploy_cfn_template, aws_client): def _assert(expected_len): rs = aws_client.events.list_event_buses() @@ -211,7 +212,8 @@ def _assert(expected_len): """ -@markers.aws.unknown +# {"LogicalResourceId": "ScheduledRule", "ResourceType": "AWS::Events::Rule", "ResourceStatus": "CREATE_FAILED", "ResourceStatusReason": "s3 is not a supported service for a target."} +@markers.aws.needs_fixing def test_cfn_handle_events_rule(deploy_cfn_template, aws_client): bucket_name = f"target-{short_uid()}" rule_prefix = f"s3-rule-{short_uid()}" @@ -234,7 +236,8 @@ def test_cfn_handle_events_rule(deploy_cfn_template, aws_client): assert rule_name not in [rule["Name"] for rule in rs["Rules"]] -@markers.aws.unknown +# {"LogicalResourceId": "TestStateMachine", "ResourceType": "AWS::StepFunctions::StateMachine", "ResourceStatus": "CREATE_FAILED", "ResourceStatusReason": "Resource handler returned message: \"Cross-account pass role is not allowed."} +@markers.aws.needs_fixing def test_cfn_handle_events_rule_without_name(deploy_cfn_template, aws_client): rs = aws_client.events.list_rules() rule_names = [rule["Name"] for rule in rs["Rules"]] diff --git a/tests/aws/services/cloudformation/resources/test_stepfunctions.py b/tests/aws/services/cloudformation/resources/test_stepfunctions.py index 4ff7c04efc9e6..622a8b381e5c4 100644 --- a/tests/aws/services/cloudformation/resources/test_stepfunctions.py +++ b/tests/aws/services/cloudformation/resources/test_stepfunctions.py @@ -10,7 +10,7 @@ from tests.aws.services.stepfunctions.utils import await_execution_terminated -@markers.aws.unknown +@markers.aws.validated def test_statemachine_definitionsubstitution(deploy_cfn_template, aws_client): stack = deploy_cfn_template( template_path=os.path.join( @@ -44,7 +44,7 @@ def _is_executed(): assert "hello from statemachine" in execution_desc["output"] -@markers.aws.unknown +@markers.aws.validated def test_nested_statemachine_with_sync2(deploy_cfn_template, aws_client): stack = deploy_cfn_template( template_path=os.path.join( @@ -76,7 +76,7 @@ def _is_executed(): assert output["Value"] == 3 -@markers.aws.unknown +@markers.aws.needs_fixing def test_apigateway_invoke(deploy_cfn_template, aws_client): deploy_result = deploy_cfn_template( template_path=os.path.join( @@ -102,7 +102,7 @@ def _sfn_finished_running(): assert "hello from stepfunctions" in execution_result["output"] -@markers.aws.unknown +@markers.aws.validated def test_apigateway_invoke_with_path(deploy_cfn_template, aws_client): deploy_result = deploy_cfn_template( template_path=os.path.join( @@ -128,7 +128,7 @@ def _sfn_finished_running(): assert "hello_with_path from stepfunctions" in execution_result["output"] -@markers.aws.unknown +@markers.aws.only_localstack def test_apigateway_invoke_localhost(deploy_cfn_template, aws_client): """tests the same as above but with the "generic" localhost version of invoking the apigateway""" deploy_result = deploy_cfn_template( @@ -174,7 +174,7 @@ def _sfn_finished_running(): assert "hello from stepfunctions" in execution_result["output"] -@markers.aws.unknown +@markers.aws.only_localstack def test_apigateway_invoke_localhost_with_path(deploy_cfn_template, aws_client): """tests the same as above but with the "generic" localhost version of invoking the apigateway""" deploy_result = deploy_cfn_template( diff --git a/tests/aws/services/cloudformation/test_template_engine.py b/tests/aws/services/cloudformation/test_template_engine.py index ad4dd27a9d8bf..6b49ef43449c3 100644 --- a/tests/aws/services/cloudformation/test_template_engine.py +++ b/tests/aws/services/cloudformation/test_template_engine.py @@ -117,7 +117,7 @@ class TestIntrinsicFunctions: ("Fn::Or", "1", "1", True), ], ) - @markers.aws.unknown + @markers.aws.validated def test_and_or_functions( self, intrinsic_fn, @@ -329,7 +329,7 @@ def test_create_stack_with_ssm_parameters( tags = aws_client.sns.list_tags_for_resource(ResourceArn=matching[0]) snapshot.match("topic-tags", tags) - @markers.aws.unknown + @markers.aws.validated def test_resolve_ssm(self, create_parameter, deploy_cfn_template): parameter_key = f"param-key-{short_uid()}" parameter_value = f"param-value-{short_uid()}" @@ -345,7 +345,7 @@ def test_resolve_ssm(self, create_parameter, deploy_cfn_template): topic_name = result.outputs["TopicName"] assert topic_name == parameter_value - @markers.aws.unknown + @markers.aws.validated def test_resolve_ssm_with_version(self, create_parameter, deploy_cfn_template, aws_client): parameter_key = f"param-key-{short_uid()}" parameter_value_v0 = f"param-value-{short_uid()}" @@ -371,7 +371,7 @@ def test_resolve_ssm_with_version(self, create_parameter, deploy_cfn_template, a topic_name = result.outputs["TopicName"] assert topic_name == parameter_value_v1 - @markers.aws.unknown + @markers.aws.needs_fixing def test_resolve_ssm_secure(self, create_parameter, deploy_cfn_template): parameter_key = f"param-key-{short_uid()}" parameter_value = f"param-value-{short_uid()}" @@ -398,7 +398,7 @@ class TestSecretsManagerParameters: "resolve_secretsmanager.yaml", ], ) - @markers.aws.unknown + @markers.aws.validated def test_resolve_secretsmanager(self, create_secret, deploy_cfn_template, template_name): parameter_key = f"param-key-{short_uid()}" parameter_value = f"param-value-{short_uid()}" diff --git a/tests/aws/services/lambda_/test_lambda_common.py b/tests/aws/services/lambda_/test_lambda_common.py index e1e7935c4df1e..15f44fc4936a0 100644 --- a/tests/aws/services/lambda_/test_lambda_common.py +++ b/tests/aws/services/lambda_/test_lambda_common.py @@ -250,7 +250,6 @@ def test_runtime_wrapper_invoke(self, multiruntime_lambda, snapshot, tmp_path, a # TODO: Split this and move to PRO -@pytest.mark.whitebox @pytest.mark.skipif( condition=is_old_provider(), reason="Local executor does not support the majority of the runtimes", @@ -271,7 +270,7 @@ class TestLambdaCallingLocalstack: "dotnet6", # TODO: does not yet support transparent endpoint injection ], ) - @markers.aws.unknown + @markers.aws.only_localstack def test_calling_localstack_from_lambda(self, multiruntime_lambda, tmp_path, aws_client): create_function_result = multiruntime_lambda.create_function( MemorySize=1024, diff --git a/tests/aws/services/lambda_/test_lambda_whitebox.py b/tests/aws/services/lambda_/test_lambda_whitebox.py index 46b7e73d990aa..7d68fa79773a1 100644 --- a/tests/aws/services/lambda_/test_lambda_whitebox.py +++ b/tests/aws/services/lambda_/test_lambda_whitebox.py @@ -76,7 +76,7 @@ def _run_forward_to_fallback_url( else: config.LAMBDA_FORWARD_URL = "" - @markers.aws.unknown + @markers.aws.only_localstack def test_forward_to_fallback_url_dynamodb(self, aws_client): db_table = f"lambda-records-{short_uid()}" ddb_client = aws_client.dynamodb @@ -89,7 +89,7 @@ def num_items(): items_after = num_items() assert items_before + 3 == items_after - @markers.aws.unknown + @markers.aws.only_localstack def test_forward_to_fallback_url_http(self, aws_client): lambda_client = aws_client.lambda_ lambda_result = {"result": "test123"} @@ -153,7 +153,7 @@ def _handler(_request: Request): # clean up / shutdown lambda_client.delete_function(FunctionName=lambda_name) - @markers.aws.unknown + @markers.aws.only_localstack def test_adding_fallback_function_name_in_headers(self, aws_client): lambda_client = aws_client.lambda_ ddb_client = aws_client.dynamodb @@ -176,7 +176,7 @@ def check_item(): class TestDockerExecutors: @pytest.mark.skipif(not use_docker(), reason="Only applicable with docker executor") - @markers.aws.unknown + @markers.aws.only_localstack def test_additional_docker_flags(self, aws_client): flags_before = config.LAMBDA_DOCKER_FLAGS env_value = short_uid() @@ -203,7 +203,7 @@ def test_additional_docker_flags(self, aws_client): # clean up lambda_client.delete_function(FunctionName=function_name) - @markers.aws.unknown + @markers.aws.only_localstack def test_code_updated_on_redeployment(self, aws_client): lambda_api.LAMBDA_EXECUTOR.cleanup() @@ -244,7 +244,7 @@ def test_code_updated_on_redeployment(self, aws_client): ), reason="Test only applicable if docker-reuse executor is selected", ) - @markers.aws.unknown + @markers.aws.only_localstack def test_prime_and_destroy_containers(self, aws_client): executor = lambda_api.LAMBDA_EXECUTOR func_name = f"test_prime_and_destroy_containers_{short_uid()}" @@ -315,7 +315,7 @@ def test_prime_and_destroy_containers(self, aws_client): ), reason="Test only applicable if docker-reuse executor is selected", ) - @markers.aws.unknown + @markers.aws.only_localstack def test_destroy_idle_containers(self, aws_client): executor = lambda_api.LAMBDA_EXECUTOR func_name = "test_destroy_idle_containers" @@ -364,7 +364,7 @@ def assert_container_destroyed(): ), reason="Test only applicable if docker-reuse executor is selected", ) - @markers.aws.unknown + @markers.aws.only_localstack def test_logresult_more_than_4k_characters(self, aws_client): lambda_api.LAMBDA_EXECUTOR.cleanup() @@ -388,7 +388,7 @@ def test_logresult_more_than_4k_characters(self, aws_client): class TestLocalExecutors: - @markers.aws.unknown + @markers.aws.only_localstack def test_python3_runtime_multiple_create_with_conflicting_module(self, aws_client): lambda_client = aws_client.lambda_ original_do_use_docker = lambda_api.DO_USE_DOCKER @@ -439,7 +439,7 @@ def test_python3_runtime_multiple_create_with_conflicting_module(self, aws_clien class TestFunctionStates: - @markers.aws.unknown + @markers.aws.only_localstack def test_invoke_failure_when_state_pending(self, lambda_su_role, monkeypatch, aws_client): """Tests if a lambda invocation fails if state is pending""" function_name = f"test-function-{short_uid()}" diff --git a/tests/aws/services/sqs/test_sqs.py b/tests/aws/services/sqs/test_sqs.py index 092f798fee4fc..7530237ed60ec 100644 --- a/tests/aws/services/sqs/test_sqs.py +++ b/tests/aws/services/sqs/test_sqs.py @@ -968,7 +968,7 @@ def test_terminate_visibility_timeout_after_receive(self, sqs_create_queue, aws_ response = aws_client.sqs.receive_message(QueueUrl=queue_url, WaitTimeSeconds=1) assert len(response["Messages"]) == 1 - @markers.aws.unknown + @markers.aws.needs_fixing def test_delete_message_batch_from_lambda( self, sqs_create_queue, create_lambda_function, aws_client ): @@ -2087,7 +2087,7 @@ def test_standard_queue_cannot_have_fifo_suffix(self, sqs_create_queue): e.match("InvalidParameterValue") @pytest.mark.xfail - @markers.aws.unknown + @markers.aws.validated def test_redrive_policy_attribute_validity(self, sqs_create_queue, sqs_queue_arn, aws_client): dl_queue_name = f"dl-queue-{short_uid()}" dl_queue_url = sqs_create_queue(QueueName=dl_queue_name) @@ -2502,7 +2502,7 @@ def test_dead_letter_queue_max_receive_count(self, sqs_create_queue, aws_client) == result_send["MessageId"] ) - @markers.aws.unknown + @markers.aws.needs_fixing def test_dead_letter_queue_chain(self, sqs_create_queue, aws_client): # test a chain of 3 queues, with DLQ flow q1 -> q2 -> q3 @@ -2835,7 +2835,7 @@ def test_system_attributes_have_no_effect_on_attr_md5(self, sqs_create_queue, aw == "5ae4d5d7636402d80f4eb6d213245a88" ) - @markers.aws.unknown + @markers.aws.validated def test_inflight_message_requeue(self, sqs_create_queue, aws_client): visibility_timeout = 3 queue_name = f"queue-{short_uid()}" @@ -3980,7 +3980,7 @@ def test_endpoint_strategy_with_multi_region( assert response.ok assert "foobar" in response.text - @markers.aws.unknown + @markers.aws.only_localstack def test_queue_url_format_path_strategy(self, sqs_create_queue, monkeypatch): monkeypatch.setattr(config, "SQS_ENDPOINT_STRATEGY", "path") queue_name = f"path_queue_{short_uid()}" diff --git a/tests/aws/services/stepfunctions/legacy/test_stepfunctions_legacy.py b/tests/aws/services/stepfunctions/legacy/test_stepfunctions_legacy.py index 961e7bd4962fa..50e3be0bcc05d 100644 --- a/tests/aws/services/stepfunctions/legacy/test_stepfunctions_legacy.py +++ b/tests/aws/services/stepfunctions/legacy/test_stepfunctions_legacy.py @@ -6,6 +6,7 @@ from localstack.services.events.provider import TEST_EVENTS_CACHE from localstack.services.stepfunctions.stepfunctions_utils import await_sfn_execution_result +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.utils import testutil from localstack.utils.aws import arns @@ -273,13 +274,14 @@ def get_machine_arn(sm_name, sfn_client): pytestmark = pytest.mark.skipif( - condition=is_new_provider(), reason="Test suite only for legacy provider." + condition=not is_aws_cloud() and is_new_provider(), + reason="Test suite only for legacy provider.", ) @pytest.mark.usefixtures("setup_and_tear_down") class TestStateMachine: - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_choice_state_machine(self, aws_client): state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] role_arn = arns.role_arn("sfn_role") @@ -317,7 +319,7 @@ def check_result(): # clean up cleanup(sm_arn, state_machines_before, sfn_client=aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_run_map_state_machine(self, aws_client): names = ["Bob", "Meg", "Joe"] test_input = [{"map": name} for name in names] @@ -357,7 +359,7 @@ def check_invocations(): # clean up cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_run_state_machine(self, aws_client): state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] @@ -393,7 +395,7 @@ def check_invocations(): # clean up cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_try_catch_state_machine(self, aws_client): if os.environ.get("AWS_DEFAULT_REGION") != "us-east-1": pytest.skip("skipping non us-east-1 temporarily") @@ -431,7 +433,7 @@ def check_invocations(): cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) # TODO: validate against AWS - @markers.aws.unknown + @markers.aws.needs_fixing def test_intrinsic_functions(self, aws_client): if os.environ.get("AWS_DEFAULT_REGION") != "us-east-1": pytest.skip("skipping non us-east-1 temporarily") @@ -473,7 +475,7 @@ def check_invocations(): # clean up cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_events_state_machine(self, aws_client): events = aws_client.events state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] @@ -514,7 +516,7 @@ def check_invocations(): cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) events.delete_event_bus(Name=bus_name) - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_state_machines_in_parallel(self, cleanups, aws_client): """ Perform a test that creates a series of state machines in parallel. Without concurrency control, using @@ -604,7 +606,7 @@ def _create_sm(*_): @pytest.mark.parametrize("region_name", ("us-east-1", "us-east-2", "eu-west-1", "eu-central-1")) @pytest.mark.parametrize("statemachine_definition", (TEST_STATE_MACHINE_3,)) # TODO: add sync2 test -@markers.aws.unknown +@markers.aws.needs_fixing def test_multiregion_nested(aws_client_factory, region_name, statemachine_definition): client1 = aws_client_factory(region_name=region_name).stepfunctions # create state machine @@ -682,7 +684,7 @@ def test_default_logging_configuration(create_state_machine, aws_client): @pytest.mark.skip("Does not work against Pro in new pipeline.") -@markers.aws.unknown +@markers.aws.needs_fixing def test_aws_sdk_task(sfn_execution_role, aws_client): statemachine_definition = { "StartAt": "CreateTopicTask", @@ -764,7 +766,7 @@ def _retry_execution(): @pytest.mark.skip("Does not work against Pro in new pipeline.") -@markers.aws.unknown +@markers.aws.needs_fixing def test_aws_sdk_task_delete_s3_object(s3_bucket, sfn_execution_role, aws_client): s3_key = "test-key" statemachine_definition = { diff --git a/tests/aws/services/stepfunctions/v2/base/test_base.py b/tests/aws/services/stepfunctions/v2/base/test_base.py index 985218b8aa79c..8523ba0ab1ba5 100644 --- a/tests/aws/services/stepfunctions/v2/base/test_base.py +++ b/tests/aws/services/stepfunctions/v2/base/test_base.py @@ -133,7 +133,7 @@ def test_event_bridge_events_base( ) @pytest.mark.skip(reason="flaky") # FIXME - @markers.aws.unknown + @markers.aws.needs_fixing def test_event_bridge_events_failure( self, create_iam_role_for_sfn, diff --git a/tests/aws/services/stepfunctions/v2/callback/test_callback.py b/tests/aws/services/stepfunctions/v2/callback/test_callback.py index 04e562589e096..c509d468c4f7a 100644 --- a/tests/aws/services/stepfunctions/v2/callback/test_callback.py +++ b/tests/aws/services/stepfunctions/v2/callback/test_callback.py @@ -34,7 +34,7 @@ ) class TestCallback: @markers.snapshot.skip_snapshot_verify(paths=["$..MD5OfMessageBody"]) - @markers.aws.unknown + @markers.aws.needs_fixing def test_sqs_wait_for_task_token( self, aws_client, @@ -75,7 +75,7 @@ def test_sqs_wait_for_task_token( ) @markers.snapshot.skip_snapshot_verify(paths=["$..MD5OfMessageBody"]) - @markers.aws.unknown + @markers.aws.needs_fixing def test_sqs_wait_for_task_token_timeout( self, aws_client, @@ -114,7 +114,7 @@ def test_sqs_wait_for_task_token_timeout( ) @markers.snapshot.skip_snapshot_verify(paths=["$..MD5OfMessageBody"]) - @markers.aws.unknown + @markers.aws.needs_fixing def test_sqs_failure_in_wait_for_task_token( self, aws_client, @@ -155,7 +155,7 @@ def test_sqs_failure_in_wait_for_task_token( ) @markers.snapshot.skip_snapshot_verify(paths=["$..MD5OfMessageBody"]) - @markers.aws.unknown + @markers.aws.needs_fixing def test_sqs_wait_for_task_tok_with_heartbeat( self, aws_client, @@ -196,7 +196,7 @@ def test_sqs_wait_for_task_tok_with_heartbeat( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_start_execution_sync( self, aws_client, @@ -243,7 +243,7 @@ def test_start_execution_sync( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_start_execution_sync2( self, aws_client, @@ -290,7 +290,7 @@ def test_start_execution_sync2( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_start_execution_sync_delegate_failure( self, aws_client, @@ -344,7 +344,7 @@ def test_start_execution_sync_delegate_failure( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_start_execution_sync_delegate_timeout( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py b/tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py index 46387744deb6d..5a151742d534d 100644 --- a/tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py +++ b/tests/aws/services/stepfunctions/v2/choice_operators/test_boolean_equals.py @@ -19,7 +19,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestBooleanEquals: - @markers.aws.unknown + @markers.aws.validated def test_boolean_equals( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -32,7 +32,7 @@ def test_boolean_equals( comparisons=TYPE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_boolean_equals_path( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py b/tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py index 6d48a918eedd8..8da6e25ae9369 100644 --- a/tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py +++ b/tests/aws/services/stepfunctions/v2/choice_operators/test_is_operators.py @@ -1,5 +1,6 @@ import pytest +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from tests.aws.services.stepfunctions.utils import is_old_provider from tests.aws.services.stepfunctions.v2.choice_operators.utils import ( @@ -19,7 +20,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestIsOperators: - @markers.aws.unknown + @markers.aws.validated def test_is_boolean( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -32,7 +33,7 @@ def test_is_boolean( comparisons=TYPE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_is_null(self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client): create_and_test_comparison_function( aws_client.stepfunctions, @@ -43,7 +44,7 @@ def test_is_null(self, create_iam_role_for_sfn, create_state_machine, sfn_snapsh comparisons=TYPE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_is_numeric( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -56,7 +57,7 @@ def test_is_numeric( comparisons=TYPE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_is_present( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -69,7 +70,7 @@ def test_is_present( comparisons=TYPE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_is_string( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -82,8 +83,10 @@ def test_is_string( comparisons=TYPE_COMPARISONS, ) - @pytest.mark.skip(reason="TODO: investigate IsTimestamp behaviour.") - @markers.aws.unknown + @pytest.mark.skipif( + condition=not is_aws_cloud(), reason="TODO: investigate IsTimestamp behaviour." + ) + @markers.aws.needs_fixing def test_is_timestamp( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py b/tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py index 57afb4870160e..8ba5d957ab495 100644 --- a/tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py +++ b/tests/aws/services/stepfunctions/v2/choice_operators/test_numeric.py @@ -36,7 +36,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestNumerics: - @markers.aws.unknown + @markers.aws.validated def test_numeric_equals( self, aws_client, @@ -60,7 +60,7 @@ def test_numeric_equals( comparisons=[*type_equals, (-0, 0), (0.0, 0), (2.22, 2.22)], ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_equals_path( self, aws_client, @@ -85,7 +85,7 @@ def test_numeric_equals_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_greater_than( self, aws_client, @@ -102,7 +102,7 @@ def test_numeric_greater_than( comparisons=[(-0, 0), (0.0, 0), (0, 1), (1, 1), (1, 0), (0, 1)], ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_greater_than_path( self, aws_client, @@ -120,7 +120,7 @@ def test_numeric_greater_than_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_greater_than_equals( self, aws_client, @@ -137,7 +137,7 @@ def test_numeric_greater_than_equals( comparisons=[(-0, 0), (0.0, 0), (0, 1), (1, 1), (1, 0), (0, 1)], ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_greater_than_equals_path( self, aws_client, @@ -155,7 +155,7 @@ def test_numeric_greater_than_equals_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_less_than( self, aws_client, @@ -172,7 +172,7 @@ def test_numeric_less_than( comparisons=[(-0, 0), (0.0, 0), (0, 1), (1, 1), (1, 0), (0, 1)], ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_less_than_path( self, aws_client, @@ -190,7 +190,7 @@ def test_numeric_less_than_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_less_than_equals( self, aws_client, @@ -207,7 +207,7 @@ def test_numeric_less_than_equals( comparisons=[(-0, 0), (0.0, 0), (0, 1), (1, 1), (1, 0), (0, 1)], ) - @markers.aws.unknown + @markers.aws.validated def test_numeric_less_than_equals_path( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py b/tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py index 7a7723be16fd5..5bb815023847b 100644 --- a/tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py +++ b/tests/aws/services/stepfunctions/v2/choice_operators/test_string_operators.py @@ -36,7 +36,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestStrings: - @markers.aws.unknown + @markers.aws.validated def test_string_equals( self, aws_client, @@ -57,7 +57,7 @@ def test_string_equals( comparisons=[*type_equals, (" ", " "), ("\t\n", "\t\r\n"), ("Hello", "Hello")], ) - @markers.aws.unknown + @markers.aws.validated def test_string_equals_path( self, aws_client, @@ -82,7 +82,7 @@ def test_string_equals_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_string_greater_than( self, aws_client, @@ -99,7 +99,7 @@ def test_string_greater_than( comparisons=[("", ""), ("A", "A "), ("A", "A\t\n\r"), ("AB", "ABC")], ) - @markers.aws.unknown + @markers.aws.validated def test_string_greater_than_path( self, aws_client, @@ -117,7 +117,7 @@ def test_string_greater_than_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_string_greater_than_equals( self, aws_client, @@ -134,7 +134,7 @@ def test_string_greater_than_equals( comparisons=[("", ""), ("A", "AB"), ("AB", "A")], ) - @markers.aws.unknown + @markers.aws.validated def test_string_greater_than_equals_path( self, aws_client, @@ -152,7 +152,7 @@ def test_string_greater_than_equals_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_string_less_than( self, aws_client, @@ -169,7 +169,7 @@ def test_string_less_than( comparisons=[("", ""), ("A", "AB"), ("AB", "A")], ) - @markers.aws.unknown + @markers.aws.validated def test_string_less_than_path( self, aws_client, @@ -187,7 +187,7 @@ def test_string_less_than_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_string_less_than_equals( self, aws_client, @@ -204,7 +204,7 @@ def test_string_less_than_equals( comparisons=[("", ""), ("A", "AB"), ("AB", "A")], ) - @markers.aws.unknown + @markers.aws.validated def test_string_less_than_equals_path( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py b/tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py index 2e0cd8f418d79..ac31bed5a62a5 100644 --- a/tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py +++ b/tests/aws/services/stepfunctions/v2/choice_operators/test_timestamp_operators.py @@ -41,7 +41,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestTimestamps: - @markers.aws.unknown + @markers.aws.validated def test_timestamp_equals( self, aws_client, @@ -62,7 +62,7 @@ def test_timestamp_equals( comparisons=[*type_equals, *BASE_COMPARISONS], ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_equals_path( self, aws_client, @@ -80,7 +80,7 @@ def test_timestamp_equals_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_greater_than( self, aws_client, @@ -97,7 +97,7 @@ def test_timestamp_greater_than( comparisons=BASE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_greater_than_path( self, aws_client, @@ -115,7 +115,7 @@ def test_timestamp_greater_than_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_greater_than_equals( self, aws_client, @@ -132,7 +132,7 @@ def test_timestamp_greater_than_equals( comparisons=BASE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_greater_than_equals_path( self, aws_client, @@ -150,7 +150,7 @@ def test_timestamp_greater_than_equals_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_less_than( self, aws_client, @@ -167,7 +167,7 @@ def test_timestamp_less_than( comparisons=BASE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_less_than_path( self, aws_client, @@ -185,7 +185,7 @@ def test_timestamp_less_than_path( add_literal_value=False, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_less_than_equals( self, aws_client, @@ -202,7 +202,7 @@ def test_timestamp_less_than_equals( comparisons=BASE_COMPARISONS, ) - @markers.aws.unknown + @markers.aws.validated def test_timestamp_less_than_equals_path( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py b/tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py index 76d16683a6637..edb07e5b7385a 100644 --- a/tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py +++ b/tests/aws/services/stepfunctions/v2/error_handling/test_aws_sdk.py @@ -2,6 +2,7 @@ import pytest +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.testing.snapshots.transformer import RegexTransformer from localstack.utils.strings import short_uid @@ -19,7 +20,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestAwsSdk: - @markers.aws.unknown + @markers.aws.validated def test_invalid_secret_name( self, aws_client, create_iam_role_for_sfn, create_state_machine, sfn_snapshot ): @@ -35,7 +36,7 @@ def test_invalid_secret_name( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_no_such_bucket( self, aws_client, create_iam_role_for_sfn, create_state_machine, sfn_snapshot ): @@ -53,9 +54,12 @@ def test_no_such_bucket( exec_input, ) - @pytest.mark.skip(reason="No parameters validation for dynamodb api calls being returned.") + @pytest.mark.skipif( + condition=not is_aws_cloud(), + reason="No parameters validation for dynamodb api calls being returned.", + ) @markers.snapshot.skip_snapshot_verify(paths=["$..cause"]) - @markers.aws.unknown + @markers.aws.validated def test_dynamodb_invalid_param( self, aws_client, @@ -82,7 +86,7 @@ def test_dynamodb_invalid_param( ) @markers.snapshot.skip_snapshot_verify(paths=["$..cause"]) - @markers.aws.unknown + @markers.aws.validated def test_dynamodb_put_item_no_such_table( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py b/tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py index 3019a5015c119..30c67d07caa55 100644 --- a/tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py +++ b/tests/aws/services/stepfunctions/v2/error_handling/test_task_lambda.py @@ -25,7 +25,7 @@ ] ) class TestTaskLambda: - @markers.aws.unknown + @markers.aws.validated def test_raise_exception( self, aws_client, @@ -58,7 +58,7 @@ def test_raise_exception( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_raise_exception_catch( self, aws_client, @@ -91,7 +91,7 @@ def test_raise_exception_catch( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_no_such_function( self, aws_client, @@ -124,7 +124,7 @@ def test_no_such_function( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_no_such_function_catch( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py b/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py index ca044fa5bdc4b..fe05dec27a1c2 100644 --- a/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py +++ b/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_lambda.py @@ -22,7 +22,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestTaskServiceLambda: - @markers.aws.unknown + @markers.aws.validated def test_raise_exception( self, aws_client, @@ -52,7 +52,7 @@ def test_raise_exception( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_raise_exception_catch( self, aws_client, @@ -82,7 +82,7 @@ def test_raise_exception_catch( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_no_such_function( self, aws_client, @@ -112,7 +112,7 @@ def test_no_such_function( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_no_such_function_catch( self, aws_client, @@ -142,7 +142,7 @@ def test_no_such_function_catch( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_timeout( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sfn.py b/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sfn.py index 91a5bd341ce55..134fadfe239e8 100644 --- a/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sfn.py +++ b/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sfn.py @@ -31,7 +31,7 @@ ] ) class TestTaskServiceSfn: - @markers.aws.unknown + @markers.aws.validated def test_start_execution_no_such_arn( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py b/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py index 4dcfd92d6c5e8..d28124b6217f0 100644 --- a/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py +++ b/tests/aws/services/stepfunctions/v2/error_handling/test_task_service_sqs.py @@ -2,6 +2,7 @@ import pytest +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.testing.snapshots.transformer import JsonpathTransformer, RegexTransformer from localstack.utils.strings import short_uid @@ -32,7 +33,7 @@ ] ) class TestTaskServiceSqs: - @markers.aws.unknown + @markers.aws.needs_fixing def test_send_message_no_such_queue( self, aws_client, @@ -61,7 +62,7 @@ def test_send_message_no_such_queue( exec_input, ) - @markers.aws.unknown + @markers.aws.needs_fixing def test_send_message_no_such_queue_no_catch( self, aws_client, @@ -90,8 +91,10 @@ def test_send_message_no_such_queue_no_catch( exec_input, ) - @pytest.mark.skip("SQS does not raise error on empty body.") - @markers.aws.unknown + @pytest.mark.skipif( + condition=not is_aws_cloud(), reason="SQS does not raise error on empty body." + ) + @markers.aws.validated def test_send_message_empty_body( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py index f597e92c0ad82..99f8b597fbba5 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_array.py @@ -21,7 +21,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestArray: - @markers.aws.unknown + @markers.aws.validated def test_array_0(self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client): create_and_test_on_inputs( aws_client.stepfunctions, @@ -32,7 +32,7 @@ def test_array_0(self, create_iam_role_for_sfn, create_state_machine, sfn_snapsh ["HelloWorld"], ) - @markers.aws.unknown + @markers.aws.validated def test_array_2(self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client): values = [ "", @@ -56,7 +56,7 @@ def test_array_2(self, create_iam_role_for_sfn, create_state_machine, sfn_snapsh input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_array_partition( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -74,7 +74,7 @@ def test_array_partition( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_array_contains( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -101,7 +101,7 @@ def test_array_contains( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_array_range( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -123,7 +123,7 @@ def test_array_range( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_array_get_item( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -137,7 +137,7 @@ def test_array_get_item( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_array_length( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -151,7 +151,7 @@ def test_array_length( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_array_unique( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py index 84651427eb302..a38f519eaa1d7 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_encode_decode.py @@ -19,7 +19,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestEncodeDecode: - @markers.aws.unknown + @markers.aws.validated def test_base_64_encode( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -33,7 +33,7 @@ def test_base_64_encode( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_base_64_decode( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py index b4fd1d590743c..235612b871905 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_generic.py @@ -21,7 +21,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestGeneric: - @markers.aws.unknown + @markers.aws.validated def test_format_1( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -35,7 +35,7 @@ def test_format_1( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_format_2( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_hash_calculations.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_hash_calculations.py index b083ae09c816e..fd5f8d0601077 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_hash_calculations.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_hash_calculations.py @@ -19,7 +19,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestHashCalculations: - @markers.aws.unknown + @markers.aws.validated def test_hash(self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client): hash_bindings = [ ("input data", "MD5"), diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py index 2734d13eb3fdf..c7042827bcff2 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_json_manipulation.py @@ -21,7 +21,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestJsonManipulation: - @markers.aws.unknown + @markers.aws.validated def test_string_to_json( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -46,7 +46,7 @@ def test_string_to_json( input_values, ) - @markers.aws.unknown + @markers.aws.validated def test_json_to_string( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -70,7 +70,7 @@ def test_json_to_string( input_values_jsons, ) - @markers.aws.unknown + @markers.aws.validated def test_json_merge( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py index 14fd8678662f1..ae76f49c4a8a4 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py @@ -2,6 +2,7 @@ import pytest +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.testing.snapshots.transformer import JsonpathTransformer, RegexTransformer from localstack.utils.strings import short_uid @@ -12,7 +13,7 @@ from tests.aws.services.stepfunctions.v2.intrinsic_functions.utils import create_and_test_on_inputs pytestmark = pytest.mark.skipif( - condition=is_old_provider(), reason="Test suite for v2 provider only." + condition=is_old_provider() and not is_aws_cloud(), reason="Test suite for v2 provider only." ) @@ -23,7 +24,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestMathOperations: - @markers.aws.unknown + @markers.aws.validated def test_math_random( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -76,7 +77,7 @@ def test_math_random( ) sfn_snapshot.match(f"exec_hist_resp_{i}", exec_hist_resp) - @markers.aws.unknown + @markers.aws.validated def test_math_random_seeded( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -124,11 +125,35 @@ def test_math_random_seeded( exec_hist_resp = aws_client.stepfunctions.get_execution_history(executionArn=execution_arn) sfn_snapshot.match("exec_hist_resp", exec_hist_resp) - @markers.aws.unknown + @markers.aws.validated def test_math_add( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): - add_tuples = [(-9, 3), (1.49, 1.50), (1.50, 1.51), (-1.49, -1.50), (-1.50, -1.51)] + add_tuples = [ + (-9, 3), + (1.49, 1.50), + (1.50, 1.51), + (-1.49, -1.50), + (-1.50, -1.51), + (1.49, 0), + (1.49, -1.49), + (1.50, 0), + (1.51, 0), + (-1.49, 0), + (-1.50, 0), + (-1.51, 0), + # below are cases specifically to verify java vs. python rounding + # python by default would round to even + (0.5, 0), # python: 0, # java: 1 + (1.5, 0), # python: 2, # java: 2 + (2.5, 0), # python: 2, # java: 3 + (3.5, 0), # python: 4, # java: 4 + (-0.5, 0.5), # python: 0, # java: 1 + (-0.5, 0), # python: 0, # java: -1 + (-1.5, 0), # python: -2, # java: -2 + (-2.5, 0), # python: -2, # java: -3 + (-3.5, 0), # python: -4, # java: -4 + ] input_values = list() for fst, snd in add_tuples: input_values.append({"fst": fst, "snd": snd}) diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.snapshot.json b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.snapshot.json index 2ddfaa35e8965..eae19b6b4313b 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.snapshot.json +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.snapshot.json @@ -304,7 +304,7 @@ } }, "tests/aws/services/stepfunctions/v2/intrinsic_functions/test_math_operations.py::TestMathOperations::test_math_add": { - "recorded-date": "13-02-2023, 14:51:11", + "recorded-date": "13-09-2023, 23:07:34", "recorded-content": { "exec_hist_resp_0": { "events": [ @@ -423,7 +423,7 @@ "stateExitedEventDetails": { "name": "State_0", "output": { - "FunctionResult": 2 + "FunctionResult": 3 }, "outputDetails": { "truncated": false @@ -435,7 +435,7 @@ { "executionSucceededEventDetails": { "output": { - "FunctionResult": 2 + "FunctionResult": 3 }, "outputDetails": { "truncated": false @@ -496,7 +496,7 @@ "stateExitedEventDetails": { "name": "State_0", "output": { - "FunctionResult": 2 + "FunctionResult": 4 }, "outputDetails": { "truncated": false @@ -508,7 +508,7 @@ { "executionSucceededEventDetails": { "output": { - "FunctionResult": 2 + "FunctionResult": 4 }, "outputDetails": { "truncated": false @@ -642,7 +642,7 @@ "stateExitedEventDetails": { "name": "State_0", "output": { - "FunctionResult": -2 + "FunctionResult": -3 }, "outputDetails": { "truncated": false @@ -654,7 +654,1175 @@ { "executionSucceededEventDetails": { "output": { - "FunctionResult": -2 + "FunctionResult": -3 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_5": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.49, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.49, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 1 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 1 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_6": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.49, + "snd": -1.49 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.49, + "snd": -1.49 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 0 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 0 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_7": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 2 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 2 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_8": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.51, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.51, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 2 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 2 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_9": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.49, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.49, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": -1 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": -1 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_10": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": -1 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": -1 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_11": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.51, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.51, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": -2 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": -2 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_12": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 0.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 0.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 1 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 1 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_13": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 2 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 2 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_14": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 2.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 2.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 3 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 3 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_15": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": 3.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": 3.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 4 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 4 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_16": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -0.5, + "snd": 0.5 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -0.5, + "snd": 0.5 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 1 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 1 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_17": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -0.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -0.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": 0 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": 0 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_18": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -1.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": -1 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": -1 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_19": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -2.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -2.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": -2 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": -2 + }, + "outputDetails": { + "truncated": false + } + }, + "id": 4, + "previousEventId": 3, + "timestamp": "timestamp", + "type": "ExecutionSucceeded" + } + ], + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "exec_hist_resp_20": { + "events": [ + { + "executionStartedEventDetails": { + "input": { + "FunctionInput": { + "fst": -3.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "roleArn": "snf_role_arn" + }, + "id": 1, + "previousEventId": 0, + "timestamp": "timestamp", + "type": "ExecutionStarted" + }, + { + "id": 2, + "previousEventId": 0, + "stateEnteredEventDetails": { + "input": { + "FunctionInput": { + "fst": -3.5, + "snd": 0 + } + }, + "inputDetails": { + "truncated": false + }, + "name": "State_0" + }, + "timestamp": "timestamp", + "type": "PassStateEntered" + }, + { + "id": 3, + "previousEventId": 2, + "stateExitedEventDetails": { + "name": "State_0", + "output": { + "FunctionResult": -3 + }, + "outputDetails": { + "truncated": false + } + }, + "timestamp": "timestamp", + "type": "PassStateExited" + }, + { + "executionSucceededEventDetails": { + "output": { + "FunctionResult": -3 }, "outputDetails": { "truncated": false diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py index 9ad7c0fa212b5..60ffb2e3ae4ab 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_string_operations.py @@ -19,7 +19,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestStringOperations: - @markers.aws.unknown + @markers.aws.validated def test_string_split( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_unique_id_generation.py b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_unique_id_generation.py index 8684403c2e5d6..55b48c61fe79e 100644 --- a/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_unique_id_generation.py +++ b/tests/aws/services/stepfunctions/v2/intrinsic_functions/test_unique_id_generation.py @@ -20,7 +20,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestUniqueIdGeneration: - @markers.aws.unknown + @markers.aws.validated def test_uuid(self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client): snf_role_arn = create_iam_role_for_sfn() sfn_snapshot.add_transformer(RegexTransformer(snf_role_arn, "snf_role_arn")) diff --git a/tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py b/tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py index d31174b0f9aa1..fb2f7cd29d3b8 100644 --- a/tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py +++ b/tests/aws/services/stepfunctions/v2/scenarios/test_base_scenarios.py @@ -18,7 +18,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestBaseScenarios: - @markers.aws.unknown + @markers.aws.validated def test_parallel_state( self, aws_client, @@ -40,7 +40,7 @@ def test_parallel_state( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state( self, aws_client, @@ -61,7 +61,7 @@ def test_map_state( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_legacy( self, aws_client, @@ -82,7 +82,7 @@ def test_map_state_legacy( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_item_selector( self, aws_client, @@ -103,7 +103,7 @@ def test_map_state_item_selector( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_parameters_legacy( self, aws_client, @@ -124,7 +124,7 @@ def test_map_state_parameters_legacy( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_item_selector_singleton( self, aws_client, @@ -145,7 +145,7 @@ def test_map_state_item_selector_singleton( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_parameters_singleton_legacy( self, aws_client, @@ -166,7 +166,7 @@ def test_map_state_parameters_singleton_legacy( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_catch( self, aws_client, @@ -208,7 +208,7 @@ def test_map_state_catch_empty_fail( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_catch_legacy( self, aws_client, @@ -229,7 +229,7 @@ def test_map_state_catch_legacy( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_retry( self, aws_client, @@ -250,7 +250,7 @@ def test_map_state_retry( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_retry_multiple_retriers( self, aws_client, @@ -271,7 +271,7 @@ def test_map_state_retry_multiple_retriers( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_retry_legacy( self, aws_client, @@ -292,7 +292,7 @@ def test_map_state_retry_legacy( exec_input, ) - @markers.aws.unknown + @markers.aws.needs_fixing def test_map_state_break_condition( self, aws_client, @@ -313,7 +313,7 @@ def test_map_state_break_condition( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_map_state_break_condition_legacy( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py b/tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py index 39f0735c3e57a..65665476304b6 100644 --- a/tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py +++ b/tests/aws/services/stepfunctions/v2/services/test_apigetway_task_service.py @@ -186,7 +186,7 @@ def _create_lambda_api_response( invocation_url = f"{config.service_url('apigateway')}/restapis/{api_id}" return invocation_url, stage_name - @markers.aws.unknown + @markers.aws.validated def test_invoke_base( self, aws_client, @@ -236,7 +236,7 @@ def test_invoke_base( {"message": "HelloWorld!"}, ], ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_with_body_post( self, aws_client, @@ -291,7 +291,7 @@ def test_invoke_with_body_post( "$..output.ResponseBody" ] ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_with_query_parameters( self, aws_client, @@ -349,7 +349,7 @@ def test_invoke_with_query_parameters( "$..cause", ] ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_error( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py b/tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py index bdf60df8dd83f..99b6e0ad95c98 100644 --- a/tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py +++ b/tests/aws/services/stepfunctions/v2/services/test_aws_sdk_task_service.py @@ -26,7 +26,7 @@ ) class TestTaskServiceAwsSdk: @markers.snapshot.skip_snapshot_verify(paths=["$..SecretList"]) - @markers.aws.unknown + @markers.aws.validated def test_list_secrets( self, aws_client, create_iam_role_for_sfn, create_state_machine, sfn_snapshot ): diff --git a/tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py b/tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py index 8b8f37915be47..4df6a8049647c 100644 --- a/tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py +++ b/tests/aws/services/stepfunctions/v2/services/test_dynamodb_task_service.py @@ -25,7 +25,7 @@ ] ) class TestTaskServiceDynamoDB: - @markers.aws.unknown + @markers.aws.needs_fixing def test_put_get_item( self, aws_client, @@ -58,7 +58,7 @@ def test_put_get_item( exec_input, ) - @markers.aws.unknown + @markers.aws.needs_fixing def test_put_delete_item( self, aws_client, @@ -91,7 +91,7 @@ def test_put_delete_item( exec_input, ) - @markers.aws.unknown + @markers.aws.needs_fixing def test_put_update_get_item( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/services/test_lambda_task.py b/tests/aws/services/stepfunctions/v2/services/test_lambda_task.py index c246a16d1e95c..276f58e085a1a 100644 --- a/tests/aws/services/stepfunctions/v2/services/test_lambda_task.py +++ b/tests/aws/services/stepfunctions/v2/services/test_lambda_task.py @@ -20,7 +20,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestTaskLambda: - @markers.aws.unknown + @markers.aws.validated def test_invoke_bytes_payload( self, aws_client, @@ -65,7 +65,7 @@ def test_invoke_bytes_payload( [], ], ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_json_values( self, aws_client, @@ -99,7 +99,7 @@ def test_invoke_json_values( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_pipe( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py b/tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py index 81aace2018a79..e17c7aa2cb92d 100644 --- a/tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py +++ b/tests/aws/services/stepfunctions/v2/services/test_lambda_task_service.py @@ -3,6 +3,7 @@ import pytest from localstack.aws.api.lambda_ import LogType +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.testing.snapshots.transformer import JsonpathTransformer, RegexTransformer from localstack.utils.strings import short_uid @@ -27,7 +28,7 @@ ] ) class TestTaskServiceLambda: - @markers.aws.unknown + @markers.aws.validated def test_invoke( self, aws_client, @@ -57,7 +58,7 @@ def test_invoke( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_bytes_payload( self, aws_client, @@ -90,7 +91,7 @@ def test_invoke_bytes_payload( ) # AWS's stepfuctions documentation seems to incorrectly classify LogType parameters as unsupported. - @markers.aws.unknown + @markers.aws.validated def test_invoke_unsupported_param( self, aws_client, @@ -137,7 +138,7 @@ def test_invoke_unsupported_param( [], ], ) - @markers.aws.unknown + @markers.aws.validated def test_invoke_json_values( self, aws_client, @@ -171,8 +172,11 @@ def test_invoke_json_values( exec_input, ) - @pytest.mark.skip(reason="Add support for Invalid State Machine Definition errors") - @markers.aws.unknown + @pytest.mark.skipif( + condition=not is_aws_cloud(), + reason="Add support for Invalid State Machine Definition errors", + ) + @markers.aws.needs_fixing def test_list_functions( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py b/tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py index e0facf33bcb9e..10c2e9cf1b98e 100644 --- a/tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py +++ b/tests/aws/services/stepfunctions/v2/services/test_sfn_task_service.py @@ -30,7 +30,7 @@ ] ) class TestTaskServiceSfn: - @markers.aws.unknown + @markers.aws.needs_fixing def test_start_execution( self, aws_client, @@ -70,7 +70,7 @@ def test_start_execution( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_start_execution_input_json( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py b/tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py index 29ff3af8cf8fb..39e075fc6f6f0 100644 --- a/tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py +++ b/tests/aws/services/stepfunctions/v2/services/test_sqs_task_service.py @@ -30,7 +30,7 @@ ] ) class TestTaskServiceSqs: - @markers.aws.unknown + @markers.aws.needs_fixing def test_send_message( self, aws_client, @@ -64,7 +64,7 @@ def test_send_message( assert len(receive_message_res["Messages"]) == 1 assert receive_message_res["Messages"][0]["Body"] == message_body - @markers.aws.unknown + @markers.aws.needs_fixing def test_send_message_unsupported_parameters( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/test_sfn_api.py b/tests/aws/services/stepfunctions/v2/test_sfn_api.py index 4aec7b4c78502..072bed75ada7b 100644 --- a/tests/aws/services/stepfunctions/v2/test_sfn_api.py +++ b/tests/aws/services/stepfunctions/v2/test_sfn_api.py @@ -28,7 +28,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestSnfApi: - @markers.aws.unknown + @markers.aws.validated def test_create_delete_valid_sm( self, create_iam_role_for_sfn, @@ -73,7 +73,7 @@ def test_create_delete_valid_sm( "$..message", ] ) - @markers.aws.unknown + @markers.aws.validated def test_create_delete_invalid_sm( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot ): @@ -89,7 +89,7 @@ def test_create_delete_invalid_sm( create_state_machine(name=sm_name, definition=definition_str, roleArn=snf_role_arn) sfn_snapshot.match("invalid_definition_1", resource_not_found.value.response) - @markers.aws.unknown + @markers.aws.validated def test_delete_nonexistent_sm( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -113,7 +113,7 @@ def test_delete_nonexistent_sm( ) sfn_snapshot.match("deletion_resp_1", deletion_resp_1) - @markers.aws.unknown + @markers.aws.validated def test_create_exact_duplicate_sm( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -153,7 +153,7 @@ def test_create_exact_duplicate_sm( ) sfn_snapshot.match("describe_resp_1_2", describe_resp_1_2) - @markers.aws.unknown + @markers.aws.validated def test_create_duplicate_definition_format_sm( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -181,7 +181,7 @@ def test_create_duplicate_definition_format_sm( create_state_machine(name=sm_name, definition=definition_str_2, roleArn=snf_role_arn) sfn_snapshot.match("already_exists_1", resource_not_found.value.response) - @markers.aws.unknown + @markers.aws.validated def test_create_duplicate_sm_name( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -212,7 +212,7 @@ def test_create_duplicate_sm_name( create_state_machine(name=sm_name, definition=definition_str_2, roleArn=snf_role_arn) sfn_snapshot.match("already_exists_1", resource_not_found.value.response) - @markers.aws.unknown + @markers.aws.needs_fixing def test_list_sms( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -268,7 +268,7 @@ def test_list_sms( lst_resp = aws_client.stepfunctions.list_state_machines() sfn_snapshot.match("lst_resp_del_end", lst_resp) - @markers.aws.unknown + @markers.aws.needs_fixing def test_start_execution( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -301,7 +301,7 @@ def test_start_execution( exec_hist_resp = aws_client.stepfunctions.get_execution_history(executionArn=execution_arn) sfn_snapshot.match("exec_hist_resp", exec_hist_resp) - @markers.aws.unknown + @markers.aws.validated def test_invalid_start_execution_arn( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -329,7 +329,7 @@ def test_invalid_start_execution_arn( sfn_snapshot.match("start_exec_of_deleted", resource_not_found.value.response) @markers.snapshot.skip_snapshot_verify(paths=["$..Error.Message", "$..message"]) - @markers.aws.unknown + @markers.aws.validated def test_invalid_start_execution_input( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): @@ -381,7 +381,7 @@ def test_invalid_start_execution_input( sfn_snapshot.add_transformer(sfn_snapshot.transform.sfn_sm_exec_arn(start_res_null, 2)) sfn_snapshot.match("start_res_null", start_res_null) - @markers.aws.unknown + @markers.aws.validated def test_stop_execution( self, create_iam_role_for_sfn, create_state_machine, sfn_snapshot, aws_client ): diff --git a/tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py b/tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py index 7725c93aba395..09346b95d71c6 100644 --- a/tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py +++ b/tests/aws/services/stepfunctions/v2/test_sfn_api_versioning.py @@ -23,7 +23,7 @@ paths=["$..loggingConfiguration", "$..tracingConfiguration", "$..previousEventId"] ) class TestSnfApiVersioning: - @markers.aws.unknown + @markers.aws.validated def test_create_with_publish( self, create_iam_role_for_sfn, @@ -44,7 +44,7 @@ def test_create_with_publish( sfn_snapshot.add_transformer(sfn_snapshot.transform.sfn_sm_create_arn(creation_resp_1, 0)) sfn_snapshot.match("creation_resp_1", creation_resp_1) - @markers.aws.unknown + @markers.aws.validated def test_create_with_version_description_no_publish( self, create_iam_role_for_sfn, @@ -68,7 +68,7 @@ def test_create_with_version_description_no_publish( ) sfn_snapshot.match("validation_exception", validation_exception.value.response) - @markers.aws.unknown + @markers.aws.validated def test_create_publish_describe_no_version_description( self, create_iam_role_for_sfn, @@ -101,7 +101,7 @@ def test_create_publish_describe_no_version_description( ) sfn_snapshot.match("describe_resp", describe_resp) - @markers.aws.unknown + @markers.aws.validated def test_create_publish_describe_with_version_description( self, create_iam_role_for_sfn, @@ -138,7 +138,7 @@ def test_create_publish_describe_with_version_description( ) sfn_snapshot.match("describe_resp", describe_resp) - @markers.aws.unknown + @markers.aws.validated def test_list_delete_version( self, create_iam_role_for_sfn, @@ -194,7 +194,7 @@ def test_list_delete_version( ) sfn_snapshot.match("delete_version_resp_after_del", delete_version_resp_after_del) - @markers.aws.unknown + @markers.aws.validated def test_update_state_machine( self, create_iam_role_for_sfn, @@ -271,7 +271,7 @@ def test_update_state_machine( ) sfn_snapshot.match("invalid_arn_2", invalid_arn_2.value.response) - @markers.aws.unknown + @markers.aws.validated def test_publish_state_machine_version( self, create_iam_role_for_sfn, @@ -367,7 +367,7 @@ def test_publish_state_machine_version( ) sfn_snapshot.match("conflict_exception", conflict_exception.value) - @markers.aws.unknown + @markers.aws.validated def test_start_version_execution( self, create_iam_role_for_sfn, @@ -432,7 +432,7 @@ def test_start_version_execution( ) sfn_snapshot.match("exec_version_list_resp", exec_version_list_resp) - @markers.aws.unknown + @markers.aws.validated def test_version_ids_between_deletions( self, create_iam_role_for_sfn, @@ -481,7 +481,7 @@ def test_version_ids_between_deletions( ) sfn_snapshot.match("publish_res_v2_2", publish_res_v2_2) - @markers.aws.unknown + @markers.aws.validated def test_idempotent_publish( self, create_iam_role_for_sfn, @@ -521,7 +521,7 @@ def test_idempotent_publish( ) sfn_snapshot.match("list_versions_resp", list_versions_resp) - @markers.aws.unknown + @markers.aws.validated def test_empty_revision_with_publish_and_publish_on_creation( self, create_iam_role_for_sfn, @@ -553,7 +553,7 @@ def test_empty_revision_with_publish_and_publish_on_creation( ) sfn_snapshot.match("update_resp_2", update_resp_2) - @markers.aws.unknown + @markers.aws.validated def test_empty_revision_with_publish_and_no_publish_on_creation( self, create_iam_role_for_sfn, diff --git a/tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py b/tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py index 80b2db7f0250b..bb29a2f2a0257 100644 --- a/tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py +++ b/tests/aws/services/stepfunctions/v2/test_stepfunctions_v2.py @@ -9,6 +9,7 @@ SECONDARY_TEST_AWS_SECRET_ACCESS_KEY, ) from localstack.services.events.provider import TEST_EVENTS_CACHE +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.utils import testutil from localstack.utils.aws import arns @@ -278,7 +279,7 @@ def get_machine_arn(sm_name, sfn_client): @pytest.mark.usefixtures("setup_and_tear_down") class TestStateMachine: - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_choice_state_machine(self, aws_client): state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] role_arn = arns.role_arn("sfn_role") @@ -316,7 +317,7 @@ def check_result(): # clean up cleanup(sm_arn, state_machines_before, sfn_client=aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_run_map_state_machine(self, aws_client): names = ["Bob", "Meg", "Joe"] test_input = [{"map": name} for name in names] @@ -356,7 +357,7 @@ def check_invocations(): # clean up cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_run_state_machine(self, aws_client): state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] @@ -392,7 +393,7 @@ def check_invocations(): # clean up cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_try_catch_state_machine(self, aws_client): state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] @@ -426,7 +427,7 @@ def check_invocations(): # clean up cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) - @markers.aws.unknown + @markers.aws.needs_fixing def test_intrinsic_functions(self, aws_client): state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] @@ -465,8 +466,10 @@ def check_invocations(): # clean up cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) - @pytest.mark.skip("Accurate events reporting not yet supported.") - @markers.aws.unknown + @pytest.mark.skipif( + condition=not is_aws_cloud(), reason="Accurate events reporting not yet supported." + ) + @markers.aws.needs_fixing def test_events_state_machine(self, aws_client): events = aws_client.events state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] @@ -507,7 +510,7 @@ def check_invocations(): cleanup(sm_arn, state_machines_before, aws_client.stepfunctions) events.delete_event_bus(Name=bus_name) - @markers.aws.unknown + @markers.aws.needs_fixing def test_create_state_machines_in_parallel(self, cleanups, aws_client): """ Perform a test that creates a series of state machines in parallel. Without concurrency control, using @@ -596,10 +599,12 @@ def _create_sm(*_): } -@pytest.mark.skip("Investigate error around states:startExecution.sync") +@pytest.mark.skipif( + condition=not is_aws_cloud(), reason="Investigate error around states:startExecution.sync" +) @pytest.mark.parametrize("region_name", ("us-east-1", "us-east-2", "eu-west-1", "eu-central-1")) @pytest.mark.parametrize("statemachine_definition", (TEST_STATE_MACHINE_3,)) # TODO: add sync2 test -@markers.aws.unknown +@markers.aws.needs_fixing def test_multiregion_nested(aws_client_factory, region_name, statemachine_definition): client1 = aws_client_factory( region_name=region_name, @@ -682,7 +687,7 @@ def test_default_logging_configuration(create_state_machine, aws_client): aws_client.iam.delete_role(RoleName=role_name) -@markers.aws.unknown +@markers.aws.validated def test_aws_sdk_task(aws_client): statemachine_definition = { "StartAt": "CreateTopicTask", @@ -773,7 +778,7 @@ def _retry_execution(): aws_client.stepfunctions.delete_state_machine(stateMachineArn=machine_arn) -@markers.aws.unknown +@markers.aws.needs_fixing def test_run_aws_sdk_secrets_manager(aws_client): state_machines_before = aws_client.stepfunctions.list_state_machines()["stateMachines"] diff --git a/tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py b/tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py index 2876155b56f28..14adb4e68ec73 100644 --- a/tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py +++ b/tests/aws/services/stepfunctions/v2/timeouts/test_heartbeats.py @@ -26,7 +26,7 @@ ) class TestHeartbeats: @markers.snapshot.skip_snapshot_verify(paths=["$..MD5OfMessageBody"]) - @markers.aws.unknown + @markers.aws.needs_fixing def test_heartbeat_timeout( self, aws_client, @@ -65,7 +65,7 @@ def test_heartbeat_timeout( ) @markers.snapshot.skip_snapshot_verify(paths=["$..MD5OfMessageBody"]) - @markers.aws.unknown + @markers.aws.needs_fixing def test_heartbeat_path_timeout( self, aws_client, @@ -108,7 +108,7 @@ def test_heartbeat_path_timeout( ) @markers.snapshot.skip_snapshot_verify(paths=["$..MD5OfMessageBody"]) - @markers.aws.unknown + @markers.aws.needs_fixing def test_heartbeat_no_timeout( self, aws_client, diff --git a/tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py b/tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py index 3ef1897960749..d8fbf5a9fc2f3 100644 --- a/tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py +++ b/tests/aws/services/stepfunctions/v2/timeouts/test_timeouts.py @@ -2,6 +2,7 @@ import pytest +from localstack.testing.aws.util import is_aws_cloud from localstack.testing.pytest import markers from localstack.testing.snapshots.transformer import RegexTransformer from localstack.utils.strings import short_uid @@ -59,7 +60,7 @@ def test_global_timeout( describe_execution = aws_client.stepfunctions.describe_execution(executionArn=execution_arn) sfn_snapshot.match("describe_execution", describe_execution) - @markers.aws.unknown + @markers.aws.validated def test_fixed_timeout_service_lambda( self, aws_client, @@ -89,7 +90,7 @@ def test_fixed_timeout_service_lambda( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_fixed_timeout_service_lambda_with_path( self, aws_client, @@ -123,7 +124,7 @@ def test_fixed_timeout_service_lambda_with_path( exec_input, ) - @markers.aws.unknown + @markers.aws.validated def test_fixed_timeout_lambda( self, aws_client, @@ -155,8 +156,10 @@ def test_fixed_timeout_lambda( exec_input, ) - @pytest.mark.skip(reason="Add support for State Map event history first.") - @markers.aws.unknown + @pytest.mark.skipif( + condition=not is_aws_cloud(), reason="Add support for State Map event history first." + ) + @markers.aws.needs_fixing def test_service_lambda_map_timeout( self, aws_client, diff --git a/tests/aws/templates/stepfunctions_statemachine_substitutions.yaml b/tests/aws/templates/stepfunctions_statemachine_substitutions.yaml index 0e994f63df63a..2289e3a90ebcf 100644 --- a/tests/aws/templates/stepfunctions_statemachine_substitutions.yaml +++ b/tests/aws/templates/stepfunctions_statemachine_substitutions.yaml @@ -60,7 +60,7 @@ Resources: - startFnServiceRoleB86C6980 - Arn Handler: index.handler - Runtime: nodejs12.x + Runtime: nodejs16.x DependsOn: - startFnServiceRoleB86C6980 stm: diff --git a/tests/aws/test_moto.py b/tests/aws/test_moto.py index 79b44aab81e67..5bbb0b36fb522 100644 --- a/tests/aws/test_moto.py +++ b/tests/aws/test_moto.py @@ -14,7 +14,7 @@ from localstack.utils.common import short_uid -@markers.aws.unknown +@markers.aws.only_localstack def test_call_with_sqs_creates_state_correctly(): qname = f"queue-{short_uid()}" @@ -37,7 +37,7 @@ def test_call_with_sqs_creates_state_correctly(): assert url not in response.get("QueueUrls", []) -@markers.aws.unknown +@markers.aws.only_localstack def test_call_sqs_invalid_call_raises_http_exception(): with pytest.raises(ServiceException) as e: moto.call_moto( @@ -52,7 +52,7 @@ def test_call_sqs_invalid_call_raises_http_exception(): e.match("The specified queue does not exist") -@markers.aws.unknown +@markers.aws.only_localstack def test_call_non_implemented_operation(): with pytest.raises(NotImplementedError): # we'll need to keep finding methods that moto doesn't implement ;-) @@ -61,7 +61,7 @@ def test_call_non_implemented_operation(): ) -@markers.aws.unknown +@markers.aws.only_localstack def test_call_with_sqs_modifies_state_in_moto_backend(): """Whitebox test to check that moto backends are populated correctly""" from moto.sqs.models import sqs_backends @@ -80,7 +80,7 @@ def test_call_with_sqs_modifies_state_in_moto_backend(): @pytest.mark.parametrize( "payload", ["foobar", b"foobar", BytesIO(b"foobar")], ids=["str", "bytes", "IO[bytes]"] ) -@markers.aws.unknown +@markers.aws.only_localstack def test_call_s3_with_streaming_trait(payload, monkeypatch): monkeypatch.setenv("MOTO_S3_CUSTOM_ENDPOINTS", "s3.localhost.localstack.cloud:4566") @@ -118,7 +118,7 @@ def test_call_s3_with_streaming_trait(payload, monkeypatch): moto.call_moto(moto.create_aws_request_context("s3", "DeleteBucket", {"Bucket": bucket_name})) -@markers.aws.unknown +@markers.aws.only_localstack def test_call_include_response_metadata(): ctx = moto.create_aws_request_context("sqs", "ListQueues") @@ -129,7 +129,7 @@ def test_call_include_response_metadata(): assert "ResponseMetadata" in response -@markers.aws.unknown +@markers.aws.only_localstack def test_call_with_modified_request(): from moto.sqs.models import sqs_backends @@ -146,7 +146,7 @@ def test_call_with_modified_request(): moto.call_moto(moto.create_aws_request_context("sqs", "DeleteQueue", {"QueueUrl": url})) -@markers.aws.unknown +@markers.aws.only_localstack def test_call_with_es_creates_state_correctly(): domain_name = f"domain-{short_uid()}" response = moto.call_moto( @@ -175,7 +175,7 @@ def test_call_with_es_creates_state_correctly(): assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 -@markers.aws.unknown +@markers.aws.only_localstack def test_call_multi_region_backends(): from moto.sqs.models import sqs_backends @@ -203,7 +203,7 @@ def test_call_multi_region_backends(): del sqs_backends[DEFAULT_MOTO_ACCOUNT_ID]["eu-central-1"].queues[qname_eu] -@markers.aws.unknown +@markers.aws.only_localstack def test_call_with_sqs_invalid_call_raises_exception(): with pytest.raises(ServiceException): moto.call_moto( @@ -217,7 +217,7 @@ def test_call_with_sqs_invalid_call_raises_exception(): ) -@markers.aws.unknown +@markers.aws.only_localstack def test_call_with_sqs_returns_service_response(): qname = f"queue-{short_uid()}" @@ -250,7 +250,7 @@ def list_queues(self, context, request): return moto.call_moto(context) -@markers.aws.unknown +@markers.aws.only_localstack def test_moto_fallback_dispatcher(): provider = FakeSqsProvider() dispatcher = MotoFallbackDispatcher(provider) @@ -307,7 +307,7 @@ def put_object(self, _, __): raise NotImplementedAvoidFallbackError -@markers.aws.unknown +@markers.aws.only_localstack def test_moto_fallback_dispatcher_error_handling(monkeypatch): """ This test checks if the error handling (marshalling / unmarshalling) works correctly on all levels, including @@ -343,7 +343,7 @@ def _dispatch(action, params): _dispatch("PutObject", {"Bucket": bucket_name, "Key": "key"}) -@markers.aws.unknown +@markers.aws.only_localstack def test_request_with_response_header_location_fields(): # CreateHostedZoneResponse has a member "Location" that's located in the headers zone_name = f"zone-{short_uid()}.com" diff --git a/tests/aws/test_multi_accounts.py b/tests/aws/test_multi_accounts.py index f2efe8169c2cf..00cc871adca83 100644 --- a/tests/aws/test_multi_accounts.py +++ b/tests/aws/test_multi_accounts.py @@ -18,7 +18,7 @@ def _client_factory(service: str, aws_access_key_id: str, region_name: str = "eu class TestMultiAccounts: - @markers.aws.unknown + @markers.aws.only_localstack def test_account_id_namespacing_for_moto_backends(self, client_factory): # # ACM @@ -70,7 +70,7 @@ def test_account_id_namespacing_for_moto_backends(self, client_factory): vpcs = ec2_client1.describe_vpcs()["Vpcs"] assert all([vpc["OwnerId"] == account_id1 for vpc in vpcs]) - @markers.aws.unknown + @markers.aws.only_localstack def test_account_id_namespacing_for_localstack_backends(self, client_factory): # Ensure resources are isolated by account ID namespaces account_id1 = "420420420420" @@ -104,7 +104,7 @@ def test_account_id_namespacing_for_localstack_backends(self, client_factory): assert len(sns_client2.list_tags_for_resource(ResourceArn=arn2)["Tags"]) == 2 assert len(sns_client2.list_tags_for_resource(ResourceArn=arn3)["Tags"]) == 1 - @markers.aws.unknown + @markers.aws.only_localstack def test_multi_accounts_dynamodb(self, client_factory, cleanups): """DynamoDB depends on an external service - DynamoDB Local""" account_id1 = "420420420420" @@ -175,7 +175,7 @@ def test_multi_accounts_dynamodb(self, client_factory, cleanups): response = ddb_client3.describe_table(TableName=tab1) assert response["Table"]["ItemCount"] == 3 - @markers.aws.unknown + @markers.aws.only_localstack def test_multi_accounts_kinesis(self, client_factory): """Test that multi-accounts work with external dependency, Kinesis Mock.""" account_id1 = "420420420420" diff --git a/tests/aws/test_terraform.py b/tests/aws/test_terraform.py index 8f898c15f0758..566948762074f 100644 --- a/tests/aws/test_terraform.py +++ b/tests/aws/test_terraform.py @@ -96,7 +96,7 @@ def _run(*args): start_worker_thread(_run) @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_bucket_exists(self, aws_client): response = aws_client.s3.head_bucket(Bucket=BUCKET_NAME) assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 @@ -116,7 +116,7 @@ def test_bucket_exists(self, aws_client): assert response["Status"] == "Enabled" @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_sqs(self, aws_client): queue_url = aws_client.sqs.get_queue_url(QueueName=QUEUE_NAME)["QueueUrl"] response = aws_client.sqs.get_queue_attributes(QueueUrl=queue_url, AttributeNames=["All"]) @@ -127,7 +127,7 @@ def test_sqs(self, aws_client): assert response["Attributes"]["ReceiveMessageWaitTimeSeconds"] == "10" @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_lambda(self, aws_client): account_id = get_aws_account_id() response = aws_client.lambda_.get_function(FunctionName=LAMBDA_NAME) @@ -137,7 +137,7 @@ def test_lambda(self, aws_client): assert response["Configuration"]["Role"] == LAMBDA_ROLE.format(account_id=account_id) @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_event_source_mapping(self, aws_client): queue_arn = QUEUE_ARN.format(account_id=get_aws_account_id()) lambda_arn = LAMBDA_ARN.format(account_id=get_aws_account_id(), lambda_name=LAMBDA_NAME) @@ -150,7 +150,7 @@ def test_event_source_mapping(self, aws_client): @markers.skip_offline @pytest.mark.xfail(reason="flaky") - @markers.aws.unknown + @markers.aws.needs_fixing def test_apigateway(self, aws_client): rest_apis = aws_client.apigateway.get_rest_apis() @@ -180,7 +180,7 @@ def test_apigateway(self, aws_client): assert res2[0]["resourceMethods"]["GET"]["methodIntegration"]["uri"] @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_route53(self, aws_client): response = aws_client.route53.create_hosted_zone(Name="zone123", CallerReference="ref123") assert response["ResponseMetadata"]["HTTPStatusCode"] == 201 @@ -190,7 +190,7 @@ def test_route53(self, aws_client): assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_acm(self, aws_client): certs = aws_client.acm.list_certificates()["CertificateSummaryList"] certs = [c for c in certs if c.get("DomainName") == "example.com"] @@ -198,7 +198,7 @@ def test_acm(self, aws_client): @markers.skip_offline @pytest.mark.xfail(reason="flaky") - @markers.aws.unknown + @markers.aws.needs_fixing def test_apigateway_escaped_policy(self, aws_client): rest_apis = aws_client.apigateway.get_rest_apis() @@ -211,7 +211,7 @@ def test_apigateway_escaped_policy(self, aws_client): assert len(service_apis) == 1 @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_dynamodb(self, aws_client): def _table_exists(tablename, dynamotables): return any(name for name in dynamotables["TableNames"] if name == tablename) @@ -222,7 +222,7 @@ def _table_exists(tablename, dynamotables): assert _table_exists("tf_dynamotable3", tables) @markers.skip_offline - @markers.aws.unknown + @markers.aws.needs_fixing def test_security_groups(self, aws_client): rules = aws_client.ec2.describe_security_groups(MaxResults=100)["SecurityGroups"] matching = [r for r in rules if r["Description"] == "TF SG with ingress / egress rules"]