Techdebt: Replace sure with regular asserts in CF (#6481)
This commit is contained in:
parent
4011a68f06
commit
d98d8cf0d5
@ -1,7 +1,6 @@
|
||||
import boto3
|
||||
import json
|
||||
import requests
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import time
|
||||
import pytest
|
||||
|
||||
@ -69,9 +68,9 @@ def test_create_custom_lambda_resource():
|
||||
|
||||
# Verify the correct Output was returned
|
||||
outputs = get_outputs(cf, stack_name)
|
||||
outputs.should.have.length_of(1)
|
||||
outputs[0].should.have.key("OutputKey").equals("infokey")
|
||||
outputs[0].should.have.key("OutputValue").equals("special value")
|
||||
assert len(outputs) == 1
|
||||
assert outputs[0]["OutputKey"] == "infokey"
|
||||
assert outputs[0]["OutputValue"] == "special value"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -104,25 +103,25 @@ def test_create_custom_lambda_resource__verify_cfnresponse_failed():
|
||||
execution_failed, logs = wait_for_log_msg(
|
||||
expected_msg="failed executing http.request", log_group=log_group_name
|
||||
)
|
||||
execution_failed.should.equal(True)
|
||||
assert execution_failed is True
|
||||
|
||||
printed_events = [
|
||||
line for line in logs if line.startswith("{'RequestType': 'Create'")
|
||||
]
|
||||
printed_events.should.have.length_of(1)
|
||||
assert len(printed_events) == 1
|
||||
original_event = json.loads(printed_events[0].replace("'", '"'))
|
||||
original_event.should.have.key("RequestType").equals("Create")
|
||||
original_event.should.have.key("ServiceToken") # Should equal Lambda ARN
|
||||
original_event.should.have.key("ResponseURL")
|
||||
original_event.should.have.key("StackId")
|
||||
original_event.should.have.key("RequestId") # type UUID
|
||||
original_event.should.have.key("LogicalResourceId").equals("CustomInfo")
|
||||
original_event.should.have.key("ResourceType").equals("Custom::Info")
|
||||
original_event.should.have.key("ResourceProperties")
|
||||
original_event["ResourceProperties"].should.have.key(
|
||||
"ServiceToken"
|
||||
assert original_event["RequestType"] == "Create"
|
||||
assert "ServiceToken" in original_event # Should equal Lambda ARN
|
||||
assert "ResponseURL" in original_event
|
||||
assert "StackId" in original_event
|
||||
assert "RequestId" in original_event # type UUID
|
||||
assert original_event["LogicalResourceId"] == "CustomInfo"
|
||||
assert original_event["ResourceType"] == "Custom::Info"
|
||||
assert "ResourceProperties" in original_event
|
||||
assert (
|
||||
"ServiceToken" in original_event["ResourceProperties"]
|
||||
) # Should equal Lambda ARN
|
||||
original_event["ResourceProperties"].should.have.key("MyProperty").equals("stuff")
|
||||
assert original_event["ResourceProperties"]["MyProperty"] == "stuff"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -155,8 +154,8 @@ def test_create_custom_lambda_resource__verify_manual_request():
|
||||
)
|
||||
stack_id = stack["StackId"]
|
||||
stack = cf.describe_stacks(StackName=stack_id)["Stacks"][0]
|
||||
stack["Outputs"].should.equal([])
|
||||
stack["StackStatus"].should.equal("CREATE_IN_PROGRESS")
|
||||
assert stack["Outputs"] == []
|
||||
assert stack["StackStatus"] == "CREATE_IN_PROGRESS"
|
||||
|
||||
callback_url = f"http://cloudformation.{region_name}.amazonaws.com/cloudformation_{region_name}/cfnresponse?stack={stack_id}"
|
||||
data = {
|
||||
@ -168,10 +167,10 @@ def test_create_custom_lambda_resource__verify_manual_request():
|
||||
requests.post(callback_url, json=data)
|
||||
|
||||
stack = cf.describe_stacks(StackName=stack_id)["Stacks"][0]
|
||||
stack["StackStatus"].should.equal("CREATE_COMPLETE")
|
||||
stack["Outputs"].should.equal(
|
||||
[{"OutputKey": "infokey", "OutputValue": "resultfromthirdpartysystem"}]
|
||||
)
|
||||
assert stack["StackStatus"] == "CREATE_COMPLETE"
|
||||
assert stack["Outputs"] == [
|
||||
{"OutputKey": "infokey", "OutputValue": "resultfromthirdpartysystem"}
|
||||
]
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -186,9 +185,10 @@ def test_create_custom_lambda_resource__unknown_arn():
|
||||
Capabilities=["CAPABILITY_IAM"],
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal(
|
||||
"Template error: instance of Fn::GetAtt references undefined resource InfoFunction"
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert (
|
||||
err["Message"]
|
||||
== "Template error: instance of Fn::GetAtt references undefined resource InfoFunction"
|
||||
)
|
||||
|
||||
|
||||
|
@ -94,11 +94,11 @@ class TestStackSetMultipleAccounts(TestCase):
|
||||
StackInstanceAccount=accnt,
|
||||
StackInstanceRegion=region or "us-east-1",
|
||||
)["StackInstance"]
|
||||
resp.should.have.key("Account").equals(accnt)
|
||||
assert resp["Account"] == accnt
|
||||
|
||||
def _verify_queues(self, accnt, expected, region=None):
|
||||
list(sqs_backends[accnt][region or "us-east-1"].queues.keys()).should.equal(
|
||||
expected
|
||||
assert (
|
||||
list(sqs_backends[accnt][region or "us-east-1"].queues.keys()) == expected
|
||||
)
|
||||
|
||||
|
||||
@ -122,9 +122,10 @@ class TestServiceManagedStacks(TestStackSetMultipleAccounts):
|
||||
StackSetName=self.name, Accounts=["888781156701"], Regions=["us-east-1"]
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal(
|
||||
"StackSets with SERVICE_MANAGED permission model can only have OrganizationalUnit as target"
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert (
|
||||
err["Message"]
|
||||
== "StackSets with SERVICE_MANAGED permission model can only have OrganizationalUnit as target"
|
||||
)
|
||||
|
||||
def test_create_instances__specifying_only_accounts_in_deployment_targets(self):
|
||||
@ -137,8 +138,8 @@ class TestServiceManagedStacks(TestStackSetMultipleAccounts):
|
||||
Regions=["us-east-1"],
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal("OrganizationalUnitIds are required")
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert err["Message"] == "OrganizationalUnitIds are required"
|
||||
|
||||
def test_create_instances___with_invalid_ou(self):
|
||||
with pytest.raises(ClientError) as exc:
|
||||
@ -148,9 +149,10 @@ class TestServiceManagedStacks(TestStackSetMultipleAccounts):
|
||||
Regions=["us-east-1"],
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal(
|
||||
"1 validation error detected: Value '[unknown]' at 'deploymentTargets.organizationalUnitIds' failed to satisfy constraint: Member must satisfy constraint: [Member must have length less than or equal to 68, Member must have length greater than or equal to 6, Member must satisfy regular expression pattern: ^(ou-[a-z0-9]{4,32}-[a-z0-9]{8,32}|r-[a-z0-9]{4,32})$]"
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert (
|
||||
err["Message"]
|
||||
== "1 validation error detected: Value '[unknown]' at 'deploymentTargets.organizationalUnitIds' failed to satisfy constraint: Member must satisfy constraint: [Member must have length less than or equal to 68, Member must have length greater than or equal to 6, Member must satisfy regular expression pattern: ^(ou-[a-z0-9]{4,32}-[a-z0-9]{8,32}|r-[a-z0-9]{4,32})$]"
|
||||
)
|
||||
|
||||
def test_create_instances__single_ou(self):
|
||||
@ -210,12 +212,12 @@ class TestSelfManagedStacks(TestStackSetMultipleAccounts):
|
||||
self._verify_stack_instance(self.acct01, region="us-east-2")
|
||||
|
||||
# acct01 has a Stack
|
||||
cf_backends[self.acct01]["us-east-2"].stacks.should.have.length_of(1)
|
||||
assert len(cf_backends[self.acct01]["us-east-2"].stacks) == 1
|
||||
# Other acounts do not
|
||||
cf_backends[self.acct02]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[self.acct21]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[self.acct22]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[DEFAULT_ACCOUNT_ID]["us-east-2"].stacks.should.have.length_of(0)
|
||||
assert len(cf_backends[self.acct02]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[self.acct21]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[self.acct22]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[DEFAULT_ACCOUNT_ID]["us-east-2"].stacks) == 0
|
||||
|
||||
# acct01 has a queue
|
||||
self._verify_queues(self.acct01, ["testqueue"], region="us-east-2")
|
||||
@ -233,12 +235,12 @@ class TestSelfManagedStacks(TestStackSetMultipleAccounts):
|
||||
)
|
||||
|
||||
# acct01 and 02 have a Stack
|
||||
cf_backends[self.acct01]["us-east-2"].stacks.should.have.length_of(1)
|
||||
cf_backends[self.acct02]["us-east-2"].stacks.should.have.length_of(1)
|
||||
assert len(cf_backends[self.acct01]["us-east-2"].stacks) == 1
|
||||
assert len(cf_backends[self.acct02]["us-east-2"].stacks) == 1
|
||||
# Other acounts do not
|
||||
cf_backends[self.acct21]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[self.acct22]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[DEFAULT_ACCOUNT_ID]["us-east-2"].stacks.should.have.length_of(0)
|
||||
assert len(cf_backends[self.acct21]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[self.acct22]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[DEFAULT_ACCOUNT_ID]["us-east-2"].stacks) == 0
|
||||
|
||||
# acct01 and 02 have the queue
|
||||
self._verify_queues(self.acct01, ["testqueue"], region="us-east-2")
|
||||
@ -265,12 +267,12 @@ class TestSelfManagedStacks(TestStackSetMultipleAccounts):
|
||||
)
|
||||
|
||||
# Act02 still has it's stack
|
||||
cf_backends[self.acct02]["us-east-2"].stacks.should.have.length_of(1)
|
||||
assert len(cf_backends[self.acct02]["us-east-2"].stacks) == 1
|
||||
# Other Stacks are removed
|
||||
cf_backends[self.acct01]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[self.acct21]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[self.acct22]["us-east-2"].stacks.should.have.length_of(0)
|
||||
cf_backends[DEFAULT_ACCOUNT_ID]["us-east-2"].stacks.should.have.length_of(0)
|
||||
assert len(cf_backends[self.acct01]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[self.acct21]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[self.acct22]["us-east-2"].stacks) == 0
|
||||
assert len(cf_backends[DEFAULT_ACCOUNT_ID]["us-east-2"].stacks) == 0
|
||||
|
||||
# Acct02 still has it's queue as well
|
||||
self._verify_queues(self.acct02, ["testqueue"], region="us-east-2")
|
||||
@ -288,7 +290,8 @@ class TestSelfManagedStacks(TestStackSetMultipleAccounts):
|
||||
Regions=["us-east-1"],
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal(
|
||||
"StackSets with SELF_MANAGED permission model can only have accounts as target"
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert (
|
||||
err["Message"]
|
||||
== "StackSets with SELF_MANAGED permission model can only have accounts as target"
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,11 @@
|
||||
import boto3
|
||||
import json
|
||||
import io
|
||||
import pytest
|
||||
import zipfile
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
from decimal import Decimal
|
||||
from string import Template
|
||||
|
||||
from moto import (
|
||||
@ -29,9 +27,6 @@ from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
|
||||
from tests.markers import requires_docker
|
||||
from tests.test_cloudformation.fixtures import fn_join, single_instance_with_ebs_volume
|
||||
from tests.helpers import ( # noqa # pylint: disable=unused-import
|
||||
containing_item_with_attributes,
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -41,8 +36,8 @@ def test_create_template_without_required_param_boto3():
|
||||
with pytest.raises(ClientError) as ex:
|
||||
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
err = ex.value.response["Error"]
|
||||
err.should.have.key("Code").equal("Missing Parameter")
|
||||
err.should.have.key("Message").equal("Missing parameter KeyName")
|
||||
assert err["Code"] == "Missing Parameter"
|
||||
assert err["Message"] == "Missing parameter KeyName"
|
||||
|
||||
|
||||
@mock_ec2
|
||||
@ -56,7 +51,7 @@ def test_fn_join_boto3():
|
||||
|
||||
stack = cf.describe_stacks()["Stacks"][0]
|
||||
fn_join_output = stack["Outputs"][0]
|
||||
fn_join_output["OutputValue"].should.equal(f"test eip:{eip['PublicIp']}")
|
||||
assert fn_join_output["OutputValue"] == f"test eip:{eip['PublicIp']}"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -85,14 +80,14 @@ def test_conditional_resources_boto3():
|
||||
Parameters=[{"ParameterKey": "EnvType", "ParameterValue": "staging"}],
|
||||
)
|
||||
sqs = boto3.client("sqs", region_name="us-west-1")
|
||||
sqs.list_queues().shouldnt.have.key("QueueUrls")
|
||||
assert "QueueUrls" not in sqs.list_queues()
|
||||
|
||||
cf.create_stack(
|
||||
StackName="test_stack_with_queue",
|
||||
TemplateBody=sqs_template_json,
|
||||
Parameters=[{"ParameterKey": "EnvType", "ParameterValue": "prod"}],
|
||||
)
|
||||
sqs.list_queues()["QueueUrls"].should.have.length_of(1)
|
||||
assert len(sqs.list_queues()["QueueUrls"]) == 1
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -126,7 +121,7 @@ def test_conditional_if_handling_boto3():
|
||||
cf.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
|
||||
ec2 = boto3.client("ec2", region_name="us-west-1")
|
||||
ec2_instance = ec2.describe_instances()["Reservations"][0]["Instances"][0]
|
||||
ec2_instance["ImageId"].should.equal(EXAMPLE_AMI_ID2)
|
||||
assert ec2_instance["ImageId"] == EXAMPLE_AMI_ID2
|
||||
|
||||
cf = boto3.client("cloudformation", region_name="us-west-2")
|
||||
cf.create_stack(
|
||||
@ -136,7 +131,7 @@ def test_conditional_if_handling_boto3():
|
||||
)
|
||||
ec2 = boto3.client("ec2", region_name="us-west-2")
|
||||
ec2_instance = ec2.describe_instances()["Reservations"][0]["Instances"][0]
|
||||
ec2_instance["ImageId"].should.equal(EXAMPLE_AMI_ID)
|
||||
assert ec2_instance["ImageId"] == EXAMPLE_AMI_ID
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -172,13 +167,13 @@ def test_cloudformation_mapping_boto3():
|
||||
cf.create_stack(StackName="test_stack1", TemplateBody=dummy_template_json)
|
||||
ec2 = boto3.client("ec2", region_name="us-east-1")
|
||||
ec2_instance = ec2.describe_instances()["Reservations"][0]["Instances"][0]
|
||||
ec2_instance["ImageId"].should.equal(EXAMPLE_AMI_ID)
|
||||
assert ec2_instance["ImageId"] == EXAMPLE_AMI_ID
|
||||
|
||||
cf = boto3.client("cloudformation", region_name="us-west-1")
|
||||
cf.create_stack(StackName="test_stack1", TemplateBody=dummy_template_json)
|
||||
ec2 = boto3.client("ec2", region_name="us-west-1")
|
||||
ec2_instance = ec2.describe_instances()["Reservations"][0]["Instances"][0]
|
||||
ec2_instance["ImageId"].should.equal(EXAMPLE_AMI_ID2)
|
||||
assert ec2_instance["ImageId"] == EXAMPLE_AMI_ID2
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -232,23 +227,23 @@ def lambda_handler(event, context):
|
||||
|
||||
conn = boto3.client("lambda", "us-east-1")
|
||||
result = conn.list_functions()
|
||||
result["Functions"].should.have.length_of(1)
|
||||
result["Functions"][0]["Description"].should.equal("Test function")
|
||||
result["Functions"][0]["Handler"].should.equal("index.lambda_handler")
|
||||
result["Functions"][0]["MemorySize"].should.equal(128)
|
||||
result["Functions"][0]["Runtime"].should.equal("python2.7")
|
||||
result["Functions"][0]["Environment"].should.equal(
|
||||
{"Variables": {"TEST_ENV_KEY": "test-env-val"}}
|
||||
)
|
||||
assert len(result["Functions"]) == 1
|
||||
assert result["Functions"][0]["Description"] == "Test function"
|
||||
assert result["Functions"][0]["Handler"] == "index.lambda_handler"
|
||||
assert result["Functions"][0]["MemorySize"] == 128
|
||||
assert result["Functions"][0]["Runtime"] == "python2.7"
|
||||
assert result["Functions"][0]["Environment"] == {
|
||||
"Variables": {"TEST_ENV_KEY": "test-env-val"}
|
||||
}
|
||||
|
||||
function_name = result["Functions"][0]["FunctionName"]
|
||||
result = conn.get_function(FunctionName=function_name)
|
||||
|
||||
result["Concurrency"]["ReservedConcurrentExecutions"].should.equal(10)
|
||||
assert result["Concurrency"]["ReservedConcurrentExecutions"] == 10
|
||||
|
||||
response = conn.invoke(FunctionName=function_name)
|
||||
result = json.loads(response["Payload"].read())
|
||||
result.should.equal({"event": "{}"})
|
||||
assert result == {"event": "{}"}
|
||||
|
||||
|
||||
def _make_zipfile(func_str):
|
||||
@ -302,18 +297,16 @@ def lambda_handler(event, context):
|
||||
layer_name = result["Layers"][0]["LayerName"]
|
||||
result = lambda_conn.list_layer_versions(LayerName=layer_name)
|
||||
result["LayerVersions"][0].pop("CreatedDate")
|
||||
result["LayerVersions"].should.equal(
|
||||
[
|
||||
{
|
||||
"Version": 1,
|
||||
"LayerVersionArn": f"arn:aws:lambda:{region}:{ACCOUNT_ID}:layer:{layer_name}:1",
|
||||
"CompatibleRuntimes": ["python2.7", "python3.6"],
|
||||
"Description": "Test Layer",
|
||||
"LicenseInfo": "MIT",
|
||||
"CompatibleArchitectures": [],
|
||||
}
|
||||
]
|
||||
)
|
||||
assert result["LayerVersions"] == [
|
||||
{
|
||||
"Version": 1,
|
||||
"LayerVersionArn": f"arn:aws:lambda:{region}:{ACCOUNT_ID}:layer:{layer_name}:1",
|
||||
"CompatibleRuntimes": ["python2.7", "python3.6"],
|
||||
"Description": "Test Layer",
|
||||
"LicenseInfo": "MIT",
|
||||
"CompatibleArchitectures": [],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -370,14 +363,13 @@ def test_nat_gateway():
|
||||
route_resource = resource
|
||||
|
||||
result = ec2_conn.describe_nat_gateways()
|
||||
result["NatGateways"].should.have.length_of(1)
|
||||
result["NatGateways"][0]["VpcId"].should.equal(vpc_id)
|
||||
result["NatGateways"][0]["SubnetId"].should.equal(subnet_id)
|
||||
result["NatGateways"][0]["State"].should.equal("available")
|
||||
result["NatGateways"][0]["NatGatewayId"].should.equal(
|
||||
nat_gateway_resource.get("PhysicalResourceId")
|
||||
)
|
||||
route_resource.get("PhysicalResourceId").should.contain("rtb-")
|
||||
assert len(result["NatGateways"]) == 1
|
||||
assert result["NatGateways"][0]["VpcId"] == vpc_id
|
||||
assert result["NatGateways"][0]["SubnetId"] == subnet_id
|
||||
assert result["NatGateways"][0]["State"] == "available"
|
||||
physical_id = nat_gateway_resource.get("PhysicalResourceId")
|
||||
assert result["NatGateways"][0]["NatGatewayId"] == physical_id
|
||||
assert "rtb-" in route_resource["PhysicalResourceId"]
|
||||
|
||||
|
||||
@mock_cloudformation()
|
||||
@ -403,11 +395,11 @@ def test_stack_kms():
|
||||
|
||||
kms_conn = boto3.client("kms", "us-east-1")
|
||||
keys = kms_conn.list_keys()["Keys"]
|
||||
len(keys).should.equal(1)
|
||||
assert len(keys) == 1
|
||||
result = kms_conn.describe_key(KeyId=keys[0]["KeyId"])
|
||||
|
||||
result["KeyMetadata"]["Enabled"].should.equal(True)
|
||||
result["KeyMetadata"]["KeyUsage"].should.equal("ENCRYPT_DECRYPT")
|
||||
assert result["KeyMetadata"]["Enabled"] is True
|
||||
assert result["KeyMetadata"]["KeyUsage"] == "ENCRYPT_DECRYPT"
|
||||
|
||||
|
||||
@mock_cloudformation()
|
||||
@ -467,34 +459,32 @@ def test_stack_spot_fleet():
|
||||
)["StackId"]
|
||||
|
||||
stack_resources = cf_conn.list_stack_resources(StackName=stack_id)
|
||||
stack_resources["StackResourceSummaries"].should.have.length_of(1)
|
||||
assert len(stack_resources["StackResourceSummaries"]) == 1
|
||||
spot_fleet_id = stack_resources["StackResourceSummaries"][0]["PhysicalResourceId"]
|
||||
|
||||
spot_fleet_requests = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"]
|
||||
len(spot_fleet_requests).should.equal(1)
|
||||
assert len(spot_fleet_requests) == 1
|
||||
spot_fleet_request = spot_fleet_requests[0]
|
||||
spot_fleet_request["SpotFleetRequestState"].should.equal("active")
|
||||
assert spot_fleet_request["SpotFleetRequestState"] == "active"
|
||||
spot_fleet_config = spot_fleet_request["SpotFleetRequestConfig"]
|
||||
|
||||
spot_fleet_config["SpotPrice"].should.equal("0.12")
|
||||
spot_fleet_config["TargetCapacity"].should.equal(6)
|
||||
spot_fleet_config["IamFleetRole"].should.equal(
|
||||
f"arn:aws:iam::{ACCOUNT_ID}:role/fleet"
|
||||
)
|
||||
spot_fleet_config["AllocationStrategy"].should.equal("diversified")
|
||||
spot_fleet_config["FulfilledCapacity"].should.equal(6.0)
|
||||
assert spot_fleet_config["SpotPrice"] == "0.12"
|
||||
assert spot_fleet_config["TargetCapacity"] == 6
|
||||
assert spot_fleet_config["IamFleetRole"] == f"arn:aws:iam::{ACCOUNT_ID}:role/fleet"
|
||||
assert spot_fleet_config["AllocationStrategy"] == "diversified"
|
||||
assert spot_fleet_config["FulfilledCapacity"] == 6.0
|
||||
|
||||
len(spot_fleet_config["LaunchSpecifications"]).should.equal(2)
|
||||
assert len(spot_fleet_config["LaunchSpecifications"]) == 2
|
||||
launch_spec = spot_fleet_config["LaunchSpecifications"][0]
|
||||
|
||||
launch_spec["EbsOptimized"].should.equal(False)
|
||||
launch_spec["ImageId"].should.equal(EXAMPLE_AMI_ID)
|
||||
launch_spec["InstanceType"].should.equal("t2.small")
|
||||
launch_spec["SubnetId"].should.equal(subnet_id)
|
||||
launch_spec["SpotPrice"].should.equal("0.13")
|
||||
launch_spec["WeightedCapacity"].should.equal(2.0)
|
||||
assert launch_spec["EbsOptimized"] is False
|
||||
assert launch_spec["ImageId"] == EXAMPLE_AMI_ID
|
||||
assert launch_spec["InstanceType"] == "t2.small"
|
||||
assert launch_spec["SubnetId"] == subnet_id
|
||||
assert launch_spec["SpotPrice"] == "0.13"
|
||||
assert launch_spec["WeightedCapacity"] == 2.0
|
||||
|
||||
|
||||
@mock_cloudformation()
|
||||
@ -551,19 +541,19 @@ def test_stack_spot_fleet_should_figure_out_default_price():
|
||||
)["StackId"]
|
||||
|
||||
stack_resources = cf_conn.list_stack_resources(StackName=stack_id)
|
||||
stack_resources["StackResourceSummaries"].should.have.length_of(1)
|
||||
assert len(stack_resources["StackResourceSummaries"]) == 1
|
||||
spot_fleet_id = stack_resources["StackResourceSummaries"][0]["PhysicalResourceId"]
|
||||
|
||||
spot_fleet_requests = conn.describe_spot_fleet_requests(
|
||||
SpotFleetRequestIds=[spot_fleet_id]
|
||||
)["SpotFleetRequestConfigs"]
|
||||
len(spot_fleet_requests).should.equal(1)
|
||||
assert len(spot_fleet_requests) == 1
|
||||
spot_fleet_request = spot_fleet_requests[0]
|
||||
spot_fleet_request["SpotFleetRequestState"].should.equal("active")
|
||||
assert spot_fleet_request["SpotFleetRequestState"] == "active"
|
||||
spot_fleet_config = spot_fleet_request["SpotFleetRequestConfig"]
|
||||
|
||||
assert "SpotPrice" not in spot_fleet_config
|
||||
len(spot_fleet_config["LaunchSpecifications"]).should.equal(2)
|
||||
assert len(spot_fleet_config["LaunchSpecifications"]) == 2
|
||||
launch_spec1 = spot_fleet_config["LaunchSpecifications"][0]
|
||||
launch_spec2 = spot_fleet_config["LaunchSpecifications"][1]
|
||||
|
||||
@ -575,7 +565,6 @@ def test_stack_spot_fleet_should_figure_out_default_price():
|
||||
@mock_elbv2
|
||||
@mock_cloudformation
|
||||
def test_invalid_action_type_listener_rule():
|
||||
|
||||
invalid_listener_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
@ -634,9 +623,10 @@ def test_invalid_action_type_listener_rule():
|
||||
listener_template_json = json.dumps(invalid_listener_template)
|
||||
|
||||
cfn_conn = boto3.client("cloudformation", "us-west-1")
|
||||
cfn_conn.create_stack.when.called_with(
|
||||
StackName="listener_stack", TemplateBody=listener_template_json
|
||||
).should.throw(ClientError)
|
||||
with pytest.raises(ClientError) as exc:
|
||||
cfn_conn.create_stack(StackName="s", TemplateBody=listener_template_json)
|
||||
err = exc.value.response["Error"]
|
||||
assert err["Code"] == "ValidationError"
|
||||
|
||||
|
||||
@mock_ec2
|
||||
@ -644,7 +634,6 @@ def test_invalid_action_type_listener_rule():
|
||||
@mock_cloudformation
|
||||
@mock_events
|
||||
def test_update_stack_listener_and_rule():
|
||||
|
||||
initial_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
@ -731,15 +720,11 @@ def test_update_stack_listener_and_rule():
|
||||
listeners = elbv2_conn.describe_listeners(
|
||||
LoadBalancerArn=load_balancers[0]["LoadBalancerArn"]
|
||||
)["Listeners"]
|
||||
listeners[0]["Port"].should.equal(90)
|
||||
assert listeners[0]["Port"] == 90
|
||||
|
||||
listener_rule = elbv2_conn.describe_rules(ListenerArn=listeners[0]["ListenerArn"])[
|
||||
"Rules"
|
||||
]
|
||||
l_rule = elbv2_conn.describe_rules(ListenerArn=listeners[0]["ListenerArn"])["Rules"]
|
||||
|
||||
listener_rule[0]["Conditions"].should.equal(
|
||||
[{"Field": "host-header", "Values": ["*"]}]
|
||||
)
|
||||
assert l_rule[0]["Conditions"] == [{"Field": "host-header", "Values": ["*"]}]
|
||||
|
||||
|
||||
@mock_ec2
|
||||
@ -887,96 +872,88 @@ def test_stack_elbv2_resources_integration():
|
||||
|
||||
elbv2_conn = boto3.client("elbv2", "us-west-1")
|
||||
|
||||
load_balancers = elbv2_conn.describe_load_balancers()["LoadBalancers"]
|
||||
len(load_balancers).should.equal(1)
|
||||
load_balancers[0]["LoadBalancerName"].should.equal("myelbv2")
|
||||
load_balancers[0]["Scheme"].should.equal("internet-facing")
|
||||
load_balancers[0]["Type"].should.equal("application")
|
||||
load_balancers[0]["IpAddressType"].should.equal("ipv4")
|
||||
lbs = elbv2_conn.describe_load_balancers()["LoadBalancers"]
|
||||
assert len(lbs) == 1
|
||||
assert lbs[0]["LoadBalancerName"] == "myelbv2"
|
||||
assert lbs[0]["Scheme"] == "internet-facing"
|
||||
assert lbs[0]["Type"] == "application"
|
||||
assert lbs[0]["IpAddressType"] == "ipv4"
|
||||
|
||||
target_groups = sorted(
|
||||
elbv2_conn.describe_target_groups()["TargetGroups"],
|
||||
key=lambda tg: tg["TargetGroupName"],
|
||||
) # sort to do comparison with indexes
|
||||
len(target_groups).should.equal(2)
|
||||
target_groups[0]["HealthCheckIntervalSeconds"].should.equal(30)
|
||||
target_groups[0]["HealthCheckPath"].should.equal("/status")
|
||||
target_groups[0]["HealthCheckPort"].should.equal("80")
|
||||
target_groups[0]["HealthCheckProtocol"].should.equal("HTTP")
|
||||
target_groups[0]["HealthCheckTimeoutSeconds"].should.equal(5)
|
||||
target_groups[0]["HealthyThresholdCount"].should.equal(30)
|
||||
target_groups[0]["UnhealthyThresholdCount"].should.equal(5)
|
||||
target_groups[0]["Matcher"].should.equal({"HttpCode": "200,201"})
|
||||
target_groups[0]["TargetGroupName"].should.equal("mytargetgroup1")
|
||||
target_groups[0]["Port"].should.equal(80)
|
||||
target_groups[0]["Protocol"].should.equal("HTTP")
|
||||
target_groups[0]["TargetType"].should.equal("instance")
|
||||
target_groups = elbv2_conn.describe_target_groups()["TargetGroups"]
|
||||
# sort to do comparison with indexes
|
||||
target_groups = sorted(target_groups, key=lambda tg: tg["TargetGroupName"])
|
||||
assert len(target_groups) == 2
|
||||
assert target_groups[0]["HealthCheckIntervalSeconds"] == 30
|
||||
assert target_groups[0]["HealthCheckPath"] == "/status"
|
||||
assert target_groups[0]["HealthCheckPort"] == "80"
|
||||
assert target_groups[0]["HealthCheckProtocol"] == "HTTP"
|
||||
assert target_groups[0]["HealthCheckTimeoutSeconds"] == 5
|
||||
assert target_groups[0]["HealthyThresholdCount"] == 30
|
||||
assert target_groups[0]["UnhealthyThresholdCount"] == 5
|
||||
assert target_groups[0]["Matcher"] == {"HttpCode": "200,201"}
|
||||
assert target_groups[0]["TargetGroupName"] == "mytargetgroup1"
|
||||
assert target_groups[0]["Port"] == 80
|
||||
assert target_groups[0]["Protocol"] == "HTTP"
|
||||
assert target_groups[0]["TargetType"] == "instance"
|
||||
|
||||
target_groups[1]["HealthCheckIntervalSeconds"].should.equal(30)
|
||||
target_groups[1]["HealthCheckPath"].should.equal("/status")
|
||||
target_groups[1]["HealthCheckPort"].should.equal("8080")
|
||||
target_groups[1]["HealthCheckProtocol"].should.equal("HTTP")
|
||||
target_groups[1]["HealthCheckTimeoutSeconds"].should.equal(5)
|
||||
target_groups[1]["HealthyThresholdCount"].should.equal(30)
|
||||
target_groups[1]["UnhealthyThresholdCount"].should.equal(5)
|
||||
target_groups[1]["Matcher"].should.equal({"HttpCode": "200"})
|
||||
target_groups[1]["TargetGroupName"].should.equal("mytargetgroup2")
|
||||
target_groups[1]["Port"].should.equal(8080)
|
||||
target_groups[1]["Protocol"].should.equal("HTTP")
|
||||
target_groups[1]["TargetType"].should.equal("instance")
|
||||
assert target_groups[1]["HealthCheckIntervalSeconds"] == 30
|
||||
assert target_groups[1]["HealthCheckPath"] == "/status"
|
||||
assert target_groups[1]["HealthCheckPort"] == "8080"
|
||||
assert target_groups[1]["HealthCheckProtocol"] == "HTTP"
|
||||
assert target_groups[1]["HealthCheckTimeoutSeconds"] == 5
|
||||
assert target_groups[1]["HealthyThresholdCount"] == 30
|
||||
assert target_groups[1]["UnhealthyThresholdCount"] == 5
|
||||
assert target_groups[1]["Matcher"] == {"HttpCode": "200"}
|
||||
assert target_groups[1]["TargetGroupName"] == "mytargetgroup2"
|
||||
assert target_groups[1]["Port"] == 8080
|
||||
assert target_groups[1]["Protocol"] == "HTTP"
|
||||
assert target_groups[1]["TargetType"] == "instance"
|
||||
|
||||
listeners = elbv2_conn.describe_listeners(
|
||||
LoadBalancerArn=load_balancers[0]["LoadBalancerArn"]
|
||||
)["Listeners"]
|
||||
len(listeners).should.equal(1)
|
||||
listeners[0]["LoadBalancerArn"].should.equal(load_balancers[0]["LoadBalancerArn"])
|
||||
listeners[0]["Port"].should.equal(80)
|
||||
listeners[0]["Protocol"].should.equal("HTTP")
|
||||
listeners[0]["DefaultActions"].should.equal(
|
||||
[{"Type": "forward", "TargetGroupArn": target_groups[0]["TargetGroupArn"]}]
|
||||
)
|
||||
|
||||
listener_rule = elbv2_conn.describe_rules(ListenerArn=listeners[0]["ListenerArn"])[
|
||||
"Rules"
|
||||
lstnrs = elbv2_conn.describe_listeners(LoadBalancerArn=lbs[0]["LoadBalancerArn"])[
|
||||
"Listeners"
|
||||
]
|
||||
assert len(lstnrs) == 1
|
||||
assert lstnrs[0]["LoadBalancerArn"] == lbs[0]["LoadBalancerArn"]
|
||||
assert lstnrs[0]["Port"] == 80
|
||||
assert lstnrs[0]["Protocol"] == "HTTP"
|
||||
assert lstnrs[0]["DefaultActions"] == [
|
||||
{"Type": "forward", "TargetGroupArn": target_groups[0]["TargetGroupArn"]}
|
||||
]
|
||||
len(listener_rule).should.equal(3)
|
||||
listener_rule[0]["Priority"].should.equal("2")
|
||||
listener_rule[0]["Actions"].should.equal(
|
||||
[
|
||||
{
|
||||
"Type": "forward",
|
||||
"ForwardConfig": {
|
||||
"TargetGroups": [
|
||||
{
|
||||
"TargetGroupArn": target_groups[1]["TargetGroupArn"],
|
||||
"Weight": 1,
|
||||
},
|
||||
{
|
||||
"TargetGroupArn": target_groups[0]["TargetGroupArn"],
|
||||
"Weight": 2,
|
||||
},
|
||||
],
|
||||
"TargetGroupStickinessConfig": {"Enabled": False},
|
||||
},
|
||||
}
|
||||
],
|
||||
[{"Type": "forward", "TargetGroupArn": target_groups[1]["TargetGroupArn"]}],
|
||||
)
|
||||
listener_rule[0]["Conditions"].should.equal(
|
||||
[{"Field": "path-pattern", "Values": ["/*"]}]
|
||||
)
|
||||
|
||||
listener_rule[1]["Priority"].should.equal("30")
|
||||
listener_rule[1]["Actions"].should.equal(
|
||||
[{"Type": "forward", "TargetGroupArn": target_groups[1]["TargetGroupArn"]}]
|
||||
)
|
||||
listener_rule[1]["Conditions"].should.equal(
|
||||
[{"Field": "host-header", "Values": ["example.com"]}]
|
||||
)
|
||||
rule = elbv2_conn.describe_rules(ListenerArn=lstnrs[0]["ListenerArn"])["Rules"]
|
||||
assert len(rule) == 3
|
||||
assert rule[0]["Priority"] == "2"
|
||||
assert rule[0]["Actions"] == [
|
||||
{
|
||||
"Type": "forward",
|
||||
"ForwardConfig": {
|
||||
"TargetGroups": [
|
||||
{
|
||||
"TargetGroupArn": target_groups[1]["TargetGroupArn"],
|
||||
"Weight": 1,
|
||||
},
|
||||
{
|
||||
"TargetGroupArn": target_groups[0]["TargetGroupArn"],
|
||||
"Weight": 2,
|
||||
},
|
||||
],
|
||||
"TargetGroupStickinessConfig": {"Enabled": False},
|
||||
},
|
||||
}
|
||||
]
|
||||
assert rule[0]["Conditions"] == [{"Field": "path-pattern", "Values": ["/*"]}]
|
||||
|
||||
assert rule[1]["Priority"] == "30"
|
||||
assert rule[1]["Actions"] == [
|
||||
{"Type": "forward", "TargetGroupArn": target_groups[1]["TargetGroupArn"]}
|
||||
]
|
||||
assert rule[1]["Conditions"] == [
|
||||
{"Field": "host-header", "Values": ["example.com"]}
|
||||
]
|
||||
|
||||
# test outputs
|
||||
stacks = cfn_conn.describe_stacks(StackName="elb_stack")["Stacks"]
|
||||
len(stacks).should.equal(1)
|
||||
assert len(stacks) == 1
|
||||
|
||||
dns = list(
|
||||
filter(lambda item: item["OutputKey"] == "albdns", stacks[0]["Outputs"])
|
||||
@ -985,8 +962,8 @@ def test_stack_elbv2_resources_integration():
|
||||
filter(lambda item: item["OutputKey"] == "albname", stacks[0]["Outputs"])
|
||||
)[0]
|
||||
|
||||
dns["OutputValue"].should.equal(load_balancers[0]["DNSName"])
|
||||
name["OutputValue"].should.equal(load_balancers[0]["LoadBalancerName"])
|
||||
assert dns["OutputValue"] == lbs[0]["DNSName"]
|
||||
assert name["OutputValue"] == lbs[0]["LoadBalancerName"]
|
||||
|
||||
|
||||
@mock_dynamodb
|
||||
@ -1073,13 +1050,14 @@ def test_stack_dynamodb_resources_integration():
|
||||
|
||||
dynamodb_client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
table_desc = dynamodb_client.describe_table(TableName="myTableName")["Table"]
|
||||
table_desc["StreamSpecification"].should.equal(
|
||||
{"StreamEnabled": True, "StreamViewType": "KEYS_ONLY"}
|
||||
)
|
||||
assert table_desc["StreamSpecification"] == {
|
||||
"StreamEnabled": True,
|
||||
"StreamViewType": "KEYS_ONLY",
|
||||
}
|
||||
|
||||
dynamodb_conn = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
table = dynamodb_conn.Table("myTableName")
|
||||
table.name.should.equal("myTableName")
|
||||
assert table.name == "myTableName"
|
||||
|
||||
table.put_item(
|
||||
Item={"Album": "myAlbum", "Artist": "myArtist", "Sales": 10, "NumberOfSongs": 5}
|
||||
@ -1087,10 +1065,10 @@ def test_stack_dynamodb_resources_integration():
|
||||
|
||||
response = table.get_item(Key={"Album": "myAlbum", "Artist": "myArtist"})
|
||||
|
||||
response["Item"]["Album"].should.equal("myAlbum")
|
||||
response["Item"]["Sales"].should.equal(Decimal("10"))
|
||||
response["Item"]["NumberOfSongs"].should.equal(Decimal("5"))
|
||||
response["Item"]["Album"].should.equal("myAlbum")
|
||||
assert response["Item"]["Album"] == "myAlbum"
|
||||
assert response["Item"]["Sales"] == Decimal("10")
|
||||
assert response["Item"]["NumberOfSongs"] == Decimal("5")
|
||||
assert response["Item"]["Album"] == "myAlbum"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1133,7 +1111,7 @@ def test_create_log_group_using_fntransform():
|
||||
|
||||
logs_conn = boto3.client("logs", region_name="us-west-2")
|
||||
log_group = logs_conn.describe_log_groups()["logGroups"][0]
|
||||
log_group["logGroupName"].should.equal("some-log-group")
|
||||
assert log_group["logGroupName"] == "some-log-group"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1188,27 +1166,30 @@ def test_create_cloudwatch_logs_resource_policy():
|
||||
|
||||
logs_conn = boto3.client("logs", region_name="us-east-1")
|
||||
policies = logs_conn.describe_resource_policies()["resourcePolicies"]
|
||||
policies.should.have.length_of(1)
|
||||
policies.should.be.containing_item_with_attributes(
|
||||
policyName="TestPolicyA", policyDocument=policy_document
|
||||
)
|
||||
assert len(policies) == 1
|
||||
|
||||
assert policies[0]["policyName"] == "TestPolicyA"
|
||||
assert policies[0]["policyDocument"] == policy_document
|
||||
|
||||
cf_conn.update_stack(StackName="test_stack", TemplateBody=json.dumps(template2))
|
||||
policies = logs_conn.describe_resource_policies()["resourcePolicies"]
|
||||
policies.should.have.length_of(2)
|
||||
policies.should.be.containing_item_with_attributes(
|
||||
policyName="TestPolicyB", policyDocument=policy_document
|
||||
)
|
||||
policies.should.be.containing_item_with_attributes(
|
||||
policyName="TestPolicyC", policyDocument=policy_document
|
||||
)
|
||||
assert len(policies) == 2
|
||||
|
||||
policy_b = [pol for pol in policies if pol["policyName"] == "TestPolicyB"][0][
|
||||
"policyDocument"
|
||||
]
|
||||
assert policy_b == policy_document
|
||||
|
||||
policy_c = [pol for pol in policies if pol["policyName"] == "TestPolicyC"][0][
|
||||
"policyDocument"
|
||||
]
|
||||
assert policy_c == policy_document
|
||||
|
||||
cf_conn.update_stack(StackName="test_stack", TemplateBody=json.dumps(template1))
|
||||
policies = logs_conn.describe_resource_policies()["resourcePolicies"]
|
||||
policies.should.have.length_of(1)
|
||||
policies.should.be.containing_item_with_attributes(
|
||||
policyName="TestPolicyA", policyDocument=policy_document
|
||||
)
|
||||
assert len(policies) == 1
|
||||
assert policies[0]["policyName"] == "TestPolicyA"
|
||||
assert policies[0]["policyDocument"] == policy_document
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1232,11 +1213,11 @@ def test_delete_stack_containing_cloudwatch_logs_resource_policy():
|
||||
|
||||
logs_conn = boto3.client("logs", region_name="us-east-1")
|
||||
policies = logs_conn.describe_resource_policies()["resourcePolicies"]
|
||||
policies.should.have.length_of(1)
|
||||
assert len(policies) == 1
|
||||
|
||||
cf_conn.delete_stack(StackName="test_stack")
|
||||
policies = logs_conn.describe_resource_policies()["resourcePolicies"]
|
||||
policies.should.have.length_of(0)
|
||||
assert len(policies) == 0
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1261,12 +1242,10 @@ def test_delete_stack_with_deletion_policy_boto3():
|
||||
TemplateBody=sqs_template_json,
|
||||
)
|
||||
sqs = boto3.client("sqs", region_name="us-west-1")
|
||||
sqs.list_queues()["QueueUrls"].should.have.length_of(1)
|
||||
assert len(sqs.list_queues()["QueueUrls"]) == 1
|
||||
|
||||
cf.delete_stack(
|
||||
StackName="test_stack",
|
||||
)
|
||||
sqs.list_queues()["QueueUrls"].should.have.length_of(1)
|
||||
cf.delete_stack(StackName="test_stack")
|
||||
assert len(sqs.list_queues()["QueueUrls"]) == 1
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1291,10 +1270,10 @@ def test_stack_events_create_rule_integration():
|
||||
)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
rules["Rules"].should.have.length_of(1)
|
||||
rules["Rules"][0]["Name"].should.equal("quick-fox")
|
||||
rules["Rules"][0]["State"].should.equal("ENABLED")
|
||||
rules["Rules"][0]["ScheduleExpression"].should.equal("rate(5 minutes)")
|
||||
assert len(rules["Rules"]) == 1
|
||||
assert rules["Rules"][0]["Name"] == "quick-fox"
|
||||
assert rules["Rules"][0]["State"] == "ENABLED"
|
||||
assert rules["Rules"][0]["ScheduleExpression"] == "rate(5 minutes)"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1319,12 +1298,12 @@ def test_stack_events_delete_rule_integration():
|
||||
)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
rules["Rules"].should.have.length_of(1)
|
||||
assert len(rules["Rules"]) == 1
|
||||
|
||||
cf_conn.delete_stack(StackName="test_stack")
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
rules["Rules"].should.have.length_of(0)
|
||||
assert len(rules["Rules"]) == 0
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1348,7 +1327,7 @@ def test_stack_events_create_rule_without_name_integration():
|
||||
)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
rules["Rules"][0]["Name"].should.contain("test_stack-Event-")
|
||||
assert "test_stack-Event-" in rules["Rules"][0]["Name"]
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1382,10 +1361,10 @@ def test_stack_events_create_rule_as_target():
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
log_groups = boto3.client("logs", "us-west-2").describe_log_groups()
|
||||
|
||||
rules["Rules"][0]["Name"].should.contain("test_stack-Event-")
|
||||
assert "test_stack-Event-" in rules["Rules"][0]["Name"]
|
||||
|
||||
log_groups["logGroups"][0]["logGroupName"].should.equal(rules["Rules"][0]["Arn"])
|
||||
log_groups["logGroups"][0]["retentionInDays"].should.equal(3)
|
||||
assert log_groups["logGroups"][0]["logGroupName"] == rules["Rules"][0]["Arn"]
|
||||
assert log_groups["logGroups"][0]["retentionInDays"] == 3
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1413,18 +1392,18 @@ def test_stack_events_update_rule_integration():
|
||||
cf_conn.create_stack(StackName="test_stack", TemplateBody=original_template)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
rules["Rules"].should.have.length_of(1)
|
||||
rules["Rules"][0]["Name"].should.equal("Foo")
|
||||
rules["Rules"][0]["State"].should.equal("ENABLED")
|
||||
assert len(rules["Rules"]) == 1
|
||||
assert rules["Rules"][0]["Name"] == "Foo"
|
||||
assert rules["Rules"][0]["State"] == "ENABLED"
|
||||
|
||||
update_template = events_template.substitute(Name="Bar", State="DISABLED")
|
||||
cf_conn.update_stack(StackName="test_stack", TemplateBody=update_template)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
|
||||
rules["Rules"].should.have.length_of(1)
|
||||
rules["Rules"][0]["Name"].should.equal("Bar")
|
||||
rules["Rules"][0]["State"].should.equal("DISABLED")
|
||||
assert len(rules["Rules"]) == 1
|
||||
assert rules["Rules"][0]["Name"] == "Bar"
|
||||
assert rules["Rules"][0]["State"] == "DISABLED"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1519,8 +1498,8 @@ def test_stack_eventbus_create_from_cfn_integration():
|
||||
NamePrefix="MyCustom"
|
||||
)
|
||||
|
||||
event_buses["EventBuses"].should.have.length_of(1)
|
||||
event_buses["EventBuses"][0]["Name"].should.equal("MyCustomEventBus")
|
||||
assert len(event_buses["EventBuses"]) == 1
|
||||
assert event_buses["EventBuses"][0]["Name"] == "MyCustomEventBus"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1543,14 +1522,14 @@ def test_stack_events_delete_eventbus_integration():
|
||||
event_buses = boto3.client("events", "us-west-2").list_event_buses(
|
||||
NamePrefix="MyCustom"
|
||||
)
|
||||
event_buses["EventBuses"].should.have.length_of(1)
|
||||
assert len(event_buses["EventBuses"]) == 1
|
||||
|
||||
cf_conn.delete_stack(StackName="test_stack")
|
||||
|
||||
event_buses = boto3.client("events", "us-west-2").list_event_buses(
|
||||
NamePrefix="MyCustom"
|
||||
)
|
||||
event_buses["EventBuses"].should.have.length_of(0)
|
||||
assert len(event_buses["EventBuses"]) == 0
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1580,7 +1559,7 @@ def test_stack_events_delete_from_cfn_integration():
|
||||
original_event_buses = boto3.client("events", "us-west-2").list_event_buses(
|
||||
NamePrefix="MyCustom"
|
||||
)
|
||||
original_event_buses["EventBuses"].should.have.length_of(1)
|
||||
assert len(original_event_buses["EventBuses"]) == 1
|
||||
|
||||
original_eventbus = original_event_buses["EventBuses"][0]
|
||||
|
||||
@ -1592,8 +1571,8 @@ def test_stack_events_delete_from_cfn_integration():
|
||||
update_event_buses = boto3.client("events", "us-west-2").list_event_buses(
|
||||
NamePrefix="AnotherEventBus"
|
||||
)
|
||||
update_event_buses["EventBuses"].should.have.length_of(1)
|
||||
update_event_buses["EventBuses"][0]["Arn"].shouldnt.equal(original_eventbus["Arn"])
|
||||
assert len(update_event_buses["EventBuses"]) == 1
|
||||
assert update_event_buses["EventBuses"][0]["Arn"] != original_eventbus["Arn"]
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1621,7 +1600,7 @@ def test_stack_events_update_from_cfn_integration():
|
||||
original_event_buses = boto3.client("events", "us-west-2").list_event_buses(
|
||||
NamePrefix="MyCustom"
|
||||
)
|
||||
original_event_buses["EventBuses"].should.have.length_of(1)
|
||||
assert len(original_event_buses["EventBuses"]) == 1
|
||||
|
||||
original_eventbus = original_event_buses["EventBuses"][0]
|
||||
|
||||
@ -1631,9 +1610,9 @@ def test_stack_events_update_from_cfn_integration():
|
||||
update_event_buses = boto3.client("events", "us-west-2").list_event_buses(
|
||||
NamePrefix="NewEventBus"
|
||||
)
|
||||
update_event_buses["EventBuses"].should.have.length_of(1)
|
||||
update_event_buses["EventBuses"][0]["Name"].should.equal("NewEventBus")
|
||||
update_event_buses["EventBuses"][0]["Arn"].shouldnt.equal(original_eventbus["Arn"])
|
||||
assert len(update_event_buses["EventBuses"]) == 1
|
||||
assert update_event_buses["EventBuses"][0]["Name"] == "NewEventBus"
|
||||
assert update_event_buses["EventBuses"][0]["Arn"] != original_eventbus["Arn"]
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1668,8 +1647,8 @@ def test_stack_events_get_attribute_integration():
|
||||
|
||||
event_bus = events.list_event_buses(NamePrefix="MyEventBus")["EventBuses"][0]
|
||||
|
||||
output_arn["OutputValue"].should.equal(event_bus["Arn"])
|
||||
output_name["OutputValue"].should.equal(event_bus["Name"])
|
||||
assert output_arn["OutputValue"] == event_bus["Arn"]
|
||||
assert output_name["OutputValue"] == event_bus["Name"]
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1699,13 +1678,13 @@ def test_dynamodb_table_creation():
|
||||
# Verify the TableName is part of the outputs
|
||||
stack = cfn.describe_stacks(StackName=stack_name)["Stacks"][0]
|
||||
outputs = stack["Outputs"]
|
||||
outputs.should.have.length_of(1)
|
||||
outputs[0]["OutputKey"].should.equal("MyTableName")
|
||||
outputs[0]["OutputValue"].should.contain("foobar")
|
||||
assert len(outputs) == 1
|
||||
assert outputs[0]["OutputKey"] == "MyTableName"
|
||||
assert "foobar" in outputs[0]["OutputValue"]
|
||||
# Assert the table is created
|
||||
ddb = boto3.client("dynamodb", "us-west-2")
|
||||
table_names = ddb.list_tables()["TableNames"]
|
||||
table_names.should.equal([outputs[0]["OutputValue"]])
|
||||
assert table_names == [outputs[0]["OutputValue"]]
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1735,15 +1714,15 @@ def test_ssm_parameter():
|
||||
|
||||
stack_resources = cfn.list_stack_resources(StackName=stack_name)
|
||||
ssm_resource = stack_resources.get("StackResourceSummaries")[0]
|
||||
ssm_resource.get("PhysicalResourceId").should.equal("test_ssm")
|
||||
assert ssm_resource.get("PhysicalResourceId") == "test_ssm"
|
||||
|
||||
ssm_client = boto3.client("ssm", region_name="us-west-2")
|
||||
parameters = ssm_client.get_parameters(Names=["test_ssm"], WithDecryption=False)[
|
||||
"Parameters"
|
||||
]
|
||||
parameters.should.have.length_of(1)
|
||||
parameters[0]["Name"].should.equal("test_ssm")
|
||||
parameters[0]["Value"].should.equal("Test SSM Parameter")
|
||||
assert len(parameters) == 1
|
||||
assert parameters[0]["Name"] == "test_ssm"
|
||||
assert parameters[0]["Value"] == "Test SSM Parameter"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1775,9 +1754,9 @@ def test_ssm_parameter_update_stack():
|
||||
parameters = ssm_client.get_parameters(Names=["test_ssm"], WithDecryption=False)[
|
||||
"Parameters"
|
||||
]
|
||||
parameters.should.have.length_of(1)
|
||||
parameters[0]["Name"].should.equal("test_ssm")
|
||||
parameters[0]["Value"].should.equal("Test SSM Parameter")
|
||||
assert len(parameters) == 1
|
||||
assert parameters[0]["Name"] == "test_ssm"
|
||||
assert parameters[0]["Value"] == "Test SSM Parameter"
|
||||
|
||||
parameter_template["Resources"]["BasicParameter"]["Properties"][
|
||||
"Value"
|
||||
@ -1788,9 +1767,9 @@ def test_ssm_parameter_update_stack():
|
||||
parameters = ssm_client.get_parameters(Names=["test_ssm"], WithDecryption=False)[
|
||||
"Parameters"
|
||||
]
|
||||
parameters.should.have.length_of(1)
|
||||
parameters[0]["Name"].should.equal("test_ssm")
|
||||
parameters[0]["Value"].should.equal("Test SSM Parameter Updated")
|
||||
assert len(parameters) == 1
|
||||
assert parameters[0]["Name"] == "test_ssm"
|
||||
assert parameters[0]["Value"] == "Test SSM Parameter Updated"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1822,9 +1801,9 @@ def test_ssm_parameter_update_stack_and_remove_resource():
|
||||
parameters = ssm_client.get_parameters(Names=["test_ssm"], WithDecryption=False)[
|
||||
"Parameters"
|
||||
]
|
||||
parameters.should.have.length_of(1)
|
||||
parameters[0]["Name"].should.equal("test_ssm")
|
||||
parameters[0]["Value"].should.equal("Test SSM Parameter")
|
||||
assert len(parameters) == 1
|
||||
assert parameters[0]["Name"] == "test_ssm"
|
||||
assert parameters[0]["Value"] == "Test SSM Parameter"
|
||||
|
||||
parameter_template["Resources"].pop("BasicParameter")
|
||||
cfn.update_stack(StackName=stack_name, TemplateBody=json.dumps(parameter_template))
|
||||
@ -1833,7 +1812,7 @@ def test_ssm_parameter_update_stack_and_remove_resource():
|
||||
parameters = ssm_client.get_parameters(Names=["test_ssm"], WithDecryption=False)[
|
||||
"Parameters"
|
||||
]
|
||||
parameters.should.have.length_of(0)
|
||||
assert len(parameters) == 0
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -1851,7 +1830,7 @@ def test_ssm_parameter_update_stack_and_add_resource():
|
||||
parameters = ssm_client.get_parameters(Names=["test_ssm"], WithDecryption=False)[
|
||||
"Parameters"
|
||||
]
|
||||
parameters.should.have.length_of(0)
|
||||
assert len(parameters) == 0
|
||||
|
||||
parameter_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
@ -1874,6 +1853,6 @@ def test_ssm_parameter_update_stack_and_add_resource():
|
||||
parameters = ssm_client.get_parameters(Names=["test_ssm"], WithDecryption=False)[
|
||||
"Parameters"
|
||||
]
|
||||
parameters.should.have.length_of(1)
|
||||
parameters[0]["Name"].should.equal("test_ssm")
|
||||
parameters[0]["Value"].should.equal("Test SSM Parameter")
|
||||
assert len(parameters) == 1
|
||||
assert parameters[0]["Name"] == "test_ssm"
|
||||
assert parameters[0]["Value"] == "Test SSM Parameter"
|
||||
|
@ -15,9 +15,9 @@ def test_set_stack_policy_on_nonexisting_stack():
|
||||
with pytest.raises(ClientError) as exc:
|
||||
cf_conn.set_stack_policy(StackName="unknown", StackPolicyBody="{}")
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal("Stack: unknown does not exist")
|
||||
err["Type"].should.equal("Sender")
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert err["Message"] == "Stack: unknown does not exist"
|
||||
assert err["Type"] == "Sender"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -27,9 +27,9 @@ def test_get_stack_policy_on_nonexisting_stack():
|
||||
with pytest.raises(ClientError) as exc:
|
||||
cf_conn.get_stack_policy(StackName="unknown")
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal("Stack: unknown does not exist")
|
||||
err["Type"].should.equal("Sender")
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert err["Message"] == "Stack: unknown does not exist"
|
||||
assert err["Type"] == "Sender"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -38,7 +38,7 @@ def test_get_stack_policy_on_stack_without_policy():
|
||||
cf_conn.create_stack(StackName="test_stack", TemplateBody=dummy_template_json)
|
||||
|
||||
resp = cf_conn.get_stack_policy(StackName="test_stack")
|
||||
resp.shouldnt.have.key("StackPolicyBody")
|
||||
assert "StackPolicyBody" not in resp
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -51,11 +51,11 @@ def test_set_stack_policy_with_both_body_and_url():
|
||||
StackName="test_stack", StackPolicyBody="{}", StackPolicyURL="..."
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal(
|
||||
"You cannot specify both StackPolicyURL and StackPolicyBody"
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert (
|
||||
err["Message"] == "You cannot specify both StackPolicyURL and StackPolicyBody"
|
||||
)
|
||||
err["Type"].should.equal("Sender")
|
||||
assert err["Type"] == "Sender"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -68,7 +68,7 @@ def test_set_stack_policy_with_body():
|
||||
cf_conn.set_stack_policy(StackName="test_stack", StackPolicyBody=policy)
|
||||
|
||||
resp = cf_conn.get_stack_policy(StackName="test_stack")
|
||||
resp.should.have.key("StackPolicyBody").equals(policy)
|
||||
assert resp["StackPolicyBody"] == policy
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -81,7 +81,7 @@ def test_set_stack_policy_on_create():
|
||||
)
|
||||
|
||||
resp = cf_conn.get_stack_policy(StackName="test_stack")
|
||||
resp.should.have.key("StackPolicyBody").equals("stack_policy_body")
|
||||
assert resp["StackPolicyBody"] == "stack_policy_body"
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -101,7 +101,7 @@ def test_set_stack_policy_with_url():
|
||||
cf_conn.set_stack_policy(StackName="test_stack", StackPolicyURL=key_url)
|
||||
|
||||
resp = cf_conn.get_stack_policy(StackName="test_stack")
|
||||
resp.should.have.key("StackPolicyBody").equals(policy)
|
||||
assert resp["StackPolicyBody"] == policy
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -113,6 +113,6 @@ def test_set_stack_policy_with_url_pointing_to_unknown_key():
|
||||
with pytest.raises(ClientError) as exc:
|
||||
cf_conn.set_stack_policy(StackName="test_stack", StackPolicyURL="...")
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.contain("S3 error: Access Denied")
|
||||
err["Type"].should.equal("Sender")
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert "S3 error: Access Denied" in err["Message"]
|
||||
assert err["Type"] == "Sender"
|
||||
|
@ -1,6 +1,5 @@
|
||||
import json
|
||||
import re
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
import moto.server as server
|
||||
|
||||
@ -17,17 +16,15 @@ def test_cloudformation_server_get():
|
||||
create_stack_resp = test_client.action_data(
|
||||
"CreateStack", StackName=stack_name, TemplateBody=json.dumps(template_body)
|
||||
)
|
||||
create_stack_resp.should.match(
|
||||
r"<CreateStackResponse>.*<CreateStackResult>.*<StackId>.*</StackId>.*</CreateStackResult>.*</CreateStackResponse>",
|
||||
re.DOTALL,
|
||||
)
|
||||
stack_id_from_create_response = re.search(
|
||||
assert "<CreateStackResponse>" in create_stack_resp
|
||||
assert "<StackId>" in create_stack_resp
|
||||
stack_id_from_create = re.search(
|
||||
"<StackId>(.*)</StackId>", create_stack_resp
|
||||
).groups()[0]
|
||||
|
||||
list_stacks_resp = test_client.action_data("ListStacks")
|
||||
stack_id_from_list_response = re.search(
|
||||
stack_id_from_list = re.search(
|
||||
"<StackId>(.*)</StackId>", list_stacks_resp
|
||||
).groups()[0]
|
||||
|
||||
stack_id_from_create_response.should.equal(stack_id_from_list_response)
|
||||
assert stack_id_from_create == stack_id_from_list
|
||||
|
@ -3,7 +3,6 @@ import json
|
||||
import yaml
|
||||
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from botocore.exceptions import ClientError
|
||||
from unittest.mock import patch
|
||||
|
||||
@ -259,15 +258,15 @@ def test_parse_stack_resources():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(2)
|
||||
assert len(stack.resource_map) == 2
|
||||
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.should.be.a(Queue)
|
||||
queue.name.should.equal("my-queue")
|
||||
assert isinstance(queue, Queue)
|
||||
assert queue.name == "my-queue"
|
||||
|
||||
bucket = stack.resource_map["S3Bucket"]
|
||||
bucket.should.be.a(FakeBucket)
|
||||
bucket.physical_resource_id.should.equal(bucket.name)
|
||||
assert isinstance(bucket, FakeBucket)
|
||||
assert bucket.physical_resource_id == bucket.name
|
||||
|
||||
|
||||
@patch("moto.cloudformation.parsing.logger")
|
||||
@ -286,10 +285,10 @@ def test_parse_stack_with_name_type_resource():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
list(stack.resource_map.keys())[0].should.equal("Queue")
|
||||
assert len(stack.resource_map) == 1
|
||||
assert list(stack.resource_map.keys())[0] == "Queue"
|
||||
queue = list(stack.resource_map.values())[0]
|
||||
queue.should.be.a(Queue)
|
||||
assert isinstance(queue, Queue)
|
||||
|
||||
|
||||
def test_parse_stack_with_tabbed_json_template():
|
||||
@ -302,10 +301,10 @@ def test_parse_stack_with_tabbed_json_template():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
list(stack.resource_map.keys())[0].should.equal("Queue")
|
||||
assert len(stack.resource_map) == 1
|
||||
assert list(stack.resource_map.keys())[0] == "Queue"
|
||||
queue = list(stack.resource_map.values())[0]
|
||||
queue.should.be.a(Queue)
|
||||
assert isinstance(queue, Queue)
|
||||
|
||||
|
||||
def test_parse_stack_with_yaml_template():
|
||||
@ -318,10 +317,10 @@ def test_parse_stack_with_yaml_template():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
list(stack.resource_map.keys())[0].should.equal("Queue")
|
||||
assert len(stack.resource_map) == 1
|
||||
assert list(stack.resource_map.keys())[0] == "Queue"
|
||||
queue = list(stack.resource_map.values())[0]
|
||||
queue.should.be.a(Queue)
|
||||
assert isinstance(queue, Queue)
|
||||
|
||||
|
||||
def test_parse_stack_with_outputs():
|
||||
@ -334,11 +333,11 @@ def test_parse_stack_with_outputs():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal("Output1")
|
||||
assert len(stack.output_map) == 1
|
||||
assert list(stack.output_map.keys())[0] == "Output1"
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
output.description.should.equal("This is a description.")
|
||||
assert isinstance(output, Output)
|
||||
assert output.description == "This is a description."
|
||||
|
||||
|
||||
def test_parse_stack_with_get_attribute_outputs():
|
||||
@ -351,11 +350,11 @@ def test_parse_stack_with_get_attribute_outputs():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal("Output1")
|
||||
assert len(stack.output_map) == 1
|
||||
assert list(stack.output_map.keys())[0] == "Output1"
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
output.value.should.equal("my-queue")
|
||||
assert isinstance(output, Output)
|
||||
assert output.value == "my-queue"
|
||||
|
||||
|
||||
def test_parse_stack_with_get_attribute_kms():
|
||||
@ -371,10 +370,10 @@ def test_parse_stack_with_get_attribute_kms():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal("KeyArn")
|
||||
assert len(stack.output_map) == 1
|
||||
assert list(stack.output_map.keys())[0] == "KeyArn"
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
assert isinstance(output, Output)
|
||||
|
||||
|
||||
def test_parse_stack_with_get_availability_zones():
|
||||
@ -387,11 +386,11 @@ def test_parse_stack_with_get_availability_zones():
|
||||
region_name="us-east-1",
|
||||
)
|
||||
|
||||
stack.output_map.should.have.length_of(1)
|
||||
list(stack.output_map.keys())[0].should.equal("Output1")
|
||||
assert len(stack.output_map) == 1
|
||||
assert list(stack.output_map.keys())[0] == "Output1"
|
||||
output = list(stack.output_map.values())[0]
|
||||
output.should.be.a(Output)
|
||||
output.value.should.equal(["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d"])
|
||||
assert isinstance(output, Output)
|
||||
assert output.value == ["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d"]
|
||||
|
||||
|
||||
@mock_sqs
|
||||
@ -401,9 +400,10 @@ def test_parse_stack_with_bad_get_attribute_outputs_using_boto3():
|
||||
with pytest.raises(ClientError) as exc:
|
||||
conn.create_stack(StackName="teststack", TemplateBody=bad_output_template_json)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ValidationError")
|
||||
err["Message"].should.equal(
|
||||
"Template error: resource Queue does not support attribute type InvalidAttribute in Fn::GetAtt"
|
||||
assert err["Code"] == "ValidationError"
|
||||
assert (
|
||||
err["Message"]
|
||||
== "Template error: resource Queue does not support attribute type InvalidAttribute in Fn::GetAtt"
|
||||
)
|
||||
|
||||
|
||||
@ -417,8 +417,7 @@ def test_parse_stack_with_null_outputs_section():
|
||||
account_id=ACCOUNT_ID,
|
||||
region_name="us-west-1",
|
||||
)
|
||||
err = str(exc.value)
|
||||
err.should.contain("[/Outputs] 'null' values are not allowed in templates")
|
||||
assert "[/Outputs] 'null' values are not allowed in templates" in str(exc.value)
|
||||
|
||||
|
||||
def test_parse_stack_with_parameters():
|
||||
@ -436,98 +435,123 @@ def test_parse_stack_with_parameters():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.no_echo_parameter_keys.should.have("NoEchoParam")
|
||||
stack.resource_map.no_echo_parameter_keys.should_not.have("Param")
|
||||
stack.resource_map.no_echo_parameter_keys.should_not.have("NumberParam")
|
||||
stack.resource_map.no_echo_parameter_keys.should_not.have("NumberListParam")
|
||||
stack.resource_map.resolved_parameters["NumberParam"].should.equal(42)
|
||||
stack.resource_map.resolved_parameters["NumberListParam"].should.equal(
|
||||
[42, 3.14159]
|
||||
)
|
||||
assert "NoEchoParam" in stack.resource_map.no_echo_parameter_keys
|
||||
assert "Param" not in stack.resource_map.no_echo_parameter_keys
|
||||
assert "NumberParam" not in stack.resource_map.no_echo_parameter_keys
|
||||
assert "NumberListParam" not in stack.resource_map.no_echo_parameter_keys
|
||||
assert stack.resource_map.resolved_parameters["NumberParam"] == 42
|
||||
assert stack.resource_map.resolved_parameters["NumberListParam"] == [42, 3.14159]
|
||||
|
||||
|
||||
def test_parse_equals_condition():
|
||||
parse_condition(
|
||||
condition={"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
).should.equal(True)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
parse_condition(
|
||||
condition={"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
resources_map={"EnvType": "staging"},
|
||||
condition_map={},
|
||||
).should.equal(False)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
resources_map={"EnvType": "staging"},
|
||||
condition_map={},
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
def test_parse_not_condition():
|
||||
parse_condition(
|
||||
condition={"Fn::Not": [{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]}]},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
).should.equal(False)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={"Fn::Not": [{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]}]},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
parse_condition(
|
||||
condition={"Fn::Not": [{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]}]},
|
||||
resources_map={"EnvType": "staging"},
|
||||
condition_map={},
|
||||
).should.equal(True)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={"Fn::Not": [{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]}]},
|
||||
resources_map={"EnvType": "staging"},
|
||||
condition_map={},
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
|
||||
def test_parse_and_condition():
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::And": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
).should.equal(False)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::And": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::And": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
).should.equal(True)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::And": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
|
||||
def test_parse_or_condition():
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::Or": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
).should.equal(True)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::Or": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::Or": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
).should.equal(False)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={
|
||||
"Fn::Or": [
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
{"Fn::Equals": [{"Ref": "EnvType"}, "staging"]},
|
||||
]
|
||||
},
|
||||
resources_map={"EnvType": "prod"},
|
||||
condition_map={},
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
def test_reference_other_conditions():
|
||||
parse_condition(
|
||||
condition={"Fn::Not": [{"Condition": "OtherCondition"}]},
|
||||
resources_map={},
|
||||
condition_map={"OtherCondition": True},
|
||||
).should.equal(False)
|
||||
assert (
|
||||
parse_condition(
|
||||
condition={"Fn::Not": [{"Condition": "OtherCondition"}]},
|
||||
resources_map={},
|
||||
condition_map={"OtherCondition": True},
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
def test_parse_split_and_select():
|
||||
@ -540,9 +564,9 @@ def test_parse_split_and_select():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
assert len(stack.resource_map) == 1
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.name.should.equal("myqueue")
|
||||
assert queue.name == "myqueue"
|
||||
|
||||
|
||||
def test_sub():
|
||||
@ -557,7 +581,7 @@ def test_sub():
|
||||
|
||||
queue1 = stack.resource_map["Queue1"]
|
||||
queue2 = stack.resource_map["Queue2"]
|
||||
queue2.name.should.equal(queue1.name)
|
||||
assert queue2.name == queue1.name
|
||||
|
||||
|
||||
def test_sub_num():
|
||||
@ -572,7 +596,7 @@ def test_sub_num():
|
||||
|
||||
# Errors on moto<=4.0.10 because int(42) is used with str.replace
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.name.should.equal("test_stack-queue-42")
|
||||
assert queue.name == "test_stack-queue-42"
|
||||
|
||||
|
||||
def test_sub_mapping():
|
||||
@ -585,7 +609,7 @@ def test_sub_mapping():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.name.should.equal("test_stack-queue-apple-yes")
|
||||
assert queue.name == "test_stack-queue-apple-yes"
|
||||
|
||||
stack = FakeStack(
|
||||
stack_id="test_id",
|
||||
@ -596,7 +620,7 @@ def test_sub_mapping():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.name.should.equal("test_stack-queue-banana-no")
|
||||
assert queue.name == "test_stack-queue-banana-no"
|
||||
|
||||
|
||||
def test_import():
|
||||
@ -619,7 +643,7 @@ def test_import():
|
||||
)
|
||||
|
||||
queue = import_stack.resource_map["Queue"]
|
||||
queue.name.should.equal("value")
|
||||
assert queue.name == "value"
|
||||
|
||||
|
||||
def test_to_json_string():
|
||||
@ -632,8 +656,8 @@ def test_to_json_string():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
queue = stack.resource_map["Queue"]
|
||||
queue.name.should.equal("test")
|
||||
queue.dead_letter_queue.name.should.equal("deadletter")
|
||||
assert queue.name == "test"
|
||||
assert queue.dead_letter_queue.name == "deadletter"
|
||||
|
||||
|
||||
def test_short_form_func_in_yaml_teamplate():
|
||||
@ -676,7 +700,7 @@ def test_short_form_func_in_yaml_teamplate():
|
||||
["KeySub", {"Fn::Sub": "A"}],
|
||||
]
|
||||
for k, v in key_and_expects:
|
||||
template_dict.should.have.key(k).which.should.be.equal(v)
|
||||
assert template_dict[k] == v
|
||||
|
||||
|
||||
@mock_ssm
|
||||
@ -700,10 +724,9 @@ def test_ssm_parameter_parsing():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.resolved_parameters["SingleParamCfn"].should.equal("string")
|
||||
stack.resource_map.resolved_parameters["ListParamCfn"].should.equal(
|
||||
["comma", "separated", "string"]
|
||||
)
|
||||
params = stack.resource_map.resolved_parameters
|
||||
assert params["SingleParamCfn"] == "string"
|
||||
assert params["ListParamCfn"] == ["comma", "separated", "string"]
|
||||
|
||||
# Not passing in a value for ListParamCfn to test Default value
|
||||
if not settings.TEST_SERVER_MODE:
|
||||
@ -716,7 +739,6 @@ def test_ssm_parameter_parsing():
|
||||
region_name="us-west-1",
|
||||
)
|
||||
|
||||
stack.resource_map.resolved_parameters["SingleParamCfn"].should.equal("string")
|
||||
stack.resource_map.resolved_parameters["ListParamCfn"].should.equal(
|
||||
["comma", "separated", "string"]
|
||||
)
|
||||
params = stack.resource_map.resolved_parameters
|
||||
assert params["SingleParamCfn"] == "string"
|
||||
assert params["ListParamCfn"] == ["comma", "separated", "string"]
|
||||
|
@ -1,7 +1,7 @@
|
||||
import json
|
||||
import boto3
|
||||
import botocore
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
|
||||
from moto import mock_cloudformation, mock_s3
|
||||
from tests import EXAMPLE_AMI_ID
|
||||
@ -63,15 +63,13 @@ def test_boto3_json_with_tabs_validate_successful():
|
||||
@mock_cloudformation
|
||||
def test_boto3_json_invalid_missing_resource():
|
||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
try:
|
||||
with pytest.raises(botocore.exceptions.ClientError) as exc:
|
||||
cf_conn.validate_template(TemplateBody=dummy_bad_template_json)
|
||||
assert False
|
||||
except botocore.exceptions.ClientError as e:
|
||||
str(e).should.contain(
|
||||
"An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack"
|
||||
" with id Missing top level"
|
||||
)
|
||||
assert True
|
||||
err = exc.value.response["Error"]
|
||||
assert (
|
||||
err["Message"]
|
||||
== "Stack with id Missing top level template section Resources does not exist"
|
||||
)
|
||||
|
||||
|
||||
yaml_template = """
|
||||
@ -122,12 +120,10 @@ def test_boto3_yaml_validate_template_url_successful():
|
||||
@mock_cloudformation
|
||||
def test_boto3_yaml_invalid_missing_resource():
|
||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
try:
|
||||
with pytest.raises(botocore.exceptions.ClientError) as exc:
|
||||
cf_conn.validate_template(TemplateBody=yaml_bad_template)
|
||||
assert False
|
||||
except botocore.exceptions.ClientError as e:
|
||||
str(e).should.contain(
|
||||
"An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack"
|
||||
" with id Missing top level"
|
||||
)
|
||||
assert True
|
||||
err = exc.value.response["Error"]
|
||||
assert (
|
||||
err["Message"]
|
||||
== "Stack with id Missing top level template section Resources does not exist"
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user