ticket47808_test.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. from lib389 import DirSrv, Entry, tools
  11. from lib389.tools import DirSrvTools
  12. from lib389._constants import *
  13. from lib389.properties import *
  14. from constants import *
  15. log = logging.getLogger(__name__)
  16. installation_prefix = None
  17. ATTRIBUTE_UNIQUENESS_PLUGIN = 'cn=attribute uniqueness,cn=plugins,cn=config'
  18. ENTRY_NAME = 'test_entry'
  19. class TopologyStandalone(object):
  20. def __init__(self, standalone):
  21. standalone.open()
  22. self.standalone = standalone
  23. @pytest.fixture(scope="module")
  24. def topology(request):
  25. '''
  26. This fixture is used to standalone topology for the 'module'.
  27. At the beginning, It may exists a standalone instance.
  28. It may also exists a backup for the standalone instance.
  29. Principle:
  30. If standalone instance exists:
  31. restart it
  32. If backup of standalone exists:
  33. create/rebind to standalone
  34. restore standalone instance from backup
  35. else:
  36. Cleanup everything
  37. remove instance
  38. remove backup
  39. Create instance
  40. Create backup
  41. '''
  42. global installation_prefix
  43. if installation_prefix:
  44. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  45. standalone = DirSrv(verbose=True)
  46. # Args for the standalone instance
  47. args_instance[SER_HOST] = HOST_STANDALONE
  48. args_instance[SER_PORT] = PORT_STANDALONE
  49. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  50. args_standalone = args_instance.copy()
  51. standalone.allocate(args_standalone)
  52. # Get the status of the backups
  53. backup_standalone = standalone.checkBackupFS()
  54. # Get the status of the instance and restart it if it exists
  55. instance_standalone = standalone.exists()
  56. if instance_standalone:
  57. # assuming the instance is already stopped, just wait 5 sec max
  58. standalone.stop(timeout=5)
  59. standalone.start(timeout=10)
  60. if backup_standalone:
  61. # The backup exist, assuming it is correct
  62. # we just re-init the instance with it
  63. if not instance_standalone:
  64. standalone.create()
  65. # Used to retrieve configuration information (dbdir, confdir...)
  66. standalone.open()
  67. # restore standalone instance from backup
  68. standalone.stop(timeout=10)
  69. standalone.restoreFS(backup_standalone)
  70. standalone.start(timeout=10)
  71. else:
  72. # We should be here only in two conditions
  73. # - This is the first time a test involve standalone instance
  74. # - Something weird happened (instance/backup destroyed)
  75. # so we discard everything and recreate all
  76. # Remove the backup. So even if we have a specific backup file
  77. # (e.g backup_standalone) we clear backup that an instance may have created
  78. if backup_standalone:
  79. standalone.clearBackupFS()
  80. # Remove the instance
  81. if instance_standalone:
  82. standalone.delete()
  83. # Create the instance
  84. standalone.create()
  85. # Used to retrieve configuration information (dbdir, confdir...)
  86. standalone.open()
  87. # Time to create the backups
  88. standalone.stop(timeout=10)
  89. standalone.backupfile = standalone.backupFS()
  90. standalone.start(timeout=10)
  91. #
  92. # Here we have standalone instance up and running
  93. # Either coming from a backup recovery
  94. # or from a fresh (re)init
  95. # Time to return the topology
  96. return TopologyStandalone(standalone)
  97. def test_ticket47808_run(topology):
  98. """
  99. It enables attribute uniqueness plugin with sn as a unique attribute
  100. Add an entry 1 with sn = ENTRY_NAME
  101. Add an entry 2 with sn = ENTRY_NAME
  102. If the second add does not crash the server and the following search found none,
  103. the bug is fixed.
  104. """
  105. # bind as directory manager
  106. topology.standalone.log.info("Bind as %s" % DN_DM)
  107. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  108. topology.standalone.log.info("\n\n######################### SETUP ATTR UNIQ PLUGIN ######################\n")
  109. # enable attribute uniqueness plugin
  110. mod = [(ldap.MOD_REPLACE, 'nsslapd-pluginEnabled', 'on'), (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'sn'), (ldap.MOD_REPLACE, 'nsslapd-pluginarg1', SUFFIX)]
  111. topology.standalone.modify_s(ATTRIBUTE_UNIQUENESS_PLUGIN, mod)
  112. topology.standalone.log.info("\n\n######################### ADD USER 1 ######################\n")
  113. # Prepare entry 1
  114. entry_name = '%s 1' % (ENTRY_NAME)
  115. entry_dn_1 = 'cn=%s, %s' % (entry_name, SUFFIX)
  116. entry_1 = Entry(entry_dn_1)
  117. entry_1.setValues('objectclass', 'top', 'person')
  118. entry_1.setValues('sn', ENTRY_NAME)
  119. entry_1.setValues('cn', entry_name)
  120. topology.standalone.log.info("Try to add Add %s: %r" % (entry_1, entry_1))
  121. topology.standalone.add_s(entry_1)
  122. topology.standalone.log.info("\n\n######################### Restart Server ######################\n")
  123. topology.standalone.stop(timeout=10)
  124. topology.standalone.start(timeout=10)
  125. topology.standalone.log.info("\n\n######################### ADD USER 2 ######################\n")
  126. # Prepare entry 2 having the same sn, which crashes the server
  127. entry_name = '%s 2' % (ENTRY_NAME)
  128. entry_dn_2 = 'cn=%s, %s' % (entry_name, SUFFIX)
  129. entry_2 = Entry(entry_dn_2)
  130. entry_2.setValues('objectclass', 'top', 'person')
  131. entry_2.setValues('sn', ENTRY_NAME)
  132. entry_2.setValues('cn', entry_name)
  133. topology.standalone.log.info("Try to add Add %s: %r" % (entry_2, entry_2))
  134. try:
  135. topology.standalone.add_s(entry_2)
  136. except:
  137. topology.standalone.log.warn("Adding %s failed" % entry_dn_2)
  138. pass
  139. topology.standalone.log.info("\n\n######################### IS SERVER UP? ######################\n")
  140. ents = topology.standalone.search_s(entry_dn_1, ldap.SCOPE_BASE, '(objectclass=*)')
  141. assert len(ents) == 1
  142. topology.standalone.log.info("Yes, it's up.")
  143. topology.standalone.log.info("\n\n######################### CHECK USER 2 NOT ADDED ######################\n")
  144. topology.standalone.log.info("Try to search %s" % entry_dn_2)
  145. try:
  146. ents = topology.standalone.search_s(entry_dn_2, ldap.SCOPE_BASE, '(objectclass=*)')
  147. except ldap.NO_SUCH_OBJECT:
  148. topology.standalone.log.info("Found none")
  149. topology.standalone.log.info("\n\n######################### DELETE USER 1 ######################\n")
  150. topology.standalone.log.info("Try to delete %s " % entry_dn_1)
  151. topology.standalone.delete_s(entry_dn_1)
  152. def test_ticket47808_final(topology):
  153. topology.standalone.stop(timeout=10)
  154. def run_isolated():
  155. '''
  156. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  157. To run isolated without py.test, you need to
  158. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  159. - set the installation prefix
  160. - run this program
  161. '''
  162. global installation_prefix
  163. installation_prefix = None
  164. topo = topology(True)
  165. test_ticket47808_run(topo)
  166. test_ticket47808_final(topo)
  167. if __name__ == '__main__':
  168. run_isolated()