Merge "Make NovaException format errors fatal for tests"

This commit is contained in:
Jenkins
2017-05-17 00:26:21 +00:00
committed by Gerrit Code Review
4 changed files with 58 additions and 6 deletions

View File

@@ -86,17 +86,21 @@ class NovaException(Exception):
message = self.msg_fmt % kwargs message = self.msg_fmt % kwargs
except Exception: except Exception:
# kwargs doesn't match a variable in the message # NOTE(melwitt): This is done in a separate method so it can be
# log the issue and the kwargs # monkey-patched during testing to make it a hard failure.
LOG.exception(_LE('Exception in string format operation')) self._log_exception()
for name, value in kwargs.items():
LOG.error("%s: %s" % (name, value)) # noqa
message = self.msg_fmt message = self.msg_fmt
self.message = message self.message = message
super(NovaException, self).__init__(message) super(NovaException, self).__init__(message)
def _log_exception(self):
# kwargs doesn't match a variable in the message
# log the issue and the kwargs
LOG.exception(_LE('Exception in string format operation'))
for name, value in self.kwargs.items():
LOG.error("%s: %s" % (name, value)) # noqa
def format_message(self): def format_message(self):
# NOTE(mrodden): use the first argument to the python Exception object # NOTE(mrodden): use the first argument to the python Exception object
# which should be our full NovaException message, (see __init__) # which should be our full NovaException message, (see __init__)

View File

@@ -31,6 +31,7 @@ import datetime
import inspect import inspect
import os import os
import pprint import pprint
import sys
import fixtures import fixtures
import mock import mock
@@ -49,6 +50,7 @@ import testtools
from nova import context from nova import context
from nova import db from nova import db
from nova import exception
from nova.network import manager as network_manager from nova.network import manager as network_manager
from nova.network.security_group import openstack_driver from nova.network.security_group import openstack_driver
from nova import objects from nova import objects
@@ -169,6 +171,26 @@ def _patch_mock_to_raise_for_invalid_assert_calls():
_patch_mock_to_raise_for_invalid_assert_calls() _patch_mock_to_raise_for_invalid_assert_calls()
class NovaExceptionReraiseFormatError(object):
real_log_exception = exception.NovaException._log_exception
@classmethod
def patch(cls):
exception.NovaException._log_exception = cls._wrap_log_exception
@staticmethod
def _wrap_log_exception(self):
exc_info = sys.exc_info()
NovaExceptionReraiseFormatError.real_log_exception(self)
six.reraise(*exc_info)
# NOTE(melwitt) This needs to be done at import time in order to also catch
# NovaException format errors that are in mock decorators. In these cases, the
# errors will be raised during test listing, before tests actually run.
NovaExceptionReraiseFormatError.patch()
class TestCase(testtools.TestCase): class TestCase(testtools.TestCase):
"""Test case base class for all unit tests. """Test case base class for all unit tests.

View File

@@ -16,6 +16,7 @@
import inspect import inspect
import fixtures
import mock import mock
import six import six
from webob.util import status_reasons from webob.util import status_reasons
@@ -211,6 +212,13 @@ class NovaExceptionTestCase(test.NoDBTestCase):
self.assertEqual("some message", exc.format_message()) self.assertEqual("some message", exc.format_message())
def test_format_message_remote_error(self): def test_format_message_remote_error(self):
# NOTE(melwitt): This test checks that errors are formatted as expected
# in a real environment where format errors are caught and not
# reraised, so we patch in the real implementation.
self.useFixture(fixtures.MonkeyPatch(
'nova.exception.NovaException._log_exception',
test.NovaExceptionReraiseFormatError.real_log_exception))
class FakeNovaException_Remote(exception.NovaException): class FakeNovaException_Remote(exception.NovaException):
msg_fmt = "some message %(somearg)s" msg_fmt = "some message %(somearg)s"

View File

@@ -21,6 +21,7 @@ import oslo_messaging as messaging
import six import six
import nova.conf import nova.conf
from nova import exception
from nova import rpc from nova import rpc
from nova import test from nova import test
from nova.tests import fixtures from nova.tests import fixtures
@@ -283,3 +284,20 @@ class ContainKeyValueTestCase(test.NoDBTestCase):
# Raise KeyError # Raise KeyError
self.assertNotEqual(matcher, {1: 2, '3': 4, 5: '6'}) self.assertNotEqual(matcher, {1: 2, '3': 4, 5: '6'})
self.assertNotEqual(matcher, {'bar': 'foo'}) self.assertNotEqual(matcher, {'bar': 'foo'})
class NovaExceptionReraiseFormatErrorTestCase(test.NoDBTestCase):
"""Test that format errors are reraised in tests."""
def test_format_error_in_nova_exception(self):
class FakeImageException(exception.NovaException):
msg_fmt = 'Image %(image_id)s has wrong type %(type)s.'
# wrong kwarg
ex = self.assertRaises(KeyError, FakeImageException,
bogus='wrongkwarg')
self.assertIn('image_id', six.text_type(ex))
# no kwarg
ex = self.assertRaises(KeyError, FakeImageException)
self.assertIn('image_id', six.text_type(ex))
# not enough kwargs
ex = self.assertRaises(KeyError, FakeImageException, image_id='image')
self.assertIn('type', six.text_type(ex))