ComparableVersionedObject.__eq__ reports non-equality if list of changed fields differ

Bug #1563787 reported by Daniel Berrange
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
oslo.versionedobjects
Confirmed
Medium
Unassigned

Bug Description

Consider this code from the ovo test suite test_objects.py file

    def test_comparable_objects(self):
        obj1 = MyComparableObj(foo=1)
        obj2 = MyComparableObj(foo=1)
        obj3 = MyComparableObj(foo=2)
 self.assertTrue(obj1 == obj2)
        self.assertFalse(obj1 == obj3)

This all looks fine, and indeed it passes, but now lets reset the list of change fields on obj2 and try that comparison again

        obj2.obj_reset_changes()
        self.assertEqual(obj1, obj2)

obj1 and obj2 should still be treated as equal since all their properties are the same but the test now fails

FAIL: oslo_versionedobjects.tests.test_objects.TestRemoteObject.test_comparable_objects
tags: worker-6
----------------------------------------------------------------------
Empty attachments:
  pythonlogging:''
  stderr
  stdout

Traceback (most recent call last):
  File "oslo_versionedobjects/tests/test_objects.py", line 1317, in test_comparable_objects
    self.assertEqual(obj1, obj2)
  File "/home/berrange/src/cloud/oslo.versionedobjects/.tox/py27/lib/python2.7/site-packages/testtools/testcase.py", line 362, in assertEqual
    self.assertThat(observed, matcher, message)
  File "/home/berrange/src/cloud/oslo.versionedobjects/.tox/py27/lib/python2.7/site-packages/testtools/testcase.py", line 447, in assertThat
    raise mismatch_error
testtools.matchers._impl.MismatchError: !=:
reference = MyComparableObj(bar=<?>,foo=1,missing=<?>,mutable_default=<?>,readonly=<?>,rel_object=<?>,rel_objects=<?>,timestamp=<?>)
actual = MyComparableObj(bar=<?>,foo=1,missing=<?>,mutable_default=<?>,readonly=<?>,rel_object=<?>,rel_objects=<?>,timestamp=<?>)

What is particularly unpleasant is that the result of __repr__ shows that are identical.

Looking at the __eq__ implementation, it calls obj_to_primitive(). This dict it generates includes a list of changed fields and this causes the equality comparison to fail.

The __eq__ implementation should not be affected by the list of changed fields - only the actual field values should affect it.

This has had other nasty side effects too, such as __eq__ method being fragile wrt python hash seed which causes random failures of tests which use object eqality (see https://bugs.launchpad.net/oslo.versionedobjects/+bug/1552676)

Ben Nemec (bnemec)
Changed in oslo.versionedobjects:
status: New → Confirmed
importance: Undecided → Medium
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.