[389-commits] dirsrvtests/tickets

thierry bordaz tbordaz at fedoraproject.org
Tue Dec 3 20:14:15 UTC 2013


 dirsrvtests/tickets/constants.py        |   20 --
 dirsrvtests/tickets/finalizer.py        |   73 +++++++
 dirsrvtests/tickets/ticket47560_test.py |  310 ++++++++++++++++++++++++++++++++
 3 files changed, 392 insertions(+), 11 deletions(-)

New commits:
commit 9ec7b929b5a1e2fd17a41cc5eadba79d28933d0c
Author: Thierry bordaz (tbordaz) <tbordaz at redhat.com>
Date:   Tue Nov 5 18:01:32 2013 +0100

    Ticket 47575 - CI test: add test case for ticket47560
    
    Bug Description:
    	https://fedorahosted.org/389/ticket/47560
    	memberof plugins supports fixup tasks.
    	A task can be created with the perl script /usr/lib64/dirsrv/slapd-<instance>/fixup-memberof.pl
    	due to bug 47560, the task entry was not created
    
    Fix Description:
    	The test case is to
                       SETUP
                    - Create entry cn=group,SUFFIX
                    - Create entry cn=member,SUFFIX
                    - Update 'cn=member,SUFFIX' to add "memberOf: cn=group,SUFFIX"
                    - Enable Memberof Plugins
    
                    # Here the cn=member entry has a 'memberOf' but
                    # cn=group entry does not contain 'cn=member' in its member
    
                      TEST CASE
                    - start the fixupmemberof task
                    - read the cn=member entry
                    - check 'memberOf is now empty
    
                      TEARDOWN
                    - Delete entry cn=group,SUFFIX
                    - Delete entry cn=member,SUFFIX
                    - Disable Memberof Plugins
    
    	The test ends with stopping the standalone instance
    
    https://fedorahosted.org/389/ticket/47575
    
    Reviewed by: Rich, Jan, Roberto (thanks to you all !!)
    
    Platforms tested: F19
    
    Flag Day: no
    
    Doc impact: no

diff --git a/dirsrvtests/tickets/constants.py b/dirsrvtests/tickets/constants.py
index 88fdea5..44b9b3a 100644
--- a/dirsrvtests/tickets/constants.py
+++ b/dirsrvtests/tickets/constants.py
@@ -44,17 +44,15 @@ HOST_CONSUMER_2 = LOCALHOST
 PORT_CONSUMER_2 = 55389
 SERVERID_CONSUMER_2 = 'consumer_2'
 
-args_standalone = {
-                   'prefix': os.environ.get('PREFIX', None),
-                   'backupdir': os.environ.get('BACKUPDIR', "/tmp"),
-                   'newrootdn': DN_DM,
-                   'newrootpw': PASSWORD,
-                   'newhost': HOST_STANDALONE,
-                   'newport': PORT_STANDALONE,
-                   'newinstance': SERVERID_STANDALONE,
-                   'newsuffix': SUFFIX,
-                   'no_admin': True}
-
+# Each defined instance above must be added in that list 
+ALL_INSTANCES = [ {'host': HOST_STANDALONE, 'port': PORT_STANDALONE, 'serverid': SERVERID_STANDALONE},
+                  {'host': HOST_MASTER,     'port': PORT_MASTER,     'serverid': SERVERID_MASTER},
+                  {'host': HOST_CONSUMER,   'port': PORT_CONSUMER,   'serverid': SERVERID_CONSUMER},
+                  {'host': HOST_MASTER_1,   'port': PORT_MASTER_1,   'serverid': SERVERID_MASTER_1},
+                  {'host': HOST_MASTER_2,   'port': PORT_MASTER_2,   'serverid': SERVERID_MASTER_2},
+                  {'host': HOST_CONSUMER_1, 'port': PORT_CONSUMER_1, 'serverid': SERVERID_CONSUMER_1},
+                  {'host': HOST_CONSUMER_2, 'port': PORT_CONSUMER_2, 'serverid': SERVERID_CONSUMER_2},
+                 ]
 # This is a template
 args_instance = {
                    'prefix': os.environ.get('PREFIX', None),
diff --git a/dirsrvtests/tickets/finalizer.py b/dirsrvtests/tickets/finalizer.py
new file mode 100644
index 0000000..23356dd
--- /dev/null
+++ b/dirsrvtests/tickets/finalizer.py
@@ -0,0 +1,73 @@
+'''
+Created on Nov 5, 2013
+
+ at author: tbordaz
+'''
+import os
+import sys
+import time
+import ldap
+import logging
+import socket
+import time
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools
+from lib389.tools import DirSrvTools
+from lib389._constants import DN_DM
+from constants import *
+
+log = logging.getLogger(__name__)
+
+global installation_prefix
+
+
+def _remove_instance(args):
+    
+    # check the instance parameters
+    args_instance['newhost'] = args.get('host', None)
+    if not args_instance['newhost']:
+        raise ValueError("host not defined")
+    
+    args_instance['newport'] = args.get('port', None)
+    if not args_instance['newport']:
+        raise ValueError("port not defined")
+    
+    args_instance['newinstance'] = args.get('serverid', None)
+    if not args_instance['newinstance']:
+        raise ValueError("serverid not defined")
+
+    args_instance['prefix'] = args.get('prefix', None)
+
+    # Get the status of the instance and remove it if it exists
+    instance   = DirSrvTools.existsInstance(args_instance)
+    if instance:
+        log.debug("_remove_instance %s %s:%d" % (instance.serverId, instance.host, instance.port))
+        DirSrvTools.removeInstance(instance)
+
+
+def test_finalizer():
+    global installation_prefix
+    
+    # for each defined instance, remove it
+    for instance in ALL_INSTANCES:
+        if installation_prefix:
+            # overwrite the environment setting
+            instance['prefix'] = installation_prefix
+        _remove_instance(instance)
+        
+def run_isolated():
+    '''
+        run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+        To run isolated without py.test, you need to 
+            - set the installation prefix
+            - run this program
+    '''
+    global installation_prefix
+    installation_prefix =  None
+        
+    test_finalizer()
+
+if __name__ == '__main__':
+    run_isolated()
+
diff --git a/dirsrvtests/tickets/ticket47560_test.py b/dirsrvtests/tickets/ticket47560_test.py
new file mode 100644
index 0000000..1561f21
--- /dev/null
+++ b/dirsrvtests/tickets/ticket47560_test.py
@@ -0,0 +1,310 @@
+import os
+import sys
+import time
+import ldap
+import logging
+import socket
+import time
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+installation_prefix = None
+
+def _ds_create_instance(args):
+    # create the standalone instance
+    return tools.DirSrvTools.createInstance(args, verbose=False)
+
+def _ds_rebind_instance(dirsrv):
+    args_instance['prefix']      = dirsrv.prefix
+    args_instance['backupdir']   = dirsrv.backupdir
+    args_instance['newrootdn']   = dirsrv.binddn
+    args_instance['newrootpw']   = dirsrv.bindpw
+    args_instance['newhost']     = dirsrv.host
+    args_instance['newport']     = dirsrv.port
+    args_instance['newinstance'] = dirsrv.serverId
+    args_instance['newsuffix']   = SUFFIX
+    args_instance['no_admin']    = True
+
+    return tools.DirSrvTools.createInstance(args_instance)
+
+class TopologyStandalone(object):
+    def __init__(self, standalone):
+        self.standalone = _ds_rebind_instance(standalone)
+
+
+ at pytest.fixture(scope="module")
+def topology(request):
+    '''
+        This fixture is used to standalone topology for the 'module'.
+        At the beginning, It may exists a standalone instance.
+        It may also exists a backup for the standalone instance.
+    
+        Principle:
+            If standalone instance exists:
+                restart it
+            If backup of standalone exists:
+                create or rebind to standalone
+
+                restore standalone instance from backup
+            else:
+                Cleanup everything
+                    remove instance
+                    remove backup
+                Create instance
+                Create backup
+    '''
+    global installation_prefix
+
+    if installation_prefix:
+        args_instance['prefix'] = installation_prefix
+    
+    # Args for the standalone instance
+    args_instance['newhost'] = HOST_STANDALONE
+    args_instance['newport'] = PORT_STANDALONE
+    args_instance['newinstance'] = SERVERID_STANDALONE
+    args_standalone = args_instance.copy()
+    
+    # Get the status of the backups
+    backup_standalone   = DirSrvTools.existsBackup(args_standalone)
+    
+    # Get the status of the instance and restart it if it exists
+    instance_standalone   = DirSrvTools.existsInstance(args_standalone)
+    if instance_standalone:
+        # assuming the instance is already stopped, just wait 5 sec max
+        DirSrvTools.stop(instance_standalone, timeout=5)
+        DirSrvTools.start(instance_standalone, timeout=10)
+    
+    if backup_standalone:
+        # The backup exist, assuming it is correct 
+        # we just re-init the instance with it
+        standalone   = _ds_create_instance(args_standalone)
+        
+        # restore standalone instance from backup
+        DirSrvTools.stop(standalone, timeout=10)
+        DirSrvTools.instanceRestoreFS(standalone, backup_standalone)
+        DirSrvTools.start(standalone, timeout=10)
+        
+    else:
+        # We should be here only in two conditions
+        #      - This is the first time a test involve standalone instance
+        #      - Something weird happened (instance/backup destroyed)
+        #        so we discard everything and recreate all
+        
+        # Remove the backup. So even if we have a specific backup file
+        # (e.g backup_standalone) we clear backup that an instance may have created
+        if backup_standalone:
+            DirSrvTools.clearInstanceBackupFS(dirsrv=instance_standalone)
+        
+        # Remove the instance
+        if instance_standalone:
+            DirSrvTools.removeInstance(instance_standalone)
+            
+        # Create the instance
+        standalone   = _ds_create_instance(args_standalone)
+                
+        # Time to create the backups
+        DirSrvTools.stop(standalone, timeout=10)
+        standalone.backupfile = DirSrvTools.instanceBackupFS(standalone)
+        DirSrvTools.start(standalone, timeout=10)
+    
+    # 
+    # Here we have standalone instance up and running
+    # Either coming from a backup recovery
+    # or from a fresh (re)init
+    # Time to return the topology
+    return TopologyStandalone(standalone)
+
+
+def test_ticket47560(topology):
+    """
+       This test case does the following:
+          SETUP
+            - Create entry cn=group,SUFFIX
+            - Create entry cn=member,SUFFIX
+            - Update 'cn=member,SUFFIX' to add "memberOf: cn=group,SUFFIX"
+            - Enable Memberof Plugins
+                
+            # Here the cn=member entry has a 'memberOf' but 
+            # cn=group entry does not contain 'cn=member' in its member
+                
+          TEST CASE
+            - start the fixupmemberof task
+            - read the cn=member entry
+            - check 'memberOf is now empty
+                
+           TEARDOWN
+            - Delete entry cn=group,SUFFIX
+            - Delete entry cn=member,SUFFIX
+            - Disable Memberof Plugins
+    """
+        
+    def _enable_disable_mbo(value):
+        """
+            Enable or disable mbo plugin depending on 'value' ('on'/'off')
+        """
+        # enable/disable the mbo plugin
+        if value != 'on':
+           value = 'off'
+        log.debug("-------------> _enable_disable_mbo(%s)" % value)
+        MEMBEROF_PLUGIN_DN = 'cn=MemberOf Plugin,cn=plugins,cn=config'
+        replace = [(ldap.MOD_REPLACE, 'nsslapd-pluginEnabled', value)]
+        topology.standalone.modify_s(MEMBEROF_PLUGIN_DN, replace)
+        DirSrvTools.stop(topology.standalone, verbose=False, timeout=120)
+        time.sleep(1)
+        DirSrvTools.start(topology.standalone, verbose=False, timeout=120)
+        time.sleep(3)
+            
+        # need to reopen a connection toward the instance
+        topology.standalone = _ds_rebind_instance(topology.standalone)
+        
+    def _test_ticket47560_setup():
+        """
+        - Create entry cn=group,SUFFIX
+        - Create entry cn=member,SUFFIX
+        - Update 'cn=member,SUFFIX' to add "memberOf: cn=group,SUFFIX"
+        - Enable Memberof Plugins
+        """
+        log.debug( "-------- > _test_ticket47560_setup\n")
+            
+        #
+        # By default the memberof plugin is disabled create 
+        # - create a group entry
+        # - create a member entry
+        # - set the member entry as memberof the group entry
+        #
+        entry = Entry(group_DN)
+        entry.setValues('objectclass', 'top', 'groupOfNames', 'inetUser')
+        entry.setValues('cn', 'group')
+        try:
+            topology.standalone.add_s(entry)
+        except ldap.ALREADY_EXISTS:
+            log.debug( "Entry %s already exists" % (group_DN))
+        
+
+        entry = Entry(member_DN)
+        entry.setValues('objectclass', 'top', 'person', 'organizationalPerson', 'inetorgperson', 'inetUser')
+        entry.setValues('uid', 'member')
+        entry.setValues('cn', 'member')
+        entry.setValues('sn', 'member')
+        try:
+            topology.standalone.add_s(entry)
+        except ldap.ALREADY_EXISTS:
+            log.debug( "Entry %s already exists" % (member_DN))
+            
+        replace = [(ldap.MOD_REPLACE, 'memberof', group_DN)]
+        topology.standalone.modify_s(member_DN, replace)
+    
+ 
+        #
+        # enable the memberof plugin and restart the instance
+        #
+        _enable_disable_mbo('on')
+           
+              
+        #
+        # check memberof attribute is still present
+        #
+        filt = 'uid=member'
+        ents = topology.standalone.search_s(member_DN, ldap.SCOPE_BASE, filt)
+        assert len(ents) == 1
+        ent = ents[0]
+        #print ent
+        value = ent.getValue('memberof')
+        #print "memberof: %s" % (value)
+        assert value == group_DN 
+            
+    def _test_ticket47560_teardown():
+        """
+            - Delete entry cn=group,SUFFIX
+            - Delete entry cn=member,SUFFIX
+            - Disable Memberof Plugins
+        """
+        log.debug( "-------- > _test_ticket47560_teardown\n")
+        # remove the entries group_DN and member_DN
+        try:
+            topology.standalone.delete_s(group_DN)
+        except:
+            log.warning("Entry %s fail to delete" % (group_DN))
+        try:
+            topology.standalone.delete_s(member_DN)
+        except:
+            log.warning("Entry %s fail to delete" % (member_DN))
+        #
+        # disable the memberof plugin and restart the instance
+        #
+        _enable_disable_mbo('off')
+
+        
+    
+    group_DN  = "cn=group,%s"   % (SUFFIX)
+    member_DN = "uid=member,%s" % (SUFFIX)
+        
+    #
+    # Initialize the test case
+    #
+    _test_ticket47560_setup()
+        
+    # 
+    # start the test
+    #   - start the fixup task
+    #   - check the entry is fixed (no longer memberof the group)
+    #
+    log.debug( "-------- > Start ticket tests\n")
+        
+    filt = 'uid=member'
+    ents = topology.standalone.search_s(member_DN, ldap.SCOPE_BASE, filt)
+    assert len(ents) == 1
+    ent = ents[0]
+    log.debug( "Unfixed entry %r\n" % ent)
+        
+    # run the fixup task
+    topology.standalone.fixupMemberOf(SUFFIX, verbose=False)
+        
+    ents = topology.standalone.search_s(member_DN, ldap.SCOPE_BASE, filt)
+    assert len(ents) == 1
+    ent = ents[0]
+    log.debug( "Fixed entry %r\n" % ent)
+        
+    if ent.getValue('memberof') == group_DN:
+        log.warning("Error the fixupMemberOf did not fix %s" % (member_DN))
+        result_successful = False
+    else:
+        result_successful = True
+                  
+    #
+    # cleanup up the test case
+    #
+    _test_ticket47560_teardown() 
+        
+    assert result_successful == True
+
+def test_ticket47560_final(topology):
+    DirSrvTools.stop(topology.standalone, timeout=10)
+    
+
+
+def run_isolated():
+    '''
+        run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+        To run isolated without py.test, you need to 
+            - edit this file and comment '@pytest.fixture' line before 'topology' function.
+            - set the installation prefix
+            - run this program
+    '''
+    global installation_prefix
+    installation_prefix =  None
+        
+    topo = topology(True)
+    test_ticket47560(topo)
+    test_ticket47560_final(topo)
+
+
+if __name__ == '__main__':
+    run_isolated()
+




More information about the 389-commits mailing list