diff --git a/.changes/next-release/enhancement-ErrorMessages-78207.json b/.changes/next-release/enhancement-ErrorMessages-78207.json new file mode 100644 index 000000000000..c935f8701ac6 --- /dev/null +++ b/.changes/next-release/enhancement-ErrorMessages-78207.json @@ -0,0 +1,5 @@ +{ + "type": "enhancement", + "category": "Error Messages", + "description": "Standardize CLI error message format to use `aws: [ERROR]: ` prefix for consistency across all error types." +} diff --git a/awscli/argparser.py b/awscli/argparser.py index 104fefdb7825..dc92e1b9f988 100644 --- a/awscli/argparser.py +++ b/awscli/argparser.py @@ -14,6 +14,7 @@ import copy import sys from difflib import get_close_matches +from awscli.errorformat import format_error_message HELP_BLURB = ( "To see help text, you can run:\n" @@ -113,7 +114,7 @@ def error(self, message): should raise an exception. """ usage_message = self.format_usage() - error_message = f'{self.prog}: [ERROR]: {message}' + error_message = format_error_message(message, prog=self.prog) raise ArgParseException(f'{error_message}\n\n{usage_message}') diff --git a/awscli/customizations/configure/mfalogin.py b/awscli/customizations/configure/mfalogin.py index 885e624c45a7..638a714acf5c 100644 --- a/awscli/customizations/configure/mfalogin.py +++ b/awscli/customizations/configure/mfalogin.py @@ -24,6 +24,7 @@ from awscli.customizations.commands import BasicCommand from awscli.customizations.configure import profile_to_section from awscli.customizations.configure.writer import ConfigFileWriter +from awscli.errorformat import write_error LOG = logging.getLogger(__name__) @@ -142,7 +143,7 @@ def _get_mfa_token(self): 'None', 'mfa_token', 'MFA token code' ) if not token_code: - sys.stderr.write("MFA token code is required\n") + write_error(sys.stderr, "MFA token code is required") return None return token_code @@ -156,7 +157,7 @@ def _call_sts_get_session_token(self, sts_client, duration_seconds, mfa_serial, ) return response except ClientError as e: - sys.stderr.write(f"An error occurred: {e}\n") + write_error(sys.stderr, f"An error occurred: {e}") return None def _resolve_mfa_serial(self, parsed_args, source_config): @@ -167,7 +168,7 @@ def _resolve_mfa_serial(self, parsed_args, source_config): 'None', 'mfa_serial', 'MFA serial number or ARN' ) if not mfa_serial: - sys.stderr.write("MFA serial number or MFA device ARN is required\n") + write_error(sys.stderr, "MFA serial number or MFA device ARN is required") return None return mfa_serial @@ -252,7 +253,7 @@ def _handle_interactive_prompting(self, parsed_args, duration_seconds): 'None', config_name, prompt_text ) if not value or value == 'None': - sys.stderr.write(f"{prompt_text} is required\n") + write_error(sys.stderr, f"{prompt_text} is required") return 1 values[config_name] = value diff --git a/awscli/customizations/ecs/exceptions.py b/awscli/customizations/ecs/exceptions.py index 4ee66a51290c..f5694555f27d 100644 --- a/awscli/customizations/ecs/exceptions.py +++ b/awscli/customizations/ecs/exceptions.py @@ -24,26 +24,26 @@ def __init__(self, **kwargs): class MissingPropertyError(ECSError): - fmt = "Error: Resource '{resource}' must include property '{prop_name}'" + fmt = "Resource '{resource}' must include property '{prop_name}'" class FileLoadError(ECSError): - fmt = "Error: Unable to load file at {file_path}: {error}" + fmt = "Unable to load file at {file_path}: {error}" class InvalidPlatformError(ECSError): - fmt = "Error: {resource} '{name}' must support 'ECS' compute platform" + fmt = "{resource} '{name}' must support 'ECS' compute platform" class InvalidProperyError(ECSError): fmt = ( - "Error: deployment group '{dg_name}' does not target " + "deployment group '{dg_name}' does not target " "ECS {resource} '{resource_name}'" ) class InvalidServiceError(ECSError): - fmt = "Error: Service '{service}' not found in cluster '{cluster}'" + fmt = "Service '{service}' not found in cluster '{cluster}'" class ServiceClientError(ECSError): diff --git a/awscli/customizations/emr/applicationutils.py b/awscli/customizations/emr/applicationutils.py index 4072fc4126c8..b32563bec024 100644 --- a/awscli/customizations/emr/applicationutils.py +++ b/awscli/customizations/emr/applicationutils.py @@ -62,7 +62,7 @@ def build_applications(region, parsed_applications, ami_version=None): ) else: raise ParamValidationError( - 'aws: error: AMI version %s is not ' + 'AMI version %s is not ' 'compatible with HBase.' % ami_version ) elif app_name == constants.IMPALA: diff --git a/awscli/customizations/emr/createcluster.py b/awscli/customizations/emr/createcluster.py index 4075c85a6303..a55bc5baf939 100644 --- a/awscli/customizations/emr/createcluster.py +++ b/awscli/customizations/emr/createcluster.py @@ -293,7 +293,7 @@ def _run_main_command(self, parsed_args, parsed_globals): ) except ValueError: raise ParamValidationError( - 'aws: error: invalid json argument for ' + 'invalid json argument for ' 'option --configurations' ) @@ -697,7 +697,7 @@ def _build_bootstrap_actions(self, cluster, parsed_boostrap_actions): > constants.MAX_BOOTSTRAP_ACTION_NUMBER ): raise ParamValidationError( - 'aws: error: maximum number of ' + 'maximum number of ' 'bootstrap actions for a cluster exceeded.' ) diff --git a/awscli/customizations/emr/emrutils.py b/awscli/customizations/emr/emrutils.py index ce005ce3304e..e2a4048a8700 100644 --- a/awscli/customizations/emr/emrutils.py +++ b/awscli/customizations/emr/emrutils.py @@ -60,7 +60,7 @@ def apply_boolean_options( ): if true_option and false_option: error_message = ( - 'aws: error: cannot use both ' + 'cannot use both ' + true_option_name + ' and ' + false_option_name diff --git a/awscli/customizations/emr/exceptions.py b/awscli/customizations/emr/exceptions.py index d1559886a498..7b3714a1de48 100644 --- a/awscli/customizations/emr/exceptions.py +++ b/awscli/customizations/emr/exceptions.py @@ -41,7 +41,7 @@ class MissingParametersError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: The following required parameters are missing for ' + 'The following required parameters are missing for ' '{object_name}: {missing}.' ) @@ -53,7 +53,7 @@ class EmptyListError(EmrError, ParamValidationError): :ivar param: The provided list parameter """ - fmt = 'aws: error: The prameter {param} cannot be an empty list.' + fmt = 'The prameter {param} cannot be an empty list.' class MissingRequiredInstanceGroupsError(EmrError, ParamValidationError): @@ -63,7 +63,7 @@ class MissingRequiredInstanceGroupsError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: Must specify either --instance-groups or ' + 'Must specify either --instance-groups or ' '--instance-type with --instance-count(optional) to ' 'configure instance groups.' ) @@ -77,7 +77,7 @@ class InstanceGroupsValidationError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: You may not specify --instance-type ' + 'You may not specify --instance-type ' 'or --instance-count with --instance-groups, ' 'because --instance-type and --instance-count are ' 'shortcut options for --instance-groups.' @@ -91,7 +91,7 @@ class InvalidAmiVersionError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: The supplied AMI version "{ami_version}" is invalid.' + 'The supplied AMI version "{ami_version}" is invalid.' ' Please see AMI Versions Supported in Amazon EMR in ' 'Amazon Elastic MapReduce Developer Guide: ' 'http://docs.aws.amazon.com/ElasticMapReduce/' @@ -108,7 +108,7 @@ class MissingBooleanOptionsError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: Must specify one of the following boolean options: ' + 'Must specify one of the following boolean options: ' '{true_option}|{false_option}.' ) @@ -120,7 +120,7 @@ class UnknownStepTypeError(EmrError, ParamValidationError): :ivar step_type: the step_type provided. """ - fmt = 'aws: error: The step type {step_type} is not supported.' + fmt = 'The step type {step_type} is not supported.' class UnknownIamEndpointError(EmrError): @@ -154,7 +154,7 @@ class LogUriError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: LogUri not specified. You must specify a logUri ' + 'LogUri not specified. You must specify a logUri ' 'if you enable debugging when creating a cluster.' ) @@ -212,7 +212,7 @@ class SubnetAndAzValidationError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: You may not specify both a SubnetId and an Availabili' + 'You may not specify both a SubnetId and an Availabili' 'tyZone (placement) because ec2SubnetId implies a placement.' ) @@ -222,7 +222,7 @@ class RequiredOptionsError(EmrError, ParamValidationError): Either of option1 or option2 is required. """ - fmt = 'aws: error: Either {option1} or {option2} is required.' + fmt = 'Either {option1} or {option2} is required.' class MutualExclusiveOptionError(EmrError, ParamValidationError): @@ -236,7 +236,7 @@ class MutualExclusiveOptionError(EmrError, ParamValidationError): def __init__(self, **kwargs): msg = ( - 'aws: error: You cannot specify both ' + 'You cannot specify both ' + kwargs.get('option1', '') + ' and ' + kwargs.get('option2', '') @@ -256,7 +256,7 @@ class MissingApplicationsError(EmrError, ParamValidationError): def __init__(self, **kwargs): msg = ( - 'aws: error: Some of the steps require the following' + 'Some of the steps require the following' ' applications to be installed: ' + ', '.join(kwargs['applications']) + '. Please install the' @@ -270,7 +270,7 @@ class ClusterTerminatedError(EmrError): The cluster is terminating or has already terminated. """ - fmt = 'aws: error: Cluster terminating or already terminated.' + fmt = 'Cluster terminating or already terminated.' class ClusterStatesFilterValidationError(EmrError, ParamValidationError): @@ -282,7 +282,7 @@ class ClusterStatesFilterValidationError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: You can specify only one of the cluster state ' + 'You can specify only one of the cluster state ' 'filters: --cluster-states, --active, --terminated, --failed.' ) @@ -296,7 +296,7 @@ class MissingClusterAttributesError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: Must specify one of the following boolean options: ' + 'Must specify one of the following boolean options: ' '--visible-to-all-users|--no-visible-to-all-users, ' '--termination-protected|--no-termination-protected, ' '--auto-terminate|--no-auto-terminate, ' @@ -314,14 +314,14 @@ class InvalidEmrFsArgumentsError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: {parent_object_name} is not specified. Thus, ' + '{parent_object_name} is not specified. Thus, ' ' following parameters are invalid: {invalid}' ) class DuplicateEmrFsConfigurationError(EmrError, ParamValidationError): fmt = ( - 'aws: error: EMRFS should be configured either using ' + 'EMRFS should be configured either using ' '--configuration or --emrfs but not both' ) @@ -334,7 +334,7 @@ class UnknownCseProviderTypeError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: The client side encryption type "{provider_type}" is ' + 'The client side encryption type "{provider_type}" is ' 'not supported. You must specify either KMS or Custom' ) @@ -347,7 +347,7 @@ class UnknownEncryptionTypeError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: The encryption type "{encryption}" is invalid. ' + 'The encryption type "{encryption}" is invalid. ' 'You must specify either ServerSide or ClientSide' ) @@ -361,14 +361,14 @@ class BothSseAndEncryptionConfiguredError(EmrError, ParamValidationError): """ fmt = ( - 'aws: error: Both SSE={sse} and Encryption={encryption} are ' + 'Both SSE={sse} and Encryption={encryption} are ' 'configured for --emrfs. You must specify only one of the two.' ) class InvalidBooleanConfigError(EmrError, ParamValidationError): fmt = ( - "aws: error: {config_value} for {config_key} in the config file is " + "{config_value} for {config_key} in the config file is " "invalid. The value should be either 'True' or 'False'. Use " "'aws configure set {profile_var_name}.emr.{config_key} ' " "command to set a valid value." @@ -377,13 +377,13 @@ class InvalidBooleanConfigError(EmrError, ParamValidationError): class UnsupportedCommandWithReleaseError(EmrError, ParamValidationError): fmt = ( - "aws: error: {command} is not supported with " + "{command} is not supported with " "'{release_label}' release." ) class MissingAutoScalingRoleError(EmrError, ParamValidationError): fmt = ( - "aws: error: Must specify --auto-scaling-role when configuring an " + "Must specify --auto-scaling-role when configuring an " "AutoScaling policy for an instance group." ) diff --git a/awscli/customizations/emr/hbase.py b/awscli/customizations/emr/hbase.py index 5963b6070afb..105993b5e28a 100644 --- a/awscli/customizations/emr/hbase.py +++ b/awscli/customizations/emr/hbase.py @@ -129,7 +129,7 @@ def _check_type(self, type): type = type.lower() if type != constants.FULL and type != constants.INCREMENTAL: raise ParamValidationError( - 'aws: error: invalid type. ' + 'invalid type. ' 'type should be either ' + constants.FULL + ' or ' @@ -145,7 +145,7 @@ def _check_unit(self, unit): and unit != constants.DAYS ): raise ParamValidationError( - 'aws: error: invalid unit. unit should be one of' + 'invalid unit. unit should be one of' ' the following values: ' + constants.MINUTES + ', ' diff --git a/awscli/customizations/emr/installapplications.py b/awscli/customizations/emr/installapplications.py index 6212a6b14c99..c24cb63acc2c 100644 --- a/awscli/customizations/emr/installapplications.py +++ b/awscli/customizations/emr/installapplications.py @@ -67,13 +67,13 @@ def _check_for_supported_apps(self, parsed_applications): if app_name in constants.APPLICATIONS: if app_name not in self.supported_apps: raise ParamValidationError( - "aws: error: " + app_config['Name'] + " cannot be" + app_config['Name'] + " cannot be" " installed on a running cluster. 'Name' should be one" " of the following: " + ', '.join(self.supported_apps) ) else: raise ParamValidationError( - "aws: error: Unknown application: " + "Unknown application: " + app_config['Name'] + ". 'Name' should be one of the following: " + ', '.join(constants.APPLICATIONS) diff --git a/awscli/errorformat.py b/awscli/errorformat.py new file mode 100644 index 000000000000..3f7e01429df9 --- /dev/null +++ b/awscli/errorformat.py @@ -0,0 +1,41 @@ +# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +""" +Error message formatting module for AWS CLI. + +This module provides centralized error formatting functionality to ensure +all error messages follow the standard format: aws: [ERROR]: + +This standardization improves accessibility for users with visual disabilities +and those using assistive technologies like screen readers. +""" + +# Standard error prefix format for all AWS CLI error messages +ERROR_PREFIX = "aws: [ERROR]:" + + +def format_error_message(message, prog="aws"): + if not message: + return f"{prog}: [ERROR]:" + + message = message.strip() + + return f"{prog}: [ERROR]: {message}" + + +def write_error(stderr, message): + formatted_message = format_error_message(message) + stderr.write("\n") + stderr.write(formatted_message) + stderr.write("\n") diff --git a/awscli/errorhandler.py b/awscli/errorhandler.py index 51d1c31f9514..9f1c2b8862c4 100644 --- a/awscli/errorhandler.py +++ b/awscli/errorhandler.py @@ -37,6 +37,7 @@ ParamValidationError, ) from awscli.utils import PagerInitializationException +from awscli.errorformat import write_error LOG = logging.getLogger(__name__) @@ -82,9 +83,8 @@ def handle_exception(self, exception, stdout, stderr): return return_val def _do_handle_exception(self, exception, stdout, stderr): - stderr.write("\n") - stderr.write(self.MESSAGE % exception) - stderr.write("\n") + message = self.MESSAGE % exception + write_error(stderr, message) return self.RC @@ -145,8 +145,8 @@ class UnknownArgumentErrorHandler(FilteredExceptionHandler): def _do_handle_exception(self, exception, stdout, stderr): stderr.write("\n") - stderr.write(f'usage: {USAGE}\n{exception}\n') - stderr.write("\n") + stderr.write(f'usage: {USAGE}\n') + write_error(stderr, str(exception)) return self.RC diff --git a/tests/functional/ecs/test_deploy.py b/tests/functional/ecs/test_deploy.py index 9874ba6055e6..fe597f6235e1 100644 --- a/tests/functional/ecs/test_deploy.py +++ b/tests/functional/ecs/test_deploy.py @@ -501,7 +501,7 @@ def test_deploy_error_missing_appspec_property(self): ) expected_stderr = ( - "\nError: Resource 'properties' must " + "\naws: [ERROR]: Resource 'properties' must " "include property 'taskDefinition'\n" ) @@ -573,7 +573,7 @@ def test_deploy_error_invalid_platform(self): ] expected_stderr = ( - "\nError: Application '" + "\naws: [ERROR]: Application '" + self.application_name + "' must support 'ECS' compute platform\n" ) diff --git a/tests/functional/history/test_list.py b/tests/functional/history/test_list.py index 6391d5791bac..18b87f036ade 100644 --- a/tests/functional/history/test_list.py +++ b/tests/functional/history/test_list.py @@ -45,7 +45,7 @@ def test_show_nothing_when_no_history(self): 'to the config file.' ) self.assertEqual('', ensure_text_type(out)) - self.assertEqual('\n%s\n' % error_message, ensure_text_type(err)) + self.assertEqual('\naws: [ERROR]: %s\n' % error_message, ensure_text_type(err)) def test_show_one_call_present(self): self.parsed_responses = [ diff --git a/tests/functional/s3/test_mv_command.py b/tests/functional/s3/test_mv_command.py index 17ce7a5aa1f8..91eb11c85a2c 100644 --- a/tests/functional/s3/test_mv_command.py +++ b/tests/functional/s3/test_mv_command.py @@ -525,7 +525,7 @@ def test_get_mrap_buckets_raises_if_alias_not_found(self): ] stderr = self.run_cmd(cmdline, expected_rc=252)[1] self.assertEqual( - "\nCouldn't find multi-region access point with alias foobar.mrap " + "\naws: [ERROR]: Couldn't find multi-region access point with alias foobar.mrap " "in account 123456789012\n", stderr, ) diff --git a/tests/unit/customizations/configure/test_mfalogin.py b/tests/unit/customizations/configure/test_mfalogin.py index 1c6ab7ba9b18..a91b809f2a0e 100644 --- a/tests/unit/customizations/configure/test_mfalogin.py +++ b/tests/unit/customizations/configure/test_mfalogin.py @@ -166,9 +166,8 @@ def test_no_mfa_serial_provided(self): self.parsed_args, self.parsed_globals ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - "MFA serial number or MFA device ARN is required\n" - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]: MFA serial number or MFA device ARN is required", all_writes) def test_no_token_code_provided(self): # Mock botocore.session.Session @@ -188,9 +187,8 @@ def test_no_token_code_provided(self): self.parsed_args, self.parsed_globals ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - "MFA token code is required\n" - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]: MFA token code is required", all_writes) def test_sts_client_error(self): self.session.get_scoped_config.return_value = {} @@ -218,9 +216,9 @@ def test_sts_client_error(self): self.parsed_args, self.parsed_globals ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - mock.ANY - ) # Just check it was called + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]:", all_writes) + self.assertIn("An error occurred", all_writes) def test_successful_mfa_login(self): # Setup @@ -448,9 +446,8 @@ def test_handle_missing_default_profile_missing_access_key(self): ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - "AWS Access Key ID is required\n" - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]: AWS Access Key ID is required", all_writes) def test_handle_missing_default_profile_missing_secret_key(self): """Test error when secret key is not provided.""" @@ -465,9 +462,8 @@ def test_handle_missing_default_profile_missing_secret_key(self): ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - "AWS Secret Access Key is required\n" - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]: AWS Secret Access Key is required", all_writes) def test_credential_value_prompting_clean_display(self): """Test that credential prompting doesn't show default values.""" @@ -515,11 +511,9 @@ def test_handle_missing_default_profile_sts_error(self): ) self.assertEqual(rc, 1) - # Verify error message was written - mock_stderr.write.assert_called() - self.assertIn( - 'An error occurred', str(mock_stderr.write.call_args) - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]:", all_writes) + self.assertIn("An error occurred", all_writes) def test_non_interactive_missing_mfa_serial(self): """Test non-interactive mode when MFA serial is missing.""" @@ -539,9 +533,8 @@ def test_non_interactive_missing_mfa_serial(self): ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - "MFA serial number or MFA device ARN is required\n" - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]: MFA serial number or MFA device ARN is required", all_writes) def test_non_interactive_missing_token_code(self): """Test non-interactive mode when token code would be prompted.""" @@ -559,9 +552,8 @@ def test_non_interactive_missing_token_code(self): ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - "MFA token code is required\n" - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]: MFA token code is required", all_writes) def test_empty_credential_input_handling(self): """Test handling of empty credential inputs.""" @@ -573,6 +565,5 @@ def test_empty_credential_input_handling(self): ) self.assertEqual(rc, 1) - mock_stderr.write.assert_called_with( - "AWS Access Key ID is required\n" - ) + all_writes = ''.join(str(call) for call in mock_stderr.write.call_args_list) + self.assertIn("aws: [ERROR]: AWS Access Key ID is required", all_writes) \ No newline at end of file diff --git a/tests/unit/customizations/emr/__init__.py b/tests/unit/customizations/emr/__init__.py index bd22f2a01026..635d69227c0e 100644 --- a/tests/unit/customizations/emr/__init__.py +++ b/tests/unit/customizations/emr/__init__.py @@ -42,6 +42,6 @@ def assert_error_msg( self, cmd, exception_class_name, error_msg_kwargs={}, rc=255 ): exception_class = getattr(exceptions, exception_class_name) - error_msg = "\n%s\n" % exception_class.fmt.format(**error_msg_kwargs) + error_msg = "\naws: [ERROR]: %s\n" % exception_class.fmt.format(**error_msg_kwargs) result = self.run_cmd(cmd, rc) self.assertEqual(error_msg, result[1]) diff --git a/tests/unit/customizations/emr/test_add_steps.py b/tests/unit/customizations/emr/test_add_steps.py index ea2edde91f6d..d34f494530d8 100644 --- a/tests/unit/customizations/emr/test_add_steps.py +++ b/tests/unit/customizations/emr/test_add_steps.py @@ -188,7 +188,7 @@ class TestAddSteps(BaseAWSCommandParamsTest): def test_unknown_step_type(self): cmd = self.prefix + 'Type=unknown' expected_error_msg = ( - '\naws: error: ' + 'The step type unknown is not supported.\n' + '\naws: [ERROR]: ' + 'The step type unknown is not supported.\n' ) self.assert_error_for_ami_and_release_based_clusters( cmd=cmd, @@ -218,7 +218,7 @@ def test_default_step_type_name_action_on_failure(self): def test_custom_jar_step_missing_jar(self): cmd = self.prefix + 'Name=CustomJarMissingJar' expected_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for CustomJARStepConfig: Jar.\n' ) self.assert_error_for_ami_and_release_based_clusters( @@ -420,7 +420,7 @@ def test_step_with_execution_role_arn(self): def test_streaming_step_missing_args(self): cmd = self.prefix + 'Type=Streaming' expected_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for StreamingStepConfig: Args.\n' ) self.assert_error_for_ami_and_release_based_clusters( @@ -602,7 +602,7 @@ def test_hive_step_with_default_fields(self): def test_hive_step_missing_args(self): cmd = self.prefix + 'Type=Hive' expected_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for HiveStepConfig: Args.\n' ) @@ -781,7 +781,7 @@ def test_pig_step_with_default_fields(self): def test_pig_missing_args(self): cmd = self.prefix + 'Type=Pig' expected_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for PigStepConfig: Args.\n' ) self.assert_error_for_ami_and_release_based_clusters( @@ -973,7 +973,7 @@ def test_SPARK_SUBMIT_SCRIPT_RUNNER_STEP(self): def test_spark_missing_arg(self): cmd = self.prefix + 'Type=SPARK' expected_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for SparkStepConfig: Args.\n' ) self.assert_error_for_ami_and_release_based_clusters( @@ -1114,7 +1114,7 @@ def test_spark_step_with_step_monitoring_configuration_no_log_uri_or_encryption_ def test_impala_missing_args(self): cmd = self.prefix + 'Type=Impala' expected_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for ImpalaStepConfig: Args.\n' ) self.assert_error_for_ami_and_release_based_clusters( @@ -1249,7 +1249,7 @@ def test_impala_step_with_release(self): test_step_config = 'Type=Impala,' + self.IMPALA_BASIC_ARGS cmd = self.prefix + test_step_config expected_result_release = ( - '\naws: error: The step type impala ' + 'is not supported.\n' + '\naws: [ERROR]: The step type impala ' + 'is not supported.\n' ) self.assert_error_for_ami_and_release_based_clusters( @@ -1261,7 +1261,7 @@ def test_impala_step_with_release(self): def test_empty_step_args(self): cmd = self.prefix + 'Type=Streaming,Args=' expected_error_msg = ( - '\naws: error: The prameter Args cannot ' 'be an empty list.\n' + '\naws: [ERROR]: The prameter Args cannot ' 'be an empty list.\n' ) self.assert_error_for_ami_and_release_based_clusters( cmd=cmd, @@ -1285,7 +1285,7 @@ def test_empty_step_args(self): cmd = self.prefix + 'Args=' expected_error_msg = ( - '\naws: error: The following required parameters' + '\naws: [ERROR]: The following required parameters' ' are missing for CustomJARStepConfig: Jar.\n' ) self.assert_error_for_ami_and_release_based_clusters( diff --git a/tests/unit/customizations/emr/test_config.py b/tests/unit/customizations/emr/test_config.py index 1574e0fcedd9..921e5949e85a 100644 --- a/tests/unit/customizations/emr/test_config.py +++ b/tests/unit/customizations/emr/test_config.py @@ -91,7 +91,7 @@ def test_with_bad_configs(self, mock_run_main_command): def test_with_bad_boolean_value(self): self.set_configs(BAD_BOOLEAN_VALUE_CONFIGS) cmd = CREATE_CLUSTER_CMD - expect_error_msg = "\n%s\n" % InvalidBooleanConfigError.fmt.format( + expect_error_msg = "\naws: [ERROR]: %s\n" % InvalidBooleanConfigError.fmt.format( config_value='False1', config_key='enable_debugging', profile_var_name='default', diff --git a/tests/unit/customizations/emr/test_create_cluster_ami_version.py b/tests/unit/customizations/emr/test_create_cluster_ami_version.py index e97b48393ea2..555ac052dcca 100644 --- a/tests/unit/customizations/emr/test_create_cluster_ami_version.py +++ b/tests/unit/customizations/emr/test_create_cluster_ami_version.py @@ -440,7 +440,7 @@ def test_mutual_exclusive_use_default_roles_and_service_role(self): + '--ec2-attributes InstanceProfile=Ec2_InstanceProfile' ) expected_error_msg = ( - '\naws: error: You cannot specify both --use-default-roles ' + '\naws: [ERROR]: You cannot specify both --use-default-roles ' 'and --ec2-attributes InstanceProfile options together. Either ' 'choose --use-default-roles or use both --service-role ' ' and --ec2-attributes InstanceProfile=.\n' @@ -454,7 +454,7 @@ def test_mutual_exclusive_use_default_roles_and_instance_profile(self): '--ec2-attributes InstanceProfile=Ec2_InstanceProfile' ) expected_error_msg = ( - '\naws: error: You cannot specify both --use-default-roles ' + '\naws: [ERROR]: You cannot specify both --use-default-roles ' 'and --service-role options together. Either choose ' '--use-default-roles or use both --service-role ' 'and --ec2-attributes InstanceProfile=.\n' @@ -512,7 +512,7 @@ def test_auto_terminate_and_no_auto_terminate(self): + '--auto-terminate --no-auto-terminate' ) expected_error_msg = ( - '\naws: error: cannot use both --no-auto-terminate and' + '\naws: [ERROR]: cannot use both --no-auto-terminate and' ' --auto-terminate options together.\n' ) result = self.run_cmd(cmd, 252) @@ -535,7 +535,7 @@ def test_termination_protected_and_no_termination_protected(self): DEFAULT_CMD + '--termination-protected --no-termination-protected' ) expected_error_msg = ( - '\naws: error: cannot use both --termination-protected' + '\naws: [ERROR]: cannot use both --termination-protected' ' and --no-termination-protected options together.\n' ) result = self.run_cmd(cmd, 252) @@ -565,7 +565,7 @@ def test_unhealthy_node_replacement_and_no_unhealthy_node_replacement( + '--unhealthy-node-replacement --no-unhealthy-node-replacement' ) expected_error_msg = ( - '\naws: error: cannot use both --unhealthy-node-replacement' + '\naws: [ERROR]: cannot use both --unhealthy-node-replacement' ' and --no-unhealthy-node-replacement options together.\n' ) result = self.run_cmd(cmd, 252) @@ -584,7 +584,7 @@ def test_no_visible_to_all_users(self): def test_visible_to_all_users_and_no_visible_to_all_users(self): cmd = DEFAULT_CMD + '--visible-to-all-users --no-visible-to-all-users' expected_error_msg = ( - '\naws: error: cannot use both --visible-to-all-users and ' + '\naws: [ERROR]: cannot use both --visible-to-all-users and ' '--no-visible-to-all-users options together.\n' ) result = self.run_cmd(cmd, 252) @@ -605,7 +605,7 @@ def test_no_extended_support(self): def test_extended_support_and_no_extended_support(self): cmd = DEFAULT_CMD + '--extended-support --no-extended-support' expected_error_msg = ( - '\naws: error: cannot use both --extended-support' + '\naws: [ERROR]: cannot use both --extended-support' ' and --no-extended-support options together.\n' ) result = self.run_cmd(cmd, 252) @@ -670,7 +670,7 @@ def test_enable_debugging(self): def test_enable_debugging_no_log_uri(self): cmd = DEFAULT_CMD + '--enable-debugging' expected_error_msg = ( - '\naws: error: LogUri not specified. You must specify a logUri' + '\naws: [ERROR]: LogUri not specified. You must specify a logUri' ' if you enable debugging when creating a cluster.\n' ) result = self.run_cmd(cmd, 252) @@ -683,7 +683,7 @@ def test_enable_debugging_and_no_enable_debugging(self): + ' --log-uri s3://test/logs' ) expected_error_msg = ( - '\naws: error: cannot use both --enable-debugging and ' + '\naws: [ERROR]: cannot use both --enable-debugging and ' '--no-enable-debugging options together.\n' ) result = self.run_cmd(cmd, 252) @@ -760,7 +760,7 @@ def test_instance_groups_instance_type_and_count(self): def test_instance_groups_missing_required_parameter_error(self): cmd = 'emr create-cluster --use-default-roles --ami-version 3.0.4 ' expect_error_msg = ( - '\naws: error: Must specify either --instance-groups or ' + '\naws: [ERROR]: Must specify either --instance-groups or ' '--instance-type with --instance-count(optional) to ' 'configure instance groups.\n' ) @@ -772,7 +772,7 @@ def test_instance_groups_missing_required_parameter_error(self): '--instance-count 2' ) expect_error_msg = ( - '\naws: error: Must specify either --instance-groups or ' + '\naws: [ERROR]: Must specify either --instance-groups or ' '--instance-type with --instance-count(optional) to ' 'configure instance groups.\n' ) @@ -786,7 +786,7 @@ def test_instance_groups_exclusive_parameter_validation_error(self): + DEFAULT_INSTANCE_GROUPS_ARG ) expect_error_msg = ( - '\naws: error: You may not specify --instance-type ' + '\naws: [ERROR]: You may not specify --instance-type ' 'or --instance-count with --instance-groups, ' 'because --instance-type and --instance-count are ' 'shortcut options for --instance-groups.\n' @@ -800,7 +800,7 @@ def test_instance_groups_exclusive_parameter_validation_error(self): '--instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG ) expect_error_msg = ( - '\naws: error: You may not specify --instance-type ' + '\naws: [ERROR]: You may not specify --instance-type ' 'or --instance-count with --instance-groups, ' 'because --instance-type and --instance-count are ' 'shortcut options for --instance-groups.\n' @@ -938,7 +938,7 @@ def test_ec2_attributes_subnet_az_error(self): + 'SubnetId=subnet-123456,AvailabilityZone=us-east-1a' ) expect_error_msg = ( - '\naws: error: You may not specify both a SubnetId and an Availab' + '\naws: [ERROR]: You may not specify both a SubnetId and an Availab' 'ilityZone (placement) because ec2SubnetId implies a placement.\n' ) result = self.run_cmd(cmd, 252) @@ -1004,7 +1004,7 @@ def test_bootstrap_actions_exceed_maximum_error(self): cmd += ba_cmd expected_error_msg = ( - '\naws: error: maximum number of ' + '\naws: [ERROR]: maximum number of ' + 'bootstrap actions for a cluster exceeded.\n' ) result = self.run_cmd(cmd, 252) @@ -1021,7 +1021,7 @@ def test_bootstrap_actions_exceed_maximum_with_applications_error(self): for i in range(1, 15): cmd += ba_cmd expected_error_msg = ( - '\naws: error: maximum number of ' + '\naws: [ERROR]: maximum number of ' + 'bootstrap actions for a cluster exceeded.\n' ) result = self.run_cmd(cmd, 252) @@ -1194,7 +1194,7 @@ def test_applications_all_types_from_json_file(self): def test_wrong_step_type_error(self): cmd = DEFAULT_CMD + '--steps Type=unknown' expected_error_msg = ( - '\naws: error: The step type unknown is not supported.\n' + '\naws: [ERROR]: The step type unknown is not supported.\n' ) result = self.run_cmd(cmd, 252) self.assertEqual(expected_error_msg, result[1]) @@ -1208,7 +1208,7 @@ def test_default_step_type_name_action_on_failure(self): def test_custom_jar_step_missing_jar(self): cmd = DEFAULT_CMD + '--steps Name=CustomJarMissingJar' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for CustomJARStepConfig: Jar.\n' ) result = self.run_cmd(cmd, 252) @@ -1255,7 +1255,7 @@ def test_streaming_step_with_default_fields(self): def test_streaming_step_missing_args(self): cmd = DEFAULT_CMD + '--steps Type=Streaming' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for StreamingStepConfig: Args.\n' ) result = self.run_cmd(cmd, 252) @@ -1288,7 +1288,7 @@ def test_hive_step_with_default_fields(self): def test_hive_step_missing_args(self): cmd = DEFAULT_CMD + '--applications Name=Hive --steps Type=Hive' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for HiveStepConfig: Args.\n' ) result = self.run_cmd(cmd, 252) @@ -1318,7 +1318,7 @@ def test_pig_step_with_default_fields(self): def test_pig_missing_args(self): cmd = DEFAULT_CMD + '--applications Name=Pig --steps Type=Pig' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for PigStepConfig: Args.\n' ) result = self.run_cmd(cmd, 252) @@ -1351,7 +1351,7 @@ def test_impala_step_with_default_fields(self): def test_impala_missing_args(self): cmd = DEFAULT_CMD + '--applications Name=Impala --steps Type=Impala' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for ImpalaStepConfig: Args.\n' ) result = self.run_cmd(cmd, 252) @@ -1412,7 +1412,7 @@ def test_restore_from_hbase(self): def test_empty_step_args(self): cmd = DEFAULT_CMD + '--steps Type=Streaming,Args= ' expect_error_msg = ( - '\naws: error: The prameter Args cannot ' 'be an empty list.\n' + '\naws: [ERROR]: The prameter Args cannot ' 'be an empty list.\n' ) result = self.run_cmd(cmd, 252) self.assertEqual(expect_error_msg, result[1]) @@ -1427,7 +1427,7 @@ def test_empty_step_args(self): cmd = DEFAULT_CMD + '--steps Args= ' expect_error_msg = ( - '\naws: error: The following required parameters ' + '\naws: [ERROR]: The following required parameters ' 'are missing for CustomJARStepConfig: Jar.\n' ) result = self.run_cmd(cmd, 252) @@ -1451,12 +1451,12 @@ def test_missing_applications_for_steps(self): ) expected_error_msg1 = ( - '\naws: error: Some of the steps require the following' + '\naws: [ERROR]: Some of the steps require the following' ' applications to be installed: Impala, Pig. ' 'Please install the applications using --applications.\n' ) expected_error_msg2 = ( - '\naws: error: Some of the steps require the following' + '\naws: [ERROR]: Some of the steps require the following' ' applications to be installed: Pig, Impala. ' 'Please install the applications using --applications.\n' ) @@ -1485,12 +1485,12 @@ def test_missing_applications_with_hbase(self): ) expected_error_msg1 = ( - '\naws: error: Some of the steps require the following' + '\naws: [ERROR]: Some of the steps require the following' ' applications to be installed: Hbase, Impala. ' 'Please install the applications using --applications.\n' ) expected_error_msg2 = ( - '\naws: error: Some of the steps require the following' + '\naws: [ERROR]: Some of the steps require the following' ' applications to be installed: Impala, Hbase. ' 'Please install the applications using --applications.\n' ) @@ -1632,7 +1632,7 @@ def test_instance_group_with_autoscaling_policy_missing_autoscaling_role( + CONSTANTS.INSTANCE_GROUPS_WITH_AUTOSCALING_POLICY_ARG ) expected_error_msg = ( - '\naws: error: Must specify --auto-scaling-role when' + '\naws: [ERROR]: Must specify --auto-scaling-role when' ' configuring an AutoScaling policy for an instance group.\n' ) result = self.run_cmd(cmd, 252) @@ -1990,7 +1990,7 @@ def test_instance_fleets_with_both_az_azs_specified(self): + ' --ec2-attributes AvailabilityZone=us-east-1a,AvailabilityZones=[us-east-1a,us-east-1b]' ) expected_error_msg = ( - '\naws: error: You cannot specify both AvailabilityZone' + '\naws: [ERROR]: You cannot specify both AvailabilityZone' ' and AvailabilityZones options together.\n' ) result = self.run_cmd(cmd, 252) diff --git a/tests/unit/customizations/emr/test_create_cluster_release_label.py b/tests/unit/customizations/emr/test_create_cluster_release_label.py index df45de1b04fd..2d987384dfd2 100644 --- a/tests/unit/customizations/emr/test_create_cluster_release_label.py +++ b/tests/unit/customizations/emr/test_create_cluster_release_label.py @@ -289,7 +289,7 @@ def test_ami_version_release_label_exclusive_validation(self): 'emr-4.0.0 --instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG ) expected_error_msg = ( - '\naws: error: You cannot specify both --ami-version' + '\naws: [ERROR]: You cannot specify both --ami-version' ' and --release-label options together.\n' ) result = self.run_cmd(cmd, 252) @@ -298,7 +298,7 @@ def test_ami_version_release_label_exclusive_validation(self): def test_if_ami_version_or_release_label_is_provided(self): cmd = self.prefix + ' --instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG expected_error_msg = ( - '\naws: error: Either --ami-version or' + '\naws: [ERROR]: Either --ami-version or' ' --release-label is required.\n' ) result = self.run_cmd(cmd, 252) @@ -406,7 +406,7 @@ def test_mutual_exclusive_use_default_roles_and_service_role(self): + '--ec2-attributes InstanceProfile=Ec2_InstanceProfile' ) expected_error_msg = ( - '\naws: error: You cannot specify both --use-default-roles ' + '\naws: [ERROR]: You cannot specify both --use-default-roles ' 'and --ec2-attributes InstanceProfile options together. Either ' 'choose --use-default-roles or use both --service-role ' ' and --ec2-attributes InstanceProfile=.\n' @@ -420,7 +420,7 @@ def test_mutual_exclusive_use_default_roles_and_instance_profile(self): '--ec2-attributes InstanceProfile=Ec2_InstanceProfile' ) expected_error_msg = ( - '\naws: error: You cannot specify both --use-default-roles ' + '\naws: [ERROR]: You cannot specify both --use-default-roles ' 'and --service-role options together. Either choose ' '--use-default-roles or use both --service-role ' 'and --ec2-attributes InstanceProfile=.\n' @@ -479,7 +479,7 @@ def test_auto_terminate_and_no_auto_terminate(self): + '--auto-terminate --no-auto-terminate' ) expected_error_msg = ( - '\naws: error: cannot use both --no-auto-terminate and' + '\naws: [ERROR]: cannot use both --no-auto-terminate and' ' --auto-terminate options together.\n' ) result = self.run_cmd(cmd, 252) @@ -502,7 +502,7 @@ def test_termination_protected_and_no_termination_protected(self): DEFAULT_CMD + '--termination-protected --no-termination-protected' ) expected_error_msg = ( - '\naws: error: cannot use both --termination-protected' + '\naws: [ERROR]: cannot use both --termination-protected' ' and --no-termination-protected options together.\n' ) result = self.run_cmd(cmd, 252) @@ -532,7 +532,7 @@ def test_unhealthy_node_replacement_and_no_unhealthy_node_replacement( + '--unhealthy-node-replacement --no-unhealthy-node-replacement' ) expected_error_msg = ( - '\naws: error: cannot use both --unhealthy-node-replacement' + '\naws: [ERROR]: cannot use both --unhealthy-node-replacement' ' and --no-unhealthy-node-replacement options together.\n' ) result = self.run_cmd(cmd, 252) @@ -551,7 +551,7 @@ def test_no_visible_to_all_users(self): def test_visible_to_all_users_and_no_visible_to_all_users(self): cmd = DEFAULT_CMD + '--visible-to-all-users --no-visible-to-all-users' expected_error_msg = ( - '\naws: error: cannot use both --visible-to-all-users and ' + '\naws: [ERROR]: cannot use both --visible-to-all-users and ' '--no-visible-to-all-users options together.\n' ) result = self.run_cmd(cmd, 252) @@ -572,7 +572,7 @@ def test_no_extended_support(self): def test_extended_support_and_no_extended_support(self): cmd = DEFAULT_CMD + '--extended-support --no-extended-support' expected_error_msg = ( - '\naws: error: cannot use both --extended-support' + '\naws: [ERROR]: cannot use both --extended-support' ' and --no-extended-support options together.\n' ) result = self.run_cmd(cmd, 252) @@ -625,7 +625,7 @@ def test_enable_debugging(self): def test_enable_debugging_no_log_uri(self): cmd = DEFAULT_CMD + '--enable-debugging' expected_error_msg = ( - '\naws: error: LogUri not specified. You must specify a logUri' + '\naws: [ERROR]: LogUri not specified. You must specify a logUri' ' if you enable debugging when creating a cluster.\n' ) result = self.run_cmd(cmd, 252) @@ -638,7 +638,7 @@ def test_enable_debugging_and_no_enable_debugging(self): + ' --log-uri s3://test/logs' ) expected_error_msg = ( - '\naws: error: cannot use both --enable-debugging and ' + '\naws: [ERROR]: cannot use both --enable-debugging and ' '--no-enable-debugging options together.\n' ) result = self.run_cmd(cmd, 252) @@ -718,7 +718,7 @@ def test_instance_groups_missing_required_parameter_error(self): ' emr-4.0.0 ' ) expect_error_msg = ( - '\naws: error: Must specify either --instance-groups or ' + '\naws: [ERROR]: Must specify either --instance-groups or ' '--instance-type with --instance-count(optional) to ' 'configure instance groups.\n' ) @@ -730,7 +730,7 @@ def test_instance_groups_missing_required_parameter_error(self): '--instance-count 2' ) expect_error_msg = ( - '\naws: error: Must specify either --instance-groups or ' + '\naws: [ERROR]: Must specify either --instance-groups or ' '--instance-type with --instance-count(optional) to ' 'configure instance groups.\n' ) @@ -744,7 +744,7 @@ def test_instance_groups_exclusive_parameter_validation_error(self): + DEFAULT_INSTANCE_GROUPS_ARG ) expect_error_msg = ( - '\naws: error: You may not specify --instance-type ' + '\naws: [ERROR]: You may not specify --instance-type ' 'or --instance-count with --instance-groups, ' 'because --instance-type and --instance-count are ' 'shortcut options for --instance-groups.\n' @@ -758,7 +758,7 @@ def test_instance_groups_exclusive_parameter_validation_error(self): '--instance-groups ' + DEFAULT_INSTANCE_GROUPS_ARG ) expect_error_msg = ( - '\naws: error: You may not specify --instance-type ' + '\naws: [ERROR]: You may not specify --instance-type ' 'or --instance-count with --instance-groups, ' 'because --instance-type and --instance-count are ' 'shortcut options for --instance-groups.\n' @@ -927,7 +927,7 @@ def test_ec2_attributes_subnet_az_error(self): + 'SubnetId=subnet-123456,AvailabilityZone=us-east-1a' ) expect_error_msg = ( - '\naws: error: You may not specify both a SubnetId and an Availab' + '\naws: [ERROR]: You may not specify both a SubnetId and an Availab' 'ilityZone (placement) because ec2SubnetId implies a placement.\n' ) result = self.run_cmd(cmd, 252) @@ -993,7 +993,7 @@ def test_bootstrap_actions_exceed_maximum_error(self): cmd += ba_cmd expected_error_msg = ( - '\naws: error: maximum number of ' + '\naws: [ERROR]: maximum number of ' + 'bootstrap actions for a cluster exceeded.\n' ) result = self.run_cmd(cmd, 252) @@ -1006,7 +1006,7 @@ def test_bootstrap_actions_exceed_maximum_with_applications_error(self): for i in range(1, 20): cmd += ba_cmd expected_error_msg = ( - '\naws: error: maximum number of ' + '\naws: [ERROR]: maximum number of ' + 'bootstrap actions for a cluster exceeded.\n' ) result = self.run_cmd(cmd, 252) @@ -1057,7 +1057,7 @@ def test_bootstrap_actions_from_json_file(self): def test_wrong_step_type_error(self): cmd = DEFAULT_CMD + '--steps Type=unknown' expected_error_msg = ( - '\naws: error: The step type unknown is not supported.\n' + '\naws: [ERROR]: The step type unknown is not supported.\n' ) result = self.run_cmd(cmd, 252) self.assertEqual(expected_error_msg, result[1]) @@ -1071,7 +1071,7 @@ def test_default_step_type_name_action_on_failure(self): def test_custom_jar_step_missing_jar(self): cmd = DEFAULT_CMD + '--steps Name=CustomJarMissingJar' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for CustomJARStepConfig: Jar.\n' ) result = self.run_cmd(cmd, 252) @@ -1118,7 +1118,7 @@ def test_streaming_step_with_default_fields(self): def test_streaming_step_missing_args(self): cmd = DEFAULT_CMD + '--steps Type=Streaming' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for StreamingStepConfig: Args.\n' ) result = self.run_cmd(cmd, 252) @@ -1152,7 +1152,7 @@ def test_hive_step_with_default_fields(self): def test_hive_step_missing_args(self): cmd = DEFAULT_CMD + '--applications Name=Hive --steps Type=Hive' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for HiveStepConfig: Args.\n' ) result = self.run_cmd(cmd, 252) @@ -1183,7 +1183,7 @@ def test_pig_step_with_default_fields(self): def test_pig_missing_args(self): cmd = DEFAULT_CMD + '--applications Name=Pig --steps Type=Pig' expect_error_msg = ( - '\naws: error: The following ' + '\naws: [ERROR]: The following ' + 'required parameters are missing for PigStepConfig: Args.\n' ) result = self.run_cmd(cmd, 252) @@ -1331,7 +1331,7 @@ def test_instance_group_with_autoscaling_policy_missing_autoscaling_role( + CONSTANTS.INSTANCE_GROUPS_WITH_AUTOSCALING_POLICY_ARG ) expected_error_msg = ( - '\naws: error: Must specify --auto-scaling-role when' + '\naws: [ERROR]: Must specify --auto-scaling-role when' ' configuring an AutoScaling policy for an instance group.\n' ) result = self.run_cmd(cmd, 252) @@ -1582,7 +1582,7 @@ def test_instance_fleets_with_both_fleet_group_specified(self): + CONSTANTS.INSTANCE_GROUPS_WITH_EBS_VOLUME_ARG ) expected_error_msg = ( - '\naws: error: You cannot specify both --instance-groups' + '\naws: [ERROR]: You cannot specify both --instance-groups' ' and --instance-fleets options together.\n' ) result = self.run_cmd(cmd, 252) @@ -1596,7 +1596,7 @@ def test_instance_fleets_with_both_subnetid_subnetids_specified(self): + ' --ec2-attributes SubnetId=subnetid-1,SubnetIds=[subnetid-1,subnetid-2]' ) expected_error_msg = ( - '\naws: error: You cannot specify both SubnetId' + '\naws: [ERROR]: You cannot specify both SubnetId' ' and SubnetIds options together.\n' ) result = self.run_cmd(cmd, 252) diff --git a/tests/unit/customizations/emr/test_create_hbase_backup.py b/tests/unit/customizations/emr/test_create_hbase_backup.py index c1837ddab414..f5bcaa883b1e 100644 --- a/tests/unit/customizations/emr/test_create_hbase_backup.py +++ b/tests/unit/customizations/emr/test_create_hbase_backup.py @@ -62,7 +62,7 @@ def test_unsupported_command_on_release_based_cluster_error( args = ' --cluster-id j-ABCD --dir s3://abc/' cmdline = self.prefix + args expected_error_msg = ( - "\naws: error: create-hbase-backup" + "\naws: [ERROR]: create-hbase-backup" " is not supported with 'emr-4.0' release.\n" ) result = self.run_cmd(cmdline, 252) diff --git a/tests/unit/customizations/emr/test_disable_hbase_backup.py b/tests/unit/customizations/emr/test_disable_hbase_backup.py index 0cd4d27ddbd9..5ecd5a9b3d6f 100644 --- a/tests/unit/customizations/emr/test_disable_hbase_backup.py +++ b/tests/unit/customizations/emr/test_disable_hbase_backup.py @@ -73,7 +73,7 @@ def test_disable_hbase_backups_none(self): args = ' --cluster-id j-ABCD' cmdline = self.prefix + args expected_error_msg = ( - '\nShould specify at least one of --full' + ' and --incremental.\n' + '\naws: [ERROR]: Should specify at least one of --full' + ' and --incremental.\n' ) result = self.run_cmd(cmdline, 252) @@ -87,7 +87,7 @@ def test_unsupported_command_on_release_based_cluster_error( args = ' --cluster-id j-ABCD --full' cmdline = self.prefix + args expected_error_msg = ( - "\naws: error: disable-hbase-backups" + "\naws: [ERROR]: disable-hbase-backups" " is not supported with 'emr-4.0' release.\n" ) result = self.run_cmd(cmdline, 252) diff --git a/tests/unit/customizations/emr/test_install_applications.py b/tests/unit/customizations/emr/test_install_applications.py index 8344b3964ba1..eb623a4f7fb6 100644 --- a/tests/unit/customizations/emr/test_install_applications.py +++ b/tests/unit/customizations/emr/test_install_applications.py @@ -120,7 +120,7 @@ def test_install_impala_error(self): cmdline = self.prefix + ' Name=Impala' expected_error_msg = ( - "\naws: error: Impala cannot be installed on" + "\naws: [ERROR]: Impala cannot be installed on" + " a running cluster. 'Name' should be one of the following:" + " HIVE, PIG\n" ) @@ -131,7 +131,7 @@ def test_install_unknown_app_error(self): cmdline = self.prefix + 'Name=unknown' expected_error_msg = ( - "\naws: error: Unknown application: unknown." + "\naws: [ERROR]: Unknown application: unknown." + " 'Name' should be one of the following: HIVE, PIG, HBASE," + " GANGLIA, IMPALA, SPARK, MAPR, MAPR_M3, MAPR_M5, MAPR_M7\n" ) @@ -149,7 +149,7 @@ def test_unsupported_command_on_release_based_cluster_error( ) expected_error_msg = ( - "\naws: error: install-applications" + "\naws: [ERROR]: install-applications" " is not supported with 'emr-4.0' release.\n" ) result = self.run_cmd(cmdline, 252) diff --git a/tests/unit/customizations/emr/test_list_clusters.py b/tests/unit/customizations/emr/test_list_clusters.py index 2a0eda9ef33c..fc7ab1247a64 100644 --- a/tests/unit/customizations/emr/test_list_clusters.py +++ b/tests/unit/customizations/emr/test_list_clusters.py @@ -58,7 +58,7 @@ def test_exclusive_states_filters(self): args = '--active --failed' cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: You can specify only one of the cluster state ' + '\naws: [ERROR]: You can specify only one of the cluster state ' 'filters: --cluster-states, --active, --terminated, --failed.\n' ) result = self.run_cmd(cmdline, 252) @@ -67,7 +67,7 @@ def test_exclusive_states_filters(self): args = '--cluster-states STARTING RUNNING --terminated' cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: You can specify only one of the cluster state ' + '\naws: [ERROR]: You can specify only one of the cluster state ' 'filters: --cluster-states, --active, --terminated, --failed.\n' ) result = self.run_cmd(cmdline, 252) diff --git a/tests/unit/customizations/emr/test_modify_cluster_attributes.py b/tests/unit/customizations/emr/test_modify_cluster_attributes.py index 71dfd72ed117..98f6b5fe6771 100644 --- a/tests/unit/customizations/emr/test_modify_cluster_attributes.py +++ b/tests/unit/customizations/emr/test_modify_cluster_attributes.py @@ -85,7 +85,7 @@ def test_visible_to_all_and_no_visible_to_all(self): ) cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: You cannot specify both --visible-to-all-users ' + '\naws: [ERROR]: You cannot specify both --visible-to-all-users ' 'and --no-visible-to-all-users options together.\n' ) result = self.run_cmd(cmdline, 252) @@ -98,7 +98,7 @@ def test_temination_protected_and_no_termination_protected(self): ) cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: You cannot specify both --termination-protected ' + '\naws: [ERROR]: You cannot specify both --termination-protected ' 'and --no-termination-protected options together.\n' ) result = self.run_cmd(cmdline, 252) @@ -110,7 +110,7 @@ def test_auto_terminate_and_no_auto_terminate(self): ) cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: You cannot specify both --auto-terminate ' + '\naws: [ERROR]: You cannot specify both --auto-terminate ' 'and --no-auto-terminate options together.\n' ) result = self.run_cmd(cmdline, 252) @@ -178,7 +178,7 @@ def test_at_least_one_option(self): args = ' --cluster-id j-ABC123456' cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: Must specify one of the following boolean options: ' + '\naws: [ERROR]: Must specify one of the following boolean options: ' '--visible-to-all-users|--no-visible-to-all-users, ' '--termination-protected|--no-termination-protected, ' '--auto-terminate|--no-auto-terminate, ' diff --git a/tests/unit/customizations/emr/test_restore_from_hbase_backup.py b/tests/unit/customizations/emr/test_restore_from_hbase_backup.py index 2956ad1d963a..feb00ee3b39e 100644 --- a/tests/unit/customizations/emr/test_restore_from_hbase_backup.py +++ b/tests/unit/customizations/emr/test_restore_from_hbase_backup.py @@ -63,7 +63,7 @@ def test_unsupported_command_on_release_based_cluster_error( args = ' --cluster-id j-ABCD --dir s3://abc/' cmdline = self.prefix + args expected_error_msg = ( - "\naws: error: restore-from-hbase-backup" + "\naws: [ERROR]: restore-from-hbase-backup" " is not supported with 'emr-4.0' release.\n" ) result = self.run_cmd(cmdline, 252) diff --git a/tests/unit/customizations/emr/test_schedule_hbase_backup.py b/tests/unit/customizations/emr/test_schedule_hbase_backup.py index 362c19be6f60..636e726ff816 100644 --- a/tests/unit/customizations/emr/test_schedule_hbase_backup.py +++ b/tests/unit/customizations/emr/test_schedule_hbase_backup.py @@ -104,7 +104,7 @@ def test_schedule_hbase_backup_wrong_type(self): ) cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: invalid type. type should be' + '\naws: [ERROR]: invalid type. type should be' + ' either full or incremental.\n' ) result = self.run_cmd(cmdline, 252) @@ -118,7 +118,7 @@ def test_schedule_hbase_backup_wrong_unit(self): ) cmdline = self.prefix + args expected_error_msg = ( - '\naws: error: invalid unit. unit should be' + '\naws: [ERROR]: invalid unit. unit should be' + ' one of the following values: minutes,' + ' hours or days.\n' ) @@ -163,7 +163,7 @@ def test_unsupported_command_on_release_based_cluster_error( ) cmdline = self.prefix + args expected_error_msg = ( - "\naws: error: schedule-hbase-backup" + "\naws: [ERROR]: schedule-hbase-backup" " is not supported with 'emr-4.0' release.\n" ) result = self.run_cmd(cmdline, 252) diff --git a/tests/unit/test_clidriver.py b/tests/unit/test_clidriver.py index e965d6bf352c..3fa7882607c8 100644 --- a/tests/unit/test_clidriver.py +++ b/tests/unit/test_clidriver.py @@ -333,7 +333,7 @@ def test_error_unicode(self): rc = self.driver.main('s3 list-objects --bucket foo'.split()) stderr.flush() assert rc == 255 - assert stderr_b.getvalue().strip() == "☃".encode() + assert stderr_b.getvalue().strip() == "aws: [ERROR]: ☃".encode() @pytest.mark.parametrize( 'env_vars', @@ -354,7 +354,7 @@ def test_error_unicode_env_override(self, env_vars): rc = self.driver.main('s3 list-objects --bucket foo'.split()) stderr.flush() assert rc == 255 - assert stderr_b.getvalue().strip() == "☃".encode() + assert stderr_b.getvalue().strip() == "aws: [ERROR]: ☃".encode() def test_invalid_output_encoding_throws(self): stderr_b = io.BytesIO() @@ -368,7 +368,7 @@ def test_invalid_output_encoding_throws(self): fake_stderr.flush() assert ( stderr_b.getvalue().decode().strip() - == 'Unknown codec `invalid` specified for AWS_CLI_OUTPUT_ENCODING.' + == 'aws: [ERROR]: Unknown codec `invalid` specified for AWS_CLI_OUTPUT_ENCODING.' ) def test_can_access_subcommand_table(self): @@ -725,7 +725,7 @@ def raise_exception(*args, **kwargs): driver.main('ec2 describe-instances'.split()) self.assertEqual( f.write.call_args_list[1][0][0], - 'Unable to locate credentials. ' + 'aws: [ERROR]: Unable to locate credentials. ' 'You can configure credentials by running "aws login".', )