From 99313068d69d346d9174afc64ea92f77611ae3fa Mon Sep 17 00:00:00 2001
From: Sankar Ramalingam <sramling@redhat.com>
Date: Wed, 20 Sep 2017 17:39:00 +0530
Subject: [PATCH] Ticket #48085 - CI tests - replication ruvstore

Description: Adding ruvstore tests for replication. Test cases check
if RUV details are backed up correctly and other test case checks, if
memoryruv and databaseruv are synced.

https://pagure.io/389-ds-base/issue/48085

Reviewed by: ?
---
 .../tests/suites/replication/ruvstore_test.py      | 160 +++++++++++++++++++++
 1 file changed, 160 insertions(+)
 create mode 100755 dirsrvtests/tests/suites/replication/ruvstore_test.py

diff --git a/dirsrvtests/tests/suites/replication/ruvstore_test.py b/dirsrvtests/tests/suites/replication/ruvstore_test.py
new file mode 100755
index 000000000..6baf85078
--- /dev/null
+++ b/dirsrvtests/tests/suites/replication/ruvstore_test.py
@@ -0,0 +1,160 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2017 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import logging
+import ldap
+import pytest
+from ldif import LDIFParser
+from lib389.replica import Replicas
+from lib389.idm.user import UserAccounts
+from lib389.topologies import topology_m2 as topo
+from lib389._constants import *
+
+TEST_ENTRY_NAME = 'rep2lusr'
+NEW_RDN_NAME = 'ruvusr'
+ATTRIBUTES = ['objectClass', 'nsUniqueId', 'nsds50ruv', 'nsruvReplicaLastModified']
+USER_PROPERTIES = {
+    'uid': TEST_ENTRY_NAME,
+    'cn': TEST_ENTRY_NAME,
+    'sn': TEST_ENTRY_NAME,
+    'uidNumber': '1001',
+    'gidNumber': '2001',
+    'userpassword': PASSWORD,
+    'description': 'userdesc',
+    'homeDirectory': '/home/testuser'
+}
+
+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__)
+
+
+class MyLDIF(LDIFParser):
+    def __init__(self, input):
+        LDIFParser.__init__(self, input)
+
+    def handle(self, dn, entry):
+        if 'nsuniqueid=' + REPLICA_RUV_UUID in dn:
+            for attr in ATTRIBUTES:
+                assert entry.get(attr), 'Failed to find attribute: {}'.format(attr)
+                log.info('Attribute found in RUV: {}'.format(attr))
+
+
+def _perform_ldap_operations(topo):
+    """Add a test user, modify description, modrdn user and delete it"""
+
+    users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX)
+    log.info('Adding user to master1')
+    tuser = users.create(properties=USER_PROPERTIES)
+    tuser.replace('description', 'newdesc')
+    log.info('Modify RDN of user: {}'.format(tuser.dn))
+    try:
+        topo.ms['master1'].modrdn_s(tuser.dn, 'uid={}'.format(NEW_RDN_NAME), 0)
+    except ldap.LDAPError as e:
+        log.fatal('Failed to modrdn entry: {}'.format(tuser.dn))
+        raise e
+    tuser = users.get(NEW_RDN_NAME)
+    log.info('Deleting user: {}'.format(tuser.dn))
+    tuser.delete()
+
+
+def _compare_memoryruv_and_databaseruv(topo, operation_type):
+    """Compare the memoryruv and databaseruv for ldap operations"""
+
+    log.info('Checking memory ruv for ldap: {} operation'.format(operation_type))
+    replicas = Replicas(topo.ms['master1'])
+    replica = replicas.list()[0]
+    memory_ruv = replica.get_attr_val_utf8('nsds50ruv')
+
+    log.info('Checking database ruv for ldap: {} operation'.format(operation_type))
+    entry = replicas.get_ruv_entry(DEFAULT_SUFFIX)
+    database_ruv = entry.getValues('nsds50ruv')[0]
+    assert memory_ruv == database_ruv
+
+
+def test_ruv_entry_backup(topo):
+    """Check if db2ldif stores the RUV details in the backup file
+
+    :id: cbe2c473-8578-4caf-ac0a-841140e41e66
+    :setup: Replication with two masters.
+    :steps: 1. Add user to server.
+            2. Perform ldap modify, modrdn and delete operations.
+            3. Stop the server and backup the database using db2ldif task.
+            4. Start the server and check if correct RUV is stored in the backup file.
+    :expectedresults:
+            1. Add user should PASS.
+            2. Ldap operations should PASS.
+            3. Database backup using db2ldif task should PASS.
+            4. Backup file should contain the correct RUV details.
+    """
+
+    log.info('LDAP operations add, modify, modrdn and delete')
+    _perform_ldap_operations(topo)
+
+    output_file = os.path.join(topo.ms['master1'].get_ldif_dir(), 'master1.ldif')
+    log.info('Stopping the server instance to run db2ldif task to create backup file')
+    topo.ms['master1'].stop()
+    topo.ms['master1'].db2ldif(bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX], excludeSuffixes=[],
+                               encrypt=False, repl_data=True, outputfile=output_file)
+    log.info('Starting the server after backup')
+    topo.ms['master1'].start()
+
+    log.info('Checking if backup file contains RUV and required attributes')
+    with open(output_file, 'r') as ldif_file:
+        parser = MyLDIF(ldif_file)
+        parser.parse()
+
+
+def test_memoryruv_sync_with_databaseruv(topo):
+    """Check if memory ruv and database ruv are synced
+
+    :id: 5f38ac5f-6353-460d-bf60-49cafffda5b3
+    :setup: Replication with two masters.
+    :steps: 1. Add user to server and compare memory ruv and database ruv.
+            2. Modify description of user and compare memory ruv and database ruv.
+            3. Modrdn of user and compare memory ruv and database ruv.
+            4. Delete user and compare memory ruv and database ruv.
+    :expectedresults:
+            1. For add user, the memory ruv and database ruv should be the same.
+            2. For modify operation, the memory ruv and database ruv should be the same.
+            3. For modrdn operation, the memory ruv and database ruv should be the same.
+            4. For delete operation, the memory ruv and database ruv should be the same.
+    """
+
+    log.info('Adding user: {} to master1'.format(TEST_ENTRY_NAME))
+    users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX)
+    tuser = users.create(properties=USER_PROPERTIES)
+    _compare_memoryruv_and_databaseruv(topo, 'add')
+
+    log.info('Modify user: {} description'.format(TEST_ENTRY_NAME))
+    tuser.replace('description', 'newdesc')
+    _compare_memoryruv_and_databaseruv(topo, 'modify')
+
+    log.info('Modify RDN of user: {}'.format(tuser.dn))
+    try:
+        topo.ms['master1'].modrdn_s(tuser.dn, 'uid={}'.format(NEW_RDN_NAME), 0)
+    except ldap.LDAPError as e:
+        log.fatal('Failed to modrdn entry: {}'.format(tuser.dn))
+        raise e
+    _compare_memoryruv_and_databaseruv(topo, 'modrdn')
+
+    tuser = users.get(NEW_RDN_NAME)
+    log.info('Delete user: {}'.format(tuser.dn))
+    tuser.delete()
+    _compare_memoryruv_and_databaseruv(topo, 'delete')
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main('-s {}'.format(CURRENT_FILE))
-- 
2.13.5

