Path: blob/develop/tests/unit/customizations/emr/test_emrfs_utils.py
1569 views
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.1213import copy14import os15import json1617from awscli.customizations.emr.emrfsutils import CONSISTENT_OPTION_NAME18from awscli.customizations.emr.emrfsutils import CSE_CUSTOM_OPTION_NAME19from awscli.customizations.emr.emrfsutils import CSE_KMS_OPTION_NAME20from awscli.customizations.emr.emrfsutils import CSE_OPTION_NAME212223from tests.unit.customizations.emr import EMRBaseAWSCommandParamsTest as \24BaseAWSCommandParamsTest252627DEFAULT_INSTANCES = {28'KeepJobFlowAliveWhenNoSteps': True,29'TerminationProtected': False,30'InstanceGroups': [{31'InstanceRole': 'MASTER',32'InstanceCount': 1,33'Name': 'MASTER',34'Market': 'ON_DEMAND',35'InstanceType': 'm1.large'36}]37}3839DEFAULT_CMD = ('emr create-cluster --use-default-roles'40' --instance-type m1.large ')41DEFAULT_RESULT = {42'Name': "Development Cluster",43'Instances': DEFAULT_INSTANCES,44'VisibleToAllUsers': True,45'JobFlowRole': "EMR_EC2_DefaultRole",46'ServiceRole': "EMR_DefaultRole",47'Tags': []48}4950EMPTY_EMRFS_CONFIGURATION = {51'Classification': 'emrfs-site',52'Properties': {}53}5455DEFAULT_CONFIGURATIONS = [56{57'Classification': 'hadoop-env',58'Configurations': [],59'Properties': {'someProperty': 'someValue'}60}61]626364class TestEmrfsUtils(BaseAWSCommandParamsTest):6566def test_consistent(self):67emrfs_option_value = 'Consistent=true'68expected_emrfs_properties = {'fs.s3.consistent': 'true'}69expected_emrfs_ba_key_values = [70'fs.s3.consistent=true'71]7273self._assert_bootstrap_actions(74emrfs_option_value, expected_emrfs_ba_key_values,75expected_emrfs_properties)7677def test_consistent_w_optional_args(self):78emrfs_option_value = 'Consistent=true,RetryCount=5,RetryPeriod=30'7980expected_emrfs_properties = \81{'fs.s3.consistent': 'true',82'fs.s3.consistent.retryCount': '5',83'fs.s3.consistent.retryPeriodSeconds': '30'}8485expected_emrfs_ba_key_values = [86'fs.s3.consistent=true', 'fs.s3.consistent.retryCount=5',87'fs.s3.consistent.retryPeriodSeconds=30'88]8990self._assert_bootstrap_actions(91emrfs_option_value, expected_emrfs_ba_key_values,92expected_emrfs_properties)9394def test_consistent_false_w_optional_args(self):95emrfs_option_value = 'Consistent=false,RetryCount=5'9697expected_emrfs_properties = {98'fs.s3.consistent': 'false',99'fs.s3.consistent.retryCount': '5'}100101expected_emrfs_ba_key_values = [102'fs.s3.consistent=false', 'fs.s3.consistent.retryCount=5'103]104105self._assert_bootstrap_actions(106emrfs_option_value, expected_emrfs_ba_key_values,107expected_emrfs_properties)108109def test_sse(self):110emrfs_option_value = 'SSE=true'111expected_emrfs_ba_key_values = [112'fs.s3.enableServerSideEncryption=true'113]114expected_emrfs_properties = {115'fs.s3.enableServerSideEncryption': 'true'}116self._assert_bootstrap_actions(117emrfs_option_value, expected_emrfs_ba_key_values,118expected_emrfs_properties)119120emrfs_option_value = 'Encryption=ServerSide'121expected_emrfs_ba_key_values = [122'fs.s3.enableServerSideEncryption=true'123]124expected_emrfs_properties = {125'fs.s3.enableServerSideEncryption': 'true'}126self._assert_bootstrap_actions(127emrfs_option_value, expected_emrfs_ba_key_values,128expected_emrfs_properties)129130def test_cse_kms(self):131emrfs_option_value = 'Encryption=ClientSide,ProviderType=KMS,' \132'KMSKeyId=my_key'133expected_emrfs_ba_key_values = [134'fs.s3.cse.enabled=true', 'fs.s3.cse.encryptionMaterialsProvider='135'com.amazon.ws.emr.hadoop.fs.cse.KMSEncryptionMaterialsProvider',136'fs.s3.cse.kms.keyId=my_key'137]138expected_emrfs_properties = {139'fs.s3.cse.enabled': 'true',140'fs.s3.cse.encryptionMaterialsProvider':141'com.amazon.ws.emr.hadoop.fs.cse.'142'KMSEncryptionMaterialsProvider',143'fs.s3.cse.kms.keyId': 'my_key'}144self._assert_bootstrap_actions(145emrfs_option_value, expected_emrfs_ba_key_values,146expected_emrfs_properties)147148def test_cse_custom(self):149emrfs_option_value = 'Encryption=ClientSide,ProviderType=Custom,' \150'CustomProviderLocation=my_location,CustomProviderClass=my_class'151expected_emrfs_ba_key_values = [152'fs.s3.cse.enabled=true', 'fs.s3.cse.encryptionMaterialsProvider='153'my_class'154]155expected_emrfs_properties = {156'fs.s3.cse.enabled': 'true',157'fs.s3.cse.encryptionMaterialsProvider': 'my_class',158'fs.s3.cse.encryptionMaterialsProvider.uri': 'my_location'}159160self._assert_bootstrap_actions(161emrfs_option_value, expected_emrfs_ba_key_values,162expected_emrfs_properties, 'my_location')163164def test_sse_and_consistent(self):165emrfs_option_value = 'SSE=true,Consistent=true'166expected_emrfs_ba_key_values = [167'fs.s3.consistent=true',168'fs.s3.enableServerSideEncryption=true']169expected_emrfs_properties = {170'fs.s3.consistent': 'true',171'fs.s3.enableServerSideEncryption': 'true'}172self._assert_bootstrap_actions(173emrfs_option_value, expected_emrfs_ba_key_values,174expected_emrfs_properties)175176emrfs_option_value = 'Consistent=false,Encryption=serVERSIde'177expected_emrfs_ba_key_values = [178'fs.s3.consistent=false',179'fs.s3.enableServerSideEncryption=true']180expected_emrfs_properties = {181'fs.s3.consistent': 'false',182'fs.s3.enableServerSideEncryption': 'true'}183184self._assert_bootstrap_actions(185emrfs_option_value, expected_emrfs_ba_key_values,186expected_emrfs_properties)187188def test_cse_and_consistent(self):189emrfs_option_value = ('Encryption=ClientSide,ProviderType=KMS,'190'KMSKeyId=my_key,Consistent=true')191expected_emrfs_ba_key_values = [192'fs.s3.consistent=true', 'fs.s3.cse.enabled=true',193'fs.s3.cse.encryptionMaterialsProvider=com.amazon.ws.emr.'194'hadoop.fs.cse.KMSEncryptionMaterialsProvider',195'fs.s3.cse.kms.keyId=my_key']196expected_emrfs_properties = {197'fs.s3.consistent': 'true',198'fs.s3.cse.enabled': 'true',199'fs.s3.cse.encryptionMaterialsProvider': 'com.amazon.ws.emr.'200'hadoop.fs.cse.KMSEncryptionMaterialsProvider',201'fs.s3.cse.kms.keyId': 'my_key'}202203self._assert_bootstrap_actions(204emrfs_option_value, expected_emrfs_ba_key_values,205expected_emrfs_properties)206207def test_args_and_sse(self):208emrfs_option_value = \209'SSE=true,Args=[fs.s3.serverSideEncryptionAlgorithm=AES256]'210expected_emrfs_ba_key_values = [211'fs.s3.enableServerSideEncryption=true',212'fs.s3.serverSideEncryptionAlgorithm=AES256']213expected_emrfs_properties = {214'fs.s3.enableServerSideEncryption': 'true',215'fs.s3.serverSideEncryptionAlgorithm': 'AES256'}216217self._assert_bootstrap_actions(218emrfs_option_value, expected_emrfs_ba_key_values,219expected_emrfs_properties)220221def test_args_and_cse(self):222emrfs_option_value = ('Encryption=ClientSide,ProviderType=KMS,'223'KMSKeyId=my_key,Args=[k1=v1]')224expected_emrfs_ba_key_values = [225'fs.s3.cse.enabled=true',226'fs.s3.cse.encryptionMaterialsProvider=com.amazon.ws.emr.'227'hadoop.fs.cse.KMSEncryptionMaterialsProvider',228'fs.s3.cse.kms.keyId=my_key', 'k1=v1']229expected_emrfs_properties = {230'fs.s3.cse.enabled': 'true',231'fs.s3.cse.encryptionMaterialsProvider': 'com.amazon.ws.emr.'232'hadoop.fs.cse.KMSEncryptionMaterialsProvider',233'fs.s3.cse.kms.keyId': 'my_key',234'k1': 'v1'}235236self._assert_bootstrap_actions(237emrfs_option_value, expected_emrfs_ba_key_values,238expected_emrfs_properties)239240def test_args_and_consistent(self):241emrfs_option_value = 'Consistent=true,Args=[k1=v1,k2=v2]'242expected_emrfs_ba_key_values = ['fs.s3.consistent=true',243'k1=v1', 'k2=v2']244expected_emrfs_properties = {245'fs.s3.consistent': 'true',246'k1': 'v1',247'k2': 'v2'}248249self._assert_bootstrap_actions(250emrfs_option_value, expected_emrfs_ba_key_values,251expected_emrfs_properties)252253def test_only_args(self):254emrfs_option_value = 'Args=[k1=v1,k2=v2,k3]'255expected_emrfs_ba_key_values = ['k1=v1', 'k2=v2', 'k3']256expected_emrfs_properties = {257'k1': 'v1',258'k2': 'v2',259'k3': ''}260261self._assert_bootstrap_actions(262emrfs_option_value, expected_emrfs_ba_key_values,263expected_emrfs_properties)264265def test_using_json_file(self):266data_path = os.path.join(267os.path.dirname(__file__), 'input_emr_fs.json')268emrfs_option_value = 'file://%s' % data_path269expected_emrfs_ba_key_values = [270'fs.s3.consistent=true',271'fs.s3.consistent.retryCount=10',272'fs.s3.consistent.retryPeriodSeconds=3',273'fs.s3.enableServerSideEncryption=false',274'fs.s3.serverSideEncryptionAlgorithm=AES256',275'fs.s3.sleepTimeSeconds=30']276expected_emrfs_properties = {277'fs.s3.consistent': 'true',278'fs.s3.consistent.retryCount': '10',279'fs.s3.consistent.retryPeriodSeconds': '3',280'fs.s3.enableServerSideEncryption': 'false',281'fs.s3.serverSideEncryptionAlgorithm': 'AES256',282'fs.s3.sleepTimeSeconds': '30'}283284self._assert_bootstrap_actions(285emrfs_option_value, expected_emrfs_ba_key_values,286expected_emrfs_properties)287288def test_only_one_encryption_type(self):289self._assert_error_msg(290emrfs_option_value='SSE=true,Encryption=ClientSide,'291'ProviderType=KMS,KMSKeyId=k1',292exception_class_name='BothSseAndEncryptionConfiguredError',293error_msg_kwargs={'sse': 'True', 'encryption': 'ClientSide'}294)295296def test_cse_missing_provider_type(self):297self._assert_error_msg(298emrfs_option_value='Encryption=ClientSide',299exception_class_name='MissingParametersError',300error_msg_kwargs={'object_name': CSE_OPTION_NAME,301'missing': 'ProviderType'}302)303304def test_cse_kms_missing_key_id(self):305self._assert_error_msg(306emrfs_option_value='Encryption=ClientSide,ProviderType=KMS',307exception_class_name='MissingParametersError',308error_msg_kwargs={'object_name': CSE_KMS_OPTION_NAME,309'missing': 'KMSKeyId'}310)311312def test_cse_custom_missing_all(self):313self._assert_error_msg(314emrfs_option_value='Encryption=ClientSide,ProviderType=Custom',315exception_class_name='MissingParametersError',316error_msg_kwargs={'object_name': CSE_CUSTOM_OPTION_NAME,317'missing': 'CustomProviderClass and '318'CustomProviderLocation'}319)320321def test_cse_custom_missing_provider_class(self):322self._assert_error_msg(323emrfs_option_value='Encryption=ClientSide,ProviderType=Custom,'324'CustomProviderLocation=my_location',325exception_class_name='MissingParametersError',326error_msg_kwargs={'object_name': CSE_CUSTOM_OPTION_NAME,327'missing': 'CustomProviderClass'}328)329330def test_cse_custom_missing_provider_location(self):331self._assert_error_msg(332emrfs_option_value='Encryption=ClientSide,ProviderType=Custom,'333'CustomProviderClass=my_class',334exception_class_name='MissingParametersError',335error_msg_kwargs={'object_name': CSE_CUSTOM_OPTION_NAME,336'missing': 'CustomProviderLocation'}337)338339def test_valid_encryption(self):340self._assert_error_msg(341emrfs_option_value='Encryption=ClientSide1',342exception_class_name='UnknownEncryptionTypeError',343error_msg_kwargs={'encryption': 'ClientSide1'}344)345346def test_valid_cse_provider_type(self):347self._assert_error_msg(348emrfs_option_value='Encryption=ClientSide,ProviderType=KMS1',349exception_class_name='UnknownCseProviderTypeError',350error_msg_kwargs={'provider_type': 'KMS1'}351)352353def test_valid_consistent_args(self):354self._assert_error_msg(355emrfs_option_value='SSE=true,RetryCount=5,RetryPeriod=30',356exception_class_name='InvalidEmrFsArgumentsError',357error_msg_kwargs={'invalid': 'RetryCount and RetryPeriod',358'parent_object_name': CONSISTENT_OPTION_NAME}359)360361def test_valid_cse_kms_args(self):362self._assert_error_msg(363emrfs_option_value='Consistent=true,KMSKeyId=k1',364exception_class_name='InvalidEmrFsArgumentsError',365error_msg_kwargs={'invalid': 'KMSKeyId',366'parent_object_name': CSE_KMS_OPTION_NAME}367)368369def test_valid_cse_custom_args(self):370self._assert_error_msg(371emrfs_option_value='Consistent=true,CustomProviderLocation=loc',372exception_class_name='InvalidEmrFsArgumentsError',373error_msg_kwargs={'invalid': 'CustomProviderLocation',374'parent_object_name': CSE_CUSTOM_OPTION_NAME}375)376377def test_configurations_and_emrfs(self):378emrfs_option_value = 'Args=[someProperty=someValue]'379configurations = json.dumps(DEFAULT_CONFIGURATIONS,380separators=(',', ':'))381382cmd = "%s --release-label emr-4.0 --emrfs %s --configurations %s" \383% (DEFAULT_CMD, emrfs_option_value, configurations)384385expected_emrfs_properties = {'someProperty': 'someValue'}386387emrfs_configuration = copy.deepcopy(EMPTY_EMRFS_CONFIGURATION)388configurations = copy.deepcopy(DEFAULT_CONFIGURATIONS)389result = copy.deepcopy(DEFAULT_RESULT)390391emrfs_configuration['Properties'] = expected_emrfs_properties392configurations.append(emrfs_configuration)393result['ReleaseLabel'] = 'emr-4.0'394result['Configurations'] = configurations395396self.assert_params_for_cmd(cmd, result)397398def test_duplicate_emrfs_configuration_exception(self):399emrfs_option_value = 'Args=[someProperty=someValue]'400expected_emrfs_properties = {'someProperty': 'someValue'}401402emrfs_configuration = copy.deepcopy(EMPTY_EMRFS_CONFIGURATION)403emrfs_configuration['Properties'] = expected_emrfs_properties404configurations = copy.deepcopy(DEFAULT_CONFIGURATIONS)405configurations.append(EMPTY_EMRFS_CONFIGURATION)406407configurations_json = json.dumps(configurations,408separators=(',', ':'))409410cmd = "%s --release-label emr-4.0 --emrfs %s --configurations %s" \411% (DEFAULT_CMD, emrfs_option_value, configurations_json)412413result = copy.deepcopy(DEFAULT_RESULT)414result['ReleaseLabel'] = 'emr-4.0'415result['Configurations'] = configurations416417self.assert_error_msg(cmd, 'DuplicateEmrFsConfigurationError')418419def _assert_error_msg(self, emrfs_option_value,420exception_class_name, error_msg_kwargs):421cmd = "%s --ami-version 3.4 --emrfs %s" \422% (DEFAULT_CMD, emrfs_option_value)423self.assert_error_msg(424cmd,425exception_class_name=exception_class_name,426error_msg_kwargs=error_msg_kwargs)427428cmd = "%s --release-label emr-4.0 --emrfs %s" \429% (DEFAULT_CMD, emrfs_option_value)430self.assert_error_msg(431cmd,432exception_class_name=exception_class_name,433error_msg_kwargs=error_msg_kwargs)434435def _assert_bootstrap_actions(self, emrfs_option_value,436expected_emrfs_ba_key_values,437expected_emrfs_properties,438provider_location=None):439if expected_emrfs_ba_key_values is not None:440cmd = "%s --ami-version 3.4 --emrfs %s" \441% (DEFAULT_CMD, emrfs_option_value)442result = copy.deepcopy(DEFAULT_RESULT)443result['BootstrapActions'] = [self._create_s3_get_ba_config(444provider_location)] if provider_location is not None else []445result['BootstrapActions'] += [self._create_setup_emrfs_ba_config(446expected_emrfs_ba_key_values)]447result['AmiVersion'] = '3.4'448449self.assert_params_for_cmd(cmd, result)450451if expected_emrfs_properties is not None:452cmd = "%s --release-label emr-4.0 --emrfs %s" \453% (DEFAULT_CMD, emrfs_option_value)454result = copy.deepcopy(DEFAULT_RESULT)455emrfs_configuration = copy.deepcopy(EMPTY_EMRFS_CONFIGURATION)456emrfs_configuration['Properties'] = expected_emrfs_properties457result['Configurations'] = [emrfs_configuration]458result['ReleaseLabel'] = 'emr-4.0'459460self.assert_params_for_cmd(cmd, result)461462def _create_setup_emrfs_ba_config(self, ba_arg_values):463ba_arg_keys = ['-e' for x in ba_arg_values]464ba_args = [x for pair in zip(ba_arg_keys, ba_arg_values) for x in pair]465466return {467'Name': 'Setup EMRFS',468'ScriptBootstrapAction': {469'Path': ('s3://us-east-1.elasticmapreduce/'470'bootstrap-actions/configure-hadoop'),471'Args': ba_args472}473}474475def _create_s3_get_ba_config(self, provider_location):476return {477'Name': 'S3 get',478'ScriptBootstrapAction': {479'Path': 'file:/usr/share/aws/emr/scripts/s3get',480'Args': [481'-s', provider_location,482'-d', '/usr/share/aws/emr/auxlib',483'-f'484]485}486}487488489