From 8a08fb65a2bd8b8811e5648132512519ca992fab Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Dec 14 2018 18:27:42 +0000 Subject: Ticket 49994 - Add test for backend/suffix CLI functions Description: Add tests for the backend CLI functions. Also fixed a few minor bugs found from this testing in lib389 and in core DS(chaining). https://pagure.io/389-ds-base/issue/49994 Reviewed by: spichugi(Thanks!) --- diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c index 62fe54c..092b6b7 100644 --- a/ldap/servers/plugins/chainingdb/cb_instance.c +++ b/ldap/servers/plugins/chainingdb/cb_instance.c @@ -1840,7 +1840,7 @@ cb_instance_add_config_check_callback(Slapi_PBlock *pb __attribute__((unused)), if ((rc = cb_build_backend_instance_config(inst, e, 0)) != LDAP_SUCCESS) { slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, "cb_instance_add_config_check_callback - Can't instantiate chaining backend instance %s.\n", inst->inst_name); - *returncode = rc; + *returncode = LDAP_UNWILLING_TO_PERFORM; cb_instance_free(inst); return SLAPI_DSE_CALLBACK_ERROR; } diff --git a/src/cockpit/389-console/src/replication.js b/src/cockpit/389-console/src/replication.js index 1490bc0..13d0d40 100644 --- a/src/cockpit/389-console/src/replication.js +++ b/src/cockpit/389-console/src/replication.js @@ -1149,7 +1149,7 @@ $(document).ready( function() { if ( !('nsds5replicacredentials' in repl_agmt_values) || agmt_bindpw != repl_agmt_values['nsds5replicacredentials']) { - cmd_args.push('--bind-passwd="' + agmt_bindpw); + cmd_args.push('--bind-passwd=' + agmt_bindpw); } } // Frac attrs diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py index 3a9712e..eb1d60e 100644 --- a/src/lib389/lib389/backend.py +++ b/src/lib389/lib389/backend.py @@ -555,6 +555,9 @@ class Backend(DSLdapObject): return result return None + def get_suffix(self): + return self.get_attr_val_utf8_l('nsslapd-suffix') + def disable(self): # Disable backend (mapping tree) suffix = self.get_attr_val_utf8_l('nsslapd-suffix') diff --git a/src/lib389/lib389/chaining.py b/src/lib389/lib389/chaining.py index 7139c31..c528df8 100644 --- a/src/lib389/lib389/chaining.py +++ b/src/lib389/lib389/chaining.py @@ -105,7 +105,7 @@ class ChainingLink(DSLdapObject): """Get a MonitorChaining(DSLdapObject) for the chaining link :param rdn - The 'cn' value of the chaining link :returns - chaining monitor entry""" - links = Chaining_Links(self._instance).list() + links = ChainingLinks(self._instance).list() for link in links: cn = ensure_str(link.get_attr_val('cn')).lower() if cn == rdn.lower(): diff --git a/src/lib389/lib389/cli_conf/backend.py b/src/lib389/lib389/cli_conf/backend.py index 159c6b4..002b811 100644 --- a/src/lib389/lib389/cli_conf/backend.py +++ b/src/lib389/lib389/cli_conf/backend.py @@ -94,7 +94,8 @@ def _get_backend(inst, name): be_insts = Backends(inst).list() for be in be_insts: be_suffix = ensure_str(be.get_attr_val_utf8_l('nsslapd-suffix')).lower() - if be_suffix == name.lower(): + cn = ensure_str(be.get_attr_val_utf8_l('cn')).lower() + if be_suffix == name.lower() or cn == name.lower(): return be raise ValueError('Could not find backend suffix: {}'.format(name)) @@ -104,7 +105,8 @@ def _get_index(inst, bename, attr): be_insts = Backends(inst).list() for be in be_insts: be_suffix = ensure_str(be.get_attr_val_utf8_l('nsslapd-suffix')) - if be_suffix == bename.lower(): + cn = ensure_str(be.get_attr_val_utf8_l('cn')).lower() + if be_suffix == bename.lower() or cn == bename.lower(): for index in be.get_indexes().list(): idx_name = index.get_attr_val_utf8_l('cn').lower() if idx_name == attr.lower(): @@ -353,7 +355,7 @@ def get_monitor(inst, basedn, log, args): def backend_add_index(inst, basedn, log, args): be = _get_backend(inst, args.be_name) be.add_index(args.attr, args.index_type, args.matching_rule, reindex=args.reindex) - print("Successfull added index") + print("Successfully added index") def backend_set_index(inst, basedn, log, args): @@ -446,7 +448,7 @@ def backend_attr_encrypt(inst, basedn, log, args): if args.del_attr is not None: for attr in args.del_attr: be.del_encrypted_attr(attr) - if len(args.add_attr) > 1: + if len(args.del_attr) > 1: print("Successfully deleted encrypted attributes") else: print("Successfully deleted encrypted attribute") @@ -529,7 +531,7 @@ def backend_create_vlv(inst, basedn, log, args): 'vlvscope': args.search_scope, 'vlvfilter': args.search_filter} be.add_vlv_search(args.name, props) - print("Successfully create new VLV Search entry, now you can add indexes to it.") + print("Successfully created new VLV Search entry, now you can add indexes to it.") def backend_edit_vlv(inst, basedn, log, args): @@ -579,8 +581,9 @@ def backend_delete_vlv_index(inst, basedn, log, args): def backend_reindex_vlv(inst, basedn, log, args): be = _get_backend(inst, args.be_name) + suffix = be.get_suffix() vlv_search = be.get_vlv_searches(vlv_name=args.parent_name) - vlv_search.reindex(args.be_name, vlv_index=args.index_name) + vlv_search.reindex(suffix, vlv_index=args.index_name) print("Successfully reindexed VLV indexes") @@ -595,10 +598,10 @@ def create_parser(subparsers): suffix_subcommands = suffix_parser.add_subparsers(help="action") # List backends/suffixes - Zlist_parser = suffix_subcommands.add_parser('list', help="List current active backends and suffixes") - Zlist_parser.set_defaults(func=backend_list) - Zlist_parser.add_argument('--suffix', action='store_true', help='Just display the suffix, and not the backend name') - Zlist_parser.add_argument('--skip-subsuffixes', action='store_true', help='Skip over sub-suffixes') + list_parser = suffix_subcommands.add_parser('list', help="List current active backends and suffixes") + list_parser.set_defaults(func=backend_list) + list_parser.add_argument('--suffix', action='store_true', help='Just display the suffix, and not the backend name') + list_parser.add_argument('--skip-subsuffixes', action='store_true', help='Skip over sub-suffixes') # Get backend get_parser = suffix_subcommands.add_parser('get', help='Get the suffix entry') @@ -692,7 +695,7 @@ def create_parser(subparsers): reindex_parser = index_subcommands.add_parser('reindex', help='Reindex the database (for a single index or all indexes') reindex_parser.set_defaults(func=backend_reindex) reindex_parser.add_argument('--attr', action='append', help='The index attribute\'s name to reindex. Skip this argument to reindex all attributes') - reindex_parser.add_argument('be_name', help='The backend name or suffix to to reindex') + reindex_parser.add_argument('be_name', help='The backend name or suffix to reindex') ############################################# # VLV parser diff --git a/src/lib389/lib389/cli_conf/chaining.py b/src/lib389/lib389/cli_conf/chaining.py index cd2cf2b..c74a342 100644 --- a/src/lib389/lib389/cli_conf/chaining.py +++ b/src/lib389/lib389/cli_conf/chaining.py @@ -140,7 +140,8 @@ def create_link(inst, basedn, log, args, warn=True): def get_link(inst, basedn, log, args, warn=True): - rdn = _get_arg(args.selector, msg="Enter 'cn' to retrieve") + + rdn = _get_arg(args.CHAIN_NAME[0], msg="Enter 'cn' to retrieve") _generic_get(inst, basedn, log.getChild('get_link'), ChainingLinks, rdn, args) @@ -239,7 +240,7 @@ def create_parser(subparsers): get_link_parser = subcommands.add_parser('link-get', help='get chaining database link') get_link_parser.set_defaults(func=get_link) - get_link_parser.add_argument('selector', nargs='?', help='The chaining link name to search for') + get_link_parser.add_argument('CHAIN_NAME', nargs=1, help='The chaining link name to search for') edit_link_parser = subcommands.add_parser('link-set', add_help=False, conflict_handler='resolve', parents=[def_config_set_parser], help='Edit a database link to a remote server') diff --git a/src/lib389/lib389/index.py b/src/lib389/lib389/index.py index 7292234..4c472a6 100644 --- a/src/lib389/lib389/index.py +++ b/src/lib389/lib389/index.py @@ -106,12 +106,12 @@ class VLVSearch(DSLdapObject): def delete_all(self): # Delete the child indexes, then the parent search entry - print ("deleting main vlv search: " + self._dn) + print("deleting vlv search: " + self._dn) vlvsorts = VLVIndexes(self._instance, basedn=self._dn).list() for vlvsort in vlvsorts: - print("Deleting vlv idnex:: " + vlvsort._dn) + print("Deleting vlv index: " + vlvsort._dn + " ...") vlvsort.delete() - print ("deleting main vlv search") + print("deleting vlv search entry...") self.delete() def reindex(self, be_name, vlv_index=None): diff --git a/src/lib389/lib389/tests/cli/__init__.py b/src/lib389/lib389/tests/cli/__init__.py index 5a2da52..d6173dc 100644 --- a/src/lib389/lib389/tests/cli/__init__.py +++ b/src/lib389/lib389/tests/cli/__init__.py @@ -7,22 +7,18 @@ # --- END COPYRIGHT BLOCK --- import pytest - -from lib389 import DirSrv -from lib389.cli_base import LogCapture, FakeArgs - -from lib389.instance.setup import SetupDs -from lib389.instance.options import General2Base, Slapd2Base +import sys +import io +from lib389.cli_base import LogCapture from lib389._constants import * - from lib389.topologies import create_topology, DEBUGGING - -from lib389.utils import generate_ds_params from lib389.configurations import get_sample_entries + @pytest.fixture(scope="module") def topology(request): topology = create_topology({ReplicaRole.STANDALONE: 1}, None) + def fin(): if DEBUGGING: topology.standalone.stop() @@ -33,12 +29,13 @@ def topology(request): topology.logcap = LogCapture() return topology + @pytest.fixture(scope="module") def topology_be_latest(request): topology = create_topology({ReplicaRole.STANDALONE: 1}, None) - be = topology.standalone.backends.create(properties={ + topology.standalone.backends.create(properties={ 'cn': 'userRoot', - 'suffix' : DEFAULT_SUFFIX, + 'suffix': DEFAULT_SUFFIX, }) # Now apply sample entries centries = get_sample_entries(INSTALL_LATEST_CONFIG) @@ -55,12 +52,13 @@ def topology_be_latest(request): topology.logcap = LogCapture() return topology + @pytest.fixture(scope="module") def topology_be_001003006(request): topology = create_topology({ReplicaRole.STANDALONE: 1}, None) - be = topology.standalone.backends.create(properties={ + topology.standalone.backends.create(properties={ 'cn': 'userRoot', - 'suffix' : DEFAULT_SUFFIX, + 'suffix': DEFAULT_SUFFIX, }) # Now apply sample entries centries = get_sample_entries('001003006') @@ -78,3 +76,21 @@ def topology_be_001003006(request): return topology +def check_output(some_string, missing=False, ignorecase=True): + """Check the output of captured STDOUT. This assumes "sys.stdout = io.StringIO()" + otherwise there would be nothing to read + :param some_string - text to search for in output + :param missing - test if some_string is NOT present in output + :param ignorecase - Set whether to ignore the character case in both the output + and some_string + """ + output = sys.stdout.getvalue() + if ignorecase: + output = output.lower() + some_string = some_string.lower() + if missing: + assert(some_string not in output) + else: + assert(some_string in output) + # clear buffer + sys.stdout = io.StringIO() diff --git a/src/lib389/lib389/tests/cli/conf_backend_test.py b/src/lib389/lib389/tests/cli/conf_backend_test.py index c8ca24b..5043622 100644 --- a/src/lib389/lib389/tests/cli/conf_backend_test.py +++ b/src/lib389/lib389/tests/cli/conf_backend_test.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2018 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -7,66 +7,375 @@ # --- END COPYRIGHT BLOCK --- import os +import io +import sys import pytest +import time -from lib389.cli_conf.backend import backend_list, backend_get, backend_get_dn, backend_create, backend_delete, backend_export, backend_import +from lib389.cli_conf.backend import (backend_list, backend_get, backend_set, backend_get_dn, + backend_create, backend_delete, backend_export, + backend_import, backend_add_index, backend_list_index, + backend_set_index, backend_get_index, backend_reindex, + backend_del_index, backend_attr_encrypt, get_monitor, + backend_create_vlv, backend_del_vlv, backend_create_vlv_index, + backend_get_vlv, backend_edit_vlv, backend_reindex_vlv, + backend_list_vlv) from lib389.cli_base import LogCapture, FakeArgs -from lib389.tests.cli import topology +from lib389.tests.cli import check_output from lib389.topologies import topology_st from lib389.utils import ds_is_older pytestmark = pytest.mark.skipif(ds_is_older('1.4.0'), reason="Not implemented") +stdout = sys.__stdout__ +BE_NAME = 'backendRoot' +SUFFIX = 'dc=backend,dc=test' +SUB_BE_NAME = 'subBackendRoot' +SUB_SUFFIX = 'dc=sub_suffix,dc=backend,dc=test' + + +@pytest.fixture(scope="function") +def create_backend(topology_st, request): + """Create backend "dc=backend,dc=test" / backendRoot + """ + sys.stdout = io.StringIO() -# Topology is pulled from __init__.py -def test_basic(topology): - # args = FakeArgs() - backend_list(topology.standalone, None, topology.logcap.log, None) - # Assert none. - assert(topology.logcap.contains("No objects to display")) - topology.logcap.flush() - # Add a backend - # We need to fake the args - args.cn = 'userRoot' - args.nsslapd_suffix = 'dc=example,dc=com' - backend_create(topology.standalone, None, topology.logcap.log, args) - # Assert one. - backend_list(topology.standalone, None, topology.logcap.log, None) - # Assert none. - assert(topology.logcap.contains("userRoot")) - topology.logcap.flush() - # Assert we can get by name, suffix, dn - args.selector = 'userRoot' - backend_get(topology.standalone, None, topology.logcap.log, args) - # Assert none. - assert(topology.logcap.contains("userRoot")) - topology.logcap.flush() - # Assert we can get by name, suffix, dn - args.dn = 'cn=userRoot,cn=ldbm database,cn=plugins,cn=config' - backend_get_dn(topology.standalone, None, topology.logcap.log, args) - # Assert none. - assert(topology.logcap.contains("userRoot")) - topology.logcap.flush() - # delete it - backend_delete(topology.standalone, None, topology.logcap.log, args, warn=False) - backend_list(topology.standalone, None, topology.logcap.log, None) - # Assert none. - assert(topology.logcap.contains("No objects to display")) - topology.logcap.flush() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = False + args.nsslapd_suffix = SUFFIX + args.skip_subsuffixes = False + args.json = False + args.parent_suffix = False + args.create_entries = True + + args.suffix = SUFFIX + backend_create(topology_st.standalone, None, None, args) + check_output("The database was sucessfully created") + + def fin(): + sys.stdout = io.StringIO() + args = FakeArgs() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = SUFFIX + args.skip_subsuffixes = False + args.json = False + + # Delete backend + backend_delete(topology_st.standalone, None, None, args, warn=False) + check_output("sucessfully deleted") + + # Verify it's removed + args.suffix = False + backend_list(topology_st.standalone, None, None, args) + check_output("backendroot", missing=True) + + request.addfinalizer(fin) + + +def test_backend_cli(topology_st, create_backend): + """Test creating, listing, getting, and deleting a backend (and subsuffix) + :id: 800f432a-52ab-4661-ac66-a2bdd9b984d7 + :setup: Standalone instance + :steps: + 1. List backends + 2. Get backend by suffix + 3. Get backend by DN + 4. Add subsuffix + 5. Verify subsuffix + 6. Modify subsuffix + 7. Delete subsuffix + 8. Verify subsuffix is removed + 9. Modify backend + 10. Verify modify worked + 11. Test monitor works + :expectedresults: + 1. Success + 2. Success + 3. Success + 4. Success + 5. Success + 6. Success + 7. Success + 8. Success + 9. Success + 10. Success + 11. Success + """ + topology_st.logcap = LogCapture() + sys.stdout = io.StringIO() + + args = FakeArgs() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = False + args.nsslapd_suffix = SUFFIX + args.skip_subsuffixes = False + args.json = False + args.parent_suffix = False + args.create_entries = True + + # List backend + backend_list(topology_st.standalone, None, topology_st.logcap.log, args) + check_output(SUFFIX) + + # Get backend by by name + args.selector = BE_NAME + backend_get(topology_st.standalone, None, topology_st.logcap.log, args) + check_output(BE_NAME) + + # Get backend by DN + args.dn = 'cn=backendRoot,cn=ldbm database,cn=plugins,cn=config' + backend_get_dn(topology_st.standalone, None, topology_st.logcap.log, args) + check_output(BE_NAME) + + # Add subsuffix + args.parent_suffix = SUFFIX + args.suffix = SUB_SUFFIX + args.be_name = SUB_BE_NAME + backend_create(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("The database was sucessfully created") + + # Verify subsuffix + args.suffix = False + backend_list(topology_st.standalone, None, topology_st.logcap.log, args) + check_output(SUB_SUFFIX) + + # Modify subsuffix + args.enable = False + args.disable = False + args.add_referral = False + args.del_referral = False + args.cache_size = False + args.cache_memsize = False + args.dncache_memsize = False + args.enable_readonly = True # Setting nsslapd-readonly to "on" + args.disable_readonly = False + backend_set(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("sucessfully updated") + + # Verify modified worked + args.selector = SUB_BE_NAME + backend_get(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("nsslapd-readonly: on") + + # Delete subsuffix + args.suffix = SUB_SUFFIX + backend_delete(topology_st.standalone, None, topology_st.logcap.log, args, warn=False) + check_output("sucessfully deleted") + + # Verify it is deleted + args.suffix = False + backend_list(topology_st.standalone, None, topology_st.logcap.log, args) + check_output(SUB_BE_NAME, missing=True) + + # Modify backend (use same args from subsuffix modify) + args.be_name = BE_NAME + backend_set(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("sucessfully updated") + + # Verify modified worked + args.selector = BE_NAME + backend_get(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("nsslapd-readonly: on") + + # Run database monitor + args.suffix = SUFFIX + get_monitor(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("entrycachetries") + # Done! +def test_indexes(topology_st, create_backend): + """Test creating, listing, getting, and deleting an index + :id: 800f432a-52ab-4661-ac66-a2bdd9b984d78 + :setup: Standalone instance + :steps: + 1. Add index (description) + 2. Verify index was added + 3. Modify index (Add type) + 4. Verify index was modified + 5. Modify index (Delete type) + 6. Verify index was modified + 7. Modify index (Add MR) + 8. Verify index was modified + 9. Modify index (Delete MR) + 10. Verify index was modified + 11. Reindex index + 12. Remove index + 13. Verify index was removed + + :expectedresults: + 1. Success + 2. Success + 3. Success + 4. Success + 5. Success + 6. Success + 7. Success + 8. Success + 9. Success + 10. Success + 11. Success + 12. Success + 13. Success + """ + sys.stdout = io.StringIO() + + args = FakeArgs() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = False + args.nsslapd_suffix = SUFFIX + args.attr = 'description' + args.index_type = 'eq' + args.matching_rule = None + args.reindex = False + args.json = False + args.just_names = False + args.add_type = None + args.del_type = None + args.add_mr = None + args.del_mr = None + + # Add an index + backend_add_index(topology_st.standalone, None, None, args) + check_output("added index") + + # List indexes + backend_list_index(topology_st.standalone, None, None, args) + check_output("cn: description") + + # Modify index (Add type) + args.add_type = ['sub'] + backend_set_index(topology_st.standalone, None, None, args) + args.add_type = None + check_output("successfully updated") + + # Verify type was added + args.attr = ['description'] + backend_get_index(topology_st.standalone, None, None, args) + check_output("nsindextype: sub") + + # Remove index type sub + args.attr = 'description' + + args.del_type = ['sub'] + backend_set_index(topology_st.standalone, None, None, args) + args.del_type = None + check_output("successfully updated") + + # Verify type was removed + args.attr = ['description'] + backend_get_index(topology_st.standalone, None, None, args) + check_output("nsindextype: sub", missing=True) + + # Modify index (add MR) + args.attr = 'description' + args.add_mr = ['1.1.1.1.1.1'] + backend_set_index(topology_st.standalone, None, None, args) + args.add_mr = None + check_output("successfully updated") + + # Verify MR was added + args.attr = ['description'] + backend_get_index(topology_st.standalone, None, None, args) + check_output("nsmatchingrule: 1.1.1.1.1.1") + + # Modify index (delete MR) + args.attr = 'description' + args.del_mr = ['1.1.1.1.1.1'] + backend_set_index(topology_st.standalone, None, None, args) + args.del_mr = None + check_output("successfully updated") + + # Verify MR was added + args.attr = ['description'] + backend_get_index(topology_st.standalone, None, None, args) + check_output("nsmatchingrule: 1.1.1.1.1.1", missing=True) + + # Reindex index + backend_reindex(topology_st.standalone, None, None, args) + check_output("reindexed database") + time.sleep(2) + + # Delete index + backend_del_index(topology_st.standalone, None, None, args) + check_output("deleted index") + + # Verify index was removed + backend_list_index(topology_st.standalone, None, None, args) + check_output("cn: description", missing=True) + + +def test_attr_encrypt(topology_st, create_backend): + """Test adding/removing encrypted attrs + :id: 800f432a-52ab-4661-ac66-a2bdd9b984d789 + :setup: Standalone instance + :steps: + 1. Add encrypted attr + 2. Verify it succeeded + 3. Delete encrypted attr + 4. Verity it was removed + :expectedresults: + 1. Success + 2. Success + 3. Success + 4. Success + + """ + sys.stdout = io.StringIO() + args = FakeArgs() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = False + args.nsslapd_suffix = SUFFIX + args.json = False + args.just_names = False + args.list = False + args.add_attr = None + args.del_attr = None + + # Add an encrytped attr + args.add_attr = ['description'] + backend_attr_encrypt(topology_st.standalone, None, None, args) + args.add_attr = None + check_output("added encrypted attribute") + + # Verify it worked + args.list = True + backend_attr_encrypt(topology_st.standalone, None, None, args) + args.list = False + check_output("cn: description") + + # Delete encrypted attr + args.del_attr = ['description'] + backend_attr_encrypt(topology_st.standalone, None, None, args) + args.del_attr = None + check_output("deleted encrypted attribute") + + # Verify it worked + args.list = True + backend_attr_encrypt(topology_st.standalone, None, None, args) + args.list = False + check_output("cn: description", missing=True) + + def test_import_export(topology_st): BE_NAME = 'userRoot' EXCLUDE_SUFFIX = "ou=Groups,dc=example,dc=com" - LDIF_PATH = os.path.join(topology_st.standalone.ds_paths.ldif_dir, "test_import_export.ldif") + LDIF_NAME = "test_import_export.ldif" + LDIF_PATH = os.path.join(topology_st.standalone.ds_paths.ldif_dir, LDIF_NAME) topology_st.logcap = LogCapture() args = FakeArgs() + # Export the backend args.be_names = [BE_NAME] - args.ldif = LDIF_PATH + args.ldif = LDIF_NAME args.use_id2entry = None args.encrypted = None args.min_base64 = None @@ -77,17 +386,16 @@ def test_import_export(topology_st): args.include_suffixes = None args.exclude_suffixes = [EXCLUDE_SUFFIX] backend_export(topology_st.standalone, None, topology_st.logcap.log, args) - # Assert the right ldif was created - os.path.exists(LDIF_PATH) + + # Verify export worked assert os.path.exists(LDIF_PATH) with open(LDIF_PATH, 'r') as ldif: for line in ldif: assert not line.endswith("%s\n" % EXCLUDE_SUFFIX) - # Assert the ldif was created - os.path.exists(LDIF_PATH) + # Import the backend args.be_name = BE_NAME - args.ldifs = [LDIF_PATH] + args.ldifs = [LDIF_NAME] args.chunks_size = None args.encrypted = None args.gen_uniq_id = None @@ -95,6 +403,107 @@ def test_import_export(topology_st): args.include_suffixes = None args.exclude_suffixes = None backend_import(topology_st.standalone, None, topology_st.logcap.log, args) - # No error has happened! Done! - # Clean up os.remove(LDIF_PATH) + + # Done! + + +def test_vlv(topology_st, create_backend): + """Test creating, listing, getting, and deleting vlv's + :id: 800f432a-52ab-4661-ac66-a2bdd9b984d790 + :setup: Standalone instance + :steps: + 1. Add VLV search and index entries + 2. Verify they are created + 3. Edit VLV search and verify change + 4. Create additional VLV indexes + 5. Verity new indedxes were created + 6. Remove VLV indexes + 7. Verify indexes were removed + 8. Reindex VLV + :expectedresults: + 1. Success + 2. Success + 3. Success + 4. Success + 5. Success + 6. Success + 7. Success + 8. Success + + """ + sys.stdout = io.StringIO() + args = FakeArgs() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = False + args.nsslapd_suffix = SUFFIX + args.json = False + args.name = "myVLVSearch" + args.index_name = "myVLVIndex" + args.search_base = SUFFIX + args.search_scope = '2' + args.search_filter = "cn=*" + args.parent_name = args.name + args.index = False + args.reindex = False + args.sort = "cn sn" + args.just_names = False + + + # Create vlv search + backend_create_vlv(topology_st.standalone, None, None, args) + check_output("created new VLV Search entry") + + # Verify search is present + backend_get_vlv(topology_st.standalone, None, None, args) + check_output("VLV Search:") + + # Create VLV index under vlvSearch + backend_create_vlv_index(topology_st.standalone, None, None, args) + check_output("created new VLV index entry") + + # Verify index is present + backend_get_vlv(topology_st.standalone, None, None, args) + check_output("VLV Index:") + + # Edit VLV Search + args.search_base = None + args.search_scope = '0' + args.search_filter = None + args.sort = None + backend_edit_vlv(topology_st.standalone, None, None, args) + check_output("updated VLV search entry") + + # Verify edit was successful + backend_get_vlv(topology_st.standalone, None, None, args) + check_output("vlvscope: 0") + + # List vlv searches + backend_list_vlv(topology_st.standalone, None, None, args) + check_output("vlvbase: " + SUFFIX) + + # Add another index + args.index_name = "my2ndVLVIndex" + args.sort = "uid givenname" + backend_create_vlv_index(topology_st.standalone, None, None, args) + check_output("created new VLV index entry") + + # Verify new index was created + backend_get_vlv(topology_st.standalone, None, None, args) + check_output("vlvsort: uid givenname") + + # Reindex VLV + backend_reindex_vlv(topology_st.standalone, None, None, args) + check_output("reindexed VLV indexes") + time.sleep(2) + + # Delete VLV search and indexes + backend_del_vlv(topology_st.standalone, None, None, args) + check_output("deleted VLV search and its indexes") + + # List vlv searches/indexes + backend_list_vlv(topology_st.standalone, None, None, args) + check_output("") + + # Done! diff --git a/src/lib389/lib389/tests/cli/conf_chaining_test.py b/src/lib389/lib389/tests/cli/conf_chaining_test.py new file mode 100644 index 0000000..be19077 --- /dev/null +++ b/src/lib389/lib389/tests/cli/conf_chaining_test.py @@ -0,0 +1,198 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2018 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- + +import os +import io +import sys +import pytest +import time +from lib389.cli_conf.chaining import (config_get, config_set, def_config_get, def_config_set, + create_link, get_link, edit_link, delete_link, + monitor_link, list_links) +from lib389.cli_conf.backend import (backend_create, backend_delete, backend_list) +from lib389.cli_base import LogCapture, FakeArgs +from lib389.tests.cli import check_output +from lib389.topologies import topology_st + +from lib389.utils import ds_is_older +pytestmark = pytest.mark.skipif(ds_is_older('1.4.0'), reason="Not implemented") + +LINK_NAME = "mylink" +LINK_SUFFIX = "ou=link,dc=chaining,dc=test" +SUFFIX = "dc=chaining,dc=test" +BE_NAME = "chainingRoot" +stdout = sys.__stdout__ + + +@pytest.fixture(scope="function") +def create_backend(topology_st, request): + """Create backend "dc=backend,dc=test" / backendRoot + """ + sys.stdout = io.StringIO() + + args = FakeArgs() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = False + args.nsslapd_suffix = SUFFIX + args.skip_subsuffixes = False + args.json = False + args.parent_suffix = False + args.create_entries = True + args.suffix = SUFFIX + backend_create(topology_st.standalone, None, None, args) + check_output("The database was sucessfully created") + + def fin(): + sys.stdout = io.StringIO() + + args = FakeArgs() + args.cn = BE_NAME + args.be_name = BE_NAME + args.suffix = SUFFIX + args.skip_subsuffixes = False + args.json = False + + # Delete backend + backend_delete(topology_st.standalone, None, None, args, warn=False) + check_output("sucessfully deleted") + + # Verify it's removed + args.suffix = False + backend_list(topology_st.standalone, None, None, args) + check_output(BE_NAME, missing=True) + + request.addfinalizer(fin) + + +def test_chaining_cli(topology_st, create_backend): + """Test creating, listing, getting, and deleting a backend (and subsuffix) + :id: 800f432a-52ab-4661-ac66-a2bdd9b984d7 + :setup: Standalone instance + :steps: + 1. Update config controls and components + 2. Verify update to config + 3. Set default config + 4. Verify update to default config + 5. Add DB Link + 6. Verify Link was created + 7. Edit Link + 8. Verify edit to link + 9. Test monitor + 10. Delete link + 11. Verify link was deleted + :expectedresults: + 1. Success + 2. Success + 3. Success + 4. Success + 5. Success + 6. Success + 7. Success + 8. Success + 9. Success + 10. Success + 11. Success + """ + topology_st.logcap = LogCapture() + sys.stdout = io.StringIO() + args = FakeArgs() + args.CHAIN_NAME = [LINK_NAME] + args.suffix = LINK_SUFFIX + args.json = False + args.add_control = None + args.del_control = None + args.add_comp = None + args.del_comp = None + + # Set config (add control) + args.add_control = '1.1.1.1.1.1.1' + config_set(topology_st.standalone, None, None, args) + args.add_control = None + check_output("updated chaining configuration") + + # Verify config change + config_get(topology_st.standalone, None, None, args) + check_output("1.1.1.1.1.1.1") + + # Set config (delete control) + args.del_control = '1.1.1.1.1.1.1' + config_set(topology_st.standalone, None, None, args) + args.del_control = None + check_output("updated chaining configuration") + + # Verify config change + config_get(topology_st.standalone, None, None, args) + check_output("1.1.1.1.1.1.1", missing=True) + + # Set config (add comp) + args.add_comp = 'cn=test,cn=config' + config_set(topology_st.standalone, None, None, args) + args.add_comp = None + check_output("updated chaining configuration") + + # Verify config change + config_get(topology_st.standalone, None, None, args) + check_output('cn=test,cn=config') + + # Set config (delete comp) + args.del_comp = 'cn=test,cn=config' + config_set(topology_st.standalone, None, None, args) + args.del_comp = None + check_output("updated chaining configuration") + + # Verify config change + config_get(topology_st.standalone, None, None, args) + check_output("cn=test,cn=config", missing=True) + + # Set default config + args.time_limit = '5555' + def_config_set(topology_st.standalone, None, None, args) + check_output("updated chaining default instance creation configuration") + + # Verify default config change + def_config_get(topology_st.standalone, None, None, args) + check_output("nsslapd_timelimit: 5555") + + # Create database link + args.server_url = "ldap://localhost.localdomain" + args.bind_dn = "cn=link_admin," + SUFFIX + args.bind_pw = "secret_157" + args.bind_mech = "LDAP" + create_link(topology_st.standalone, None, None, args) + check_output("created database link") + + # Verify link was created + list_links(topology_st.standalone, None, topology_st.logcap.log, args) + check_output(LINK_NAME) + + # Edit link + args.bind_dn = "uid=newuser,cn=config" + args.suffix = None + edit_link(topology_st.standalone, None, None, args) + check_output("updated database chaining link") + + # Verify link was edited + args.cn = LINK_NAME + get_link(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("uid=newuser,cn=config") + + # Test monitor + time.sleep(2) # need time for link to start up and generate monitor + monitor_link(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("nssearchonelevelcount: ") + + # Delete link + delete_link(topology_st.standalone, None, topology_st.logcap.log, args) + check_output("deleted database link") + + # Verify link was deleted + list_links(topology_st.standalone, None, topology_st.logcap.log, args) + check_output(LINK_NAME, missing=True) + + # Done!