Skip to content

Commit e214b39

Browse files
committed
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 c9a329a commit e214b39

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

Tests/t_ldapobject.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
import linecache
88
import os
99
import socket
10+
import threading
11+
import time
1012
import unittest
1113
import pickle
1214

15+
1316
# Switch off processing .ldaprc or ldap.conf before importing _ldap
1417
os.environ['LDAPNOINIT'] = '1'
1518

@@ -547,6 +550,7 @@ def test103_reconnect_get_state(self):
547550
{}
548551
),
549552
'_options': [(17, 3)],
553+
'_reconnect_exceptions': (ldap.SERVER_DOWN, ldap.UNAVAILABLE),
550554
'_reconnects_done': 0,
551555
'_retry_delay': 60.0,
552556
'_retry_max': 1,
@@ -585,6 +589,63 @@ def test105_reconnect_restore(self):
585589
self.server._start_slapd()
586590
self.assertEqual(l1.whoami_s(), 'dn:'+bind_dn)
587591

592+
def test_106_reconnect_restore(self):
593+
lo = self.ldap_object_class(self.server.ldap_uri, retry_max=2, retry_delay=1)
594+
bind_dn = 'cn=user1,' + self.server.suffix
595+
lo.simple_bind_s(bind_dn, 'user1_pw')
596+
597+
dn = lo.whoami_s()[3:]
598+
599+
self.server._proc.terminate()
600+
self.server.wait()
601+
602+
# do a search, wait for the timeout, handle SERVER_DOWN exception
603+
try:
604+
print(lo.search_s(dn, ldap.SCOPE_BASE, '(objectClass=*)'))
605+
except ldap.SERVER_DOWN:
606+
pass # some handling here
607+
else:
608+
self.assertEqual(True, False)
609+
610+
self.server._start_slapd()
611+
612+
# try to use the connection again
613+
print(lo.search_s(dn, ldap.SCOPE_BASE, '(objectClass=*)'))
614+
# this now raises ldap.INSUFFICIENT_ACCESS, as it is now a unbound connection and does everything anonymously.
615+
616+
def test_107_reconnect_restore(self):
617+
def foo():
618+
lo = self.ldap_object_class(self.server.ldap_uri)
619+
bind_dn = 'cn=user1,' + self.server.suffix
620+
lo.simple_bind_s(bind_dn, 'user1_pw')
621+
lo._retry_max = 10E4
622+
lo._retry_delay = .001
623+
x = 0
624+
lo.search_ext_s(self.server.suffix, ldap.SCOPE_SUBTREE, "cn=user1", attrlist=["cn"])
625+
s = time.time()
626+
print("go")
627+
while (time.time() - s) < run_time:
628+
x += 1
629+
lo.search_ext_s(self.server.suffix, ldap.SCOPE_SUBTREE, filterstr="cn=user1", attrlist=["cn"])
630+
print("Searches per sec: {}".format(x / run_time))
631+
632+
thread_count = 100
633+
run_time = 10.0
634+
my_thread = [None] * thread_count
635+
for i in range(0, thread_count):
636+
my_thread[i] = threading.Thread(target=foo)
637+
for t in my_thread:
638+
t.start()
639+
print("warmup")
640+
time.sleep(3)
641+
print("restart slapd")
642+
self.server.restart()
643+
print("restarted")
644+
for t in my_thread:
645+
t.join()
646+
647+
print("done")
648+
588649

589650
@requires_init_fd()
590651
class Test03_SimpleLDAPObjectWithFileno(Test00_SimpleLDAPObject):

0 commit comments

Comments
 (0)