ticket47966_test.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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
  16. from lib389._constants import *
  17. from lib389.properties import *
  18. from lib389.tasks import *
  19. from lib389.utils import *
  20. logging.getLogger(__name__).setLevel(logging.DEBUG)
  21. log = logging.getLogger(__name__)
  22. installation1_prefix = None
  23. m1_m2_agmt = ""
  24. class TopologyReplication(object):
  25. def __init__(self, master1, master2):
  26. master1.open()
  27. self.master1 = master1
  28. master2.open()
  29. self.master2 = master2
  30. @pytest.fixture(scope="module")
  31. def topology(request):
  32. global installation1_prefix
  33. if installation1_prefix:
  34. args_instance[SER_DEPLOYED_DIR] = installation1_prefix
  35. # Creating master 1...
  36. master1 = DirSrv(verbose=False)
  37. args_instance[SER_HOST] = HOST_MASTER_1
  38. args_instance[SER_PORT] = PORT_MASTER_1
  39. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
  40. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  41. args_master = args_instance.copy()
  42. master1.allocate(args_master)
  43. instance_master1 = master1.exists()
  44. if instance_master1:
  45. master1.delete()
  46. master1.create()
  47. master1.open()
  48. master1.replica.enableReplication(suffix=DEFAULT_SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1)
  49. # Creating master 2...
  50. master2 = DirSrv(verbose=False)
  51. args_instance[SER_HOST] = HOST_MASTER_2
  52. args_instance[SER_PORT] = PORT_MASTER_2
  53. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
  54. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  55. args_master = args_instance.copy()
  56. master2.allocate(args_master)
  57. instance_master2 = master2.exists()
  58. if instance_master2:
  59. master2.delete()
  60. master2.create()
  61. master2.open()
  62. master2.replica.enableReplication(suffix=DEFAULT_SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
  63. #
  64. # Create all the agreements
  65. #
  66. # Creating agreement from master 1 to master 2
  67. properties = {RA_NAME: r'meTo_$host:$port',
  68. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  69. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  70. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  71. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  72. global m1_m2_agmt
  73. m1_m2_agmt = master1.agreement.create(suffix=DEFAULT_SUFFIX, host=master2.host, port=master2.port, properties=properties)
  74. if not m1_m2_agmt:
  75. log.fatal("Fail to create a master -> master replica agreement")
  76. sys.exit(1)
  77. log.debug("%s created" % m1_m2_agmt)
  78. # Creating agreement from master 2 to master 1
  79. properties = {RA_NAME: r'meTo_$host:$port',
  80. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  81. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  82. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  83. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  84. m2_m1_agmt = master2.agreement.create(suffix=DEFAULT_SUFFIX, host=master1.host, port=master1.port, properties=properties)
  85. if not m2_m1_agmt:
  86. log.fatal("Fail to create a master -> master replica agreement")
  87. sys.exit(1)
  88. log.debug("%s created" % m2_m1_agmt)
  89. # Allow the replicas to get situated with the new agreements...
  90. time.sleep(5)
  91. #
  92. # Initialize all the agreements
  93. #
  94. master1.agreement.init(DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
  95. master1.waitForReplInit(m1_m2_agmt)
  96. # Check replication is working...
  97. if master1.testReplication(DEFAULT_SUFFIX, master2):
  98. log.info('Replication is working.')
  99. else:
  100. log.fatal('Replication is not working.')
  101. assert False
  102. def fin():
  103. master1.delete()
  104. master2.delete()
  105. request.addfinalizer(fin)
  106. return TopologyReplication(master1, master2)
  107. def test_ticket47966(topology):
  108. '''
  109. Testing bulk import when the backend with VLV was recreated.
  110. If the test passes without the server crash, 47966 is verified.
  111. '''
  112. log.info('Testing Ticket 47966 - [VLV] slapd crashes during Dogtag clone reinstallation')
  113. M1 = topology.master1
  114. M2 = topology.master2
  115. log.info('0. Create a VLV index on Master 2.')
  116. # get the backend entry
  117. be = M2.replica.conn.backend.list(suffix=DEFAULT_SUFFIX)
  118. if not be:
  119. log.fatal("ticket47966: enable to retrieve the backend for %s" % DEFAULT_SUFFIX)
  120. raise ValueError("no backend for suffix %s" % DEFAULT_SUFFIX)
  121. bent = be[0]
  122. beName = bent.getValue('cn')
  123. beDn = "cn=%s,cn=ldbm database,cn=plugins,cn=config" % beName
  124. # generate vlvSearch entry
  125. vlvSrchDn = "cn=vlvSrch,%s" % beDn
  126. log.info('0-1. vlvSearch dn: %s' % vlvSrchDn)
  127. vlvSrchEntry = Entry(vlvSrchDn)
  128. vlvSrchEntry.setValues('objectclass', 'top', 'vlvSearch')
  129. vlvSrchEntry.setValues('cn', 'vlvSrch')
  130. vlvSrchEntry.setValues('vlvBase', DEFAULT_SUFFIX)
  131. vlvSrchEntry.setValues('vlvFilter', '(|(objectclass=*)(objectclass=ldapsubentry))')
  132. vlvSrchEntry.setValues('vlvScope', '2')
  133. M2.add_s(vlvSrchEntry)
  134. # generate vlvIndex entry
  135. vlvIndexDn = "cn=vlvIdx,%s" % vlvSrchDn
  136. log.info('0-2. vlvIndex dn: %s' % vlvIndexDn)
  137. vlvIndexEntry = Entry(vlvIndexDn)
  138. vlvIndexEntry.setValues('objectclass', 'top', 'vlvIndex')
  139. vlvIndexEntry.setValues('cn', 'vlvIdx')
  140. vlvIndexEntry.setValues('vlvSort', 'cn ou sn')
  141. M2.add_s(vlvIndexEntry)
  142. log.info('1. Initialize Master 2 from Master 1.')
  143. M1.agreement.init(DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
  144. M1.waitForReplInit(m1_m2_agmt)
  145. # Check replication is working...
  146. if M1.testReplication(DEFAULT_SUFFIX, M2):
  147. log.info('1-1. Replication is working.')
  148. else:
  149. log.fatal('1-1. Replication is not working.')
  150. assert False
  151. log.info('2. Delete the backend instance on Master 2.')
  152. M2.delete_s(vlvIndexDn)
  153. M2.delete_s(vlvSrchDn)
  154. # delete the agreement, replica, and mapping tree, too.
  155. M2.replica.disableReplication(DEFAULT_SUFFIX)
  156. mappingTree = 'cn="%s",cn=mapping tree,cn=config' % DEFAULT_SUFFIX
  157. M2.mappingtree.delete(DEFAULT_SUFFIX, beName, mappingTree)
  158. M2.backend.delete(DEFAULT_SUFFIX, beDn, beName)
  159. log.info('3. Recreate the backend and the VLV index on Master 2.')
  160. M2.mappingtree.create(DEFAULT_SUFFIX, beName)
  161. M2.backend.create(DEFAULT_SUFFIX, {BACKEND_NAME: beName})
  162. log.info('3-1. Recreating %s and %s on Master 2.' % (vlvSrchDn, vlvIndexDn))
  163. M2.add_s(vlvSrchEntry)
  164. M2.add_s(vlvIndexEntry)
  165. M2.replica.enableReplication(suffix=DEFAULT_SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
  166. # agreement m2_m1_agmt is not needed... :p
  167. log.info('4. Initialize Master 2 from Master 1 again.')
  168. M1.agreement.init(DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
  169. M1.waitForReplInit(m1_m2_agmt)
  170. # Check replication is working...
  171. if M1.testReplication(DEFAULT_SUFFIX, M2):
  172. log.info('4-1. Replication is working.')
  173. else:
  174. log.fatal('4-1. Replication is not working.')
  175. assert False
  176. log.info('5. Check Master 2 is up.')
  177. entries = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(cn=*)')
  178. assert len(entries) > 0
  179. log.info('5-1. %s entries are returned from M2.' % len(entries))
  180. log.info('Test complete')
  181. if __name__ == '__main__':
  182. # Run isolated
  183. # -s for DEBUG mode
  184. CURRENT_FILE = os.path.realpath(__file__)
  185. pytest.main("-s %s" % CURRENT_FILE)