mmr_01_4m_test.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. import os
  2. import sys
  3. import time
  4. import datetime
  5. import ldap
  6. import logging
  7. import pytest
  8. import threading
  9. from lib389._constants import *
  10. from lib389.properties import *
  11. from lib389.tasks import *
  12. from lib389.utils import *
  13. from lib389.repltools import ReplTools
  14. logging.getLogger(__name__).setLevel(logging.DEBUG)
  15. log = logging.getLogger(__name__)
  16. DEBUGGING = False
  17. ADD_DEL_COUNT = 5000
  18. MAX_LOOPS = 5
  19. TEST_CONVERGE_LATENCY = True
  20. CONVERGENCE_TIMEOUT = '60'
  21. master_list = []
  22. hub_list = []
  23. con_list = []
  24. TEST_START = time.time()
  25. LAST_DN_IDX = ADD_DEL_COUNT - 1
  26. LAST_DN_M1 = 'DEL dn="uid=master_1-%d,%s' % (LAST_DN_IDX, DEFAULT_SUFFIX)
  27. LAST_DN_M2 = 'DEL dn="uid=master_2-%d,%s' % (LAST_DN_IDX, DEFAULT_SUFFIX)
  28. LAST_DN_M3 = 'DEL dn="uid=master_3-%d,%s' % (LAST_DN_IDX, DEFAULT_SUFFIX)
  29. LAST_DN_M4 = 'DEL dn="uid=master_4-%d,%s' % (LAST_DN_IDX, DEFAULT_SUFFIX)
  30. class TopologyReplication(object):
  31. """The Replication Topology Class"""
  32. def __init__(self, master1, master2, master3, master4):
  33. """Init"""
  34. master1.open()
  35. self.master1 = master1
  36. master2.open()
  37. self.master2 = master2
  38. master3.open()
  39. self.master3 = master3
  40. master4.open()
  41. self.master4 = master4
  42. @pytest.fixture(scope="module")
  43. def topology(request):
  44. """Create Replication Deployment"""
  45. # Creating master 1...
  46. if DEBUGGING:
  47. master1 = DirSrv(verbose=True)
  48. else:
  49. master1 = DirSrv(verbose=False)
  50. args_instance[SER_HOST] = HOST_MASTER_1
  51. args_instance[SER_PORT] = PORT_MASTER_1
  52. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
  53. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  54. args_master = args_instance.copy()
  55. master1.allocate(args_master)
  56. instance_master1 = master1.exists()
  57. if instance_master1:
  58. master1.delete()
  59. master1.create()
  60. master1.open()
  61. master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER,
  62. replicaId=REPLICAID_MASTER_1)
  63. # Creating master 2...
  64. if DEBUGGING:
  65. master2 = DirSrv(verbose=True)
  66. else:
  67. master2 = DirSrv(verbose=False)
  68. args_instance[SER_HOST] = HOST_MASTER_2
  69. args_instance[SER_PORT] = PORT_MASTER_2
  70. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
  71. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  72. args_master = args_instance.copy()
  73. master2.allocate(args_master)
  74. instance_master2 = master2.exists()
  75. if instance_master2:
  76. master2.delete()
  77. master2.create()
  78. master2.open()
  79. master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER,
  80. replicaId=REPLICAID_MASTER_2)
  81. # Creating master 3...
  82. if DEBUGGING:
  83. master3 = DirSrv(verbose=True)
  84. else:
  85. master3 = DirSrv(verbose=False)
  86. args_instance[SER_HOST] = HOST_MASTER_3
  87. args_instance[SER_PORT] = PORT_MASTER_3
  88. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_3
  89. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  90. args_master = args_instance.copy()
  91. master3.allocate(args_master)
  92. instance_master3 = master3.exists()
  93. if instance_master3:
  94. master3.delete()
  95. master3.create()
  96. master3.open()
  97. master3.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER,
  98. replicaId=REPLICAID_MASTER_3)
  99. # Creating master 4...
  100. if DEBUGGING:
  101. master4 = DirSrv(verbose=True)
  102. else:
  103. master4 = DirSrv(verbose=False)
  104. args_instance[SER_HOST] = HOST_MASTER_4
  105. args_instance[SER_PORT] = PORT_MASTER_4
  106. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_4
  107. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  108. args_master = args_instance.copy()
  109. master4.allocate(args_master)
  110. instance_master4 = master4.exists()
  111. if instance_master4:
  112. master4.delete()
  113. master4.create()
  114. master4.open()
  115. master4.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER,
  116. replicaId=REPLICAID_MASTER_4)
  117. #
  118. # Create all the agreements
  119. #
  120. # Creating agreement from master 1 to master 2
  121. properties = {RA_NAME: 'meTo_' + master2.host + ':' + str(master2.port),
  122. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  123. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  124. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  125. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  126. m1_m2_agmt = master1.agreement.create(suffix=SUFFIX, host=master2.host,
  127. port=master2.port,
  128. properties=properties)
  129. if not m1_m2_agmt:
  130. log.fatal("Fail to create a master -> master replica agreement")
  131. sys.exit(1)
  132. log.debug("%s created" % m1_m2_agmt)
  133. # Creating agreement from master 1 to master 3
  134. properties = {RA_NAME: 'meTo_' + master3.host + ':' + str(master3.port),
  135. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  136. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  137. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  138. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  139. m1_m3_agmt = master1.agreement.create(suffix=SUFFIX, host=master3.host,
  140. port=master3.port,
  141. properties=properties)
  142. if not m1_m3_agmt:
  143. log.fatal("Fail to create a master -> master replica agreement")
  144. sys.exit(1)
  145. log.debug("%s created" % m1_m3_agmt)
  146. # Creating agreement from master 1 to master 4
  147. properties = {RA_NAME: 'meTo_' + master4.host + ':' + str(master4.port),
  148. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  149. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  150. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  151. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  152. m1_m4_agmt = master1.agreement.create(suffix=SUFFIX, host=master4.host,
  153. port=master4.port,
  154. properties=properties)
  155. if not m1_m4_agmt:
  156. log.fatal("Fail to create a master -> master replica agreement")
  157. sys.exit(1)
  158. log.debug("%s created" % m1_m4_agmt)
  159. # Creating agreement from master 2 to master 1
  160. properties = {RA_NAME: 'meTo_' + master1.host + ':' + str(master1.port),
  161. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  162. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  163. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  164. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  165. m2_m1_agmt = master2.agreement.create(suffix=SUFFIX, host=master1.host,
  166. port=master1.port,
  167. properties=properties)
  168. if not m2_m1_agmt:
  169. log.fatal("Fail to create a master -> master replica agreement")
  170. sys.exit(1)
  171. log.debug("%s created" % m2_m1_agmt)
  172. # Creating agreement from master 2 to master 3
  173. properties = {RA_NAME: 'meTo_' + master3.host + ':' + str(master3.port),
  174. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  175. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  176. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  177. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  178. m2_m3_agmt = master2.agreement.create(suffix=SUFFIX, host=master3.host,
  179. port=master3.port,
  180. properties=properties)
  181. if not m2_m3_agmt:
  182. log.fatal("Fail to create a master -> master replica agreement")
  183. sys.exit(1)
  184. log.debug("%s created" % m2_m3_agmt)
  185. # Creating agreement from master 2 to master 4
  186. properties = {RA_NAME: 'meTo_' + master4.host + ':' + str(master4.port),
  187. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  188. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  189. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  190. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  191. m2_m4_agmt = master2.agreement.create(suffix=SUFFIX, host=master4.host,
  192. port=master4.port,
  193. properties=properties)
  194. if not m2_m4_agmt:
  195. log.fatal("Fail to create a master -> master replica agreement")
  196. sys.exit(1)
  197. log.debug("%s created" % m2_m4_agmt)
  198. # Creating agreement from master 3 to master 1
  199. properties = {RA_NAME: 'meTo_' + master1.host + ':' + str(master1.port),
  200. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  201. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  202. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  203. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  204. m3_m1_agmt = master3.agreement.create(suffix=SUFFIX, host=master1.host,
  205. port=master1.port,
  206. properties=properties)
  207. if not m3_m1_agmt:
  208. log.fatal("Fail to create a master -> master replica agreement")
  209. sys.exit(1)
  210. log.debug("%s created" % m3_m1_agmt)
  211. # Creating agreement from master 3 to master 2
  212. properties = {RA_NAME: 'meTo_' + master2.host + ':' + str(master2.port),
  213. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  214. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  215. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  216. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  217. m3_m2_agmt = master3.agreement.create(suffix=SUFFIX, host=master2.host,
  218. port=master2.port,
  219. properties=properties)
  220. if not m3_m2_agmt:
  221. log.fatal("Fail to create a master -> master replica agreement")
  222. sys.exit(1)
  223. log.debug("%s created" % m3_m2_agmt)
  224. # Creating agreement from master 3 to master 4
  225. properties = {RA_NAME: 'meTo_' + master4.host + ':' + str(master4.port),
  226. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  227. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  228. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  229. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  230. m3_m4_agmt = master3.agreement.create(suffix=SUFFIX, host=master4.host,
  231. port=master4.port,
  232. properties=properties)
  233. if not m3_m4_agmt:
  234. log.fatal("Fail to create a master -> master replica agreement")
  235. sys.exit(1)
  236. log.debug("%s created" % m3_m4_agmt)
  237. # Creating agreement from master 4 to master 1
  238. properties = {RA_NAME: 'meTo_' + master1.host + ':' + str(master1.port),
  239. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  240. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  241. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  242. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  243. m4_m1_agmt = master4.agreement.create(suffix=SUFFIX, host=master1.host,
  244. port=master1.port,
  245. properties=properties)
  246. if not m4_m1_agmt:
  247. log.fatal("Fail to create a master -> master replica agreement")
  248. sys.exit(1)
  249. log.debug("%s created" % m4_m1_agmt)
  250. # Creating agreement from master 4 to master 2
  251. properties = {RA_NAME: 'meTo_' + master2.host + ':' + str(master2.port),
  252. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  253. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  254. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  255. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  256. m4_m2_agmt = master4.agreement.create(suffix=SUFFIX, host=master2.host,
  257. port=master2.port,
  258. properties=properties)
  259. if not m4_m2_agmt:
  260. log.fatal("Fail to create a master -> master replica agreement")
  261. sys.exit(1)
  262. log.debug("%s created" % m4_m2_agmt)
  263. # Creating agreement from master 4 to master 3
  264. properties = {RA_NAME: 'meTo_' + master3.host + ':' + str(master3.port),
  265. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  266. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  267. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  268. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  269. m4_m3_agmt = master4.agreement.create(suffix=SUFFIX, host=master3.host,
  270. port=master3.port,
  271. properties=properties)
  272. if not m4_m3_agmt:
  273. log.fatal("Fail to create a master -> master replica agreement")
  274. sys.exit(1)
  275. log.debug("%s created" % m4_m3_agmt)
  276. # Allow the replicas to get situated with the new agreements...
  277. time.sleep(5)
  278. #
  279. # Initialize all the agreements
  280. #
  281. master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
  282. master1.waitForReplInit(m1_m2_agmt)
  283. master1.agreement.init(SUFFIX, HOST_MASTER_3, PORT_MASTER_3)
  284. master1.waitForReplInit(m1_m3_agmt)
  285. master1.agreement.init(SUFFIX, HOST_MASTER_4, PORT_MASTER_4)
  286. master1.waitForReplInit(m1_m4_agmt)
  287. # Check replication is working...
  288. if master1.testReplication(DEFAULT_SUFFIX, master4):
  289. log.info('Replication is working.')
  290. else:
  291. log.fatal('Replication is not working.')
  292. assert False
  293. def fin():
  294. """If we are debugging just stop the instances, otherwise remove
  295. them
  296. """
  297. if 1 or DEBUGGING:
  298. master1.stop()
  299. master2.stop()
  300. master3.stop()
  301. master4.stop()
  302. else:
  303. master1.delete()
  304. master2.delete()
  305. master3.delete()
  306. master4.delete()
  307. request.addfinalizer(fin)
  308. return TopologyReplication(master1, master2, master3, master4)
  309. class AddDelUsers(threading.Thread):
  310. """Add's and delets 50000 entries"""
  311. def __init__(self, inst):
  312. """
  313. Initialize the thread
  314. """
  315. threading.Thread.__init__(self)
  316. self.daemon = True
  317. self.inst = inst
  318. self.name = inst.serverid
  319. def run(self):
  320. """
  321. Start adding users
  322. """
  323. idx = 0
  324. log.info('AddDelUsers (%s) Adding and deleting %d entries...' %
  325. (self.name, ADD_DEL_COUNT))
  326. while idx < ADD_DEL_COUNT:
  327. RDN_VAL = ('uid=%s-%d' % (self.name, idx))
  328. USER_DN = ('%s,%s' % (RDN_VAL, DEFAULT_SUFFIX))
  329. try:
  330. self.inst.add_s(Entry((USER_DN, {'objectclass':
  331. 'top extensibleObject'.split(),
  332. 'uid': RDN_VAL})))
  333. except ldap.LDAPError as e:
  334. log.fatal('AddDelUsers (%s): failed to add (%s) error: %s' %
  335. (self.name, USER_DN, str(e)))
  336. assert False
  337. try:
  338. self.inst.delete_s(USER_DN)
  339. except ldap.LDAPError as e:
  340. log.fatal('AddDelUsers (%s): failed to delete (%s) error: %s' %
  341. (self.name, USER_DN, str(e)))
  342. assert False
  343. idx += 1
  344. log.info('AddDelUsers (%s) - Finished at: %s' %
  345. (self.name, getDateTime()))
  346. def measureConvergence(topology):
  347. """Find and measure the convergence of entries from each master
  348. """
  349. replicas = [topology.master1, topology.master2, topology.master3,
  350. topology.master4]
  351. if ADD_DEL_COUNT > 10:
  352. interval = int(ADD_DEL_COUNT / 10)
  353. else:
  354. interval = 1
  355. for master in [('1', topology.master1),
  356. ('2', topology.master2),
  357. ('3', topology.master3),
  358. ('4', topology.master4)]:
  359. # Start with the first entry
  360. entries = ['ADD dn="uid=master_%s-0,%s' %
  361. (master[0], DEFAULT_SUFFIX)]
  362. # Add incremental entries to the list
  363. idx = interval
  364. while idx < ADD_DEL_COUNT:
  365. entries.append('ADD dn="uid=master_%s-%d,%s' %
  366. (master[0], idx, DEFAULT_SUFFIX))
  367. idx += interval
  368. # Add the last entry to the list (if it was not already added)
  369. if idx != (ADD_DEL_COUNT - 1):
  370. entries.append('ADD dn="uid=master_%s-%d,%s' %
  371. (master[0], (ADD_DEL_COUNT - 1),
  372. DEFAULT_SUFFIX))
  373. ReplTools.replConvReport(DEFAULT_SUFFIX, entries, master[1], replicas)
  374. def test_MMR_Integrity(topology):
  375. """Apply load to 4 masters at the same time. Perform adds and deletes.
  376. If any updates are missed we will see an error 32 in the access logs or
  377. we will have entries left over once the test completes.
  378. """
  379. loop = 0
  380. ALL_REPLICAS = [topology.master1, topology.master2, topology.master3,
  381. topology.master4]
  382. if TEST_CONVERGE_LATENCY:
  383. try:
  384. for inst in ALL_REPLICAS:
  385. replica = inst.replicas.get(DEFAULT_SUFFIX)
  386. replica.set('nsds5ReplicaReleaseTimeout', CONVERGENCE_TIMEOUT)
  387. except ldap.LDAPError as e:
  388. log.fatal('Failed to set replicas release timeout - error: %s' %
  389. (str(e)))
  390. assert False
  391. if DEBUGGING:
  392. # Enable Repl logging, and increase the max logs
  393. try:
  394. for inst in ALL_REPLICAS:
  395. inst.enableReplLogging()
  396. inst.modify_s("cn=config", [(ldap.MOD_REPLACE,
  397. 'nsslapd-errorlog-maxlogsperdir',
  398. '5')])
  399. except ldap.LDAPError as e:
  400. log.fatal('Failed to set max logs - error: %s' % (str(e)))
  401. assert False
  402. while loop < MAX_LOOPS:
  403. # Remove the current logs so we have a clean set of logs to check.
  404. log.info('Pass %d...' % (loop + 1))
  405. log.info("Removing logs...")
  406. for inst in ALL_REPLICAS:
  407. inst.deleteAllLogs()
  408. # Fire off 4 threads to apply the load
  409. log.info("Start adding/deleting: " + getDateTime())
  410. startTime = time.time()
  411. add_del_m1 = AddDelUsers(topology.master1)
  412. add_del_m1.start()
  413. add_del_m2 = AddDelUsers(topology.master2)
  414. add_del_m2.start()
  415. add_del_m3 = AddDelUsers(topology.master3)
  416. add_del_m3.start()
  417. add_del_m4 = AddDelUsers(topology.master4)
  418. add_del_m4.start()
  419. # Wait for threads to finish sending their updates
  420. add_del_m1.join()
  421. add_del_m2.join()
  422. add_del_m3.join()
  423. add_del_m4.join()
  424. log.info("Finished adding/deleting entries: " + getDateTime())
  425. #
  426. # Loop checking for error 32's, and for convergence to complete
  427. #
  428. log.info("Waiting for replication to converge...")
  429. while True:
  430. # First check for error 32's
  431. for inst in ALL_REPLICAS:
  432. if inst.searchAccessLog(" err=32 "):
  433. log.fatal('An add was missed on: ' + inst.serverid)
  434. assert False
  435. # Next check to see if the last update is in the access log
  436. converged = True
  437. for inst in ALL_REPLICAS:
  438. if not inst.searchAccessLog(LAST_DN_M1) or \
  439. not inst.searchAccessLog(LAST_DN_M2) or \
  440. not inst.searchAccessLog(LAST_DN_M3) or \
  441. not inst.searchAccessLog(LAST_DN_M4):
  442. converged = False
  443. break
  444. if converged:
  445. elapsed_tm = int(time.time() - startTime)
  446. convtime = str(datetime.timedelta(seconds=elapsed_tm))
  447. log.info('Replication converged at: ' + getDateTime() +
  448. ' - Elapsed Time: ' + convtime)
  449. break
  450. else:
  451. # Check if replication is idle
  452. replicas = [topology.master1, topology.master2,
  453. topology.master3, topology.master4]
  454. if ReplTools.replIdle(replicas, DEFAULT_SUFFIX):
  455. # Replication is idle - wait 30 secs for access log buffer
  456. time.sleep(30)
  457. # Now check the access log again...
  458. converged = True
  459. for inst in ALL_REPLICAS:
  460. if not inst.searchAccessLog(LAST_DN_M1) or \
  461. not inst.searchAccessLog(LAST_DN_M2) or \
  462. not inst.searchAccessLog(LAST_DN_M3) or \
  463. not inst.searchAccessLog(LAST_DN_M4):
  464. converged = False
  465. break
  466. if converged:
  467. elapsed_tm = int(time.time() - startTime)
  468. convtime = str(datetime.timedelta(seconds=elapsed_tm))
  469. log.info('Replication converged at: ' + getDateTime() +
  470. ' - Elapsed Time: ' + convtime)
  471. break
  472. else:
  473. log.fatal('Stopping replication check: ' +
  474. getDateTime())
  475. log.fatal('Failure: Replication is complete, but we ' +
  476. 'never converged.')
  477. assert False
  478. # Sleep a bit before the next pass
  479. time.sleep(3)
  480. #
  481. # Finally check the CSN's
  482. #
  483. log.info("Check the CSN's...")
  484. if not ReplTools.checkCSNs(ALL_REPLICAS):
  485. assert False
  486. log.info("All CSN's present and accounted for.")
  487. #
  488. # Print the convergence report
  489. #
  490. log.info('Measuring convergence...')
  491. measureConvergence(topology)
  492. #
  493. # Test complete
  494. #
  495. log.info('No lingering entries.')
  496. log.info('Pass %d complete.' % (loop + 1))
  497. elapsed_tm = int(time.time() - TEST_START)
  498. convtime = str(datetime.timedelta(seconds=elapsed_tm))
  499. log.info('Entire test ran for: ' + convtime)
  500. loop += 1
  501. log.info('Test PASSED')
  502. if __name__ == '__main__':
  503. # Run isolated
  504. # -s for DEBUG mode
  505. CURRENT_FILE = os.path.realpath(__file__)
  506. pytest.main("-s %s" % CURRENT_FILE)