ticket47664_test.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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. from ldap.controls.simple import GetEffectiveRightsControl
  22. log = logging.getLogger(__name__)
  23. installation_prefix = None
  24. MYSUFFIX = 'o=ticket47664.org'
  25. MYSUFFIXBE = 'ticket47664'
  26. _MYLDIF = 'ticket47664.ldif'
  27. SEARCHFILTER = '(objectclass=*)'
  28. class TopologyStandalone(object):
  29. def __init__(self, standalone):
  30. standalone.open()
  31. self.standalone = standalone
  32. @pytest.fixture(scope="module")
  33. def topology(request):
  34. '''
  35. This fixture is used to standalone topology for the 'module'.
  36. '''
  37. global installation_prefix
  38. if installation_prefix:
  39. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  40. standalone = DirSrv(verbose=False)
  41. # Args for the standalone instance
  42. args_instance[SER_HOST] = HOST_STANDALONE
  43. args_instance[SER_PORT] = PORT_STANDALONE
  44. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  45. args_standalone = args_instance.copy()
  46. standalone.allocate(args_standalone)
  47. # Get the status of the instance and restart it if it exists
  48. instance_standalone = standalone.exists()
  49. # Remove the instance
  50. if instance_standalone:
  51. standalone.delete()
  52. # Create the instance
  53. standalone.create()
  54. # Used to retrieve configuration information (dbdir, confdir...)
  55. standalone.open()
  56. # clear the tmp directory
  57. standalone.clearTmpDir(__file__)
  58. # Here we have standalone instance up and running
  59. return TopologyStandalone(standalone)
  60. def test_ticket47664_run(topology):
  61. """
  62. Import 20 entries
  63. Search with Simple Paged Results Control (pagesize = 4) + Get Effective Rights Control (attrs list = ['cn'])
  64. If Get Effective Rights attribute (attributeLevelRights for 'cn') is returned 4 attrs / page AND
  65. the page count == 20/4, then the fix is verified.
  66. """
  67. log.info('Testing Ticket 47664 - paged results control is not working in some cases when we have a subsuffix')
  68. # bind as directory manager
  69. topology.standalone.log.info("Bind as %s" % DN_DM)
  70. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  71. topology.standalone.log.info("\n\n######################### SETUP SUFFIX o=ticket47664.org ######################\n")
  72. topology.standalone.backend.create(MYSUFFIX, {BACKEND_NAME: MYSUFFIXBE})
  73. topology.standalone.mappingtree.create(MYSUFFIX, bename=MYSUFFIXBE)
  74. topology.standalone.log.info("\n\n######################### Generate Test data ######################\n")
  75. # get tmp dir
  76. mytmp = topology.standalone.getDir(__file__, TMP_DIR)
  77. if mytmp is None:
  78. mytmp = "/tmp"
  79. MYLDIF = '%s%s' % (mytmp, _MYLDIF)
  80. os.system('ls %s' % MYLDIF)
  81. os.system('rm -f %s' % MYLDIF)
  82. if hasattr(topology.standalone, 'prefix'):
  83. prefix = topology.standalone.prefix
  84. else:
  85. prefix = None
  86. dbgen_prog = prefix + '/bin/dbgen.pl'
  87. topology.standalone.log.info('dbgen_prog: %s' % dbgen_prog)
  88. os.system('%s -s %s -o %s -n 14' % (dbgen_prog, MYSUFFIX, MYLDIF))
  89. cmdline = 'egrep dn: %s | wc -l' % MYLDIF
  90. p = os.popen(cmdline, "r")
  91. dnnumstr = p.readline()
  92. dnnum = int(dnnumstr)
  93. topology.standalone.log.info("We have %d entries.\n", dnnum)
  94. topology.standalone.log.info("\n\n######################### Import Test data ######################\n")
  95. args = {TASK_WAIT: True}
  96. importTask = Tasks(topology.standalone)
  97. importTask.importLDIF(MYSUFFIX, MYSUFFIXBE, MYLDIF, args)
  98. topology.standalone.log.info("\n\n######################### SEARCH ALL ######################\n")
  99. topology.standalone.log.info("Bind as %s and add the READ/SEARCH SELFDN aci" % DN_DM)
  100. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  101. entries = topology.standalone.search_s(MYSUFFIX, ldap.SCOPE_SUBTREE, SEARCHFILTER)
  102. topology.standalone.log.info("Returned %d entries.\n", len(entries))
  103. #print entries
  104. assert dnnum == len(entries)
  105. topology.standalone.log.info('%d entries are successfully imported.' % dnnum)
  106. topology.standalone.log.info("\n\n######################### SEARCH WITH SIMPLE PAGED RESULTS CONTROL ######################\n")
  107. page_size = 4
  108. spr_req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
  109. ger_req_ctrl = GetEffectiveRightsControl(True, "dn: " + DN_DM)
  110. known_ldap_resp_ctrls = {
  111. SimplePagedResultsControl.controlType: SimplePagedResultsControl,
  112. }
  113. topology.standalone.log.info("Calling search_ext...")
  114. msgid = topology.standalone.search_ext(MYSUFFIX,
  115. ldap.SCOPE_SUBTREE,
  116. SEARCHFILTER,
  117. ['cn'],
  118. serverctrls=[spr_req_ctrl, ger_req_ctrl])
  119. attrlevelrightscnt = 0
  120. pageddncnt = 0
  121. pages = 0
  122. while True:
  123. pages += 1
  124. topology.standalone.log.info("Getting page %d" % pages)
  125. rtype, rdata, rmsgid, responcectrls = topology.standalone.result3(msgid, resp_ctrl_classes=known_ldap_resp_ctrls)
  126. topology.standalone.log.info("%d results" % len(rdata))
  127. pageddncnt += len(rdata)
  128. topology.standalone.log.info("Results:")
  129. for dn, attrs in rdata:
  130. topology.standalone.log.info("dn: %s" % dn)
  131. topology.standalone.log.info("attributeLevelRights: %s" % attrs['attributeLevelRights'][0])
  132. if attrs['attributeLevelRights'][0] != "":
  133. attrlevelrightscnt += 1
  134. pctrls = [
  135. c for c in responcectrls if c.controlType == SimplePagedResultsControl.controlType
  136. ]
  137. if not pctrls:
  138. topology.standalone.log.info('Warning: Server ignores RFC 2696 control.')
  139. break
  140. if pctrls[0].cookie:
  141. spr_req_ctrl.cookie = pctrls[0].cookie
  142. topology.standalone.log.info("cookie: %s" % spr_req_ctrl.cookie)
  143. msgid = topology.standalone.search_ext(MYSUFFIX,
  144. ldap.SCOPE_SUBTREE,
  145. SEARCHFILTER,
  146. ['cn'],
  147. serverctrls=[spr_req_ctrl, ger_req_ctrl])
  148. else:
  149. topology.standalone.log.info("No cookie")
  150. break
  151. topology.standalone.log.info("Paged result search returned %d entries in %d pages.\n", pageddncnt, pages)
  152. assert dnnum == len(entries)
  153. assert dnnum == attrlevelrightscnt
  154. assert pages == (dnnum / page_size)
  155. topology.standalone.log.info("ticket47664 was successfully verified.")
  156. def test_ticket47664_final(topology):
  157. topology.standalone.delete()
  158. log.info('Testcase PASSED')
  159. def run_isolated():
  160. '''
  161. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  162. To run isolated without py.test, you need to
  163. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  164. - set the installation prefix
  165. - run this program
  166. '''
  167. global installation_prefix
  168. installation_prefix = None
  169. topo = topology(True)
  170. test_ticket47664_run(topo)
  171. test_ticket47664_final(topo)
  172. if __name__ == '__main__':
  173. run_isolated()