ticket47920_test.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import os
  2. import sys
  3. import time
  4. import ldap
  5. import logging
  6. import socket
  7. import time
  8. import logging
  9. import pytest
  10. import re
  11. from lib389 import DirSrv, Entry, tools
  12. from lib389.tools import DirSrvTools
  13. from lib389._constants import *
  14. from lib389.properties import *
  15. from constants import *
  16. from ldap.controls.readentry import PreReadControl,PostReadControl
  17. SCOPE_IN_CN = 'in'
  18. SCOPE_OUT_CN = 'out'
  19. SCOPE_IN_DN = 'cn=%s,%s' % (SCOPE_IN_CN, SUFFIX)
  20. SCOPE_OUT_DN = 'cn=%s,%s' % (SCOPE_OUT_CN, SUFFIX)
  21. PROVISIONING_CN = "provisioning"
  22. PROVISIONING_DN = "cn=%s,%s" % (PROVISIONING_CN, SCOPE_IN_DN)
  23. ACTIVE_CN = "accounts"
  24. STAGE_CN = "staged users"
  25. DELETE_CN = "deleted users"
  26. ACTIVE_DN = "cn=%s,%s" % (ACTIVE_CN, SCOPE_IN_DN)
  27. STAGE_DN = "cn=%s,%s" % (STAGE_CN, PROVISIONING_DN)
  28. DELETE_DN = "cn=%s,%s" % (DELETE_CN, PROVISIONING_DN)
  29. STAGE_USER_CN = "stage guy"
  30. STAGE_USER_DN = "cn=%s,%s" % (STAGE_USER_CN, STAGE_DN)
  31. ACTIVE_USER_CN = "active guy"
  32. ACTIVE_USER_DN = "cn=%s,%s" % (ACTIVE_USER_CN, ACTIVE_DN)
  33. OUT_USER_CN = "out guy"
  34. OUT_USER_DN = "cn=%s,%s" % (OUT_USER_CN, SCOPE_OUT_DN)
  35. STAGE_GROUP_CN = "stage group"
  36. STAGE_GROUP_DN = "cn=%s,%s" % (STAGE_GROUP_CN, STAGE_DN)
  37. ACTIVE_GROUP_CN = "active group"
  38. ACTIVE_GROUP_DN = "cn=%s,%s" % (ACTIVE_GROUP_CN, ACTIVE_DN)
  39. OUT_GROUP_CN = "out group"
  40. OUT_GROUP_DN = "cn=%s,%s" % (OUT_GROUP_CN, SCOPE_OUT_DN)
  41. INDIRECT_ACTIVE_GROUP_CN = "indirect active group"
  42. INDIRECT_ACTIVE_GROUP_DN = "cn=%s,%s" % (INDIRECT_ACTIVE_GROUP_CN, ACTIVE_DN)
  43. INITIAL_DESC="inital description"
  44. FINAL_DESC ="final description"
  45. log = logging.getLogger(__name__)
  46. installation_prefix = None
  47. class TopologyStandalone(object):
  48. def __init__(self, standalone):
  49. standalone.open()
  50. self.standalone = standalone
  51. @pytest.fixture(scope="module")
  52. def topology(request):
  53. '''
  54. This fixture is used to standalone topology for the 'module'.
  55. At the beginning, It may exists a standalone instance.
  56. It may also exists a backup for the standalone instance.
  57. Principle:
  58. If standalone instance exists:
  59. restart it
  60. If backup of standalone exists:
  61. create/rebind to standalone
  62. restore standalone instance from backup
  63. else:
  64. Cleanup everything
  65. remove instance
  66. remove backup
  67. Create instance
  68. Create backup
  69. '''
  70. global installation_prefix
  71. if installation_prefix:
  72. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  73. standalone = DirSrv(verbose=False)
  74. # Args for the standalone instance
  75. args_instance[SER_HOST] = HOST_STANDALONE
  76. args_instance[SER_PORT] = PORT_STANDALONE
  77. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  78. args_standalone = args_instance.copy()
  79. standalone.allocate(args_standalone)
  80. # Get the status of the backups
  81. backup_standalone = standalone.checkBackupFS()
  82. # Get the status of the instance and restart it if it exists
  83. instance_standalone = standalone.exists()
  84. if instance_standalone:
  85. # assuming the instance is already stopped, just wait 5 sec max
  86. standalone.stop(timeout=5)
  87. standalone.start(timeout=10)
  88. if backup_standalone:
  89. # The backup exist, assuming it is correct
  90. # we just re-init the instance with it
  91. if not instance_standalone:
  92. standalone.create()
  93. # Used to retrieve configuration information (dbdir, confdir...)
  94. standalone.open()
  95. # restore standalone instance from backup
  96. standalone.stop(timeout=10)
  97. standalone.restoreFS(backup_standalone)
  98. standalone.start(timeout=10)
  99. else:
  100. # We should be here only in two conditions
  101. # - This is the first time a test involve standalone instance
  102. # - Something weird happened (instance/backup destroyed)
  103. # so we discard everything and recreate all
  104. # Remove the backup. So even if we have a specific backup file
  105. # (e.g backup_standalone) we clear backup that an instance may have created
  106. if backup_standalone:
  107. standalone.clearBackupFS()
  108. # Remove the instance
  109. if instance_standalone:
  110. standalone.delete()
  111. # Create the instance
  112. standalone.create()
  113. # Used to retrieve configuration information (dbdir, confdir...)
  114. standalone.open()
  115. # Time to create the backups
  116. standalone.stop(timeout=10)
  117. standalone.backupfile = standalone.backupFS()
  118. standalone.start(timeout=10)
  119. # clear the tmp directory
  120. standalone.clearTmpDir(__file__)
  121. #
  122. # Here we have standalone instance up and running
  123. # Either coming from a backup recovery
  124. # or from a fresh (re)init
  125. # Time to return the topology
  126. return TopologyStandalone(standalone)
  127. def _header(topology, label):
  128. topology.standalone.log.info("\n\n###############################################")
  129. topology.standalone.log.info("#######")
  130. topology.standalone.log.info("####### %s" % label)
  131. topology.standalone.log.info("#######")
  132. topology.standalone.log.info("###############################################")
  133. def _add_user(topology, type='active'):
  134. if type == 'active':
  135. topology.standalone.add_s(Entry((ACTIVE_USER_DN, {
  136. 'objectclass': "top person inetuser".split(),
  137. 'sn': ACTIVE_USER_CN,
  138. 'cn': ACTIVE_USER_CN,
  139. 'description': INITIAL_DESC})))
  140. elif type == 'stage':
  141. topology.standalone.add_s(Entry((STAGE_USER_DN, {
  142. 'objectclass': "top person inetuser".split(),
  143. 'sn': STAGE_USER_CN,
  144. 'cn': STAGE_USER_CN})))
  145. else:
  146. topology.standalone.add_s(Entry((OUT_USER_DN, {
  147. 'objectclass': "top person inetuser".split(),
  148. 'sn': OUT_USER_CN,
  149. 'cn': OUT_USER_CN})))
  150. def test_ticket47920_init(topology):
  151. topology.standalone.add_s(Entry((SCOPE_IN_DN, {
  152. 'objectclass': "top nscontainer".split(),
  153. 'cn': SCOPE_IN_DN})))
  154. topology.standalone.add_s(Entry((ACTIVE_DN, {
  155. 'objectclass': "top nscontainer".split(),
  156. 'cn': ACTIVE_CN})))
  157. # add users
  158. _add_user(topology, 'active')
  159. def test_ticket47920_mod_readentry_ctrl(topology):
  160. _header(topology, 'MOD: with a readentry control')
  161. topology.standalone.log.info("Check the initial value of the entry")
  162. ent = topology.standalone.getEntry(ACTIVE_USER_DN, ldap.SCOPE_BASE, "(objectclass=*)", ['description'])
  163. assert ent.hasAttr('description')
  164. assert ent.getValue('description') == INITIAL_DESC
  165. pr = PostReadControl(criticality=True,attrList=['cn', 'description'])
  166. _,_,_,resp_ctrls = topology.standalone.modify_ext_s(ACTIVE_USER_DN, [(ldap.MOD_REPLACE, 'description', [FINAL_DESC])], serverctrls= [pr])
  167. assert resp_ctrls[0].dn == ACTIVE_USER_DN
  168. assert resp_ctrls[0].entry.has_key('description')
  169. assert resp_ctrls[0].entry.has_key('cn')
  170. print resp_ctrls[0].entry['description']
  171. ent = topology.standalone.getEntry(ACTIVE_USER_DN, ldap.SCOPE_BASE, "(objectclass=*)", ['description'])
  172. assert ent.hasAttr('description')
  173. assert ent.getValue('description') == FINAL_DESC
  174. def test_ticket47920_final(topology):
  175. topology.standalone.stop(timeout=10)
  176. def run_isolated():
  177. '''
  178. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  179. To run isolated without py.test, you need to
  180. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  181. - set the installation prefix
  182. - run this program
  183. '''
  184. global installation_prefix
  185. installation_prefix = None
  186. topo = topology(True)
  187. test_ticket47920_init(topo)
  188. test_ticket47920_mod_readentry_ctrl(topo)
  189. test_ticket47920_final(topo)
  190. if __name__ == '__main__':
  191. run_isolated()