Update integration test to use Pytest (#3703)
* Refactor int test to use pytest * Add comments to int test script
This commit is contained in:
parent
613b1395b8
commit
d3ad9d6686
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
# Runs a test to verify whether each service has the correct dependencies listed in setup.py
|
# Runs a test to verify whether each service has the correct dependencies listed in setup.py
|
||||||
#
|
#
|
||||||
|
# Tests that depend on multiple services are assumed to be located in dedicated testfiles (and ignored during this test)
|
||||||
|
# (test_*_integration.py/test_*_cloudformation.py)
|
||||||
|
#
|
||||||
# ::Algorithm::
|
# ::Algorithm::
|
||||||
# For each valid service:
|
# For each valid service:
|
||||||
# - Create a virtual environment
|
# - Create a virtual environment
|
||||||
@ -48,13 +51,14 @@ test_service() {
|
|||||||
# Can't just install requirements-file, as it points to all dependencies
|
# Can't just install requirements-file, as it points to all dependencies
|
||||||
pip install -r requirements-tests.txt > /dev/null
|
pip install -r requirements-tests.txt > /dev/null
|
||||||
pip install .[$service] > /dev/null 2>&1
|
pip install .[$service] > /dev/null 2>&1
|
||||||
|
pip install boto > /dev/null 2>&1
|
||||||
# Restart venv - ensure these deps are loaded
|
# Restart venv - ensure these deps are loaded
|
||||||
deactivate
|
deactivate
|
||||||
source ${venv_path}/bin/activate > /dev/null
|
source ${venv_path}/bin/activate > /dev/null
|
||||||
# Run tests for this service
|
# Run tests for this service
|
||||||
test_result_filename="test_results_${service}.log"
|
test_result_filename="test_results_${service}.log"
|
||||||
touch $test_result_filename
|
touch $test_result_filename
|
||||||
nosetests -qxs --ignore-files="test_server\.py" --ignore-files="test_${service}_cloudformation\.py" --ignore-files="test_integration\.py" $path_to_test_file >$test_result_filename 2>&1
|
pytest -sv --ignore-glob="**/test_server.py" --ignore-glob="**/test_*_cloudformation.py" --ignore-glob="**/test_*_integration.py" $path_to_test_file >$test_result_filename 2>&1
|
||||||
RESULT=$?
|
RESULT=$?
|
||||||
if [[ $RESULT != 0 ]]; then
|
if [[ $RESULT != 0 ]]; then
|
||||||
echo -e "Tests for ${service} have failed!\n"
|
echo -e "Tests for ${service} have failed!\n"
|
||||||
|
@ -6,14 +6,10 @@ import boto3
|
|||||||
|
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
from botocore.parsers import ResponseParserError
|
from botocore.parsers import ResponseParserError
|
||||||
import json
|
|
||||||
import sure # noqa
|
import sure # noqa
|
||||||
import random
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from moto import (
|
from moto import (
|
||||||
settings,
|
settings,
|
||||||
mock_cloudformation,
|
|
||||||
mock_ec2,
|
mock_ec2,
|
||||||
mock_s3,
|
mock_s3,
|
||||||
mock_logs,
|
mock_logs,
|
||||||
@ -630,48 +626,3 @@ def test_flow_logs_by_ids():
|
|||||||
flow_logs = client.delete_flow_logs(FlowLogIds=[fl2])
|
flow_logs = client.delete_flow_logs(FlowLogIds=[fl2])
|
||||||
flow_logs = client.describe_flow_logs()["FlowLogs"]
|
flow_logs = client.describe_flow_logs()["FlowLogs"]
|
||||||
flow_logs.should.have.length_of(0)
|
flow_logs.should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
@mock_cloudformation
|
|
||||||
@mock_ec2
|
|
||||||
@mock_s3
|
|
||||||
def test_flow_logs_by_cloudformation():
|
|
||||||
s3 = boto3.resource("s3", region_name="us-west-1")
|
|
||||||
client = boto3.client("ec2", region_name="us-west-1")
|
|
||||||
cf_client = boto3.client("cloudformation", "us-west-1")
|
|
||||||
|
|
||||||
vpc = client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
|
||||||
|
|
||||||
bucket = s3.create_bucket(
|
|
||||||
Bucket="test-flow-logs",
|
|
||||||
CreateBucketConfiguration={"LocationConstraint": "us-west-1"},
|
|
||||||
)
|
|
||||||
|
|
||||||
flow_log_template = {
|
|
||||||
"AWSTemplateFormatVersion": "2010-09-09",
|
|
||||||
"Description": "Template for VPC Flow Logs creation.",
|
|
||||||
"Resources": {
|
|
||||||
"TestFlowLogs": {
|
|
||||||
"Type": "AWS::EC2::FlowLog",
|
|
||||||
"Properties": {
|
|
||||||
"ResourceType": "VPC",
|
|
||||||
"ResourceId": vpc["VpcId"],
|
|
||||||
"TrafficType": "ALL",
|
|
||||||
"LogDestinationType": "s3",
|
|
||||||
"LogDestination": "arn:aws:s3:::" + bucket.name,
|
|
||||||
"MaxAggregationInterval": "60",
|
|
||||||
"Tags": [{"Key": "foo", "Value": "bar"}],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
flow_log_template_json = json.dumps(flow_log_template)
|
|
||||||
stack_id = cf_client.create_stack(
|
|
||||||
StackName="test_stack", TemplateBody=flow_log_template_json
|
|
||||||
)["StackId"]
|
|
||||||
|
|
||||||
flow_logs = client.describe_flow_logs()["FlowLogs"]
|
|
||||||
flow_logs.should.have.length_of(1)
|
|
||||||
flow_logs[0]["ResourceId"].should.equal(vpc["VpcId"])
|
|
||||||
flow_logs[0]["LogDestination"].should.equal("arn:aws:s3:::" + bucket.name)
|
|
||||||
flow_logs[0]["MaxAggregationInterval"].should.equal(60)
|
|
||||||
|
95
tests/test_ec2/test_flow_logs_cloudformation.py
Normal file
95
tests/test_ec2/test_flow_logs_cloudformation.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
from moto import (
|
||||||
|
mock_cloudformation,
|
||||||
|
mock_ec2,
|
||||||
|
mock_s3,
|
||||||
|
)
|
||||||
|
from tests import EXAMPLE_AMI_ID
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cloudformation
|
||||||
|
@mock_ec2
|
||||||
|
@mock_s3
|
||||||
|
def test_flow_logs_by_cloudformation():
|
||||||
|
s3 = boto3.resource("s3", region_name="us-west-1")
|
||||||
|
client = boto3.client("ec2", region_name="us-west-1")
|
||||||
|
cf_client = boto3.client("cloudformation", "us-west-1")
|
||||||
|
|
||||||
|
vpc = client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
|
||||||
|
|
||||||
|
bucket = s3.create_bucket(
|
||||||
|
Bucket="test-flow-logs",
|
||||||
|
CreateBucketConfiguration={"LocationConstraint": "us-west-1"},
|
||||||
|
)
|
||||||
|
|
||||||
|
flow_log_template = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "Template for VPC Flow Logs creation.",
|
||||||
|
"Resources": {
|
||||||
|
"TestFlowLogs": {
|
||||||
|
"Type": "AWS::EC2::FlowLog",
|
||||||
|
"Properties": {
|
||||||
|
"ResourceType": "VPC",
|
||||||
|
"ResourceId": vpc["VpcId"],
|
||||||
|
"TrafficType": "ALL",
|
||||||
|
"LogDestinationType": "s3",
|
||||||
|
"LogDestination": "arn:aws:s3:::" + bucket.name,
|
||||||
|
"MaxAggregationInterval": "60",
|
||||||
|
"Tags": [{"Key": "foo", "Value": "bar"}],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
flow_log_template_json = json.dumps(flow_log_template)
|
||||||
|
stack_id = cf_client.create_stack(
|
||||||
|
StackName="test_stack", TemplateBody=flow_log_template_json
|
||||||
|
)["StackId"]
|
||||||
|
|
||||||
|
flow_logs = client.describe_flow_logs()["FlowLogs"]
|
||||||
|
flow_logs.should.have.length_of(1)
|
||||||
|
flow_logs[0]["ResourceId"].should.equal(vpc["VpcId"])
|
||||||
|
flow_logs[0]["LogDestination"].should.equal("arn:aws:s3:::" + bucket.name)
|
||||||
|
flow_logs[0]["MaxAggregationInterval"].should.equal(60)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_cloudformation
|
||||||
|
def test_cloudformation():
|
||||||
|
dummy_template_json = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Resources": {
|
||||||
|
"InstanceProfile": {
|
||||||
|
"Type": "AWS::IAM::InstanceProfile",
|
||||||
|
"Properties": {"Path": "/", "Roles": []},
|
||||||
|
},
|
||||||
|
"Ec2Instance": {
|
||||||
|
"Type": "AWS::EC2::Instance",
|
||||||
|
"Properties": {
|
||||||
|
"IamInstanceProfile": {"Ref": "InstanceProfile"},
|
||||||
|
"KeyName": "mykey1",
|
||||||
|
"ImageId": EXAMPLE_AMI_ID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||||
|
cf_conn.create_stack(
|
||||||
|
StackName="test_stack", TemplateBody=json.dumps(dummy_template_json)
|
||||||
|
)
|
||||||
|
associations = client.describe_iam_instance_profile_associations()
|
||||||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(1)
|
||||||
|
associations["IamInstanceProfileAssociations"][0]["IamInstanceProfile"][
|
||||||
|
"Arn"
|
||||||
|
].should.contain("test_stack")
|
||||||
|
|
||||||
|
cf_conn.delete_stack(StackName="test_stack")
|
||||||
|
associations = client.describe_iam_instance_profile_associations()
|
||||||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(0)
|
@ -307,40 +307,3 @@ def test_invalid_disassociate():
|
|||||||
client.disassociate_iam_instance_profile(AssociationId="fake",)
|
client.disassociate_iam_instance_profile(AssociationId="fake",)
|
||||||
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
|
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
|
||||||
ex.value.response["Error"]["Message"].should.contain("An invalid association-id of")
|
ex.value.response["Error"]["Message"].should.contain("An invalid association-id of")
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
|
||||||
@mock_cloudformation
|
|
||||||
def test_cloudformation():
|
|
||||||
dummy_template_json = {
|
|
||||||
"AWSTemplateFormatVersion": "2010-09-09",
|
|
||||||
"Resources": {
|
|
||||||
"InstanceProfile": {
|
|
||||||
"Type": "AWS::IAM::InstanceProfile",
|
|
||||||
"Properties": {"Path": "/", "Roles": []},
|
|
||||||
},
|
|
||||||
"Ec2Instance": {
|
|
||||||
"Type": "AWS::EC2::Instance",
|
|
||||||
"Properties": {
|
|
||||||
"IamInstanceProfile": {"Ref": "InstanceProfile"},
|
|
||||||
"KeyName": "mykey1",
|
|
||||||
"ImageId": EXAMPLE_AMI_ID,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
client = boto3.client("ec2", region_name="us-east-1")
|
|
||||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
|
||||||
cf_conn.create_stack(
|
|
||||||
StackName="test_stack", TemplateBody=json.dumps(dummy_template_json)
|
|
||||||
)
|
|
||||||
associations = client.describe_iam_instance_profile_associations()
|
|
||||||
associations["IamInstanceProfileAssociations"].should.have.length_of(1)
|
|
||||||
associations["IamInstanceProfileAssociations"][0]["IamInstanceProfile"][
|
|
||||||
"Arn"
|
|
||||||
].should.contain("test_stack")
|
|
||||||
|
|
||||||
cf_conn.delete_stack(StackName="test_stack")
|
|
||||||
associations = client.describe_iam_instance_profile_associations()
|
|
||||||
associations["IamInstanceProfileAssociations"].should.have.length_of(0)
|
|
@ -983,198 +983,6 @@ def test_state_machine_get_execution_history_contains_expected_failure_events_wh
|
|||||||
execution_history["events"].should.equal(expected_events)
|
execution_history["events"].should.equal(expected_events)
|
||||||
|
|
||||||
|
|
||||||
@mock_stepfunctions
|
|
||||||
@mock_cloudformation
|
|
||||||
def test_state_machine_cloudformation():
|
|
||||||
sf = boto3.client("stepfunctions", region_name="us-east-1")
|
|
||||||
cf = boto3.resource("cloudformation", region_name="us-east-1")
|
|
||||||
definition = '{"StartAt": "HelloWorld", "States": {"HelloWorld": {"Type": "Task", "Resource": "arn:aws:lambda:us-east-1:111122223333;:function:HelloFunction", "End": true}}}'
|
|
||||||
role_arn = (
|
|
||||||
"arn:aws:iam::111122223333:role/service-role/StatesExecutionRole-us-east-1;"
|
|
||||||
)
|
|
||||||
template = {
|
|
||||||
"AWSTemplateFormatVersion": "2010-09-09",
|
|
||||||
"Description": "An example template for a Step Functions state machine.",
|
|
||||||
"Resources": {
|
|
||||||
"MyStateMachine": {
|
|
||||||
"Type": "AWS::StepFunctions::StateMachine",
|
|
||||||
"Properties": {
|
|
||||||
"StateMachineName": "HelloWorld-StateMachine",
|
|
||||||
"StateMachineType": "STANDARD",
|
|
||||||
"DefinitionString": definition,
|
|
||||||
"RoleArn": role_arn,
|
|
||||||
"Tags": [
|
|
||||||
{"Key": "key1", "Value": "value1"},
|
|
||||||
{"Key": "key2", "Value": "value2"},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Outputs": {
|
|
||||||
"StateMachineArn": {"Value": {"Ref": "MyStateMachine"}},
|
|
||||||
"StateMachineName": {"Value": {"Fn::GetAtt": ["MyStateMachine", "Name"]}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
cf.create_stack(StackName="test_stack", TemplateBody=json.dumps(template))
|
|
||||||
outputs_list = cf.Stack("test_stack").outputs
|
|
||||||
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
|
||||||
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
|
||||||
state_machine["stateMachineArn"].should.equal(output["StateMachineArn"])
|
|
||||||
state_machine["name"].should.equal(output["StateMachineName"])
|
|
||||||
state_machine["roleArn"].should.equal(role_arn)
|
|
||||||
state_machine["definition"].should.equal(definition)
|
|
||||||
tags = sf.list_tags_for_resource(resourceArn=output["StateMachineArn"]).get("tags")
|
|
||||||
for i, tag in enumerate(tags, 1):
|
|
||||||
tag["key"].should.equal("key{}".format(i))
|
|
||||||
tag["value"].should.equal("value{}".format(i))
|
|
||||||
|
|
||||||
cf.Stack("test_stack").delete()
|
|
||||||
with pytest.raises(ClientError) as ex:
|
|
||||||
sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
|
||||||
ex.value.response["Error"]["Code"].should.equal("StateMachineDoesNotExist")
|
|
||||||
ex.value.response["Error"]["Message"].should.contain("Does Not Exist")
|
|
||||||
|
|
||||||
|
|
||||||
@mock_stepfunctions
|
|
||||||
@mock_cloudformation
|
|
||||||
def test_state_machine_cloudformation_update_with_replacement():
|
|
||||||
sf = boto3.client("stepfunctions", region_name="us-east-1")
|
|
||||||
cf = boto3.resource("cloudformation", region_name="us-east-1")
|
|
||||||
definition = '{"StartAt": "HelloWorld", "States": {"HelloWorld": {"Type": "Task", "Resource": "arn:aws:lambda:us-east-1:111122223333;:function:HelloFunction", "End": true}}}'
|
|
||||||
role_arn = (
|
|
||||||
"arn:aws:iam::111122223333:role/service-role/StatesExecutionRole-us-east-1"
|
|
||||||
)
|
|
||||||
properties = {
|
|
||||||
"StateMachineName": "HelloWorld-StateMachine",
|
|
||||||
"DefinitionString": definition,
|
|
||||||
"RoleArn": role_arn,
|
|
||||||
"Tags": [
|
|
||||||
{"Key": "key1", "Value": "value1"},
|
|
||||||
{"Key": "key2", "Value": "value2"},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
template = {
|
|
||||||
"AWSTemplateFormatVersion": "2010-09-09",
|
|
||||||
"Description": "An example template for a Step Functions state machine.",
|
|
||||||
"Resources": {
|
|
||||||
"MyStateMachine": {
|
|
||||||
"Type": "AWS::StepFunctions::StateMachine",
|
|
||||||
"Properties": {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Outputs": {
|
|
||||||
"StateMachineArn": {"Value": {"Ref": "MyStateMachine"}},
|
|
||||||
"StateMachineName": {"Value": {"Fn::GetAtt": ["MyStateMachine", "Name"]}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
template["Resources"]["MyStateMachine"]["Properties"] = properties
|
|
||||||
cf.create_stack(StackName="test_stack", TemplateBody=json.dumps(template))
|
|
||||||
outputs_list = cf.Stack("test_stack").outputs
|
|
||||||
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
|
||||||
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
|
||||||
original_machine_arn = state_machine["stateMachineArn"]
|
|
||||||
original_creation_date = state_machine["creationDate"]
|
|
||||||
|
|
||||||
# Update State Machine, with replacement.
|
|
||||||
updated_role = role_arn + "-updated"
|
|
||||||
updated_definition = definition.replace("HelloWorld", "HelloWorld2")
|
|
||||||
updated_properties = {
|
|
||||||
"StateMachineName": "New-StateMachine-Name",
|
|
||||||
"DefinitionString": updated_definition,
|
|
||||||
"RoleArn": updated_role,
|
|
||||||
"Tags": [
|
|
||||||
{"Key": "key3", "Value": "value3"},
|
|
||||||
{"Key": "key1", "Value": "updated_value"},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
template["Resources"]["MyStateMachine"]["Properties"] = updated_properties
|
|
||||||
cf.Stack("test_stack").update(TemplateBody=json.dumps(template))
|
|
||||||
outputs_list = cf.Stack("test_stack").outputs
|
|
||||||
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
|
||||||
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
|
||||||
state_machine["stateMachineArn"].should_not.equal(original_machine_arn)
|
|
||||||
state_machine["name"].should.equal("New-StateMachine-Name")
|
|
||||||
state_machine["creationDate"].should.be.greater_than(original_creation_date)
|
|
||||||
state_machine["roleArn"].should.equal(updated_role)
|
|
||||||
state_machine["definition"].should.equal(updated_definition)
|
|
||||||
tags = sf.list_tags_for_resource(resourceArn=output["StateMachineArn"]).get("tags")
|
|
||||||
tags.should.have.length_of(3)
|
|
||||||
for tag in tags:
|
|
||||||
if tag["key"] == "key1":
|
|
||||||
tag["value"].should.equal("updated_value")
|
|
||||||
|
|
||||||
with pytest.raises(ClientError) as ex:
|
|
||||||
sf.describe_state_machine(stateMachineArn=original_machine_arn)
|
|
||||||
ex.value.response["Error"]["Code"].should.equal("StateMachineDoesNotExist")
|
|
||||||
ex.value.response["Error"]["Message"].should.contain("State Machine Does Not Exist")
|
|
||||||
|
|
||||||
|
|
||||||
@mock_stepfunctions
|
|
||||||
@mock_cloudformation
|
|
||||||
def test_state_machine_cloudformation_update_with_no_interruption():
|
|
||||||
sf = boto3.client("stepfunctions", region_name="us-east-1")
|
|
||||||
cf = boto3.resource("cloudformation", region_name="us-east-1")
|
|
||||||
definition = '{"StartAt": "HelloWorld", "States": {"HelloWorld": {"Type": "Task", "Resource": "arn:aws:lambda:us-east-1:111122223333;:function:HelloFunction", "End": true}}}'
|
|
||||||
role_arn = (
|
|
||||||
"arn:aws:iam::111122223333:role/service-role/StatesExecutionRole-us-east-1"
|
|
||||||
)
|
|
||||||
properties = {
|
|
||||||
"StateMachineName": "HelloWorld-StateMachine",
|
|
||||||
"DefinitionString": definition,
|
|
||||||
"RoleArn": role_arn,
|
|
||||||
"Tags": [
|
|
||||||
{"Key": "key1", "Value": "value1"},
|
|
||||||
{"Key": "key2", "Value": "value2"},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
template = {
|
|
||||||
"AWSTemplateFormatVersion": "2010-09-09",
|
|
||||||
"Description": "An example template for a Step Functions state machine.",
|
|
||||||
"Resources": {
|
|
||||||
"MyStateMachine": {
|
|
||||||
"Type": "AWS::StepFunctions::StateMachine",
|
|
||||||
"Properties": {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Outputs": {
|
|
||||||
"StateMachineArn": {"Value": {"Ref": "MyStateMachine"}},
|
|
||||||
"StateMachineName": {"Value": {"Fn::GetAtt": ["MyStateMachine", "Name"]}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
template["Resources"]["MyStateMachine"]["Properties"] = properties
|
|
||||||
cf.create_stack(StackName="test_stack", TemplateBody=json.dumps(template))
|
|
||||||
outputs_list = cf.Stack("test_stack").outputs
|
|
||||||
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
|
||||||
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
|
||||||
machine_arn = state_machine["stateMachineArn"]
|
|
||||||
creation_date = state_machine["creationDate"]
|
|
||||||
|
|
||||||
# Update State Machine in-place, no replacement.
|
|
||||||
updated_role = role_arn + "-updated"
|
|
||||||
updated_definition = definition.replace("HelloWorld", "HelloWorldUpdated")
|
|
||||||
updated_properties = {
|
|
||||||
"DefinitionString": updated_definition,
|
|
||||||
"RoleArn": updated_role,
|
|
||||||
"Tags": [
|
|
||||||
{"Key": "key3", "Value": "value3"},
|
|
||||||
{"Key": "key1", "Value": "updated_value"},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
template["Resources"]["MyStateMachine"]["Properties"] = updated_properties
|
|
||||||
cf.Stack("test_stack").update(TemplateBody=json.dumps(template))
|
|
||||||
|
|
||||||
state_machine = sf.describe_state_machine(stateMachineArn=machine_arn)
|
|
||||||
state_machine["name"].should.equal("HelloWorld-StateMachine")
|
|
||||||
state_machine["creationDate"].should.equal(creation_date)
|
|
||||||
state_machine["roleArn"].should.equal(updated_role)
|
|
||||||
state_machine["definition"].should.equal(updated_definition)
|
|
||||||
tags = sf.list_tags_for_resource(resourceArn=machine_arn).get("tags")
|
|
||||||
tags.should.have.length_of(3)
|
|
||||||
for tag in tags:
|
|
||||||
if tag["key"] == "key1":
|
|
||||||
tag["value"].should.equal("updated_value")
|
|
||||||
|
|
||||||
|
|
||||||
def _get_account_id():
|
def _get_account_id():
|
||||||
global account_id
|
global account_id
|
||||||
if account_id:
|
if account_id:
|
||||||
|
201
tests/test_stepfunctions/test_stepfunctions_cloudformation.py
Normal file
201
tests/test_stepfunctions/test_stepfunctions_cloudformation.py
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
import json
|
||||||
|
import sure # noqa
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from moto import mock_cloudformation, mock_stepfunctions
|
||||||
|
|
||||||
|
|
||||||
|
@mock_stepfunctions
|
||||||
|
@mock_cloudformation
|
||||||
|
def test_state_machine_cloudformation():
|
||||||
|
sf = boto3.client("stepfunctions", region_name="us-east-1")
|
||||||
|
cf = boto3.resource("cloudformation", region_name="us-east-1")
|
||||||
|
definition = '{"StartAt": "HelloWorld", "States": {"HelloWorld": {"Type": "Task", "Resource": "arn:aws:lambda:us-east-1:111122223333;:function:HelloFunction", "End": true}}}'
|
||||||
|
role_arn = (
|
||||||
|
"arn:aws:iam::111122223333:role/service-role/StatesExecutionRole-us-east-1;"
|
||||||
|
)
|
||||||
|
template = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "An example template for a Step Functions state machine.",
|
||||||
|
"Resources": {
|
||||||
|
"MyStateMachine": {
|
||||||
|
"Type": "AWS::StepFunctions::StateMachine",
|
||||||
|
"Properties": {
|
||||||
|
"StateMachineName": "HelloWorld-StateMachine",
|
||||||
|
"StateMachineType": "STANDARD",
|
||||||
|
"DefinitionString": definition,
|
||||||
|
"RoleArn": role_arn,
|
||||||
|
"Tags": [
|
||||||
|
{"Key": "key1", "Value": "value1"},
|
||||||
|
{"Key": "key2", "Value": "value2"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Outputs": {
|
||||||
|
"StateMachineArn": {"Value": {"Ref": "MyStateMachine"}},
|
||||||
|
"StateMachineName": {"Value": {"Fn::GetAtt": ["MyStateMachine", "Name"]}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cf.create_stack(StackName="test_stack", TemplateBody=json.dumps(template))
|
||||||
|
outputs_list = cf.Stack("test_stack").outputs
|
||||||
|
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
||||||
|
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
||||||
|
state_machine["stateMachineArn"].should.equal(output["StateMachineArn"])
|
||||||
|
state_machine["name"].should.equal(output["StateMachineName"])
|
||||||
|
state_machine["roleArn"].should.equal(role_arn)
|
||||||
|
state_machine["definition"].should.equal(definition)
|
||||||
|
tags = sf.list_tags_for_resource(resourceArn=output["StateMachineArn"]).get("tags")
|
||||||
|
for i, tag in enumerate(tags, 1):
|
||||||
|
tag["key"].should.equal("key{}".format(i))
|
||||||
|
tag["value"].should.equal("value{}".format(i))
|
||||||
|
|
||||||
|
cf.Stack("test_stack").delete()
|
||||||
|
with pytest.raises(ClientError) as ex:
|
||||||
|
sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
||||||
|
ex.value.response["Error"]["Code"].should.equal("StateMachineDoesNotExist")
|
||||||
|
ex.value.response["Error"]["Message"].should.contain("Does Not Exist")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_stepfunctions
|
||||||
|
@mock_cloudformation
|
||||||
|
def test_state_machine_cloudformation_update_with_replacement():
|
||||||
|
sf = boto3.client("stepfunctions", region_name="us-east-1")
|
||||||
|
cf = boto3.resource("cloudformation", region_name="us-east-1")
|
||||||
|
definition = '{"StartAt": "HelloWorld", "States": {"HelloWorld": {"Type": "Task", "Resource": "arn:aws:lambda:us-east-1:111122223333;:function:HelloFunction", "End": true}}}'
|
||||||
|
role_arn = (
|
||||||
|
"arn:aws:iam::111122223333:role/service-role/StatesExecutionRole-us-east-1"
|
||||||
|
)
|
||||||
|
properties = {
|
||||||
|
"StateMachineName": "HelloWorld-StateMachine",
|
||||||
|
"DefinitionString": definition,
|
||||||
|
"RoleArn": role_arn,
|
||||||
|
"Tags": [
|
||||||
|
{"Key": "key1", "Value": "value1"},
|
||||||
|
{"Key": "key2", "Value": "value2"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
template = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "An example template for a Step Functions state machine.",
|
||||||
|
"Resources": {
|
||||||
|
"MyStateMachine": {
|
||||||
|
"Type": "AWS::StepFunctions::StateMachine",
|
||||||
|
"Properties": {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Outputs": {
|
||||||
|
"StateMachineArn": {"Value": {"Ref": "MyStateMachine"}},
|
||||||
|
"StateMachineName": {"Value": {"Fn::GetAtt": ["MyStateMachine", "Name"]}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
template["Resources"]["MyStateMachine"]["Properties"] = properties
|
||||||
|
cf.create_stack(StackName="test_stack", TemplateBody=json.dumps(template))
|
||||||
|
outputs_list = cf.Stack("test_stack").outputs
|
||||||
|
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
||||||
|
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
||||||
|
original_machine_arn = state_machine["stateMachineArn"]
|
||||||
|
original_creation_date = state_machine["creationDate"]
|
||||||
|
|
||||||
|
# Update State Machine, with replacement.
|
||||||
|
updated_role = role_arn + "-updated"
|
||||||
|
updated_definition = definition.replace("HelloWorld", "HelloWorld2")
|
||||||
|
updated_properties = {
|
||||||
|
"StateMachineName": "New-StateMachine-Name",
|
||||||
|
"DefinitionString": updated_definition,
|
||||||
|
"RoleArn": updated_role,
|
||||||
|
"Tags": [
|
||||||
|
{"Key": "key3", "Value": "value3"},
|
||||||
|
{"Key": "key1", "Value": "updated_value"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
template["Resources"]["MyStateMachine"]["Properties"] = updated_properties
|
||||||
|
cf.Stack("test_stack").update(TemplateBody=json.dumps(template))
|
||||||
|
outputs_list = cf.Stack("test_stack").outputs
|
||||||
|
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
||||||
|
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
||||||
|
state_machine["stateMachineArn"].should_not.equal(original_machine_arn)
|
||||||
|
state_machine["name"].should.equal("New-StateMachine-Name")
|
||||||
|
state_machine["creationDate"].should.be.greater_than(original_creation_date)
|
||||||
|
state_machine["roleArn"].should.equal(updated_role)
|
||||||
|
state_machine["definition"].should.equal(updated_definition)
|
||||||
|
tags = sf.list_tags_for_resource(resourceArn=output["StateMachineArn"]).get("tags")
|
||||||
|
tags.should.have.length_of(3)
|
||||||
|
for tag in tags:
|
||||||
|
if tag["key"] == "key1":
|
||||||
|
tag["value"].should.equal("updated_value")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as ex:
|
||||||
|
sf.describe_state_machine(stateMachineArn=original_machine_arn)
|
||||||
|
ex.value.response["Error"]["Code"].should.equal("StateMachineDoesNotExist")
|
||||||
|
ex.value.response["Error"]["Message"].should.contain("State Machine Does Not Exist")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_stepfunctions
|
||||||
|
@mock_cloudformation
|
||||||
|
def test_state_machine_cloudformation_update_with_no_interruption():
|
||||||
|
sf = boto3.client("stepfunctions", region_name="us-east-1")
|
||||||
|
cf = boto3.resource("cloudformation", region_name="us-east-1")
|
||||||
|
definition = '{"StartAt": "HelloWorld", "States": {"HelloWorld": {"Type": "Task", "Resource": "arn:aws:lambda:us-east-1:111122223333;:function:HelloFunction", "End": true}}}'
|
||||||
|
role_arn = (
|
||||||
|
"arn:aws:iam::111122223333:role/service-role/StatesExecutionRole-us-east-1"
|
||||||
|
)
|
||||||
|
properties = {
|
||||||
|
"StateMachineName": "HelloWorld-StateMachine",
|
||||||
|
"DefinitionString": definition,
|
||||||
|
"RoleArn": role_arn,
|
||||||
|
"Tags": [
|
||||||
|
{"Key": "key1", "Value": "value1"},
|
||||||
|
{"Key": "key2", "Value": "value2"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
template = {
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "An example template for a Step Functions state machine.",
|
||||||
|
"Resources": {
|
||||||
|
"MyStateMachine": {
|
||||||
|
"Type": "AWS::StepFunctions::StateMachine",
|
||||||
|
"Properties": {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Outputs": {
|
||||||
|
"StateMachineArn": {"Value": {"Ref": "MyStateMachine"}},
|
||||||
|
"StateMachineName": {"Value": {"Fn::GetAtt": ["MyStateMachine", "Name"]}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
template["Resources"]["MyStateMachine"]["Properties"] = properties
|
||||||
|
cf.create_stack(StackName="test_stack", TemplateBody=json.dumps(template))
|
||||||
|
outputs_list = cf.Stack("test_stack").outputs
|
||||||
|
output = {item["OutputKey"]: item["OutputValue"] for item in outputs_list}
|
||||||
|
state_machine = sf.describe_state_machine(stateMachineArn=output["StateMachineArn"])
|
||||||
|
machine_arn = state_machine["stateMachineArn"]
|
||||||
|
creation_date = state_machine["creationDate"]
|
||||||
|
|
||||||
|
# Update State Machine in-place, no replacement.
|
||||||
|
updated_role = role_arn + "-updated"
|
||||||
|
updated_definition = definition.replace("HelloWorld", "HelloWorldUpdated")
|
||||||
|
updated_properties = {
|
||||||
|
"DefinitionString": updated_definition,
|
||||||
|
"RoleArn": updated_role,
|
||||||
|
"Tags": [
|
||||||
|
{"Key": "key3", "Value": "value3"},
|
||||||
|
{"Key": "key1", "Value": "updated_value"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
template["Resources"]["MyStateMachine"]["Properties"] = updated_properties
|
||||||
|
cf.Stack("test_stack").update(TemplateBody=json.dumps(template))
|
||||||
|
|
||||||
|
state_machine = sf.describe_state_machine(stateMachineArn=machine_arn)
|
||||||
|
state_machine["name"].should.equal("HelloWorld-StateMachine")
|
||||||
|
state_machine["creationDate"].should.equal(creation_date)
|
||||||
|
state_machine["roleArn"].should.equal(updated_role)
|
||||||
|
state_machine["definition"].should.equal(updated_definition)
|
||||||
|
tags = sf.list_tags_for_resource(resourceArn=machine_arn).get("tags")
|
||||||
|
tags.should.have.length_of(3)
|
||||||
|
for tag in tags:
|
||||||
|
if tag["key"] == "key1":
|
||||||
|
tag["value"].should.equal("updated_value")
|
Loading…
x
Reference in New Issue
Block a user