import logging
import pytest
import os
import ldap
import time
import sys
print(sys.path)
from lib389 import Entry
from lib389._constants import DEFAULT_SUFFIX
from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
from lib389.topologies import topology_m3 as topo

DEBUGGING = os.getenv("DEBUGGING", default=False)
if DEBUGGING:
    logging.getLogger(__name__).setLevel(logging.DEBUG)
else:
    logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)


MAX_EMPLOYEENUMBER_USER = 10
MAX_STANDARD_USER = 100
MAX_USER = MAX_STANDARD_USER + MAX_EMPLOYEENUMBER_USER
EMPLOYEENUMBER_RDN_START = 10000

USER_UID='user_'

def _user_get_dn(no):
    uid = '%s%d' % (USER_UID, no)
    dn = 'uid=%s,ou=people,%s' % (uid, DEFAULT_SUFFIX)
    return (uid, dn)

def add_user(server, no, init_val):
    (uid, dn) = _user_get_dn(no)
    log.fatal('Adding user (%s): ' % dn)
    server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson'],
                             'uid': [uid],
                             'sn' : [uid],
                             'cn' : [uid],
                             'employeeNumber': init_val})))
    return dn

def _employeenumber_user_get_dn(no):
    employeeNumber = str(no)
    dn = 'employeeNumber=%s,ou=people,%s' % (employeeNumber, DEFAULT_SUFFIX)
    return (employeeNumber, dn)

def add_employeenumber_user(server, no):
    (uid, dn) = _employeenumber_user_get_dn(EMPLOYEENUMBER_RDN_START + no)
    log.fatal('Adding user (%s): ' % dn)
    server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson'],
                             'uid': [uid],
                             'sn' : [uid],
                             'cn' : [uid],
                             'employeeNumber': str(EMPLOYEENUMBER_RDN_START + no)})))
    return dn

def save_stuff():
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_11 = '11'.encode()
    value_1000 = '1000'.encode()
    value_13 = '13'.encode()
    value_14 = '14'.encode()
    
    # Step 2
    test_user_dn= add_user(M3, 0, value_11)
    log.info('Adding %s on M3' % test_user_dn)
    M3.modify_s(test_user_dn, [(ldap.MOD_DELETE, 'employeeNumber', value_11), (ldap.MOD_ADD, 'employeeNumber', value_1000)])
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == 1
    
    
    # Step 3
    # Check the entry is replicated on M1
    for j in range(30):
            try:
                ent = M1.getEntry(test_user_dn, ldap.SCOPE_BASE,)
                if not ent.hasAttr('employeeNumber'):
                    # wait for the MOD
                    log.info('M1 waiting for employeeNumber')
                    time.sleep(1)
                    continue;
                break;
            except ldap.NO_SUCH_OBJECT:
                time.sleep(1)
                pass
    time.sleep(1)
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == 1
                
    # Check the entry is replicated on M2
    for j in range(30):
            try:
                ent = M2.getEntry(test_user_dn, ldap.SCOPE_BASE,)
                if not ent.hasAttr('employeeNumber'):
                    # wait for the MOD
                    log.info('M2 waiting for employeeNumber')
                    time.sleep(1)
                    continue;

                break;
            except ldap.NO_SUCH_OBJECT:
                time.sleep(1)
                pass
    time.sleep(1)
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == 1
    
def test_ticket49658_init(topo):
    """Specify a test case purpose or name here

    :id: 0
    :setup: 3 Master Instances
    :steps:
        1. Create 3 suppliers
        2. Create on M3 MAX_USER test entries having a single-value attribute employeeNumber=11
            and update it MOD_DEL 11 + MOD_ADD 1000
        3. Check they are replicated on M1 and M2
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_11 = '11'.encode()
    value_1000 = '1000'.encode()
    
    # Step 2
    for i in range(MAX_EMPLOYEENUMBER_USER):
        test_user_dn= add_employeenumber_user(M3, i)
        log.info('Adding %s on M3' % test_user_dn)
        ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
        assert len(ents) == (i + 1)
        
    for i in range(MAX_STANDARD_USER):
        test_user_dn= add_user(M3, i, value_11)
        log.info('Adding %s on M3' % test_user_dn)
        M3.modify_s(test_user_dn, [(ldap.MOD_DELETE, 'employeeNumber', value_11), (ldap.MOD_ADD, 'employeeNumber', value_1000)])
        ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
        assert len(ents) == (MAX_EMPLOYEENUMBER_USER + i + 1)
    
    
    # Step 3
    # Check the last entry is replicated on M1
    (uid, test_user_dn) = _user_get_dn(MAX_STANDARD_USER - 1)
    for j in range(30):
            try:
                ent = M1.getEntry(test_user_dn, ldap.SCOPE_BASE,)
                if not ent.hasAttr('employeeNumber'):
                    # wait for the MOD
                    log.info('M1 waiting for employeeNumber')
                    time.sleep(1)
                    continue;
                break;
            except ldap.NO_SUCH_OBJECT:
                time.sleep(1)
                pass
    time.sleep(1)
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
                
    # Check the last entry is replicated on M2
    for j in range(30):
            try:
                ent = M2.getEntry(test_user_dn, ldap.SCOPE_BASE,)
                if not ent.hasAttr('employeeNumber'):
                    # wait for the MOD
                    log.info('M2 waiting for employeeNumber')
                    time.sleep(1)
                    continue;

                break;
            except ldap.NO_SUCH_OBJECT:
                time.sleep(1)
                pass
    time.sleep(1)
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER

def test_ticket49658_0(topo):
    """Do MOD(DEL+ADD) and replicate MOST RECENT first
        M1: MOD(DEL+ADD)      -> V1
        M2: MOD(DEL+ADD)      -> V1
        expected: V1

    :id: 0
    :setup: 3 Master Instances
        1. using user_0 where employNumber=1000
    :steps:
        1. Create 3 suppliers
        2. Isolate M1 and M2 by pausing the replication agreements
        3. On M1 do MOD_DEL 1000 + MOD_ADD_13
        4. On M2 do MOD_DEL 1000 + MOD_ADD_13
        5. Enable replication agreement M2 -> M3, so that update step 6 is replicated first
        6. Enable replication agreement M1 -> M3, so that update step 5 is replicated second
        7. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'.encode()
    last = '0'
    value_end = last.encode()
    theFilter = '(employeeNumber=%s)' % last
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 2
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 3
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    M1.modify_s(test_user_dn, [(ldap.MOD_DELETE, 'employeeNumber', value_1000), (ldap.MOD_ADD, 'employeeNumber', value_end)])
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 4
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M2.modify_s(test_user_dn, [(ldap.MOD_DELETE, 'employeeNumber', value_1000), (ldap.MOD_ADD, 'employeeNumber', value_end)])
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
        
def test_ticket49658_1(topo):
    """Do MOD(DEL+ADD) and replicate OLDEST first
        M2: MOD(DEL+ADD)      -> V1
        M1: MOD(DEL+ADD)      -> V1
        expected: V1

    :id: 1
    :setup: 3 Master Instances
        1. using user_1 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M2 do MOD_DEL 1000 + MOD_ADD_13
        3. On M1 do MOD_DEL 1000 + MOD_ADD_13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'.encode()
    last = '1'
    value_end = last.encode()
    theFilter = '(employeeNumber=%s)' % last
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(1))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M2.modify_s(test_user_dn, [(ldap.MOD_DELETE, 'employeeNumber', value_1000), (ldap.MOD_ADD, 'employeeNumber', value_end)])
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M1.modify_s(test_user_dn, [(ldap.MOD_DELETE, 'employeeNumber', value_1000), (ldap.MOD_ADD, 'employeeNumber', value_end)])
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end

def test_ticket49658_2(topo):
    """Do MOD(ADD+DEL) and replicate OLDEST first
        M2: MOD(ADD+DEL)      -> V1
        M1: MOD(ADD+DEL)      -> V1
        expected: V1

    :id: 2
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M2 do MOD_DEL 1000 + MOD_ADD_13
        3. On M1 do MOD_DEL 1000 + MOD_ADD_13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'.encode()
    last = '2'
    value_end = last.encode()
    theFilter = '(employeeNumber=%s)' % last
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M2.modify_s(test_user_dn, [(ldap.MOD_ADD, 'employeeNumber', value_end),(ldap.MOD_DELETE, 'employeeNumber', value_1000)])
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M1.modify_s(test_user_dn, [(ldap.MOD_ADD, 'employeeNumber', value_end), (ldap.MOD_DELETE, 'employeeNumber', value_1000)])
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end

def test_ticket49658_3(topo):
    """Do MOD(ADD+DEL) and replicate MOST RECENT first
        M1: MOD(ADD+DEL)      -> V1
        M2: MOD(ADD+DEL)      -> V1
        expected: V1
    :id: 3
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_DEL 1000 + MOD_ADD_13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'.encode()
    last = '3'
    value_end = last.encode()
    theFilter = '(employeeNumber=%s)' % last
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    M1.modify_s(test_user_dn, [(ldap.MOD_ADD, 'employeeNumber', value_end),(ldap.MOD_DELETE, 'employeeNumber', value_1000)])
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M2.modify_s(test_user_dn, [(ldap.MOD_ADD, 'employeeNumber', value_end), (ldap.MOD_DELETE, 'employeeNumber', value_1000)])
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
def test_ticket49658_4(topo):
    """Do MOD(ADD+DEL) MOD(REPL) and replicate MOST RECENT first
        M1: MOD(ADD+DEL)      -> V1
        M2: MOD(REPL)      -> V1
        expected: V1

    :id: 4
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_REPL _13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'.encode()
    last = '4'
    value_end = last.encode()
    theFilter = '(employeeNumber=%s)' % last
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    M1.modify_s(test_user_dn, [(ldap.MOD_ADD, 'employeeNumber', value_end),(ldap.MOD_DELETE, 'employeeNumber', value_1000)])
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M2.modify_s(test_user_dn, [(ldap.MOD_REPLACE, 'employeeNumber', value_end)])
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
def test_ticket49658_5(topo):
    """Do MOD(REPL) MOD(ADD+DEL) and replicate MOST RECENT first
        M1: MOD(REPL)         -> V1
        M2: MOD(ADD+DEL)      -> V1
        expected: V1
    :id: 5
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_REPL _13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'.encode()
    last = '5'
    value_end = last.encode()
    theFilter = '(employeeNumber=%s)' % last
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    M1.modify_s(test_user_dn, [(ldap.MOD_REPLACE, 'employeeNumber', value_end)])
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    M2.modify_s(test_user_dn, [(ldap.MOD_ADD, 'employeeNumber', value_end),(ldap.MOD_DELETE, 'employeeNumber', value_1000)])
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, theFilter)
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), value_end))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == value_end
    
def test_ticket49658_6(topo):
    """Do 
        M1: MOD(REPL)    -> V1
        M2: MOD(ADD+DEL) -> V2
        expected: V2

    :id: 6
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_REPL _13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '6'
    value_S1 = '6.1'
    value_S2 = '6.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_ADD, 'employeeNumber', value_S2.encode()),(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode())],
    "expected": value_S2}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()

def test_ticket49658_7(topo):
    """Do 
        M1: MOD(ADD+DEL)    -> V1
        M2: MOD(REPL)       -> V2
        expected: V2

    :id: 7
    :setup: 3 Master Instances
    :steps:
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '7'
    value_S1 = '7.1'
    value_S2 = '7.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_ADD, 'employeeNumber', value_S1.encode()),(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode())],
    "S2_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S2.encode())],
    "expected": value_S2}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
def test_ticket49658_8(topo):
    """Do 
        M1: MOD(DEL+ADD)    -> V1
        M2: MOD(REPL)       -> V2
        expected: V2

    :id: 8
    :setup: 3 Master Instances
    :steps:
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '8'
    value_S1 = '8.1'
    value_S2 = '8.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode()),(ldap.MOD_ADD, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S2.encode())],
    "expected": value_S2}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    

def test_ticket49658_9(topo):
    """Do 
        M1: MOD(REPL)         -> V1
        M2: MOD(DEL+ADD)      -> V2
        expected: V2

    :id: 9
    :setup: 3 Master Instances
    :steps:
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '9'
    value_S1 = '9.1'
    value_S2 = '9.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode()),(ldap.MOD_ADD, 'employeeNumber', value_S2.encode())],
    "expected": value_S2}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    


def test_ticket49658_10(topo):
    """Do 
        M1: MOD(REPL)         -> V1
        M2: MOD(REPL)         -> V2
        expected: V2

    :id: 10
    :setup: 3 Master Instances
    :steps:
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '10'
    value_S1 = '10.1'
    value_S2 = '10.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S2.encode())],
    "expected": value_S2}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    
 
def test_ticket49658_11(topo):
    """Do 
        M2: MOD(REPL)         -> V2
        M1: MOD(REPL)         -> V1
        expected: V1

    :id: 11
    :setup: 3 Master Instances
    :steps:
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '11'
    value_S1 = '11.1'
    value_S2 = '11.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S2.encode())],
    "expected": value_S1}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
def test_ticket49658_12(topo):
    """Do 
        M2: MOD(ADD+DEL) -> V2
        M1: MOD(REPL)    -> V1
        expected: V1

    :id: 12
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_REPL _13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '12'
    value_S1 = '12.1'
    value_S2 = '12.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_ADD, 'employeeNumber', value_S2.encode()),(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode())],
    "expected": value_S1}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()

def test_ticket49658_13(topo):
    """Do 
        M2: MOD(DEL+ADD) -> V2
        M1: MOD(REPL)    -> V1
        expected: V1

    :id: 13
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_REPL _13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '13'
    value_S1 = '13.1'
    value_S2 = '13.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_REPLACE, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode()),(ldap.MOD_ADD, 'employeeNumber', value_S2.encode())],
    "expected": value_S1}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    
def test_ticket49658_14(topo):
    """Do 
        M2: MOD(DEL+ADD)    -> V2
        M1: MOD(DEL+ADD)    -> V1
        expected: V1

    :id: 14
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_REPL _13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '14'
    value_S1 = '14.1'
    value_S2 = '14.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode()),(ldap.MOD_ADD, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode()),(ldap.MOD_ADD, 'employeeNumber', value_S2.encode())],
    "expected": value_S1}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()

def test_ticket49658_15(topo):
    """Do 
        M2: MOD(ADD+DEL)    -> V2
        M1: MOD(DEL+ADD)    -> V1
        expected: V1

    :id: 15
    :setup: 3 Master Instances
        1. using user_2 where employNumber=1000
    :steps:
        1. Isolate M1 and M2 by pausing the replication agreements
        2. On M1 do MOD_DEL 1000 + MOD_ADD_13
        3. On M2 do MOD_REPL _13
        4. Enable replication agreement M2 -> M3, so that update step 2 is replicated first
        5. Enable replication agreement M1 -> M3, so that update step 3 is replicated second
        6. Check that the employeeNumber is 13 on all servers
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
    


    if DEBUGGING:
        # Add debugging steps(if any)...
        pass
    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    M3 = topo.ms["master3"]
    value_1000 = '1000'
    last = '15'
    value_S1 = '15.1'
    value_S2 = '15.2'
    
    description = {
    "S1": M1,
    "S2": M2,
    "S1_MOD": [(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode()),(ldap.MOD_ADD, 'employeeNumber', value_S1.encode())],
    "S2_MOD": [(ldap.MOD_ADD, 'employeeNumber', value_S2.encode()),(ldap.MOD_DELETE, 'employeeNumber', value_1000.encode())],
    "expected": value_S1}
    
    # This test takes the user_1
    (uid, test_user_dn) = _user_get_dn(int(last))
    
    #
    # Step 4
    #
    # disable all RA from M1 and M2
    # only M3 can replicate the update
    #
    agreement_m1_m2 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M2.host, consumer_port=M2.port)
    agreement_m1_m3 = M1.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    agreement_m2_m1 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M1.host, consumer_port=M1.port)
    agreement_m2_m3 = M2.agreement.list(suffix=DEFAULT_SUFFIX, consumer_host=M3.host, consumer_port=M3.port)
    
    M1.agreement.pause(agreement_m1_m2[0].dn)
    M1.agreement.pause(agreement_m1_m3[0].dn)
    M2.agreement.pause(agreement_m2_m1[0].dn)
    M2.agreement.pause(agreement_m2_m3[0].dn)

    # Step 5
    # Oldest update
    # check that the entry on M1 contains employeeNumber=<value_end>
    description["S2"].modify_s(test_user_dn, description["S2_MOD"])
    ents = description["S2"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S2)
    assert len(ents) == 1
    time.sleep(1)
    
    # Step 6
    # More recent update
    # check that the entry on M2 contains employeeNumber=<value_end>
    description["S1"].modify_s(test_user_dn, description["S1_MOD"])
    ents = description["S1"].search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % value_S1)
    assert len(ents) == 1

    #time.sleep(60)
    # Step 7
    # Renable M2 before M1 so that on M3, the most recent update is replicated before
    for ra in agreement_m2_m1, agreement_m2_m3:
        M2.agreement.resume(ra[0].dn)
        
    # Step 8
    # Renable M1 so that on M3 oldest update is now replicated
    time.sleep(4)
    for ra in agreement_m1_m2, agreement_m1_m3:
        M1.agreement.resume(ra[0].dn)
    
    # Step 9
    # Check that M1 still contains employeeNumber=<value_end>
    ents = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M1 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
        
    # Check that M2 still contains employeeNumber=<value_end>
    ents = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M2 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()
    
    # Check that M3 still contain employeeNumber and it contains employeeNumber=<value_end>
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=*)')
    assert len(ents) == MAX_USER
    ents = M3.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(employeeNumber=%s)' % description["expected"])
    log.info('Search M3 employeeNumber=%s (vs. %s)' % (ents[0].getValue('employeeNumber'), description["expected"]))
    assert len(ents) == 1
    assert ents[0].hasAttr('employeeNumber') and ents[0].getValue('employeeNumber') == description["expected"].encode()







if __name__ == '__main__':
    # Run isolated
    # -s for DEBUG mode
    CURRENT_FILE = os.path.realpath(__file__)
    pytest.main(["-s", CURRENT_FILE])

