1
0

ticket47973_test.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import os
  2. import sys
  3. import time
  4. import ldap
  5. import ldap.sasl
  6. import logging
  7. import pytest
  8. from lib389 import DirSrv, Entry, tools, tasks
  9. from lib389.tools import DirSrvTools
  10. from lib389._constants import *
  11. from lib389.properties import *
  12. from lib389.tasks import *
  13. log = logging.getLogger(__name__)
  14. installation_prefix = None
  15. USER_DN = 'uid=user1,%s' % (DEFAULT_SUFFIX)
  16. SCHEMA_RELOAD_COUNT = 10
  17. class TopologyStandalone(object):
  18. def __init__(self, standalone):
  19. standalone.open()
  20. self.standalone = standalone
  21. @pytest.fixture(scope="module")
  22. def topology(request):
  23. '''
  24. This fixture is used to standalone topology for the 'module'.
  25. '''
  26. global installation_prefix
  27. if installation_prefix:
  28. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  29. standalone = DirSrv(verbose=False)
  30. # Args for the standalone instance
  31. args_instance[SER_HOST] = HOST_STANDALONE
  32. args_instance[SER_PORT] = PORT_STANDALONE
  33. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  34. args_standalone = args_instance.copy()
  35. standalone.allocate(args_standalone)
  36. # Get the status of the instance and restart it if it exists
  37. instance_standalone = standalone.exists()
  38. # Remove the instance
  39. if instance_standalone:
  40. standalone.delete()
  41. # Create the instance
  42. standalone.create()
  43. # Used to retrieve configuration information (dbdir, confdir...)
  44. standalone.open()
  45. # clear the tmp directory
  46. standalone.clearTmpDir(__file__)
  47. # Here we have standalone instance up and running
  48. return TopologyStandalone(standalone)
  49. def task_complete(conn, task_dn):
  50. finished = False
  51. try:
  52. task_entry = conn.search_s(task_dn, ldap.SCOPE_BASE, 'objectclass=*')
  53. if not task_entry:
  54. log.fatal('wait_for_task: Search failed to find task: ' + task_dn)
  55. assert False
  56. if task_entry[0].hasAttr('nstaskexitcode'):
  57. # task is done
  58. finished = True
  59. except ldap.LDAPError, e:
  60. log.fatal('wait_for_task: Search failed: ' + e.message['desc'])
  61. assert False
  62. return finished
  63. def test_ticket47973(topology):
  64. """
  65. During the schema reload task there is a small window where the new schema is not loaded
  66. into the asi hashtables - this results in searches not returning entries.
  67. """
  68. log.info('Testing Ticket 47973 - Test the searches still work as expected during schema reload tasks')
  69. #
  70. # Add a user
  71. #
  72. try:
  73. topology.standalone.add_s(Entry((USER_DN, {
  74. 'objectclass': 'top extensibleObject'.split(),
  75. 'uid': 'user1'
  76. })))
  77. except ldap.LDAPError, e:
  78. log.error('Failed to add user1: error ' + e.message['desc'])
  79. assert False
  80. #
  81. # Run a series of schema_reload tasks while searching for our user. Since
  82. # this is a race condition, run it several times.
  83. #
  84. task_count = 0
  85. while task_count < SCHEMA_RELOAD_COUNT:
  86. #
  87. # Add a schema reload task
  88. #
  89. TASK_DN = 'cn=task-' + str(task_count) + ',cn=schema reload task, cn=tasks, cn=config'
  90. try:
  91. topology.standalone.add_s(Entry((TASK_DN, {
  92. 'objectclass': 'top extensibleObject'.split(),
  93. 'cn': 'task-' + str(task_count)
  94. })))
  95. except ldap.LDAPError, e:
  96. log.error('Failed to add task entry: error ' + e.message['desc'])
  97. assert False
  98. #
  99. # While we wait for the task to complete keep searching for our user
  100. #
  101. search_count = 0
  102. while search_count < 100:
  103. #
  104. # Now check the user is still being returned
  105. #
  106. try:
  107. entries = topology.standalone.search_s(DEFAULT_SUFFIX,
  108. ldap.SCOPE_SUBTREE,
  109. '(uid=user1)')
  110. if not entries or not entries[0]:
  111. log.fatal('User was not returned from search!')
  112. assert False
  113. except ldap.LDAPError, e:
  114. log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
  115. assert False
  116. #
  117. # Check if task is complete
  118. #
  119. if task_complete(topology.standalone, TASK_DN):
  120. break
  121. search_count += 1
  122. task_count += 1
  123. def test_ticket47973_final(topology):
  124. topology.standalone.delete()
  125. log.info('Testcase PASSED')
  126. def run_isolated():
  127. '''
  128. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  129. To run isolated without py.test, you need to
  130. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  131. - set the installation prefix
  132. - run this program
  133. '''
  134. global installation_prefix
  135. installation_prefix = None
  136. topo = topology(True)
  137. test_ticket47973(topo)
  138. test_ticket47973_final(topo)
  139. if __name__ == '__main__':
  140. run_isolated()