Blame SOURCES/0052-Ticket-47451-Add-Dynamic-Plugin-CI-Suite.patch

f92ce9
From c038b581bdcabcc86a33f9a3eae446b684825698 Mon Sep 17 00:00:00 2001
f92ce9
From: Mark Reynolds <mreynolds@redhat.com>
f92ce9
Date: Tue, 16 Dec 2014 16:44:33 -0500
f92ce9
Subject: [PATCH 52/53] Ticket 47451 - Add Dynamic Plugin CI Suite
f92ce9
f92ce9
Description:  Add lib389(CI) testsuite for Dynamic Plugins
f92ce9
f92ce9
              Perform functional tests for plugins that have configuration settings
f92ce9
                  - Restart the plugin
f92ce9
                  - Make condfig change
f92ce9
                  - Test the plugin
f92ce9
                  - Make another config change
f92ce9
                  - Test plugin
f92ce9
                  - Test plugin dependency
f92ce9
                  - Cleanup
f92ce9
f92ce9
              Perform memory corruption test
f92ce9
                  - This test forces the global plugin linked list, DSE callbacks,
f92ce9
                    and task handlers to be rewritten in various orders while
f92ce9
                    testing all the plugins.
f92ce9
f92ce9
              Perform Stress tests
f92ce9
                  - Perform a series of operations that engage two plugins.  While
f92ce9
                    there operations are being performed restart various plugins.
f92ce9
                  - Verify the server does not crash, and that hte plugins work
f92ce9
                    correctly.
f92ce9
f92ce9
https://fedorahosted.org/389/ticket/47451
f92ce9
f92ce9
Reviewed by: nhosoi(Thanks!)
f92ce9
f92ce9
(cherry picked from commit 4e39dbbfde56ca68f5a26d0bf2ac3a261234c8cd)
f92ce9
(cherry picked from commit 2ace01377aec2872579f9f892361946f1d5b07d2)
f92ce9
---
f92ce9
 dirsrvtests/suites/dynamic-plugins/constants.py    |   33 +
f92ce9
 dirsrvtests/suites/dynamic-plugins/finalizer.py    |   57 +
f92ce9
 dirsrvtests/suites/dynamic-plugins/plugin_tests.py | 1973 ++++++++++++++++++++
f92ce9
 dirsrvtests/suites/dynamic-plugins/stress_tests.py |  133 ++
f92ce9
 .../suites/dynamic-plugins/test_dynamic_plugins.py |  315 ++++
f92ce9
 5 files changed, 2511 insertions(+)
f92ce9
 create mode 100644 dirsrvtests/suites/dynamic-plugins/constants.py
f92ce9
 create mode 100644 dirsrvtests/suites/dynamic-plugins/finalizer.py
f92ce9
 create mode 100644 dirsrvtests/suites/dynamic-plugins/plugin_tests.py
f92ce9
 create mode 100644 dirsrvtests/suites/dynamic-plugins/stress_tests.py
f92ce9
 create mode 100644 dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py
f92ce9
f92ce9
diff --git a/dirsrvtests/suites/dynamic-plugins/constants.py b/dirsrvtests/suites/dynamic-plugins/constants.py
f92ce9
new file mode 100644
f92ce9
index 0000000..cbc310e
f92ce9
--- /dev/null
f92ce9
+++ b/dirsrvtests/suites/dynamic-plugins/constants.py
f92ce9
@@ -0,0 +1,33 @@
f92ce9
+'''
f92ce9
+Created on Dec 09, 2014
f92ce9
+
f92ce9
+@author: mreynolds
f92ce9
+'''
f92ce9
+import os
f92ce9
+from lib389 import DN_DM
f92ce9
+from lib389._constants import *
f92ce9
+from lib389.properties import *
f92ce9
+
f92ce9
+SUFFIX    = 'dc=example,dc=com'
f92ce9
+PASSWORD  = 'password'
f92ce9
+
f92ce9
+# Used for standalone topology
f92ce9
+HOST_STANDALONE = LOCALHOST
f92ce9
+PORT_STANDALONE = 33389
f92ce9
+SERVERID_STANDALONE = 'dynamic-plugins'
f92ce9
+
f92ce9
+# Each defined instance above must be added in that list 
f92ce9
+ALL_INSTANCES = [ {SER_HOST: HOST_STANDALONE, SER_PORT: PORT_STANDALONE, SER_SERVERID_PROP: SERVERID_STANDALONE},
f92ce9
+                  ]
f92ce9
+# This is a template
f92ce9
+args_instance = {
f92ce9
+                   SER_DEPLOYED_DIR: os.environ.get('PREFIX', None),
f92ce9
+                   SER_BACKUP_INST_DIR: os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR),
f92ce9
+                   SER_ROOT_DN: DN_DM,
f92ce9
+                   SER_ROOT_PW: PASSWORD,
f92ce9
+                   SER_HOST: LOCALHOST,
f92ce9
+                   SER_PORT: DEFAULT_PORT,
f92ce9
+                   SER_SERVERID_PROP: "template",
f92ce9
+                   SER_CREATION_SUFFIX: DEFAULT_SUFFIX}
f92ce9
+
f92ce9
+
f92ce9
diff --git a/dirsrvtests/suites/dynamic-plugins/finalizer.py b/dirsrvtests/suites/dynamic-plugins/finalizer.py
f92ce9
new file mode 100644
f92ce9
index 0000000..eb02332
f92ce9
--- /dev/null
f92ce9
+++ b/dirsrvtests/suites/dynamic-plugins/finalizer.py
f92ce9
@@ -0,0 +1,57 @@
f92ce9
+'''
f92ce9
+Created on Nov 5, 2013
f92ce9
+
f92ce9
+@author: tbordaz
f92ce9
+'''
f92ce9
+import os
f92ce9
+import sys
f92ce9
+import time
f92ce9
+import ldap
f92ce9
+import logging
f92ce9
+import socket
f92ce9
+import time
f92ce9
+import logging
f92ce9
+import pytest
f92ce9
+from lib389 import DirSrv, Entry, tools
f92ce9
+from lib389.tools import DirSrvTools
f92ce9
+from lib389._constants import DN_DM
f92ce9
+from lib389.properties import *
f92ce9
+from constants import *
f92ce9
+
f92ce9
+log = logging.getLogger(__name__)
f92ce9
+
f92ce9
+global installation_prefix
f92ce9
+installation_prefix=os.getenv('PREFIX')
f92ce9
+
f92ce9
+def test_finalizer():
f92ce9
+    global installation_prefix
f92ce9
+    
f92ce9
+    # for each defined instance, remove it
f92ce9
+    for args_instance in ALL_INSTANCES:
f92ce9
+        if installation_prefix:
f92ce9
+            # overwrite the environment setting
f92ce9
+            args_instance[SER_DEPLOYED_DIR] = installation_prefix
f92ce9
+            
f92ce9
+        instance = DirSrv(verbose=True)
f92ce9
+        instance.allocate(args_instance)
f92ce9
+        if instance.exists():
f92ce9
+            instance.delete()
f92ce9
+            
f92ce9
+        # remove any existing backup for this instance
f92ce9
+        instance.clearBackupFS()
f92ce9
+        
f92ce9
+def run_isolated():
f92ce9
+    '''
f92ce9
+        run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
f92ce9
+        To run isolated without py.test, you need to 
f92ce9
+            - set the installation prefix
f92ce9
+            - run this program
f92ce9
+    '''
f92ce9
+    global installation_prefix
f92ce9
+    installation_prefix =  None
f92ce9
+        
f92ce9
+    test_finalizer()
f92ce9
+
f92ce9
+if __name__ == '__main__':
f92ce9
+    run_isolated()
f92ce9
+
f92ce9
diff --git a/dirsrvtests/suites/dynamic-plugins/plugin_tests.py b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
f92ce9
new file mode 100644
f92ce9
index 0000000..fa88145
f92ce9
--- /dev/null
f92ce9
+++ b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
f92ce9
@@ -0,0 +1,1973 @@
f92ce9
+'''
f92ce9
+Created on Dec 09, 2014
f92ce9
+
f92ce9
+@author: mreynolds
f92ce9
+'''
f92ce9
+import os
f92ce9
+import sys
f92ce9
+import time
f92ce9
+import ldap
f92ce9
+import time
f92ce9
+import logging
f92ce9
+import socket
f92ce9
+import pytest
f92ce9
+from lib389 import DirSrv, Entry, tools, tasks
f92ce9
+from lib389.tools import DirSrvTools
f92ce9
+from lib389._constants import *
f92ce9
+from lib389.properties import *
f92ce9
+from lib389.tasks import *
f92ce9
+from constants import *
f92ce9
+
f92ce9
+log = logging.getLogger(__name__)
f92ce9
+
f92ce9
+USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
f92ce9
+USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
f92ce9
+USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX
f92ce9
+BUSER1_DN = 'uid=user1,ou=branch1,' + DEFAULT_SUFFIX
f92ce9
+BUSER2_DN = 'uid=user2,ou=branch2,' + DEFAULT_SUFFIX
f92ce9
+BUSER3_DN = 'uid=user3,ou=branch2,' + DEFAULT_SUFFIX
f92ce9
+BRANCH1_DN = 'ou=branch1,' + DEFAULT_SUFFIX
f92ce9
+BRANCH2_DN = 'ou=branch2,' + DEFAULT_SUFFIX
f92ce9
+GROUP_OU = 'ou=groups,' + DEFAULT_SUFFIX
f92ce9
+PEOPLE_OU = 'ou=people,' + DEFAULT_SUFFIX
f92ce9
+GROUP_DN = 'cn=group,' + DEFAULT_SUFFIX
f92ce9
+
f92ce9
+'''
f92ce9
+   Functional tests for each plugin
f92ce9
+
f92ce9
+   Test:
f92ce9
+         plugin restarts (test when on and off)
f92ce9
+         plugin config validation
f92ce9
+         plugin dependencies
f92ce9
+         plugin functionality (including plugin tasks)
f92ce9
+'''
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Plugin Dependency
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_dependency(inst, plugin):
f92ce9
+    """
f92ce9
+    Set the "account usabilty" plugin to depend on this plugin.  This plugin
f92ce9
+    is generic, always enabled, and perfect for our testing
f92ce9
+    """
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',
f92ce9
+                      [(ldap.MOD_REPLACE, 'nsslapd-plugin-depends-on-named', plugin)])
f92ce9
+
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_dependency: Failed to modify ' + PLUGIN_ACCT_USABILITY + ': error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s('cn=' + plugin + ',cn=plugins,cn=config',
f92ce9
+                      [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'off')])
f92ce9
+
f92ce9
+    except ldap.UNWILLING_TO_PERFORM:
f92ce9
+        # failed as expected
f92ce9
+        pass
f92ce9
+    else:
f92ce9
+        # Incorrectly succeeded
f92ce9
+        log.error('test_dependency: Plugin dependency check failed (%s)' % plugin)
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Now undo the change
f92ce9
+    try:
f92ce9
+        inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',
f92ce9
+                      [(ldap.MOD_DELETE, 'nsslapd-plugin-depends-on-named', None)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_dependency: Failed to reset ' + plugin + ': error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Account Policy Plugin (0)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_acctpolicy(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
f92ce9
+    inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return True
f92ce9
+
f92ce9
+    CONFIG_DN = 'cn=config,cn=Account Policy Plugin,cn=plugins,cn=config'
f92ce9
+    log.info('Testing ' + PLUGIN_ACCT_POLICY + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add the config entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((CONFIG_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'cn': 'config',
f92ce9
+                          'alwaysrecordlogin': 'yes',
f92ce9
+                          'stateattrname': 'lastLoginTime'
f92ce9
+                          })))
f92ce9
+    except ldap.ALREADY_EXISTS:
f92ce9
+        try:
f92ce9
+            inst.modify_s(CONFIG_DN,
f92ce9
+                      [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'),
f92ce9
+                       (ldap.MOD_REPLACE, 'stateattrname', 'lastLoginTime')])
f92ce9
+        except ldap.LDAPError, e:
f92ce9
+            log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy: Failed to add config entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Now set the config entry in the plugin entry
f92ce9
+    #try:
f92ce9
+    #    inst.modify_s('cn=' + PLUGIN_ACCT_POLICY + ',cn=plugins,cn=config',
f92ce9
+    #                  [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', CONFIG_DN)])
f92ce9
+    #except ldap.LDAPError, e:
f92ce9
+    #    log.error('test_acctpolicy: Failed to set config entry in plugin entry: error ' + e.message['desc'])
f92ce9
+    #    assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # !!!! acctpolicy does have have a dse callabck to check for live updates - restart plugin for now !!!!
f92ce9
+    inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
f92ce9
+    inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
f92ce9
+
f92ce9
+    # Add an entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),
f92ce9
+                                 'sn': '1',
f92ce9
+                                 'cn': 'user 1',
f92ce9
+                                 'uid': 'user1',
f92ce9
+                                 'userpassword': 'password'})))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # bind as user
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(USER1_DN, "password")
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy:Failed to bind as user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Bind as Root DN
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(DN_DM, PASSWORD)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check lastLoginTime of USER1
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'lastLoginTime=*')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_acctpolicy: Search failed to find an entry with lastLoginTime.')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change config - change the stateAttrName to a new attribute
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'stateattrname', 'testLastLoginTime')])
f92ce9
+
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # !!!! must restart for now !!!!!
f92ce9
+    inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
f92ce9
+    inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # login as user
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(USER1_DN, "password")
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy: Failed to bind(2nd) as user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Bind as Root DN
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(DN_DM, PASSWORD)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check testLastLoginTime was added to USER1
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(testLastLoginTime=*)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_acctpolicy: Search failed to find an entry with testLastLoginTime.')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_ACCT_POLICY)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_acctpolicy: Failed to delete test entry: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_acctpolicy: PASS\n')
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Attribute Uniqueness Plugin (1)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_attruniq(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_ATTR_UNIQUENESS)
f92ce9
+    inst.plugins.enable(name=PLUGIN_ATTR_UNIQUENESS)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_ATTR_UNIQUENESS + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',
f92ce9
+                      [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'uid')])
f92ce9
+
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_attruniq: Failed to configure plugin for "uid": error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add an entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),
f92ce9
+                                     'sn': '1',
f92ce9
+                                     'cn': 'user 1',
f92ce9
+                                     'uid': 'user1',
f92ce9
+                                     'mail': 'user1@example.com',
f92ce9
+                                     'userpassword': 'password'})))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_attruniq: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add an entry with a duplicate "uid"
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
f92ce9
+                                     'sn': '2',
f92ce9
+                                     'cn': 'user 2',
f92ce9
+                                     'uid': 'user2',
f92ce9
+                                     'uid': 'user1',
f92ce9
+                                     'userpassword': 'password'})))
f92ce9
+
f92ce9
+    except ldap.CONSTRAINT_VIOLATION:
f92ce9
+        pass
f92ce9
+    else:
f92ce9
+        log.error('test_attruniq: Adding of 2nd entry(uid) incorrectly succeeded')
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change config to use "mail" instead of "uid"
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',
f92ce9
+                      [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'mail')])
f92ce9
+
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_attruniq: Failed to configure plugin for "mail": error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin - Add an entry, that has a duplicate "mail" value
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
f92ce9
+                                 'sn': '2',
f92ce9
+                                 'cn': 'user 2',
f92ce9
+                                 'uid': 'user2',
f92ce9
+                                 'mail': 'user1@example.com',
f92ce9
+                                 'userpassword': 'password'})))
f92ce9
+    except ldap.CONSTRAINT_VIOLATION:
f92ce9
+        pass
f92ce9
+    else:
f92ce9
+        log.error('test_attruniq: Adding of 2nd entry(mail) incorrectly succeeded')
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_ATTR_UNIQUENESS)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_attruniq: Failed to delete test entry: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_attruniq: PASS\n')
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Auto Membership Plugin (2)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_automember(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_AUTOMEMBER)
f92ce9
+    inst.plugins.enable(name=PLUGIN_AUTOMEMBER)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    CONFIG_DN = 'cn=config,cn=' + PLUGIN_AUTOMEMBER + ',cn=plugins,cn=config'
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_AUTOMEMBER + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add the automember group
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((GROUP_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'cn': 'group'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to add group: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add ou=branch1
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((BRANCH1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'ou': 'branch1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to add branch1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add ou=branch2
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((BRANCH2_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'ou': 'branch2'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to add branch2: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add the automember config entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((CONFIG_DN, {
f92ce9
+                          'objectclass': 'top autoMemberDefinition'.split(),
f92ce9
+                          'cn': 'config',
f92ce9
+                          'autoMemberScope': 'ou=branch1,' + DEFAULT_SUFFIX,
f92ce9
+                          'autoMemberFilter': 'objectclass=top',
f92ce9
+                          'autoMemberDefaultGroup': 'cn=group,' + DEFAULT_SUFFIX,
f92ce9
+                          'autoMemberGroupingAttr': 'member:dn'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to add config entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test the plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add a user that should get added to the group
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((BUSER1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to add user: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check the group
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
f92ce9
+                                '(member=' + BUSER1_DN + ')')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_automember: Search failed to find member user1')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_automember: Search failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change config
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(CONFIG_DN,
f92ce9
+                      [(ldap.MOD_REPLACE, 'autoMemberGroupingAttr', 'uniquemember:dn'),
f92ce9
+                       (ldap.MOD_REPLACE, 'autoMemberScope', 'ou=branch2,' + DEFAULT_SUFFIX)])
f92ce9
+
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to modify config entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add a user that should get added to the group
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((BUSER2_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user2'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to user to branch2: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check the group
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
f92ce9
+                                '(uniquemember=' + BUSER2_DN + ')')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_automember: Search failed to find uniquemember user2')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_automember: Search failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test Task
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Disable plugin
f92ce9
+    inst.plugins.disable(name=PLUGIN_AUTOMEMBER)
f92ce9
+
f92ce9
+    # Add an entry that should be picked up by automember - verify it is not(yet)
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((BUSER3_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user3'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to user3 to branch2: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check the group - uniquemember sahould not exist
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
f92ce9
+                                '(uniquemember=' + BUSER3_DN + ')')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_automember: user3 was incorrectly added to the group')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_automember: Search failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Enable plugin
f92ce9
+    inst.plugins.enable(name=PLUGIN_AUTOMEMBER)
f92ce9
+
f92ce9
+    # Add the task
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=automember rebuild membership,cn=tasks,cn=config', {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'basedn': 'ou=branch2,' + DEFAULT_SUFFIX,
f92ce9
+                          'filter': 'objectclass=top'})))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to add task: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    time.sleep(3)  # Wait for the task to do its work
f92ce9
+
f92ce9
+    # Verify the fixup task worked
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
f92ce9
+                                '(uniquemember=' + BUSER3_DN + ')')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_automember: user3 was not added to the group')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_automember: Search failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_AUTOMEMBER)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(BUSER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete test entry1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(BUSER2_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete test entry2: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(BUSER3_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete test entry3: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(BRANCH1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete branch1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(BRANCH2_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete test branch2: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(GROUP_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete test group: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(CONFIG_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete plugin config entry: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_automember: PASS\n')
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test DNA Plugin (3)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_dna(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_DNA)
f92ce9
+    inst.plugins.enable(name=PLUGIN_DNA)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    CONFIG_DN = 'cn=config,cn=' + PLUGIN_DNA + ',cn=plugins,cn=config'
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_DNA + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((CONFIG_DN, {
f92ce9
+                          'objectclass': 'top dnaPluginConfig'.split(),
f92ce9
+                          'cn': 'config',
f92ce9
+                          'dnatype': 'uidNumber',
f92ce9
+                          'dnafilter': '(objectclass=top)',
f92ce9
+                          'dnascope': DEFAULT_SUFFIX,
f92ce9
+                          'dnaMagicRegen': '-1',
f92ce9
+                          'dnaMaxValue': '50000',
f92ce9
+                          'dnaNextValue': '1'
f92ce9
+                          })))
f92ce9
+    except ldap.ALREADY_EXISTS:
f92ce9
+        try:
f92ce9
+            inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaNextValue', '1'),
f92ce9
+                                      (ldap.MOD_REPLACE, 'dnaMagicRegen', '-1')])
f92ce9
+        except ldap.LDAPError, e:
f92ce9
+            log.error('test_dna: Failed to set the DNA plugin: error ' + e.message['desc'])
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_dna: Failed to add config entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_dna: Failed to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if the entry now has the new uidNumber assignment - uidNumber=1
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=1)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_dna: user1 was not updated - (looking for uidNumber: 1)')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Test the magic regen value
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-1')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if the entry now has the new uidNumber assignment - uidNumber=2
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=2)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_dna: user1 was not updated (looking for uidNumber: 2)')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ################################################################################
f92ce9
+    # Change the config
f92ce9
+    ################################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaMagicRegen', '-2')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_dna: Failed to set the magic reg value to -2: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ################################################################################
f92ce9
+    # Test plugin
f92ce9
+    ################################################################################
f92ce9
+
f92ce9
+    # Test the magic regen value
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-2')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if the entry now has the new uidNumber assignment - uidNumber=3
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=3)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_dna: user1 was not updated (looking for uidNumber: 3)')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_AUTOMEMBER)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_automember: Failed to delete test entry1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    inst.plugins.disable(name=PLUGIN_DNA)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_dna: PASS\n')
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Linked Attrs Plugin (4)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_linkedattrs(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+    inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    CONFIG_DN = 'cn=config,cn=' + PLUGIN_LINKED_ATTRS + ',cn=plugins,cn=config'
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_LINKED_ATTRS + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add test entries
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER2_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user2'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add the linked attrs config entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((CONFIG_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'cn': 'config',
f92ce9
+                          'linkType': 'directReport',
f92ce9
+                          'managedType': 'manager'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to add config entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Set "directReport" should add "manager" to the other entry
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if manager was added to the other entry
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_linkedattrs: user2 missing "manager" attribute')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Remove "directReport" should remove "manager" to the other entry
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'directReport', None)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if manager was removed
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_linkedattrs: user2 "manager" attribute not removed')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change the config - using linkType "indirectReport" now
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'linkType', 'indirectReport')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to set linkTypee: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Make sure the old linkType(directManager) is not working
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if manager was added to the other entry, better not be...
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_linkedattrs: user2 had "manager" added unexpectedly')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Now, set the new linkType "indirectReport", which should add "manager" to the other entry
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if manager was added to the other entry, better not be
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_linkedattrs: user2 missing "manager"')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Remove "indirectReport" should remove "manager" to the other entry
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'indirectReport', None)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # See if manager was removed
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_linkedattrs: user2 "manager" attribute not removed')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test Fixup Task
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Disable plugin and make some updates that would of triggered the plugin
f92ce9
+    inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # The entry should not have a manager attribute
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Verify that the task does not work yet(not until we enable the plugin)
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'basedn': DEFAULT_SUFFIX,
f92ce9
+                          'filter': '(objectclass=top)'})))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    time.sleep(3)  # Wait for the task to do, or not do, its work
f92ce9
+
f92ce9
+    # The entry should still not have a manager attribute
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Enable the plugin and rerun the task entry
f92ce9
+    inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+
f92ce9
+    # Add the task again
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'basedn': DEFAULT_SUFFIX,
f92ce9
+                          'filter': 'objectclass=top'})))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    time.sleep(3)  # Wait for the task to do its work
f92ce9
+
f92ce9
+    # Check if user2 now has a manager attribute now
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_linkedattrs: task failed: user2 missing "manager" attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_LINKED_ATTRS)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to delete test entry1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER2_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to delete test entry2: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(CONFIG_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_linkedattrs: Failed to delete plugin config entry: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_linkedattrs: PASS\n')
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test MemberOf Plugin (5)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_memberof(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_MEMBER_OF)
f92ce9
+    inst.plugins.enable(name=PLUGIN_MEMBER_OF)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_MEMBER_OF + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'member')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to update config(member): error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add our test entries
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to add user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((GROUP_DN, {
f92ce9
+                          'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),
f92ce9
+                          'cn': 'group',
f92ce9
+                          'member': USER1_DN
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to add group: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check if the user now has a "memberOf" attribute
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_memberof: user1 missing memberOf')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Remove "member" should remove "memberOf" from the entry
f92ce9
+    try:
f92ce9
+        inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'member', None)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to delete member: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check that "memberOf" was removed
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_memberof: user1 incorrect has memberOf attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change the config
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to update config(uniquemember): error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check if the user now has a "memberOf" attribute
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_memberof: user1 missing memberOf')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Remove "uniquemember" should remove "memberOf" from the entry
f92ce9
+    try:
f92ce9
+        inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'uniquemember', None)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to delete member: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check that "memberOf" was removed
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_memberof: user1 incorrect has memberOf attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test Fixup Task
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    inst.plugins.disable(name=PLUGIN_MEMBER_OF)
f92ce9
+
f92ce9
+    # Add uniquemember, should not update USER1
f92ce9
+    try:
f92ce9
+        inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check for "memberOf"
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_memberof: user1 incorrect has memberOf attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Run fixup task while plugin disabled - should not add "memberOf
f92ce9
+    # Verify that the task does not work yet(not until we enable the plugin)
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'basedn': DEFAULT_SUFFIX,
f92ce9
+                          'filter': 'objectclass=top'})))
f92ce9
+    except ldap.NO_SUCH_OBJECT:
f92ce9
+        pass
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to add task: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    time.sleep(3)  # Wait for the task to do, or not do, its work
f92ce9
+
f92ce9
+    # Check for "memberOf"
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
f92ce9
+        if entries:
f92ce9
+            log.fatal('test_memberof: user1 incorrectly has memberOf attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Enable the plugin, and run the task
f92ce9
+    inst.plugins.enable(name=PLUGIN_MEMBER_OF)
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'basedn': DEFAULT_SUFFIX,
f92ce9
+                          'filter': 'objectclass=top'})))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to add task: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    time.sleep(3)  # Wait for the task to do its work
f92ce9
+
f92ce9
+    # Check for "memberOf"
f92ce9
+    try:
f92ce9
+        entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
f92ce9
+        if not entries:
f92ce9
+            log.fatal('test_memberof: user1 missing memberOf attr')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_MEMBER_OF)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to delete test entry1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(GROUP_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_memberof: Failed to delete test group: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_memberof: PASS\n')
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Managed Entry Plugin (6)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_mep(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)
f92ce9
+    inst.plugins.enable(name=PLUGIN_MANAGED_ENTRY)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    USER_DN = 'uid=user1,ou=people,' + DEFAULT_SUFFIX
f92ce9
+    MEP_USER_DN = 'cn=user1,ou=groups,' + DEFAULT_SUFFIX
f92ce9
+    USER_DN2 = 'uid=user 1,ou=people,' + DEFAULT_SUFFIX
f92ce9
+    MEP_USER_DN2 = 'uid=user 1,ou=groups,' + DEFAULT_SUFFIX
f92ce9
+    CONFIG_DN = 'cn=config,cn=' + PLUGIN_MANAGED_ENTRY + ',cn=plugins,cn=config'
f92ce9
+    TEMPLATE_DN = 'cn=MEP Template,' + DEFAULT_SUFFIX
f92ce9
+    TEMPLATE_DN2 = 'cn=MEP Template2,' + DEFAULT_SUFFIX
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_MANAGED_ENTRY + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add our org units
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((PEOPLE_OU, {
f92ce9
+                   'objectclass': 'top extensibleObject'.split(),
f92ce9
+                   'ou': 'people'})))
f92ce9
+    except ldap.ALREADY_EXISTS:
f92ce9
+        pass
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to add people org unit: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((GROUP_OU, {
f92ce9
+                   'objectclass': 'top extensibleObject'.split(),
f92ce9
+                   'ou': 'people'})))
f92ce9
+    except ldap.ALREADY_EXISTS:
f92ce9
+        pass
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to add people org unit: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add the template entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((TEMPLATE_DN, {
f92ce9
+                   'objectclass': 'top mepTemplateEntry extensibleObject'.split(),
f92ce9
+                   'cn': 'MEP Template',
f92ce9
+                   'mepRDNAttr': 'cn',
f92ce9
+                   'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),
f92ce9
+                   'mepMappedAttr': 'cn: $cn|uid: $cn|gidNumber: $uidNumber'.split('|')
f92ce9
+                   })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to add template entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+   # log.info('geb.....')
f92ce9
+  #  time.sleep(30)
f92ce9
+
f92ce9
+    # Add the config entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((CONFIG_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'cn': 'config',
f92ce9
+                          'originScope': PEOPLE_OU,
f92ce9
+                          'originFilter': 'objectclass=posixAccount',
f92ce9
+                          'managedBase': GROUP_OU,
f92ce9
+                          'managedTemplate': TEMPLATE_DN
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to add config entry: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add an entry that meets the MEP scope
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER_DN, {
f92ce9
+                          'objectclass': 'top posixAccount extensibleObject'.split(),
f92ce9
+                          'uid': 'user1',
f92ce9
+                          'cn': 'user1',
f92ce9
+                          'uidNumber': '1',
f92ce9
+                          'gidNumber': '1',
f92ce9
+                          'homeDirectory': '/home/user1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check if a managed group entry was created
f92ce9
+    try:
f92ce9
+        inst.search_s(MEP_USER_DN, ldap.SCOPE_BASE, '(objectclass=top)')
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_mep: Unable to find MEP entry: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change the config
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add a new template entry
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((TEMPLATE_DN2, {
f92ce9
+                   'objectclass': 'top mepTemplateEntry extensibleObject'.split(),
f92ce9
+                   'cn': 'MEP Template2',
f92ce9
+                   'mepRDNAttr': 'uid',
f92ce9
+                   'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),
f92ce9
+                   'mepMappedAttr': 'cn: $uid|uid: $cn|gidNumber: $gidNumber'.split('|')
f92ce9
+                   })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to add template entry2: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Set the new template dn
f92ce9
+    try:
f92ce9
+        inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'managedTemplate', TEMPLATE_DN2)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to set mep plugin config: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add an entry that meets the MEP scope
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER_DN2, {
f92ce9
+                          'objectclass': 'top posixAccount extensibleObject'.split(),
f92ce9
+                          'uid': 'user 1',
f92ce9
+                          'cn': 'user 1',
f92ce9
+                          'uidNumber': '1',
f92ce9
+                          'gidNumber': '1',
f92ce9
+                          'homeDirectory': '/home/user2'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to user2: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check if a managed group entry was created
f92ce9
+    try:
f92ce9
+        inst.search_s(MEP_USER_DN2, ldap.SCOPE_BASE, '(objectclass=top)')
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_mep: Unable to find MEP entry2: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_MANAGED_ENTRY)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to delete test user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER_DN2)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to delete test user 2: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(TEMPLATE_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to delete template1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(TEMPLATE_DN2)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to delete template2: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(CONFIG_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_mep: Failed to delete config: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_mep: PASS\n')
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Passthru Plugin (7)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_passthru(inst, args=None):
f92ce9
+    # Passthru is a bit picky about the state of the entry - we can't just restart it
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    # stop the plugin
f92ce9
+    inst.plugins.disable(name=PLUGIN_PASSTHRU)
f92ce9
+
f92ce9
+    PLUGIN_DN = 'cn=' + PLUGIN_PASSTHRU + ',cn=plugins,cn=config'
f92ce9
+    PASSTHRU_DN = 'uid=admin,dc=pass,dc=thru'
f92ce9
+    PASSTHRU_DN2 = 'uid=admin2,dc=pass2,dc=thru'
f92ce9
+    PASS_SUFFIX1 = 'dc=pass,dc=thru'
f92ce9
+    PASS_SUFFIX2 = 'dc=pass2,dc=thru'
f92ce9
+    PASS_BE2 = 'PASS2'
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_PASSTHRU + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Add a new "remote" instance, and a user for auth
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Create second instance
f92ce9
+    passthru_inst = DirSrv(verbose=False)
f92ce9
+
f92ce9
+    #if installation1_prefix:
f92ce9
+    #    args_instance[SER_DEPLOYED_DIR] = installation1_prefix
f92ce9
+
f92ce9
+    # Args for the master1 instance
f92ce9
+    """
f92ce9
+    args_instance[SER_HOST] = '127.0.0.1'
f92ce9
+    args_instance[SER_PORT] = '33333'
f92ce9
+    args_instance[SER_SERVERID_PROP] = 'passthru'
f92ce9
+    """
f92ce9
+    args_instance[SER_HOST] = 'localhost.localdomain'
f92ce9
+    args_instance[SER_PORT] = 33333
f92ce9
+    args_instance[SER_SERVERID_PROP] = 'passthru'
f92ce9
+
f92ce9
+    args_instance[SER_CREATION_SUFFIX] = PASS_SUFFIX1
f92ce9
+    args_passthru_inst = args_instance.copy()
f92ce9
+    passthru_inst.allocate(args_passthru_inst)
f92ce9
+    passthru_inst.create()
f92ce9
+    passthru_inst.open()
f92ce9
+
f92ce9
+    # Create a second backend
f92ce9
+    passthru_inst.backend.create(PASS_SUFFIX2, {BACKEND_NAME: PASS_BE2})
f92ce9
+    passthru_inst.mappingtree.create(PASS_SUFFIX2, bename=PASS_BE2)
f92ce9
+
f92ce9
+    # Create the top of the tree
f92ce9
+    try:
f92ce9
+        passthru_inst.add_s(Entry((PASS_SUFFIX2, {
f92ce9
+                          'objectclass': 'top domain'.split(),
f92ce9
+                          'dc': 'pass2'})))
f92ce9
+    except ldap.ALREADY_EXISTS:
f92ce9
+        pass
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: Failed to create suffix entry: error ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add user to suffix1
f92ce9
+    try:
f92ce9
+        passthru_inst.add_s(Entry((PASSTHRU_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'admin',
f92ce9
+                          'userpassword': 'password'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: Failed to admin1: error ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Add user to suffix 2
f92ce9
+    try:
f92ce9
+        passthru_inst.add_s(Entry((PASSTHRU_DN2, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'admin2',
f92ce9
+                          'userpassword': 'password'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: Failed to admin2 : error ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure and start plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'on'),
f92ce9
+                                  (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass,dc=thru')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # login as user
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(PASSTHRU_DN, "password")
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change the config
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # login as root DN
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(DN_DM, PASSWORD)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass2,dc=thru')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # login as user
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(PASSTHRU_DN2, "password")
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # login as root DN
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(DN_DM, PASSWORD)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
f92ce9
+        passthru_inst.delete()
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_PASSTHRU)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # remove the passthru instance
f92ce9
+    passthru_inst.delete()
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_passthru: PASS\n')
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Referential Integrity Plugin (8)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_referint(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
f92ce9
+    inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_REFER_INTEGRITY + '...')
f92ce9
+    PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'member')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add some users and a group
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to add user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER2_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user2'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to add user2: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((GROUP_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'cn': 'group',
f92ce9
+                          'member': USER1_DN,
f92ce9
+                          'uniquemember': USER2_DN
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to add group: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Delete a user
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check for integrity
f92ce9
+    try:
f92ce9
+        entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(member=' + USER1_DN + ')')
f92ce9
+        if entry:
f92ce9
+            log.error('test_referint: user1 was not removed from group')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_referint: Unable to search group: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change the config
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Delete a user
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER2_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check for integrity
f92ce9
+    try:
f92ce9
+        entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(uniquemember=' + USER2_DN + ')')
f92ce9
+        if entry:
f92ce9
+            log.error('test_referint: user2 was not removed from group')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_referint: Unable to search group: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_REFER_INTEGRITY)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(GROUP_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_referint: PASS\n')
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Retro Changelog Plugin (9)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_retrocl(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
f92ce9
+    inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    log.info('Testing ' + PLUGIN_RETRO_CHANGELOG + '...')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Gather the current change count (it's not 1 once we start the stabilty tests)
f92ce9
+    try:
f92ce9
+        entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_retrocl: Failed to get the count: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    entry_count = len(entry)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add a user
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user1'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_retrocl: Failed to add user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check we logged this in the retro cl
f92ce9
+    try:
f92ce9
+        entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
f92ce9
+        if not entry or len(entry) == entry_count:
f92ce9
+            log.error('test_retrocl: changelog not updated')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_retrocl: Unable to search group: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    entry_count += 1
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change the config - disable plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_retrocl: Failed to delete user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Check we didn't logged this in the retro cl
f92ce9
+    try:
f92ce9
+        entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
f92ce9
+        if len(entry) != entry_count:
f92ce9
+            log.error('test_retrocl: changelog incorrectly updated - change count: '
f92ce9
+                + str(len(entry)) + ' - expected 1')
f92ce9
+            assert False
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.fatal('test_retrocl: Unable to search retro changelog: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
f92ce9
+    test_dependency(inst, PLUGIN_RETRO_CHANGELOG)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # None
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_retrocl: PASS\n')
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+################################################################################
f92ce9
+#
f92ce9
+# Test Root DN Access Control Plugin (10)
f92ce9
+#
f92ce9
+################################################################################
f92ce9
+def test_rootdn(inst, args=None):
f92ce9
+    # stop the plugin, and start it
f92ce9
+    inst.plugins.disable(name=PLUGIN_ROOTDN_ACCESS)
f92ce9
+    inst.plugins.enable(name=PLUGIN_ROOTDN_ACCESS)
f92ce9
+
f92ce9
+    if args == "restart":
f92ce9
+        return
f92ce9
+
f92ce9
+    PLUGIN_DN = 'cn=' + PLUGIN_ROOTDN_ACCESS + ',cn=plugins,cn=config'
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Configure plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Add an user and aci to open up cn=config
f92ce9
+    try:
f92ce9
+        inst.add_s(Entry((USER1_DN, {
f92ce9
+                          'objectclass': 'top extensibleObject'.split(),
f92ce9
+                          'uid': 'user1',
f92ce9
+                          'userpassword': 'password'
f92ce9
+                          })))
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_retrocl: Failed to add user1: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Set an aci so we can modify the plugin after ew deny the root dn
f92ce9
+    ACI = '(target ="ldap:///cn=config")(targetattr = "*")(version 3.0;acl "all access";allow (all)(userdn="ldap:///anyone");)'
f92ce9
+    try:
f92ce9
+        inst.modify_s(DN_CONFIG, [(ldap.MOD_ADD, 'aci', ACI)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Set allowed IP to an unknown host - blocks root dn
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'rootdn-allow-ip', '10.10.10.10')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Bind as Root DN
f92ce9
+    failed = False
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(DN_DM, PASSWORD)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        failed = True
f92ce9
+
f92ce9
+    if not failed:
f92ce9
+        log.error('test_rootdn: Root DN was incorrectly able to bind')
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Change the config
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(USER1_DN, 'password')
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_rootdn: failed to bind as user1')
f92ce9
+        assert False
f92ce9
+
f92ce9
+    # Remove the restriction
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_DELETE, 'rootdn-allow-ip', None)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # Bind as Root DN
f92ce9
+    failed = False
f92ce9
+    try:
f92ce9
+        inst.simple_bind_s(DN_DM, PASSWORD)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        failed = True
f92ce9
+
f92ce9
+    if failed:
f92ce9
+        log.error('test_rootdn: Root DN was not able to bind')
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test plugin dependency
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    test_dependency(inst, PLUGIN_ROOTDN_ACCESS)
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Cleanup - remove ACI from cn=config and test user
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.modify_s(DN_CONFIG, [(ldap.MOD_DELETE, 'aci', ACI)])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    try:
f92ce9
+        inst.delete_s(USER1_DN)
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('test_rootdn: Failed to delete user1: ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test passed
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('test_rootdn: PASS\n')
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
+
f92ce9
+# Array of test functions
f92ce9
+func_tests = [test_acctpolicy, test_attruniq, test_automember, test_dna,
f92ce9
+              test_linkedattrs, test_memberof, test_mep, test_passthru,
f92ce9
+              test_referint, test_retrocl, test_rootdn]
f92ce9
+
f92ce9
+
f92ce9
+def test_all_plugins(inst, args=None):
f92ce9
+    for func in func_tests:
f92ce9
+        func(inst, args)
f92ce9
+
f92ce9
+    return
f92ce9
+
f92ce9
diff --git a/dirsrvtests/suites/dynamic-plugins/stress_tests.py b/dirsrvtests/suites/dynamic-plugins/stress_tests.py
f92ce9
new file mode 100644
f92ce9
index 0000000..a1f666d
f92ce9
--- /dev/null
f92ce9
+++ b/dirsrvtests/suites/dynamic-plugins/stress_tests.py
f92ce9
@@ -0,0 +1,133 @@
f92ce9
+'''
f92ce9
+Created on Dec 16, 2014
f92ce9
+
f92ce9
+@author: mreynolds
f92ce9
+'''
f92ce9
+import os
f92ce9
+import sys
f92ce9
+import time
f92ce9
+import ldap
f92ce9
+import time
f92ce9
+import logging
f92ce9
+import socket
f92ce9
+import pytest
f92ce9
+import threading
f92ce9
+from lib389 import DirSrv, Entry, tools, tasks
f92ce9
+from lib389.tools import DirSrvTools
f92ce9
+from lib389._constants import *
f92ce9
+from lib389.properties import *
f92ce9
+from constants import *
f92ce9
+
f92ce9
+log = logging.getLogger(__name__)
f92ce9
+
f92ce9
+NUM_USERS = 250
f92ce9
+
f92ce9
+
f92ce9
+def openConnection(inst):
f92ce9
+    # Open a new connection to our LDAP server
f92ce9
+    server = DirSrv(verbose=False)
f92ce9
+    args_instance[SER_HOST] = HOST_STANDALONE
f92ce9
+    args_instance[SER_PORT] = PORT_STANDALONE
f92ce9
+    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
f92ce9
+    args_standalone = args_instance.copy()
f92ce9
+    server.allocate(args_standalone)
f92ce9
+    server.open()
f92ce9
+
f92ce9
+    return server
f92ce9
+
f92ce9
+
f92ce9
+# Configure Referential Integrity Plugin for stress test
f92ce9
+def configureRI(inst):
f92ce9
+    inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
f92ce9
+    PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('configureRI: Failed to configure RI plugin: error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+
f92ce9
+# Configure MemberOf Plugin for stress test
f92ce9
+def configureMO(inst):
f92ce9
+    inst.plugins.enable(name=PLUGIN_MEMBER_OF)
f92ce9
+    PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'
f92ce9
+    try:
f92ce9
+        inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        log.error('configureMO: Failed to update config(uniquemember): error ' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+
f92ce9
+class DelUsers(threading.Thread):
f92ce9
+    def __init__(self, inst, rdnval):
f92ce9
+        threading.Thread.__init__(self)
f92ce9
+        self.daemon = True
f92ce9
+        self.inst = inst
f92ce9
+        self.rdnval = rdnval
f92ce9
+
f92ce9
+    def run(self):
f92ce9
+        conn = openConnection(self.inst)
f92ce9
+        idx = 0
f92ce9
+        log.info('DelUsers - Deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')
f92ce9
+        while idx < NUM_USERS:
f92ce9
+            USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX
f92ce9
+            try:
f92ce9
+                conn.delete_s(USER_DN)
f92ce9
+            except ldap.LDAPError, e:
f92ce9
+                log.error('DeleteUsers: failed to delete (' + USER_DN + ') error: ' + e.message['desc'])
f92ce9
+                assert False
f92ce9
+
f92ce9
+            idx += 1
f92ce9
+
f92ce9
+        conn.close()
f92ce9
+        log.info('DelUsers - Finished deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').')
f92ce9
+
f92ce9
+
f92ce9
+class AddUsers(threading.Thread):
f92ce9
+    def __init__(self, inst, rdnval, addToGroup):
f92ce9
+        threading.Thread.__init__(self)
f92ce9
+        self.daemon = True
f92ce9
+        self.inst = inst
f92ce9
+        self.addToGroup = addToGroup
f92ce9
+        self.rdnval = rdnval
f92ce9
+
f92ce9
+    def run(self):
f92ce9
+        # Start adding users
f92ce9
+        conn = openConnection(self.inst)
f92ce9
+        idx = 0
f92ce9
+
f92ce9
+        if self.addToGroup:
f92ce9
+            GROUP_DN = 'cn=stress-group,' + DEFAULT_SUFFIX
f92ce9
+            try:
f92ce9
+                conn.add_s(Entry((GROUP_DN,
f92ce9
+                    {'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),
f92ce9
+                     'uid': 'user' + str(idx)})))
f92ce9
+            except ldap.ALREADY_EXISTS:
f92ce9
+                pass
f92ce9
+            except ldap.LDAPError, e:
f92ce9
+                log.error('AddUsers: failed to add group (' + USER_DN + ') error: ' + e.message['desc'])
f92ce9
+                assert False
f92ce9
+
f92ce9
+        log.info('AddUsers - Adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')
f92ce9
+
f92ce9
+        while idx < NUM_USERS:
f92ce9
+            USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX
f92ce9
+            try:
f92ce9
+                conn.add_s(Entry((USER_DN, {'objectclass': 'top extensibleObject'.split(),
f92ce9
+                           'uid': 'user' + str(idx)})))
f92ce9
+            except ldap.LDAPError, e:
f92ce9
+                log.error('AddUsers: failed to add (' + USER_DN + ') error: ' + e.message['desc'])
f92ce9
+                assert False
f92ce9
+
f92ce9
+            if self.addToGroup:
f92ce9
+                # Add the user to the group
f92ce9
+                try:
f92ce9
+                    conn.modify_s(GROUP_DN, [(ldap.MOD_ADD, 'uniquemember', USER_DN)])
f92ce9
+                except ldap.LDAPError, e:
f92ce9
+                    log.error('AddUsers: Failed to add user' + USER_DN + ' to group: error ' + e.message['desc'])
f92ce9
+                    assert False
f92ce9
+
f92ce9
+            idx += 1
f92ce9
+
f92ce9
+        conn.close()
f92ce9
+        log.info('AddUsers - Finished adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').')
f92ce9
diff --git a/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py
f92ce9
new file mode 100644
f92ce9
index 0000000..3677fd5
f92ce9
--- /dev/null
f92ce9
+++ b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py
f92ce9
@@ -0,0 +1,315 @@
f92ce9
+'''
f92ce9
+Created on Dec 09, 2014
f92ce9
+
f92ce9
+@author: mreynolds
f92ce9
+'''
f92ce9
+import os
f92ce9
+import sys
f92ce9
+import time
f92ce9
+import ldap
f92ce9
+import ldap.sasl
f92ce9
+import logging
f92ce9
+import socket
f92ce9
+import pytest
f92ce9
+import plugin_tests
f92ce9
+import stress_tests
f92ce9
+from lib389 import DirSrv, Entry, tools, tasks
f92ce9
+from lib389.tools import DirSrvTools
f92ce9
+from lib389._constants import *
f92ce9
+from lib389.properties import *
f92ce9
+from lib389.tasks import *
f92ce9
+from constants import *
f92ce9
+
f92ce9
+log = logging.getLogger(__name__)
f92ce9
+
f92ce9
+installation_prefix = None
f92ce9
+
f92ce9
+
f92ce9
+class TopologyStandalone(object):
f92ce9
+    def __init__(self, standalone):
f92ce9
+        standalone.open()
f92ce9
+        self.standalone = standalone
f92ce9
+
f92ce9
+
f92ce9
+@pytest.fixture(scope="module")
f92ce9
+def topology(request):
f92ce9
+    '''
f92ce9
+        This fixture is used to standalone topology for the 'module'.
f92ce9
+        At the beginning, It may exists a standalone instance.
f92ce9
+        It may also exists a backup for the standalone instance.
f92ce9
+
f92ce9
+        Principle:
f92ce9
+            If standalone instance exists:
f92ce9
+                restart it
f92ce9
+            If backup of standalone exists:
f92ce9
+                create/rebind to standalone
f92ce9
+
f92ce9
+                restore standalone instance from backup
f92ce9
+            else:
f92ce9
+                Cleanup everything
f92ce9
+                    remove instance
f92ce9
+                    remove backup
f92ce9
+                Create instance
f92ce9
+                Create backup
f92ce9
+    '''
f92ce9
+    global installation_prefix
f92ce9
+
f92ce9
+    if installation_prefix:
f92ce9
+        args_instance[SER_DEPLOYED_DIR] = installation_prefix
f92ce9
+
f92ce9
+    standalone = DirSrv(verbose=False)
f92ce9
+
f92ce9
+    # Args for the standalone instance
f92ce9
+    args_instance[SER_HOST] = HOST_STANDALONE
f92ce9
+    args_instance[SER_PORT] = PORT_STANDALONE
f92ce9
+    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
f92ce9
+    args_standalone = args_instance.copy()
f92ce9
+    standalone.allocate(args_standalone)
f92ce9
+
f92ce9
+    # Get the status of the backups
f92ce9
+    backup_standalone = standalone.checkBackupFS()
f92ce9
+
f92ce9
+    # Get the status of the instance and restart it if it exists
f92ce9
+    instance_standalone = standalone.exists()
f92ce9
+    if instance_standalone:
f92ce9
+        # assuming the instance is already stopped, just wait 5 sec max
f92ce9
+        standalone.stop(timeout=5)
f92ce9
+        standalone.start(timeout=10)
f92ce9
+
f92ce9
+    if backup_standalone:
f92ce9
+        # The backup exist, assuming it is correct
f92ce9
+        # we just re-init the instance with it
f92ce9
+        if not instance_standalone:
f92ce9
+            standalone.create()
f92ce9
+            # Used to retrieve configuration information (dbdir, confdir...)
f92ce9
+            standalone.open()
f92ce9
+
f92ce9
+        # restore standalone instance from backup
f92ce9
+        standalone.stop(timeout=10)
f92ce9
+        standalone.restoreFS(backup_standalone)
f92ce9
+        standalone.start(timeout=10)
f92ce9
+
f92ce9
+    else:
f92ce9
+        # We should be here only in two conditions
f92ce9
+        #      - This is the first time a test involve standalone instance
f92ce9
+        #      - Something weird happened (instance/backup destroyed)
f92ce9
+        #        so we discard everything and recreate all
f92ce9
+
f92ce9
+        # Remove the backup. So even if we have a specific backup file
f92ce9
+        # (e.g backup_standalone) we clear backup that an instance may have created
f92ce9
+        if backup_standalone:
f92ce9
+            standalone.clearBackupFS()
f92ce9
+
f92ce9
+        # Remove the instance
f92ce9
+        if instance_standalone:
f92ce9
+            standalone.delete()
f92ce9
+
f92ce9
+        # Create the instance
f92ce9
+        standalone.create()
f92ce9
+
f92ce9
+        # Used to retrieve configuration information (dbdir, confdir...)
f92ce9
+        standalone.open()
f92ce9
+
f92ce9
+        # Time to create the backups
f92ce9
+        standalone.stop(timeout=10)
f92ce9
+        standalone.backupfile = standalone.backupFS()
f92ce9
+        standalone.start(timeout=10)
f92ce9
+
f92ce9
+    #
f92ce9
+    # Here we have standalone instance up and running
f92ce9
+    # Either coming from a backup recovery
f92ce9
+    # or from a fresh (re)init
f92ce9
+    # Time to return the topology
f92ce9
+    return TopologyStandalone(standalone)
f92ce9
+
f92ce9
+
f92ce9
+def test_dynamic_plugins(topology):
f92ce9
+    """
f92ce9
+        Test Dynamic Plugins - exercise each plugin and its main features, while
f92ce9
+        changing the configuration without restarting the server.
f92ce9
+
f92ce9
+        Need to test: functionality, stability, and stress.
f92ce9
+
f92ce9
+        Functionality - Make sure that as configuration changes are made they take
f92ce9
+                        effect immediately.  Cross plugin interaction (e.g. automember/memberOf)
f92ce9
+                        needs to tested, as well as plugin tasks.  Need to test plugin
f92ce9
+                        config validation(dependencies, etc).
f92ce9
+
f92ce9
+        Memory Corruption - Restart the plugins many times, and in different orders and test
f92ce9
+                            functionality, and stability.  This will excerise the internal
f92ce9
+                            plugin linked lists, dse callabcks, and task handlers.
f92ce9
+
f92ce9
+        Stress - Put the server under some type of load that is using a particular
f92ce9
+                 plugin for each operation, and then make changes to that plugin.
f92ce9
+                 The new changes should take effect, and the server should not crash.
f92ce9
+
f92ce9
+    """
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    #  Test plugin functionality
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    # First enable dynamic plugins
f92ce9
+    try:
f92ce9
+        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')])
f92ce9
+    except ldap.LDAPError, e:
f92ce9
+        ldap.error('Failed to enable dynamic plugin!' + e.message['desc'])
f92ce9
+        assert False
f92ce9
+
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('Testing Dynamic Plugins Functionality...')
f92ce9
+    log.info('#####################################################\n')
f92ce9
+
f92ce9
+    plugin_tests.test_all_plugins(topology.standalone)
f92ce9
+
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('Successfully Tested Dynamic Plugins Functionality.')
f92ce9
+    log.info('#####################################################\n')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Test the stability by exercising the internal lists, callabcks, and task handlers
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('Testing Dynamic Plugins for Memory Corruption...')
f92ce9
+    log.info('#####################################################\n')
f92ce9
+    prev_plugin_test = None
f92ce9
+    prev_prev_plugin_test = None
f92ce9
+    for plugin_test in plugin_tests.func_tests:
f92ce9
+        #
f92ce9
+        # Restart the plugin several times (and prev plugins) - work that linked list
f92ce9
+        #
f92ce9
+        plugin_test(topology.standalone, "restart")
f92ce9
+
f92ce9
+        if prev_prev_plugin_test:
f92ce9
+            prev_prev_plugin_test(topology.standalone, "restart")
f92ce9
+
f92ce9
+        plugin_test(topology.standalone, "restart")
f92ce9
+
f92ce9
+        if prev_plugin_test:
f92ce9
+            prev_plugin_test(topology.standalone, "restart")
f92ce9
+
f92ce9
+        plugin_test(topology.standalone, "restart")
f92ce9
+
f92ce9
+        # Now run the functional test
f92ce9
+        plugin_test(topology.standalone)
f92ce9
+
f92ce9
+        # Set the previous tests
f92ce9
+        if prev_plugin_test:
f92ce9
+            prev_prev_plugin_test = prev_plugin_test
f92ce9
+        prev_plugin_test = plugin_test
f92ce9
+
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('Successfully Tested Dynamic Plugins for Memory Corruption.')
f92ce9
+    log.info('#####################################################\n')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # Stress two plugins while restarting it, and while restarting other plugins.
f92ce9
+    # The goal is to not crash, and have the plugins work after stressing it.
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('Stressing Dynamic Plugins...')
f92ce9
+    log.info('#####################################################\n')
f92ce9
+
f92ce9
+    # Configure the plugins
f92ce9
+    stress_tests.configureMO(topology.standalone)
f92ce9
+    stress_tests.configureRI(topology.standalone)
f92ce9
+
f92ce9
+    # Launch three new threads to add a bunch of users
f92ce9
+    add_users = stress_tests.AddUsers(topology.standalone, 'user', True)
f92ce9
+    add_users.start()
f92ce9
+    add_users2 = stress_tests.AddUsers(topology.standalone, 'entry', True)
f92ce9
+    add_users2.start()
f92ce9
+    add_users3 = stress_tests.AddUsers(topology.standalone, 'person', True)
f92ce9
+    add_users3.start()
f92ce9
+    time.sleep(1)
f92ce9
+
f92ce9
+    # While we are adding users restart the MO plugin
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
f92ce9
+    time.sleep(3)
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
f92ce9
+    time.sleep(1)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
f92ce9
+
f92ce9
+    # Restart idle plugin
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+
f92ce9
+    # Wait for the 'adding' threads to complete
f92ce9
+    add_users.join()
f92ce9
+    add_users2.join()
f92ce9
+    add_users3.join()
f92ce9
+
f92ce9
+    # Now launch three threads to delete the users, and restart both the MO and RI plugins
f92ce9
+    del_users = stress_tests.DelUsers(topology.standalone, 'user')
f92ce9
+    del_users.start()
f92ce9
+    del_users2 = stress_tests.DelUsers(topology.standalone, 'entry')
f92ce9
+    del_users2.start()
f92ce9
+    del_users3 = stress_tests.DelUsers(topology.standalone, 'person')
f92ce9
+    del_users3.start()
f92ce9
+    time.sleep(1)
f92ce9
+
f92ce9
+    # Restart the both the MO and RI plugins during these deletes
f92ce9
+
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
f92ce9
+    time.sleep(3)
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
f92ce9
+    time.sleep(1)
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
f92ce9
+    time.sleep(1)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
f92ce9
+    time.sleep(1)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
f92ce9
+
f92ce9
+    # Restart idle plugin
f92ce9
+    topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+    topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
f92ce9
+
f92ce9
+    # Wait for the 'deleting' threads to complete
f92ce9
+    del_users.join()
f92ce9
+    del_users2.join()
f92ce9
+    del_users3.join()
f92ce9
+
f92ce9
+    # Now make sure both the MO and RI plugins still work
f92ce9
+    plugin_tests.func_tests[8](topology.standalone)  # RI plugin
f92ce9
+    plugin_tests.func_tests[5](topology.standalone)  # MO plugin
f92ce9
+
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('Successfully Stressed Dynamic Plugins.')
f92ce9
+    log.info('#####################################################\n')
f92ce9
+
f92ce9
+    ############################################################################
f92ce9
+    # We made it to the end!
f92ce9
+    ############################################################################
f92ce9
+
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info("Dynamic Plugins Testsuite: Completed Successfully!")
f92ce9
+    log.info('#####################################################')
f92ce9
+    log.info('#####################################################')
f92ce9
+
f92ce9
+def test_dynamic_plugins_final(topology):
f92ce9
+    topology.standalone.stop(timeout=10)
f92ce9
+
f92ce9
+
f92ce9
+def run_isolated():
f92ce9
+    '''
f92ce9
+        run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
f92ce9
+        To run isolated without py.test, you need to
f92ce9
+            - edit this file and comment '@pytest.fixture' line before 'topology' function.
f92ce9
+            - set the installation prefix
f92ce9
+            - run this program
f92ce9
+    '''
f92ce9
+    global installation_prefix
f92ce9
+    installation_prefix = None
f92ce9
+
f92ce9
+    topo = topology(True)
f92ce9
+    test_dynamic_plugins(topo)
f92ce9
+
f92ce9
+if __name__ == '__main__':
f92ce9
+    run_isolated()
f92ce9
-- 
f92ce9
1.9.3
f92ce9