ticket47824_test.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2015 Red Hat, Inc.
  3. # All rights reserved.
  4. #
  5. # License: GPL (version 3 or any later version).
  6. # See LICENSE for details.
  7. # --- END COPYRIGHT BLOCK ---
  8. #
  9. import os
  10. import sys
  11. import time
  12. import ldap
  13. import logging
  14. import pytest
  15. from lib389 import DirSrv, Entry, tools, tasks
  16. from lib389.tools import DirSrvTools
  17. from lib389._constants import *
  18. from lib389.properties import *
  19. from lib389.tasks import *
  20. from ldap.controls import SimplePagedResultsControl
  21. log = logging.getLogger(__name__)
  22. installation_prefix = None
  23. MYSUFFIX = 'o=ticket47824.org'
  24. MYSUFFIXBE = 'ticket47824'
  25. SUBSUFFIX0 = 'ou=OU0,o=ticket47824.org'
  26. SUBSUFFIX0BE = 'OU0'
  27. SUBSUFFIX1 = 'ou=OU1,o=ticket47824.org'
  28. SUBSUFFIX1BE = 'OU1'
  29. SUBSUFFIX2 = 'ou=OU2,o=ticket47824.org'
  30. SUBSUFFIX2BE = 'OU2'
  31. _MYLDIF = 'ticket47824.ldif'
  32. _SUBLDIF0TMP = 'ticket47824_0.tmp'
  33. _SUBLDIF0 = 'ticket47824_0.ldif'
  34. _SUBLDIF1TMP = 'ticket47824_1.tmp'
  35. _SUBLDIF1 = 'ticket47824_1.ldif'
  36. _SUBLDIF2TMP = 'ticket47824_2.tmp'
  37. _SUBLDIF2 = 'ticket47824_2.ldif'
  38. SEARCHFILTER = '(objectclass=*)'
  39. class TopologyStandalone(object):
  40. def __init__(self, standalone):
  41. standalone.open()
  42. self.standalone = standalone
  43. @pytest.fixture(scope="module")
  44. def topology(request):
  45. '''
  46. This fixture is used to standalone topology for the 'module'.
  47. '''
  48. global installation_prefix
  49. if installation_prefix:
  50. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  51. standalone = DirSrv(verbose=False)
  52. # Args for the standalone instance
  53. args_instance[SER_HOST] = HOST_STANDALONE
  54. args_instance[SER_PORT] = PORT_STANDALONE
  55. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  56. args_standalone = args_instance.copy()
  57. standalone.allocate(args_standalone)
  58. # Get the status of the instance and restart it if it exists
  59. instance_standalone = standalone.exists()
  60. # Remove the instance
  61. if instance_standalone:
  62. standalone.delete()
  63. # Create the instance
  64. standalone.create()
  65. # Used to retrieve configuration information (dbdir, confdir...)
  66. standalone.open()
  67. # clear the tmp directory
  68. standalone.clearTmpDir(__file__)
  69. # Here we have standalone instance up and running
  70. return TopologyStandalone(standalone)
  71. def test_ticket47824_run(topology):
  72. """
  73. Add 3 sub suffixes under the primary suffix
  74. Import 16 entries each
  75. Search with Simple Paged Results Control from the primary suffix (pagesize = 4)
  76. If all of them are returned, the bug is verified
  77. """
  78. log.info('Testing Ticket 47824 - paged results control is not working in some cases when we have a subsuffix')
  79. # bind as directory manager
  80. topology.standalone.log.info("Bind as %s" % DN_DM)
  81. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  82. topology.standalone.log.info("\n\n######################### SETUP SUFFIX o=ticket47824.org ######################\n")
  83. topology.standalone.backend.create(MYSUFFIX, {BACKEND_NAME: MYSUFFIXBE})
  84. topology.standalone.mappingtree.create(MYSUFFIX, bename=MYSUFFIXBE)
  85. topology.standalone.log.info("\n\n######################### SETUP SUB SUFFIX ou=OU0 ######################\n")
  86. topology.standalone.backend.create(SUBSUFFIX0, {BACKEND_NAME: SUBSUFFIX0BE})
  87. topology.standalone.mappingtree.create(SUBSUFFIX0, bename=SUBSUFFIX0BE, parent=MYSUFFIX)
  88. topology.standalone.log.info("\n\n######################### SETUP SUB SUFFIX ou=OU1 ######################\n")
  89. topology.standalone.backend.create(SUBSUFFIX1, {BACKEND_NAME: SUBSUFFIX1BE})
  90. topology.standalone.mappingtree.create(SUBSUFFIX1, bename=SUBSUFFIX1BE, parent=MYSUFFIX)
  91. topology.standalone.log.info("\n\n######################### SETUP SUB SUFFIX ou=OU2 ######################\n")
  92. topology.standalone.backend.create(SUBSUFFIX2, {BACKEND_NAME: SUBSUFFIX2BE})
  93. topology.standalone.mappingtree.create(SUBSUFFIX2, bename=SUBSUFFIX2BE, parent=MYSUFFIX)
  94. topology.standalone.log.info("\n\n######################### Generate Test data ######################\n")
  95. # get tmp dir
  96. mytmp = topology.standalone.getDir(__file__, TMP_DIR)
  97. if mytmp is None:
  98. mytmp = "/tmp"
  99. MYLDIF = '%s%s' % (mytmp, _MYLDIF)
  100. SUBLDIF0TMP = '%s%s' % (mytmp, _SUBLDIF0TMP)
  101. SUBLDIF0 = '%s%s' % (mytmp, _SUBLDIF0)
  102. SUBLDIF1TMP = '%s%s' % (mytmp, _SUBLDIF1TMP)
  103. SUBLDIF1 = '%s%s' % (mytmp, _SUBLDIF1)
  104. SUBLDIF2TMP = '%s%s' % (mytmp, _SUBLDIF2TMP)
  105. SUBLDIF2 = '%s%s' % (mytmp, _SUBLDIF2)
  106. os.system('ls %s' % MYLDIF)
  107. os.system('ls %s' % SUBLDIF0TMP)
  108. os.system('ls %s' % SUBLDIF1TMP)
  109. os.system('ls %s' % SUBLDIF2TMP)
  110. os.system('rm -f %s' % MYLDIF)
  111. os.system('rm -f %s' % SUBLDIF0TMP)
  112. os.system('rm -f %s' % SUBLDIF1TMP)
  113. os.system('rm -f %s' % SUBLDIF2TMP)
  114. if hasattr(topology.standalone, 'prefix'):
  115. prefix = topology.standalone.prefix
  116. else:
  117. prefix = None
  118. dbgen_prog = prefix + '/bin/dbgen.pl'
  119. topology.standalone.log.info('dbgen: %s' % dbgen_prog)
  120. os.system('%s -s %s -o %s -n 10' % (dbgen_prog, MYSUFFIX, MYLDIF))
  121. os.system('%s -s %s -o %s -n 10' % (dbgen_prog, SUBSUFFIX0, SUBLDIF0TMP))
  122. os.system('%s -s %s -o %s -n 10' % (dbgen_prog, SUBSUFFIX1, SUBLDIF1TMP))
  123. os.system('%s -s %s -o %s -n 10' % (dbgen_prog, SUBSUFFIX2, SUBLDIF2TMP))
  124. os.system('cat %s | sed -e "s/\<objectClass: organization\>/objectClass: organizationalUnit/" | sed -e "/^o:.*/d" > %s' % (SUBLDIF0TMP, SUBLDIF0))
  125. os.system('cat %s | sed -e "s/\<objectClass: organization\>/objectClass: organizationalUnit/" | sed -e "/^o:.*/d" > %s' % (SUBLDIF1TMP, SUBLDIF1))
  126. os.system('cat %s | sed -e "s/\<objectClass: organization\>/objectClass: organizationalUnit/" | sed -e "/^o:.*/d" > %s' % (SUBLDIF2TMP, SUBLDIF2))
  127. cmdline = 'egrep dn: %s %s %s %s | wc -l' % (MYLDIF, SUBLDIF0, SUBLDIF1, SUBLDIF2)
  128. p = os.popen(cmdline, "r")
  129. dnnumstr = p.readline()
  130. dnnum = int(dnnumstr)
  131. topology.standalone.log.info("We have %d entries.\n", dnnum)
  132. topology.standalone.log.info("\n\n######################### Import Test data ######################\n")
  133. args = {TASK_WAIT: True}
  134. importTask = Tasks(topology.standalone)
  135. importTask.importLDIF(MYSUFFIX, MYSUFFIXBE, MYLDIF, args)
  136. importTask.importLDIF(SUBSUFFIX0, SUBSUFFIX0BE, SUBLDIF0, args)
  137. importTask.importLDIF(SUBSUFFIX1, SUBSUFFIX1BE, SUBLDIF1, args)
  138. importTask.importLDIF(SUBSUFFIX2, SUBSUFFIX2BE, SUBLDIF2, args)
  139. topology.standalone.log.info("\n\n######################### SEARCH ALL ######################\n")
  140. topology.standalone.log.info("Bind as %s and add the READ/SEARCH SELFDN aci" % DN_DM)
  141. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  142. entries = topology.standalone.search_s(MYSUFFIX, ldap.SCOPE_SUBTREE, SEARCHFILTER)
  143. topology.standalone.log.info("Returned %d entries.\n", len(entries))
  144. #print entries
  145. assert dnnum == len(entries)
  146. topology.standalone.log.info('%d entries are successfully imported.' % dnnum)
  147. topology.standalone.log.info("\n\n######################### SEARCH WITH SIMPLE PAGED RESULTS CONTROL ######################\n")
  148. page_size = 4
  149. req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
  150. known_ldap_resp_ctrls = {
  151. SimplePagedResultsControl.controlType: SimplePagedResultsControl,
  152. }
  153. topology.standalone.log.info("Calling search_ext...")
  154. msgid = topology.standalone.search_ext(MYSUFFIX, ldap.SCOPE_SUBTREE, SEARCHFILTER, None, serverctrls=[req_ctrl])
  155. pageddncnt = 0
  156. pages = 0
  157. while True:
  158. pages += 1
  159. topology.standalone.log.info("Getting page %d" % pages)
  160. rtype, rdata, rmsgid, serverctrls = topology.standalone.result3(msgid, resp_ctrl_classes=known_ldap_resp_ctrls)
  161. topology.standalone.log.info("%d results" % len(rdata))
  162. pageddncnt += len(rdata)
  163. topology.standalone.log.info("Results:")
  164. for dn, attrs in rdata:
  165. topology.standalone.log.info("dn: %s" % dn)
  166. pctrls = [
  167. c for c in serverctrls if c.controlType == SimplePagedResultsControl.controlType
  168. ]
  169. if not pctrls:
  170. topology.standalone.log.info('Warning: Server ignores RFC 2696 control.')
  171. break
  172. if pctrls[0].cookie:
  173. req_ctrl.cookie = pctrls[0].cookie
  174. topology.standalone.log.info("cookie: %s" % req_ctrl.cookie)
  175. msgid = topology.standalone.search_ext(MYSUFFIX,
  176. ldap.SCOPE_SUBTREE,
  177. SEARCHFILTER,
  178. None,
  179. serverctrls=[req_ctrl])
  180. else:
  181. topology.standalone.log.info("No cookie")
  182. break
  183. topology.standalone.log.info("Paged result search returned %d entries.\n", pageddncnt)
  184. assert dnnum == len(entries)
  185. topology.standalone.log.info("ticket47824 was successfully verified.")
  186. def test_ticket47824_final(topology):
  187. topology.standalone.delete()
  188. log.info('Testcase PASSED')
  189. def run_isolated():
  190. '''
  191. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  192. To run isolated without py.test, you need to
  193. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  194. - set the installation prefix
  195. - run this program
  196. '''
  197. global installation_prefix
  198. installation_prefix = None
  199. topo = topology(True)
  200. test_ticket47824_run(topo)
  201. test_ticket47824_final(topo)
  202. if __name__ == '__main__':
  203. run_isolated()