amoralej / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 years ago
Clone

Blame SOURCES/0025-Ticket-48226-CI-test-added-test-cases-for-ticket-482.patch

a2f18f
From e6b20ffcc995b2ac190b96850073c0569bc6d294 Mon Sep 17 00:00:00 2001
a2f18f
From: Noriko Hosoi <nhosoi@redhat.com>
a2f18f
Date: Thu, 16 Jul 2015 10:41:53 -0700
a2f18f
Subject: [PATCH 25/30] Ticket #48226 - CI test: added test cases for ticket
a2f18f
 48226
a2f18f
a2f18f
Description: In MMR, double free coould occur under some special condition
a2f18f
a2f18f
This test script was written by thierry bordaz <tbordaz@redhat.com>.
a2f18f
A small modification to check the memory leak was added.
a2f18f
a2f18f
(cherry picked from commit f5d24450477f8341261c3e5cb5c54ec1ab83328f)
a2f18f
(cherry picked from commit 8600a5eabc78848ad1bf0a9c2014823d0cd6cedc)
a2f18f
---
a2f18f
 dirsrvtests/tickets/ticket48226_test.py | 239 ++++++++++++++++++++++++++++++++
a2f18f
 1 file changed, 239 insertions(+)
a2f18f
 create mode 100644 dirsrvtests/tickets/ticket48226_test.py
a2f18f
a2f18f
diff --git a/dirsrvtests/tickets/ticket48226_test.py b/dirsrvtests/tickets/ticket48226_test.py
a2f18f
new file mode 100644
a2f18f
index 0000000..87814e7
a2f18f
--- /dev/null
a2f18f
+++ b/dirsrvtests/tickets/ticket48226_test.py
a2f18f
@@ -0,0 +1,239 @@
a2f18f
+# --- BEGIN COPYRIGHT BLOCK ---
a2f18f
+# Copyright (C) 2015 Red Hat, Inc.
a2f18f
+# All rights reserved.
a2f18f
+#
a2f18f
+# License: GPL (version 3 or any later version).
a2f18f
+# See LICENSE for details. 
a2f18f
+# --- END COPYRIGHT BLOCK ---
a2f18f
+#
a2f18f
+import os
a2f18f
+import sys
a2f18f
+import time
a2f18f
+import ldap
a2f18f
+import logging
a2f18f
+import pytest
a2f18f
+from lib389 import DirSrv, Entry, tools, tasks
a2f18f
+from lib389.tools import DirSrvTools
a2f18f
+from lib389._constants import *
a2f18f
+from lib389.properties import *
a2f18f
+from lib389.tasks import *
a2f18f
+from lib389.utils import *
a2f18f
+
a2f18f
+logging.getLogger(__name__).setLevel(logging.DEBUG)
a2f18f
+log = logging.getLogger(__name__)
a2f18f
+
a2f18f
+installation1_prefix = None
a2f18f
+
a2f18f
+
a2f18f
+class TopologyReplication(object):
a2f18f
+    def __init__(self, master1, master2):
a2f18f
+        master1.open()
a2f18f
+        self.master1 = master1
a2f18f
+        master2.open()
a2f18f
+        self.master2 = master2
a2f18f
+
a2f18f
+
a2f18f
+@pytest.fixture(scope="module")
a2f18f
+def topology(request):
a2f18f
+    global installation1_prefix
a2f18f
+    os.environ['USE_VALGRIND'] = '1'
a2f18f
+    if installation1_prefix:
a2f18f
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
a2f18f
+
a2f18f
+    # Creating master 1...
a2f18f
+    master1 = DirSrv(verbose=False)
a2f18f
+    if installation1_prefix:
a2f18f
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
a2f18f
+    args_instance[SER_HOST] = HOST_MASTER_1
a2f18f
+    args_instance[SER_PORT] = PORT_MASTER_1
a2f18f
+    args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
a2f18f
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
a2f18f
+    args_master = args_instance.copy()
a2f18f
+    master1.allocate(args_master)
a2f18f
+    instance_master1 = master1.exists()
a2f18f
+    if instance_master1:
a2f18f
+        master1.delete()
a2f18f
+    master1.create()
a2f18f
+    master1.open()
a2f18f
+    master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1)
a2f18f
+
a2f18f
+    # Creating master 2...
a2f18f
+    master2 = DirSrv(verbose=False)
a2f18f
+    if installation1_prefix:
a2f18f
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
a2f18f
+    args_instance[SER_HOST] = HOST_MASTER_2
a2f18f
+    args_instance[SER_PORT] = PORT_MASTER_2
a2f18f
+    args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
a2f18f
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
a2f18f
+    args_master = args_instance.copy()
a2f18f
+    master2.allocate(args_master)
a2f18f
+    instance_master2 = master2.exists()
a2f18f
+    if instance_master2:
a2f18f
+        master2.delete()
a2f18f
+    master2.create()
a2f18f
+    master2.open()
a2f18f
+    master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
a2f18f
+
a2f18f
+    #
a2f18f
+    # Create all the agreements
a2f18f
+    #
a2f18f
+    # Creating agreement from master 1 to master 2
a2f18f
+    properties = {RA_NAME:      r'meTo_$host:$port',
a2f18f
+                  RA_BINDDN:    defaultProperties[REPLICATION_BIND_DN],
a2f18f
+                  RA_BINDPW:    defaultProperties[REPLICATION_BIND_PW],
a2f18f
+                  RA_METHOD:    defaultProperties[REPLICATION_BIND_METHOD],
a2f18f
+                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
a2f18f
+    m1_m2_agmt = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
a2f18f
+    if not m1_m2_agmt:
a2f18f
+        log.fatal("Fail to create a master -> master replica agreement")
a2f18f
+        sys.exit(1)
a2f18f
+    log.debug("%s created" % m1_m2_agmt)
a2f18f
+
a2f18f
+    # Creating agreement from master 2 to master 1
a2f18f
+    properties = {RA_NAME:      r'meTo_$host:$port',
a2f18f
+                  RA_BINDDN:    defaultProperties[REPLICATION_BIND_DN],
a2f18f
+                  RA_BINDPW:    defaultProperties[REPLICATION_BIND_PW],
a2f18f
+                  RA_METHOD:    defaultProperties[REPLICATION_BIND_METHOD],
a2f18f
+                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
a2f18f
+    m2_m1_agmt = master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
a2f18f
+    if not m2_m1_agmt:
a2f18f
+        log.fatal("Fail to create a master -> master replica agreement")
a2f18f
+        sys.exit(1)
a2f18f
+    log.debug("%s created" % m2_m1_agmt)
a2f18f
+
a2f18f
+    # Allow the replicas to get situated with the new agreements...
a2f18f
+    time.sleep(5)
a2f18f
+
a2f18f
+    #
a2f18f
+    # Initialize all the agreements
a2f18f
+    #
a2f18f
+    master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
a2f18f
+    master1.waitForReplInit(m1_m2_agmt)
a2f18f
+
a2f18f
+    # Check replication is working...
a2f18f
+    if master1.testReplication(DEFAULT_SUFFIX, master2):
a2f18f
+        log.info('Replication is working.')
a2f18f
+    else:
a2f18f
+        log.fatal('Replication is not working.')
a2f18f
+        assert False
a2f18f
+
a2f18f
+    # Clear out the tmp dir
a2f18f
+    master1.clearTmpDir(__file__)
a2f18f
+
a2f18f
+    return TopologyReplication(master1, master2)
a2f18f
+
a2f18f
+def test_ticket11111_set_purgedelay(topology):
a2f18f
+    args = {REPLICA_PURGE_DELAY: '5',
a2f18f
+            REPLICA_PURGE_INTERVAL: '5'}
a2f18f
+    try:
a2f18f
+        topology.master1.replica.setProperties(DEFAULT_SUFFIX, None, None, args)
a2f18f
+    except:
a2f18f
+        log.fatal('Failed to configure replica')
a2f18f
+        assert False
a2f18f
+    try:
a2f18f
+        topology.master2.replica.setProperties(DEFAULT_SUFFIX, None, None, args)
a2f18f
+    except:
a2f18f
+        log.fatal('Failed to configure replica')
a2f18f
+        assert False
a2f18f
+    topology.master1.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-auditlog-logging-enabled', 'on')])
a2f18f
+    topology.master2.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-auditlog-logging-enabled', 'on')])
a2f18f
+    topology.master1.restart(10)
a2f18f
+    topology.master2.restart(10)
a2f18f
+    
a2f18f
+
a2f18f
+def test_ticket11111_1(topology):
a2f18f
+    name = 'test_entry'
a2f18f
+    dn = "cn=%s,%s" % (name, SUFFIX)
a2f18f
+    
a2f18f
+    topology.master1.add_s(Entry((dn , {
a2f18f
+                                            'objectclass': "top person".split(),
a2f18f
+                                            'sn': name,
a2f18f
+                                            'cn': name})))
a2f18f
+                                            
a2f18f
+    # First do an update that is replicated
a2f18f
+    mods = [(ldap.MOD_ADD, 'description', '5')]
a2f18f
+    topology.master1.modify_s(dn, mods)
a2f18f
+    
a2f18f
+    nbtry = 0
a2f18f
+    while (nbtry <= 10):
a2f18f
+        try:
a2f18f
+            ent = topology.master2.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)", ['description'])
a2f18f
+            if ent.hasAttr('description') and ent.getValue('description') == '5':
a2f18f
+                break
a2f18f
+        except ldap.NO_SUCH_OBJECT:
a2f18f
+            pass
a2f18f
+        nbtry = nbtry + 1
a2f18f
+        time.sleep(1)
a2f18f
+    assert nbtry <= 10
a2f18f
+    
a2f18f
+    # Stop M2 so that it will not receive the next update
a2f18f
+    topology.master2.stop(10)
a2f18f
+    
a2f18f
+    # ADD a new value that is not replicated
a2f18f
+    mods = [(ldap.MOD_DELETE, 'description', '5')]
a2f18f
+    topology.master1.modify_s(dn, mods)
a2f18f
+    
a2f18f
+    # Stop M1 so that it will keep del '5' that is unknown from master2
a2f18f
+    topology.master1.stop(10)
a2f18f
+    
a2f18f
+    # Get the sbin directory so we know where to replace 'ns-slapd'
a2f18f
+    sbin_dir = get_sbin_dir(prefix=topology.master2.prefix)
a2f18f
+
a2f18f
+    # Enable valgrind
a2f18f
+    valgrind_enable(sbin_dir)
a2f18f
+
a2f18f
+    # start M2 to do the next updates
a2f18f
+    topology.master2.start(10)
a2f18f
+    
a2f18f
+    # ADD 'description' by '5' 
a2f18f
+    mods = [(ldap.MOD_DELETE, 'description', '5')]
a2f18f
+    topology.master2.modify_s(dn, mods)
a2f18f
+    
a2f18f
+    # DEL 'description' by '5'
a2f18f
+    mods = [(ldap.MOD_ADD, 'description', '5')]
a2f18f
+    topology.master2.modify_s(dn, mods)
a2f18f
+    
a2f18f
+    # sleep of purgedelay so that the next update will purge the CSN_7
a2f18f
+    time.sleep(6)
a2f18f
+    
a2f18f
+    # ADD 'description' by '8' that purge the state info
a2f18f
+    mods = [(ldap.MOD_ADD, 'description', '6')]
a2f18f
+    topology.master2.modify_s(dn, mods)
a2f18f
+
a2f18f
+    if valgrind_check_leak(topology.master2, 'csnset_dup'):
a2f18f
+        log.error('test_csnset_dup: Memory leak is present!')
a2f18f
+    else:
a2f18f
+        log.info('test_csnset_dup: No leak is present!')
a2f18f
+    
a2f18f
+    if valgrind_check_leak(topology.master2, 'Invalid'):
a2f18f
+        log.info('Valgrind reported invalid!')
a2f18f
+    else:
a2f18f
+        log.info('Valgrind is happy!')
a2f18f
+    
a2f18f
+    #log.info("You can attach yourself")
a2f18f
+    #time.sleep(60)
a2f18f
+    
a2f18f
+    # Enable valgrind
a2f18f
+    valgrind_disable(sbin_dir)
a2f18f
+
a2f18f
+    topology.master1.start(10)
a2f18f
+
a2f18f
+    
a2f18f
+def test_ticket11111_final(topology):
a2f18f
+    topology.master1.delete()
a2f18f
+    topology.master2.delete()
a2f18f
+    log.info('Testcase PASSED')
a2f18f
+
a2f18f
+
a2f18f
+def run_isolated():
a2f18f
+    global installation1_prefix
a2f18f
+    installation1_prefix = None
a2f18f
+
a2f18f
+    topo = topology(True)
a2f18f
+    test_ticket11111_set_purgedelay(topo)
a2f18f
+    test_ticket11111_1(topo)
a2f18f
+    
a2f18f
+
a2f18f
+if __name__ == '__main__':
a2f18f
+    run_isolated()
a2f18f
+
a2f18f
-- 
a2f18f
1.9.3
a2f18f