Skip to content

Commit 36384c2

Browse files
committed
test: Implement test cases for reconnection handling
test_106_reconnect_restore() handles a SERVER_DOWN exception manually and tries to re-use the connection afterwards again. This established the connection again but did not bind(), so it now raises ldap.INSUFFICIENT_ACCESS. test_107_reconnect_restore() restarts the LDAP server during searches, which causes a UNAVAILABLE exception.
1 parent 72c1b5e commit 36384c2

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

Tests/t_ldapobject.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
import os
1010
import re
1111
import socket
12+
import threading
13+
import time
1214
import unittest
1315
import pickle
1416

17+
1518
# Switch off processing .ldaprc or ldap.conf before importing _ldap
1619
os.environ['LDAPNOINIT'] = '1'
1720

@@ -643,6 +646,66 @@ def test105_reconnect_restore(self):
643646
self.server._start_slapd()
644647
self.assertEqual(l1.whoami_s(), 'dn:'+bind_dn)
645648

649+
def test106_reconnect_restore(self):
650+
lo = self.ldap_object_class(self.server.ldap_uri, retry_max=2, retry_delay=1)
651+
bind_dn = 'cn=user1,' + self.server.suffix
652+
lo.simple_bind_s(bind_dn, 'user1_pw')
653+
654+
dn = lo.whoami_s()[3:]
655+
656+
self.server._proc.terminate()
657+
self.server.wait()
658+
659+
# do a search, wait for the timeout, handle SERVER_DOWN exception
660+
with self.assertRaises(ldap.SERVER_DOWN):
661+
lo.search_s(dn, ldap.SCOPE_BASE, '(objectClass=*)')
662+
663+
self.server._start_slapd()
664+
665+
# try to use the connection again
666+
lo.search_s(dn, ldap.SCOPE_BASE, '(objectClass=*)')
667+
# this used to raise ldap.INSUFFICIENT_ACCESS, as it is became a unbound connection and did everything anonymously.
668+
669+
def test107_reconnect_restore(self):
670+
"""The idea of this test is to restart the LDAP-Server while there are ongoing searches.
671+
This causes :class:`ldap.UNAVAILABLE` to be raised (with |OpenLDAP|) for a short time.
672+
To increase the chance of triggering this bug we are starting multiple threads
673+
with a large number of retry attempts in a short amount of time.
674+
"""
675+
# TODO: refactor this test
676+
excs = []
677+
678+
def _reconnect_search_thread():
679+
lo = self.ldap_object_class(self.server.ldap_uri)
680+
bind_dn = 'cn=user1,' + self.server.suffix
681+
lo.simple_bind_s(bind_dn, 'user1_pw')
682+
lo._retry_max = 10E4
683+
lo._retry_delay = .001
684+
lo.search_ext_s(self.server.suffix, ldap.SCOPE_SUBTREE, "cn=user1", attrlist=["cn"])
685+
s = time.time()
686+
while (time.time() - s) < run_time:
687+
lo.search_ext_s(self.server.suffix, ldap.SCOPE_SUBTREE, filterstr="cn=user1", attrlist=["cn"])
688+
689+
def reconnect_search_thread():
690+
try:
691+
_reconnect_search_thread()
692+
except Exception as exc:
693+
excs.append(exc)
694+
695+
thread_count = 100
696+
run_time = 10.0
697+
my_thread = [None] * thread_count
698+
for i in range(0, thread_count):
699+
my_thread[i] = threading.Thread(target=reconnect_search_thread)
700+
for t in my_thread:
701+
t.start()
702+
time.sleep(3)
703+
self.server.restart()
704+
for t in my_thread:
705+
t.join()
706+
707+
self.assertEqual(excs, [])
708+
646709

647710
@requires_init_fd()
648711
class Test03_SimpleLDAPObjectWithFileno(Test00_SimpleLDAPObject):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy