Path: blob/develop/tests/unit/customizations/emr/test_create_cluster_release_label.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 os1516from botocore.compat import OrderedDict, json1718from awscli.testutils import mock, unittest19from tests.unit.customizations.emr import (20EMRBaseAWSCommandParamsTest as BaseAWSCommandParamsTest,21)22from tests.unit.customizations.emr import test_constants as CONSTANTS23from tests.unit.customizations.emr import (24test_constants_instance_fleets as CONSTANTS_FLEET,25)2627DEFAULT_CLUSTER_NAME = "Development Cluster"2829DEFAULT_INSTANCE_GROUPS_ARG = (30'InstanceGroupType=MASTER,Name=MASTER,'31'InstanceCount=1,InstanceType=m1.large '32'InstanceGroupType=CORE,Name=CORE,'33'InstanceCount=1,InstanceType=m1.large '34'InstanceGroupType=TASK,Name=TASK,'35'InstanceCount=1,InstanceType=m1.large '36)3738HA_INSTANCE_GROUPS_ARG = (39'InstanceGroupType=MASTER,Name=MASTER,'40'InstanceCount=3,InstanceType=m1.large '41'InstanceGroupType=CORE,Name=CORE,'42'InstanceCount=1,InstanceType=m1.large '43)4445DEFAULT_INSTANCE_GROUPS = [46{47'InstanceRole': 'MASTER',48'InstanceCount': 1,49'Name': 'MASTER',50'Market': 'ON_DEMAND',51'InstanceType': 'm1.large',52},53{54'InstanceRole': 'CORE',55'InstanceCount': 1,56'Name': 'CORE',57'Market': 'ON_DEMAND',58'InstanceType': 'm1.large',59},60{61'InstanceRole': 'TASK',62'InstanceCount': 1,63'Name': 'TASK',64'Market': 'ON_DEMAND',65'InstanceType': 'm1.large',66},67]6869HA_INSTANCE_GROUPS = [70{71'InstanceRole': 'MASTER',72'InstanceCount': 3,73'Name': 'MASTER',74'Market': 'ON_DEMAND',75'InstanceType': 'm1.large',76},77{78'InstanceRole': 'CORE',79'InstanceCount': 1,80'Name': 'CORE',81'Market': 'ON_DEMAND',82'InstanceType': 'm1.large',83},84]858687DEFAULT_CMD = (88'emr create-cluster --release-label emr-4.0.0'89' --use-default-roles'90' --instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG + ' '91)9293DEFAULT_INSTANCES = {94'KeepJobFlowAliveWhenNoSteps': True,95'TerminationProtected': False,96'InstanceGroups': DEFAULT_INSTANCE_GROUPS,97}9899HA_INSTANCES = {100'KeepJobFlowAliveWhenNoSteps': True,101'TerminationProtected': False,102'InstanceGroups': HA_INSTANCE_GROUPS,103}104105EC2_ROLE_NAME = "EMR_EC2_DefaultRole"106EMR_ROLE_NAME = "EMR_DefaultRole"107108DEFAULT_KERBEROS_ATTRIBUTES_ARGS = (109'Realm=EC2.INTERNAL,'110'KdcAdminPassword=123,'111'CrossRealmTrustPrincipalPassword=123,'112'ADDomainJoinUser=aws,'113'ADDomainJoinPassword=123'114)115116KERBEROS_ATTRIBUTES = {117'Realm': 'EC2.INTERNAL',118'KdcAdminPassword': '123',119'CrossRealmTrustPrincipalPassword': '123',120'ADDomainJoinUser': 'aws',121'ADDomainJoinPassword': '123',122}123124TEST_BA = [125{126'ScriptBootstrapAction': {127'Path': 's3://test/ba1',128'Args': ['arg1', 'arg2', 'arg3'],129},130'Name': 'ba1',131},132{133'ScriptBootstrapAction': {134'Path': 's3://test/ba2',135'Args': ['arg1', 'arg2', 'arg3'],136},137'Name': 'ba2',138},139]140141CUSTOM_JAR_STEP = {142'Name': 'Custom JAR',143'ActionOnFailure': 'CONTINUE',144'HadoopJarStep': {'Jar': 's3://mybucket/mytest.jar'},145}146147STREAMING_ARGS = (148'Args=-files,'149's3://elasticmapreduce/samples/wordcount/wordSplitter.py,'150'-mapper,wordSplitter.py,'151'-reducer,aggregate,'152'-input,s3://elasticmapreduce/samples/wordcount/input,'153'-output,s3://mybucket/wordcount/output/2014-04-18/12-15-24'154)155156STREAMING_HADOOP_JAR_STEP = {157'Jar': 'command-runner.jar',158'Args': [159'hadoop-streaming',160'-files',161's3://elasticmapreduce/samples/wordcount/wordSplitter.py',162'-mapper',163'wordSplitter.py',164'-reducer',165'aggregate',166'-input',167's3://elasticmapreduce/samples/wordcount/input',168'-output',169's3://mybucket/wordcount/output/2014-04-18/12-15-24',170],171}172173CREATE_CLUSTER_RESULT = {174"JobFlowId": "j-XXXX",175"ClusterArn": "arn:aws:elasticmapreduce:region:012345678910:cluster/j-XXXX",176}177178CONSTRUCTED_RESULT = {179"ClusterId": "j-XXXX",180"ClusterArn": "arn:aws:elasticmapreduce:region:012345678910:cluster/j-XXXX",181}182183DEFAULT_RESULT = {184'Name': DEFAULT_CLUSTER_NAME,185'Instances': DEFAULT_INSTANCES,186'ReleaseLabel': 'emr-4.0.0',187'VisibleToAllUsers': True,188'JobFlowRole': EC2_ROLE_NAME,189'ServiceRole': EMR_ROLE_NAME,190'Tags': [],191}192193EMR_MANAGED_MASTER_SECURITY_GROUP = 'sg-master1'194195EMR_MANAGED_SLAVE_SECURITY_GROUP = 'sg-slave1'196197SERVICE_ACCESS_SECURITY_GROUP = "sg-service-access"198199ADDITIONAL_MASTER_SECURITY_GROUPS = [200'sg-addMaster1',201'sg-addMaster2',202'sg-addMaster3',203'sg-addMaster4',204]205206ADDITIONAL_SLAVE_SECURITY_GROUPS = [207'sg-addSlave1',208'sg-addSlave2',209'sg-addSlave3',210'sg-addSlave4',211]212213HIVE_BASIC_ARGS = (214'Args=-f,s3://elasticmapreduce/samples/hive-ads/libs/model-build.q'215)216217HIVE_DEFAULT_STEP = {218'Name': 'Hive program',219'ActionOnFailure': 'CONTINUE',220'HadoopJarStep': {221'Jar': ('command-runner.jar'),222'Args': [223'hive-script',224'--run-hive-script',225'--args',226'-f',227's3://elasticmapreduce/samples/hive-ads/libs/model-build.q',228],229},230}231232HIVE_STEP = {233'Name': 'HiveBasicStep',234'ActionOnFailure': 'CANCEL_AND_WAIT',235'HadoopJarStep': {236'Jar': ('command-runner.jar'),237'Args': [238'hive-script',239'--run-hive-script',240'--args',241'-f',242's3://elasticmapreduce/samples/hive-ads/libs/model-build.q',243],244},245}246247PIG_BASIC_ARGS = (248'Args=-f,' + 's3://elasticmapreduce/samples/pig-apache/do-reports2.pig'249)250251PIG_DEFAULT_STEP = {252'Name': 'Pig program',253'ActionOnFailure': 'CONTINUE',254'HadoopJarStep': {255'Jar': ('command-runner.jar'),256'Args': [257'pig-script',258'--run-pig-script',259'--args',260'-f',261's3://elasticmapreduce/samples/' 'pig-apache/do-reports2.pig',262],263},264}265266PIG_STEP = {267'Name': 'PigBasicStep',268'ActionOnFailure': 'CANCEL_AND_WAIT',269'HadoopJarStep': {270'Jar': ('command-runner.jar'),271'Args': [272'pig-script',273'--run-pig-script',274'--args',275'-f',276's3://elasticmapreduce/samples/' 'pig-apache/do-reports2.pig',277],278},279}280281282class TestCreateCluster(BaseAWSCommandParamsTest):283prefix = 'emr create-cluster '284285def test_ami_version_release_label_exclusive_validation(self):286cmd = (287self.prefix + '--ami-version 3.8.0 --release-label '288'emr-4.0.0 --instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG289)290expected_error_msg = (291'\naws: error: You cannot specify both --ami-version'292' and --release-label options together.\n'293)294result = self.run_cmd(cmd, 255)295self.assertEqual(expected_error_msg, result[1])296297def test_if_ami_version_or_release_label_is_provided(self):298cmd = self.prefix + ' --instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG299expected_error_msg = (300'\naws: error: Either --ami-version or'301' --release-label is required.\n'302)303result = self.run_cmd(cmd, 255)304self.assertEqual(expected_error_msg, result[1])305306def test_no_special_steps_added_for_applications(self):307cmd = DEFAULT_CMD + '--applications Name=MapR'308result = copy.deepcopy(DEFAULT_RESULT)309result['Applications'] = [{'Name': 'MapR'}]310self.assert_params_for_cmd(cmd, result)311312cmd = DEFAULT_CMD + '--applications Name=HUE'313result = copy.deepcopy(DEFAULT_RESULT)314result['Applications'] = [{'Name': 'HUE'}]315self.assert_params_for_cmd(cmd, result)316317cmd = DEFAULT_CMD + '--applications Name=HIVE'318result = copy.deepcopy(DEFAULT_RESULT)319result['Applications'] = [{'Name': 'HIVE'}]320self.assert_params_for_cmd(cmd, result)321322cmd = DEFAULT_CMD + '--applications Name=PIG'323result = copy.deepcopy(DEFAULT_RESULT)324result['Applications'] = [{'Name': 'PIG'}]325self.assert_params_for_cmd(cmd, result)326327cmd = DEFAULT_CMD + '--applications Name=HBASE'328result = copy.deepcopy(DEFAULT_RESULT)329result['Applications'] = [{'Name': 'HBASE'}]330self.assert_params_for_cmd(cmd, result)331332cmd = DEFAULT_CMD + '--applications Name=IMPALA'333result = copy.deepcopy(DEFAULT_RESULT)334result['Applications'] = [{'Name': 'IMPALA'}]335self.assert_params_for_cmd(cmd, result)336337cmd = DEFAULT_CMD + '--applications Name=GANGLIA'338result = copy.deepcopy(DEFAULT_RESULT)339result['Applications'] = [{'Name': 'GANGLIA'}]340self.assert_params_for_cmd(cmd, result)341342def test_configurations(self):343cmd = (344DEFAULT_CMD + ' --configurations '345'[{"Classification":"hadoop-env","Properties":{'346'"someProperty":"someValue"},"Configurations":[]}]'347)348result = copy.deepcopy(DEFAULT_RESULT)349result['Configurations'] = [350{351'Classification': 'hadoop-env',352'Configurations': [],353'Properties': {'someProperty': 'someValue'},354}355]356self.assert_params_for_cmd(cmd, result)357358def test_quick_start(self):359cmd = (360self.prefix361+ '--release-label emr-4.0.0 --instance-groups '362+ DEFAULT_INSTANCE_GROUPS_ARG363)364result = {365'Name': DEFAULT_CLUSTER_NAME,366'Instances': DEFAULT_INSTANCES,367'ReleaseLabel': 'emr-4.0.0',368'VisibleToAllUsers': True,369'Tags': [],370}371self.assert_params_for_cmd(cmd, result)372373def assert_error_message_has_field_name(self, error_msg, field_name):374self.assertIn('Missing required parameter', error_msg)375self.assertIn(field_name, error_msg)376377def test_default_cmd(self):378self.assert_params_for_cmd(DEFAULT_CMD, DEFAULT_RESULT)379380def test_cluster_without_service_role_and_instance_profile(self):381cmd = (382'emr create-cluster --release-label emr-4.0.0 '383'--instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG384)385result = copy.deepcopy(DEFAULT_RESULT)386del result['JobFlowRole']387del result['ServiceRole']388self.assert_params_for_cmd(cmd, result)389390def test_cluster_with_service_role_and_instance_profile(self):391cmd = (392'emr create-cluster --release-label emr-4.0.0'393' --service-role ServiceRole --ec2-attributes '394'InstanceProfile=Ec2_InstanceProfile '395'--instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG396)397result = copy.deepcopy(DEFAULT_RESULT)398result['JobFlowRole'] = 'Ec2_InstanceProfile'399result['ServiceRole'] = 'ServiceRole'400self.assert_params_for_cmd(cmd, result)401402def test_mutual_exclusive_use_default_roles_and_service_role(self):403cmd = (404DEFAULT_CMD405+ '--ec2-attributes InstanceProfile=Ec2_InstanceProfile'406)407expected_error_msg = (408'\naws: error: You cannot specify both --use-default-roles '409'and --ec2-attributes InstanceProfile options together. Either '410'choose --use-default-roles or use both --service-role <roleName>'411' and --ec2-attributes InstanceProfile=<profileName>.\n'412)413result = self.run_cmd(cmd, 255)414self.assertEqual(expected_error_msg, result[1])415416def test_mutual_exclusive_use_default_roles_and_instance_profile(self):417cmd = (418DEFAULT_CMD + '--service-role ServiceRole '419'--ec2-attributes InstanceProfile=Ec2_InstanceProfile'420)421expected_error_msg = (422'\naws: error: You cannot specify both --use-default-roles '423'and --service-role options together. Either choose '424'--use-default-roles or use both --service-role <roleName> '425'and --ec2-attributes InstanceProfile=<profileName>.\n'426)427result = self.run_cmd(cmd, 255)428self.assertEqual(expected_error_msg, result[1])429430def test_cluster_name_no_space(self):431cmd = DEFAULT_CMD + '--name MyCluster'432result = copy.deepcopy(DEFAULT_RESULT)433result['Name'] = 'MyCluster'434self.assert_params_for_cmd(cmd, result)435436def test_cluster_name_with_space(self):437cmd = DEFAULT_CMD.split() + ['--name', 'My Cluster']438result = copy.deepcopy(DEFAULT_RESULT)439result['Name'] = 'My Cluster'440self.assert_params_for_cmd(cmd, result)441442def test_ami_version(self):443cmd = DEFAULT_CMD + '--release-label emr-4.0.0'444result = copy.deepcopy(DEFAULT_RESULT)445result['ReleaseLabel'] = 'emr-4.0.0'446self.assert_params_for_cmd(cmd, result)447448def test_log_uri(self):449test_log_uri = 's3://test/logs'450cmd = DEFAULT_CMD + '--log-uri ' + test_log_uri451result = copy.deepcopy(DEFAULT_RESULT)452result['LogUri'] = test_log_uri453self.assert_params_for_cmd(cmd, result)454455def test_additional_info(self):456test_info = '{ami32: "ami-82e305f5"}'457cmd = DEFAULT_CMD.split() + ['--additional-info', test_info]458result = copy.deepcopy(DEFAULT_RESULT)459result['AdditionalInfo'] = test_info460self.assert_params_for_cmd(cmd, result)461462def test_auto_terminte(self):463cmd = (464'emr create-cluster --use-default-roles'465' --release-label emr-4.0.0 '466'--auto-terminate --instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG467)468result = copy.deepcopy(DEFAULT_RESULT)469instances = copy.deepcopy(DEFAULT_INSTANCES)470instances['KeepJobFlowAliveWhenNoSteps'] = False471result['Instances'] = instances472self.assert_params_for_cmd(cmd, result)473474def test_auto_terminate_and_no_auto_terminate(self):475cmd = (476DEFAULT_CMD477+ '--release-label emr-4.0.0 '478+ '--auto-terminate --no-auto-terminate'479)480expected_error_msg = (481'\naws: error: cannot use both --no-auto-terminate and'482' --auto-terminate options together.\n'483)484result = self.run_cmd(cmd, 255)485self.assertEqual(expected_error_msg, result[1])486487def test_termination_protected(self):488cmd = DEFAULT_CMD + '--termination-protected'489result = copy.deepcopy(DEFAULT_RESULT)490instances = copy.deepcopy(DEFAULT_INSTANCES)491instances['TerminationProtected'] = True492result['Instances'] = instances493self.assert_params_for_cmd(cmd, result)494495def test_no_termination_protected(self):496cmd = DEFAULT_CMD + '--no-termination-protected'497self.assert_params_for_cmd(cmd, DEFAULT_RESULT)498499def test_termination_protected_and_no_termination_protected(self):500cmd = (501DEFAULT_CMD + '--termination-protected --no-termination-protected'502)503expected_error_msg = (504'\naws: error: cannot use both --termination-protected'505' and --no-termination-protected options together.\n'506)507result = self.run_cmd(cmd, 255)508self.assertEqual(expected_error_msg, result[1])509510def test_unhealthy_node_replacement(self):511cmd = DEFAULT_CMD + '--unhealthy-node-replacement'512result = copy.deepcopy(DEFAULT_RESULT)513instances = copy.deepcopy(DEFAULT_INSTANCES)514instances['UnhealthyNodeReplacement'] = True515result['Instances'] = instances516self.assert_params_for_cmd(cmd, result)517518def test_no_unhealthy_node_replacement(self):519cmd = DEFAULT_CMD + '--no-unhealthy-node-replacement'520result = copy.deepcopy(DEFAULT_RESULT)521instances = copy.deepcopy(DEFAULT_INSTANCES)522instances['UnhealthyNodeReplacement'] = False523result['Instances'] = instances524self.assert_params_for_cmd(cmd, result)525526def test_unhealthy_node_replacement_and_no_unhealthy_node_replacement(527self,528):529cmd = (530DEFAULT_CMD531+ '--unhealthy-node-replacement --no-unhealthy-node-replacement'532)533expected_error_msg = (534'\naws: error: cannot use both --unhealthy-node-replacement'535' and --no-unhealthy-node-replacement options together.\n'536)537result = self.run_cmd(cmd, 255)538self.assertEqual(expected_error_msg, result[1])539540def test_visible_to_all_users(self):541cmd = DEFAULT_CMD + '--visible-to-all-users'542self.assert_params_for_cmd(cmd, DEFAULT_RESULT)543544def test_no_visible_to_all_users(self):545cmd = DEFAULT_CMD + '--no-visible-to-all-users'546result = copy.deepcopy(DEFAULT_RESULT)547result['VisibleToAllUsers'] = False548self.assert_params_for_cmd(cmd, result)549550def test_visible_to_all_users_and_no_visible_to_all_users(self):551cmd = DEFAULT_CMD + '--visible-to-all-users --no-visible-to-all-users'552expected_error_msg = (553'\naws: error: cannot use both --visible-to-all-users and '554'--no-visible-to-all-users options together.\n'555)556result = self.run_cmd(cmd, 255)557self.assertEqual(expected_error_msg, result[1])558559def test_extended_support(self):560cmd = DEFAULT_CMD + '--extended-support'561result = copy.deepcopy(DEFAULT_RESULT)562result['ExtendedSupport'] = True563self.assert_params_for_cmd(cmd, result)564565def test_no_extended_support(self):566cmd = DEFAULT_CMD + '--no-extended-support'567result = copy.deepcopy(DEFAULT_RESULT)568result['ExtendedSupport'] = False569self.assert_params_for_cmd(cmd, result)570571def test_extended_support_and_no_extended_support(self):572cmd = DEFAULT_CMD + '--extended-support --no-extended-support'573expected_error_msg = (574'\naws: error: cannot use both --extended-support'575' and --no-extended-support options together.\n'576)577result = self.run_cmd(cmd, 255)578self.assertEqual(expected_error_msg, result[1])579580def test_tags(self):581cmd = DEFAULT_CMD.split() + ['--tags', 'k1=v1', 'k2', 'k3=spaces v3']582result = copy.deepcopy(DEFAULT_RESULT)583tags = [584{'Key': 'k1', 'Value': 'v1'},585{'Key': 'k2', 'Value': ''},586{'Key': 'k3', 'Value': 'spaces v3'},587]588result['Tags'] = tags589self.assert_params_for_cmd(cmd, result)590591def test_enable_debugging(self):592cmd = DEFAULT_CMD + '--log-uri s3://test/logs --enable-debugging'593result = copy.deepcopy(DEFAULT_RESULT)594result['LogUri'] = 's3://test/logs'595debugging_config = [596{597'Name': 'Setup Hadoop Debugging',598'ActionOnFailure': 'TERMINATE_CLUSTER',599'HadoopJarStep': {600'Args': ['state-pusher-script'],601'Jar': 'command-runner.jar',602},603}604]605result['Steps'] = debugging_config606self.assert_params_for_cmd(cmd, result)607608cmd = DEFAULT_CMD + (609'--log-uri s3://test/logs --enable-debugging ' '--region us-west-2'610)611debugging_config = [612{613'Name': 'Setup Hadoop Debugging',614'ActionOnFailure': 'TERMINATE_CLUSTER',615'HadoopJarStep': {616'Args': ['state-pusher-script'],617'Jar': 'command-runner.jar',618},619}620]621result['Steps'] = debugging_config622self.assert_params_for_cmd(cmd, result)623624def test_enable_debugging_no_log_uri(self):625cmd = DEFAULT_CMD + '--enable-debugging'626expected_error_msg = (627'\naws: error: LogUri not specified. You must specify a logUri'628' if you enable debugging when creating a cluster.\n'629)630result = self.run_cmd(cmd, 255)631self.assertEqual(expected_error_msg, result[1])632633def test_enable_debugging_and_no_enable_debugging(self):634cmd = (635DEFAULT_CMD636+ '--enable-debugging --no-enable-debugging'637+ ' --log-uri s3://test/logs'638)639expected_error_msg = (640'\naws: error: cannot use both --enable-debugging and '641'--no-enable-debugging options together.\n'642)643result = self.run_cmd(cmd, 255)644self.assertEqual(expected_error_msg, result[1])645646def test_instance_groups_default_name_market(self):647cmd = (648'emr create-cluster --use-default-roles --release-label emr-4.0.0 '649'--instance-groups '650'InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m1.large '651'InstanceGroupType=CORE,InstanceCount=1,InstanceType=m1.large '652'InstanceGroupType=TASK,InstanceCount=1,InstanceType=m1.large '653)654self.assert_params_for_cmd(cmd, DEFAULT_RESULT)655656def test_instance_groups_instance_group_type_mismatch_cases(self):657cmd = (658'emr create-cluster --use-default-roles --release-label emr-4.0.0 '659'--instance-groups '660'Name=MASTER,InstanceGroupType=MaSter,InstanceCount=1,'661'InstanceType=m1.large Name=CORE,InstanceGroupType=cORE,'662'InstanceCount=1,InstanceType=m1.large Name=TASK,'663'InstanceGroupType=tAsK,InstanceCount=1,InstanceType=m1.large'664)665self.assert_params_for_cmd(cmd, DEFAULT_RESULT)666667def test_instance_groups_instance_type_and_count(self):668cmd = (669'emr create-cluster --use-default-roles --release-label emr-4.0.0 '670'--instance-type m1.large'671)672expected_result = copy.deepcopy(DEFAULT_RESULT)673expected_result['Instances'] = {674'KeepJobFlowAliveWhenNoSteps': True,675'TerminationProtected': False,676'InstanceGroups': [677{678'InstanceRole': 'MASTER',679'InstanceCount': 1,680'Name': 'MASTER',681'Market': 'ON_DEMAND',682'InstanceType': 'm1.large',683}684],685}686self.assert_params_for_cmd(cmd, expected_result)687cmd = (688'emr create-cluster --use-default-roles --release-label emr-4.0.0 '689'--instance-type m1.large --instance-count 3'690)691expected_result = copy.deepcopy(DEFAULT_RESULT)692expected_result['Instances'] = {693'KeepJobFlowAliveWhenNoSteps': True,694'TerminationProtected': False,695'InstanceGroups': [696{697'InstanceRole': 'MASTER',698'InstanceCount': 1,699'Name': 'MASTER',700'Market': 'ON_DEMAND',701'InstanceType': 'm1.large',702},703{704'InstanceRole': 'CORE',705'InstanceCount': 2,706'Name': 'CORE',707'Market': 'ON_DEMAND',708'InstanceType': 'm1.large',709},710],711}712self.assert_params_for_cmd(cmd, expected_result)713714def test_instance_groups_missing_required_parameter_error(self):715cmd = (716'emr create-cluster --use-default-roles --release-label'717' emr-4.0.0 '718)719expect_error_msg = (720'\naws: error: Must specify either --instance-groups or '721'--instance-type with --instance-count(optional) to '722'configure instance groups.\n'723)724result = self.run_cmd(cmd, 255)725self.assertEqual(expect_error_msg, result[1])726727cmd = (728'emr create-cluster --use-default-roles --release-label emr-4.0.0 '729'--instance-count 2'730)731expect_error_msg = (732'\naws: error: Must specify either --instance-groups or '733'--instance-type with --instance-count(optional) to '734'configure instance groups.\n'735)736result = self.run_cmd(cmd, 255)737self.assertEqual(expect_error_msg, result[1])738739def test_instance_groups_exclusive_parameter_validation_error(self):740cmd = (741'emr create-cluster --use-default-roles --release-label 4.0.0 '742'--instance-type m1.large --instance-groups '743+ DEFAULT_INSTANCE_GROUPS_ARG744)745expect_error_msg = (746'\naws: error: You may not specify --instance-type '747'or --instance-count with --instance-groups, '748'because --instance-type and --instance-count are '749'shortcut options for --instance-groups.\n'750)751result = self.run_cmd(cmd, 255)752self.assertEqual(expect_error_msg, result[1])753754cmd = (755'emr create-cluster --use-default-roles --release-label emr-4.0.0 '756'--instance-type m1.large --instance-count 2 '757'--instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG758)759expect_error_msg = (760'\naws: error: You may not specify --instance-type '761'or --instance-count with --instance-groups, '762'because --instance-type and --instance-count are '763'shortcut options for --instance-groups.\n'764)765result = self.run_cmd(cmd, 255)766self.assertEqual(expect_error_msg, result[1])767768def test_instance_groups_missing_instance_group_type_error(self):769cmd = (770'emr create-cluster --use-default-roles --release-label emr-4.0.0 '771'--auto-terminate '772'--instance-groups '773'Name=Master,InstanceCount=1,InstanceType=m1.small'774)775stderr = self.run_cmd(cmd, 255)[1]776self.assert_error_message_has_field_name(stderr, 'InstanceGroupType')777778def test_instance_groups_missing_instance_type_error(self):779cmd = (780'emr create-cluster --use-default-roles --release-label emr-4.0.0 '781'--auto-terminate '782'--instance-groups '783'Name=Master,InstanceGroupType=MASTER,InstanceCount=1'784)785stderr = self.run_cmd(cmd, 255)[1]786self.assert_error_message_has_field_name(stderr, 'InstanceType')787788def test_instance_groups_missing_instance_count_error(self):789cmd = (790'emr create-cluster --use-default-roles --release-label emr-4.0.0 '791'--auto-terminate '792'--instance-groups '793'Name=Master,InstanceGroupType=MASTER,InstanceType=m1.xlarge'794)795stderr = self.run_cmd(cmd, 255)[1]796self.assert_error_message_has_field_name(stderr, 'InstanceCount')797798def test_instance_groups_from_json_file(self):799data_path = os.path.join(800os.path.dirname(__file__), 'input_instance_groups.json'801)802cmd = (803'emr create-cluster --use-default-roles'804' --release-label emr-4.0.0 '805'--instance-groups file://' + data_path806)807result = copy.deepcopy(DEFAULT_RESULT)808result['Instances']['InstanceGroups'] = [809{810'InstanceRole': 'MASTER',811'InstanceCount': 1,812'Name': 'Master Instance Group',813'Market': 'ON_DEMAND',814'InstanceType': 'm1.large',815},816{817'InstanceRole': 'CORE',818'InstanceCount': 2,819'Name': 'Core Instance Group',820'Market': 'ON_DEMAND',821'InstanceType': 'm1.xlarge',822},823{824'InstanceRole': 'TASK',825'InstanceCount': 3,826'Name': 'Task Instance Group',827'Market': 'SPOT',828'BidPrice': '3.45',829'InstanceType': 'm1.xlarge',830},831]832self.assert_params_for_cmd(cmd, result)833834def test_instance_groups_from_json_file_spot_bidprice_equals_ondemandprice(835self,836):837data_path = os.path.join(838os.path.dirname(__file__),839'input_instance_groups_spot_bidprice_equals_ondemandprice.json',840)841cmd = (842'emr create-cluster --use-default-roles'843' --release-label emr-4.0.0 '844'--instance-groups file://' + data_path845)846result = copy.deepcopy(DEFAULT_RESULT)847result['Instances']['InstanceGroups'] = [848{849'InstanceRole': 'MASTER',850'InstanceCount': 1,851'Name': 'Master Instance Group',852'Market': 'SPOT',853'InstanceType': 'm1.large',854},855{856'InstanceRole': 'CORE',857'InstanceCount': 2,858'Name': 'Core Instance Group',859'Market': 'SPOT',860'InstanceType': 'm1.xlarge',861},862{863'InstanceRole': 'TASK',864'InstanceCount': 3,865'Name': 'Task Instance Group',866'Market': 'SPOT',867'InstanceType': 'm1.xlarge',868},869]870self.assert_params_for_cmd(cmd, result)871872def test_instance_groups_adds_configurations(self):873data_path = os.path.join(874os.path.dirname(__file__),875'input_instance_groups_with_configurations.json',876)877cmd = (878'emr create-cluster --use-default-roles'879' --release-label emr-4.0.0 '880'--instance-groups file://' + data_path881)882result = copy.deepcopy(DEFAULT_RESULT)883result['Instances']['InstanceGroups'][1]['Configurations'] = [884OrderedDict(885[886("Classification", "hdfs-site"),887(888"Properties",889OrderedDict(890[891("test-key1", "test-value1"),892("test-key2", "test-value2"),893]894),895),896]897)898]899self.assert_params_for_cmd(cmd, result)900901def test_ec2_attributes_no_az(self):902cmd = (903'emr create-cluster --release-label emr-4.0.0 '904'--instance-groups '905+ DEFAULT_INSTANCE_GROUPS_ARG906+ ' --ec2-attributes KeyName=testkey,SubnetId=subnet-123456,'907'InstanceProfile=EMR_EC2_DefaultRole '908'--service-role EMR_DefaultRole'909)910result = copy.deepcopy(DEFAULT_RESULT)911result['Instances']['Ec2KeyName'] = 'testkey'912result['Instances']['Ec2SubnetId'] = 'subnet-123456'913result['JobFlowRole'] = 'EMR_EC2_DefaultRole'914self.assert_params_for_cmd(cmd, result)915916def test_ec2_attributes_az(self):917cmd = DEFAULT_CMD + '--ec2-attributes AvailabilityZone=us-east-1a'918result = copy.deepcopy(DEFAULT_RESULT)919result['Instances']['Placement'] = {'AvailabilityZone': 'us-east-1a'}920self.assert_params_for_cmd(cmd, result)921922def test_ec2_attributes_subnet_az_error(self):923cmd = (924DEFAULT_CMD925+ '--ec2-attributes '926+ 'SubnetId=subnet-123456,AvailabilityZone=us-east-1a'927)928expect_error_msg = (929'\naws: error: You may not specify both a SubnetId and an Availab'930'ilityZone (placement) because ec2SubnetId implies a placement.\n'931)932result = self.run_cmd(cmd, 255)933self.assertEqual(expect_error_msg, result[1])934935def test_ec2_attributes_with_subnet_from_json_file(self):936data_path = os.path.join(937os.path.dirname(__file__), 'input_ec2_attributes_with_subnet.json'938)939cmd = (940'emr create-cluster --release-label emr-4.0.0 '941'--instance-groups '942+ DEFAULT_INSTANCE_GROUPS_ARG943+ ' --ec2-attributes file://'944+ data_path945+ ' --service-role EMR_DefaultRole'946)947result = copy.deepcopy(DEFAULT_RESULT)948result['Instances']['Ec2KeyName'] = 'testkey'949result['Instances']['Ec2SubnetId'] = 'subnet-123456'950result['JobFlowRole'] = 'EMR_EC2_DefaultRole'951self.assert_params_for_cmd(cmd, result)952953def test_ec2_attributes_with_az_from_json_file(self):954data_path = os.path.join(955os.path.dirname(__file__), 'input_ec2_attributes_with_az.json'956)957cmd = (958'emr create-cluster --release-label emr-4.0.0 '959'--instance-groups '960+ DEFAULT_INSTANCE_GROUPS_ARG961+ ' --ec2-attributes file://'962+ data_path963+ ' --service-role EMR_DefaultRole'964)965result = copy.deepcopy(DEFAULT_RESULT)966result['Instances']['Ec2KeyName'] = 'testkey'967result['Instances']['Placement'] = {'AvailabilityZone': 'us-east-1a'}968result['JobFlowRole'] = 'EMR_EC2_DefaultRole'969self.assert_params_for_cmd(cmd, result)970971# Bootstrap Actions test cases972def test_bootstrap_actions_missing_path_error(self):973cmd = DEFAULT_CMD + '--bootstrap-actions Name=ba1,Args=arg1,arg2'974stderr = self.run_cmd(cmd, 255)[1]975self.assert_error_message_has_field_name(stderr, 'Path')976977def test_bootstrap_actions_with_all_fields(self):978cmd = DEFAULT_CMD + (979' --bootstrap-actions '980'Path=s3://test/ba1,Name=ba1,Args=arg1,arg2,arg3 '981'Path=s3://test/ba2,Name=ba2,Args=arg1,arg2,arg3'982)983result = copy.deepcopy(DEFAULT_RESULT)984result['BootstrapActions'] = TEST_BA985986self.assert_params_for_cmd(cmd, result)987988def test_bootstrap_actions_exceed_maximum_error(self):989cmd = DEFAULT_CMD + ' --bootstrap-actions'990ba_cmd = ' Path=s3://test/ba1,Name=ba1,Args=arg1,arg2,arg3'991for i in range(1, 18):992cmd += ba_cmd993994expected_error_msg = (995'\naws: error: maximum number of '996+ 'bootstrap actions for a cluster exceeded.\n'997)998result = self.run_cmd(cmd, 255)9991000self.assertEqual(expected_error_msg, result[1])10011002def test_bootstrap_actions_exceed_maximum_with_applications_error(self):1003cmd = DEFAULT_CMD + ' --bootstrap-actions'1004ba_cmd = ' Path=s3://test/ba1,Name=ba1,Args=arg1,arg2,arg3'1005for i in range(1, 20):1006cmd += ba_cmd1007expected_error_msg = (1008'\naws: error: maximum number of '1009+ 'bootstrap actions for a cluster exceeded.\n'1010)1011result = self.run_cmd(cmd, 255)1012self.assertEqual(expected_error_msg, result[1])10131014def test_boostrap_actions_with_default_fields(self):1015cmd = DEFAULT_CMD + (1016' --bootstrap-actions Path=s3://test/ba1 Path=s3://test/ba2'1017)1018result = copy.deepcopy(DEFAULT_RESULT)1019result['BootstrapActions'] = [1020{1021'Name': 'Bootstrap action',1022'ScriptBootstrapAction': {'Path': 's3://test/ba1'},1023},1024{1025'Name': 'Bootstrap action',1026'ScriptBootstrapAction': {'Path': 's3://test/ba2'},1027},1028]1029self.assert_params_for_cmd(cmd, result)10301031def test_bootstrap_actions_from_json_file(self):1032data_path = os.path.join(1033os.path.dirname(__file__), 'input_bootstrap_actions.json'1034)1035cmd = DEFAULT_CMD + ' --bootstrap-actions file://' + data_path1036result = copy.deepcopy(DEFAULT_RESULT)1037result['BootstrapActions'] = [1038{1039"Name": "Bootstrap Action 1",1040"ScriptBootstrapAction": {1041"Path": "s3://mybucket/test1",1042"Args": ["arg1", "arg2"],1043},1044},1045{1046"Name": "Bootstrap Action 2",1047"ScriptBootstrapAction": {1048"Path": "s3://mybucket/test2",1049"Args": ["arg1", "arg2"],1050},1051},1052]1053self.assert_params_for_cmd(cmd, result)10541055# Steps test cases1056def test_wrong_step_type_error(self):1057cmd = DEFAULT_CMD + '--steps Type=unknown'1058expected_error_msg = (1059'\naws: error: The step type unknown is not supported.\n'1060)1061result = self.run_cmd(cmd, 255)1062self.assertEqual(expected_error_msg, result[1])10631064def test_default_step_type_name_action_on_failure(self):1065cmd = DEFAULT_CMD + '--steps Jar=s3://mybucket/mytest.jar'1066result = copy.deepcopy(DEFAULT_RESULT)1067result['Steps'] = [CUSTOM_JAR_STEP]1068self.assert_params_for_cmd(cmd, result)10691070def test_custom_jar_step_missing_jar(self):1071cmd = DEFAULT_CMD + '--steps Name=CustomJarMissingJar'1072expect_error_msg = (1073'\naws: error: The following '1074+ 'required parameters are missing for CustomJARStepConfig: Jar.\n'1075)1076result = self.run_cmd(cmd, 255)1077self.assertEqual(expect_error_msg, result[1])10781079def test_custom_jar_step_with_all_fields(self):1080cmd = (1081DEFAULT_CMD1082+ '--steps '1083+ (1084'Name=Custom,Type=Custom_JAR,'1085'Jar=s3://mybucket/mytest.jar,'1086'Args=arg1,arg2,MainClass=mymainclass,'1087'ActionOnFailure=TERMINATE_CLUSTER'1088)1089)1090expected_steps = [1091{1092'Name': 'Custom',1093'ActionOnFailure': 'TERMINATE_CLUSTER',1094'HadoopJarStep': {1095'Jar': 's3://mybucket/mytest.jar',1096'Args': ['arg1', 'arg2'],1097'MainClass': 'mymainclass',1098},1099}1100]1101result = copy.deepcopy(DEFAULT_RESULT)1102result['Steps'] = expected_steps1103self.assert_params_for_cmd(cmd, result)11041105def test_streaming_step_with_default_fields(self):1106cmd = DEFAULT_CMD + '--steps Type=Streaming,' + STREAMING_ARGS1107result = copy.deepcopy(DEFAULT_RESULT)1108result['Steps'] = [1109{1110'Name': 'Streaming program',1111'ActionOnFailure': 'CONTINUE',1112'HadoopJarStep': STREAMING_HADOOP_JAR_STEP,1113}1114]1115self.assert_params_for_cmd(cmd, result)11161117def test_streaming_step_missing_args(self):1118cmd = DEFAULT_CMD + '--steps Type=Streaming'1119expect_error_msg = (1120'\naws: error: The following '1121+ 'required parameters are missing for StreamingStepConfig: Args.\n'1122)1123result = self.run_cmd(cmd, 255)1124self.assertEqual(expect_error_msg, result[1])11251126def test_streaming_jar_with_all_fields(self):1127test_step_config = (1128'--steps Type=Streaming,Name=StreamingStepAllFields,'1129'ActionOnFailure=CANCEL_AND_WAIT,' + STREAMING_ARGS1130)1131cmd = DEFAULT_CMD + test_step_config1132result = copy.deepcopy(DEFAULT_RESULT)1133result['Steps'] = [1134{1135'Name': 'StreamingStepAllFields',1136'ActionOnFailure': 'CANCEL_AND_WAIT',1137'HadoopJarStep': STREAMING_HADOOP_JAR_STEP,1138}1139]1140self.assert_params_for_cmd(cmd, result)11411142def test_hive_step_with_default_fields(self):1143cmd = DEFAULT_CMD + (1144'--applications Name=Hive --steps Type=Hive,' + HIVE_BASIC_ARGS1145)1146result = copy.deepcopy(DEFAULT_RESULT)1147result['Applications'] = [{'Name': 'Hive'}]1148result['Steps'] = [HIVE_DEFAULT_STEP]1149self.assert_params_for_cmd(cmd, result)11501151def test_hive_step_missing_args(self):1152cmd = DEFAULT_CMD + '--applications Name=Hive --steps Type=Hive'1153expect_error_msg = (1154'\naws: error: The following '1155+ 'required parameters are missing for HiveStepConfig: Args.\n'1156)1157result = self.run_cmd(cmd, 255)1158self.assertEqual(expect_error_msg, result[1])11591160def test_hive_step_with_all_fields(self):1161test_step_config = (1162'Type=Hive,ActionOnFailure=CANCEL_AND_WAIT,'1163'Name=HiveBasicStep,' + HIVE_BASIC_ARGS1164)1165cmd = DEFAULT_CMD + (1166'--applications Name=Hive --steps ' + test_step_config1167)1168result = copy.deepcopy(DEFAULT_RESULT)1169result['Steps'] = [HIVE_STEP]1170result['Applications'] = [{'Name': 'Hive'}]1171self.assert_params_for_cmd(cmd, result)11721173def test_pig_step_with_default_fields(self):1174cmd = DEFAULT_CMD + (1175'--applications Name=Pig --steps Type=Pig,' + PIG_BASIC_ARGS1176)1177result = copy.deepcopy(DEFAULT_RESULT)1178result['Steps'] = [PIG_DEFAULT_STEP]1179result['Applications'] = [{'Name': 'Pig'}]1180self.assert_params_for_cmd(cmd, result)11811182def test_pig_missing_args(self):1183cmd = DEFAULT_CMD + '--applications Name=Pig --steps Type=Pig'1184expect_error_msg = (1185'\naws: error: The following '1186+ 'required parameters are missing for PigStepConfig: Args.\n'1187)1188result = self.run_cmd(cmd, 255)1189self.assertEqual(expect_error_msg, result[1])11901191def test_pig_step_with_all_fields(self):1192test_step_config = (1193'Name=PigBasicStep,Type=Pig,'1194+ PIG_BASIC_ARGS1195+ ',ActionOnFailure=CANCEL_AND_WAIT'1196)1197cmd = DEFAULT_CMD + (1198'--applications Name=Pig --steps ' + test_step_config1199)1200result = copy.deepcopy(DEFAULT_RESULT)1201result['Applications'] = [{'Name': 'Pig'}]1202result['Steps'] = [PIG_STEP]1203self.assert_params_for_cmd(cmd, result)12041205@mock.patch('awscli.customizations.emr.emrutils.call')1206def test_constructed_result(self, call_patch):1207call_patch.return_value = CREATE_CLUSTER_RESULT1208cmd = DEFAULT_CMD1209result = self.run_cmd(cmd, expected_rc=0)1210result_json = json.loads(result[0])1211self.assertEqual(result_json, CONSTRUCTED_RESULT)12121213def test_all_security_groups(self):1214cmd = DEFAULT_CMD + (1215'--ec2-attributes EmrManagedMasterSecurityGroup=sg-master1,'1216'EmrManagedSlaveSecurityGroup=sg-slave1,'1217'ServiceAccessSecurityGroup=sg-service-access,'1218'AdditionalMasterSecurityGroups='1219'[sg-addMaster1,sg-addMaster2,sg-addMaster3,'1220'sg-addMaster4],AdditionalSlaveSecurityGroups=[sg-addSlave1,'1221'sg-addSlave2,sg-addSlave3,sg-addSlave4]'1222)12231224result = copy.deepcopy(DEFAULT_RESULT)1225instances = result['Instances']1226instances['EmrManagedMasterSecurityGroup'] = (1227EMR_MANAGED_MASTER_SECURITY_GROUP1228)1229instances['EmrManagedSlaveSecurityGroup'] = (1230EMR_MANAGED_SLAVE_SECURITY_GROUP1231)1232instances['ServiceAccessSecurityGroup'] = SERVICE_ACCESS_SECURITY_GROUP1233instances['AdditionalMasterSecurityGroups'] = (1234ADDITIONAL_MASTER_SECURITY_GROUPS1235)1236instances['AdditionalSlaveSecurityGroups'] = (1237ADDITIONAL_SLAVE_SECURITY_GROUPS1238)12391240self.assert_params_for_cmd(cmd, result)12411242def test_emr_managed_security_groups(self):1243cmd = DEFAULT_CMD + (1244'--ec2-attributes EmrManagedMasterSecurityGroup=sg-master1,'1245'EmrManagedSlaveSecurityGroup=sg-slave1,'1246'ServiceAccessSecurityGroup=sg-service-access'1247)12481249result = copy.deepcopy(DEFAULT_RESULT)1250instances = result['Instances']1251instances['EmrManagedMasterSecurityGroup'] = (1252EMR_MANAGED_MASTER_SECURITY_GROUP1253)1254instances['EmrManagedSlaveSecurityGroup'] = (1255EMR_MANAGED_SLAVE_SECURITY_GROUP1256)1257instances['ServiceAccessSecurityGroup'] = SERVICE_ACCESS_SECURITY_GROUP12581259self.assert_params_for_cmd(cmd, result)12601261def test_additional_security_groups(self):1262cmd = DEFAULT_CMD + (1263'--ec2-attributes AdditionalMasterSecurityGroups=[sg-addMaster1'1264',sg-addMaster2,sg-addMaster3,sg-addMaster4],AdditionalSlaveSecu'1265'rityGroups=[sg-addSlave1,sg-addSlave2,sg-addSlave3,sg-addSlave4]'1266)12671268result = copy.deepcopy(DEFAULT_RESULT)1269instances = result['Instances']1270instances['AdditionalMasterSecurityGroups'] = (1271ADDITIONAL_MASTER_SECURITY_GROUPS1272)1273instances['AdditionalSlaveSecurityGroups'] = (1274ADDITIONAL_SLAVE_SECURITY_GROUPS1275)12761277self.assert_params_for_cmd(cmd, result)12781279def test_security_groups_from_json_file(self):1280data_path = os.path.join(1281os.path.dirname(__file__),1282'input_ec2_attributes_with_security_groups.json',1283)1284cmd = DEFAULT_CMD + '--ec2-attributes file://' + data_path12851286result = copy.deepcopy(DEFAULT_RESULT)1287instances = result['Instances']1288instances['EmrManagedMasterSecurityGroup'] = (1289EMR_MANAGED_MASTER_SECURITY_GROUP1290)1291instances['EmrManagedSlaveSecurityGroup'] = (1292EMR_MANAGED_SLAVE_SECURITY_GROUP1293)1294instances['ServiceAccessSecurityGroup'] = SERVICE_ACCESS_SECURITY_GROUP1295instances['AdditionalMasterSecurityGroups'] = (1296ADDITIONAL_MASTER_SECURITY_GROUPS1297)1298instances['AdditionalSlaveSecurityGroups'] = (1299ADDITIONAL_SLAVE_SECURITY_GROUPS1300)13011302self.assert_params_for_cmd(cmd, result)13031304def test_instance_group_with_autoscaling_policy(self):1305cmd = (1306self.prefix1307+ '--release-label emr-4.2.0 --auto-scaling-role EMR_AUTOSCALING_ROLE --instance-groups '1308+ CONSTANTS.INSTANCE_GROUPS_WITH_AUTOSCALING_POLICY_ARG1309)1310result = {1311'Name': DEFAULT_CLUSTER_NAME,1312'Instances': {1313'KeepJobFlowAliveWhenNoSteps': True,1314'TerminationProtected': False,1315'InstanceGroups': CONSTANTS.INSTANCE_GROUPS_WITH_AUTOSCALING_POLICY,1316},1317'ReleaseLabel': 'emr-4.2.0',1318'AutoScalingRole': 'EMR_AUTOSCALING_ROLE',1319'VisibleToAllUsers': True,1320'Tags': [],1321}1322self.assert_params_for_cmd(cmd, result)13231324def test_instance_group_with_autoscaling_policy_missing_autoscaling_role(1325self,1326):1327cmd = (1328self.prefix1329+ '--release-label emr-4.2.0 --instance-groups '1330+ CONSTANTS.INSTANCE_GROUPS_WITH_AUTOSCALING_POLICY_ARG1331)1332expected_error_msg = (1333'\naws: error: Must specify --auto-scaling-role when'1334' configuring an AutoScaling policy for an instance group.\n'1335)1336result = self.run_cmd(cmd, 255)1337self.assertEqual(expected_error_msg, result[1])13381339def test_scale_down_behavior(self):1340cmd = (1341self.prefix1342+ '--release-label emr-4.0.0 --scale-down-behavior TERMINATE_AT_INSTANCE_HOUR '1343'--instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG1344)1345result = {1346'Name': DEFAULT_CLUSTER_NAME,1347'Instances': DEFAULT_INSTANCES,1348'ReleaseLabel': 'emr-4.0.0',1349'VisibleToAllUsers': True,1350'ScaleDownBehavior': 'TERMINATE_AT_INSTANCE_HOUR',1351'Tags': [],1352}1353self.assert_params_for_cmd(cmd, result)13541355def test_instance_group_with_ebs_config(self):1356cmd = (1357self.prefix1358+ '--release-label emr-4.2.0 --instance-groups '1359+ CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_ARG1360)1361result = {1362'Name': DEFAULT_CLUSTER_NAME,1363'Instances': {1364'KeepJobFlowAliveWhenNoSteps': True,1365'TerminationProtected': False,1366'InstanceGroups': CONSTANTS.INSTANCE_GROUPS_WITH_EBS,1367},1368'ReleaseLabel': 'emr-4.2.0',1369'VisibleToAllUsers': True,1370'Tags': [],1371}1372self.assert_params_for_cmd(cmd, result)13731374def test_instance_groups_with_ebs_config_missing_volume_type(self):1375cmd = (1376self.prefix1377+ '--release-label emr-4.2.0 --instance-groups '1378+ CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_MISSING_VOLTYPE_ARG1379)1380stderr = self.run_cmd(cmd, 255)[1]1381self.assert_error_message_has_field_name(stderr, 'VolumeType')13821383def test_instance_groups_with_ebs_config_missing_size(self):1384cmd = (1385self.prefix1386+ '--release-label emr-4.2.0 --instance-groups '1387+ CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_MISSING_SIZE_ARG1388)1389stderr = self.run_cmd(cmd, 255)[1]1390self.assert_error_message_has_field_name(stderr, 'SizeInGB')13911392def test_instance_groups_with_ebs_config_missing_volume_spec(self):1393cmd = (1394self.prefix1395+ '--release-label emr-4.2.0 --instance-groups '1396+ CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_MISSING_VOLSPEC_ARG1397)1398result = {1399'Name': DEFAULT_CLUSTER_NAME,1400'Instances': {1401'KeepJobFlowAliveWhenNoSteps': True,1402'TerminationProtected': False,1403'InstanceGroups': CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_MISSING_VOLSPEC,1404},1405'ReleaseLabel': 'emr-4.2.0',1406'VisibleToAllUsers': True,1407'Tags': [],1408}1409self.assert_params_for_cmd(cmd, result)14101411def test_instance_groups_with_ebs_config_missing_iops(self):1412cmd = (1413self.prefix1414+ '--release-label emr-4.2.0 --instance-groups '1415+ CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_MISSING_IOPS_ARG1416)1417result = {1418'Name': DEFAULT_CLUSTER_NAME,1419'Instances': {1420'KeepJobFlowAliveWhenNoSteps': True,1421'TerminationProtected': False,1422'InstanceGroups': CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_MISSING_IOPS,1423},1424'ReleaseLabel': 'emr-4.2.0',1425'VisibleToAllUsers': True,1426'Tags': [],1427}1428self.assert_params_for_cmd(cmd, result)14291430def test_instance_groups_with_ebs_config_multiple_instance_groups(self):1431cmd = (1432self.prefix1433+ '--release-label emr-4.2.0 --instance-groups '1434+ CONSTANTS.MULTIPLE_INSTANCE_GROUPS_WITH_EBS_VOLUMES_VOLUME_ARG1435)1436result = {1437'Name': DEFAULT_CLUSTER_NAME,1438'Instances': {1439'KeepJobFlowAliveWhenNoSteps': True,1440'TerminationProtected': False,1441'InstanceGroups': CONSTANTS.MULTIPLE_INSTANCE_GROUPS_WITH_EBS_VOLUMES,1442},1443'ReleaseLabel': 'emr-4.2.0',1444'VisibleToAllUsers': True,1445'Tags': [],1446}1447self.assert_params_for_cmd(cmd, result)14481449def test_instance_fleets_with_on_demand_master_only(self):1450cmd = (1451self.prefix1452+ '--release-label emr-4.2.0 --instance-fleets '1453+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_ON_DEMAND_MASTER_ONLY1454)1455result = {1456'Name': DEFAULT_CLUSTER_NAME,1457'Instances': {1458'KeepJobFlowAliveWhenNoSteps': True,1459'TerminationProtected': False,1460'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_ON_DEMAND_MASTER_ONLY,1461},1462'ReleaseLabel': 'emr-4.2.0',1463'VisibleToAllUsers': True,1464'Tags': [],1465}1466self.assert_params_for_cmd(cmd, result)14671468def test_instance_fleets_with_spot_master_only_with_ebs_conf(self):1469cmd = (1470self.prefix1471+ '--release-label emr-4.2.0 --instance-fleets '1472+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY_WITH_EBS_CONF1473)1474result = {1475'Name': DEFAULT_CLUSTER_NAME,1476'Instances': {1477'KeepJobFlowAliveWhenNoSteps': True,1478'TerminationProtected': False,1479'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY_WITH_EBS_CONF,1480},1481'ReleaseLabel': 'emr-4.2.0',1482'VisibleToAllUsers': True,1483'Tags': [],1484}1485self.assert_params_for_cmd(cmd, result)14861487def test_instance_fleets_with_spot_master_specific_azs(self):1488cmd = (1489self.prefix1490+ '--release-label emr-4.2.0 --instance-fleets '1491+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY1492+ ' --ec2-attributes AvailabilityZones=[us-east-1a,us-east-1b]'1493)1494result = {1495'Name': DEFAULT_CLUSTER_NAME,1496'Instances': {1497'KeepJobFlowAliveWhenNoSteps': True,1498'TerminationProtected': False,1499'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY,1500'Placement': {1501'AvailabilityZones': ['us-east-1a', 'us-east-1b']1502},1503},1504'ReleaseLabel': 'emr-4.2.0',1505'VisibleToAllUsers': True,1506'Tags': [],1507}1508self.assert_params_for_cmd(cmd, result)15091510def test_instance_fleets_with_spot_master_subnet_ids(self):1511cmd = (1512self.prefix1513+ '--release-label emr-4.2.0 --instance-fleets '1514+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY1515+ ' --ec2-attributes SubnetIds=[subnetid-1,subnetid-2]'1516)1517result = {1518'Name': DEFAULT_CLUSTER_NAME,1519'Instances': {1520'KeepJobFlowAliveWhenNoSteps': True,1521'TerminationProtected': False,1522'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY,1523'Ec2SubnetIds': ['subnetid-1', 'subnetid-2'],1524},1525'ReleaseLabel': 'emr-4.2.0',1526'VisibleToAllUsers': True,1527'Tags': [],1528}1529self.assert_params_for_cmd(cmd, result)15301531def test_instance_fleets_with_spot_master_core_cluster_multiple_instance_types(1532self,1533):1534cmd = (1535self.prefix1536+ '--release-label emr-4.2.0 --instance-fleets '1537+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_SPOT_MASTER_CORE_CLUSTER1538)1539result = {1540'Name': DEFAULT_CLUSTER_NAME,1541'Instances': {1542'KeepJobFlowAliveWhenNoSteps': True,1543'TerminationProtected': False,1544'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_SPOT_MASTER_CORE_CLUSTER,1545},1546'ReleaseLabel': 'emr-4.2.0',1547'VisibleToAllUsers': True,1548'Tags': [],1549}1550self.assert_params_for_cmd(cmd, result)15511552def test_instance_fleets_with_complex_config_from_json(self):1553data_path = os.path.join(1554os.path.dirname(__file__), 'input_instance_fleets.json'1555)1556cmd = (1557'emr create-cluster --use-default-roles --release-label emr-4.2.0 '1558'--instance-fleets file://' + data_path1559)1560result = {1561'Name': DEFAULT_CLUSTER_NAME,1562'Instances': {1563'KeepJobFlowAliveWhenNoSteps': True,1564'TerminationProtected': False,1565'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_COMPLEX_CONFIG_FROM_JSON,1566},1567'ReleaseLabel': 'emr-4.2.0',1568'VisibleToAllUsers': True,1569'Tags': [],1570'JobFlowRole': 'EMR_EC2_DefaultRole',1571'ServiceRole': 'EMR_DefaultRole',1572}1573self.assert_params_for_cmd(cmd, result)15741575def test_instance_fleets_with_both_fleet_group_specified(self):1576cmd = (1577self.prefix1578+ '--release-label emr-4.2.0 --instance-fleets '1579+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY1580+ ' --instance-groups '1581+ CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_ARG1582)1583expected_error_msg = (1584'\naws: error: You cannot specify both --instance-groups'1585' and --instance-fleets options together.\n'1586)1587result = self.run_cmd(cmd, 255)1588self.assertEqual(expected_error_msg, result[1])15891590def test_instance_fleets_with_both_subnetid_subnetids_specified(self):1591cmd = (1592self.prefix1593+ '--release-label emr-4.2.0 --instance-fleets '1594+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_SPOT_MASTER_ONLY1595+ ' --ec2-attributes SubnetId=subnetid-1,SubnetIds=[subnetid-1,subnetid-2]'1596)1597expected_error_msg = (1598'\naws: error: You cannot specify both SubnetId'1599' and SubnetIds options together.\n'1600)1601result = self.run_cmd(cmd, 255)1602self.assertEqual(expected_error_msg, result[1])16031604def test_create_cluster_with_security_config(self):1605cmd = (1606self.prefix1607+ '--release-label emr-4.7.2 --security-configuration MySecurityConfig '1608+ '--instance-groups '1609+ DEFAULT_INSTANCE_GROUPS_ARG1610)1611result = {1612'Name': DEFAULT_CLUSTER_NAME,1613'Instances': DEFAULT_INSTANCES,1614'ReleaseLabel': 'emr-4.7.2',1615'VisibleToAllUsers': True,1616'Tags': [],1617'SecurityConfiguration': 'MySecurityConfig',1618}1619self.assert_params_for_cmd(cmd, result)16201621def test_create_cluster_with_security_config_and_kerberos_attributes(self):1622cmd = (1623self.prefix1624+ '--release-label emr-4.7.2 --security-configuration MySecurityConfig'1625+ ' --kerberos-attributes '1626+ DEFAULT_KERBEROS_ATTRIBUTES_ARGS1627+ ' --instance-groups '1628+ DEFAULT_INSTANCE_GROUPS_ARG1629)1630result = {1631'Name': DEFAULT_CLUSTER_NAME,1632'Instances': DEFAULT_INSTANCES,1633'KerberosAttributes': KERBEROS_ATTRIBUTES,1634'ReleaseLabel': 'emr-4.7.2',1635'VisibleToAllUsers': True,1636'Tags': [],1637'SecurityConfiguration': 'MySecurityConfig',1638}1639self.assert_params_for_cmd(cmd, result)16401641def test_create_cluster_with_custom_ami_id(self):1642cmd = (1643self.prefix1644+ '--release-label emr-4.7.2 --security-configuration MySecurityConfig '1645+ ' --custom-ami-id ami-9be6f38c'1646+ ' --instance-groups '1647+ DEFAULT_INSTANCE_GROUPS_ARG1648)1649result = {1650'Name': DEFAULT_CLUSTER_NAME,1651'Instances': DEFAULT_INSTANCES,1652'ReleaseLabel': 'emr-4.7.2',1653'VisibleToAllUsers': True,1654'Tags': [],1655'CustomAmiId': 'ami-9be6f38c',1656'SecurityConfiguration': 'MySecurityConfig',1657}1658self.assert_params_for_cmd(cmd, result)16591660def test_create_cluster_with_ebs_root_volume_size(self):1661cmd = (1662self.prefix1663+ '--release-label emr-4.7.2 --security-configuration MySecurityConfig '1664+ ' --ebs-root-volume-size 50'1665+ ' --instance-groups '1666+ DEFAULT_INSTANCE_GROUPS_ARG1667)1668result = {1669'Name': DEFAULT_CLUSTER_NAME,1670'Instances': DEFAULT_INSTANCES,1671'ReleaseLabel': 'emr-4.7.2',1672'VisibleToAllUsers': True,1673'Tags': [],1674'EbsRootVolumeSize': 50,1675'SecurityConfiguration': 'MySecurityConfig',1676}1677self.assert_params_for_cmd(cmd, result)16781679def test_create_cluster_with_ebs_root_volume_iops(self):1680cmd = (1681self.prefix1682+ '--release-label emr-6.15.0 --security-configuration MySecurityConfig '1683+ ' --ebs-root-volume-iops 3000'1684+ ' --instance-groups '1685+ DEFAULT_INSTANCE_GROUPS_ARG1686)1687result = {1688'Name': DEFAULT_CLUSTER_NAME,1689'Instances': DEFAULT_INSTANCES,1690'ReleaseLabel': 'emr-6.15.0',1691'VisibleToAllUsers': True,1692'Tags': [],1693'EbsRootVolumeIops': 3000,1694'SecurityConfiguration': 'MySecurityConfig',1695}1696self.assert_params_for_cmd(cmd, result)16971698def test_create_cluster_with_ebs_root_volume_throughput(self):1699cmd = (1700self.prefix1701+ '--release-label emr-6.15.0 --security-configuration MySecurityConfig '1702+ ' --ebs-root-volume-throughput 125'1703+ ' --instance-groups '1704+ DEFAULT_INSTANCE_GROUPS_ARG1705)1706result = {1707'Name': DEFAULT_CLUSTER_NAME,1708'Instances': DEFAULT_INSTANCES,1709'ReleaseLabel': 'emr-6.15.0',1710'VisibleToAllUsers': True,1711'Tags': [],1712'EbsRootVolumeThroughput': 125,1713'SecurityConfiguration': 'MySecurityConfig',1714}1715self.assert_params_for_cmd(cmd, result)17161717def test_create_cluster_with_repo_upgrade_on_boot(self):1718cmd = (1719self.prefix1720+ '--release-label emr-4.7.2 --security-configuration MySecurityConfig '1721+ ' --repo-upgrade-on-boot NONE'1722+ ' --instance-groups '1723+ DEFAULT_INSTANCE_GROUPS_ARG1724)1725result = {1726'Name': DEFAULT_CLUSTER_NAME,1727'Instances': DEFAULT_INSTANCES,1728'ReleaseLabel': 'emr-4.7.2',1729'VisibleToAllUsers': True,1730'Tags': [],1731'RepoUpgradeOnBoot': 'NONE',1732'SecurityConfiguration': 'MySecurityConfig',1733}1734self.assert_params_for_cmd(cmd, result)17351736def test_create_cluster_with_step_concurrency_level(self):1737cmd = (1738self.prefix1739+ '--release-label emr-5.28.0 --security-configuration MySecurityConfig '1740+ '--step-concurrency-level 30 '1741+ '--instance-groups '1742+ DEFAULT_INSTANCE_GROUPS_ARG1743)1744result = {1745'Name': DEFAULT_CLUSTER_NAME,1746'Instances': DEFAULT_INSTANCES,1747'ReleaseLabel': 'emr-5.28.0',1748'VisibleToAllUsers': True,1749'Tags': [],1750'StepConcurrencyLevel': 30,1751'SecurityConfiguration': 'MySecurityConfig',1752}1753self.assert_params_for_cmd(cmd, result)17541755def test_create_cluster_with_managed_scaling_policy(self):1756cmd = (1757self.prefix1758+ '--release-label emr-5.28.0 --security-configuration MySecurityConfig '1759+ '--managed-scaling-policy ComputeLimits={MinimumCapacityUnits=2,MaximumCapacityUnits=4,UnitType=Instances,MaximumCoreCapacityUnits=1} '1760+ '--instance-groups '1761+ DEFAULT_INSTANCE_GROUPS_ARG1762)1763result = {1764'Name': DEFAULT_CLUSTER_NAME,1765'Instances': DEFAULT_INSTANCES,1766'ReleaseLabel': 'emr-5.28.0',1767'VisibleToAllUsers': True,1768'Tags': [],1769'ManagedScalingPolicy': {1770'ComputeLimits': {1771'MinimumCapacityUnits': 2,1772'MaximumCapacityUnits': 4,1773'UnitType': 'Instances',1774'MaximumCoreCapacityUnits': 1,1775}1776},1777'SecurityConfiguration': 'MySecurityConfig',1778}1779self.assert_params_for_cmd(cmd, result)17801781def test_create_cluster_with_managed_scaling_policy_customer_knobs(self):1782cmd = (1783self.prefix1784+ '--release-label emr-5.28.0 --security-configuration MySecurityConfig '1785+ '--managed-scaling-policy ComputeLimits={MinimumCapacityUnits=2,MaximumCapacityUnits=4,'1786+ 'UnitType=Instances,MaximumCoreCapacityUnits=1},ScalingStrategy=ADVANCED,'1787+ 'UtilizationPerformanceIndex=1 --instance-groups '1788+ DEFAULT_INSTANCE_GROUPS_ARG1789)1790result = {1791'Name': DEFAULT_CLUSTER_NAME,1792'Instances': DEFAULT_INSTANCES,1793'ReleaseLabel': 'emr-5.28.0',1794'VisibleToAllUsers': True,1795'Tags': [],1796'ManagedScalingPolicy': {1797'ComputeLimits': {1798'MinimumCapacityUnits': 2,1799'MaximumCapacityUnits': 4,1800'UnitType': 'Instances',1801'MaximumCoreCapacityUnits': 1,1802},1803'ScalingStrategy': 'ADVANCED',1804'UtilizationPerformanceIndex': 1,1805},1806'SecurityConfiguration': 'MySecurityConfig',1807}1808self.assert_params_for_cmd(cmd, result)18091810def test_create_cluster_with_auto_termination_policy(self):1811cmd = (1812self.prefix1813+ '--release-label emr-5.34.0 '1814+ '--auto-termination-policy IdleTimeout=100 '1815+ '--instance-groups '1816+ DEFAULT_INSTANCE_GROUPS_ARG1817)1818result = {1819'Name': DEFAULT_CLUSTER_NAME,1820'Instances': DEFAULT_INSTANCES,1821'ReleaseLabel': 'emr-5.34.0',1822'VisibleToAllUsers': True,1823'Tags': [],1824'AutoTerminationPolicy': {1825'IdleTimeout': 100,1826},1827}1828self.assert_params_for_cmd(cmd, result)18291830def test_create_cluster_with_log_encryption_kms_key_id(self):1831test_log_uri = 's3://test/logs'1832test_log_encryption_kms_key_id = 'valid_kms_key'1833cmd = (1834self.prefix1835+ '--release-label emr-5.30.0 '1836+ '--log-uri '1837+ test_log_uri1838+ ' --log-encryption-kms-key-id '1839+ test_log_encryption_kms_key_id1840+ ' --instance-groups '1841+ DEFAULT_INSTANCE_GROUPS_ARG1842)1843result = {1844'Name': DEFAULT_CLUSTER_NAME,1845'Instances': DEFAULT_INSTANCES,1846'ReleaseLabel': 'emr-5.30.0',1847'VisibleToAllUsers': True,1848'Tags': [],1849'LogUri': test_log_uri,1850'LogEncryptionKmsKeyId': test_log_encryption_kms_key_id,1851}1852self.assert_params_for_cmd(cmd, result)18531854def test_create_cluster_with_placement_groups(self):1855cmd = (1856self.prefix1857+ '--release-label emr-5.28.0 --security-configuration '1858+ 'MySecurityConfig --placement-group-configs '1859+ 'InstanceRole=MASTER,PlacementStrategy=SPREAD '1860+ '--instance-groups '1861+ HA_INSTANCE_GROUPS_ARG1862)1863result = {1864'Name': DEFAULT_CLUSTER_NAME,1865'Instances': HA_INSTANCES,1866'ReleaseLabel': 'emr-5.28.0',1867'VisibleToAllUsers': True,1868'Tags': [],1869'PlacementGroupConfigs': [1870{'InstanceRole': 'MASTER', 'PlacementStrategy': 'SPREAD'}1871],1872'SecurityConfiguration': 'MySecurityConfig',1873}1874self.assert_params_for_cmd(cmd, result)18751876def test_instance_fleets_with_resize_allocation_strategy_spot_od(self):1877cmd = (1878self.prefix1879+ '--release-label emr-4.2.0 --instance-fleets '1880+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_RESIZE_ALLOCATION_STRATEGY_SPOT_AND_OD1881+ ' --ec2-attributes AvailabilityZones=[us-east-1a,us-east-1b]'1882)1883instance_fleets = CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_RESIZE_ALLOCATION_STRATEGY_SPOT_AND_OD1884result = {1885'Name': DEFAULT_CLUSTER_NAME,1886'Instances': {1887'KeepJobFlowAliveWhenNoSteps': True,1888'TerminationProtected': False,1889'InstanceFleets': instance_fleets,1890'Placement': {1891'AvailabilityZones': ['us-east-1a', 'us-east-1b']1892},1893},1894'ReleaseLabel': 'emr-4.2.0',1895'VisibleToAllUsers': True,1896'Tags': [],1897}1898self.assert_params_for_cmd(cmd, result)18991900def test_create_cluster_with_os_release_label(self):1901test_os_release_label = '2.0.20220406.1'1902cmd = (1903self.prefix1904+ '--release-label emr-6.6.0'1905+ ' --os-release-label '1906+ test_os_release_label1907+ ' --instance-groups '1908+ DEFAULT_INSTANCE_GROUPS_ARG1909)1910result = {1911'Name': DEFAULT_CLUSTER_NAME,1912'Instances': DEFAULT_INSTANCES,1913'ReleaseLabel': 'emr-6.6.0',1914'VisibleToAllUsers': True,1915'Tags': [],1916'OSReleaseLabel': test_os_release_label,1917}1918self.assert_params_for_cmd(cmd, result)19191920def test_instance_fleets_with_spot_allocation_strategy(self):1921cmd = (1922self.prefix1923+ '--release-label emr-4.2.0 --instance-fleets '1924+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_SPOT_ALLOCATION_STRATEGY1925+ ' --ec2-attributes AvailabilityZones=[us-east-1a,us-east-1b]'1926)1927result = {1928'Name': DEFAULT_CLUSTER_NAME,1929'Instances': {1930'KeepJobFlowAliveWhenNoSteps': True,1931'TerminationProtected': False,1932'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_SPOT_ALLOCATION_STRATEGY,1933'Placement': {1934'AvailabilityZones': ['us-east-1a', 'us-east-1b']1935},1936},1937'ReleaseLabel': 'emr-4.2.0',1938'VisibleToAllUsers': True,1939'Tags': [],1940}1941self.assert_params_for_cmd(cmd, result)19421943def test_instance_fleets_with_prioritized_allocation_strategy_spot_ondemand(1944self,1945):1946cmd = (1947self.prefix1948+ '--release-label emr-4.2.0 --instance-fleets '1949+ CONSTANTS_FLEET.INSTANCE_FLEETS_WITH_PRIORITIZED_ALLOCATION_STRATEGY_SPOT_AND_OD1950+ ' --ec2-attributes AvailabilityZones=[us-east-1a,us-east-1b]'1951)1952result = {1953'Name': DEFAULT_CLUSTER_NAME,1954'Instances': {1955'KeepJobFlowAliveWhenNoSteps': True,1956'TerminationProtected': False,1957'InstanceFleets': CONSTANTS_FLEET.RES_INSTANCE_FLEETS_WITH_PRIORITIZED_ALLOCATION_STRATEGY_SPOT_AND_OD,1958'Placement': {1959'AvailabilityZones': ['us-east-1a', 'us-east-1b']1960},1961},1962'ReleaseLabel': 'emr-4.2.0',1963'VisibleToAllUsers': True,1964'Tags': [],1965}1966self.assert_params_for_cmd(cmd, result)196719681969if __name__ == "__main__":1970unittest.main()197119721973