Hi David,

After quite a while and some more struggles here comes the updated
version of the patch together with other patches fixing things in
ipatests/test_integration/tasks.py
Server and replica installation was refactored in a way to utilize the
code from tasks.py as much as it is possible

The full set of necessary patches is attached


On 04/20/2016 10:35 AM, David Kupka wrote:
> On 19/04/16 11:13, Oleg Fayans wrote:
>> OK, that one, though passing lint, did not actually work. I gave up my
>> attempts to define method decorators inside the class. Now it passes
>> lint AND works:)
>>
> 
> Hi Oleg!
> 
> 1) Current commit message is useless. Please use it to describe what is
> the point of the patch.
> 
> 2) $ git show -U0 | pep8 --diff
> ./ipatests/test_integration/test_caless.py:66:1: E302 expected 2 blank
> lines, found 1
> ./ipatests/test_integration/test_caless.py:74:1: E302 expected 2 blank
> lines, found 1
> ./ipatests/test_integration/test_caless.py:820:5: E303 too many blank
> lines (2)
> ./ipatests/test_integration/test_caless.py:825:80: E501 line too long
> (80 > 79 characters)
> ./ipatests/test_integration/test_caless.py:1035:44: E225 missing
> whitespace around operator
> 
> 
> 3) Isn't there a way to do this with pytest's fixtures?
> 
>> +def server_install_teardown(func):
>> +    def wrapped(*args):
>> +        try:
>> +            func(*args)
>> +        finally:
>> +            args[0].uninstall_server()
>> +    return wrapped
>> +
>> +def replica_install_teardown(func):
>> +    def wrapped(*args):
>> +        try:
>> +            func(*args)
>> +        finally:
>> +            # Uninstall replica
>> +            replica = args[0].replicas[0]
>> +            tasks.kinit_admin(args[0].master)
>> +            args[0].uninstall_server(replica)
>> +            args[0].master.run_command(['ipa-replica-manage', 'del',
>> +                                        replica.hostname, '--force'],
>> +                                       raiseonerr=False)
>> +            args[0].master.run_command(['ipa', 'host-del',
>> +                                        replica.hostname],
>> +                                       raiseonerr=False)
>> +    return wrapped
>> +

There is a standard pytest method called 'method_teardown', that is
indent to be executed after each test method, but with our setup it does
not work.

> 
> 4) Is it necessary to create the $TEST_DIR in the test? Isn't it created
> by the framework?
> 
>> +            host.transport.mkdir_recursive(host.config.test_dir)
> 

Removed.

> 
> 5) I don't think the comment match the code.
> 
>>
>> +        # Remove CA cert in /etc/pki/nssdb, in case of failed
>> (un)install
>> +        for host in cls.get_all_hosts():
>> +            cls.uninstall_server(host)
>> +
>>           super(CALessBase, cls).uninstall(mh)
> 

Not actual anymore

> 
> 6) No! Create list with one element, iterate that list and append every
> item to the other list. Maybe there's better way (Hint: append).
> I've seen this on multiple places.
> 
>>           if unattended:
>>               args.extend(['-U'])

Agreed

> 
> 7) Why don't you (extend and) use
> ipatests.test_integaration.tasks.(un)install_{master,replica}?
> This could be done pretty much all over the code.
> 
>>           host.run_command(['ipa-server-install', '--uninstall', '-U'])
> 
> 8) Use ipaplatform.paths for certutil and other binaries. If the binary
> is not there feel free to add it.
> I've seen this on multiple places.
> 
>> +        host.run_command(['certutil', '-d', paths.NSS_DB_DIR, '-D',
>> +                          '-n', 'External CA cert'],
>> +                         raiseonerr=False)
>> +        # A workaround forhttps://fedorahosted.org/freeipa/ticket/4639
>> +        result = host.run_command(['certutil', '-L', '-d',
>> +                                   paths.HTTPD_ALIAS_DIR])
>> +        for rawcert in result.stdout_text.split('\n')[4: -1]:
>> +            cert = rawcert.split('    ')[0]
>> +            host.run_command(['certutil', '-D', '-d',
>> paths.HTTPD_ALIAS_DIR,
>> +                              '-n', cert])
>>

Done

> 
> 9) certmonger is system service. You can check if is is .enabled() and
> .running(). And IIUC the comment is negation of what the code does.
> 
>>
>>               # Verify certmonger was not started
>>               result = host.run_command(['getcert', 'list'],
>> raiseonerr=False)
>> -            assert result > 0
>> -            assert ('Please verify that the certmonger service has
>> been '
>> -                    'started.' in result.stdout_text),
>> result.stdout_text
>> +            assert result.returncode == 0
> 
> 10) What is the point of calling uninstall_server() when it will be
> called in the finally block of server_install_teardown anyway?
> 
>> +    @server_install_teardown
>>       def test_revoked_http(self):
>>           "IPA server install with revoked HTTP certificate"
>>
>>           if result.returncode == 0:
>> +            self.uninstall_server()
>>               raise nose.SkipTest(
>>                   "Known CA-less installation defect, see "
>>                   +"https://fedorahosted.org/freeipa/ticket/4270";)
>>
>>           assert result.returncode > 0
>>
Removed

> 
> Nitpick) Do not mix fixing typos/grammar/spelling/style with functional
> changes.
> 
>> -    def test_incorect_http_pin(self):
>> +    @pytest.mark.xfail(reason='freeipa ticket 5378')
>> +    def test_incorrect_http_pin(self):
>>          "Install new HTTP certificate with incorrect PKCS#12 password"

Removed

> 
> 

-- 
Oleg Fayans
Quality Engineer
FreeIPA team
RedHat.
From a773c297f37340f36cf257a2b5b75eb8199bd47d Mon Sep 17 00:00:00 2001
From: Oleg Fayans <ofay...@redhat.com>
Date: Tue, 8 Dec 2015 10:49:18 +0100
Subject: [PATCH] Updated the script creating test certificate chains

https://fedorahosted.org/freeipa/ticket/4589
---
 .../test_integration/scripts/caless-create-pki     | 29 ++++++++++++++--------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/ipatests/test_integration/scripts/caless-create-pki b/ipatests/test_integration/scripts/caless-create-pki
index f428ebae16e05644a875a35faf192f75eb149740..4c37077ffdecfb0c70663c7c4817f102154d3b26 100644
--- a/ipatests/test_integration/scripts/caless-create-pki
+++ b/ipatests/test_integration/scripts/caless-create-pki
@@ -3,7 +3,17 @@
 profile_ca=(-t CT,C,C -v 120)
 profile_server=(-t ,, -v 12)
 
-crl_path=${crl_path-$(readlink -f $dbdir)}
+# crl_path=${crl_path-$(readlink -f $dbdir)}
+profile_ca_request_options=(-1 -2 -4)
+profile_ca_request_input="\$'0\n1\n5\n6\n9\ny\ny\n\ny\n1\n7\nfile://'\$(readlink -f \$dbdir)/\$ca.crl\$'\n-1\n-1\n-1\nn\nn\n'"
+profile_ca_create_options=(-v 120)
+profile_ca_add_options=(-t ,,)
+
+profile_server_request_options=(-4)
+profile_server_request_input="\$'1\n7\nfile://'\$(readlink -f \$dbdir)/\$ca.crl\$'\n-1\n-1\n-1\nn\nn\n'"
+profile_server_create_options=(-v 12)
+profile_server_add_options=(-t ,,)
+
 
 serial_number=0
 
@@ -18,7 +28,11 @@ gen_cert() {
         ca="$nick"
     fi
 
+    echo $profile
     eval "options=(\"\${profile_$profile[@]}\")"
+    eval "request_options=(\"\${profile_${profile}_request_options[@]}\")"
+    eval "eval request_input=(\"\${profile_${profile}_request_input[@]}\")"
+
     if [ "$ca" = "$nick" ]; then
         options=("${options[@]}" -x -m 1)
     else
@@ -38,16 +52,7 @@ gen_cert() {
 
     csr="$(mktemp)"
     crt="$(mktemp)"
-    certutil -R -d "$dbdir" -s "$subject" -f "$pwfile" -z "$noise" -o "$csr" -4 >/dev/null <<EOF
-1
-7
-file://$crl_path/$ca.crl
--1
--1
--1
-n
-n
-EOF
+    certutil -R -d "$dbdir" -s "$subject" -f "$pwfile" -z "$noise" -o "$csr" "${request_options[@]}" >/dev/null <<<"$request_input"
     serial_number=$(($serial_number+1))
     certutil -C -d "$dbdir" -f "$pwfile" -m "$serial_number" -i "$csr" -o "$crt" "${options[@]}" "$@"
     certutil -A -d "$dbdir" -n "$nick" -f "$pwfile" -i "$crt" "${options[@]}"
@@ -117,3 +122,5 @@ gen_cert server replica-selfsign "CN=$server2,O=Self-signed"
 gen_subtree ca1 'Example Organization'
 gen_subtree ca1/subca 'Subsidiary Example Organization'
 gen_subtree ca2 'Other Example Organization'
+gen_subtree ca3 'Unknown Organization'
+certutil -D -d "$dbdir" -n ca3
-- 
2.4.3

From b810e963d2a7bd768991a5d32a96127d5df41962 Mon Sep 17 00:00:00 2001
From: Oleg Fayans <ofay...@redhat.com>
Date: Tue, 10 May 2016 13:12:05 +0200
Subject: [PATCH] Fixed numerous errors in ca-less tests

---
 ipatests/test_integration/test_caless.py | 513 +++++++++++++++----------------
 1 file changed, 250 insertions(+), 263 deletions(-)

diff --git a/ipatests/test_integration/test_caless.py b/ipatests/test_integration/test_caless.py
index fdc4fc8efe73631e9ab03f3b9019444f7d7e09ec..b6b261dc15d59fff4861be41a23e2697f462aff4 100644
--- a/ipatests/test_integration/test_caless.py
+++ b/ipatests/test_integration/test_caless.py
@@ -32,20 +32,19 @@ from ipaplatform.paths import paths
 from ipapython.dn import DN
 from ipatests.test_integration.base import IntegrationTest
 from ipatests.test_integration import tasks
+from ipatests.test_integration.env_config import get_global_config
+from ipalib.constants import DOMAIN_LEVEL_0, DOMAIN_LEVEL_1
 
 _DEFAULT = object()
+config = get_global_config()
 
 
 def get_install_stdin(cert_passwords=()):
     lines = [
-        'yes',  # Existing BIND configuration detected, overwrite? [no]
         '',  # Server host name (has default)
-        '',  # Confirm domain name (has default)
     ]
     lines.extend(cert_passwords)  # Enter foo.p12 unlock password
     lines += [
-        '',  # Do you want to configure the reverse zone? [yes]
-        '',  # Please specify the reverse zone name [47.34.10.in-addr.arpa.]
         'yes',  # Continue with these values?
     ]
     return '\n'.join(lines + [''])
@@ -65,10 +64,55 @@ def assert_error(result, stderr_text, returncode=None):
         assert result.returncode > 0
 
 
+def ipa_certs_cleanup(host):
+    host.run_command(['certutil', '-d', paths.NSS_DB_DIR, '-D',
+                      '-n', 'External CA cert'],
+                     raiseonerr=False)
+    # A workaround for https://fedorahosted.org/freeipa/ticket/4639
+    result = host.run_command(['certutil', '-L', '-d',
+                               paths.HTTPD_ALIAS_DIR])
+    for rawcert in result.stdout_text.split('\n')[4: -1]:
+        cert = rawcert.split('    ')[0]
+        host.run_command(['certutil', '-D', '-d', paths.HTTPD_ALIAS_DIR,
+                          '-n', cert])
+
+
+def server_install_teardown(func):
+    def wrapped(*args):
+        master = args[0].master
+        try:
+            func(*args)
+        finally:
+            tasks.uninstall_master(master)
+            ipa_certs_cleanup(master)
+    return wrapped
+
+
+def replica_install_teardown(func):
+    def wrapped(*args):
+        try:
+            func(*args)
+        finally:
+            # Uninstall replica
+            replica = args[0].replicas[0]
+            master = args[0].master
+            tasks.kinit_admin(master)
+            tasks.uninstall_master(replica)
+            # Now let's uninstall client for the cases when client promotion
+            # was not successful
+            tasks.uninstall_client(replica)
+            tasks.clean_replication_agreement(master, replica)
+            master.run_command(['ipa', 'host-del',
+                                replica.hostname],
+                               raiseonerr=False)
+            ipa_certs_cleanup(replica)
+    return wrapped
+
+
 class CALessBase(IntegrationTest):
     @classmethod
     def install(cls, mh):
-        super(CALessBase, cls).install(mh)
+#        super(CALessBase, cls).install(mh)
         cls.cert_dir = tempfile.mkdtemp(prefix="ipatest-")
         cls.pem_filename = os.path.join(cls.cert_dir, 'root.pem')
         scriptfile = os.path.join(os.path.dirname(__file__),
@@ -86,16 +130,16 @@ class CALessBase(IntegrationTest):
             client_hostname = cls.clients[0].hostname
         else:
             client_hostname = 'unused-client.test'
-        env = {
+        cls.env = {
             'domain': cls.master.domain.name,
             'server1': cls.master.hostname,
             'server2': replica_hostname,
             'client': client_hostname,
             'dbdir': 'nssdb',
-            'dbpassword': cls.cert_password,
             'crl_path': cls.crl_path,
+            'dirman_password': cls.master.config.dirman_password,
         }
-        ipautil.run(['bash', '-ex', scriptfile], cwd=cls.cert_dir, env=env)
+        ipautil.run(['bash', '-ex', scriptfile], cwd=cls.cert_dir, env=cls.env)
 
         for host in cls.get_all_hosts():
             tasks.apply_common_fixes(host)
@@ -112,6 +156,9 @@ class CALessBase(IntegrationTest):
         # Remove the NSS database
         shutil.rmtree(cls.cert_dir)
 
+        for host in cls.get_all_hosts():
+            tasks.uninstall_master(host)
+
         super(CALessBase, cls).uninstall(mh)
 
     @classmethod
@@ -131,7 +178,7 @@ class CALessBase(IntegrationTest):
             http_pin = cls.cert_password
         if dirsrv_pin is _DEFAULT:
             dirsrv_pin = cls.cert_password
-
+        tasks.prepare_host(host)
         files_to_copy = ['root.pem']
         if http_pkcs12_exists:
             files_to_copy.append(http_pkcs12)
@@ -140,51 +187,36 @@ class CALessBase(IntegrationTest):
         for filename in set(files_to_copy):
             cls.copy_cert(host, filename)
 
-        host.collect_log(paths.IPASERVER_INSTALL_LOG)
-        host.collect_log(paths.IPACLIENT_INSTALL_LOG)
-        inst = host.domain.realm.replace('.', '-')
-        host.collect_log(paths.SLAPD_INSTANCE_ERROR_LOG_TEMPLATE % inst)
-        host.collect_log(paths.SLAPD_INSTANCE_ACCESS_LOG_TEMPLATE % inst)
+        # Remove existing ca certs from default database to avoid conflicts
+        args = [paths.CERTUTIL, "-D", "-d", "/etc/httpd/alias", "-n"]
+        host.run_command(args + ["ca1"], raiseonerr=False)
+        host.run_command(args + ["ca1/server"], raiseonerr=False)
 
-        args = [
-            'ipa-server-install',
-            '--http-cert-file', http_pkcs12,
-            '--dirsrv-cert-file', dirsrv_pkcs12,
-            '--ca-cert-file', root_ca_file,
-            '--ip-address', host.ip,
-            '-r', host.domain.name,
-            '-p', host.config.dirman_password,
-            '-a', host.config.admin_password,
-            '--setup-dns',
-            '--forwarder', host.config.dns_forwarder,
-        ]
+        extra_args = ['--http-cert-file', http_pkcs12,
+                      '--dirsrv-cert-file', dirsrv_pkcs12,
+                      '--ca-cert-file', root_ca_file,
+                      '--ip-address', host.ip]
 
         if http_pin is not None:
-            args.extend(['--http-pin', http_pin])
+            extra_args.extend(['--http-pin', http_pin])
         if dirsrv_pin is not None:
-            args.extend(['--dirsrv-pin', dirsrv_pin])
-        if unattended:
-            args.extend(['-U'])
-
-        return host.run_command(args, raiseonerr=False, stdin_text=stdin_text)
+            extra_args.extend(['--dirsrv-pin', dirsrv_pin])
+        return tasks.install_master(host, extra_args=extra_args,
+                                    unattended=unattended,
+                                    stdin_text=stdin_text,
+                                    raiseonerr=False)
 
     @classmethod
     def copy_cert(cls, host, filename):
         host.transport.put_file(os.path.join(cls.cert_dir, filename),
                                 os.path.join(host.config.test_dir, filename))
 
-    @classmethod
-    def uninstall_server(self, host=None):
-        if host is None:
-            host = self.master
-        host.run_command(['ipa-server-install', '--uninstall', '-U'])
-
     def prepare_replica(self, _replica_number=0, replica=None, master=None,
                         http_pkcs12='replica.p12', dirsrv_pkcs12='replica.p12',
                         http_pkcs12_exists=True, dirsrv_pkcs12_exists=True,
                         http_pin=_DEFAULT, dirsrv_pin=_DEFAULT,
                         root_ca_file='root.pem', unattended=True,
-                        stdin_text=None):
+                        stdin_text=None, domain_level=None):
         """Prepare a CA-less replica
 
         Puts the bundle file into test_dir on the replica if successful,
@@ -200,78 +232,56 @@ class CALessBase(IntegrationTest):
             http_pin = self.cert_password
         if dirsrv_pin is _DEFAULT:
             dirsrv_pin = self.cert_password
+        if domain_level is None:
+            domain_level = tasks.domainlevel(master)
 
         files_to_copy = ['root.pem']
         if http_pkcs12_exists:
             files_to_copy.append(http_pkcs12)
+
         if dirsrv_pkcs12_exists:
             files_to_copy.append(dirsrv_pkcs12)
+        if domain_level == DOMAIN_LEVEL_0:
+            destination_host = master
+        else:
+            destination_host = replica
+            tasks.prepare_host(replica)
         for filename in set(files_to_copy):
-            master.transport.put_file(
-                os.path.join(self.cert_dir, filename),
-                os.path.join(master.config.test_dir, filename))
+            try:
+                destination_host.transport.put_file(
+                    os.path.join(self.cert_dir, filename),
+                    os.path.join(destination_host.config.test_dir, filename))
+            except OSError:
+                pass
 
-        replica.collect_log(paths.IPAREPLICA_INSTALL_LOG)
-        replica.collect_log(paths.IPACLIENT_INSTALL_LOG)
-        inst = replica.domain.realm.replace('.', '-')
-        replica.collect_log(paths.SLAPD_INSTANCE_ERROR_LOG_TEMPLATE % inst)
-        replica.collect_log(paths.SLAPD_INSTANCE_ACCESS_LOG_TEMPLATE % inst)
+        extra_args = []
 
-        args = [
-            'ipa-replica-prepare',
-            '--ip-address', replica.ip,
-            '-p', replica.config.dirman_password,
-        ]
-
-        if http_pkcs12:
-            args.extend(['--http-cert-file', http_pkcs12])
-        if dirsrv_pkcs12:
-            args.extend(['--dirsrv-cert-file', dirsrv_pkcs12])
+        if http_pkcs12_exists:
+            extra_args.extend(['--http-cert-file', http_pkcs12])
+        if dirsrv_pkcs12_exists:
+            extra_args.extend(['--dirsrv-cert-file', dirsrv_pkcs12])
         if http_pin is not None:
-            args.extend(['--http-pin', http_pin])
+            extra_args.extend(['--http-pin', http_pin])
         if dirsrv_pin is not None:
-            args.extend(['--dirsrv-pin', dirsrv_pin])
+            extra_args.extend(['--dirsrv-pin', dirsrv_pin])
 
-        args.extend([replica.hostname])
-
-        result = master.run_command(args, raiseonerr=False,
-                                    stdin_text=stdin_text)
-
-        if result.returncode == 0:
-            replica_bundle = master.get_file_contents(
-                paths.REPLICA_INFO_GPG_TEMPLATE % replica.hostname)
-            replica.put_file_contents(self.get_replica_filename(replica),
-                                      replica_bundle)
+        if domain_level == DOMAIN_LEVEL_0:
+            result = tasks.replica_prepare(master, replica,
+                                           extra_args=extra_args,
+                                           raiseonerr=False,
+                                           stdin_text=stdin_text)
         else:
-            replica.run_command(['rm', self.get_replica_filename(replica)],
-                                raiseonerr=False)
-
+            result = tasks.install_replica(master, replica, setup_ca=False,
+                                           extra_args=extra_args,
+                                           unattended=unattended,
+                                           stdin_text=stdin_text,
+                                           raiseonerr=False)
         return result
 
     def get_replica_filename(self, replica):
         return os.path.join(replica.config.test_dir,
                             'replica-info.gpg')
 
-    def install_replica(self, _replica_number=0, replica=None,
-                        unattended=True):
-        """Install a CA-less replica
-
-        The bundle file is expected to be in the test_dir
-
-        Return value is the remote ipa-replica-install command
-        """
-        if replica is None:
-            replica = self.replicas[_replica_number]
-
-        args = ['ipa-replica-install', '-U',
-                '-p', replica.config.dirman_password,
-                '-w', replica.config.admin_password,
-                '--ip-address', replica.ip,
-                self.get_replica_filename(replica)]
-        if unattended:
-            args.append('-U')
-        return replica.run_command(args)
-
     @classmethod
     def export_pkcs12(cls, nickname, filename='server.p12', password=None):
         """Export a cert as PKCS#12 to the given file"""
@@ -287,8 +297,8 @@ class CALessBase(IntegrationTest):
     @classmethod
     def get_pem(cls, nickname):
         pem_cert, _stderr, _returncode = ipautil.run(
-            ['certutil', '-L', '-d', 'nssdb', '-n', nickname, '-a'],
-            cwd=cls.cert_dir)
+            [paths.CERTUTIL, '-L', '-d', 'nssdb', '-n', nickname, '-a'],
+            cwd=cls.cert_dir, capture_output=True)
         return pem_cert
 
     def verify_installation(self):
@@ -315,10 +325,9 @@ class CALessBase(IntegrationTest):
             assert cert_from_ldap == expected_binary_cacrt
 
             # Verify certmonger was not started
+
             result = host.run_command(['getcert', 'list'], raiseonerr=False)
-            assert result > 0
-            assert ('Please verify that the certmonger service has been '
-                    'started.' in result.stdout_text), result.stdout_text
+            assert result.returncode == 0
 
         for host in self.get_all_hosts():
             # Check the cert PEM file
@@ -334,9 +343,7 @@ class CALessBase(IntegrationTest):
 class TestServerInstall(CALessBase):
     num_replicas = 0
 
-    def tearDown(self):
-        self.uninstall_server()
-
+    @server_install_teardown
     def test_nonexistent_ca_pem_file(self):
         "IPA server install with non-existent CA PEM file "
 
@@ -349,42 +356,19 @@ class TestServerInstall(CALessBase):
                      'Failed to open does_not_exist: No such file '
                      'or directory')
 
+    @server_install_teardown
     def test_unknown_ca(self):
         "IPA server install with CA PEM file with unknown CA certificate"
 
-        self.export_pkcs12('ca1/server')
+        self.export_pkcs12('ca3/server')
         with open(self.pem_filename, 'w') as f:
             f.write(self.get_pem('ca2'))
 
         result = self.install_server()
         assert_error(result,
-                     'server.p12 is not signed by root.pem, or the full '
-                     'certificate chain is not present in the PKCS#12 '
-                     'file')
-
-    def test_ca_server_cert(self):
-        "IPA server install with CA PEM file with server certificate"
-
-        self.export_pkcs12('ca1/server')
-        with open(self.pem_filename, 'w') as f:
-            f.write(self.get_pem('ca1/server'))
-
-        result = self.install_server()
-        assert_error(result,
-                     'trust chain of the server certificate in server.p12 '
-                     'contains 1 certificates, expected 2')
-
-    def test_ca_2_certs(self):
-        "IPA server install with CA PEM file with 2 certificates"
-
-        self.export_pkcs12('ca1/server')
-        with open(self.pem_filename, 'w') as f:
-            f.write(self.get_pem('ca1'))
-            f.write(self.get_pem('ca2'))
-
-        result = self.install_server()
-        assert_error(result, 'root.pem contains more than one certificate')
+                     'The full certificate chain is not present in server.p12')
 
+    @server_install_teardown
     def test_nonexistent_http_pkcs12_file(self):
         "IPA server install with non-existent HTTP PKCS#12 file"
 
@@ -396,6 +380,7 @@ class TestServerInstall(CALessBase):
                                      http_pkcs12_exists=False)
         assert_error(result, 'Failed to open does_not_exist')
 
+    @server_install_teardown
     def test_nonexistent_ds_pkcs12_file(self):
         "IPA server install with non-existent DS PKCS#12 file"
 
@@ -407,6 +392,7 @@ class TestServerInstall(CALessBase):
                                      dirsrv_pkcs12_exists=False)
         assert_error(result, 'Failed to open does_not_exist')
 
+    @server_install_teardown
     def test_missing_http_password(self):
         "IPA server install with missing HTTP PKCS#12 password (unattended)"
 
@@ -419,6 +405,7 @@ class TestServerInstall(CALessBase):
                      'ipa-server-install: error: You must specify --http-pin '
                      'with --http-cert-file')
 
+    @server_install_teardown
     def test_missing_ds_password(self):
         "IPA server install with missing DS PKCS#12 password (unattended)"
 
@@ -431,6 +418,8 @@ class TestServerInstall(CALessBase):
                      'ipa-server-install: error: You must specify '
                      '--dirsrv-pin with --dirsrv-cert-file')
 
+    @pytest.mark.xfail(reason='freeipa ticket 5378')
+    @server_install_teardown
     def test_incorect_http_pin(self):
         "IPA server install with incorrect HTTP PKCS#12 password"
 
@@ -441,7 +430,9 @@ class TestServerInstall(CALessBase):
         result = self.install_server(http_pin='bad<pin>')
         assert_error(result, 'incorrect password for pkcs#12 file server.p12')
 
-    def test_incorect_ds_pin(self):
+    @pytest.mark.xfail(reason='freeipa ticket 5378')
+    @server_install_teardown
+    def test_incorrect_ds_pin(self):
         "IPA server install with incorrect DS PKCS#12 password"
 
         self.export_pkcs12('ca1/server')
@@ -451,6 +442,7 @@ class TestServerInstall(CALessBase):
         result = self.install_server(dirsrv_pin='bad<pin>')
         assert_error(result, 'incorrect password for pkcs#12 file server.p12')
 
+    @server_install_teardown
     def test_invalid_http_cn(self):
         "IPA server install with HTTP certificate with invalid CN"
 
@@ -465,6 +457,7 @@ class TestServerInstall(CALessBase):
                      'The server certificate in http.p12 is not valid: '
                      'invalid for server %s' % self.master.hostname)
 
+    @server_install_teardown
     def test_invalid_ds_cn(self):
         "IPA server install with DS certificate with invalid CN"
 
@@ -479,6 +472,7 @@ class TestServerInstall(CALessBase):
                      'The server certificate in dirsrv.p12 is not valid: '
                      'invalid for server %s' % self.master.hostname)
 
+    @server_install_teardown
     def test_expired_http(self):
         "IPA server install with expired HTTP certificate"
 
@@ -494,6 +488,7 @@ class TestServerInstall(CALessBase):
                      "(SEC_ERROR_EXPIRED_CERTIFICATE) Peer's Certificate has "
                      'expired.')
 
+    @server_install_teardown
     def test_expired_ds(self):
         "IPA server install with expired DS certificate"
 
@@ -509,6 +504,7 @@ class TestServerInstall(CALessBase):
                      "(SEC_ERROR_EXPIRED_CERTIFICATE) Peer's Certificate has "
                      'expired.')
 
+    @server_install_teardown
     def test_http_bad_usage(self):
         "IPA server install with HTTP certificate with invalid key usage"
 
@@ -523,6 +519,7 @@ class TestServerInstall(CALessBase):
                      'The server certificate in http.p12 is not valid: '
                      'invalid for a SSL server')
 
+    @server_install_teardown
     def test_ds_bad_usage(self):
         "IPA server install with DS certificate with invalid key usage"
 
@@ -537,6 +534,7 @@ class TestServerInstall(CALessBase):
                      'The server certificate in dirsrv.p12 is not valid: '
                      'invalid for a SSL server')
 
+    @server_install_teardown
     def test_revoked_http(self):
         "IPA server install with revoked HTTP certificate"
 
@@ -555,6 +553,7 @@ class TestServerInstall(CALessBase):
 
         assert result.returncode > 0
 
+    @server_install_teardown
     def test_revoked_ds(self):
         "IPA server install with revoked DS certificate"
 
@@ -573,6 +572,7 @@ class TestServerInstall(CALessBase):
 
         assert result.returncode > 0
 
+    @server_install_teardown
     def test_http_intermediate_ca(self):
         "IPA server install with HTTP certificate issued by intermediate CA"
 
@@ -583,10 +583,11 @@ class TestServerInstall(CALessBase):
 
         result = self.install_server(http_pkcs12='http.p12',
                                      dirsrv_pkcs12='dirsrv.p12')
-        assert_error(result,
-                     'http.p12 is not signed by root.pem, or the full '
-                     'certificate chain is not present in the PKCS#12 file')
+        assert_error(result, 'Apache Server SSL certificate and'
+                             ' Directory Server SSL certificate are not'
+                             ' signed by the same CA certificate')
 
+    @server_install_teardown
     def test_ds_intermediate_ca(self):
         "IPA server install with DS certificate issued by intermediate CA"
 
@@ -598,9 +599,10 @@ class TestServerInstall(CALessBase):
         result = self.install_server(http_pkcs12='http.p12',
                                      dirsrv_pkcs12='dirsrv.p12')
         assert_error(result,
-                     'dirsrv.p12 is not signed by root.pem, or the full '
-                     'certificate chain is not present in the PKCS#12 file')
+                     'Apache Server SSL certificate and Directory Server SSL'
+                     ' certificate are not signed by the same CA certificate')
 
+    @server_install_teardown
     def test_ca_self_signed(self):
         "IPA server install with self-signed certificate"
 
@@ -611,6 +613,7 @@ class TestServerInstall(CALessBase):
         result = self.install_server()
         assert result.returncode > 0
 
+    @server_install_teardown
     def test_valid_certs(self):
         "IPA server install with valid certificates"
 
@@ -622,6 +625,8 @@ class TestServerInstall(CALessBase):
         assert result.returncode == 0
         self.verify_installation()
 
+    @pytest.mark.xfail(reason='freeipa ticket 5603')
+    @server_install_teardown
     def test_wildcard_http(self):
         "IPA server install with wildcard HTTP certificate"
 
@@ -635,6 +640,8 @@ class TestServerInstall(CALessBase):
         assert result.returncode == 0
         self.verify_installation()
 
+    @pytest.mark.xfail(reason='freeipa ticket 5603')
+    @server_install_teardown
     def test_wildcard_ds(self):
         "IPA server install with wildcard DS certificate"
 
@@ -648,6 +655,7 @@ class TestServerInstall(CALessBase):
         assert result.returncode == 0
         self.verify_installation()
 
+    @server_install_teardown
     def test_http_san(self):
         "IPA server install with HTTP certificate with SAN"
 
@@ -661,6 +669,7 @@ class TestServerInstall(CALessBase):
         assert result.returncode == 0
         self.verify_installation()
 
+    @server_install_teardown
     def test_ds_san(self):
         "IPA server install with DS certificate with SAN"
 
@@ -674,6 +683,7 @@ class TestServerInstall(CALessBase):
         assert result.returncode == 0
         self.verify_installation()
 
+    @server_install_teardown
     def test_interactive_missing_http_pkcs_password(self):
         "IPA server install with prompt for HTTP PKCS#12 password"
 
@@ -687,9 +697,10 @@ class TestServerInstall(CALessBase):
                                      stdin_text=stdin_text)
         assert result.returncode == 0
         self.verify_installation()
-        assert ('Enter server.p12 unlock password:'
+        assert ('Enter Apache Server private key unlock password'
                 in result.stdout_text), result.stdout_text
 
+    @server_install_teardown
     def test_interactive_missing_ds_pkcs_password(self):
         "IPA server install with prompt for DS PKCS#12 password"
 
@@ -703,9 +714,10 @@ class TestServerInstall(CALessBase):
                                      stdin_text=stdin_text)
         assert result.returncode == 0
         self.verify_installation()
-        assert ('Enter server.p12 unlock password:'
+        assert ('Enter Directory Server private key unlock password'
                 in result.stdout_text), result.stdout_text
 
+    @server_install_teardown
     def test_no_http_password(self):
         "IPA server install with empty HTTP password"
 
@@ -720,6 +732,7 @@ class TestServerInstall(CALessBase):
         assert result.returncode == 0
         self.verify_installation()
 
+    @server_install_teardown
     def test_no_ds_password(self):
         "IPA server install with empty DS password"
 
@@ -738,59 +751,46 @@ class TestServerInstall(CALessBase):
 class TestReplicaInstall(CALessBase):
     num_replicas = 1
 
-    def setUp(self):
-        # Install the master for every test
-        self.export_pkcs12('ca1/server')
-        with open(self.pem_filename, 'w') as f:
-            f.write(self.get_pem('ca1'))
-
-        result = self.install_server()
+    @classmethod
+    def install(cls, mh):
+        super(TestReplicaInstall, cls).install(mh)
+        cls.export_pkcs12('ca1/server')
+        with open(cls.pem_filename, 'w') as f:
+            f.write(cls.get_pem('ca1'))
+        result = cls.install_server()
         assert result.returncode == 0
 
-    def tearDown(self):
-        # Uninstall both master and replica
-        replica = self.replicas[0]
-        tasks.kinit_admin(self.master)
-        self.uninstall_server(replica)
-        self.master.run_command(['ipa-replica-manage', 'del', replica.hostname,
-                                 '--force'], raiseonerr=False)
-        self.master.run_command(['ipa', 'host-del', replica.hostname],
-                                raiseonerr=False)
-
-        self.uninstall_server()
-
+    @replica_install_teardown
     def test_no_certs(self):
         "IPA replica install without certificates"
+        result = self.prepare_replica(http_pkcs12_exists=False,
+                                      dirsrv_pkcs12_exists=False)
+        assert_error(result, "Cannot issue certificates: a CA is not "
+                             "installed. Use the --http-cert-file, "
+                             "--dirsrv-cert-file options to provide "
+                             "custom certificates.")
 
-        result = self.master.run_command(['ipa-replica-prepare',
-                                          self.replicas[0].hostname],
-                                         raiseonerr=False)
-        assert result.returncode > 0
-        assert ('Cannot issue certificates: a CA is not installed. Use the '
-                '--http-cert-file, --dirsrv-cert-file options to provide '
-                'custom certificates.' in result.stderr_text), \
-               result.stderr_text
-
+    @replica_install_teardown
     def test_nonexistent_http_pkcs12_file(self):
         "IPA replica install with non-existent HTTP PKCS#12 file"
 
-        self.export_pkcs12('ca1/replica', filename='dirsrv.p12')
-
+        self.export_pkcs12('ca1/replica', filename='http.p12')
         result = self.prepare_replica(http_pkcs12='does_not_exist',
-                                      dirsrv_pkcs12='dirsrv.p12',
-                                      http_pkcs12_exists=False)
+                                      dirsrv_pkcs12='http.p12')
         assert_error(result, 'Failed to open does_not_exist')
 
+    @replica_install_teardown
     def test_nonexistent_ds_pkcs12_file(self):
         "IPA replica install with non-existent DS PKCS#12 file"
 
         self.export_pkcs12('ca1/replica', filename='http.p12')
 
         result = self.prepare_replica(dirsrv_pkcs12='does_not_exist',
-                                      http_pkcs12='http.p12',
-                                      dirsrv_pkcs12_exists=False)
+                                      http_pkcs12='http.p12')
         assert_error(result, 'Failed to open does_not_exist')
 
+    @pytest.mark.xfail(reason='freeipa ticket 5378')
+    @replica_install_teardown
     def test_incorect_http_pin(self):
         "IPA replica install with incorrect HTTP PKCS#12 password"
 
@@ -800,7 +800,9 @@ class TestReplicaInstall(CALessBase):
         assert result.returncode > 0
         assert_error(result, 'incorrect password for pkcs#12 file replica.p12')
 
-    def test_incorect_ds_pin(self):
+    @pytest.mark.xfail(reason='freeipa ticket 5378')
+    @replica_install_teardown
+    def test_incorrect_ds_pin(self):
         "IPA replica install with incorrect DS PKCS#12 password"
 
         self.export_pkcs12('ca1/replica', filename='replica.p12')
@@ -808,6 +810,7 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(dirsrv_pin='bad<pin>')
         assert_error(result, 'incorrect password for pkcs#12 file replica.p12')
 
+    @replica_install_teardown
     def test_http_unknown_ca(self):
         "IPA replica install with HTTP certificate issued by unknown CA"
 
@@ -816,10 +819,11 @@ class TestReplicaInstall(CALessBase):
 
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
-        assert_error(result,
-                     'http.p12 is not signed by /etc/ipa/ca.crt, or the full '
-                     'certificate chain is not present in the PKCS#12 file')
+        assert_error(result, 'Apache Server SSL certificate and'
+                             ' Directory Server SSL certificate are not'
+                             ' signed by the same CA certificate')
 
+    @replica_install_teardown
     def test_ds_unknown_ca(self):
         "IPA replica install with DS certificate issued by unknown CA"
 
@@ -829,10 +833,10 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
         assert_error(result,
-                     'dirsrv.p12 is not signed by /etc/ipa/ca.crt, or the '
-                     'full certificate chain is not present in the PKCS#12 '
-                     'file')
+                     'Apache Server SSL certificate and Directory Server SSL'
+                     ' certificate are not signed by the same CA certificate')
 
+    @replica_install_teardown
     def test_invalid_http_cn(self):
         "IPA replica install with HTTP certificate with invalid CN"
 
@@ -845,6 +849,7 @@ class TestReplicaInstall(CALessBase):
                      'The server certificate in http.p12 is not valid: '
                      'invalid for server %s' % self.replicas[0].hostname)
 
+    @replica_install_teardown
     def test_invalid_ds_cn(self):
         "IPA replica install with DS certificate with invalid CN"
 
@@ -857,6 +862,7 @@ class TestReplicaInstall(CALessBase):
                      'The server certificate in dirsrv.p12 is not valid: '
                      'invalid for server %s' % self.replicas[0].hostname)
 
+    @replica_install_teardown
     def test_expired_http(self):
         "IPA replica install with expired HTTP certificate"
 
@@ -870,6 +876,7 @@ class TestReplicaInstall(CALessBase):
                      "(SEC_ERROR_EXPIRED_CERTIFICATE) Peer's Certificate has "
                      'expired.')
 
+    @replica_install_teardown
     def test_expired_ds(self):
         "IPA replica install with expired DS certificate"
 
@@ -883,6 +890,7 @@ class TestReplicaInstall(CALessBase):
                      "(SEC_ERROR_EXPIRED_CERTIFICATE) Peer's Certificate has "
                      'expired.')
 
+    @replica_install_teardown
     def test_http_bad_usage(self):
         "IPA replica install with HTTP certificate with invalid key usage"
 
@@ -895,6 +903,7 @@ class TestReplicaInstall(CALessBase):
                      'The server certificate in http.p12 is not valid: '
                      'invalid for a SSL server')
 
+    @replica_install_teardown
     def test_ds_bad_usage(self):
         "IPA replica install with DS certificate with invalid key usage"
 
@@ -907,6 +916,7 @@ class TestReplicaInstall(CALessBase):
                      'The server certificate in dirsrv.p12 is not valid: '
                      'invalid for a SSL server')
 
+    @replica_install_teardown
     def test_revoked_http(self):
         "IPA replica install with revoked HTTP certificate"
 
@@ -923,6 +933,7 @@ class TestReplicaInstall(CALessBase):
 
         assert result.returncode > 0
 
+    @replica_install_teardown
     def test_revoked_ds(self):
         "IPA replica install with revoked DS certificate"
 
@@ -939,6 +950,7 @@ class TestReplicaInstall(CALessBase):
 
         assert result.returncode > 0
 
+    @replica_install_teardown
     def test_http_intermediate_ca(self):
         "IPA replica install with HTTP certificate issued by intermediate CA"
 
@@ -948,9 +960,10 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
         assert_error(result,
-                     'http.p12 is not signed by /etc/ipa/ca.crt, or the full '
-                     'certificate chain is not present in the PKCS#12 file')
+                     'Apache Server SSL certificate and Directory Server SSL'
+                     ' certificate are not signed by the same CA certificate')
 
+    @replica_install_teardown
     def test_ds_intermediate_ca(self):
         "IPA replica install with DS certificate issued by intermediate CA"
 
@@ -959,11 +972,13 @@ class TestReplicaInstall(CALessBase):
 
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
-        assert_error(result,
-                     'dirsrv.p12 is not signed by /etc/ipa/ca.crt, or the '
-                     'full certificate chain is not present in the PKCS#12 '
-                     'file')
+        assert_error(result, 'Apache Server SSL certificate and'
+                             ' Directory Server SSL certificate are not'
+                             ' signed by the same CA certificate')
 
+    @pytest.mark.skipif(config.domain_level == DOMAIN_LEVEL_1,
+                        reason='freeipa ticket 5721')
+    @replica_install_teardown
     def test_valid_certs(self):
         "IPA replica install with valid certificates"
 
@@ -972,12 +987,11 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pkcs12='server.p12',
                                       dirsrv_pkcs12='server.p12')
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @pytest.mark.xfail(reason='freeipa ticket 5603')
+    @replica_install_teardown
     def test_wildcard_http(self):
         "IPA replica install with wildcard HTTP certificate"
 
@@ -987,12 +1001,11 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @pytest.mark.xfail(reason='freeipa ticket 5603')
+    @replica_install_teardown
     def test_wildcard_ds(self):
         "IPA replica install with wildcard DS certificate"
 
@@ -1002,12 +1015,10 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @replica_install_teardown
     def test_http_san(self):
         "IPA replica install with HTTP certificate with SAN"
 
@@ -1017,12 +1028,10 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @replica_install_teardown
     def test_ds_san(self):
         "IPA replica install with DS certificate with SAN"
 
@@ -1032,12 +1041,10 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pkcs12='http.p12',
                                       dirsrv_pkcs12='dirsrv.p12')
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @replica_install_teardown
     def test_interactive_missing_http_pkcs_password(self):
         "IPA replica install with missing HTTP PKCS#12 password"
 
@@ -1049,12 +1056,10 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(http_pin=None, unattended=False,
                                       stdin_text=stdin_text)
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @replica_install_teardown
     def test_interactive_missing_ds_pkcs_password(self):
         "IPA replica install with missing DS PKCS#12 password"
 
@@ -1066,12 +1071,12 @@ class TestReplicaInstall(CALessBase):
         result = self.prepare_replica(dirsrv_pin=None, unattended=False,
                                       stdin_text=stdin_text)
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @pytest.mark.skipif(config.domain_level == DOMAIN_LEVEL_1,
+                        reason='freeipa ticket 5789')
+    @replica_install_teardown
     def test_no_http_password(self):
         "IPA replica install with empty HTTP password"
 
@@ -1082,12 +1087,10 @@ class TestReplicaInstall(CALessBase):
                                       dirsrv_pkcs12='dirsrv.p12',
                                       http_pin='')
         assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
-        result = self.install_replica()
-        assert result.returncode == 0
-
-        self.verify_installation()
-
+    @replica_install_teardown
     def test_no_ds_password(self):
         "IPA replica install with empty DS password"
 
@@ -1098,9 +1101,8 @@ class TestReplicaInstall(CALessBase):
                                       dirsrv_pkcs12='dirsrv.p12',
                                       dirsrv_pin='')
         assert result.returncode == 0
-
-        result = self.install_replica()
-        assert result.returncode == 0
+        if self.domain_level > DOMAIN_LEVEL_0:
+            self.verify_installation()
 
 
 class TestClientInstall(CALessBase):
@@ -1151,31 +1153,15 @@ class TestIPACommands(CALessBase):
         result = self.master.run_command(['ipa', command], raiseonerr=False)
         assert_error(result, "ipa: ERROR: unknown command '%s'" % command)
 
-    @pytest.mark.parametrize('command', (
-        'cert-status',
-        'cert-show',
-        'cert-find',
-        'cert-revoke',
-        'cert-remove-hold',
-        'cert-status'))
-    def test_cert_commands_unavailable(self, command):
-        result = self.master.run_command(['ipa', command], raiseonerr=False)
-        assert_error(result, "ipa: ERROR: unknown command '%s'" % command)
-
-    def test_cert_help_unavailable(self):
-        "Verify that cert plugin help is not available"
-        result = self.master.run_command(['ipa', 'help', 'cert'],
-                                         raiseonerr=False)
-        assert_error(result,
-                     "ipa: ERROR: no command nor help topic 'cert'",
-                     returncode=1)
-
     @contextlib.contextmanager
     def host(self):
         "Context manager that adds and removes a host entry with a certificate"
         self.master.run_command(['ipa', 'host-add', self.test_hostname,
                                  '--force',
                                  '--certificate', self.client_pem])
+        self.master.run_command(['ipa-getkeytab', '-s', self.master.hostname,
+                                 '-p' "host/%s" % self.test_hostname,
+                                 '-k', paths.IPA_KEYTAB])
         try:
             yield
         finally:
@@ -1189,6 +1175,10 @@ class TestIPACommands(CALessBase):
             self.master.run_command(['ipa', 'service-add', self.test_service,
                                      '--force',
                                      '--certificate', self.client_pem])
+            self.master.run_command(['ipa-getkeytab', '-s',
+                                     self.master.hostname,
+                                     '-p', self.test_service,
+                                     '-k', paths.IPA_KEYTAB])
             yield
 
     def test_service_mod_doesnt_revoke(self):
@@ -1200,8 +1190,11 @@ class TestIPACommands(CALessBase):
     def test_service_disable_doesnt_revoke(self):
         "Verify that service-disable does not attempt to revoke certificate"
         with self.service():
-            self.master.run_command(['ipa', 'service-disable',
-                                     self.test_service])
+            result = self.master.run_command(['ipa', 'service-disable',
+                                              self.test_service],
+                                             raiseonerr=False)
+            assert(result.returncode == 0), (
+                "Failed to disable ipa-service: %s" % result.stderr_text)
 
     def test_service_del_doesnt_revoke(self):
         "Verify that service-del does not attempt to revoke certificate"
@@ -1229,7 +1222,7 @@ class TestIPACommands(CALessBase):
 class TestCertinstall(CALessBase):
     @classmethod
     def install(cls, mh):
-        super(TestCertinstall, cls).install()
+        super(TestCertinstall, cls).install(mh)
 
         cls.export_pkcs12('ca1/server')
         with open(cls.pem_filename, 'w') as f:
@@ -1251,12 +1244,10 @@ class TestCertinstall(CALessBase):
             self.copy_cert(self.master, filename)
         if not args:
             args = ['ipa-server-certinstall',
+                    '-p', self.master.config.dirman_password,
                     '-%s' % mode, filename]
             if pin is not None:
                 args += ['--pin', pin]
-            if mode == 'd':
-                args += ['--dirman-password',
-                         self.master.config.dirman_password]
         return self.master.run_command(args,
                                        raiseonerr=False,
                                        stdin_text=stdin_text)
@@ -1275,6 +1266,7 @@ class TestCertinstall(CALessBase):
                                   cert_exists=False)
         assert_error(result, 'Failed to open does_not_exist')
 
+    @pytest.mark.xfail(reason='freeipa ticket 5378')
     def test_incorect_http_pin(self):
         "Install new HTTP certificate with incorrect PKCS#12 password"
 
@@ -1282,6 +1274,7 @@ class TestCertinstall(CALessBase):
         assert_error(result,
                      'incorrect password for pkcs#12 file server.p12')
 
+    @pytest.mark.xfail(reason='freeipa ticket 5378')
     def test_incorect_dirsrv_pin(self):
         "Install new DS certificate with incorrect PKCS#12 password"
 
@@ -1367,28 +1360,20 @@ class TestCertinstall(CALessBase):
         "Install new HTTP certificate issued by intermediate CA"
 
         result = self.certinstall('w', 'ca1/subca/server')
-        assert_error(result,
-                     'server.p12 is not signed by /etc/ipa/ca.crt, or the '
-                     'full certificate chain is not present in the PKCS#12 '
-                     'file')
+        assert result.returncode == 0, result.stderr_text
 
     def test_ds_intermediate_ca(self):
         "Install new DS certificate issued by intermediate CA"
 
         result = self.certinstall('d', 'ca1/subca/server')
-        assert_error(result,
-                     'server.p12 is not signed by /etc/ipa/ca.crt, or the '
-                     'full certificate chain is not present in the PKCS#12 '
-                     'file')
+        assert result.returncode == 0, result.stderr_text
 
     def test_self_signed(self):
         "Install new self-signed certificate"
 
         result = self.certinstall('w', 'server-selfsign')
         assert_error(result,
-                     'server.p12 is not signed by /etc/ipa/ca.crt, or the '
-                     'full certificate chain is not present in the PKCS#12 '
-                     'file')
+                     'The full certificate chain is not present in server.p12')
 
     def test_valid_http(self):
         "Install new valid HTTP certificate"
@@ -1402,12 +1387,14 @@ class TestCertinstall(CALessBase):
         result = self.certinstall('d', 'ca1/server')
         assert result.returncode == 0
 
+    @pytest.mark.xfail(reason='freeipa ticket 5603')
     def test_wildcard_http(self):
         "Install new wildcard HTTP certificate"
 
         result = self.certinstall('w', 'ca1/wildcard')
         assert result.returncode == 0
 
+    @pytest.mark.xfail(reason='freeipa ticket 5603')
     def test_wildcard_ds(self):
         "Install new wildcard DS certificate"
 
@@ -1463,7 +1450,7 @@ class TestCertinstall(CALessBase):
                 '--http-pin', self.cert_password]
 
         result = self.certinstall('w', 'ca1/server', args=args)
-        assert result.returncode == 0
+        assert_error(result, "no such option: --http-pin")
 
     def test_ds_old_options(self):
         "Install new valid DS certificate using pre-v3.3 CLI options"
@@ -1476,4 +1463,4 @@ class TestCertinstall(CALessBase):
 
         result = self.certinstall('d', 'ca1/server',
                                   args=args, stdin_text=stdin_text)
-        assert result.returncode == 0
+        assert_error(result, "no such option: --dirsrv-pin")
-- 
1.8.3.1

From 15c2a8f203662c3632ae288f2f487fadc888af53 Mon Sep 17 00:00:00 2001
From: Oleg Fayans <ofay...@redhat.com>
Date: Tue, 10 May 2016 14:51:36 +0200
Subject: [PATCH] Updated generic installation methods for ca-less tests

---
 ipatests/test_integration/tasks.py | 93 +++++++++++++++++++++++---------------
 1 file changed, 57 insertions(+), 36 deletions(-)

diff --git a/ipatests/test_integration/tasks.py b/ipatests/test_integration/tasks.py
index 70f4fa7fd96f9d993332996f087577d1c88f828e..c6e368d44dcf38bcfa0c5cc36dcc18cec238c919 100644
--- a/ipatests/test_integration/tasks.py
+++ b/ipatests/test_integration/tasks.py
@@ -231,7 +231,8 @@ def enable_replication_debugging(host):
 
 
 def install_master(host, setup_dns=True, setup_kra=False, extra_args=(),
-                   domain_level=None):
+                   domain_level=None, unattended=True, stdin_text=None,
+                   raiseonerr=True):
     if domain_level is None:
         domain_level = host.config.domain_level
     host.collect_log(paths.IPASERVER_INSTALL_LOG)
@@ -244,7 +245,7 @@ def install_master(host, setup_dns=True, setup_kra=False, extra_args=(),
     fix_apache_semaphores(host)
 
     args = [
-        'ipa-server-install', '-U',
+        'ipa-server-install',
         '-n', host.domain.name,
         '-r', host.domain.realm,
         '-p', host.config.dirman_password,
@@ -252,6 +253,9 @@ def install_master(host, setup_dns=True, setup_kra=False, extra_args=(),
         "--domain-level=%i" % domain_level,
     ]
 
+    if unattended:
+        args.append('-U')
+
     if setup_dns:
         args.extend([
             '--setup-dns',
@@ -261,19 +265,22 @@ def install_master(host, setup_dns=True, setup_kra=False, extra_args=(),
 
     args.extend(extra_args)
 
-    host.run_command(args)
-    enable_replication_debugging(host)
-    setup_sssd_debugging(host)
+    result = host.run_command(args, raiseonerr=raiseonerr,
+                              stdin_text=stdin_text)
+    if result.returncode == 0:
+        enable_replication_debugging(host)
+        setup_sssd_debugging(host)
 
-    if setup_kra:
-        args = [
-            "ipa-kra-install",
-            "-p", host.config.dirman_password,
-            "-U",
-        ]
-        host.run_command(args)
+        if setup_kra:
+            args = [
+                "ipa-kra-install",
+                "-p", host.config.dirman_password,
+                "-U",
+            ]
+            host.run_command(args)
 
-    kinit_admin(host)
+        kinit_admin(host)
+    return result
 
 
 def get_replica_filename(replica):
@@ -301,7 +308,8 @@ def master_authoritative_for_client_domain(master, client):
         return False
 
 
-def replica_prepare(master, replica):
+def replica_prepare(master, replica, extra_args=(),
+                    raiseonerr=True, stdin_text=None):
     fix_apache_semaphores(replica)
     prepare_reverse_zone(master, replica.ip)
     args = ['ipa-replica-prepare',
@@ -309,15 +317,20 @@ def replica_prepare(master, replica):
             replica.hostname]
     if master_authoritative_for_client_domain(master, replica):
         args.extend(['--ip-address', replica.ip])
-    master.run_command(args)
-    replica_bundle = master.get_file_contents(
-        paths.REPLICA_INFO_GPG_TEMPLATE % replica.hostname)
-    replica_filename = get_replica_filename(replica)
-    replica.put_file_contents(replica_filename, replica_bundle)
+    args.extend(extra_args)
+    result = master.run_command(args, raiseonerr=raiseonerr,
+                                stdin_text=stdin_text)
+    if result.returncode == 0:
+        replica_bundle = master.get_file_contents(
+            paths.REPLICA_INFO_GPG_TEMPLATE % replica.hostname)
+        replica_filename = get_replica_filename(replica)
+        replica.put_file_contents(replica_filename, replica_bundle)
+    return result
 
 
 def install_replica(master, replica, setup_ca=True, setup_dns=False,
-                    setup_kra=False, extra_args=(), domain_level=None):
+                    setup_kra=False, extra_args=(), domain_level=None,
+                    unattended=True, stdin_text=None, raiseonerr=True):
     if domain_level is None:
         domain_level = domainlevel(master)
     apply_common_fixes(replica)
@@ -326,9 +339,11 @@ def install_replica(master, replica, setup_ca=True, setup_dns=False,
     allow_sync_ptr(master)
     # Otherwise ipa-client-install would not create a PTR
     # and replica installation would fail
-    args = ['ipa-replica-install', '-U',
+    args = ['ipa-replica-install',
             '-p', replica.config.dirman_password,
             '-w', replica.config.admin_password]
+    if unattended:
+        args.append('-U')
     if setup_ca:
         args.append('--setup-ca')
     if setup_dns:
@@ -351,22 +366,25 @@ def install_replica(master, replica, setup_ca=True, setup_dns=False,
         install_client(master, replica)
         fix_apache_semaphores(replica)
         args.extend(['-r', replica.domain.realm])
-    replica.run_command(args)
-    enable_replication_debugging(replica)
-    setup_sssd_debugging(replica)
+    result = replica.run_command(args, raiseonerr=raiseonerr,
+                                 stdin_text=stdin_text)
+    if result.returncode == 0:
+        enable_replication_debugging(replica)
+        setup_sssd_debugging(replica)
 
-    if setup_kra:
-        assert setup_ca, "CA must be installed on replica with KRA"
-        args = [
-            "ipa-kra-install",
-            "-p", replica.config.dirman_password,
-            "-U",
-        ]
-        if domainlevel(master) == DOMAIN_LEVEL_0:
-            args.append(replica_filename)
-        replica.run_command(args)
+        if setup_kra:
+            assert setup_ca, "CA must be installed on replica with KRA"
+            args = [
+                "ipa-kra-install",
+                "-p", replica.config.dirman_password,
+                "-U",
+            ]
+            if domainlevel(master) == DOMAIN_LEVEL_0:
+                args.append(replica_filename)
+            replica.run_command(args)
 
-    kinit_admin(replica)
+        kinit_admin(replica)
+    return result
 
 
 def install_client(master, client, extra_args=()):
@@ -698,6 +716,9 @@ def uninstall_master(host, ignore_topology_disconnect=True):
                       paths.PKI_TOMCAT,
                       paths.REPLICA_INFO_GPG_TEMPLATE % host.hostname],
                      raiseonerr=False)
+    host.run_command([paths.CERTUTIL, '-d', paths.NSS_DB_DIR, '-D',
+                      '-n', 'External CA cert'],
+                     raiseonerr=False)
     unapply_fixes(host)
 
 
@@ -717,7 +738,7 @@ def clean_replication_agreement(master, replica):
     master.run_command(['ipa-replica-manage',
                         'del',
                         replica.hostname,
-                        '--force'])
+                        '--force', '--cleanup'])
 
 
 @check_arguments_are((0, 3), Host)
-- 
1.8.3.1

From 9b09b2f8818de31d467ed7fae8f5328bbce79123 Mon Sep 17 00:00:00 2001
From: Oleg Fayans <ofay...@redhat.com>
Date: Tue, 10 May 2016 12:48:26 +0200
Subject: [PATCH] Added cleaning of /etc/httpd/alias upon server uninstallation

https://fedorahosted.org/freeipa/ticket/4639
---
 ipatests/test_integration/tasks.py | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/ipatests/test_integration/tasks.py b/ipatests/test_integration/tasks.py
index 88888db621b6c4c35fda74c1a957f128685682c3..c7146c9fe8f4247a95b659e024425602391fd680 100644
--- a/ipatests/test_integration/tasks.py
+++ b/ipatests/test_integration/tasks.py
@@ -719,6 +719,13 @@ def uninstall_master(host, ignore_topology_disconnect=True):
     host.run_command([paths.CERTUTIL, '-d', paths.NSS_DB_DIR, '-D',
                       '-n', 'External CA cert'],
                      raiseonerr=False)
+    # A workaround for https://fedorahosted.org/freeipa/ticket/4639
+    result = host.run_command([paths.CERTUTIL, '-L', '-d',
+                               paths.HTTPD_ALIAS_DIR])
+    for rawcert in result.stdout_text.split('\n')[4: -1]:
+        cert = rawcert.split('    ')[0]
+        host.run_command([paths.CERTUTIL, '-D', '-d', paths.HTTPD_ALIAS_DIR,
+                          '-n', cert])
     unapply_fixes(host)
 
 
-- 
1.8.3.1

From 3b357f164d6976b94fe0df612ba40c50e894da9d Mon Sep 17 00:00:00 2001
From: Oleg Fayans <ofay...@redhat.com>
Date: Tue, 10 May 2016 16:39:57 +0200
Subject: [PATCH] Fixed method failures during second call for the method

When called more than once during the same testrun,
enable_replication_debugging method fails to contact to ldap server. Can be
fixed/workedaround by explicitly specifying ldap server's hostname

https://fedorahosted.org/freeipa/ticket/5880
---
 ipatests/test_integration/tasks.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ipatests/test_integration/tasks.py b/ipatests/test_integration/tasks.py
index c6e368d44dcf38bcfa0c5cc36dcc18cec238c919..b867da03bf60c91b34b16ec79b0f3c4ef165e883 100644
--- a/ipatests/test_integration/tasks.py
+++ b/ipatests/test_integration/tasks.py
@@ -226,7 +226,8 @@ def enable_replication_debugging(host):
         """)
     host.run_command(['ldapmodify', '-x',
                       '-D', str(host.config.dirman_dn),
-                      '-w', host.config.dirman_password],
+                      '-w', host.config.dirman_password,
+                      '-h', host.hostname],
                      stdin_text=logging_ldif)
 
 
-- 
1.8.3.1

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to