1
0

ticket47490_test.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. '''
  2. Created on Nov 7, 2013
  3. @author: tbordaz
  4. '''
  5. import os
  6. import sys
  7. import time
  8. import ldap
  9. import logging
  10. import socket
  11. import time
  12. import logging
  13. import pytest
  14. import re
  15. from lib389 import DirSrv, Entry, tools
  16. from lib389.tools import DirSrvTools
  17. from lib389._constants import *
  18. from lib389.properties import *
  19. from constants import *
  20. logging.getLogger(__name__).setLevel(logging.DEBUG)
  21. log = logging.getLogger(__name__)
  22. installation_prefix = None
  23. TEST_REPL_DN = "cn=test_repl, %s" % SUFFIX
  24. ENTRY_DN = "cn=test_entry, %s" % SUFFIX
  25. MUST_OLD = "(postalAddress $ preferredLocale)"
  26. MUST_NEW = "(postalAddress $ preferredLocale $ telexNumber)"
  27. MAY_OLD = "(postalCode $ street)"
  28. MAY_NEW = "(postalCode $ street $ postOfficeBox)"
  29. class TopologyMasterConsumer(object):
  30. def __init__(self, master, consumer):
  31. master.open()
  32. self.master = master
  33. consumer.open()
  34. self.consumer = consumer
  35. def pattern_errorlog(file, log_pattern):
  36. try:
  37. pattern_errorlog.last_pos += 1
  38. except AttributeError:
  39. pattern_errorlog.last_pos = 0
  40. found = None
  41. log.debug("_pattern_errorlog: start at offset %d" % pattern_errorlog.last_pos)
  42. file.seek(pattern_errorlog.last_pos)
  43. # Use a while true iteration because 'for line in file: hit a
  44. # python bug that break file.tell()
  45. while True:
  46. line = file.readline()
  47. log.debug("_pattern_errorlog: [%d] %s" % (file.tell(), line))
  48. found = log_pattern.search(line)
  49. if ((line == '') or (found)):
  50. break
  51. log.debug("_pattern_errorlog: end at offset %d" % file.tell())
  52. pattern_errorlog.last_pos = file.tell()
  53. return found
  54. def _oc_definition(oid_ext, name, must=None, may=None):
  55. oid = "1.2.3.4.5.6.7.8.9.10.%d" % oid_ext
  56. desc = 'To test ticket 47490'
  57. sup = 'person'
  58. if not must:
  59. must = MUST_OLD
  60. if not may:
  61. may = MAY_OLD
  62. new_oc = "( %s NAME '%s' DESC '%s' SUP %s AUXILIARY MUST %s MAY %s )" % (oid, name, desc, sup, must, may)
  63. return new_oc
  64. def add_OC(instance, oid_ext, name):
  65. new_oc = _oc_definition(oid_ext, name)
  66. instance.addSchema('objectClasses', new_oc)
  67. def mod_OC(instance, oid_ext, name, old_must=None, old_may=None, new_must=None, new_may=None):
  68. old_oc = _oc_definition(oid_ext, name, old_must, old_may)
  69. new_oc = _oc_definition(oid_ext, name, new_must, new_may)
  70. instance.delSchema('objectClasses', old_oc)
  71. instance.addSchema('objectClasses', new_oc)
  72. def trigger_schema_push(topology):
  73. """
  74. It triggers an update on the supplier. This will start a replication
  75. session and a schema push
  76. """
  77. try:
  78. trigger_schema_push.value += 1
  79. except AttributeError:
  80. trigger_schema_push.value = 1
  81. replace = [(ldap.MOD_REPLACE, 'telephonenumber', str(trigger_schema_push.value))]
  82. topology.master.modify_s(ENTRY_DN, replace)
  83. # wait 10 seconds that the update is replicated
  84. loop = 0
  85. while loop <= 10:
  86. try:
  87. ent = topology.consumer.getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)", ['telephonenumber'])
  88. val = ent.telephonenumber or "0"
  89. if int(val) == trigger_schema_push.value:
  90. return
  91. # the expected value is not yet replicated. try again
  92. time.sleep(1)
  93. loop += 1
  94. log.debug("trigger_schema_push: receive %s (expected %d)" % (val, trigger_schema_push.value))
  95. except ldap.NO_SUCH_OBJECT:
  96. time.sleep(1)
  97. loop += 1
  98. @pytest.fixture(scope="module")
  99. def topology(request):
  100. '''
  101. This fixture is used to create a replicated topology for the 'module'.
  102. The replicated topology is MASTER -> Consumer.
  103. At the beginning, It may exists a master instance and/or a consumer instance.
  104. It may also exists a backup for the master and/or the consumer.
  105. Principle:
  106. If master instance exists:
  107. restart it
  108. If consumer instance exists:
  109. restart it
  110. If backup of master AND backup of consumer exists:
  111. create or rebind to consumer
  112. create or rebind to master
  113. restore master from backup
  114. restore consumer from backup
  115. else:
  116. Cleanup everything
  117. remove instances
  118. remove backups
  119. Create instances
  120. Initialize replication
  121. Create backups
  122. '''
  123. global installation_prefix
  124. if installation_prefix:
  125. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  126. master = DirSrv(verbose=False)
  127. consumer = DirSrv(verbose=False)
  128. # Args for the master instance
  129. args_instance[SER_HOST] = HOST_MASTER
  130. args_instance[SER_PORT] = PORT_MASTER
  131. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER
  132. args_master = args_instance.copy()
  133. master.allocate(args_master)
  134. # Args for the consumer instance
  135. args_instance[SER_HOST] = HOST_CONSUMER
  136. args_instance[SER_PORT] = PORT_CONSUMER
  137. args_instance[SER_SERVERID_PROP] = SERVERID_CONSUMER
  138. args_consumer = args_instance.copy()
  139. consumer.allocate(args_consumer)
  140. # Get the status of the backups
  141. backup_master = master.checkBackupFS()
  142. backup_consumer = consumer.checkBackupFS()
  143. # Get the status of the instance and restart it if it exists
  144. instance_master = master.exists()
  145. if instance_master:
  146. master.stop(timeout=10)
  147. master.start(timeout=10)
  148. instance_consumer = consumer.exists()
  149. if instance_consumer:
  150. consumer.stop(timeout=10)
  151. consumer.start(timeout=10)
  152. if backup_master and backup_consumer:
  153. # The backups exist, assuming they are correct
  154. # we just re-init the instances with them
  155. if not instance_master:
  156. master.create()
  157. # Used to retrieve configuration information (dbdir, confdir...)
  158. master.open()
  159. if not instance_consumer:
  160. consumer.create()
  161. # Used to retrieve configuration information (dbdir, confdir...)
  162. consumer.open()
  163. # restore master from backup
  164. master.stop(timeout=10)
  165. master.restoreFS(backup_master)
  166. master.start(timeout=10)
  167. # restore consumer from backup
  168. consumer.stop(timeout=10)
  169. consumer.restoreFS(backup_consumer)
  170. consumer.start(timeout=10)
  171. else:
  172. # We should be here only in two conditions
  173. # - This is the first time a test involve master-consumer
  174. # so we need to create everything
  175. # - Something weird happened (instance/backup destroyed)
  176. # so we discard everything and recreate all
  177. # Remove all the backups. So even if we have a specific backup file
  178. # (e.g backup_master) we clear all backups that an instance my have created
  179. if backup_master:
  180. master.clearBackupFS()
  181. if backup_consumer:
  182. consumer.clearBackupFS()
  183. # Remove all the instances
  184. if instance_master:
  185. master.delete()
  186. if instance_consumer:
  187. consumer.delete()
  188. # Create the instances
  189. master.create()
  190. master.open()
  191. consumer.create()
  192. consumer.open()
  193. #
  194. # Now prepare the Master-Consumer topology
  195. #
  196. # First Enable replication
  197. master.enableReplication(suffix=SUFFIX, role="master", replicaId=REPLICAID_MASTER)
  198. consumer.enableReplication(suffix=SUFFIX, role="consumer")
  199. # Initialize the supplier->consumer
  200. repl_agreement = master.agreement.create(consumer, SUFFIX, binddn=defaultProperties[REPLICATION_BIND_DN], bindpw=defaultProperties[REPLICATION_BIND_PW])
  201. if not repl_agreement:
  202. log.fatal("Fail to create a replica agreement")
  203. sys.exit(1)
  204. log.debug("%s created" % repl_agreement)
  205. master.agreement.init(SUFFIX, HOST_CONSUMER, PORT_CONSUMER)
  206. master.waitForReplInit(repl_agreement)
  207. # Check replication is working fine
  208. master.add_s(Entry((TEST_REPL_DN, {
  209. 'objectclass': "top person".split(),
  210. 'sn': 'test_repl',
  211. 'cn': 'test_repl'})))
  212. loop = 0
  213. while loop <= 10:
  214. try:
  215. ent = consumer.getEntry(TEST_REPL_DN, ldap.SCOPE_BASE, "(objectclass=*)")
  216. break
  217. except ldap.NO_SUCH_OBJECT:
  218. time.sleep(1)
  219. loop += 1
  220. # Time to create the backups
  221. master.stop(timeout=10)
  222. master.backupfile = master.backupFS()
  223. master.start(timeout=10)
  224. consumer.stop(timeout=10)
  225. consumer.backupfile = consumer.backupFS()
  226. consumer.start(timeout=10)
  227. #
  228. # Here we have two instances master and consumer
  229. # with replication working. Either coming from a backup recovery
  230. # or from a fresh (re)init
  231. # Time to return the topology
  232. return TopologyMasterConsumer(master, consumer)
  233. def test_ticket47490_init(topology):
  234. """
  235. Initialize the test environment
  236. """
  237. log.debug("test_ticket47490_init topology %r (master %r, consumer %r" % (topology, topology.master, topology.consumer))
  238. # the test case will check if a warning message is logged in the
  239. # error log of the supplier
  240. topology.master.errorlog_file = open(topology.master.errlog, "r")
  241. # This entry will be used to trigger attempt of schema push
  242. topology.master.add_s(Entry((ENTRY_DN, {
  243. 'objectclass': "top person".split(),
  244. 'sn': 'test_entry',
  245. 'cn': 'test_entry'})))
  246. def test_ticket47490_one(topology):
  247. """
  248. Summary: Extra OC Schema is pushed - no error
  249. If supplier schema is a superset (one extra OC) of consumer schema, then
  250. schema is pushed and there is no message in the error log
  251. State at startup:
  252. - supplier default schema
  253. - consumer default schema
  254. Final state
  255. - supplier +masterNewOCA
  256. - consumer +masterNewOCA
  257. """
  258. log.debug("test_ticket47490_one topology %r (master %r, consumer %r" % (topology, topology.master, topology.consumer))
  259. # update the schema of the supplier so that it is a superset of
  260. # consumer. Schema should be pushed
  261. add_OC(topology.master, 2, 'masterNewOCA')
  262. trigger_schema_push(topology)
  263. master_schema_csn = topology.master.getSchemaCSN()
  264. consumer_schema_csn = topology.consumer.getSchemaCSN()
  265. # Check the schemaCSN was updated on the consumer
  266. log.debug("test_ticket47490_one master_schema_csn=%s", master_schema_csn)
  267. log.debug("ctest_ticket47490_one onsumer_schema_csn=%s", consumer_schema_csn)
  268. assert master_schema_csn == consumer_schema_csn
  269. # Check the error log of the supplier does not contain an error
  270. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  271. res = pattern_errorlog(topology.master.errorlog_file, regex)
  272. assert res == None
  273. def test_ticket47490_two(topology):
  274. """
  275. Summary: Extra OC Schema is NOT pushed - error
  276. If consumer schema is a superset (one extra OC) of supplier schema, then
  277. schema is not pushed and there is a message in the error log
  278. State at startup
  279. - supplier +masterNewOCA
  280. - consumer +masterNewOCA
  281. Final state
  282. - supplier +masterNewOCA +masterNewOCB
  283. - consumer +masterNewOCA +consumerNewOCA
  284. """
  285. # add this OC on consumer. Supplier will no push the schema
  286. add_OC(topology.consumer, 1, 'consumerNewOCA')
  287. # add a new OC on the supplier so that its nsSchemaCSN is larger than the consumer (wait 2s)
  288. time.sleep(2)
  289. add_OC(topology.master, 3, 'masterNewOCB')
  290. # now push the scheam
  291. trigger_schema_push(topology)
  292. master_schema_csn = topology.master.getSchemaCSN()
  293. consumer_schema_csn = topology.consumer.getSchemaCSN()
  294. # Check the schemaCSN was NOT updated on the consumer
  295. log.debug("test_ticket47490_two master_schema_csn=%s", master_schema_csn)
  296. log.debug("test_ticket47490_two consumer_schema_csn=%s", consumer_schema_csn)
  297. assert master_schema_csn != consumer_schema_csn
  298. # Check the error log of the supplier does not contain an error
  299. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  300. res = pattern_errorlog(topology.master.errorlog_file, regex)
  301. assert res
  302. def test_ticket47490_three(topology):
  303. """
  304. Summary: Extra OC Schema is pushed - no error
  305. If supplier schema is again a superset (one extra OC), then
  306. schema is pushed and there is no message in the error log
  307. State at startup
  308. - supplier +masterNewOCA +masterNewOCB
  309. - consumer +masterNewOCA +consumerNewOCA
  310. Final state
  311. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  312. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  313. """
  314. # Do an upate to trigger the schema push attempt
  315. # add this OC on consumer. Supplier will no push the schema
  316. add_OC(topology.master, 1, 'consumerNewOCA')
  317. # now push the scheam
  318. trigger_schema_push(topology)
  319. master_schema_csn = topology.master.getSchemaCSN()
  320. consumer_schema_csn = topology.consumer.getSchemaCSN()
  321. # Check the schemaCSN was NOT updated on the consumer
  322. log.debug("test_ticket47490_three master_schema_csn=%s", master_schema_csn)
  323. log.debug("test_ticket47490_three consumer_schema_csn=%s", consumer_schema_csn)
  324. assert master_schema_csn == consumer_schema_csn
  325. # Check the error log of the supplier does not contain an error
  326. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  327. res = pattern_errorlog(topology.master.errorlog_file, regex)
  328. assert res == None
  329. def test_ticket47490_four(topology):
  330. """
  331. Summary: Same OC - extra MUST: Schema is pushed - no error
  332. If supplier schema is again a superset (OC with more MUST), then
  333. schema is pushed and there is no message in the error log
  334. State at startup
  335. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  336. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  337. Final state
  338. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  339. +must=telexnumber
  340. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  341. +must=telexnumber
  342. """
  343. mod_OC(topology.master, 2, 'masterNewOCA', old_must=MUST_OLD, new_must=MUST_NEW, old_may=MAY_OLD, new_may=MAY_OLD)
  344. trigger_schema_push(topology)
  345. master_schema_csn = topology.master.getSchemaCSN()
  346. consumer_schema_csn = topology.consumer.getSchemaCSN()
  347. # Check the schemaCSN was updated on the consumer
  348. log.debug("test_ticket47490_four master_schema_csn=%s", master_schema_csn)
  349. log.debug("ctest_ticket47490_four onsumer_schema_csn=%s", consumer_schema_csn)
  350. assert master_schema_csn == consumer_schema_csn
  351. # Check the error log of the supplier does not contain an error
  352. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  353. res = pattern_errorlog(topology.master.errorlog_file, regex)
  354. assert res == None
  355. def test_ticket47490_five(topology):
  356. """
  357. Summary: Same OC - extra MUST: Schema is NOT pushed - error
  358. If consumer schema is a superset (OC with more MUST), then
  359. schema is not pushed and there is a message in the error log
  360. State at startup
  361. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  362. +must=telexnumber
  363. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  364. +must=telexnumber
  365. Final state
  366. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  367. +must=telexnumber
  368. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  369. +must=telexnumber +must=telexnumber
  370. Note: replication log is enabled to get more details
  371. """
  372. # get more detail why it fails
  373. topology.master.enableReplLogging()
  374. # add telenumber to 'consumerNewOCA' on the consumer
  375. mod_OC(topology.consumer, 1, 'consumerNewOCA', old_must=MUST_OLD, new_must=MUST_NEW, old_may=MAY_OLD, new_may=MAY_OLD)
  376. # add a new OC on the supplier so that its nsSchemaCSN is larger than the consumer (wait 2s)
  377. time.sleep(2)
  378. add_OC(topology.master, 4, 'masterNewOCC')
  379. trigger_schema_push(topology)
  380. master_schema_csn = topology.master.getSchemaCSN()
  381. consumer_schema_csn = topology.consumer.getSchemaCSN()
  382. # Check the schemaCSN was NOT updated on the consumer
  383. log.debug("test_ticket47490_five master_schema_csn=%s", master_schema_csn)
  384. log.debug("ctest_ticket47490_five onsumer_schema_csn=%s", consumer_schema_csn)
  385. assert master_schema_csn != consumer_schema_csn
  386. #Check that replication logging display additional message about 'telexNumber' not being
  387. # required in the master schema
  388. # This message appears before 'must not be overwritten' so it should be check first
  389. regex = re.compile("Attribute telexNumber is not required in 'consumerNewOCA' of the local supplier schema")
  390. res = pattern_errorlog(topology.master.errorlog_file, regex)
  391. assert res != None
  392. # Check the error log of the supplier does not contain an error
  393. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  394. res = pattern_errorlog(topology.master.errorlog_file, regex)
  395. assert res != None
  396. def test_ticket47490_six(topology):
  397. """
  398. Summary: Same OC - extra MUST: Schema is pushed - no error
  399. If supplier schema is again a superset (OC with more MUST), then
  400. schema is pushed and there is no message in the error log
  401. State at startup
  402. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  403. +must=telexnumber
  404. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  405. +must=telexnumber +must=telexnumber
  406. Final state
  407. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  408. +must=telexnumber +must=telexnumber
  409. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  410. +must=telexnumber +must=telexnumber
  411. Note: replication log is enabled to get more details
  412. """
  413. # add telenumber to 'consumerNewOCA' on the consumer
  414. mod_OC(topology.master, 1, 'consumerNewOCA', old_must=MUST_OLD, new_must=MUST_NEW, old_may=MAY_OLD, new_may=MAY_OLD)
  415. trigger_schema_push(topology)
  416. master_schema_csn = topology.master.getSchemaCSN()
  417. consumer_schema_csn = topology.consumer.getSchemaCSN()
  418. # Check the schemaCSN was NOT updated on the consumer
  419. log.debug("test_ticket47490_six master_schema_csn=%s", master_schema_csn)
  420. log.debug("ctest_ticket47490_six onsumer_schema_csn=%s", consumer_schema_csn)
  421. assert master_schema_csn == consumer_schema_csn
  422. # Check the error log of the supplier does not contain an error
  423. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  424. res = pattern_errorlog(topology.master.errorlog_file, regex)
  425. assert res == None
  426. def test_ticket47490_seven(topology):
  427. """
  428. Summary: Same OC - extra MAY: Schema is pushed - no error
  429. If supplier schema is again a superset (OC with more MAY), then
  430. schema is pushed and there is no message in the error log
  431. State at startup
  432. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  433. +must=telexnumber +must=telexnumber
  434. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  435. +must=telexnumber +must=telexnumber
  436. Final stat
  437. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  438. +must=telexnumber +must=telexnumber
  439. +may=postOfficeBox
  440. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  441. +must=telexnumber +must=telexnumber
  442. +may=postOfficeBox
  443. """
  444. mod_OC(topology.master, 2, 'masterNewOCA', old_must=MUST_NEW, new_must=MUST_NEW, old_may=MAY_OLD, new_may=MAY_NEW)
  445. trigger_schema_push(topology)
  446. master_schema_csn = topology.master.getSchemaCSN()
  447. consumer_schema_csn = topology.consumer.getSchemaCSN()
  448. # Check the schemaCSN was updated on the consumer
  449. log.debug("test_ticket47490_seven master_schema_csn=%s", master_schema_csn)
  450. log.debug("ctest_ticket47490_seven consumer_schema_csn=%s", consumer_schema_csn)
  451. assert master_schema_csn == consumer_schema_csn
  452. # Check the error log of the supplier does not contain an error
  453. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  454. res = pattern_errorlog(topology.master.errorlog_file, regex)
  455. assert res == None
  456. def test_ticket47490_eight(topology):
  457. """
  458. Summary: Same OC - extra MAY: Schema is NOT pushed - error
  459. If consumer schema is a superset (OC with more MAY), then
  460. schema is not pushed and there is message in the error log
  461. State at startup
  462. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  463. +must=telexnumber +must=telexnumber
  464. +may=postOfficeBox
  465. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  466. +must=telexnumber +must=telexnumber
  467. +may=postOfficeBox
  468. Final state
  469. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  470. +must=telexnumber +must=telexnumber
  471. +may=postOfficeBox +may=postOfficeBox
  472. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  473. +must=telexnumber +must=telexnumber
  474. +may=postOfficeBox +may=postOfficeBox
  475. """
  476. mod_OC(topology.consumer, 1, 'consumerNewOCA', old_must=MUST_NEW, new_must=MUST_NEW, old_may=MAY_OLD, new_may=MAY_NEW)
  477. # modify OC on the supplier so that its nsSchemaCSN is larger than the consumer (wait 2s)
  478. time.sleep(2)
  479. mod_OC(topology.master, 4, 'masterNewOCC', old_must=MUST_OLD, new_must=MUST_OLD, old_may=MAY_OLD, new_may=MAY_NEW)
  480. trigger_schema_push(topology)
  481. master_schema_csn = topology.master.getSchemaCSN()
  482. consumer_schema_csn = topology.consumer.getSchemaCSN()
  483. # Check the schemaCSN was not updated on the consumer
  484. log.debug("test_ticket47490_eight master_schema_csn=%s", master_schema_csn)
  485. log.debug("ctest_ticket47490_eight onsumer_schema_csn=%s", consumer_schema_csn)
  486. assert master_schema_csn != consumer_schema_csn
  487. #Check that replication logging display additional message about 'postOfficeBox' not being
  488. # allowed in the master schema
  489. # This message appears before 'must not be overwritten' so it should be check first
  490. regex = re.compile("Attribute postOfficeBox is not allowed in 'consumerNewOCA' of the local supplier schema")
  491. res = pattern_errorlog(topology.master.errorlog_file, regex)
  492. assert res != None
  493. # Check the error log of the supplier does not contain an error
  494. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  495. res = pattern_errorlog(topology.master.errorlog_file, regex)
  496. assert res != None
  497. def test_ticket47490_nine(topology):
  498. """
  499. Summary: Same OC - extra MAY: Schema is pushed - no error
  500. If consumer schema is a superset (OC with more MAY), then
  501. schema is not pushed and there is message in the error log
  502. State at startup
  503. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  504. +must=telexnumber +must=telexnumber
  505. +may=postOfficeBox +may=postOfficeBox
  506. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  507. +must=telexnumber +must=telexnumber
  508. +may=postOfficeBox +may=postOfficeBox
  509. Final state
  510. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  511. +must=telexnumber +must=telexnumber
  512. +may=postOfficeBox +may=postOfficeBox +may=postOfficeBox
  513. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  514. +must=telexnumber +must=telexnumber
  515. +may=postOfficeBox +may=postOfficeBox +may=postOfficeBox
  516. """
  517. mod_OC(topology.master, 1, 'consumerNewOCA', old_must=MUST_NEW, new_must=MUST_NEW, old_may=MAY_OLD, new_may=MAY_NEW)
  518. trigger_schema_push(topology)
  519. master_schema_csn = topology.master.getSchemaCSN()
  520. consumer_schema_csn = topology.consumer.getSchemaCSN()
  521. # Check the schemaCSN was updated on the consumer
  522. log.debug("test_ticket47490_nine master_schema_csn=%s", master_schema_csn)
  523. log.debug("ctest_ticket47490_nine onsumer_schema_csn=%s", consumer_schema_csn)
  524. assert master_schema_csn == consumer_schema_csn
  525. # Check the error log of the supplier does not contain an error
  526. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  527. res = pattern_errorlog(topology.master.errorlog_file, regex)
  528. assert res == None
  529. def test_ticket47490_final(topology):
  530. topology.master.stop(timeout=10)
  531. topology.consumer.stop(timeout=10)
  532. def run_isolated():
  533. '''
  534. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  535. To run isolated without py.test, you need to
  536. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  537. - set the installation prefix
  538. - run this program
  539. '''
  540. global installation_prefix
  541. installation_prefix = None
  542. topo = topology(True)
  543. test_ticket47490_init(topo)
  544. test_ticket47490_one(topo)
  545. test_ticket47490_two(topo)
  546. test_ticket47490_three(topo)
  547. test_ticket47490_four(topo)
  548. test_ticket47490_five(topo)
  549. test_ticket47490_six(topo)
  550. test_ticket47490_seven(topo)
  551. test_ticket47490_eight(topo)
  552. test_ticket47490_nine(topo)
  553. test_ticket47490_final(topo)
  554. if __name__ == '__main__':
  555. run_isolated()