ticket48342_test.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. import os
  2. import sys
  3. import time
  4. import ldap
  5. import logging
  6. import pytest
  7. from lib389 import DirSrv, Entry, tools, tasks
  8. from lib389.tools import DirSrvTools
  9. from lib389._constants import *
  10. from lib389.properties import *
  11. from lib389.tasks import *
  12. from lib389.utils import *
  13. logging.getLogger(__name__).setLevel(logging.DEBUG)
  14. log = logging.getLogger(__name__)
  15. installation1_prefix = None
  16. PEOPLE_OU='people'
  17. PEOPLE_DN = "ou=%s,%s" % (PEOPLE_OU, SUFFIX)
  18. MAX_ACCOUNTS=5
  19. class TopologyReplication(object):
  20. def __init__(self, master1, master2, master3):
  21. master1.open()
  22. self.master1 = master1
  23. master2.open()
  24. self.master2 = master2
  25. master3.open()
  26. self.master3 = master3
  27. @pytest.fixture(scope="module")
  28. def topology(request):
  29. global installation1_prefix
  30. if installation1_prefix:
  31. args_instance[SER_DEPLOYED_DIR] = installation1_prefix
  32. # Creating master 1...
  33. master1 = DirSrv(verbose=False)
  34. if installation1_prefix:
  35. args_instance[SER_DEPLOYED_DIR] = installation1_prefix
  36. args_instance[SER_HOST] = HOST_MASTER_1
  37. args_instance[SER_PORT] = PORT_MASTER_1
  38. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
  39. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  40. args_master = args_instance.copy()
  41. master1.allocate(args_master)
  42. instance_master1 = master1.exists()
  43. if instance_master1:
  44. master1.delete()
  45. master1.create()
  46. master1.open()
  47. master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1)
  48. # Creating master 2...
  49. master2 = DirSrv(verbose=False)
  50. if installation1_prefix:
  51. args_instance[SER_DEPLOYED_DIR] = installation1_prefix
  52. args_instance[SER_HOST] = HOST_MASTER_2
  53. args_instance[SER_PORT] = PORT_MASTER_2
  54. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
  55. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  56. args_master = args_instance.copy()
  57. master2.allocate(args_master)
  58. instance_master2 = master2.exists()
  59. if instance_master2:
  60. master2.delete()
  61. master2.create()
  62. master2.open()
  63. master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
  64. # Creating master 3...
  65. master3 = DirSrv(verbose=False)
  66. if installation1_prefix:
  67. args_instance[SER_DEPLOYED_DIR] = installation1_prefix
  68. args_instance[SER_HOST] = HOST_MASTER_3
  69. args_instance[SER_PORT] = PORT_MASTER_3
  70. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_3
  71. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  72. args_master = args_instance.copy()
  73. master3.allocate(args_master)
  74. instance_master3 = master3.exists()
  75. if instance_master3:
  76. master3.delete()
  77. master3.create()
  78. master3.open()
  79. master3.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_3)
  80. #
  81. # Create all the agreements
  82. #
  83. # Creating agreement from master 1 to master 2
  84. properties = {RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  85. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  86. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  87. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  88. m1_m2_agmt = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
  89. if not m1_m2_agmt:
  90. log.fatal("Fail to create a master -> master replica agreement")
  91. sys.exit(1)
  92. log.debug("%s created" % m1_m2_agmt)
  93. # Creating agreement from master 1 to master 3
  94. # properties = {RA_NAME: r'meTo_$host:$port',
  95. # RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  96. # RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  97. # RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  98. # RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  99. # m1_m3_agmt = master1.agreement.create(suffix=SUFFIX, host=master3.host, port=master3.port, properties=properties)
  100. # if not m1_m3_agmt:
  101. # log.fatal("Fail to create a master -> master replica agreement")
  102. # sys.exit(1)
  103. # log.debug("%s created" % m1_m3_agmt)
  104. # Creating agreement from master 2 to master 1
  105. properties = {RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  106. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  107. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  108. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  109. m2_m1_agmt = master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
  110. if not m2_m1_agmt:
  111. log.fatal("Fail to create a master -> master replica agreement")
  112. sys.exit(1)
  113. log.debug("%s created" % m2_m1_agmt)
  114. # Creating agreement from master 2 to master 3
  115. properties = {RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  116. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  117. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  118. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  119. m2_m3_agmt = master2.agreement.create(suffix=SUFFIX, host=master3.host, port=master3.port, properties=properties)
  120. if not m2_m3_agmt:
  121. log.fatal("Fail to create a master -> master replica agreement")
  122. sys.exit(1)
  123. log.debug("%s created" % m2_m3_agmt)
  124. # Creating agreement from master 3 to master 1
  125. # properties = {RA_NAME: r'meTo_$host:$port',
  126. # RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  127. # RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  128. # RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  129. # RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  130. # m3_m1_agmt = master3.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
  131. # if not m3_m1_agmt:
  132. # log.fatal("Fail to create a master -> master replica agreement")
  133. # sys.exit(1)
  134. # log.debug("%s created" % m3_m1_agmt)
  135. # Creating agreement from master 3 to master 2
  136. properties = {RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  137. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  138. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  139. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  140. m3_m2_agmt = master3.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
  141. if not m3_m2_agmt:
  142. log.fatal("Fail to create a master -> master replica agreement")
  143. sys.exit(1)
  144. log.debug("%s created" % m3_m2_agmt)
  145. # Allow the replicas to get situated with the new agreements...
  146. time.sleep(5)
  147. #
  148. # Initialize all the agreements
  149. #
  150. master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
  151. master1.waitForReplInit(m1_m2_agmt)
  152. time.sleep(5) # just to be safe
  153. master2.agreement.init(SUFFIX, HOST_MASTER_3, PORT_MASTER_3)
  154. master2.waitForReplInit(m2_m3_agmt)
  155. # Check replication is working...
  156. if master1.testReplication(DEFAULT_SUFFIX, master2):
  157. log.info('Replication is working.')
  158. else:
  159. log.fatal('Replication is not working.')
  160. assert False
  161. # Delete each instance in the end
  162. def fin():
  163. for master in (master1, master2, master3):
  164. # master.db2ldif(bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX], excludeSuffixes=[], encrypt=False, \
  165. # repl_data=True, outputfile='%s/ldif/%s.ldif' % (master.dbdir,SERVERID_STANDALONE ))
  166. # master.clearBackupFS()
  167. # master.backupFS()
  168. master.delete()
  169. request.addfinalizer(fin)
  170. # Clear out the tmp dir
  171. master1.clearTmpDir(__file__)
  172. return TopologyReplication(master1, master2, master3)
  173. def _dna_config(server, nextValue=500, maxValue=510):
  174. log.info("Add dna plugin config entry...%s" % server)
  175. try:
  176. server.add_s(Entry(('cn=dna config,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config', {
  177. 'objectclass': 'top dnaPluginConfig'.split(),
  178. 'dnaType': 'description',
  179. 'dnaMagicRegen': '-1',
  180. 'dnaFilter': '(objectclass=posixAccount)',
  181. 'dnaScope': 'ou=people,%s' % SUFFIX,
  182. 'dnaNextValue': str(nextValue),
  183. 'dnaMaxValue' : str(nextValue+maxValue),
  184. 'dnaSharedCfgDN': 'ou=ranges,%s' % SUFFIX
  185. })))
  186. except ldap.LDAPError as e:
  187. log.error('Failed to add DNA config entry: error ' + e.message['desc'])
  188. assert False
  189. log.info("Enable the DNA plugin...")
  190. try:
  191. server.plugins.enable(name=PLUGIN_DNA)
  192. except e:
  193. log.error("Failed to enable DNA Plugin: error " + e.message['desc'])
  194. assert False
  195. log.info("Restarting the server...")
  196. server.stop(timeout=120)
  197. time.sleep(1)
  198. server.start(timeout=120)
  199. time.sleep(3)
  200. def test_ticket4026(topology):
  201. """Write your replication testcase here.
  202. To access each DirSrv instance use: topology.master1, topology.master2,
  203. ..., topology.hub1, ..., topology.consumer1, ...
  204. Also, if you need any testcase initialization,
  205. please, write additional fixture for that(include finalizer).
  206. """
  207. try:
  208. topology.master1.add_s(Entry((PEOPLE_DN, {
  209. 'objectclass': "top extensibleObject".split(),
  210. 'ou': 'people'})))
  211. except ldap.ALREADY_EXISTS:
  212. pass
  213. topology.master1.add_s(Entry(('ou=ranges,' + SUFFIX, {
  214. 'objectclass': 'top organizationalunit'.split(),
  215. 'ou': 'ranges'
  216. })))
  217. for cpt in range(MAX_ACCOUNTS):
  218. name = "user%d" % (cpt)
  219. topology.master1.add_s(Entry(("uid=%s,%s" %(name, PEOPLE_DN), {
  220. 'objectclass': 'top posixAccount extensibleObject'.split(),
  221. 'uid': name,
  222. 'cn': name,
  223. 'uidNumber': '1',
  224. 'gidNumber': '1',
  225. 'homeDirectory': '/home/%s' % name
  226. })))
  227. # make master3 having more free slots that master2
  228. # so master1 will contact master3
  229. _dna_config(topology.master1, nextValue=100, maxValue=10)
  230. _dna_config(topology.master2, nextValue=200, maxValue=10)
  231. _dna_config(topology.master3, nextValue=300, maxValue=3000)
  232. # Turn on lots of error logging now.
  233. mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '16384')]
  234. #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '1')]
  235. topology.master1.modify_s('cn=config', mod)
  236. topology.master2.modify_s('cn=config', mod)
  237. topology.master3.modify_s('cn=config', mod)
  238. # We need to wait for the event in dna.c to fire to start the servers
  239. # see dna.c line 899
  240. time.sleep(60)
  241. # add on master1 users with description DNA
  242. for cpt in range(10):
  243. name = "user_with_desc1_%d" % (cpt)
  244. topology.master1.add_s(Entry(("uid=%s,%s" %(name, PEOPLE_DN), {
  245. 'objectclass': 'top posixAccount extensibleObject'.split(),
  246. 'uid': name,
  247. 'cn': name,
  248. 'description' : '-1',
  249. 'uidNumber': '1',
  250. 'gidNumber': '1',
  251. 'homeDirectory': '/home/%s' % name
  252. })))
  253. # give time to negociate master1 <--> master3
  254. time.sleep(10)
  255. # add on master1 users with description DNA
  256. for cpt in range(11,20):
  257. name = "user_with_desc1_%d" % (cpt)
  258. topology.master1.add_s(Entry(("uid=%s,%s" %(name, PEOPLE_DN), {
  259. 'objectclass': 'top posixAccount extensibleObject'.split(),
  260. 'uid': name,
  261. 'cn': name,
  262. 'description' : '-1',
  263. 'uidNumber': '1',
  264. 'gidNumber': '1',
  265. 'homeDirectory': '/home/%s' % name
  266. })))
  267. log.info('Test complete')
  268. # add on master1 users with description DNA
  269. mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '16384')]
  270. #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '1')]
  271. topology.master1.modify_s('cn=config', mod)
  272. topology.master2.modify_s('cn=config', mod)
  273. topology.master3.modify_s('cn=config', mod)
  274. log.info('Test complete')
  275. if __name__ == '__main__':
  276. # Run isolated
  277. # -s for DEBUG mode
  278. # global installation1_prefix
  279. # installation1_prefix=None
  280. # topo = topology(True)
  281. # test_ticket4026(topo)
  282. CURRENT_FILE = os.path.realpath(__file__)
  283. pytest.main("-s %s" % CURRENT_FILE)