ticket48191_test.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. import os
  2. import sys
  3. import time
  4. import ldap
  5. import logging
  6. import pytest
  7. from lib389 import DirSrv, Entry, tools, tasks
  8. from lib389.tools import DirSrvTools
  9. from lib389._constants import *
  10. from lib389.properties import *
  11. from lib389.tasks import *
  12. from ldap.controls import SimplePagedResultsControl
  13. from ldap.controls.simple import GetEffectiveRightsControl
  14. log = logging.getLogger(__name__)
  15. installation_prefix = None
  16. CONFIG_DN = 'cn=config'
  17. MYSUFFIX = 'o=ticket48191.org'
  18. MYSUFFIXBE = 'ticket48191'
  19. _MYLDIF = 'ticket48191.ldif'
  20. SEARCHFILTER = '(objectclass=*)'
  21. class TopologyStandalone(object):
  22. def __init__(self, standalone):
  23. standalone.open()
  24. self.standalone = standalone
  25. @pytest.fixture(scope="module")
  26. def topology(request):
  27. '''
  28. This fixture is used to standalone topology for the 'module'.
  29. '''
  30. global installation_prefix
  31. if installation_prefix:
  32. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  33. standalone = DirSrv(verbose=False)
  34. # Args for the standalone instance
  35. args_instance[SER_HOST] = HOST_STANDALONE
  36. args_instance[SER_PORT] = PORT_STANDALONE
  37. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  38. args_standalone = args_instance.copy()
  39. standalone.allocate(args_standalone)
  40. # Get the status of the instance and restart it if it exists
  41. instance_standalone = standalone.exists()
  42. # Remove the instance
  43. if instance_standalone:
  44. standalone.delete()
  45. # Create the instance
  46. standalone.create()
  47. # Used to retrieve configuration information (dbdir, confdir...)
  48. standalone.open()
  49. # clear the tmp directory
  50. standalone.clearTmpDir(__file__)
  51. # Here we have standalone instance up and running
  52. return TopologyStandalone(standalone)
  53. def test_ticket48191_setup(topology):
  54. """
  55. Import 20 entries
  56. Set nsslapd-maxsimplepaged-per-conn in cn=config
  57. If the val is negative, no limit.
  58. If the value is 0, the simple paged results is disabled.
  59. If the value is positive, the value is the max simple paged results requests per connection.
  60. The setting has to be dynamic.
  61. """
  62. log.info('Testing Ticket 48191 - Config parameter nsslapd-maxsimplepaged-per-conn')
  63. # bind as directory manager
  64. topology.standalone.log.info("Bind as %s" % DN_DM)
  65. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  66. topology.standalone.log.info("\n\n######################### SETUP SUFFIX o=ticket48191.org ######################\n")
  67. topology.standalone.backend.create(MYSUFFIX, {BACKEND_NAME: MYSUFFIXBE})
  68. topology.standalone.mappingtree.create(MYSUFFIX, bename=MYSUFFIXBE)
  69. topology.standalone.log.info("\n\n######################### Generate Test data ######################\n")
  70. # get tmp dir
  71. mytmp = topology.standalone.getDir(__file__, TMP_DIR)
  72. if mytmp is None:
  73. mytmp = "/tmp"
  74. MYLDIF = '%s%s' % (mytmp, _MYLDIF)
  75. os.system('ls %s' % MYLDIF)
  76. os.system('rm -f %s' % MYLDIF)
  77. if hasattr(topology.standalone, 'prefix'):
  78. prefix = topology.standalone.prefix
  79. else:
  80. prefix = None
  81. dbgen_prog = prefix + '/bin/dbgen.pl'
  82. topology.standalone.log.info('dbgen_prog: %s' % dbgen_prog)
  83. os.system('%s -s %s -o %s -n 14' % (dbgen_prog, MYSUFFIX, MYLDIF))
  84. cmdline = 'egrep dn: %s | wc -l' % MYLDIF
  85. p = os.popen(cmdline, "r")
  86. dnnumstr = p.readline()
  87. global dnnum
  88. dnnum = int(dnnumstr)
  89. topology.standalone.log.info("We have %d entries.\n", dnnum)
  90. topology.standalone.log.info("\n\n######################### Import Test data ######################\n")
  91. args = {TASK_WAIT: True}
  92. importTask = Tasks(topology.standalone)
  93. importTask.importLDIF(MYSUFFIX, MYSUFFIXBE, MYLDIF, args)
  94. topology.standalone.log.info("\n\n######################### SEARCH ALL ######################\n")
  95. topology.standalone.log.info("Bind as %s and add the READ/SEARCH SELFDN aci" % DN_DM)
  96. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  97. global entries
  98. entries = topology.standalone.search_s(MYSUFFIX, ldap.SCOPE_SUBTREE, SEARCHFILTER)
  99. topology.standalone.log.info("Returned %d entries.\n", len(entries))
  100. #print entries
  101. assert dnnum == len(entries)
  102. topology.standalone.log.info('%d entries are successfully imported.' % dnnum)
  103. def test_ticket48191_run_0(topology):
  104. topology.standalone.log.info("\n\n######################### SEARCH WITH SIMPLE PAGED RESULTS CONTROL (no nsslapd-maxsimplepaged-per-conn) ######################\n")
  105. page_size = 4
  106. spr_req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
  107. known_ldap_resp_ctrls = {
  108. SimplePagedResultsControl.controlType: SimplePagedResultsControl,
  109. }
  110. topology.standalone.log.info("Calling search_ext...")
  111. msgid = topology.standalone.search_ext(MYSUFFIX,
  112. ldap.SCOPE_SUBTREE,
  113. SEARCHFILTER,
  114. ['cn'],
  115. serverctrls=[spr_req_ctrl])
  116. pageddncnt = 0
  117. pages = 0
  118. while True:
  119. pages += 1
  120. topology.standalone.log.info("Getting page %d" % pages)
  121. rtype, rdata, rmsgid, responcectrls = topology.standalone.result3(msgid, resp_ctrl_classes=known_ldap_resp_ctrls)
  122. topology.standalone.log.info("%d results" % len(rdata))
  123. pageddncnt += len(rdata)
  124. topology.standalone.log.info("Results:")
  125. for dn, attrs in rdata:
  126. topology.standalone.log.info("dn: %s" % dn)
  127. pctrls = [
  128. c for c in responcectrls if c.controlType == SimplePagedResultsControl.controlType
  129. ]
  130. if not pctrls:
  131. topology.standalone.log.info('Warning: Server ignores RFC 2696 control.')
  132. break
  133. if pctrls[0].cookie:
  134. spr_req_ctrl.cookie = pctrls[0].cookie
  135. topology.standalone.log.info("cookie: %s" % spr_req_ctrl.cookie)
  136. msgid = topology.standalone.search_ext(MYSUFFIX,
  137. ldap.SCOPE_SUBTREE,
  138. SEARCHFILTER,
  139. ['cn'],
  140. serverctrls=[spr_req_ctrl])
  141. else:
  142. topology.standalone.log.info("No cookie")
  143. break
  144. topology.standalone.log.info("Paged result search returned %d entries in %d pages.\n", pageddncnt, pages)
  145. global dnnum
  146. global entries
  147. assert dnnum == len(entries)
  148. assert pages == (dnnum / page_size)
  149. def test_ticket48191_run_1(topology):
  150. topology.standalone.log.info("\n\n######################### SEARCH WITH SIMPLE PAGED RESULTS CONTROL (nsslapd-maxsimplepaged-per-conn: 0) ######################\n")
  151. topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-maxsimplepaged-per-conn', '0')])
  152. page_size = 4
  153. spr_req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
  154. known_ldap_resp_ctrls = {
  155. SimplePagedResultsControl.controlType: SimplePagedResultsControl,
  156. }
  157. topology.standalone.log.info("Calling search_ext...")
  158. msgid = topology.standalone.search_ext(MYSUFFIX,
  159. ldap.SCOPE_SUBTREE,
  160. SEARCHFILTER,
  161. ['cn'],
  162. serverctrls=[spr_req_ctrl])
  163. topology.standalone.log.fatal('Unexpected success')
  164. try:
  165. rtype, rdata, rmsgid, responcectrls = topology.standalone.result3(msgid, resp_ctrl_classes=known_ldap_resp_ctrls)
  166. except ldap.UNWILLING_TO_PERFORM, e:
  167. topology.standalone.log.info('Returned the expected RC UNWILLING_TO_PERFORM')
  168. return
  169. except ldap.LDAPError, e:
  170. topology.standalone.log.fatal('Unexpected error: ' + e.message['desc'])
  171. assert False
  172. topology.standalone.log.info("Type %d" % rtype)
  173. topology.standalone.log.info("%d results" % len(rdata))
  174. assert False
  175. def test_ticket48191_run_2(topology):
  176. topology.standalone.log.info("\n\n######################### SEARCH WITH SIMPLE PAGED RESULTS CONTROL (nsslapd-maxsimplepaged-per-conn: 1000) ######################\n")
  177. topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-maxsimplepaged-per-conn', '1000')])
  178. page_size = 4
  179. spr_req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
  180. known_ldap_resp_ctrls = {
  181. SimplePagedResultsControl.controlType: SimplePagedResultsControl,
  182. }
  183. topology.standalone.log.info("Calling search_ext...")
  184. msgid = topology.standalone.search_ext(MYSUFFIX,
  185. ldap.SCOPE_SUBTREE,
  186. SEARCHFILTER,
  187. ['cn'],
  188. serverctrls=[spr_req_ctrl])
  189. pageddncnt = 0
  190. pages = 0
  191. while True:
  192. pages += 1
  193. topology.standalone.log.info("Getting page %d" % pages)
  194. rtype, rdata, rmsgid, responcectrls = topology.standalone.result3(msgid, resp_ctrl_classes=known_ldap_resp_ctrls)
  195. topology.standalone.log.info("%d results" % len(rdata))
  196. pageddncnt += len(rdata)
  197. topology.standalone.log.info("Results:")
  198. for dn, attrs in rdata:
  199. topology.standalone.log.info("dn: %s" % dn)
  200. pctrls = [
  201. c for c in responcectrls if c.controlType == SimplePagedResultsControl.controlType
  202. ]
  203. if not pctrls:
  204. topology.standalone.log.info('Warning: Server ignores RFC 2696 control.')
  205. break
  206. if pctrls[0].cookie:
  207. spr_req_ctrl.cookie = pctrls[0].cookie
  208. topology.standalone.log.info("cookie: %s" % spr_req_ctrl.cookie)
  209. msgid = topology.standalone.search_ext(MYSUFFIX,
  210. ldap.SCOPE_SUBTREE,
  211. SEARCHFILTER,
  212. ['cn'],
  213. serverctrls=[spr_req_ctrl])
  214. else:
  215. topology.standalone.log.info("No cookie")
  216. break
  217. topology.standalone.log.info("Paged result search returned %d entries in %d pages.\n", pageddncnt, pages)
  218. global dnnum
  219. global entries
  220. assert dnnum == len(entries)
  221. assert pages == (dnnum / page_size)
  222. topology.standalone.log.info("ticket48191 was successfully verified.")
  223. def test_ticket48191_final(topology):
  224. topology.standalone.delete()
  225. log.info('Testcase PASSED')
  226. def run_isolated():
  227. '''
  228. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  229. To run isolated without py.test, you need to
  230. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  231. - set the installation prefix
  232. - run this program
  233. '''
  234. global installation_prefix
  235. installation_prefix = None
  236. topo = topology(True)
  237. test_ticket48191_setup(topo)
  238. test_ticket48191_run_0(topo)
  239. test_ticket48191_run_1(topo)
  240. test_ticket48191_run_2(topo)
  241. test_ticket48191_final(topo)
  242. if __name__ == '__main__':
  243. run_isolated()