The nightly-previous-selinux ipa-4-10 test test_integration/test_simple_replication.py::TestSimpleReplication::test_user_replication_to_master fails at ldap.NO_SUCH_OBJECT: {'msgtype': 101, 'msgid': 4, 'result': 32, 'desc': 'No such object', 'ctrls': [], 'matched': 'cn=users,cn=accounts,dc=ufreeipa,dc=test'}.
test_integration/test_simple_replication.py::TestSimpleReplication::test_user_replication_to_master
ldap.NO_SUCH_OBJECT: {'msgtype': 101, 'msgid': 4, 'result': 32, 'desc': 'No such object', 'ctrls': [], 'matched': 'cn=users,cn=accounts,dc=ufreeipa,dc=test'}
This is possibly related to LDAP issues, for some reason LDAP can't find the created users. It seems that the replicate doesn't copy it's users over, however I'm not sure of that.
self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> arg_desc = None @contextlib.contextmanager def error_handler(self, arg_desc=None): """Context manager that handles LDAPErrors """ desc = None try: try: > yield arg_desc = None desc = 'No such object' info = '' self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> ../ipapython/ipaldap.py:1096: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> filter = '(objectClass=*)', attrs_list = None base_dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') scope = 0, time_limit = -1.0, size_limit = 0, paged_search = False get_effective_rights = False def find_entries( self, filter=None, attrs_list=None, base_dn=None, scope=ldap.SCOPE_SUBTREE, time_limit=None, size_limit=None, paged_search=False, get_effective_rights=False): """ Return a list of entries and indication of whether the results were truncated ([(dn, entry_attrs)], truncated) matching specified search parameters followed by truncated flag. If the truncated flag is True, search hit a server limit and its results are incomplete. Keyword arguments: :param attrs_list: list of attributes to return, all if None (default None) :param base_dn: dn of the entry at which to start the search (default '') :param scope: search scope, see LDAP docs (default ldap2.SCOPE_SUBTREE) :param time_limit: time limit in seconds (default unlimited) :param size_limit: size (number of entries returned) limit (default unlimited) :param paged_search: search using paged results control :param get_effective_rights: use GetEffectiveRights control :raises: errors.NotFound if result set is empty or base_dn doesn't exist """ if base_dn is None: base_dn = DN() assert isinstance(base_dn, DN) if not filter: filter = '(objectClass=*)' res = [] truncated = False if time_limit is None: time_limit = self.time_limit if time_limit == 0: time_limit = -1.0 if size_limit is None: size_limit = self.size_limit if not isinstance(size_limit, int): size_limit = int(size_limit) if not isinstance(time_limit, float): time_limit = float(time_limit) if attrs_list: attrs_list = [a.lower() for a in set(attrs_list)] base_sctrls = [] if get_effective_rights: base_sctrls.append(self.__get_effective_rights_control()) cookie = '' page_size = (size_limit if size_limit > 0 else 2000) - 1 if page_size == 0: paged_search = False # pass arguments to python-ldap with self.error_handler(): if six.PY2: filter = self.encode(filter) attrs_list = self.encode(attrs_list) while True: if paged_search: sctrls = base_sctrls + [ SimplePagedResultsControl(0, page_size, cookie) ] else: sctrls = base_sctrls or None try: id = self.conn.search_ext( str(base_dn), scope, filter, attrs_list, serverctrls=sctrls, timeout=time_limit, sizelimit=size_limit ) while True: result = self.conn.result3(id, 0) objtype, res_list, _res_id, res_ctrls = result if objtype == ldap.RES_SEARCH_RESULT: break res_list = self._convert_result(res_list) if res_list: res.append(res_list[0]) if paged_search: # Get cookie for the next page for ctrl in res_ctrls: if isinstance(ctrl, SimplePagedResultsControl): cookie = ctrl.cookie break else: cookie = '' except ldap.ADMINLIMIT_EXCEEDED: truncated = TRUNCATED_ADMIN_LIMIT break except ldap.SIZELIMIT_EXCEEDED: truncated = TRUNCATED_SIZE_LIMIT break except ldap.TIMELIMIT_EXCEEDED: truncated = TRUNCATED_TIME_LIMIT break except ldap.LDAPError as e: # If paged search is in progress, try to cancel it if paged_search and cookie: sctrls = [SimplePagedResultsControl(0, 0, cookie)] try: self.conn.search_ext_s( str(base_dn), scope, filter, attrs_list, serverctrls=sctrls, timeout=time_limit, sizelimit=size_limit) except ldap.LDAPError as e2: logger.warning( "Error cancelling paged search: %s", e2) cookie = '' try: > raise e attrs_list = None base_dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') base_sctrls = [] cookie = '' filter = '(objectClass=*)' get_effective_rights = False id = 4 page_size = 1999 paged_search = False res = [] scope = 0 sctrls = None self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> size_limit = 0 time_limit = -1.0 truncated = False ../ipapython/ipaldap.py:1600: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> filter = '(objectClass=*)', attrs_list = None base_dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') scope = 0, time_limit = -1.0, size_limit = 0, paged_search = False get_effective_rights = False def find_entries( self, filter=None, attrs_list=None, base_dn=None, scope=ldap.SCOPE_SUBTREE, time_limit=None, size_limit=None, paged_search=False, get_effective_rights=False): """ Return a list of entries and indication of whether the results were truncated ([(dn, entry_attrs)], truncated) matching specified search parameters followed by truncated flag. If the truncated flag is True, search hit a server limit and its results are incomplete. Keyword arguments: :param attrs_list: list of attributes to return, all if None (default None) :param base_dn: dn of the entry at which to start the search (default '') :param scope: search scope, see LDAP docs (default ldap2.SCOPE_SUBTREE) :param time_limit: time limit in seconds (default unlimited) :param size_limit: size (number of entries returned) limit (default unlimited) :param paged_search: search using paged results control :param get_effective_rights: use GetEffectiveRights control :raises: errors.NotFound if result set is empty or base_dn doesn't exist """ if base_dn is None: base_dn = DN() assert isinstance(base_dn, DN) if not filter: filter = '(objectClass=*)' res = [] truncated = False if time_limit is None: time_limit = self.time_limit if time_limit == 0: time_limit = -1.0 if size_limit is None: size_limit = self.size_limit if not isinstance(size_limit, int): size_limit = int(size_limit) if not isinstance(time_limit, float): time_limit = float(time_limit) if attrs_list: attrs_list = [a.lower() for a in set(attrs_list)] base_sctrls = [] if get_effective_rights: base_sctrls.append(self.__get_effective_rights_control()) cookie = '' page_size = (size_limit if size_limit > 0 else 2000) - 1 if page_size == 0: paged_search = False # pass arguments to python-ldap with self.error_handler(): if six.PY2: filter = self.encode(filter) attrs_list = self.encode(attrs_list) while True: if paged_search: sctrls = base_sctrls + [ SimplePagedResultsControl(0, page_size, cookie) ] else: sctrls = base_sctrls or None try: id = self.conn.search_ext( str(base_dn), scope, filter, attrs_list, serverctrls=sctrls, timeout=time_limit, sizelimit=size_limit ) while True: > result = self.conn.result3(id, 0) attrs_list = None base_dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') base_sctrls = [] cookie = '' filter = '(objectClass=*)' get_effective_rights = False id = 4 page_size = 1999 paged_search = False res = [] scope = 0 sctrls = None self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> size_limit = 0 time_limit = -1.0 truncated = False ../ipapython/ipaldap.py:1560: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <ldap.ldapobject.SimpleLDAPObject object at 0x7fae2b201650>, msgid = 4 all = 0, timeout = None, resp_ctrl_classes = None def result3(self,msgid=ldap.RES_ANY,all=1,timeout=None,resp_ctrl_classes=None): > resp_type, resp_data, resp_msgid, decoded_resp_ctrls, retoid, retval = self.result4( msgid,all,timeout, add_ctrls=0,add_intermediates=0,add_extop=0, resp_ctrl_classes=resp_ctrl_classes ) all = 0 msgid = 4 resp_ctrl_classes = None self = <ldap.ldapobject.SimpleLDAPObject object at 0x7fae2b201650> timeout = None /usr/lib64/python3.11/site-packages/ldap/ldapobject.py:543: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <ldap.ldapobject.SimpleLDAPObject object at 0x7fae2b201650>, msgid = 4 all = 0, timeout = -1, add_ctrls = 0, add_intermediates = 0, add_extop = 0 resp_ctrl_classes = None def result4(self,msgid=ldap.RES_ANY,all=1,timeout=None,add_ctrls=0,add_intermediates=0,add_extop=0,resp_ctrl_classes=None): if timeout is None: timeout = self.timeout > ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop) add_ctrls = 0 add_extop = 0 add_intermediates = 0 all = 0 msgid = 4 resp_ctrl_classes = None self = <ldap.ldapobject.SimpleLDAPObject object at 0x7fae2b201650> timeout = -1 /usr/lib64/python3.11/site-packages/ldap/ldapobject.py:553: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <ldap.ldapobject.SimpleLDAPObject object at 0x7fae2b201650> func = <built-in method result4 of LDAP object at 0x7fae29a2f270> args = (4, 0, -1, 0, 0, 0), kwargs = {}, diagnostic_message_success = None def _ldap_call(self,func,*args,**kwargs): """ Wrapper method mainly for serializing calls into OpenLDAP libs and trace logs """ self._ldap_object_lock.acquire() if __debug__: if self._trace_level>=1: self._trace_file.write('*** {} {} - {}\n{}\n'.format( repr(self), self._uri, '.'.join((self.__class__.__name__,func.__name__)), pprint.pformat((args,kwargs)) )) if self._trace_level>=9: traceback.print_stack(limit=self._trace_stack_limit,file=self._trace_file) diagnostic_message_success = None try: try: > result = func(*args,**kwargs) E ldap.NO_SUCH_OBJECT: {'msgtype': 101, 'msgid': 4, 'result': 32, 'desc': 'No such object', 'ctrls': [], 'matched': 'cn=users,cn=accounts,dc=ufreeipa,dc=test'} args = (4, 0, -1, 0, 0, 0) diagnostic_message_success = None func = <built-in method result4 of LDAP object at 0x7fae29a2f270> kwargs = {} self = <ldap.ldapobject.SimpleLDAPObject object at 0x7fae2b201650> /usr/lib64/python3.11/site-packages/ldap/ldapobject.py:128: NO_SUCH_OBJECT During handling of the above exception, another exception occurred: self = <ipatests.test_integration.test_simple_replication.TestSimpleReplication object at 0x7fae2b1403d0> def test_user_replication_to_master(self): """Test user replication replica -> master""" > check_replication(self.replicas[0], self.master, 'testuser2') self = <ipatests.test_integration.test_simple_replication.TestSimpleReplication object at 0x7fae2b1403d0> test_integration/test_simple_replication.py:76: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ test_integration/test_simple_replication.py:51: in check_replication entry = ldap.get_entry(user_dn) basedn = ipapython.dn.DN('dc=ufreeipa,dc=test') dest_host = <ipatests.pytest_ipa.integration.host.Host master.ufreeipa.test (master)> ldap = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> login = 'testuser2' source_host = <ipatests.pytest_ipa.integration.host.Host replica.ufreeipa.test (replica)> source_ldap = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b97a3d0> user_dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') ../ipapython/ipaldap.py:1655: in get_entry entries = self.get_entries( attrs_list = None dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') get_effective_rights = False self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> size_limit = None time_limit = None ../ipapython/ipaldap.py:1466: in get_entries entries, truncated = self.find_entries( attrs_list = None base_dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') filter = None get_effective_rights = False kwargs = {'size_limit': None, 'time_limit': None} scope = 0 self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> ../ipapython/ipaldap.py:1540: in find_entries with self.error_handler(): attrs_list = None base_dn = ipapython.dn.DN('uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test') base_sctrls = [] cookie = '' filter = '(objectClass=*)' get_effective_rights = False id = 4 page_size = 1999 paged_search = False res = [] scope = 0 sctrls = None self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> size_limit = 0 time_limit = -1.0 truncated = False /usr/lib64/python3.11/contextlib.py:158: in __exit__ self.gen.throw(typ, value, traceback) self = <contextlib._GeneratorContextManager object at 0x7fae2b202450> traceback = <traceback object at 0x7fae2b201f40> typ = <class 'ldap.NO_SUCH_OBJECT'> value = NO_SUCH_OBJECT({'msgtype': 101, 'msgid': 4, 'result': 32, 'desc': 'No such object', 'ctrls': [], 'matched': 'cn=users,cn=accounts,dc=ufreeipa,dc=test'}) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> arg_desc = None @contextlib.contextmanager def error_handler(self, arg_desc=None): """Context manager that handles LDAPErrors """ desc = None try: try: yield except ldap.TIMEOUT: raise errors.DatabaseTimeout() except ldap.LDAPError as e: desc = e.args[0]['desc'].strip() info = e.args[0].get('info', '').strip() if arg_desc is not None: info = "%s arguments: %s" % (info, arg_desc) raise except ldap.NO_SUCH_OBJECT: > raise errors.NotFound(reason=arg_desc or 'no such entry') E ipalib.errors.NotFound: no such entry arg_desc = None desc = 'No such object' info = '' self = <ipatests.pytest_ipa.integration.host.LDAPClientWithoutCertCheck object at 0x7fae2b201890> ../ipapython/ipaldap.py:1106: NotFound
Logs Artifacts
From the logs: - the user gets added to the replica at 12:01:06
[07/Feb/2025:12:01:06.923811459 +0000] conn=22 op=5 ADD dn="uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test"
After that, the test checks if replication is complete:
dn: cn=meTomaster.ufreeipa.test,cn=replica,cn=dc\=ufreeipa\,dc\=test,cn=mapping tree,cn=config nsds5replicalastupdatestatus: Error (0) Replica acquired successfully: Incre mental update succeeded nsds5replicaupdateinprogress: FALSE
On the master: The search for testuser2 happens before the add:
[07/Feb/2025:12:01:08.859879356 +0000] conn=138 op=3 SRCH base="uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test" scope=0 filter="(objectClass=*)" attrs=ALL [07/Feb/2025:12:01:08.873188581 +0000] conn=138 op=3 RESULT err=32 tag=101 nentries=0 wtime=0.000090840 optime=0.013308453 etime=0.013394064 [07/Feb/2025:12:01:08.943222515 +0000] conn=131 op=44 RESULT err=0 tag=120 nentries=0 wtime=0.000174547 optime=0.364617358 etime=0.364790252 [07/Feb/2025:12:01:09.234720965 +0000] conn=131 op=45 MOD dn="dnaHostname=replica.ufreeipa.test+dnaPortNum=389,cn=posix-ids,cn=dna,cn=ipa,cn=etc,dc=ufreeipa,dc=test" [07/Feb/2025:12:01:09.280431903 +0000] conn=131 op=45 RESULT err=0 tag=103 nentries=0 wtime=0.000247915 optime=0.045717941 etime=0.045963602 csn=67a5f603000200030000 [07/Feb/2025:12:01:09.287516236 +0000] conn=131 op=46 ADD dn="uid=testuser2,cn=users,cn=accounts,dc=ufreeipa,dc=test" [07/Feb/2025:12:01:09.349890177 +0000] conn=131 op=46 RESULT err=0 tag=105 nentries=0 wtime=0.000360786 optime=0.062384942 etime=0.062742101 csn=67a5f603000300030000
so it looks like the replication was marked as complete while it was not.
Log in to comment on this ticket.