| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- 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 *
- DEBUGGING = False
- GROUP_DN = ("cn=group," + DEFAULT_SUFFIX)
- if DEBUGGING:
- logging.getLogger(__name__).setLevel(logging.DEBUG)
- else:
- logging.getLogger(__name__).setLevel(logging.INFO)
- log = logging.getLogger(__name__)
- class TopologyReplication(object):
- def __init__(self, master1, master2):
- master1.open()
- self.master1 = master1
- master2.open()
- self.master2 = master2
- @pytest.fixture(scope="module")
- def topology(request):
- """Create Replication Deployment"""
- # Creating master 1...
- if DEBUGGING:
- master1 = DirSrv(verbose=True)
- else:
- 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 master 2...
- if DEBUGGING:
- master2 = DirSrv(verbose=True)
- else:
- master2 = DirSrv(verbose=False)
- args_instance[SER_HOST] = HOST_MASTER_2
- args_instance[SER_PORT] = PORT_MASTER_2
- args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
- args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
- args_master = args_instance.copy()
- master2.allocate(args_master)
- instance_master2 = master2.exists()
- if instance_master2:
- master2.delete()
- master2.create()
- master2.open()
- master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
- def fin():
- """If we are debugging just stop the instances,
- otherwise remove them
- """
- if DEBUGGING:
- master1.stop()
- master2.stop()
- else:
- #master1.delete()
- #master2.delete()
- pass
- request.addfinalizer(fin)
- # Create all the agreements
- # Creating agreement from master 1 to master 2
- properties = {RA_NAME: 'meTo_' + master2.host + ':' + str(master2.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_m2_agmt = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
- if not m1_m2_agmt:
- log.fatal("Fail to create a master -> master replica agreement")
- sys.exit(1)
- log.debug("%s created" % m1_m2_agmt)
- # Creating agreement from master 2 to master 1
- properties = {RA_NAME: 'meTo_' + master1.host + ':' + str(master1.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]}
- m2_m1_agmt = master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
- if not m2_m1_agmt:
- log.fatal("Fail to create a master -> master replica agreement")
- sys.exit(1)
- log.debug("%s created" % m2_m1_agmt)
- # Allow the replicas to get situated with the new agreements...
- time.sleep(5)
- # Initialize all the agreements
- master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
- master1.waitForReplInit(m1_m2_agmt)
- # Check replication is working...
- if master1.testReplication(DEFAULT_SUFFIX, master2):
- log.info('Replication is working.')
- else:
- log.fatal('Replication is not working.')
- assert False
- # Clear out the tmp dir
- master1.clearTmpDir(__file__)
- return TopologyReplication(master1, master2)
- def _add_group_with_members(topology):
- # Create group
- try:
- topology.master1.add_s(Entry((GROUP_DN,
- {'objectclass': 'top groupofnames'.split(),
- 'cn': 'group'})))
- except ldap.LDAPError as e:
- log.fatal('Failed to add group: error ' + e.message['desc'])
- assert False
- # Add members to the group - set timeout
- log.info('Adding members to the group...')
- for idx in range(1, 5):
- try:
- MEMBER_VAL = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
- topology.master1.modify_s(GROUP_DN,
- [(ldap.MOD_ADD,
- 'member',
- MEMBER_VAL)])
- except ldap.LDAPError as e:
- log.fatal('Failed to update group: member (%s) - error: %s' %
- (MEMBER_VAL, e.message['desc']))
- assert False
- def _check_memberof(master, presence_flag):
- # Check that members have memberof attribute on M1
- for idx in range(1, 5):
- try:
- USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
- ent = master.getEntry(USER_DN, ldap.SCOPE_BASE, "(objectclass=*)")
- if presence_flag:
- assert ent.hasAttr('memberof') and ent.getValue('memberof') == GROUP_DN
- else:
- assert not ent.hasAttr('memberof')
- except ldap.LDAPError as e:
- log.fatal('Failed to retrieve user (%s): error %s' % (USER_DN, e.message['desc']))
- assert False
- def _check_entry_exist(master, dn):
- attempt = 0
- while attempt <= 10:
- try:
- dn
- ent = master.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
- break
- except ldap.NO_SUCH_OBJECT:
- attempt = attempt + 1
- time.sleep(1)
- except ldap.LDAPError as e:
- log.fatal('Failed to retrieve user (%s): error %s' % (dn, e.message['desc']))
- assert False
- assert attempt != 10
- def test_ticket49073(topology):
- """Write your replication test 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).
- """
- topology.master1.plugins.enable(name=PLUGIN_MEMBER_OF)
- topology.master1.restart(timeout=10)
- topology.master2.plugins.enable(name=PLUGIN_MEMBER_OF)
- topology.master2.restart(timeout=10)
- # Configure fractional to prevent total init to send memberof
- ents = topology.master1.agreement.list(suffix=SUFFIX)
- assert len(ents) == 1
- log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % ents[0].dn)
- topology.master1.modify_s(ents[0].dn,
- [(ldap.MOD_REPLACE,
- 'nsDS5ReplicatedAttributeListTotal',
- '(objectclass=*) $ EXCLUDE '),
- (ldap.MOD_REPLACE,
- 'nsDS5ReplicatedAttributeList',
- '(objectclass=*) $ EXCLUDE memberOf')])
- topology.master1.restart(timeout=10)
- #
- # create some users and a group
- #
- log.info('create users and group...')
- for idx in range(1, 5):
- try:
- USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
- topology.master1.add_s(Entry((USER_DN,
- {'objectclass': 'top extensibleObject'.split(),
- 'uid': 'member%d' % (idx)})))
- except ldap.LDAPError as e:
- log.fatal('Failed to add user (%s): error %s' % (USER_DN, e.message['desc']))
- assert False
- _check_entry_exist(topology.master2, "uid=member4,%s" % (DEFAULT_SUFFIX))
- _add_group_with_members(topology)
- _check_entry_exist(topology.master2, GROUP_DN)
- # Check that for regular update memberof was on both side (because plugin is enabled both)
- time.sleep(5)
- _check_memberof(topology.master1, True)
- _check_memberof(topology.master2, True)
- # reinit with fractional definition
- ents = topology.master1.agreement.list(suffix=SUFFIX)
- assert len(ents) == 1
- topology.master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
- topology.master1.waitForReplInit(ents[0].dn)
- # Check that for total update memberof was on both side
- # because memberof is NOT excluded from total init
- time.sleep(5)
- _check_memberof(topology.master1, True)
- _check_memberof(topology.master2, True)
- if DEBUGGING:
- # Add debugging steps(if any)...
- pass
- if __name__ == '__main__':
- # Run isolated
- # -s for DEBUG mode
- CURRENT_FILE = os.path.realpath(__file__)
- pytest.main("-s %s" % CURRENT_FILE)
|