diff --git a/src/awscli_login/config.py b/src/awscli_login/config.py index 172bea8f..1fce1830 100644 --- a/src/awscli_login/config.py +++ b/src/awscli_login/config.py @@ -563,10 +563,11 @@ def wrapper(args: Namespace, session: Session): sig = None fargs = (extra_args_handler(args), ) if extra_args_handler else () + if hasattr(args, "verbose"): + configConsoleLogger(args.verbose) + try: if not skip_args: - # verbosity can only be set at command line - configConsoleLogger(args.verbose) del args.verbose filename, load = config_vcr(args) diff --git a/src/integration_tests/tests/traceback.bats b/src/integration_tests/tests/traceback.bats new file mode 100644 index 00000000..9b742f6a --- /dev/null +++ b/src/integration_tests/tests/traceback.bats @@ -0,0 +1,49 @@ +# Integration tests for aws login + +load 'common' + +@test "Logout verbose flag" { + ! read -r -d '' CREDS_AWS_FILE <<- EOF + [default]$CR + credential_process = aws-login --profile default + EOF + + # Regression test for #260 + run aws logout --verbose + assert_failure + assert_line "Loaded login profile: default$CR" + assert_line "Already logged out!" + + # Regression test for #260 + run aws logout --verbose --verbose + assert_failure + assert_line "Traceback (most recent call last):$CR" + + # Regression test for #260 + run aws logout --verbose --verbose --verbose + assert_failure + assert_line "Traceback (most recent call last):$CR" +} + +@test "aws-login verbose flag" { + ! read -r -d '' CREDS_AWS_FILE <<- EOF + [default]$CR + credential_process = aws-login --profile default + EOF + + # Regression test for #260 + run aws-login --verbose + assert_failure + assert_line "Loaded login profile: default$CR" + assert_line "Already logged out!" + + # Regression test for #260 + run aws-login --verbose --verbose + assert_failure + assert_line "Traceback (most recent call last):$CR" + + # Regression test for #260 + run aws-login --verbose --verbose --verbose + assert_failure + assert_line "Traceback (most recent call last):$CR" +} diff --git a/src/tests/test_error_handler.py b/src/tests/test_error_handler.py new file mode 100644 index 00000000..1b9e4988 --- /dev/null +++ b/src/tests/test_error_handler.py @@ -0,0 +1,58 @@ +import logging +import unittest + +from argparse import Namespace +from unittest.mock import patch + +from awscli_login.config import error_handler + +from .login import MockBotocoreClient + +BOTO_ERR = "ERROR:awscli_login.config:'MockBotocoreClient' " \ + "object has no attribute 'profile'" + +root = logging.getLogger() + + +class ErrorHandler(unittest.TestCase): + + @patch("awscli_login.config.Profile") + def _test_error_handler(self, args, mesg, patch): + @error_handler() + def func(profile, session): + raise Exception(mesg) + + func(args, MockBotocoreClient()) + + def _test_log_level(self, verbose: int, level): + self._test_error_handler(Namespace(verbose=verbose), "I am the law!") + self.assertEqual(root.level, level) + + def test_error_handler_logs_exception(self): + """ Ensure error_handler logs exception. """ + mesg = "First and only exception." + with self.assertLogs() as cm: + self._test_error_handler(Namespace(verbose=0), mesg) + + self.assertEqual(cm.output, [ + f"ERROR:awscli_login.config:{mesg}", + ]) + + def test_error_handler_logging_level_warn(self): + """ error_nandler sets log level to WARN w/o verbose flag. """ + self._test_log_level(0, logging.WARN) + + # Regression test #260 + def test_error_handler_logging_level_info(self): + """ error_nandler sets log level to INFO w/one verbose flag. """ + self._test_log_level(1, logging.INFO) + + # Regression test #260 + def test_error_handler_logging_level_debug(self): + """ error_nandler sets log level to DEBUG w/two verbose flag. """ + self._test_log_level(2, logging.DEBUG) + + # Regression test #260 + def test_error_handler_logging_level_notset(self): + """ error_nandler sets log level to NOTSET w/three verbose flag. """ + self._test_log_level(3, logging.NOTSET)