From 7a24286f12ced0576c49c3e92ffccea9e2437e6d Mon Sep 17 00:00:00 2001
From: Akshay Adhikari <aadhikar@redhat.com>
Date: Aug 13 2019 13:17:31 +0000
Subject: Issue 50462 - Fix CI tests


Description: Explicitly changed strings to bytes in upgrade-script(tools.py)
Also Added ds_version check in order it won't break in 1.4.
Added a new replication agreement, and a replication manager. Replication is not
working with service accounts.

related: https://pagure.io/389-ds-base/issue/50462

Reviewed by: Firstyear, vashirov (Thanks!)

---

diff --git a/dirsrvtests/tests/tickets/ticket47462_test.py b/dirsrvtests/tests/tickets/ticket47462_test.py
index 1c26ec7..021fe09 100644
--- a/dirsrvtests/tests/tickets/ticket47462_test.py
+++ b/dirsrvtests/tests/tickets/ticket47462_test.py
@@ -15,8 +15,13 @@ from lib389 import Entry
 from lib389._constants import *
 from lib389.properties import *
 from lib389.topologies import topology_m2
+from lib389.utils import *
+from lib389.replica import BootstrapReplicationManager
+from lib389.plugins import *
+
+pytestmark = [pytest.mark.tier2,
+              pytest.mark.skipif(ds_is_newer('1.4.0'), reason="Upgrade scripts are supported only on versions < 1.4.x")]
 
-pytestmark = pytest.mark.tier2
 
 logging.getLogger(__name__).setLevel(logging.DEBUG)
 log = logging.getLogger(__name__)
@@ -44,76 +49,43 @@ def test_ticket47462(topology_m2):
     #
     # Add an extra attribute to the DES plugin args
     #
-    try:
-        topology_m2.ms["master1"].modify_s(DES_PLUGIN,
-                                           [(ldap.MOD_REPLACE, 'nsslapd-pluginEnabled', 'on')])
-    except ldap.LDAPError as e:
-        log.fatal('Failed to enable DES plugin, error: ' +
-                  e.message['desc'])
-        assert False
-
-    try:
-        topology_m2.ms["master1"].modify_s(DES_PLUGIN,
-                                           [(ldap.MOD_ADD, 'nsslapd-pluginarg2', 'description')])
-    except ldap.LDAPError as e:
-        log.fatal('Failed to reset DES plugin, error: ' +
-                  e.message['desc'])
-        assert False
-
-    try:
-        topology_m2.ms["master1"].modify_s(MMR_PLUGIN,
-                                           [(ldap.MOD_DELETE,
-                                             'nsslapd-plugin-depends-on-named',
-                                             'AES')])
-
-    except ldap.NO_SUCH_ATTRIBUTE:
-        pass
-    except ldap.LDAPError as e:
-        log.fatal('Failed to reset MMR plugin, error: ' +
-                  e.message['desc'])
-        assert False
+    plugin_des = Plugin(topology_m2.ms["master1"], DES_PLUGIN)
+    plugin_des.set('nsslapd-pluginEnabled', 'on')
+    plugin_des.set('nsslapd-pluginarg2', 'description')
 
+    plugin_mmr = Plugin(topology_m2.ms["master1"], MMR_PLUGIN)
+    plugin_mmr.remove('nsslapd-plugin-depends-on-named', 'AES')
     #
     # Delete the AES plugin
     #
-    try:
-        topology_m2.ms["master1"].delete_s(AES_PLUGIN)
-    except ldap.NO_SUCH_OBJECT:
-        pass
-    except ldap.LDAPError as e:
-        log.fatal('Failed to delete AES plugin, error: ' +
-                  e.message['desc'])
-        assert False
-
+    topology_m2.ms["master1"].delete_s(AES_PLUGIN)
     # restart the server so we must use DES plugin
     topology_m2.ms["master1"].restart(timeout=10)
 
-    #
-    # Get the agmt dn, and set the password
-    #
-    try:
-        entry = topology_m2.ms["master1"].search_s('cn=config', ldap.SCOPE_SUBTREE,
-                                                   'objectclass=nsDS5ReplicationAgreement')
-        if entry:
-            agmt_dn = entry[0].dn
-            log.info('Found agmt dn (%s)' % agmt_dn)
-        else:
-            log.fatal('No replication agreements!')
-            assert False
-    except ldap.LDAPError as e:
-        log.fatal('Failed to search for replica credentials: ' +
-                  e.message['desc'])
-        assert False
+    manager = BootstrapReplicationManager(topology_m2.ms["master2"])
 
-    try:
-        properties = {RA_BINDPW: "password"}
-        topology_m2.ms["master1"].agreement.setProperties(None, agmt_dn, None,
-                                                          properties)
-        log.info('Successfully modified replication agreement')
-    except ValueError:
-        log.error('Failed to update replica agreement: ' + AGMT_DN)
-        assert False
+    manager.create(properties={
+                'cn': 'replication manager',
+                'userPassword': 'password'
+    })
+
+    DN = topology_m2.ms["master2"].replica._get_mt_entry(DEFAULT_SUFFIX)
+
+    topology_m2.ms["master2"].modify_s(DN, [(ldap.MOD_REPLACE,
+                                             'nsDS5ReplicaBindDN', ensure_bytes(defaultProperties[REPLICATION_BIND_DN]))])
+    #
+    # Create repl agreement from the newly promoted master to master1
 
+    properties = {RA_NAME: 'meTo_{}:{}'.format(topology_m2.ms["master2"].host,
+                                               str(topology_m2.ms["master2"].port)),
+                  RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
+                  RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
+                  RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
+                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+    topology_m2.ms["master1"].agreement.create(suffix=SUFFIX,
+                                               host=topology_m2.ms["master2"].host,
+                                               port=topology_m2.ms["master2"].port,
+                                               properties=properties)
     #
     # Check replication works with the new DES password
     #
@@ -139,7 +111,7 @@ def test_ticket47462(topology_m2):
         else:
             log.info('Replication test passed')
     except ldap.LDAPError as e:
-        log.fatal('Failed to add test user: ' + e.message['desc'])
+        log.fatal('Failed to add test user: ' + e.args[0]['desc'])
         assert False
 
     #
@@ -148,13 +120,15 @@ def test_ticket47462(topology_m2):
     try:
         topology_m2.ms["master1"].backend.create("o=empty", {BACKEND_NAME: "empty"})
     except ldap.LDAPError as e:
-        log.fatal('Failed to create extra/empty backend: ' + e.message['desc'])
+        log.fatal('Failed to create extra/empty backend: ' + e.args[0]['desc'])
         assert False
 
     #
     # Run the upgrade...
     #
-    topology_m2.ms["master1"].upgrade('online')
+    topology_m2.ms["master1"].stop()
+    topology_m2.ms["master2"].stop()
+    topology_m2.ms["master1"].upgrade('offline')
     topology_m2.ms["master1"].restart()
     topology_m2.ms["master2"].restart()
 
@@ -166,7 +140,7 @@ def test_ticket47462(topology_m2):
                                                    'nsDS5ReplicaCredentials=*')
         if entry:
             val = entry[0].getValue('nsDS5ReplicaCredentials')
-            if val.startswith('{AES-'):
+            if val.startswith(b'{AES-'):
                 log.info('The DES credentials have been converted to AES')
             else:
                 log.fatal('Failed to convert credentials from DES to AES!')
@@ -176,7 +150,7 @@ def test_ticket47462(topology_m2):
             assert False
     except ldap.LDAPError as e:
         log.fatal('Failed to search for replica credentials: ' +
-                  e.message['desc'])
+                  e.args[0]['desc'])
         assert False
 
     #
@@ -196,7 +170,7 @@ def test_ticket47462(topology_m2):
         else:
             log.info('The AES plugin was correctly setup')
     except ldap.LDAPError as e:
-        log.fatal('Failed to find AES plugin: ' + e.message['desc'])
+        log.fatal('Failed to find AES plugin: ' + e.args[0]['desc'])
         assert False
 
     #
@@ -211,7 +185,7 @@ def test_ticket47462(topology_m2):
         else:
             log.info('The MMR plugin was correctly updated')
     except ldap.LDAPError as e:
-        log.fatal('Failed to find AES plugin: ' + e.message['desc'])
+        log.fatal('Failed to find AES plugin: ' + e.args[0]['desc'])
         assert False
 
     #
@@ -226,7 +200,7 @@ def test_ticket47462(topology_m2):
         else:
             log.info('The DES plugin was correctly updated')
     except ldap.LDAPError as e:
-        log.fatal('Failed to find AES plugin: ' + e.message['desc'])
+        log.fatal('Failed to find AES plugin: ' + e.args[0]['desc'])
         assert False
 
     #
@@ -253,7 +227,7 @@ def test_ticket47462(topology_m2):
         else:
             log.info('Replication test passed')
     except ldap.LDAPError as e:
-        log.fatal('Failed to add test user: ' + e.message['desc'])
+        log.fatal('Failed to add test user: ' + e.args[0]['desc'])
         assert False
 
     # Check the entry
@@ -269,7 +243,7 @@ def test_ticket47462(topology_m2):
             assert False
     except ldap.LDAPError as e:
         log.fatal('Failed to search for entries: ' +
-                  e.message['desc'])
+                  e.args[0]['desc'])
         assert False
 
     #
@@ -282,7 +256,7 @@ def test_ticket47462(topology_m2):
                                                 'suffix': DEFAULT_SUFFIX,
                                                 'cn': 'convert'})))
     except ldap.LDAPError as e:
-        log.fatal('Failed to add task entry: ' + e.message['desc'])
+        log.fatal('Failed to add task entry: ' + e.args[0]['desc'])
         assert False
 
     # Wait for task
@@ -300,7 +274,7 @@ def test_ticket47462(topology_m2):
         if entry:
             val = entry[0].getValue('description')
             print(str(entry[0]))
-            if val.startswith('{AES-'):
+            if val.startswith(b'{AES-'):
                 log.info('Task: DES credentials have been converted to AES')
             else:
                 log.fatal('Task: Failed to convert credentials from DES to ' +
@@ -311,7 +285,7 @@ def test_ticket47462(topology_m2):
             assert False
     except ldap.LDAPError as e:
         log.fatal('Failed to search for entries: ' +
-                  e.message['desc'])
+                  e.args[0]['desc'])
         assert False
 
 
diff --git a/dirsrvtests/tests/tickets/ticket48194_test.py b/dirsrvtests/tests/tickets/ticket48194_test.py
index bd069b7..4431ebd 100644
--- a/dirsrvtests/tests/tickets/ticket48194_test.py
+++ b/dirsrvtests/tests/tickets/ticket48194_test.py
@@ -66,11 +66,12 @@ def test_init(topology_st):
                                                 (ldap.MOD_REPLACE, 'nsslapd-ssl-check-hostname', b'off'),
                                                 (ldap.MOD_REPLACE, 'nsslapd-secureport', ensure_bytes(LDAPSPORT))])
 
-    topology_st.standalone.add_s(Entry((RSA_DN, {'objectclass': "top nsEncryptionModule".split(),
-                                                 'cn': RSA,
-                                                 'nsSSLPersonalitySSL': SERVERCERT,
-                                                 'nsSSLToken': 'internal (software)',
-                                                 'nsSSLActivation': 'on'})))
+    if ds_is_older('1.4.0'):
+        topology_st.standalone.add_s(Entry((RSA_DN, {'objectclass': "top nsEncryptionModule".split(),
+                                                     'cn': RSA,
+                                                     'nsSSLPersonalitySSL': SERVERCERT,
+                                                     'nsSSLToken': 'internal (software)',
+                                                     'nsSSLActivation': 'on'})))
 
 
 def connectWithOpenssl(topology_st, cipher, expect):
@@ -87,7 +88,7 @@ def connectWithOpenssl(topology_st, cipher, expect):
     myurl = 'localhost:%s' % LDAPSPORT
     cmdline = ['/usr/bin/openssl', 's_client', '-connect', myurl, '-cipher', cipher]
 
-    strcmdline = '/usr/bin/openssl s_client -connect localhost:%s -cipher %s' % (LDAPSPORT, cipher)
+    strcmdline = " ".join(cmdline)
     log.info("Running cmdline: %s", strcmdline)
 
     try:
diff --git a/src/lib389/lib389/tools.py b/src/lib389/lib389/tools.py
index 919dc85..89423b4 100644
--- a/src/lib389/lib389/tools.py
+++ b/src/lib389/lib389/tools.py
@@ -52,7 +52,8 @@ from lib389.utils import (
     getdefaultsuffix,
     ensure_bytes,
     ensure_str,
-    socket_check_open,)
+    socket_check_open,
+    ds_is_older,)
 from lib389.passwd import password_hash, password_generate
 
 
@@ -862,7 +863,7 @@ class DirSrvTools(object):
                             # We just want to make sure it's in there somewhere
                             if expectedHost in words:
                                 return True
-            except AssertionError:
+            except AssertionError:  
                 raise AssertionError(
                     "Error: %s should contain '%s' host for %s" %
                     ('/etc/hosts', expectedHost, ipPattern))
@@ -903,53 +904,55 @@ class DirSrvTools(object):
 
             /prefix/lib[64]/dirsrv/slapd-INSTANCE/
         '''
-
-        libdir = os.path.join(_ds_paths.lib_dir, 'dirsrv')
-
-        # Gather all the instances so we can adjust the permissions, otherwise
-        servers = []
-        path = os.path.join(_ds_paths.sysconf_dir, 'dirsrv')
-        for files in os.listdir(path):
-            if files.startswith('slapd-') and not files.endswith('.removed'):
-                servers.append(os.path.join(libdir, files))
-
-        if len(servers) == 0:
-            # This should not happen
-            log.fatal('runUpgrade: no servers found!')
-            assert False
-
-        '''
-        The setup script calls things like /lib/dirsrv/slapd-instance/db2bak,
-        etc, and when we run the setup perl script it gets permission denied
-        as the default permissions are 750.  Adjust the permissions to 755.
-        '''
-        for instance in servers:
-            for files in os.listdir(instance):
-                os.chmod(os.path.join(instance, files), 755)
-
-        # Run the "upgrade"
-        try:
-            prog = os.path.join(_ds_paths.sbin_dir, PATH_SETUP_DS)
-            process = subprocess.Popen([prog, '--update'], shell=False,
+        if ds_is_older('1.4.0'):
+            libdir = os.path.join(_ds_paths.lib_dir, 'dirsrv')
+
+            # Gather all the instances so we can adjust the permissions, otherwise
+            servers = []
+            path = os.path.join(_ds_paths.sysconf_dir, 'dirsrv')
+            for files in os.listdir(path):
+                if files.startswith('slapd-') and not files.endswith('.removed'):
+                    servers.append(os.path.join(libdir, files))
+
+            if len(servers) == 0:
+                # This should not happen
+                log.fatal('runUpgrade: no servers found!')
+                assert False
+
+            '''
+            The setup script calls things like /lib/dirsrv/slapd-instance/db2bak,
+            etc, and when we run the setup perl script it gets permission denied
+            as the default permissions are 750.  Adjust the permissions to 755.
+            '''
+            for instance in servers:
+                for files in os.listdir(instance):
+                    os.chmod(os.path.join(instance, files), 755)
+
+            # Run the "upgrade"
+            try:
+                prog = os.path.join(_ds_paths.sbin_dir, PATH_SETUP_DS)
+                process = subprocess.Popen([prog, '--update'], shell=False,
                                        stdin=subprocess.PIPE)
-            # Answer the interactive questions, as "--update" currently does
-            # not work with INF files
-            process.stdin.write('yes\n')
-            if(online):
-                process.stdin.write('online\n')
-                for x in servers:
-                    process.stdin.write(DN_DM + '\n')
-                    process.stdin.write(PW_DM + '\n')
-            else:
-                process.stdin.write('offline\n')
-            process.stdin.close()
-            process.wait()
-            if process.returncode != 0:
-                log.fatal('runUpgrade failed!  Error: %s ' % process.returncode)
-                assert(False)
-        except:
-            log.fatal('runUpgrade failed!')
-            raise
+                # Answer the interactive questions, as "--update" currently does
+                # not work with INF files
+                process.stdin.write(b'yes\n')
+                if(online):
+                    process.stdin.write(b'online\n')
+                    for x in servers:
+                        process.stdin.write(ensure_bytes(DN_DM + '\n'))
+                        process.stdin.write(ensure_bytes(PW_DM + '\n'))
+                else:
+                    process.stdin.write(b'offline\n')
+                process.stdin.close()
+                process.wait()
+                if process.returncode != 0:
+                    log.fatal('runUpgrade failed!  Error: %s ' % process.returncode)
+                    assert(False)
+            except:
+                log.fatal('runUpgrade failed!')
+                raise
+        else:
+            pass
 
     @staticmethod
     def searchFile(filename, pattern):

