def test_boto3_validate_launch_args(): """Test validation of launch args for boto3 connection""" configDict = { 'awsaccesskey': 'the_key', 'awssecretkey': 'the_secret', 'region': 'us-east-1', 'placementgroup': 'testgroup', } # Set up adapter and process configDict adapter = Aws() adapter.process_config(configDict) # Get boto3 connection conn3 = adapter.getEC2Connection3(configDict) # We have to mock this directly since moto doesn't implement # a mock of create_placement_group at present (Oct. 2019) with mock.patch.object(conn3, 'create_placement_group') as mock_cpg: adapter._validate_ec2_launch_args(conn3, configDict) # Check results call_kwargs = mock_cpg.call_args[1] assert len(call_kwargs) == 2 assert call_kwargs['GroupName'] == configDict['placementgroup'] assert call_kwargs['Strategy'] == 'cluster'
def test_boto3_conn_setup(proxy_host, proxy_port, proxy_user, proxy_pass): """Test setup of boto3 connection""" # Construct configDict configDict = { 'awsaccesskey': 'the_key', 'awssecretkey': 'the_secret', 'region': 'us-east-1', } if proxy_host: configDict['proxy_host'] = proxy_host configDict['proxy_port'] = proxy_port if proxy_user: configDict['proxy_user'] = proxy_user configDict['proxy_pass'] = proxy_pass # Set up adapter and process configDict adapter = Aws() adapter.process_config(configDict) # Get boto3 connection session_cls = 'tortuga.resourceAdapter.aws.aws.boto3.Session' config_cls = 'tortuga.resourceAdapter.aws.aws.Config' with mock.patch(session_cls) as boto3_session_mock, \ mock.patch(config_cls) as botocore_config_mock: conn3 = adapter.getEC2Connection3(configDict) # Test session call args/kwargs session_call_kwargs = boto3_session_mock.call_args[1] assert len(session_call_kwargs) == 3 assert session_call_kwargs['aws_access_key_id'] == \ configDict['awsaccesskey'] assert session_call_kwargs['aws_secret_access_key'] == \ configDict['awssecretkey'] assert session_call_kwargs['region_name'] == configDict['region'] # Test config call args/kwargs if proxy used if proxy_host is not None: config_call_kwargs = botocore_config_mock.call_args[1] proxy_dict = config_call_kwargs['proxies'] assert len(proxy_dict) == 1 assert 'http' in proxy_dict proxy_url = f'{proxy_host}:{proxy_port}' if proxy_user is not None: proxy_url = f'{proxy_user}:{proxy_pass}@{proxy_url}' assert proxy_dict['http'] == proxy_url
def test_launch_EC2(valid_ami): """Test full EC2 launch process""" # Set up configDict configDict = { 'keypair': 'keypair_name', 'instancetype': 't2.large', 'region': 'us-east-1', 'awsaccesskey': 'the_key', 'awssecretkey': 'the_secret', 'zone': 'fake_zone', 'use_instance_hostname': False, 'block_device_map': '/dev/sda1=:30:true:io1:500:encrypted', 'ami': valid_ami, 'aki': 'fake_kernel_id', 'ari': 'fake_ramdisk_id', 'ebs_optimized': True, 'monitoring_enabled': False, 'iam_instance_profile_name': 'fake_profile_name', 'subnet_id': None, 'securitygroup': ['sg-1234'], 'associate_public_ip_address': True, 'tags': {'key1': 'value1', 'key2': 'value2'}, } # Set up adapter and process configDict adapter = Aws() adapter.process_config(configDict) # Set up a mock node node = mock.Mock(spec=Node) node.hardwareprofile.name = 'hwp_name' node.softwareprofile.name = 'swp_name' node.name = 'node_name' # Run __launchEC2 with mock_ec2(): # Get boto3 connection conn3 = adapter.getEC2Connection3(configDict) # Create mock vpc and subnet vpc = conn3.create_vpc(CidrBlock='10.0.0.0/16') subnet = conn3.create_subnet(CidrBlock='10.0.0.0/18', VpcId=vpc.id) configDict['subnet_id'] = subnet.id # Launch instances result = adapter._Aws__launchEC2(conn3, configDict, count=1, node=node) # Check results assert len(result) == 1 instance = result[0] assert instance.image.id == configDict['ami'] assert instance.key_pair.key_name == configDict['keypair'] assert instance.instance_type == configDict['instancetype'] assert instance.vpc_id == vpc.id assert instance.subnet_id == subnet.id assert len(instance.network_interfaces) == 1 assert instance.network_interfaces[0].groups[0]['GroupName'] == \ configDict['securitygroup'][0] # NOTE: moto does not give the correct result for these two. I have tested # manually on AWS and confirmed that they work as expected. #assert instance.ebs_optimized == configDict['ebs_optimized'] #assert instance.monitoring['state'] == 'disabled' # Check tags instance_tags = {d['Key']: d['Value'] for d in instance.tags} assert instance_tags['Name'] == node.name assert instance_tags['key1'] == 'value1' assert instance_tags['key2'] == 'value2' assert instance_tags['tortuga-softwareprofile'] == \ node.softwareprofile.name assert instance_tags['tortuga-hardwareprofile'] == \ node.hardwareprofile.name assert instance_tags['tortuga-installer_hostname'] == \ adapter.installer_public_hostname # Have to sanitize this one assert instance_tags['tortuga-installer_ipaddress'] == \ adapter._sanitze_tag_value(adapter.installer_public_ipaddress)
def test_get_common_launch_args3(subnet_id, valid_ami): """Test construction of launch args dict for run_instances with boto3""" # Set up configDict configDict = { 'keypair': 'keypair_name', 'instancetype': 't2.large', 'region': 'us-east-1', 'zone': 'fake_zone', 'installer_ip': '127.0.0.1', 'use_instance_hostname': False, 'placementgroup': 'fake_placementgroup', 'cloud_init': None, 'ami': valid_ami, 'aki': 'fake_kernel_id', 'ari': 'fake_ramdisk_id', 'ebs_optimized': True, 'monitoring_enabled': False, 'iam_instance_profile_name': 'fake_profile_name', 'subnet_id': subnet_id, 'securitygroup': ['sg-1234'], 'associate_public_ip_address': True, 'use_tags': True, 'tags': {'key1': 'value1', 'key2': 'value2'}, } # Set up adapter and process configDict adapter = Aws() # Get boto3 connection conn3 = adapter.getEC2Connection3(configDict) # Set up a mock node node = mock.Mock(spec=Node) node.hardwareprofile.name = 'hwp_name' node.softwareprofile.name = 'swp_name' node.name = 'node_name' # Execute function with mock_ec2(): run_args = adapter._Aws__get_common_launch_args3(conn3, configDict, node=node) # Check results assert run_args['EbsOptimized'] == configDict['ebs_optimized'] assert run_args['IamInstanceProfile']['Name'] == \ configDict['iam_instance_profile_name'] assert run_args['InstanceType'] == configDict['instancetype'] assert run_args['KernelId'] == configDict['aki'] assert run_args['KeyName'] == configDict['keypair'] assert run_args['Monitoring']['Enabled'] == \ configDict['monitoring_enabled'] assert run_args['Placement']['AvailabilityZone'] == configDict['zone'] assert run_args['Placement']['GroupName'] == configDict['placementgroup'] assert run_args['RamdiskId'] == configDict['ari'] # Depends on subnet id if subnet_id is not None: assert 'NetworkInterfaces' in run_args assert len(run_args['NetworkInterfaces']) == 1 ni = run_args['NetworkInterfaces'][0] assert ni['AssociatePublicIpAddress'] == \ configDict['associate_public_ip_address'] assert ni['Groups'] == configDict['securitygroup'] assert ni['SubnetId'] == configDict['subnet_id'] else: assert 'SecurityGroupIds' in run_args assert run_args['SecurityGroupIds'] == configDict['securitygroup'] # Don't need to check instance tags here, since it's done in another test tag_specs = \ {d['ResourceType']: d['Tags'] for d in run_args['TagSpecifications']} volume_tag_specs = {d['Key']: d['Value'] for d in tag_specs['volume']} # 5 extra tags for tortuga:* tags and Name assert len(volume_tag_specs) == len(configDict['tags']) + 5 for k in configDict['tags']: assert volume_tag_specs[k] == configDict['tags'][k] assert volume_tag_specs['tortuga-softwareprofile'] == \ node.softwareprofile.name assert volume_tag_specs['tortuga-hardwareprofile'] == \ node.hardwareprofile.name assert volume_tag_specs['tortuga-installer_hostname'] == \ adapter._sanitze_tag_value(adapter.installer_public_hostname) assert volume_tag_specs['tortuga-installer_ipaddress'] == \ adapter._sanitze_tag_value(configDict['installer_ip']) assert volume_tag_specs['Name'] == node.name
def test_get_tags_for_instance_creation(use_instance_hostname, name_tag, use_node, use_addNodesRequest): """Test tags generated for instance creation""" # Set up configDict configDict = { 'region': 'us-east-1', 'installer_ip': '127.0.0.1', 'tags': {'key1': 'value1', 'key2': 'value2'}, 'use_instance_hostname': use_instance_hostname, } if name_tag: configDict['tags']['Name'] = name_tag # Set up node mock, if needed node = None if use_node: node = mock.Mock(spec=Node) node.name = 'node_name' node.hardwareprofile.name = 'node_hwp' node.softwareprofile.name = 'node_swp' # Set up addNodesRequest, if needed addNodesRequest = {} if use_addNodesRequest: addNodesRequest = {'softwareProfile': 'swp', 'hardwareProfile': 'hwp'} # Set up adapter - no need to process configDict since the tags # are already in processed form adapter = Aws() # Get boto3 connection conn3 = adapter.getEC2Connection3(configDict) # Get tags tags = adapter._Aws__get_tags_for_instance_creation( configDict, node=node, addNodesRequest=addNodesRequest ) # Manually generate expected contents expected_hwp_name = node.hardwareprofile.name if use_node \ else addNodesRequest['hardwareProfile'] expected_swp_name = node.softwareprofile.name if use_node \ else addNodesRequest['softwareProfile'] expected_name = configDict.get('tags').get('Name', None) if use_instance_hostname: if expected_name is None: expected_name = 'Tortuga compute node' elif node: expected_name = node.name expected_num_tags = 4 + int(expected_name is not None) + \ (len(configDict['tags']) - int(bool(name_tag))) # Check results assert len(tags) == expected_num_tags assert tags['tortuga-installer_ipaddress'] == \ adapter._sanitze_tag_value(configDict['installer_ip']) assert tags['tortuga-installer_hostname'] == \ adapter._sanitze_tag_value(adapter.installer_public_hostname) assert tags['tortuga-softwareprofile'] == expected_swp_name assert tags['tortuga-hardwareprofile'] == expected_hwp_name for k,v in configDict['tags'].items(): # 'Name' tag will not *always* match - we check it below if k != 'Name': assert tags[k] == v if expected_name is None: assert 'Name' not in tags else: assert tags['Name'] == expected_name