ticket47937_test.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import os
  2. import sys
  3. import time
  4. import ldap
  5. import logging
  6. import socket
  7. import pytest
  8. from lib389 import DirSrv, Entry, tools
  9. from lib389.tools import DirSrvTools
  10. from lib389._constants import *
  11. from lib389.properties import *
  12. from constants import *
  13. log = logging.getLogger(__name__)
  14. installation_prefix = None
  15. class TopologyStandalone(object):
  16. def __init__(self, standalone):
  17. standalone.open()
  18. self.standalone = standalone
  19. @pytest.fixture(scope="module")
  20. def topology(request):
  21. '''
  22. This fixture is used to standalone topology for the 'module'.
  23. At the beginning, It may exists a standalone instance.
  24. It may also exists a backup for the standalone instance.
  25. Principle:
  26. If standalone instance exists:
  27. restart it
  28. If backup of standalone exists:
  29. create/rebind to standalone
  30. restore standalone instance from backup
  31. else:
  32. Cleanup everything
  33. remove instance
  34. remove backup
  35. Create instance
  36. Create backup
  37. '''
  38. global installation_prefix
  39. if installation_prefix:
  40. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  41. standalone = DirSrv(verbose=False)
  42. # Args for the standalone instance
  43. args_instance[SER_HOST] = HOST_STANDALONE
  44. args_instance[SER_PORT] = PORT_STANDALONE
  45. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  46. args_standalone = args_instance.copy()
  47. standalone.allocate(args_standalone)
  48. # Get the status of the backups
  49. backup_standalone = standalone.checkBackupFS()
  50. # Get the status of the instance and restart it if it exists
  51. instance_standalone = standalone.exists()
  52. if instance_standalone:
  53. # assuming the instance is already stopped, just wait 5 sec max
  54. standalone.stop(timeout=5)
  55. standalone.start(timeout=10)
  56. if backup_standalone:
  57. # The backup exist, assuming it is correct
  58. # we just re-init the instance with it
  59. if not instance_standalone:
  60. standalone.create()
  61. # Used to retrieve configuration information (dbdir, confdir...)
  62. standalone.open()
  63. # restore standalone instance from backup
  64. standalone.stop(timeout=10)
  65. standalone.restoreFS(backup_standalone)
  66. standalone.start(timeout=10)
  67. else:
  68. # We should be here only in two conditions
  69. # - This is the first time a test involve standalone instance
  70. # - Something weird happened (instance/backup destroyed)
  71. # so we discard everything and recreate all
  72. # Remove the backup. So even if we have a specific backup file
  73. # (e.g backup_standalone) we clear backup that an instance may have created
  74. if backup_standalone:
  75. standalone.clearBackupFS()
  76. # Remove the instance
  77. if instance_standalone:
  78. standalone.delete()
  79. # Create the instance
  80. standalone.create()
  81. # Used to retrieve configuration information (dbdir, confdir...)
  82. standalone.open()
  83. # Time to create the backups
  84. standalone.stop(timeout=10)
  85. standalone.backupfile = standalone.backupFS()
  86. standalone.start(timeout=10)
  87. # clear the tmp directory
  88. standalone.clearTmpDir(__file__)
  89. #
  90. # Here we have standalone instance up and running
  91. # Either coming from a backup recovery
  92. # or from a fresh (re)init
  93. # Time to return the topology
  94. return TopologyStandalone(standalone)
  95. def test_ticket47937(topology):
  96. """
  97. Test that DNA plugin only accepts valid attributes for "dnaType"
  98. """
  99. log.info("Creating \"ou=people\"...")
  100. try:
  101. topology.standalone.add_s(Entry(('ou=people,' + SUFFIX, {
  102. 'objectclass': 'top organizationalunit'.split(),
  103. 'ou': 'people'
  104. })))
  105. except ldap.ALREADY_EXISTS:
  106. pass
  107. except ldap.LDAPError, e:
  108. log.error('Failed to add ou=people org unit: error ' + e.message['desc'])
  109. assert False
  110. log.info("Creating \"ou=ranges\"...")
  111. try:
  112. topology.standalone.add_s(Entry(('ou=ranges,' + SUFFIX, {
  113. 'objectclass': 'top organizationalunit'.split(),
  114. 'ou': 'ranges'
  115. })))
  116. except ldap.LDAPError, e:
  117. log.error('Failed to add ou=ranges org unit: error ' + e.message['desc'])
  118. assert False
  119. log.info("Creating \"cn=entry\"...")
  120. try:
  121. topology.standalone.add_s(Entry(('cn=entry,ou=people,' + SUFFIX, {
  122. 'objectclass': 'top groupofuniquenames'.split(),
  123. 'cn': 'entry'
  124. })))
  125. except ldap.LDAPError, e:
  126. log.error('Failed to add test entry: error ' + e.message['desc'])
  127. assert False
  128. log.info("Creating DNA shared config entry...")
  129. try:
  130. topology.standalone.add_s(Entry(('dnaHostname=localhost.localdomain+dnaPortNum=389,ou=ranges,%s' % SUFFIX, {
  131. 'objectclass': 'top dnaSharedConfig'.split(),
  132. 'dnaHostname': 'localhost.localdomain',
  133. 'dnaPortNum': '389',
  134. 'dnaSecurePortNum': '636',
  135. 'dnaRemainingValues': '9501'
  136. })))
  137. except ldap.LDAPError, e:
  138. log.error('Failed to add shared config entry: error ' + e.message['desc'])
  139. assert False
  140. log.info("Add dna plugin config entry...")
  141. try:
  142. topology.standalone.add_s(Entry(('cn=dna config,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config', {
  143. 'objectclass': 'top dnaPluginConfig'.split(),
  144. 'dnaType': 'description',
  145. 'dnaMaxValue': '10000',
  146. 'dnaMagicRegen': '0',
  147. 'dnaFilter': '(objectclass=top)',
  148. 'dnaScope': 'ou=people,%s' % SUFFIX,
  149. 'dnaNextValue': '500',
  150. 'dnaSharedCfgDN': 'ou=ranges,%s' % SUFFIX
  151. })))
  152. except ldap.LDAPError, e:
  153. log.error('Failed to add DNA config entry: error ' + e.message['desc'])
  154. assert False
  155. log.info("Enable the DNA plugin...")
  156. try:
  157. topology.standalone.plugins.enable(name=PLUGIN_DNA)
  158. except e:
  159. log.error("Failed to enable DNA Plugin: error " + e.message['desc'])
  160. assert False
  161. log.info("Restarting the server...")
  162. topology.standalone.stop(timeout=120)
  163. time.sleep(1)
  164. topology.standalone.start(timeout=120)
  165. time.sleep(3)
  166. log.info("Apply an invalid attribute to the DNA config(dnaType: foo)...")
  167. try:
  168. topology.standalone.modify_s('cn=dna config,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config',
  169. [(ldap.MOD_REPLACE, 'dnaType', 'foo')])
  170. except ldap.LDAPError, e:
  171. log.info('Operation failed as expected (error: %s)' % e.message['desc'])
  172. else:
  173. log.error('Operation incorectly succeeded! Test Failed!')
  174. assert False
  175. topology.standalone.log.info('Test 47937 Passed.')
  176. def test_ticket47937_final(topology):
  177. topology.standalone.delete()
  178. def run_isolated():
  179. '''
  180. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  181. To run isolated without py.test, you need to
  182. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  183. - set the installation prefix
  184. - run this program
  185. '''
  186. global installation_prefix
  187. installation_prefix = None
  188. topo = topology(True)
  189. test_ticket47937(topo)
  190. test_ticket47937_final(topo)
  191. if __name__ == '__main__':
  192. run_isolated()