From d0ec3a7ebb6add2e96c4a06231939baf56e2139a Mon Sep 17 00:00:00 2001 From: Stuart McLaren Date: Wed, 30 Mar 2016 11:56:56 +0000 Subject: [PATCH] Re-enable stacktracing when --debug is used Commit 1f89beb6098f4f6a8d8c2912392b273bc068b2e3 introduced the behaviour that a stacktrace is printed if an exception is encountered. This helped make the client more supportable: $ glance --debug image-list . . . File "glanceclient/common/http.py", line 337, in get_http_client xxx NameError: global name 'xxx' is not defined global name 'xxx' is not defined The behaviour was lost at some point. This patch re-enables it. Change-Id: I25fc8624797909d606590747f54b9cf649ade079 Closes-bug: 1563830 --- glanceclient/common/utils.py | 8 ++++++ glanceclient/shell.py | 14 ++-------- glanceclient/tests/unit/test_shell.py | 39 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/glanceclient/common/utils.py b/glanceclient/common/utils.py index 878c1a53..c486c043 100644 --- a/glanceclient/common/utils.py +++ b/glanceclient/common/utils.py @@ -467,6 +467,14 @@ def endpoint_version_from_url(endpoint, default_version=None): return None, default_version +def debug_enabled(argv): + if bool(env('GLANCECLIENT_DEBUG')) is True: + return True + if '--debug' in argv or '-d' in argv: + return True + return False + + class IterableWithLength(object): def __init__(self, iterable, length): self.iterable = iterable diff --git a/glanceclient/shell.py b/glanceclient/shell.py index 86e61077..9c8f572f 100755 --- a/glanceclient/shell.py +++ b/glanceclient/shell.py @@ -489,18 +489,12 @@ class OpenStackImagesShell(object): try: return self.get_subcommand_parser(api_version) except ImportError as e: - if options.debug: - traceback.print_exc() if not str(e): # Add a generic import error message if the raised # ImportError has none. raise ImportError('Unable to import module. Re-run ' 'with --debug for more info.') raise - except Exception: - if options.debug: - traceback.print_exc() - raise # Parse args once to find version @@ -595,12 +589,6 @@ class OpenStackImagesShell(object): args.func(client, args) except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Identity credentials.") - except Exception: - # NOTE(kragniz) Print any exceptions raised to stderr if the - # --debug flag is set - if args.debug: - traceback.print_exc() - raise finally: if profile: trace_id = osprofiler_profiler.get().get_base_id() @@ -671,4 +659,6 @@ def main(): except KeyboardInterrupt: utils.exit('... terminating glance client', exit_code=130) except Exception as e: + if utils.debug_enabled(argv) is True: + traceback.print_exc() utils.exit(encodeutils.exception_to_unicode(e)) diff --git a/glanceclient/tests/unit/test_shell.py b/glanceclient/tests/unit/test_shell.py index e0f9ff75..bd753f2a 100644 --- a/glanceclient/tests/unit/test_shell.py +++ b/glanceclient/tests/unit/test_shell.py @@ -22,6 +22,7 @@ except ImportError: import hashlib import os import sys +import traceback import uuid import fixtures @@ -150,6 +151,44 @@ class ShellTest(testutils.TestCase): argstr = '--os-image-api-version 2 help foofoo' self.assertRaises(exc.CommandError, shell.main, argstr.split()) + @mock.patch('sys.stdout', six.StringIO()) + @mock.patch('sys.stderr', six.StringIO()) + @mock.patch('sys.argv', ['glance', 'help', 'foofoo']) + def test_no_stacktrace_when_debug_disabled(self): + with mock.patch.object(traceback, 'print_exc') as mock_print_exc: + try: + openstack_shell.main() + except SystemExit: + pass + self.assertFalse(mock_print_exc.called) + + @mock.patch('sys.stdout', six.StringIO()) + @mock.patch('sys.stderr', six.StringIO()) + @mock.patch('sys.argv', ['glance', 'help', 'foofoo']) + def test_stacktrace_when_debug_enabled_by_env(self): + old_environment = os.environ.copy() + os.environ = {'GLANCECLIENT_DEBUG': '1'} + try: + with mock.patch.object(traceback, 'print_exc') as mock_print_exc: + try: + openstack_shell.main() + except SystemExit: + pass + self.assertTrue(mock_print_exc.called) + finally: + os.environ = old_environment + + @mock.patch('sys.stdout', six.StringIO()) + @mock.patch('sys.stderr', six.StringIO()) + @mock.patch('sys.argv', ['glance', '--debug', 'help', 'foofoo']) + def test_stacktrace_when_debug_enabled(self): + with mock.patch.object(traceback, 'print_exc') as mock_print_exc: + try: + openstack_shell.main() + except SystemExit: + pass + self.assertTrue(mock_print_exc.called) + def test_help(self): shell = openstack_shell.OpenStackImagesShell() argstr = '--os-image-api-version 2 help'