ticket47490_test.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2016 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. '''
  10. Created on Nov 7, 2013
  11. @author: tbordaz
  12. '''
  13. import logging
  14. import re
  15. import time
  16. import ldap
  17. import pytest
  18. from lib389 import Entry
  19. from lib389._constants import *
  20. from lib389.topologies import topology_m1c1
  21. logging.getLogger(__name__).setLevel(logging.DEBUG)
  22. log = logging.getLogger(__name__)
  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. def _header(topology_m1c1, label):
  30. topology_m1c1.ms["master1"].log.info("\n\n###############################################")
  31. topology_m1c1.ms["master1"].log.info("#######")
  32. topology_m1c1.ms["master1"].log.info("####### %s" % label)
  33. topology_m1c1.ms["master1"].log.info("#######")
  34. topology_m1c1.ms["master1"].log.info("###################################################")
  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.schema.add_schema('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.schema.del_schema('objectClasses', old_oc)
  71. instance.schema.add_schema('objectClasses', new_oc)
  72. def support_schema_learning(topology_m1c1):
  73. """
  74. with https://fedorahosted.org/389/ticket/47721, the supplier and consumer can learn
  75. schema definitions when a replication occurs.
  76. Before that ticket: replication of the schema fails requiring administrative operation
  77. In the test the schemaCSN (master consumer) differs
  78. After that ticket: replication of the schema succeeds (after an initial phase of learning)
  79. In the test the schema CSN (master consumer) are in sync
  80. This function returns True if 47721 is fixed in the current release
  81. False else
  82. """
  83. ent = topology_m1c1.cs["consumer1"].getEntry(DN_CONFIG, ldap.SCOPE_BASE, "(cn=config)", ['nsslapd-versionstring'])
  84. if ent.hasAttr('nsslapd-versionstring'):
  85. val = ent.getValue('nsslapd-versionstring')
  86. version = val.split('/')[1].split('.') # something like ['1', '3', '1', '23', 'final_fix']
  87. major = int(version[0])
  88. minor = int(version[1])
  89. if major > 1:
  90. return True
  91. if minor > 3:
  92. # version is 1.4 or after
  93. return True
  94. if minor == 3:
  95. if version[2].isdigit():
  96. if int(version[2]) >= 3:
  97. return True
  98. return False
  99. def trigger_update(topology_m1c1):
  100. """
  101. It triggers an update on the supplier. This will start a replication
  102. session and a schema push
  103. """
  104. try:
  105. trigger_update.value += 1
  106. except AttributeError:
  107. trigger_update.value = 1
  108. replace = [(ldap.MOD_REPLACE, 'telephonenumber', str(trigger_update.value))]
  109. topology_m1c1.ms["master1"].modify_s(ENTRY_DN, replace)
  110. # wait 10 seconds that the update is replicated
  111. loop = 0
  112. while loop <= 10:
  113. try:
  114. ent = topology_m1c1.cs["consumer1"].getEntry(ENTRY_DN, ldap.SCOPE_BASE, "(objectclass=*)",
  115. ['telephonenumber'])
  116. val = ent.telephonenumber or "0"
  117. if int(val) == trigger_update.value:
  118. return
  119. # the expected value is not yet replicated. try again
  120. time.sleep(1)
  121. loop += 1
  122. log.debug("trigger_update: receive %s (expected %d)" % (val, trigger_update.value))
  123. except ldap.NO_SUCH_OBJECT:
  124. time.sleep(1)
  125. loop += 1
  126. def trigger_schema_push(topology_m1c1):
  127. '''
  128. Trigger update to create a replication session.
  129. In case of 47721 is fixed and the replica needs to learn the missing definition, then
  130. the first replication session learn the definition and the second replication session
  131. push the schema (and the schemaCSN.
  132. This is why there is two updates and replica agreement is stopped/start (to create a second session)
  133. '''
  134. agreements = topology_m1c1.ms["master1"].agreement.list(suffix=SUFFIX,
  135. consumer_host=topology_m1c1.cs["consumer1"].host,
  136. consumer_port=topology_m1c1.cs["consumer1"].port)
  137. assert (len(agreements) == 1)
  138. ra = agreements[0]
  139. trigger_update(topology_m1c1)
  140. topology_m1c1.ms["master1"].agreement.pause(ra.dn)
  141. topology_m1c1.ms["master1"].agreement.resume(ra.dn)
  142. trigger_update(topology_m1c1)
  143. def test_ticket47490_init(topology_m1c1):
  144. """
  145. Initialize the test environment
  146. """
  147. log.debug("test_ticket47490_init topology_m1c1 %r (master %r, consumer %r" % (
  148. topology_m1c1, topology_m1c1.ms["master1"], topology_m1c1.cs["consumer1"]))
  149. # the test case will check if a warning message is logged in the
  150. # error log of the supplier
  151. topology_m1c1.ms["master1"].errorlog_file = open(topology_m1c1.ms["master1"].errlog, "r")
  152. # This entry will be used to trigger attempt of schema push
  153. topology_m1c1.ms["master1"].add_s(Entry((ENTRY_DN, {
  154. 'objectclass': "top person".split(),
  155. 'sn': 'test_entry',
  156. 'cn': 'test_entry'})))
  157. def test_ticket47490_one(topology_m1c1):
  158. """
  159. Summary: Extra OC Schema is pushed - no error
  160. If supplier schema is a superset (one extra OC) of consumer schema, then
  161. schema is pushed and there is no message in the error log
  162. State at startup:
  163. - supplier default schema
  164. - consumer default schema
  165. Final state
  166. - supplier +masterNewOCA
  167. - consumer +masterNewOCA
  168. """
  169. _header(topology_m1c1, "Extra OC Schema is pushed - no error")
  170. log.debug("test_ticket47490_one topology_m1c1 %r (master %r, consumer %r" % (
  171. topology_m1c1, topology_m1c1.ms["master1"], topology_m1c1.cs["consumer1"]))
  172. # update the schema of the supplier so that it is a superset of
  173. # consumer. Schema should be pushed
  174. add_OC(topology_m1c1.ms["master1"], 2, 'masterNewOCA')
  175. trigger_schema_push(topology_m1c1)
  176. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  177. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  178. # Check the schemaCSN was updated on the consumer
  179. log.debug("test_ticket47490_one master_schema_csn=%s", master_schema_csn)
  180. log.debug("ctest_ticket47490_one onsumer_schema_csn=%s", consumer_schema_csn)
  181. assert master_schema_csn == consumer_schema_csn
  182. # Check the error log of the supplier does not contain an error
  183. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  184. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  185. if res is not None:
  186. assert False
  187. def test_ticket47490_two(topology_m1c1):
  188. """
  189. Summary: Extra OC Schema is pushed - (ticket 47721 allows to learn missing def)
  190. If consumer schema is a superset (one extra OC) of supplier schema, then
  191. schema is pushed and there is a message in the error log
  192. State at startup
  193. - supplier +masterNewOCA
  194. - consumer +masterNewOCA
  195. Final state
  196. - supplier +masterNewOCA +masterNewOCB
  197. - consumer +masterNewOCA +consumerNewOCA
  198. """
  199. _header(topology_m1c1, "Extra OC Schema is pushed - (ticket 47721 allows to learn missing def)")
  200. # add this OC on consumer. Supplier will no push the schema
  201. add_OC(topology_m1c1.cs["consumer1"], 1, 'consumerNewOCA')
  202. # add a new OC on the supplier so that its nsSchemaCSN is larger than the consumer (wait 2s)
  203. time.sleep(2)
  204. add_OC(topology_m1c1.ms["master1"], 3, 'masterNewOCB')
  205. # now push the scheam
  206. trigger_schema_push(topology_m1c1)
  207. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  208. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  209. # Check the schemaCSN was NOT updated on the consumer
  210. # with 47721, supplier learns the missing definition
  211. log.debug("test_ticket47490_two master_schema_csn=%s", master_schema_csn)
  212. log.debug("test_ticket47490_two consumer_schema_csn=%s", consumer_schema_csn)
  213. if support_schema_learning(topology_m1c1):
  214. assert master_schema_csn == consumer_schema_csn
  215. else:
  216. assert master_schema_csn != consumer_schema_csn
  217. # Check the error log of the supplier does not contain an error
  218. # This message may happen during the learning phase
  219. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  220. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  221. def test_ticket47490_three(topology_m1c1):
  222. """
  223. Summary: Extra OC Schema is pushed - no error
  224. If supplier schema is again a superset (one extra OC), then
  225. schema is pushed and there is no message in the error log
  226. State at startup
  227. - supplier +masterNewOCA +masterNewOCB
  228. - consumer +masterNewOCA +consumerNewOCA
  229. Final state
  230. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  231. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  232. """
  233. _header(topology_m1c1, "Extra OC Schema is pushed - no error")
  234. # Do an upate to trigger the schema push attempt
  235. # add this OC on consumer. Supplier will no push the schema
  236. add_OC(topology_m1c1.ms["master1"], 1, 'consumerNewOCA')
  237. # now push the scheam
  238. trigger_schema_push(topology_m1c1)
  239. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  240. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  241. # Check the schemaCSN was NOT updated on the consumer
  242. log.debug("test_ticket47490_three master_schema_csn=%s", master_schema_csn)
  243. log.debug("test_ticket47490_three consumer_schema_csn=%s", consumer_schema_csn)
  244. assert master_schema_csn == consumer_schema_csn
  245. # Check the error log of the supplier does not contain an error
  246. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  247. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  248. if res is not None:
  249. assert False
  250. def test_ticket47490_four(topology_m1c1):
  251. """
  252. Summary: Same OC - extra MUST: Schema is pushed - no error
  253. If supplier schema is again a superset (OC with more MUST), then
  254. schema is pushed and there is no message in the error log
  255. State at startup
  256. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  257. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  258. Final state
  259. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  260. +must=telexnumber
  261. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  262. +must=telexnumber
  263. """
  264. _header(topology_m1c1, "Same OC - extra MUST: Schema is pushed - no error")
  265. mod_OC(topology_m1c1.ms["master1"], 2, 'masterNewOCA', old_must=MUST_OLD, new_must=MUST_NEW, old_may=MAY_OLD,
  266. new_may=MAY_OLD)
  267. trigger_schema_push(topology_m1c1)
  268. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  269. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  270. # Check the schemaCSN was updated on the consumer
  271. log.debug("test_ticket47490_four master_schema_csn=%s", master_schema_csn)
  272. log.debug("ctest_ticket47490_four onsumer_schema_csn=%s", consumer_schema_csn)
  273. assert master_schema_csn == consumer_schema_csn
  274. # Check the error log of the supplier does not contain an error
  275. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  276. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  277. if res is not None:
  278. assert False
  279. def test_ticket47490_five(topology_m1c1):
  280. """
  281. Summary: Same OC - extra MUST: Schema is pushed - (fix for 47721)
  282. If consumer schema is a superset (OC with more MUST), then
  283. schema is pushed (fix for 47721) and there is a message in the error log
  284. State at startup
  285. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA
  286. +must=telexnumber
  287. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  288. +must=telexnumber
  289. Final state
  290. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  291. +must=telexnumber
  292. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  293. +must=telexnumber +must=telexnumber
  294. Note: replication log is enabled to get more details
  295. """
  296. _header(topology_m1c1, "Same OC - extra MUST: Schema is pushed - (fix for 47721)")
  297. # get more detail why it fails
  298. topology_m1c1.ms["master1"].enableReplLogging()
  299. # add telenumber to 'consumerNewOCA' on the consumer
  300. mod_OC(topology_m1c1.cs["consumer1"], 1, 'consumerNewOCA', old_must=MUST_OLD, new_must=MUST_NEW, old_may=MAY_OLD,
  301. new_may=MAY_OLD)
  302. # add a new OC on the supplier so that its nsSchemaCSN is larger than the consumer (wait 2s)
  303. time.sleep(2)
  304. add_OC(topology_m1c1.ms["master1"], 4, 'masterNewOCC')
  305. trigger_schema_push(topology_m1c1)
  306. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  307. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  308. # Check the schemaCSN was NOT updated on the consumer
  309. # with 47721, supplier learns the missing definition
  310. log.debug("test_ticket47490_five master_schema_csn=%s", master_schema_csn)
  311. log.debug("ctest_ticket47490_five onsumer_schema_csn=%s", consumer_schema_csn)
  312. if support_schema_learning(topology_m1c1):
  313. assert master_schema_csn == consumer_schema_csn
  314. else:
  315. assert master_schema_csn != consumer_schema_csn
  316. # Check the error log of the supplier does not contain an error
  317. # This message may happen during the learning phase
  318. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  319. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  320. def test_ticket47490_six(topology_m1c1):
  321. """
  322. Summary: Same OC - extra MUST: Schema is pushed - no error
  323. If supplier schema is again a superset (OC with more MUST), then
  324. schema is pushed and there is no message in the error log
  325. State at startup
  326. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  327. +must=telexnumber
  328. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA
  329. +must=telexnumber +must=telexnumber
  330. Final state
  331. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  332. +must=telexnumber +must=telexnumber
  333. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  334. +must=telexnumber +must=telexnumber
  335. Note: replication log is enabled to get more details
  336. """
  337. _header(topology_m1c1, "Same OC - extra MUST: Schema is pushed - no error")
  338. # add telenumber to 'consumerNewOCA' on the consumer
  339. mod_OC(topology_m1c1.ms["master1"], 1, 'consumerNewOCA', old_must=MUST_OLD, new_must=MUST_NEW, old_may=MAY_OLD,
  340. new_may=MAY_OLD)
  341. trigger_schema_push(topology_m1c1)
  342. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  343. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  344. # Check the schemaCSN was NOT updated on the consumer
  345. log.debug("test_ticket47490_six master_schema_csn=%s", master_schema_csn)
  346. log.debug("ctest_ticket47490_six onsumer_schema_csn=%s", consumer_schema_csn)
  347. assert master_schema_csn == consumer_schema_csn
  348. # Check the error log of the supplier does not contain an error
  349. # This message may happen during the learning phase
  350. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  351. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  352. if res is not None:
  353. assert False
  354. def test_ticket47490_seven(topology_m1c1):
  355. """
  356. Summary: Same OC - extra MAY: Schema is pushed - no error
  357. If supplier schema is again a superset (OC with more MAY), then
  358. schema is pushed and there is no message in the error log
  359. State at startup
  360. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  361. +must=telexnumber +must=telexnumber
  362. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  363. +must=telexnumber +must=telexnumber
  364. Final stat
  365. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  366. +must=telexnumber +must=telexnumber
  367. +may=postOfficeBox
  368. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  369. +must=telexnumber +must=telexnumber
  370. +may=postOfficeBox
  371. """
  372. _header(topology_m1c1, "Same OC - extra MAY: Schema is pushed - no error")
  373. mod_OC(topology_m1c1.ms["master1"], 2, 'masterNewOCA', old_must=MUST_NEW, new_must=MUST_NEW, old_may=MAY_OLD,
  374. new_may=MAY_NEW)
  375. trigger_schema_push(topology_m1c1)
  376. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  377. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  378. # Check the schemaCSN was updated on the consumer
  379. log.debug("test_ticket47490_seven master_schema_csn=%s", master_schema_csn)
  380. log.debug("ctest_ticket47490_seven consumer_schema_csn=%s", consumer_schema_csn)
  381. assert master_schema_csn == consumer_schema_csn
  382. # Check the error log of the supplier does not contain an error
  383. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  384. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  385. if res is not None:
  386. assert False
  387. def test_ticket47490_eight(topology_m1c1):
  388. """
  389. Summary: Same OC - extra MAY: Schema is pushed (fix for 47721)
  390. If consumer schema is a superset (OC with more MAY), then
  391. schema is pushed (fix for 47721) and there is message in the error log
  392. State at startup
  393. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  394. +must=telexnumber +must=telexnumber
  395. +may=postOfficeBox
  396. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  397. +must=telexnumber +must=telexnumber
  398. +may=postOfficeBox
  399. Final state
  400. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  401. +must=telexnumber +must=telexnumber
  402. +may=postOfficeBox +may=postOfficeBox
  403. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  404. +must=telexnumber +must=telexnumber
  405. +may=postOfficeBox +may=postOfficeBox
  406. """
  407. _header(topology_m1c1, "Same OC - extra MAY: Schema is pushed (fix for 47721)")
  408. mod_OC(topology_m1c1.cs["consumer1"], 1, 'consumerNewOCA', old_must=MUST_NEW, new_must=MUST_NEW, old_may=MAY_OLD,
  409. new_may=MAY_NEW)
  410. # modify OC on the supplier so that its nsSchemaCSN is larger than the consumer (wait 2s)
  411. time.sleep(2)
  412. mod_OC(topology_m1c1.ms["master1"], 4, 'masterNewOCC', old_must=MUST_OLD, new_must=MUST_OLD, old_may=MAY_OLD,
  413. new_may=MAY_NEW)
  414. trigger_schema_push(topology_m1c1)
  415. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  416. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  417. # Check the schemaCSN was not updated on the consumer
  418. # with 47721, supplier learns the missing definition
  419. log.debug("test_ticket47490_eight master_schema_csn=%s", master_schema_csn)
  420. log.debug("ctest_ticket47490_eight onsumer_schema_csn=%s", consumer_schema_csn)
  421. if support_schema_learning(topology_m1c1):
  422. assert master_schema_csn == consumer_schema_csn
  423. else:
  424. assert master_schema_csn != consumer_schema_csn
  425. # Check the error log of the supplier does not contain an error
  426. # This message may happen during the learning phase
  427. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  428. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  429. def test_ticket47490_nine(topology_m1c1):
  430. """
  431. Summary: Same OC - extra MAY: Schema is pushed - no error
  432. If consumer schema is a superset (OC with more MAY), then
  433. schema is not pushed and there is message in the error log
  434. State at startup
  435. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  436. +must=telexnumber +must=telexnumber
  437. +may=postOfficeBox +may=postOfficeBox
  438. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  439. +must=telexnumber +must=telexnumber
  440. +may=postOfficeBox +may=postOfficeBox
  441. Final state
  442. - supplier +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  443. +must=telexnumber +must=telexnumber
  444. +may=postOfficeBox +may=postOfficeBox +may=postOfficeBox
  445. - consumer +masterNewOCA +masterNewOCB +consumerNewOCA +masterNewOCC
  446. +must=telexnumber +must=telexnumber
  447. +may=postOfficeBox +may=postOfficeBox +may=postOfficeBox
  448. """
  449. _header(topology_m1c1, "Same OC - extra MAY: Schema is pushed - no error")
  450. mod_OC(topology_m1c1.ms["master1"], 1, 'consumerNewOCA', old_must=MUST_NEW, new_must=MUST_NEW, old_may=MAY_OLD,
  451. new_may=MAY_NEW)
  452. trigger_schema_push(topology_m1c1)
  453. master_schema_csn = topology_m1c1.ms["master1"].schema.get_schema_csn()
  454. consumer_schema_csn = topology_m1c1.cs["consumer1"].schema.get_schema_csn()
  455. # Check the schemaCSN was updated on the consumer
  456. log.debug("test_ticket47490_nine master_schema_csn=%s", master_schema_csn)
  457. log.debug("ctest_ticket47490_nine onsumer_schema_csn=%s", consumer_schema_csn)
  458. assert master_schema_csn == consumer_schema_csn
  459. # Check the error log of the supplier does not contain an error
  460. regex = re.compile("must not be overwritten \(set replication log for additional info\)")
  461. res = pattern_errorlog(topology_m1c1.ms["master1"].errorlog_file, regex)
  462. if res is not None:
  463. assert False
  464. log.info('Testcase PASSED')
  465. if __name__ == '__main__':
  466. # Run isolated
  467. # -s for DEBUG mode
  468. CURRENT_FILE = os.path.realpath(__file__)
  469. pytest.main("-s %s" % CURRENT_FILE)