From 7a9249566371ebac542de26dc7669265e6da7119 Mon Sep 17 00:00:00 2001 From: "Thierry bordaz (tbordaz)" Date: Tue, 5 Nov 2013 18:01:32 +0100 Subject: [PATCH] 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-/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 https://fedorahosted.org/389/ticket/47575 Reviewed by: Rich, Jan, Roberto Platforms tested: F19 Flag Day: no Doc impact: no --- dirsrvtests/tickets/_constants.py | 26 ++++ dirsrvtests/tickets/finalizer.py | 64 ++++++++++ dirsrvtests/tickets/ticket47560_test.py | 219 ++++++++++++++++++++++++++++++++ 3 files changed, 309 insertions(+) create mode 100644 dirsrvtests/tickets/_constants.py create mode 100644 dirsrvtests/tickets/finalizer.py create mode 100644 dirsrvtests/tickets/ticket47560_test.py diff --git a/dirsrvtests/tickets/_constants.py b/dirsrvtests/tickets/_constants.py new file mode 100644 index 0000000..2a19654 --- /dev/null +++ b/dirsrvtests/tickets/_constants.py @@ -0,0 +1,26 @@ +''' +Created on Oct 31, 2013 + +@author: tbordaz +''' +import os +from lib389._constants import DN_DM + +LOCALHOST = "localhost.localdomain" +SUFFIX = 'dc=example,dc=com' +PASSWORD = 'password' + +HOST_STANDALONE = LOCALHOST +PORT_STANDALONE = 33389 +SERVERID_STANDALONE = 'standalone' + + +args_standalone = { + 'prefix': os.environ.get('PREFIX', None), + 'newrootdn': DN_DM, + 'newrootpw': PASSWORD, + 'newhost': HOST_STANDALONE, + 'newport': PORT_STANDALONE, + 'newinstance': SERVERID_STANDALONE, + 'newsuffix': SUFFIX, + 'no_admin': True} diff --git a/dirsrvtests/tickets/finalizer.py b/dirsrvtests/tickets/finalizer.py new file mode 100644 index 0000000..7d4cbbf --- /dev/null +++ b/dirsrvtests/tickets/finalizer.py @@ -0,0 +1,64 @@ +''' +Created on Nov 5, 2013 + +@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 PASSWORD, HOST_STANDALONE, PORT_STANDALONE,\ + SERVERID_STANDALONE, SUFFIX, args_standalone + +log = logging.getLogger(__name__) + +def _ds_create_standalone(verbose=False): + # create the standalone instance + return tools.DirSrvTools.createInstance(args_standalone, verbose=True) + +def _ds_rebind_standalone(verbose=False): + return tools.DirSrvTools.createInstance(args_standalone, verbose) + + +class DSInstance(object): + def __init__(self, ds_instance, verbose=False): + + self.instance = ds_instance + # Check if we need to do a backup of this instance + backupFile = DirSrvTools.checkInstanceBackupFS(ds_instance) + if backupFile is None: + # This instance is brand new no need to reinit it + if verbose: + log.debug("DSInstance: take a backup") + DirSrvTools.stop(self.instance, verbose, timeout=120) + self.backupfile = DirSrvTools.instanceBackupFS(self.instance, verbose) + DirSrvTools.start(self.instance, verbose, timeout=120) + else: + # This instance was created before. Reinit it + if verbose: + log.debug("DSInstance: reinit from a backup %s" % backupFile) + DirSrvTools.stop(self.instance, verbose, timeout=120) + DirSrvTools.instanceRestoreFS(self.instance, backupFile, verbose) + DirSrvTools.start(self.instance, verbose, timeout=120) + + # In all case, the instance was restarted, we need to rebind + self.instance = _ds_rebind_standalone() + + +@pytest.fixture +def ds_instance(request): + ds_instance = _ds_create_standalone() + return DSInstance(ds_instance, verbose=True) + + +def test_finalizer(ds_instance): + log.info("%s remove the instance" % (__name__)) + tools.DirSrvTools.removeInstance(ds_instance.instance) \ No newline at end of file diff --git a/dirsrvtests/tickets/ticket47560_test.py b/dirsrvtests/tickets/ticket47560_test.py new file mode 100644 index 0000000..611e3c0 --- /dev/null +++ b/dirsrvtests/tickets/ticket47560_test.py @@ -0,0 +1,219 @@ +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 PASSWORD, HOST_STANDALONE, PORT_STANDALONE,\ + SERVERID_STANDALONE, SUFFIX, args_standalone + +log = logging.getLogger(__name__) + +def _ds_create_standalone(verbose=False): + # create the standalone instance + return tools.DirSrvTools.createInstance(args_standalone, verbose) + +def _ds_rebind_standalone(verbose=False): + return tools.DirSrvTools.createInstance(args_standalone, verbose) + + +class DSInstance(object): + def __init__(self, ds_instance, verbose=False): + + self.instance = ds_instance + # Check if we need to do a backup of this instance + backupFile = DirSrvTools.checkInstanceBackupFS(ds_instance) + if backupFile is None: + # This instance is brand new no need to reinit it + if verbose: + log.debug("DSInstance: take a backup") + DirSrvTools.stop(self.instance, verbose, timeout=120) + self.backupfile = DirSrvTools.instanceBackupFS(self.instance, verbose) + DirSrvTools.start(self.instance, verbose, timeout=120) + else: + # This instance was created before. Reinit it + if verbose: + log.debug("DSInstance: reinit from a backup %s" % backupFile) + DirSrvTools.stop(self.instance, verbose, timeout=120) + DirSrvTools.instanceRestoreFS(self.instance, backupFile, verbose) + DirSrvTools.start(self.instance, verbose, timeout=120) + + # In all case, the instance was restarted, we need to rebind + self.instance = _ds_rebind_standalone() + + +@pytest.fixture +def ds_instance(request): + + ds_instance = _ds_create_standalone() + return DSInstance(ds_instance, verbose=True) + + +def test_ticket47560(ds_instance): + """ + 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)] + ds_instance.instance.modify_s(MEMBEROF_PLUGIN_DN, replace) + DirSrvTools.stop(ds_instance.instance, verbose=False, timeout=120) + time.sleep(1) + DirSrvTools.start(ds_instance.instance, verbose=False, timeout=120) + time.sleep(3) + + # need to reopen a connection toward the instance + ds_instance.instance = _ds_rebind_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: + ds_instance.instance.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: + ds_instance.instance.add_s(entry) + except ldap.ALREADY_EXISTS: + log.debug( "Entry %s already exists" % (member_DN)) + + replace = [(ldap.MOD_REPLACE, 'memberof', group_DN)] + ds_instance.instance.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 = ds_instance.instance.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: + ds_instance.instance.delete_s(group_DN) + except: + log.warning("Entry %s fail to delete" % (group_DN)) + try: + ds_instance.instance.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 = ds_instance.instance.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 + ds_instance.instance.fixupMemberOf(SUFFIX, verbose=False) + + ents = ds_instance.instance.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 -- 1.7.11.7