ticket47973_test.py 4.6 KB

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