Skip to content

Commit

Permalink
Generalized an parametrized tests to be applied to ExampleDataBucket,…
Browse files Browse the repository at this point in the history
… too
  • Loading branch information
ckunki committed Jul 30, 2024
1 parent a8e23cb commit 865ae33
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 59 deletions.
95 changes: 62 additions & 33 deletions test/aws/mock_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,34 @@
TEST_CLOUDFRONT_ID = "test-cloudfrontet-TEST"
TEST_CLOUDFRONT_DOMAIN_NAME = "test-s3.cloudfront.net"
INSTANCE_ID = "test-instance"
VM_BUCKET_OUTPUTS = {
"VMBucketId": TEST_BUCKET_ID,
"VMExportRoleId": TEST_ROLE_ID,
"CfDistributionId": TEST_CLOUDFRONT_ID,
"CfDistributionDomainName": TEST_CLOUDFRONT_DOMAIN_NAME,
}
EXAMPLE_DATA_BUCKET_OUTPUTS = {
"ExampleDataBucketId": TEST_BUCKET_ID,
"ExportRoleId": TEST_ROLE_ID,
"CfDistributionId": TEST_CLOUDFRONT_ID,
"CfDistributionDomainName": TEST_CLOUDFRONT_DOMAIN_NAME,
}
VM_BUCKET_WAF_OUTPUTS = { 'VMDownloadACLArn': TEST_ACL_ARN }
EXAMPLE_DATA_WAF_OUTPUTS = { 'AiLabExampleDataDownloadACLArn': TEST_ACL_ARN }


def cf_stack_outputs(class_name: str, category: str) -> Dict[str, any]:
outputs = {
"VmBucketCfTemplate": {
"s3": VM_BUCKET_OUTPUTS,
"waf": VM_BUCKET_WAF_OUTPUTS,
},
"ExampleDataCfTemplate": {
"s3": EXAMPLE_DATA_BUCKET_OUTPUTS,
"waf": EXAMPLE_DATA_WAF_OUTPUTS,
},
}
return outputs[class_name][category]


def default_tags() -> List[Dict[str, str]]:
Expand Down Expand Up @@ -147,45 +175,46 @@ def get_ec2_key_pair_mock_data():
})


def get_s3_cloudformation_mock_data() -> List[CloudformationStack]:
return [CloudformationStack({
'StackId': 'test-s3-stack-id',
'StackName': "DATA-SCIENCE-SANDBOX-VM-Bucket",
'ChangeSetId': 'test-stack-changeset-id-2',
'CreationTime': datetime.datetime(2022, 8, 16, 14, 30, 45, 559000, tzinfo=tzutc()),
'LastUpdatedTime': datetime.datetime(2022, 8, 16, 14, 30, 51, 667000, tzinfo=tzutc()),
def mock_outputs(output_values: Dict[str, str]):
def transform(k, v):
return {
"OutputKey": k,
"OutputValue": v,
"Description": "n/a",
}
return [ transform(k, v) for k, v in output_values.items() ]


def cf_stack_mock_data(stack_name: str, outputs: Dict[str, str]) -> Dict[str, any]:
created = datetime.datetime(2022, 8, 16, 14, 30, 45, 559000, tzinfo=tzutc())
last_update = datetime.datetime(2022, 8, 16, 14, 30, 51, 667000, tzinfo=tzutc())
return {
'StackId': 'test-stack-id',
'StackName': stack_name,
'ChangeSetId': 'test-stack-changeset-id',
'CreationTime': created,
'LastUpdatedTime': last_update,
'RollbackConfiguration': {},
'StackStatus': 'CREATE_COMPLETE',
'DisableRollback': False, 'NotificationARNs': [], 'Capabilities': ['CAPABILITY_IAM'],
'Tags': default_tags(),
'DriftInformation': {'StackDriftStatus': 'NOT_CHECKED'},
'Outputs': [{'OutputKey': 'VMBucketId',
'OutputValue': TEST_BUCKET_ID, 'Description': ''},
{'OutputKey': 'VMExportRoleId',
'OutputValue': TEST_ROLE_ID, 'Description': ''},
{'OutputKey': 'CfDistributionId',
'OutputValue': TEST_CLOUDFRONT_ID, 'Description': ''},
{'OutputKey': 'CfDistributionDomainName',
'OutputValue': TEST_CLOUDFRONT_DOMAIN_NAME, 'Description': ''}
]
})
'Outputs': mock_outputs(outputs)
}


def cf_stack_mock(stack_name: str, outputs: Dict[str, str]) -> List[CloudformationStack]:
return [
CloudformationStack(cf_stack_mock_data(stack_name, outputs))
]


def get_s3_cloudformation_mock_data() -> List[CloudformationStack]:
return cf_stack_mock("DATA-SCIENCE-SANDBOX-VM-Bucket", VM_BUCKET_OUTPUTS)


def get_waf_cloudformation_mock_data() -> List[CloudformationStack]:
return [CloudformationStack({
'StackId': 'test-waf-stack-id',
'StackName': "DATA-SCIENCE-SANDBOX-VM-Bucket-WAF",
'ChangeSetId': 'test-stack-changeset-id-3',
'CreationTime': datetime.datetime(2022, 8, 16, 14, 30, 45, 559000, tzinfo=tzutc()),
'LastUpdatedTime': datetime.datetime(2022, 8, 16, 14, 30, 51, 667000, tzinfo=tzutc()),
'RollbackConfiguration': {},
'StackStatus': 'CREATE_COMPLETE',
'DisableRollback': False, 'NotificationARNs': [], 'Capabilities': [],
'Tags': default_tags(),
'DriftInformation': {'StackDriftStatus': 'NOT_CHECKED'},
'Outputs': [{'OutputKey': 'VMDownloadACLArn',
'OutputValue': TEST_ACL_ARN, 'Description': ''}
]
})
]
return cf_stack_mock(
"DATA-SCIENCE-SANDBOX-VM-Bucket-WAF",
VM_BUCKET_WAF_OUTPUTS,
)
31 changes: 17 additions & 14 deletions test/unit/aws/test_deploy_s3_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
ExampleDataCfTemplate,
)
from test.aws.mock_data import (
TEST_BUCKET_ID,
get_waf_cloudformation_mock_data,
get_s3_cloudformation_mock_data,
cf_stack_mock,
cf_stack_outputs,
TEST_BUCKET_ID,
)
from test.mock_cast import mock_cast

Expand All @@ -21,23 +22,25 @@ def cf_template_testee(request):
return request.param


# To enable running this test case for ExampleDataCfTemplate
# would require to create modified copies of
# - get_s3_cloudformation_mock_data
# - get_waf_cloudformation_mock_data
# - TEST_BUCKET_ID
#
# Is this worth the effort and/or code duplication?
def test_find_bucket_success(test_config):

def test_find_bucket_success(test_config, cf_template_testee):
"""
This test uses a mock to validate the correct finding of the bucket in the stack.
"""
aws: Union[AwsAccess, Mock] = create_autospec(AwsAccess, spec_set=True)
mock_cast(aws.describe_stacks).return_value = \
get_s3_cloudformation_mock_data() + \
get_waf_cloudformation_mock_data()
testee = cf_template_testee(aws)

bucket = cf_stack_mock(
testee.stack_name,
cf_stack_outputs(cf_template_testee.__name__, "s3")
)
waf = cf_stack_mock(
testee.waf(test_config).stack_name,
cf_stack_outputs(cf_template_testee.__name__, "waf"),
)

mock_cast(aws.describe_stacks).return_value = bucket + waf
mock_cast(aws.instantiate_for_region).return_value = aws
testee = VmBucketCfTemplate(aws)
testee.setup(test_config)
mock_cast(aws.upload_cloudformation_stack).assert_called_once()
assert TEST_BUCKET_ID == testee.id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
import pytest
from typing import Union
from unittest.mock import Mock, create_autospec

from exasol.ds.sandbox.lib.aws_access.aws_access import AwsAccess
from exasol.ds.sandbox.lib.cloudformation_templates import VmBucketCfTemplate
from exasol.ds.sandbox.lib.cloudformation_templates import (
VmBucketCfTemplate,
ExampleDataCfTemplate,
)
from test.aws.templates import TEST_IP, TEST_ACL_ARN
from test.aws.mock_data import get_waf_cloudformation_mock_data
from test.aws.mock_data import (
cf_stack_mock,
cf_stack_outputs,
)
from test.mock_cast import mock_cast


# To enable running this test case for ExampleDataCfTemplate
# would require to create modified copies of
# - get_s3_cloudformation_mock_data
# - get_waf_cloudformation_mock_data
# - TEST_BUCKET_ID
#
# Is this worth the effort and/or code duplication?
def test_find_acl_arn(test_config):
@pytest.fixture(params=(VmBucketCfTemplate, ExampleDataCfTemplate))
def cf_template_testee(request):
return request.param


def test_find_acl_arn(test_config, cf_template_testee):
"""
This test uses a mock to validate the correct finding of the ACL Arn
in the mocked cloudformation stack.
"""
aws: Union[AwsAccess, Mock] = create_autospec(AwsAccess, spec_set=True)
mock_cast(aws.describe_stacks).return_value = get_waf_cloudformation_mock_data()
mock_cast(aws.instantiate_for_region).return_value = aws
testee = VmBucketCfTemplate(aws).waf(config=test_config)
testee = cf_template_testee(aws).waf(config=test_config)
mock_cast(aws.describe_stacks).return_value = cf_stack_mock(
testee.stack_name,
cf_stack_outputs(cf_template_testee.__name__, "waf"),
)
testee.setup(TEST_IP)
mock_cast(aws.upload_cloudformation_stack).assert_called_once()
assert TEST_ACL_ARN == testee.acl_arn

0 comments on commit 865ae33

Please sign in to comment.