ticket48295_test.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. import shutil
  16. from lib389 import DirSrv, Entry, tools
  17. from lib389 import DirSrvTools
  18. from lib389.tools import DirSrvTools
  19. from lib389._constants import *
  20. from lib389.properties import *
  21. log = logging.getLogger(__name__)
  22. installation_prefix = None
  23. LINKEDATTR_PLUGIN = 'cn=Linked Attributes,cn=plugins,cn=config'
  24. MANAGER_LINK = 'cn=Manager Link,' + LINKEDATTR_PLUGIN
  25. OU_PEOPLE = 'ou=People,' + DEFAULT_SUFFIX
  26. LINKTYPE = 'directReport'
  27. MANAGEDTYPE = 'manager'
  28. class TopologyStandalone(object):
  29. def __init__(self, standalone):
  30. standalone.open()
  31. self.standalone = standalone
  32. @pytest.fixture(scope="module")
  33. def topology(request):
  34. '''
  35. This fixture is used to standalone topology for the 'module'.
  36. '''
  37. global installation_prefix
  38. if installation_prefix:
  39. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  40. standalone = DirSrv(verbose=False)
  41. # Args for the standalone instance
  42. args_instance[SER_HOST] = HOST_STANDALONE
  43. args_instance[SER_PORT] = PORT_STANDALONE
  44. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  45. args_standalone = args_instance.copy()
  46. standalone.allocate(args_standalone)
  47. # Get the status of the instance and restart it if it exists
  48. instance_standalone = standalone.exists()
  49. # Remove the instance
  50. if instance_standalone:
  51. standalone.delete()
  52. # Create the instance
  53. standalone.create()
  54. # Used to retrieve configuration information (dbdir, confdir...)
  55. standalone.open()
  56. # clear the tmp directory
  57. standalone.clearTmpDir(__file__)
  58. # Here we have standalone instance up and running
  59. return TopologyStandalone(standalone)
  60. def _header(topology, label):
  61. topology.standalone.log.info("###############################################")
  62. topology.standalone.log.info("####### %s" % label)
  63. topology.standalone.log.info("###############################################")
  64. def check_attr_val(topology, dn, attr, expected, revert):
  65. try:
  66. centry = topology.standalone.search_s(dn, ldap.SCOPE_BASE, 'uid=*')
  67. if centry:
  68. val = centry[0].getValue(attr)
  69. if val:
  70. if val.lower() == expected.lower():
  71. if revert:
  72. log.info('Value of %s %s exists, which should not.' % (attr, expected))
  73. assert False
  74. else:
  75. log.info('Value of %s is %s' % (attr, expected))
  76. else:
  77. if revert:
  78. log.info('NEEDINFO: Value of %s is not %s, but %s' % (attr, expected, val))
  79. else:
  80. log.info('Value of %s is not %s, but %s' % (attr, expected, val))
  81. assert False
  82. else:
  83. if revert:
  84. log.info('Value of %s does not expectedly exist' % attr)
  85. else:
  86. log.info('Value of %s does not exist' % attr)
  87. assert False
  88. else:
  89. log.fatal('Failed to get %s' % dn)
  90. assert False
  91. except ldap.LDAPError as e:
  92. log.fatal('Failed to search ' + dn + ': ' + e.message['desc'])
  93. assert False
  94. def _48295_init(topology):
  95. """
  96. Set up Linked Attribute
  97. """
  98. _header(topology, 'Testing Ticket 48295 - Entry cache is not rolled back -- Linked Attributes plug-in - wrong behaviour when adding valid and broken links')
  99. log.info('Enable Dynamic plugins, and the linked Attrs plugin')
  100. try:
  101. topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')])
  102. except ldap.LDAPError as e:
  103. ldap.fatal('Failed to enable dynamic plugin!' + e.message['desc'])
  104. assert False
  105. try:
  106. topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
  107. except ValueError as e:
  108. ldap.fatal('Failed to enable linked attributes plugin!' + e.message['desc'])
  109. assert False
  110. log.info('Add the plugin config entry')
  111. try:
  112. topology.standalone.add_s(Entry((MANAGER_LINK, {
  113. 'objectclass': 'top extensibleObject'.split(),
  114. 'cn': 'Manager Link',
  115. 'linkType': LINKTYPE,
  116. 'managedType': MANAGEDTYPE
  117. })))
  118. except ldap.LDAPError as e:
  119. log.fatal('Failed to add linked attr config entry: error ' + e.message['desc'])
  120. assert False
  121. log.info('Add 2 entries: manager1 and employee1')
  122. try:
  123. topology.standalone.add_s(Entry(('uid=manager1,%s' % OU_PEOPLE, {
  124. 'objectclass': 'top extensibleObject'.split(),
  125. 'uid': 'manager1'})))
  126. except ldap.LDAPError as e:
  127. log.fatal('Add manager1 failed: error ' + e.message['desc'])
  128. assert False
  129. try:
  130. topology.standalone.add_s(Entry(('uid=employee1,%s' % OU_PEOPLE, {
  131. 'objectclass': 'top extensibleObject'.split(),
  132. 'uid': 'employee1'})))
  133. except ldap.LDAPError as e:
  134. log.fatal('Add employee1 failed: error ' + e.message['desc'])
  135. assert False
  136. log.info('PASSED')
  137. def _48295_run(topology):
  138. """
  139. Add 2 linktypes - one exists, another does not
  140. """
  141. _header(topology, 'Add 2 linktypes to manager1 - one exists, another does not to make sure the managed entry does not have managed type.')
  142. try:
  143. topology.standalone.modify_s('uid=manager1,%s' % OU_PEOPLE,
  144. [(ldap.MOD_ADD, LINKTYPE, 'uid=employee1,%s' % OU_PEOPLE),
  145. (ldap.MOD_ADD, LINKTYPE, 'uid=doNotExist,%s' % OU_PEOPLE)])
  146. except ldap.UNWILLING_TO_PERFORM:
  147. log.info('Add uid=employee1 and uid=doNotExist expectedly failed.')
  148. pass
  149. log.info('Check managed attribute does not exist.')
  150. check_attr_val(topology, 'uid=employee1,%s' % OU_PEOPLE, MANAGEDTYPE, 'uid=manager1,%s' % OU_PEOPLE, True)
  151. log.info('PASSED')
  152. def _48295_final(topology):
  153. topology.standalone.delete()
  154. log.info('All PASSED')
  155. def test_ticket48295(topology):
  156. '''
  157. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  158. To run isolated without py.test, you need to
  159. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  160. - set the installation prefix
  161. - run this program
  162. '''
  163. global installation_prefix
  164. installation_prefix = None
  165. _48295_init(topology)
  166. _48295_run(topology)
  167. _48295_final(topology)
  168. if __name__ == '__main__':
  169. # Run isolated
  170. # -s for DEBUG mode
  171. CURRENT_FILE = os.path.realpath(__file__)
  172. pytest.main("-s %s" % CURRENT_FILE)