Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion dirsrvtests/tests/suites/lib389/idm/user_compare_m2Repl_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,35 @@

pytestmark = pytest.mark.tier1


def _attr_values_repr(values):
return sorted(repr(value) for value in values)


def _format_compare_mismatch(obj1, obj2):
obj1_attrs = obj1.get_compare_attrs()
obj2_attrs = obj2.get_compare_attrs()
obj1_attr_names = set(obj1_attrs)
obj2_attr_names = set(obj2_attrs)
lines = []

for attr in sorted(obj1_attr_names - obj2_attr_names):
lines.append(f"Only in supplier1: {attr}={_attr_values_repr(obj1_attrs[attr])}")

for attr in sorted(obj2_attr_names - obj1_attr_names):
lines.append(f"Only in supplier2: {attr}={_attr_values_repr(obj2_attrs[attr])}")

for attr in sorted(obj1_attr_names & obj2_attr_names):
if set(obj1_attrs[attr]) != set(obj2_attrs[attr]):
lines.append(
f"Different {attr}: "
f"supplier1={_attr_values_repr(obj1_attrs[attr])}, "
f"supplier2={_attr_values_repr(obj2_attrs[attr])}"
)

return "\n".join(lines) or "No compare attribute mismatch found"


def test_user_compare_m2Repl(topology_m2):
"""
User compare test between users of supplier to supplier replicaton topology.
Expand Down Expand Up @@ -55,7 +84,14 @@ def test_user_compare_m2Repl(topology_m2):

m2_testuser = m2_users.get('testuser')

assert UserAccount.compare(m1_testuser, m2_testuser)
assert 'parentid' not in m1_testuser.get_compare_attrs()
assert 'parentid' not in m2_testuser.get_compare_attrs()

if not UserAccount.compare(m1_testuser, m2_testuser):
pytest.fail(
"Replicated user compare mismatch:\n"
f"{_format_compare_mismatch(m1_testuser, m2_testuser)}"
)


if __name__ == '__main__':
Expand Down
11 changes: 7 additions & 4 deletions src/lib389/lib389/_mapped_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,9 @@ def __init__(self, instance, dn=None):
self._create_objectclasses = []
self._rdn_attribute = None
self._must_attributes = None
# attributes, we don't want to compare
self._compare_exclude = ['entryid', 'modifytimestamp', 'nsuniqueid']
# Backend-generated attributes that are local to an instance.
self._compare_exclude = ['entryid', 'modifytimestamp', 'nsuniqueid', 'parentid',
'numsubordinates', 'hassubordinates', 'tombstonenumsubordinates']
self._server_controls = None
self._client_controls = None
self._object_filter = '(objectClass=*)'
Expand Down Expand Up @@ -651,8 +652,10 @@ def compare(cls, obj1, obj2):

This comparison is a loose comparison, not a strict one i.e. "this object *is* this other object"
It will just check if the attributes are same.
'nsUniqueId' attribute is not checked intentionally because we want to compare arbitrary objects
i.e they may have different 'nsUniqueId' but same attributes.
Instance-local operational attributes like 'nsUniqueId', 'entryid',
and 'parentid' are not checked intentionally because we want to
compare arbitrary objects, i.e they may have different internal
database identity but same attributes.
Comment on lines +655 to +658

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Docstring excludes modifytimestamp but it is also in _compare_exclude.

Since _compare_exclude also skips modifytimestamp, the current wording could mislead readers into thinking only the listed attributes are excluded. Please either add modifytimestamp to the description or rephrase to make it clear the list is illustrative rather than exhaustive.

Suggested change
Instance-local operational attributes like 'nsUniqueId', 'entryid',
and 'parentid' are not checked intentionally because we want to
compare arbitrary objects, i.e they may have different internal
database identity but same attributes.
Instance-local operational attributes like 'nsUniqueId', 'entryid',
'modifytimestamp', and 'parentid' are not checked intentionally
because we want to compare arbitrary objects, i.e they may have
different internal database identity but same attributes.


Example::

Expand Down
Loading