return more details on assertJsonEqual fail
assertJsonEqual does a recursive traverse of a data structure, using assertEqual strategically along the way. The problem with this is that it can lead to really cryptic messages like Failed '3' != '4' When some very deep list was the wrong number of elements. It doesn't tell you which list was the wrong number of elements, and so it's completely opaque to get to the bottom of. Especially if this doesn't happen on every run, just some. This creates a version which catches an inner match issue, and constructs a new failure which includes information about the 2 data structures being compared at the top level. This should help debugging racey unit test in the gate like test_describe_instances_with_filters_tags. Related-Bug: #1479780 Change-Id: I6f6e961a3c63f9f86fe9b21ce6c16a2e634e9ce5
This commit is contained in:
parent
50f53d2301
commit
8316582f8d
25
nova/test.py
25
nova/test.py
@ -289,6 +289,21 @@ class TestCase(testtools.TestCase):
|
|||||||
return svc.service
|
return svc.service
|
||||||
|
|
||||||
def assertJsonEqual(self, expected, observed):
|
def assertJsonEqual(self, expected, observed):
|
||||||
|
"""Asserts that 2 complex data structures are json equivalent.
|
||||||
|
|
||||||
|
We use data structures which serialize down to json throughout
|
||||||
|
the code, and often times we just need to know that these are
|
||||||
|
json equivalent. This means that list order is not important,
|
||||||
|
and should be sorted.
|
||||||
|
|
||||||
|
Because this is a recursive set of assertions, when failure
|
||||||
|
happens we want to expose both the local failure and the
|
||||||
|
global view of the 2 data structures being compared. So a
|
||||||
|
MismatchError which includes the inner failure as the
|
||||||
|
mismatch, and the passed in expected / observed as matchee /
|
||||||
|
matcher.
|
||||||
|
|
||||||
|
"""
|
||||||
if isinstance(expected, six.string_types):
|
if isinstance(expected, six.string_types):
|
||||||
expected = jsonutils.loads(expected)
|
expected = jsonutils.loads(expected)
|
||||||
if isinstance(observed, six.string_types):
|
if isinstance(observed, six.string_types):
|
||||||
@ -325,7 +340,15 @@ class TestCase(testtools.TestCase):
|
|||||||
else:
|
else:
|
||||||
self.assertEqual(expected, observed)
|
self.assertEqual(expected, observed)
|
||||||
|
|
||||||
inner(expected, observed)
|
try:
|
||||||
|
inner(expected, observed)
|
||||||
|
except testtools.matchers.MismatchError as e:
|
||||||
|
inner_mismatch = e.mismatch
|
||||||
|
# inverting the observed / expected because testtools
|
||||||
|
# error messages assume expected is second. Possibly makes
|
||||||
|
# reading the error messages less confusing.
|
||||||
|
raise testtools.matchers.MismatchError(observed, expected,
|
||||||
|
inner_mismatch, verbose=True)
|
||||||
|
|
||||||
def assertPublicAPISignatures(self, baseinst, inst):
|
def assertPublicAPISignatures(self, baseinst, inst):
|
||||||
def get_public_apis(inst):
|
def get_public_apis(inst):
|
||||||
|
Loading…
Reference in New Issue
Block a user