ticket47808_test.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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
  16. from lib389.tools import DirSrvTools
  17. from lib389._constants import *
  18. from lib389.properties import *
  19. log = logging.getLogger(__name__)
  20. installation_prefix = None
  21. ATTRIBUTE_UNIQUENESS_PLUGIN = 'cn=attribute uniqueness,cn=plugins,cn=config'
  22. ENTRY_NAME = 'test_entry'
  23. class TopologyStandalone(object):
  24. def __init__(self, standalone):
  25. standalone.open()
  26. self.standalone = standalone
  27. @pytest.fixture(scope="module")
  28. def topology(request):
  29. '''
  30. This fixture is used to standalone topology for the 'module'.
  31. '''
  32. global installation_prefix
  33. if installation_prefix:
  34. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  35. standalone = DirSrv(verbose=False)
  36. # Args for the standalone instance
  37. args_instance[SER_HOST] = HOST_STANDALONE
  38. args_instance[SER_PORT] = PORT_STANDALONE
  39. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  40. args_standalone = args_instance.copy()
  41. standalone.allocate(args_standalone)
  42. # Get the status of the instance and restart it if it exists
  43. instance_standalone = standalone.exists()
  44. # Remove the instance
  45. if instance_standalone:
  46. standalone.delete()
  47. # Create the instance
  48. standalone.create()
  49. # Used to retrieve configuration information (dbdir, confdir...)
  50. standalone.open()
  51. def fin():
  52. standalone.delete()
  53. request.addfinalizer(fin)
  54. # Here we have standalone instance up and running
  55. return TopologyStandalone(standalone)
  56. def test_ticket47808_run(topology):
  57. """
  58. It enables attribute uniqueness plugin with sn as a unique attribute
  59. Add an entry 1 with sn = ENTRY_NAME
  60. Add an entry 2 with sn = ENTRY_NAME
  61. If the second add does not crash the server and the following search found none,
  62. the bug is fixed.
  63. """
  64. # bind as directory manager
  65. topology.standalone.log.info("Bind as %s" % DN_DM)
  66. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  67. topology.standalone.log.info("\n\n######################### SETUP ATTR UNIQ PLUGIN ######################\n")
  68. # enable attribute uniqueness plugin
  69. mod = [(ldap.MOD_REPLACE, 'nsslapd-pluginEnabled', 'on'), (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'sn'), (ldap.MOD_REPLACE, 'nsslapd-pluginarg1', SUFFIX)]
  70. topology.standalone.modify_s(ATTRIBUTE_UNIQUENESS_PLUGIN, mod)
  71. topology.standalone.log.info("\n\n######################### ADD USER 1 ######################\n")
  72. # Prepare entry 1
  73. entry_name = '%s 1' % (ENTRY_NAME)
  74. entry_dn_1 = 'cn=%s, %s' % (entry_name, SUFFIX)
  75. entry_1 = Entry(entry_dn_1)
  76. entry_1.setValues('objectclass', 'top', 'person')
  77. entry_1.setValues('sn', ENTRY_NAME)
  78. entry_1.setValues('cn', entry_name)
  79. topology.standalone.log.info("Try to add Add %s: %r" % (entry_1, entry_1))
  80. topology.standalone.add_s(entry_1)
  81. topology.standalone.log.info("\n\n######################### Restart Server ######################\n")
  82. topology.standalone.stop(timeout=10)
  83. topology.standalone.start(timeout=10)
  84. topology.standalone.log.info("\n\n######################### ADD USER 2 ######################\n")
  85. # Prepare entry 2 having the same sn, which crashes the server
  86. entry_name = '%s 2' % (ENTRY_NAME)
  87. entry_dn_2 = 'cn=%s, %s' % (entry_name, SUFFIX)
  88. entry_2 = Entry(entry_dn_2)
  89. entry_2.setValues('objectclass', 'top', 'person')
  90. entry_2.setValues('sn', ENTRY_NAME)
  91. entry_2.setValues('cn', entry_name)
  92. topology.standalone.log.info("Try to add Add %s: %r" % (entry_2, entry_2))
  93. try:
  94. topology.standalone.add_s(entry_2)
  95. except:
  96. topology.standalone.log.warn("Adding %s failed" % entry_dn_2)
  97. pass
  98. topology.standalone.log.info("\n\n######################### IS SERVER UP? ######################\n")
  99. ents = topology.standalone.search_s(entry_dn_1, ldap.SCOPE_BASE, '(objectclass=*)')
  100. assert len(ents) == 1
  101. topology.standalone.log.info("Yes, it's up.")
  102. topology.standalone.log.info("\n\n######################### CHECK USER 2 NOT ADDED ######################\n")
  103. topology.standalone.log.info("Try to search %s" % entry_dn_2)
  104. try:
  105. ents = topology.standalone.search_s(entry_dn_2, ldap.SCOPE_BASE, '(objectclass=*)')
  106. except ldap.NO_SUCH_OBJECT:
  107. topology.standalone.log.info("Found none")
  108. topology.standalone.log.info("\n\n######################### DELETE USER 1 ######################\n")
  109. topology.standalone.log.info("Try to delete %s " % entry_dn_1)
  110. topology.standalone.delete_s(entry_dn_1)
  111. def test_ticket47808_final(topology):
  112. log.info('Testcase PASSED')
  113. def run_isolated():
  114. '''
  115. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  116. To run isolated without py.test, you need to
  117. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  118. - set the installation prefix
  119. - run this program
  120. '''
  121. global installation_prefix
  122. installation_prefix = None
  123. topo = topology(True)
  124. test_ticket47808_run(topo)
  125. test_ticket47808_final(topo)
  126. if __name__ == '__main__':
  127. run_isolated()