#50903 Issue 50873 - Fix issues with healthcheck tool
Closed 3 years ago by spichugi. Opened 4 years ago by bsmejkal.
bsmejkal/389-ds-base health  into  master

@@ -0,0 +1,3 @@ 

+ """

+    :Requirement: 389-ds-base: HealthCheck

+ """ 

\ No newline at end of file

@@ -0,0 +1,565 @@ 

+ # --- BEGIN COPYRIGHT BLOCK ---

+ # Copyright (C) 2020 Red Hat, Inc.

+ # All rights reserved.

+ #

+ # License: GPL (version 3 or any later version).

+ # See LICENSE for details.

+ # --- END COPYRIGHT BLOCK ---

+ #

+ import pytest

+ import os

+ import subprocess

+ from lib389.utils import *

+ from lib389._constants import *

+ from lib389.cli_base import FakeArgs

+ from lib389.topologies import topology_st, topology_no_sample

+ from lib389.cli_ctl.health import health_check_run

+ from lib389.paths import Paths

+ 

+ 

+ ds_paths = Paths()

+ pytestmark = pytest.mark.skipif(ds_paths.perl_enabled and (os.getenv('PYINSTALL') is None),

+                                 reason="These tests need to use python installer")

+ 

+ if DEBUGGING:

+     logging.getLogger(__name__).setLevel(logging.DEBUG)

+ else:

+     logging.getLogger(__name__).setLevel(logging.INFO)

+ log = logging.getLogger(__name__)

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.xfail(ds_is_older("1.4.1"), reason="Not implemented")

+ def test_healthcheck_standalone(topology_st):

+     """Check functionality of HealthCheck Tool on standalone instance with no errors

+ 

+     :id: 4844b446-3939-4fbd-b14b-293b20bb8be0

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance

+         2. Use HealthCheck without --json option

+         3. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Success

+     """

+ 

+     standalone = topology_st.standalone

+     cmd_output = 'No issues found.'

+     json_ouput = '[]'

+ 

+     args = FakeArgs()

+     args.instance = standalone.serverid

+     args.verbose = standalone.verbose

+ 

+     log.info("Use healthcheck without --json option")

+     args.json = False

+     health_check_run(standalone, topology_st.logcap.log, args)

+     assert topology_st.logcap.contains(cmd_output)

+ 

+     log.info('Use healthcheck with --json option')

+     args.json = True

+     health_check_run(standalone, topology_st.logcap.log, args)

+     assert topology_st.logcap.contains(json_ouput)

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1796343

+ @pytest.mark.xfail(ds_is_older("1.4.1"), reason="Not implemented")

+ def test_health_check_database_not_initialized(topology_no_sample):

+     """Check if HealthCheck returns DSBLE0003 code

+ 

+     :id: 716b1ff1-94bd-4780-98b8-96ff8ef21e30

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance without example entries

+         2. Use HealthCheck without --json option

+         3. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. HealthCheck should return code DSBLE0003

+         3. HealthCheck should return code DSBLE0003

+     """

+ 

+     ret_code = 'DSBLE0003'

+     standalone = topology_no_sample.standalone

+ 

+     args = FakeArgs()

+     args.instance = standalone.serverid

+     args.verbose = standalone.verbose

+ 

+     log.info("Use healthcheck without --json option")

+     args.json = False

+     health_check_run(standalone, topology_no_sample.logcap.log, args)

+     assert topology_no_sample.logcap.contains(ret_code)

+     log.info("HealthCheck returned DSBLE0003")

+ 

+     log.info('Use healthcheck with --json option')

+     args.json = True

+     health_check_run(standalone, topology_no_sample.logcap.log, args)

+     assert topology_no_sample.logcap.contains(ret_code)

+     log.info("HealthCheck with --json argument returned DSBLE0003")

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_replication(request):

+     """Check functionality of HealthCheck Tool on replication instance with no errors

+ 

+     :id: 9ee6d491-d6d7-4c2c-ac78-70d08f054166

+     :setup: 2 MM topology

+     :steps:

+         1. Create a two masters replication topology

+         2. Use HealthCheck without --json option

+         3. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Success

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_backend_missing_mapping_tree(request):

+     """Check if HealthCheck returns DSBLE0001 and DSBLE0002 code

+ 

+     :id: 4c83ffcf-01a4-4ec8-a3d2-01022b566225

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Disable the dc=example,dc=com backend suffix entry in the mapping tree

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. Enable the dc=example,dc=com backend suffix entry in the mapping tree

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSBLE0001 and DSBLE0002 codes and related details

+         4. Healthcheck reports DSBLE0001 and DSBLE0002 codes and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_virtual_attr_incorrectly_indexed(request):

+     """Check if HealthCheck returns DSVIRTLE0001 code

+ 

+     :id: 1055173b-21aa-4aaa-9e91-4dc6c5e0c01f

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Create a CoS definition entry

+         3. Create the matching CoS template entry, with postalcode as virtual attribute

+         4. Create an index for postalcode

+         5. Use HealthCheck without --json option

+         6. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Success

+         4. Success

+         5. Healthcheck reports DSVIRTLE0001 code and related details

+         6. Healthcheck reports DSVIRTLE0001 code and related details

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_logging_format_should_be_revised(request):

+     """Check if HealthCheck returns DSCLE0001 code

+ 

+     :id: 277d7980-123b-481b-acba-d90921b9f5ac

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Set nsslapd-logging-hr-timestamps-enabled to ‘off’

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. Set nsslapd-logging-hr-timestamps-enabled to ‘on’

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSCLE0001 code and related details

+         4. Healthcheck reports DSCLE0001 code and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_insecure_pwd_hash_configured(request):

+     """Check if HealthCheck returns DSCLE0002 code

+ 

+     :id: 6baf949c-a5eb-4f4e-83b4-8302e677758a

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Configure an insecure passwordStorageScheme (as SHA) for the instance

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. Set passwordStorageScheme and nsslapd-rootpwstoragescheme to PBKDF2_SHA256

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSCLE0002 code and related details

+         4. Healthcheck reports DSCLE0002 code and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_min_allowed_tls_version_too_low(request):

+     """Check if HealthCheck returns DSELE0001 code

+ 

+     :id: a4be3390-9508-4827-8f82-e4e21081caab

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Set the TLS minimum version to TLS1.0

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. Set the TLS minimum version to TLS1.2

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSELE0001 code and related details

+         4. Healthcheck reports DSELE0001 code and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_RI_plugin_is_misconfigured(request):

+     """Check if HealthCheck returns DSRILE0001 code

+ 

+     :id: de2e90a2-89fe-472c-acdb-e13cbca5178d

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Configure the instance with Integrity Plugin

+         3. Set the referint-update-delay attribute of the RI plugin, to a value upper than 0

+         4. Use HealthCheck without --json option

+         5. Use HealthCheck with --json option

+         6. Set the referint-update-delay attribute to 0

+         7. Use HealthCheck without --json option

+         8. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Success

+         4. Healthcheck reports DSRILE0001 code and related details

+         5. Healthcheck reports DSRILE0001 code and related details

+         6. Success

+         7. Healthcheck reports no issue found

+         8. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_RI_plugin_missing_indexes(request):

+     """Check if HealthCheck returns DSRILE0002 code

+ 

+     :id: 05c55e37-bb3e-48d1-bbe8-29c980f94f10

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Configure the instance with Integrity Plugin

+         3. Change the index type of the member attribute index to ‘approx’

+         4. Use HealthCheck without --json option

+         5. Use HealthCheck with --json option

+         6. Set the index type of the member attribute index to ‘eq’

+         7. Use HealthCheck without --json option

+         8. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Success

+         4. Healthcheck reports DSRILE0002 code and related details

+         5. Healthcheck reports DSRILE0002 code and related details

+         6. Success

+         7. Healthcheck reports no issue found

+         8. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_replication_out_of_sync_broken(request):

+     """Check if HealthCheck returns DSREPLLE0001 code

+ 

+     :id: b5ae7cae-de0f-4206-95a4-f81538764bea

+     :setup: 3 MMR topology

+     :steps:

+         1. Create a 3 masters full-mesh topology, on M2 and M3 don’t set nsds5BeginReplicaRefresh:start

+         2. Perform modifications on M1

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSREPLLE0001 code and related details

+         4. Healthcheck reports DSREPLLE0001 code and related details

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_replication_presence_of_conflict_entries(request):

+     """Check if HealthCheck returns DSREPLLE0002 code

+ 

+     :id: 43abc6c6-2075-42eb-8fa3-aa092ff64cba

+     :setup: Replicated topology

+     :steps:

+         1. Create a replicated topology

+         2. Create conflict entries : different entries renamed to the same dn

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSREPLLE0002 code and related details

+         4. Healthcheck reports DSREPLLE0002 code and related details

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_replication_out_of_sync_not_broken(request):

+     """Check if HealthCheck returns DSREPLLE0003 code

+ 

+     :id: 8305000d-ba4d-4c00-8331-be0e8bd92150

+     :setup: 3 MMR topology

+     :steps:

+         1. Create a 3 masters full-mesh topology, all replicas being synchronized

+         2. stop M1

+         3. Perform an update on M2 and M3.

+         4. Check M2 and M3 are synchronized.

+         5. From M2, reinitialize the M3 agreement

+         6. Stop M2

+         7. Restart M1

+         8. Use HealthCheck without --json option

+         9. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Success

+         4. Success

+         5. Success

+         6. Success

+         7. Success

+         8. Healthcheck reports DSREPLLE0003 code and related details

+         9. Healthcheck reports DSREPLLE0003 code and related details

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_replication_presence_of_conflict_entries(request):

+     """Check if HealthCheck returns DSREPLLE0005 code

+ 

+     :id: d452a564-7b82-4c1a-b331-a71abbd82a10

+     :setup: Replicated topology

+     :steps:

+         1. Create a replicated topology

+         2. On M1, set nsds5replicaport for the replication agreement to an unreachable port on the replica

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. On M1, set nsds5replicaport for the replication agreement to a reachable port number

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSREPLLE0005 code and related details

+         4. Healthcheck reports DSREPLLE0005 code and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_changelog_trimming_not_configured(request):

+     """Check if HealthCheck returns DSCLLE0001 code

+ 

+     :id: c2165032-88ba-4978-a4ca-2fecfd8c35d8

+     :setup: Replicated topology

+     :steps:

+         1. Create a replicated topology

+         2. On M1, remove nsslapd-changelogmaxage from cn=changelog5,cn=config

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. On M1, set nsslapd-changelogmaxage to 30d

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSCLLE0001 code and related details

+         4. Healthcheck reports DSCLLE0001 code and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_certif_expiring_within_30d(request):

+     """Check if HealthCheck returns DSCERTLE0001 code

+ 

+     :id: c2165032-88ba-4978-a4ca-2fecfd8c35d8

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Use libfaketime to tell the process the date is within 30 days before certificate expiration

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSCERTLE0001 code and related details

+         4. Healthcheck reports DSCERTLE0001 code and related details

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_certif_expired(request):

+     """Check if HealthCheck returns DSCERTLE0002 code

+ 

+     :id: ceff2c22-62c0-4fd9-b737-930a88458d68

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Use libfaketime to tell the process the date is after certificate expiration

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSCERTLE0002 code and related details

+         4. Healthcheck reports DSCERTLE0002 code and related details

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_low_disk_space(request):

+     """Check if HealthCheck returns DSDSLE0001 code

+ 

+     :id: 144b335d-077e-430c-9c0e-cd6b0f2f73c1

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Get the free disk space for /

+         3. Use fallocate -l to create a file large enough for the use % be up 90%

+         4. Use HealthCheck without --json option

+         5. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. free disk space value

+         3. Success

+         3. Healthcheck reports DSDSLE0001 code and related details

+         4. Healthcheck reports DSDSLE0001 code and related details

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_resolvconf_bad_file_perm(request):

+     """Check if HealthCheck returns DSPERMLE0001 code

+ 

+     :id: 8572b9e9-70e7-49e9-b745-864f6f2468a8

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Change the /etc/resolv.conf file permissions to 444

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. set /etc/resolv.conf permissions to 644

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSPERMLE0001 code and related details

+         4. Healthcheck reports DSPERMLE0001 code and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ @pytest.mark.ds50873

+ @pytest.mark.bz1685160

+ @pytest.mark.skip(reason="Not implemented")

+ def test_healthcheck_security_bad_file_perm(request):

+     """Check if HealthCheck returns DSPERMLE0002 code

+ 

+     :id: ec137d66-bad6-4eed-90bd-fc1d572bbe1f

+     :setup: Standalone instance

+     :steps:

+         1. Create DS instance from template file

+         2. Change the /etc/dirsrv/slapd-xxx/pwdfile.txt permissions to 000

+         3. Use HealthCheck without --json option

+         4. Use HealthCheck with --json option

+         5. Change the /etc/dirsrv/slapd-xxx/pwdfile.txt permissions to 400

+         6. Use HealthCheck without --json option

+         7. Use HealthCheck with --json option

+     :expectedresults:

+         1. Success

+         2. Success

+         3. Healthcheck reports DSPERMLE0002 code and related details

+         4. Healthcheck reports DSPERMLE0002 code and related details

+         5. Success

+         6. Healthcheck reports no issue found

+         7. Healthcheck reports no issue found

+     """

+ 

+ 

+ if __name__ == '__main__':

+     # Run isolated

+     # -s for DEBUG mode

+     CURRENT_FILE = os.path.realpath(__file__)

@@ -35,7 +35,7 @@ 

      topology = create_topology({ReplicaRole.STANDALONE: 1}, None)

      topology.standalone.backends.create(properties={

          'cn': 'userRoot',

-         'suffix': DEFAULT_SUFFIX,

+         'nsslapd-suffix': DEFAULT_SUFFIX,

      })

      # Now apply sample entries

      centries = get_sample_entries(INSTALL_LATEST_CONFIG)
@@ -58,7 +58,7 @@ 

      topology = create_topology({ReplicaRole.STANDALONE: 1}, None)

      topology.standalone.backends.create(properties={

          'cn': 'userRoot',

-         'suffix': DEFAULT_SUFFIX,

+         'nsslapd-suffix': DEFAULT_SUFFIX,

      })

      # Now apply sample entries

      centries = get_sample_entries('001003006')

file modified
+43 -13
@@ -21,8 +21,11 @@ 

  from lib389.replica import ReplicationManager, Replicas

  from lib389.nss_ssl import NssSsl

  from lib389._constants import *

+ from lib389.cli_base import LogCapture

  

+ PYINSTALL = True if os.getenv('PYINSTALL') else False

  DEBUGGING = os.getenv('DEBUGGING', default=False)

+ 

  if DEBUGGING:

      logging.getLogger(__name__).setLevel(logging.DEBUG)

  else:
@@ -84,9 +87,11 @@ 

              instance.allocate(args_instance)

  

              instance_exists = instance.exists()

+ 

              if instance_exists:

-                 instance.delete()

-             instance.create()

+                 instance.delete(pyinstall=PYINSTALL)

+ 

+             instance.create(pyinstall=PYINSTALL)

              # We set a URL here to force ldap:// only. Once we turn on TLS

              # we'll flick this to ldaps.

              instance.use_ldap_uri()
@@ -246,11 +251,13 @@ 

          else:

              assert _remove_ssca_db(topology)

              if topology.standalone.exists():

-                 topology.standalone.delete()

+                 topology.standalone.delete(pyinstall=PYINSTALL)

      request.addfinalizer(fin)

  

+     topology.logcap = LogCapture()

      return topology

  

+ 

  gssapi_ack = pytest.mark.skipif(not os.environ.get('GSSAPI_ACK', False), reason="GSSAPI tests may damage system configuration.")

  

  @pytest.fixture(scope="module")
@@ -313,13 +320,36 @@ 

          else:

              assert _remove_ssca_db(topology)

              if topology.standalone.exists():

-                 topology.standalone.delete()

+                 topology.standalone.delete(pyinstall=PYINSTALL)

              krb.destroy_realm()

  

      request.addfinalizer(fin)

  

      return topology

  

+ 

+ @pytest.fixture(scope="module")

+ def topology_no_sample(request):

+     """Create instance without sample entries to reproduce not initialised database"""

+ 

+     topology = create_topology({ReplicaRole.STANDALONE: 1}, None)

+     topology.standalone.backends.create(properties={

+         'cn': 'userRoot',

+         'nsslapd-suffix': DEFAULT_SUFFIX,

+     })

+ 

+     def fin():

+         if DEBUGGING:

+             topology.standalone.stop()

+         else:

+             topology.standalone.delete(pyinstall=PYINSTALL)

+ 

+     request.addfinalizer(fin)

+ 

+     topology.logcap = LogCapture()

+     return topology

+ 

+ 

  @pytest.fixture(scope="module")

  def topology_i2(request):

      """Create two instance DS deployment"""
@@ -331,7 +361,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -348,7 +378,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -364,7 +394,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -381,7 +411,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -398,7 +428,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -415,7 +445,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -432,7 +462,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -450,7 +480,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology
@@ -486,7 +516,7 @@ 

              [inst.stop() for inst in topology]

          else:

              assert _remove_ssca_db(topology)

-             [inst.delete() for inst in topology if inst.exists()]

+             [inst.delete(pyinstall=PYINSTALL) for inst in topology if inst.exists()]

      request.addfinalizer(fin)

  

      return topology

Description:
Created sanity HealthCheck test to see if the tool works on standalone instance.
I had to create the instance from scratch, because that is how user would create it.
Also added test to check DSBLE0003.
More tests to check other error codes and sanity test for replication will be coming.

Relates: https://pagure.io/389-ds-base/issue/50873

Reviewed by: ???

If we have this error then something is wrong and there is no need to continue the execution. I am not sure why we catch the exception here and only log it (and then we continue the execution)

I think run_healthcheck and run_healthcheck_with_json can be easily merged and with_json will be just a parameter

You can use format_cmd_list(cmdline) from utils.py for better formatting.

This env is picked up in the topology, you don't need it here IIRC.

I'm pretty concerned about the structure of this test. An important aspect of how lib389 was structured is that you should be able to test parts in isolation - this test seems to break that, relying on calls to dscreate and dsctl directly. What happenes on a prefix install where dscreate is not in /bin? What happens if that version mismatches the developer instance? I think this structure really makes it more fragile.

There is a cli testing framework that allows you to test individual commands from dsctl/dsconf/dsidm, that does not require shelling out, or subprocess, and can have instances passed in, but no one seems to know about it or use it. See here:

https://pagure.io/389-ds-base/blob/master/f/src/lib389/lib389/tests/cli/idm_group_test.py

Sadly I think because it's not known abotu it,s been a bit neglected, but it's designed to:

  • Capture all command output for comparison in check
  • Allow creation of instances and commands of various structures.
  • To not need to rely on shell or fragile environment configurations.

I'd really urge you to consider swapping over to it. This is an example of how to structure a dsctl test:

https://pagure.io/389-ds-base/blob/master/f/src/lib389/lib389/tests/cli/ctl_dbtasks_test.py

rebased onto 5c63e0d152d026b445b15b26e72e853fc11c3fe7

3 years ago

@spichugi
Changes done as per suggestion, please review. Thanks!

@firstyear
Thank you for this suggestion. We mostly agreed to use subprocess because we want to test it on instance created from scratch and we need these tests done for reasons of time. But I will keep this in mind and I can convert the tests to framework later.

@spichugi
Changes done as per suggestion, please review. Thanks!
@firstyear
Thank you for this suggestion. We mostly agreed to use subprocess because we want to test it on instance created from scratch and we need these tests done for reasons of time.

Yes, but also please remember that upstream is not redhat internal ...

But I will keep this in mind and I can convert the tests to framework later.

Quick fixes, or "we'll convert later" never actually happens, ever.

There is literally a cli testing framework that exists for this purpose, does exactly what you need. It can create instances from scratch and even more. I ask you to please use it.

@firstyear
Ok, I will try to convert it to your suggested framework and see how it goes :)

Thank you - I think you'll find it will help you a lot to resolve issues and create tests. If you need more resources or help on this, please write here or email me (wbrown at suse.de)

Hey @firstyear, can you confirm that this framework actually works for you on the latest master?
Because it doesn't work with Python installer unless I do this:

diff --git a/src/lib389/lib389/tests/cli/__init__.py b/src/lib389/lib389/tests/cli/__init__.py
index 56da03a0b..51b3015bb 100644
--- a/src/lib389/lib389/tests/cli/__init__.py
+++ b/src/lib389/lib389/tests/cli/__init__.py
@@ -35,7 +35,7 @@ def topology_be_latest(request):
     topology = create_topology({ReplicaRole.STANDALONE: 1}, None)
     topology.standalone.backends.create(properties={
         'cn': 'userRoot',
-        'suffix': DEFAULT_SUFFIX,
+        'nsslapd-suffix': DEFAULT_SUFFIX,
     })
     # Now apply sample entries
     centries = get_sample_entries(INSTALL_LATEST_CONFIG)
@@ -58,7 +58,7 @@ def topology_be_001003006(request):
     topology = create_topology({ReplicaRole.STANDALONE: 1}, None)
     topology.standalone.backends.create(properties={
         'cn': 'userRoot',
-        'suffix': DEFAULT_SUFFIX,
+        'nsslapd-suffix': DEFAULT_SUFFIX,
     })
     # Now apply sample entries
     centries = get_sample_entries('001003006')

And it doesn't work with Perl installer at all, because it always expects some suffix to be created.

Also I don't see why these topologies have to live in a separate module. We can extend existing module instead of spreading several different approaches across lib389.

Errghh, yeah, it's because the cli parameters changed. I guess the test is showing you that it changed ....

Yes, it won't work with perl at all, it's python only.

It has a seperate topology because it hooks the dscreate front end api, rather than calling the python setup directly.

@firstyear
So I am getting a grasp of how the framework works but we found issue https://pagure.io/389-ds-base/issue/51019
This causes a problem when running healthcheck, because it will prompt you for bindDN and password and the tests will hang.

@firstyear
So I am getting a grasp of how the framework works but we found issue https://pagure.io/389-ds-base/issue/51019
This causes a problem when running healthcheck, because it will prompt you for bindDN and password and the tests will hang.

The problem is that lib389 topologies are still using the older installer(setup-ds.pl). We really need to get off of the legacy tools in lib389.

The problem is that lib389 topologies are still using the older installer(setup-ds.pl). We really need to get off of the legacy tools in lib389.

This is not true, we can swap between python and perl installer on the fly (via defaults.inf).
Even when python installer is used, it doesn't populate the same options as we use in dscreate.

I take that back. I tried once again with the python installer and ldapi works...

No, the topologies are agnostic to this, if defaults.inf has perl because you compiled with perl on the install, then dirsrv.create detects that and will use it. So ... don't compile with perl?

rebased onto 804e7266116ed411006741115be5d4023699022d

3 years ago

@vashirov
Can you please review if that is how we wanted to move the topologies? (So we don't use those in src/lib389/lib389/tests/cli/init.py)
And also the usage of env variable PYINSTALL.
Thanks!

This looks heaps better with the fake args by the way. I'll let @vashirov still check, but I'm much happier with this!

This indeed looks much better!

Few suggestions:
PYINSTALL unlike DEBUGGING is boolean. For DEBUGGING we planned to add multiple debug levels, but it's not there yet, so we just check for its presence, but not much else.
So with PYINSTALL we can do something like this:

PYINSTALL = True if os.getenv('PYINSTALL') else False

And then just pass PYINSTALL value everywhere for instance creation and deletion:

instance.create(pyinstall=PYINSTALL)
...
topology.standalone.delete(pyinstall=PYINSTALL)

So if PYINSTALL is present in the environment, python installer would be used. If not, lib389 will fallback to enable_perl value in defaults.inf and continue with either python or perl installer.

Please make sure you pass pyinstall to delete() everywhere, as of right now it stays on the system after the test.

Thanks!

rebased onto aa910e9ae762646109420feb1d9dacc4ce742be0

3 years ago

@vashirov
Changed the PYINSTALL variable, please review.
Thanks!

rebased onto 8f2a070a6b628a93c5cbbf56fb10e6b5a60eee9c

3 years ago

@vashirov
I added the pytestmark.skip to blank tests.

Please add a check for 'not ds_paths.perl_enabled' too, so we can run these tests if the package is built without perl and not using PYINSTALL explicitly.

rebased onto 1d772fab870e1de2a0308c44671fbd53d22e407a

3 years ago

rebased onto 497c18f

3 years ago

Pull-Request has been merged by vashirov

3 years ago

389-ds-base is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in 389-ds-base's github repository.

This pull request has been cloned to Github as issue and is available here:
- https://github.com/389ds/389-ds-base/issues/3956

If you want to continue to work on the PR, please navigate to the github issue,
download the patch from the attachments and file a new pull request.

Thank you for understanding. We apologize for all inconvenience.

Pull-Request has been closed by spichugi

3 years ago