def test_write_resources(cloudwanderer_aws, aws_interface, default_test_discovery_actions): create_iam_role() create_s3_buckets(regions=["eu-west-2", "us-east-1"]) aws_interface.get_resource_discovery_actions = MagicMock( return_value=default_test_discovery_actions) thread_results = list( cloudwanderer_aws.write_resources_concurrently( concurrency=2, cloud_interface_generator=lambda: aws_interface, storage_connector_generator=lambda: [MemoryStorageConnector()], )) connector_results = [ resource_record for result in thread_results for connector in result.storage_connectors for resource_record in connector.read_all() ] result_summary = set([(URN.from_string(result["urn"]).region, URN.from_string(result["urn"]).resource_type) for result in connector_results]) assert result_summary == { ("eu-west-2", "bucket"), ("eu-west-2", "vpc"), ("us-east-1", "bucket"), ("us-east-1", "role"), ("us-east-1", "role_policy"), ("us-east-1", "vpc"), }
def test_all_custom_resources(file_name, aws_interface): with open(file_name) as f: test_spec = json.load(f) mock, paginator_side_effects = build_mock(test_spec["mockData"]) mock_client = MagicMock( **{ **{ "meta": aws_interface.cloudwanderer_boto3_session.client(test_spec["service"]).meta, "get_caller_identity.return_value": { "UserId": "111111111111111111111", "Account": "0123456789012", "Arn": "arn:aws:iam::0123456789012:user/CloudWanderer", }, }, **mock, } ) aws_interface.cloudwanderer_boto3_session.client = MagicMock(return_value=mock_client) if "getResource" in test_spec: urn = URN.from_string(test_spec["getResource"]["urn"]) logger.info("Getting resource %s", urn) try: result = prepare_for_comparison(aws_interface.get_resource(urn=urn)) except botocore.model.NoShapeFoundError as ex: raise ValueError( "Boto3 raised a NoShapeFoundError, this suggests your test has the wrong service name specified" ) from ex if "getResources" in test_spec: get_resources = test_spec["getResources"] logger.info("Getting resources %s", get_resources) try: result = prepare_for_comparison( aws_interface.get_resources( service_name=get_resources["serviceName"], resource_type=get_resources["resourceType"], region=get_resources["region"], ) ) except NotImplementedError as ex: raise ValueError( "Boto3 raised a NotImplementedError, usually this means " "you forgot to wrap your paginate.return_results in a list or " "include the key at the top level (e.g. Instances)" ) from ex except botocore.model.NoShapeFoundError as ex: raise ValueError( "Boto3 raised a NoShapeFoundError, this suggests your test has the wrong service name specified" ) from ex compare_list_of_dicts_allow_any( test_spec["expectedResults"], [dict(x) for x in result], allow_partial_match_first=True ) for method_path, calls in test_spec["expectedCalls"].items(): logger.info("Assert calls %s on %s", calls, method_path) method = mock_client for attr in method_path.split("."): index_match = re.search(r"\[(?P<index>\d)\](?P<attr>.*)", attr) if index_match: # This will only work if it's an index of `get_paginator.side_effect` index = index_match.groupdict()["index"] attr = index_match.groupdict()["attr"] method = paginator_side_effects[int(index)] if not attr: continue method = getattr(method, attr) logger.info("Assert %s calls on %s", calls, method_path) logger.info([call(*call_dict["args"], **call_dict["kwargs"]) for call_dict in calls]) method.assert_has_calls([call(*call_dict["args"], **call_dict["kwargs"]) for call_dict in calls])