ticket47781_test.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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 os
  10. import sys
  11. import time
  12. import ldap
  13. import logging
  14. import pytest
  15. from lib389 import DirSrv, Entry, tools, tasks
  16. from lib389.tools import DirSrvTools
  17. from lib389._constants import *
  18. from lib389.properties import *
  19. from lib389.tasks import *
  20. log = logging.getLogger(__name__)
  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 test_ticket47781(topology):
  52. """
  53. Testing for a deadlock after doing an online import of an LDIF with
  54. replication data. The replication agreement should be invalid.
  55. """
  56. log.info('Testing Ticket 47781 - Testing for deadlock after importing LDIF with replication data')
  57. #
  58. # Setup Replication
  59. #
  60. log.info('Setting up replication...')
  61. topology.standalone.replica.enableReplication(suffix=DEFAULT_SUFFIX, role=REPLICAROLE_MASTER,
  62. replicaId=REPLICAID_MASTER_1)
  63. properties = {RA_NAME: r'meTo_$host:$port',
  64. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  65. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  66. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  67. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  68. # The agreement should point to a server that does NOT exist (invalid port)
  69. repl_agreement = topology.standalone.agreement.create(suffix=DEFAULT_SUFFIX,
  70. host=topology.standalone.host,
  71. port=5555,
  72. properties=properties)
  73. #
  74. # add two entries
  75. #
  76. log.info('Adding two entries...')
  77. try:
  78. topology.standalone.add_s(Entry(('cn=entry1,dc=example,dc=com', {
  79. 'objectclass': 'top person'.split(),
  80. 'sn': 'user',
  81. 'cn': 'entry1'})))
  82. except ldap.LDAPError as e:
  83. log.error('Failed to add entry 1: ' + e.message['desc'])
  84. assert False
  85. try:
  86. topology.standalone.add_s(Entry(('cn=entry2,dc=example,dc=com', {
  87. 'objectclass': 'top person'.split(),
  88. 'sn': 'user',
  89. 'cn': 'entry2'})))
  90. except ldap.LDAPError as e:
  91. log.error('Failed to add entry 2: ' + e.message['desc'])
  92. assert False
  93. #
  94. # export the replication ldif
  95. #
  96. log.info('Exporting replication ldif...')
  97. args = {EXPORT_REPL_INFO: True}
  98. exportTask = Tasks(topology.standalone)
  99. try:
  100. exportTask.exportLDIF(DEFAULT_SUFFIX, None, "/tmp/export.ldif", args)
  101. except ValueError:
  102. assert False
  103. #
  104. # Restart the server
  105. #
  106. log.info('Restarting server...')
  107. topology.standalone.stop(timeout=5)
  108. topology.standalone.start(timeout=5)
  109. #
  110. # Import the ldif
  111. #
  112. log.info('Import replication LDIF file...')
  113. importTask = Tasks(topology.standalone)
  114. args = {TASK_WAIT: True}
  115. try:
  116. importTask.importLDIF(DEFAULT_SUFFIX, None, "/tmp/export.ldif", args)
  117. os.remove("/tmp/export.ldif")
  118. except ValueError:
  119. os.remove("/tmp/export.ldif")
  120. assert False
  121. #
  122. # Search for tombstones - we should not hang/timeout
  123. #
  124. log.info('Search for tombstone entries(should find one and not hang)...')
  125. topology.standalone.set_option(ldap.OPT_NETWORK_TIMEOUT, 5)
  126. topology.standalone.set_option(ldap.OPT_TIMEOUT, 5)
  127. try:
  128. entries = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'objectclass=nsTombstone')
  129. if not entries:
  130. log.fatal('Search failed to find any entries.')
  131. assert PR_False
  132. except ldap.LDAPError as e:
  133. log.fatal('Search failed: ' + e.message['desc'])
  134. assert PR_False
  135. if __name__ == '__main__':
  136. # Run isolated
  137. # -s for DEBUG mode
  138. CURRENT_FILE = os.path.realpath(__file__)
  139. pytest.main("-s %s" % CURRENT_FILE)