ticket47973_test.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. import logging
  10. import re
  11. import ldap.sasl
  12. import pytest
  13. from lib389.tasks import *
  14. from lib389.topologies import topology_st
  15. log = logging.getLogger(__name__)
  16. USER_DN = 'uid=user1,%s' % (DEFAULT_SUFFIX)
  17. SCHEMA_RELOAD_COUNT = 10
  18. def task_complete(conn, task_dn):
  19. finished = False
  20. try:
  21. task_entry = conn.search_s(task_dn, ldap.SCOPE_BASE, 'objectclass=*')
  22. if not task_entry:
  23. log.fatal('wait_for_task: Search failed to find task: ' + task_dn)
  24. assert False
  25. if task_entry[0].hasAttr('nstaskexitcode'):
  26. # task is done
  27. finished = True
  28. except ldap.LDAPError as e:
  29. log.fatal('wait_for_task: Search failed: ' + e.message['desc'])
  30. assert False
  31. return finished
  32. def test_ticket47973(topology_st):
  33. """
  34. During the schema reload task there is a small window where the new schema is not loaded
  35. into the asi hashtables - this results in searches not returning entries.
  36. """
  37. log.info('Testing Ticket 47973 - Test the searches still work as expected during schema reload tasks')
  38. #
  39. # Add a user
  40. #
  41. try:
  42. topology_st.standalone.add_s(Entry((USER_DN, {
  43. 'objectclass': 'top extensibleObject'.split(),
  44. 'uid': 'user1'
  45. })))
  46. except ldap.LDAPError as e:
  47. log.error('Failed to add user1: error ' + e.message['desc'])
  48. assert False
  49. #
  50. # Run a series of schema_reload tasks while searching for our user. Since
  51. # this is a race condition, run it several times.
  52. #
  53. task_count = 0
  54. while task_count < SCHEMA_RELOAD_COUNT:
  55. #
  56. # Add a schema reload task
  57. #
  58. TASK_DN = 'cn=task-' + str(task_count) + ',cn=schema reload task, cn=tasks, cn=config'
  59. try:
  60. topology_st.standalone.add_s(Entry((TASK_DN, {
  61. 'objectclass': 'top extensibleObject'.split(),
  62. 'cn': 'task-' + str(task_count)
  63. })))
  64. except ldap.LDAPError as e:
  65. log.error('Failed to add task entry: error ' + e.message['desc'])
  66. assert False
  67. #
  68. # While we wait for the task to complete keep searching for our user
  69. #
  70. search_count = 0
  71. while search_count < 100:
  72. #
  73. # Now check the user is still being returned
  74. #
  75. try:
  76. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
  77. ldap.SCOPE_SUBTREE,
  78. '(uid=user1)')
  79. if not entries or not entries[0]:
  80. log.fatal('User was not returned from search!')
  81. assert False
  82. except ldap.LDAPError as e:
  83. log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
  84. assert False
  85. #
  86. # Check if task is complete
  87. #
  88. if task_complete(topology_st.standalone, TASK_DN):
  89. break
  90. search_count += 1
  91. task_count += 1
  92. def test_ticket47973_case(topology_st):
  93. log.info('Testing Ticket 47973 (case) - Test the cases in the original schema are preserved.')
  94. log.info('case 1 - Test the cases in the original schema are preserved.')
  95. tsfile = topology_st.standalone.schemadir + '/98test.ldif'
  96. tsfd = open(tsfile, "w")
  97. Mozattr0 = "MoZiLLaaTTRiBuTe"
  98. testschema = "dn: cn=schema\nattributetypes: ( 8.9.10.11.12.13.14 NAME '" + Mozattr0 + "' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Mozilla Dummy Schema' )\nobjectclasses: ( 1.2.3.4.5.6.7 NAME 'MozillaObject' SUP top MUST ( objectclass $ cn ) MAY ( " + Mozattr0 + " ) X-ORIGIN 'user defined' )"
  99. tsfd.write(testschema)
  100. tsfd.close()
  101. try:
  102. # run the schema reload task with the default schemadir
  103. topology_st.standalone.tasks.schemaReload(schemadir=topology_st.standalone.schemadir,
  104. args={TASK_WAIT: False})
  105. except ValueError:
  106. log.error('Schema Reload task failed.')
  107. assert False
  108. time.sleep(5)
  109. try:
  110. schemaentry = topology_st.standalone.search_s("cn=schema", ldap.SCOPE_BASE,
  111. 'objectclass=top',
  112. ["objectclasses"])
  113. oclist = schemaentry[0].data.get("objectclasses")
  114. except ldap.LDAPError as e:
  115. log.error('Failed to get schema entry: error (%s)' % e.message['desc'])
  116. raise e
  117. found = 0
  118. for oc in oclist:
  119. log.info('OC: %s' % oc)
  120. moz = re.findall(Mozattr0, oc)
  121. if moz:
  122. found = 1
  123. log.info('case 1: %s is in the objectclasses list -- PASS' % Mozattr0)
  124. if found == 0:
  125. log.error('case 1: %s is not in the objectclasses list -- FAILURE' % Mozattr0)
  126. assert False
  127. log.info('case 2 - Duplicated schema except cases are not loaded.')
  128. tsfile = topology_st.standalone.schemadir + '/97test.ldif'
  129. tsfd = open(tsfile, "w")
  130. Mozattr1 = "MOZILLAATTRIBUTE"
  131. testschema = "dn: cn=schema\nattributetypes: ( 8.9.10.11.12.13.14 NAME '" + Mozattr1 + "' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Mozilla Dummy Schema' )\nobjectclasses: ( 1.2.3.4.5.6.7 NAME 'MozillaObject' SUP top MUST ( objectclass $ cn ) MAY ( " + Mozattr1 + " ) X-ORIGIN 'user defined' )"
  132. tsfd.write(testschema)
  133. tsfd.close()
  134. try:
  135. # run the schema reload task with the default schemadir
  136. topology_st.standalone.tasks.schemaReload(schemadir=topology_st.standalone.schemadir,
  137. args={TASK_WAIT: False})
  138. except ValueError:
  139. log.error('Schema Reload task failed.')
  140. assert False
  141. time.sleep(5)
  142. try:
  143. schemaentry = topology_st.standalone.search_s("cn=schema", ldap.SCOPE_BASE,
  144. 'objectclass=top',
  145. ["objectclasses"])
  146. oclist = schemaentry[0].data.get("objectclasses")
  147. except ldap.LDAPError as e:
  148. log.error('Failed to get schema entry: error (%s)' % e.message['desc'])
  149. raise e
  150. for oc in oclist:
  151. log.info('OC: %s' % oc)
  152. moz = re.findall(Mozattr1, oc)
  153. if moz:
  154. log.error('case 2: %s is in the objectclasses list -- FAILURE' % Mozattr1)
  155. assert False
  156. log.info('case 2: %s is not in the objectclasses list -- PASS' % Mozattr1)
  157. Mozattr2 = "mozillaattribute"
  158. log.info('case 2-1: Use the custom schema with %s' % Mozattr2)
  159. name = "test user"
  160. try:
  161. topology_st.standalone.add_s(Entry(("cn=%s,%s" % (name, SUFFIX), {
  162. 'objectclass': "top person MozillaObject".split(),
  163. 'sn': name,
  164. 'cn': name,
  165. Mozattr2: name})))
  166. except ldap.LDAPError as e:
  167. log.error('Failed to add a test entry: error (%s)' % e.message['desc'])
  168. raise e
  169. try:
  170. testentry = topology_st.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE,
  171. 'objectclass=mozillaobject',
  172. [Mozattr2])
  173. except ldap.LDAPError as e:
  174. log.error('Failed to get schema entry: error (%s)' % e.message['desc'])
  175. raise e
  176. mozattrval = testentry[0].data.get(Mozattr2)
  177. if mozattrval[0] == name:
  178. log.info('case 2-1: %s: %s found-- PASS' % (Mozattr2, name))
  179. else:
  180. log.info('case 2-1: %s: %s not found-- FAILURE' % (Mozattr2, mozattrval[0]))
  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)