From 85f02127be1138434b99741c0de40787bf72d1af Mon Sep 17 00:00:00 2001 From: William Brown Date: Jun 08 2016 16:06:41 +0000 Subject: Ticket 48799 - Test cases for objectClass values being dropped. Bug Description: During replication, not all objectClasses were added to the consumer. Fix Description: This test case proves the issue and fix. https://fedorahosted.org/389/ticket/48799 Author: wibrown Review by: nhosoi (cherry picked from commit dcec32787a8ba87f8a9e15324cc789acbac7426f) --- diff --git a/dirsrvtests/tests/tickets/ticket48799_test.py b/dirsrvtests/tests/tickets/ticket48799_test.py new file mode 100644 index 0000000..e92b5fd --- /dev/null +++ b/dirsrvtests/tests/tickets/ticket48799_test.py @@ -0,0 +1,170 @@ +import os +import sys +import time +import ldap +import logging +import pytest +from lib389 import DirSrv, Entry, tools, tasks +from lib389.tools import DirSrvTools +from lib389._constants import * +from lib389.properties import * +from lib389.tasks import * +from lib389.utils import * + +logging.getLogger(__name__).setLevel(logging.DEBUG) +log = logging.getLogger(__name__) + +class TopologyReplication(object): + def __init__(self, master1, consumer1): + master1.open() + self.master1 = master1 + consumer1.open() + self.consumer1 = consumer1 + + +@pytest.fixture(scope="module") +def topology(request): + # Creating master 1... + master1 = DirSrv(verbose=False) + args_instance[SER_HOST] = HOST_MASTER_1 + args_instance[SER_PORT] = PORT_MASTER_1 + args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1 + args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX + args_master = args_instance.copy() + master1.allocate(args_master) + instance_master1 = master1.exists() + if instance_master1: + master1.delete() + master1.create() + master1.open() + master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1) + + # Creating consumer 1... + consumer1 = DirSrv(verbose=False) + args_instance[SER_HOST] = HOST_CONSUMER_1 + args_instance[SER_PORT] = PORT_CONSUMER_1 + args_instance[SER_SERVERID_PROP] = SERVERID_CONSUMER_1 + args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX + args_consumer = args_instance.copy() + consumer1.allocate(args_consumer) + instance_consumer1 = consumer1.exists() + if instance_consumer1: + consumer1.delete() + consumer1.create() + consumer1.open() + consumer1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_CONSUMER, replicaId=CONSUMER_REPLICAID) + + # + # Create all the agreements + # + # Creating agreement from master 1 to consumer 1 + properties = {RA_NAME: r'meTo_$host:$port', + RA_BINDDN: defaultProperties[REPLICATION_BIND_DN], + RA_BINDPW: defaultProperties[REPLICATION_BIND_PW], + RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD], + RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]} + m1_c1_agmt = master1.agreement.create(suffix=SUFFIX, host=consumer1.host, port=consumer1.port, properties=properties) + if not m1_c1_agmt: + log.fatal("Fail to create a hub -> consumer replica agreement") + sys.exit(1) + log.debug("%s created" % m1_c1_agmt) + + # Allow the replicas to get situated with the new agreements... + time.sleep(5) + + # + # Initialize all the agreements + # + master1.agreement.init(SUFFIX, HOST_CONSUMER_1, PORT_CONSUMER_1) + master1.waitForReplInit(m1_c1_agmt) + + # Check replication is working... + if master1.testReplication(DEFAULT_SUFFIX, consumer1): + log.info('Replication is working.') + else: + log.fatal('Replication is not working.') + assert False + + # Delete each instance in the end + def fin(): + master1.delete() + consumer1.delete() + request.addfinalizer(fin) + + # Clear out the tmp dir + master1.clearTmpDir(__file__) + + return TopologyReplication(master1, consumer1) + +def _add_custom_schema(server): + attr_value = "( 10.0.9.2342.19200300.100.1.1 NAME 'customManager' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' )" + mod = [(ldap.MOD_ADD, 'attributeTypes', attr_value)] + server.modify_s('cn=schema', mod) + + oc_value = "( 1.3.6.1.4.1.4843.2.1 NAME 'customPerson' SUP inetorgperson STRUCTURAL MAY (customManager) X-ORIGIN 'user defined' )" + mod = [(ldap.MOD_ADD, 'objectclasses', oc_value)] + server.modify_s('cn=schema', mod) + +def _create_user(server): + server.add_s(Entry(( + "uid=testuser,ou=People,%s" % DEFAULT_SUFFIX, + { + 'objectClass' : "top account posixaccount".split(), + 'uid' : 'testuser', + 'gecos' : 'Test User', + 'cn' : 'testuser', + 'homedirectory' : '/home/testuser', + 'passwordexpirationtime' : '20160710184141Z', + 'userpassword' : '!', + 'uidnumber' : '1111212', + 'gidnumber' : '1111212', + 'loginshell' : '/bin/bash' + } + ))) + +def _modify_user(server): + mod = [ + (ldap.MOD_ADD, 'objectClass', ['customPerson']), + (ldap.MOD_ADD, 'sn', ['User']), + (ldap.MOD_ADD, 'customManager', ['cn=manager']), + ] + server.modify("uid=testuser,ou=People,%s" % DEFAULT_SUFFIX, mod) + +def test_ticket48799(topology): + """Write your replication testcase here. + + To access each DirSrv instance use: topology.master1, topology.master2, + ..., topology.hub1, ..., topology.consumer1,... + + Also, if you need any testcase initialization, + please, write additional fixture for that(include finalizer). + """ + + # Add the new schema element. + _add_custom_schema(topology.master1) + _add_custom_schema(topology.consumer1) + + # Add a new user on the master. + _create_user(topology.master1) + # Modify the user on the master. + _modify_user(topology.master1) + + # We need to wait for replication here. + time.sleep(15) + + # Now compare the master vs consumer, and see if the objectClass was dropped. + + master_entry = topology.master1.search_s("uid=testuser,ou=People,%s" % DEFAULT_SUFFIX, ldap.SCOPE_BASE, '(objectclass=*)', ['objectClass']) + consumer_entry = topology.consumer1.search_s("uid=testuser,ou=People,%s" % DEFAULT_SUFFIX, ldap.SCOPE_BASE, '(objectclass=*)', ['objectClass']) + + assert(master_entry == consumer_entry) + + + log.info('Test complete') + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s %s" % CURRENT_FILE)