Skip to content

Commit

Permalink
Triage a few aws_unknown markers (sfn, cfn & others) (localstack#9141)
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikschubert authored Sep 13, 2023
1 parent c35d069 commit fa10d1d
Show file tree
Hide file tree
Showing 48 changed files with 1,508 additions and 276 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import decimal
from typing import Any

from localstack.services.stepfunctions.asl.component.intrinsic.argument.function_argument_list import (
Expand All @@ -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.
#
Expand Down Expand Up @@ -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)
Expand Down
41 changes: 18 additions & 23 deletions tests/aws/services/cloudformation/api/test_changesets.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
):
Expand Down Expand Up @@ -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()}"
Expand All @@ -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()}"
Expand All @@ -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()}"
Expand All @@ -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()}"
Expand All @@ -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()}"
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions tests/aws/services/cloudformation/api/test_stacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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")
Expand Down
17 changes: 10 additions & 7 deletions tests/aws/services/cloudformation/resources/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()}"

Expand Down Expand Up @@ -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()}"
Expand All @@ -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()}"
Expand Down Expand Up @@ -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(
Expand All @@ -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()
Expand Down Expand Up @@ -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()}"
Expand All @@ -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"]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down
10 changes: 5 additions & 5 deletions tests/aws/services/cloudformation/test_template_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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()}"
Expand All @@ -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()}"
Expand All @@ -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()}"
Expand All @@ -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()}"
Expand Down
3 changes: 1 addition & 2 deletions tests/aws/services/lambda_/test_lambda_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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,
Expand Down
Loading

0 comments on commit fa10d1d

Please sign in to comment.