This is an automated email from the git hooks/post-receive script.
firstyear pushed a commit to branch master
in repository 389-ds-base.
commit d3ba228724f4be5039256f5ec9290d6357ff6b7f
Author: William Brown <firstyear(a)redhat.com>
Date: Wed Jan 10 09:59:23 2018 +1000
Ticket 49527 - Improve ds* cli tool testing
Bug Description: As we get closer to release it's important
our tests work correctly and are comprehensive.
Fix Description: Improve the directory manager test, backend test
user test and correct some incompatability with memberof test.
https://pagure.io/389-ds-base/issue/49527
Author: wibrown
Review by: mreynolds, spichugi (Thanks!)
---
src/lib389/cli/dsconf | 4 +
src/lib389/cli/dsctl | 2 +
src/lib389/cli/dsidm | 2 +
src/lib389/lib389/__init__.py | 3 +-
src/lib389/lib389/_mapped_object.py | 38 ++++++++-
src/lib389/lib389/backend.py | 5 +-
src/lib389/lib389/cli_base/__init__.py | 17 +++-
src/lib389/lib389/cli_conf/backend.py | 7 +-
src/lib389/lib389/cli_conf/directory_manager.py | 35 +++++++++
src/lib389/lib389/cli_idm/user.py | 41 +++++++++-
src/lib389/lib389/idm/directorymanager.py | 3 +
src/lib389/lib389/idm/nscontainer.py | 90 ++++++++++++++++++++++
src/lib389/lib389/plugins.py | 16 ++--
src/lib389/lib389/tests/cli/adm_instance_test.py | 1 -
src/lib389/lib389/tests/cli/conf_backend_test.py | 6 +-
.../tests/cli/conf_directory_manager_test.py | 22 ++++++
.../lib389/tests/cli/conf_plugins/memberof_test.py | 56 +++++++-------
src/lib389/lib389/tests/cli/ctl_dbtasks_test.py | 3 +
src/lib389/lib389/tests/cli/idm_user_test.py | 90 ++++++++++++++++++++++
.../tests/configurations/config_001003006_test.py | 57 +-------------
20 files changed, 391 insertions(+), 107 deletions(-)
diff --git a/src/lib389/cli/dsconf b/src/lib389/cli/dsconf
index ea1d056..b13183c 100755
--- a/src/lib389/cli/dsconf
+++ b/src/lib389/cli/dsconf
@@ -19,6 +19,7 @@ logging.basicConfig(format='%(message)s')
from lib389 import DirSrv
from lib389._constants import DN_CONFIG, DN_DM
from lib389.cli_conf import backend as cli_backend
+from lib389.cli_conf import directory_manager as cli_directory_manager
from lib389.cli_conf import plugin as cli_plugin
from lib389.cli_conf import schema as cli_schema
from lib389.cli_conf import health as cli_health
@@ -65,6 +66,7 @@ if __name__ == '__main__':
subparsers = parser.add_subparsers(help="resources to act upon")
cli_backend.create_parser(subparsers)
+ cli_directory_manager.create_parsers(subparsers)
cli_schema.create_parser(subparsers)
cli_health.create_parser(subparsers)
cli_plugin.create_parser(subparsers)
@@ -109,10 +111,12 @@ if __name__ == '__main__':
if args.verbose:
inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose)
args.func(inst, None, log, args)
+ log.info("Command successful.")
else:
try:
inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose)
args.func(inst, None, log, args)
+ log.info("Command successful.")
except Exception as e:
log.debug(e, exc_info=True)
log.error("Error: %s" % e)
diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl
index 36ecf99..02a1cff 100755
--- a/src/lib389/cli/dsctl
+++ b/src/lib389/cli/dsctl
@@ -80,9 +80,11 @@ if __name__ == '__main__':
if args.verbose:
result = args.func(inst, log, args)
+ log.info("Command successful.")
else:
try:
result = args.func(inst, log, args)
+ log.info("Command successful.")
except Exception as e:
log.debug(e, exc_info=True)
log.error("Error: %s" % str(e))
diff --git a/src/lib389/cli/dsidm b/src/lib389/cli/dsidm
index 1cfc415..d6a43ab 100755
--- a/src/lib389/cli/dsidm
+++ b/src/lib389/cli/dsidm
@@ -101,10 +101,12 @@ if __name__ == '__main__':
if args.verbose:
inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose)
args.func(inst, dsrc_inst['basedn'], log, args)
+ log.info("Command successful.")
else:
try:
inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose)
args.func(inst, dsrc_inst['basedn'], log, args)
+ log.info("Command successful.")
except Exception as e:
log.debug(e, exc_info=True)
log.error("Error: %s" % str(e))
diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py
index fab1ed1..b636ebb 100644
--- a/src/lib389/lib389/__init__.py
+++ b/src/lib389/lib389/__init__.py
@@ -3323,6 +3323,7 @@ class DirSrv(SimpleLDAPObject, object):
# This could be made to delete by filter ....
def delete_branch_s(self, basedn, scope):
ents = self.search_s(basedn, scope)
- for ent in ents:
+
+ for ent in sorted(ents, key=lambda e: len(e.dn), reverse=True):
self.log.debug("Delete entry children %s" % (ent.dn))
self.delete_s(ent.dn)
diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py
index 6161500..64ccd56 100644
--- a/src/lib389/lib389/_mapped_object.py
+++ b/src/lib389/lib389/_mapped_object.py
@@ -225,7 +225,12 @@ class DSLdapObject(DSLogging):
values = self.get_attr_vals_bytes(attr)
self._log.debug("%s contains %s" % (self._dn, values))
- return ensure_bytes(value).lower() in [x.lower() for x in values]
+ if value is None:
+ # We are just checking if SOMETHING is present ....
+ return len(values) > 0
+ else:
+ # Check if a value really does exist.
+ return ensure_bytes(value).lower() in [x.lower() for x in values]
def add(self, key, value):
"""Add an attribute with a value
@@ -287,7 +292,10 @@ class DSLdapObject(DSLogging):
:type key: str
"""
- self.set(key, None, action=ldap.MOD_DELETE)
+ try:
+ self.set(key, None, action=ldap.MOD_DELETE)
+ except ldap.NO_SUCH_ATTRIBUTE:
+ pass
# maybe this could be renamed?
def set(self, key, value, action=ldap.MOD_REPLACE):
@@ -491,6 +499,21 @@ class DSLdapObject(DSLogging):
return ensure_str(self.get_attr_val(key))
+ def get_attr_val_utf8_l(self, key):
+ """Get a single attribute value from the entry in utf8 type
+
+ :param key: An attribute name
+ :type key: str
+ :returns: A single bytes value
+ :raises: ValueError - if instance is offline
+ """
+
+ x = self.get_attr_val(key)
+ if x is not None:
+ return ensure_str(x).lower()
+ else:
+ return None
+
def get_attr_vals_utf8(self, key):
"""Get attribute values from the entry in utf8 type
@@ -502,6 +525,17 @@ class DSLdapObject(DSLogging):
return ensure_list_str(self.get_attr_vals(key))
+ def get_attr_vals_utf8_l(self, key):
+ """Get attribute values from the entry in utf8 type and lowercase
+
+ :param key: An attribute name
+ :type key: str
+ :returns: A single bytes value
+ :raises: ValueError - if instance is offline
+ """
+
+ return [x.lower() for x in ensure_list_str(self.get_attr_vals(key))]
+
def get_attr_val_int(self, key):
"""Get a single attribute value from the entry in int type
diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py
index 25a244c..3fcaf07 100644
--- a/src/lib389/lib389/backend.py
+++ b/src/lib389/lib389/backend.py
@@ -516,7 +516,10 @@ class Backend(DSLdapObject):
self._instance.index.delete_all(bename)
# Now remove our children, this is all ldbm config
- self._instance.delete_branch_s(self._dn, ldap.SCOPE_ONELEVEL)
+
+ configs = self._instance.search_s(self._dn, ldap.SCOPE_ONELEVEL)
+ for c in configs:
+ self._instance.delete_branch_s(c.dn, ldap.SCOPE_SUBTREE)
# The super will actually delete ourselves.
super(Backend, self).delete()
diff --git a/src/lib389/lib389/cli_base/__init__.py
b/src/lib389/lib389/cli_base/__init__.py
index 21bf3cc..4f5e7ad 100644
--- a/src/lib389/lib389/cli_base/__init__.py
+++ b/src/lib389/lib389/cli_base/__init__.py
@@ -23,14 +23,17 @@ def _input(msg):
return raw_input(msg)
-def _get_arg(args, msg=None):
+def _get_arg(args, msg=None, hidden=False):
if args is not None and len(args) > 0:
if type(args) is list:
return args[0]
else:
return args
else:
- return _input("%s : " % msg)
+ if hidden:
+ return getpass("%s : " % msg)
+ else:
+ return _input("%s : " % msg)
def _get_args(args, kws):
kwargs = {}
@@ -50,8 +53,11 @@ def _get_args(args, kws):
def _get_attributes(args, attrs):
kwargs = {}
for attr in attrs:
- if args is not None and hasattr(args, attr) and getattr(args, attr) is not None:
- kwargs[attr] = getattr(args, attr)
+ # Python can't represent a -, so it replaces it to _
+ # in many places, so we have to normalise this.
+ attr_normal = attr.replace('-', '_')
+ if args is not None and hasattr(args, attr_normal) and getattr(args, attr_normal)
is not None:
+ kwargs[attr] = getattr(args, attr_normal)
else:
if attr.lower() == 'userpassword':
kwargs[attr] = getpass("Enter value for %s : " % attr)
@@ -168,3 +174,6 @@ class FakeArgs(object):
def __init__(self):
pass
+ def __len__(self):
+ return len(self.__dict__.keys())
+
diff --git a/src/lib389/lib389/cli_conf/backend.py
b/src/lib389/lib389/cli_conf/backend.py
index e99cc82..4437725 100644
--- a/src/lib389/lib389/cli_conf/backend.py
+++ b/src/lib389/lib389/cli_conf/backend.py
@@ -10,6 +10,7 @@ from lib389.backend import Backend, Backends
import argparse
from lib389.cli_base import (
+ populate_attr_arguments,
_generic_list,
_generic_get,
_generic_get_dn,
@@ -37,7 +38,7 @@ def backend_get_dn(inst, basedn, log, args):
_generic_get_dn(inst, basedn, log.getChild('backend_get_dn'), MANY, dn)
def backend_create(inst, basedn, log, args):
- kwargs = _get_attributes(args.extra, SINGULAR._must_attributes)
+ kwargs = _get_attributes(args, Backend._must_attributes)
_generic_create(inst, basedn, log.getChild('backend_create'), MANY, kwargs)
def backend_delete(inst, basedn, log, args, warn=True):
@@ -65,9 +66,7 @@ def create_parser(subparsers):
create_parser = subcommands.add_parser('create', help='create')
create_parser.set_defaults(func=backend_create)
- create_parser.add_argument('extra', nargs=argparse.REMAINDER,
- help='A create may take one or more extra arguments. This parameter
provides them'
- )
+ populate_attr_arguments(create_parser, Backend._must_attributes)
delete_parser = subcommands.add_parser('delete', help='deletes the
object')
delete_parser.set_defaults(func=backend_delete)
diff --git a/src/lib389/lib389/cli_conf/directory_manager.py
b/src/lib389/lib389/cli_conf/directory_manager.py
new file mode 100644
index 0000000..56c3e73
--- /dev/null
+++ b/src/lib389/lib389/cli_conf/directory_manager.py
@@ -0,0 +1,35 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2017 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from lib389.idm.directorymanager import DirectoryManager
+
+from lib389.cli_base import _get_arg
+
+import argparse
+
+def password_change(inst, basedn, log, args):
+ # Due to an issue, we can't use extended op, so we have to
+ # submit the password directly to the field.
+
+ password = _get_arg(args.password, msg="Enter new directory manager
password", hidden=True)
+ dm = DirectoryManager(inst)
+ dm.change_password(password)
+
+def create_parsers(subparsers):
+ directory_manager_parser = subparsers.add_parser('directory_manager',
help="Manage the directory manager account")
+
+ subcommands = directory_manager_parser.add_subparsers(help='action')
+
+ password_change_parser = subcommands.add_parser('password_change',
help="Change the directory manager password")
+ password_change_parser.set_defaults(func=password_change)
+ # This is to put in a dummy attr that args can work with. We do this
+ # because the actual test case will over-ride it, but it prevents
+ # a user putting the pw on the cli.
+ password_change_parser.set_defaults(password=None)
+
+
diff --git a/src/lib389/lib389/cli_idm/user.py b/src/lib389/lib389/cli_idm/user.py
index 5b57862..70e7148 100644
--- a/src/lib389/lib389/cli_idm/user.py
+++ b/src/lib389/lib389/cli_idm/user.py
@@ -43,11 +43,34 @@ def create(inst, basedn, log, args):
kwargs = _get_attributes(args, MUST_ATTRIBUTES)
_generic_create(inst, basedn, log.getChild('_generic_create'), MANY, kwargs)
-def delete(inst, basedn, log, args):
- dn = _get_arg( args, msg="Enter dn to delete")
- _warn(dn, msg="Deleting %s %s" % (SINGULAR.__name__, dn))
+def delete(inst, basedn, log, args, warn=True):
+ dn = _get_arg( args.dn, msg="Enter dn to delete")
+ if warn:
+ _warn(dn, msg="Deleting %s %s" % (SINGULAR.__name__, dn))
_generic_delete(inst, basedn, log.getChild('_generic_delete'), SINGULAR, dn)
+def status(inst, basedn, log, args):
+ uid = _get_arg( args.uid, msg="Enter %s to check" % RDN)
+ uas = UserAccounts(inst, basedn)
+ acct = uas.get(uid)
+ acct_str = "locked: %s" % acct.is_locked()
+ log.info('uid: %s' % uid)
+ log.info(acct_str)
+
+def lock(inst, basedn, log, args):
+ uid = _get_arg( args.uid, msg="Enter %s to check" % RDN)
+ accounts = UserAccounts(inst, basedn)
+ acct = accounts.get(uid)
+ acct.lock()
+ log.info('locked %s' % uid)
+
+def unlock(inst, basedn, log, args):
+ uid = _get_arg( args.uid, msg="Enter %s to check" % RDN)
+ accounts = UserAccounts(inst, basedn)
+ acct = accounts.get(uid)
+ acct.unlock()
+ log.info('unlocked %s' % uid)
+
def create_parser(subparsers):
user_parser = subparsers.add_parser('user', help='Manage posix
users')
@@ -72,5 +95,17 @@ def create_parser(subparsers):
delete_parser.set_defaults(func=delete)
delete_parser.add_argument('dn', nargs='?', help='The dn to
delete')
+ lock_parser = subcommands.add_parser('lock', help='lock')
+ lock_parser.set_defaults(func=lock)
+ lock_parser.add_argument('uid', nargs='?', help='The uid to
lock')
+
+ status_parser = subcommands.add_parser('status', help='status')
+ status_parser.set_defaults(func=status)
+ status_parser.add_argument('uid', nargs='?', help='The uid to
check')
+
+ unlock_parser = subcommands.add_parser('unlock', help='unlock')
+ unlock_parser.set_defaults(func=unlock)
+ unlock_parser.add_argument('uid', nargs='?', help='The uid to
unlock')
+
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/lib389/lib389/idm/directorymanager.py
b/src/lib389/lib389/idm/directorymanager.py
index 4028fc6..150a549 100644
--- a/src/lib389/lib389/idm/directorymanager.py
+++ b/src/lib389/lib389/idm/directorymanager.py
@@ -30,6 +30,9 @@ class DirectoryManager(Account):
self._create_objectclasses = None
self._protected = True
+ def change_password(self, new_password):
+ self._instance.config.set('nsslapd-rootpw', new_password)
+
def bind(self, password=PW_DM, *args, **kwargs):
"""Bind as the Directory Manager. We have a default test password
that can be overriden.
diff --git a/src/lib389/lib389/idm/nscontainer.py b/src/lib389/lib389/idm/nscontainer.py
new file mode 100644
index 0000000..5ea2aff
--- /dev/null
+++ b/src/lib389/lib389/idm/nscontainer.py
@@ -0,0 +1,90 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2017, Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from lib389._mapped_object import DSLdapObject, DSLdapObjects
+
+class nsContainer(DSLdapObject):
+ """A single instance of a nsContainer. This is similar to OU
+ for organisation of a directory tree.
+
+ :param instance: An instance
+ :type instance: lib389.DirSrv
+ :param dn: Entry DN
+ :type dn: str
+ """
+
+ def __init__(self, instance, dn=None):
+ super(nsContainer, self).__init__(instance, dn)
+ self._rdn_attribute = 'cn'
+ self._must_attributes = ['cn']
+ self._create_objectclasses = [
+ 'top',
+ 'nscontainer',
+ ]
+ self._protected = False
+
+class nsContainers(DSLdapObjects):
+ """The set of nsContainers on the server.
+
+ :param instance: An instance
+ :type instance: lib389.DirSrv
+ :param basedn: Base DN for all group entries below
+ :type basedn: str
+ """
+
+ def __init__(self, instance, basedn):
+ super(nsContainers, self).__init__(instance)
+ self._objectclasses = [
+ 'nscontainer',
+ ]
+ self._filterattrs = ['cn']
+ self._childobject = nsContainer
+ self._basedn = basedn
+
+class nsHiddenContainer(DSLdapObject):
+ """A single instance of a hidden container. This is a combination
+ of nsContainer and ldapsubentry.
+
+ :param instance: An instance
+ :type instance: lib389.DirSrv
+ :param dn: Entry DN
+ :type dn: str
+ """
+
+ def __init__(self, instance, dn=None):
+ super(nsHiddenContainer, self).__init__(instance, dn)
+ self._rdn_attribute = 'cn'
+ self._must_attributes = ['cn']
+ self._create_objectclasses = [
+ 'top',
+ 'nscontainer',
+ 'ldapsubentry',
+ ]
+ self._protected = False
+
+class nsHiddenContainers(DSLdapObjects):
+ """The set of nsHiddenContainers on the server.
+
+ :param instance: An instance
+ :type instance: lib389.DirSrv
+ :param basedn: Base DN for all group entries below
+ :type basedn: str
+ """
+
+ def __init__(self, instance, basedn):
+ super(nsHiddenContainers, self).__init__(instance)
+ self._objectclasses = [
+ 'nscontainer',
+ 'ldapsubentry',
+ ]
+ self._filterattrs = ['cn']
+ self._childobject = nsHiddenContainer
+ self._basedn = basedn
+
+
+
diff --git a/src/lib389/lib389/plugins.py b/src/lib389/lib389/plugins.py
index e0080d6..8180e78 100644
--- a/src/lib389/lib389/plugins.py
+++ b/src/lib389/lib389/plugins.py
@@ -271,7 +271,7 @@ class MemberOfPlugin(Plugin):
self._must_attributes.extend(['memberOfGroupAttr',
'memberOfAttr'])
def get_attr(self):
- return self.get_attr_val('memberofattr')
+ return self.get_attr_val_utf8_l('memberofattr')
def get_attr_formatted(self):
return self.display_attr('memberofattr')
@@ -280,7 +280,7 @@ class MemberOfPlugin(Plugin):
self.set('memberofattr', attr)
def get_groupattr(self):
- return self.get_attr_vals('memberofgroupattr')
+ return self.get_attr_vals_utf8_l('memberofgroupattr')
def get_groupattr_formatted(self):
return self.display_attr('memberofgroupattr')
@@ -292,7 +292,7 @@ class MemberOfPlugin(Plugin):
self.remove('memberofgroupattr', attr)
def get_allbackends(self):
- return self.get_attr_val('memberofallbackends')
+ return self.get_attr_val_utf8_l('memberofallbackends')
def get_allbackends_formatted(self):
return self.display_attr('memberofallbackends')
@@ -304,7 +304,7 @@ class MemberOfPlugin(Plugin):
self.set('memberofallbackends', 'off')
def get_skipnested(self):
- return self.get_attr_val('memberofskipnested')
+ return self.get_attr_val_utf8_l('memberofskipnested')
def get_skipnested_formatted(self):
return self.display_attr('memberofskipnested')
@@ -316,7 +316,7 @@ class MemberOfPlugin(Plugin):
self.set('memberofskipnested', 'off')
def get_autoaddoc(self):
- return self.get_attr_val('memberofautoaddoc')
+ return self.get_attr_val_utf8_l('memberofautoaddoc')
def get_autoaddoc_formatted(self):
return self.display_attr('memberofautoaddoc')
@@ -328,7 +328,7 @@ class MemberOfPlugin(Plugin):
self.remove_all('memberofautoaddoc')
def get_entryscope(self, formatted=False):
- return self.get_attr_vals('memberofentryscope')
+ return self.get_attr_vals_utf8_l('memberofentryscope')
def get_entryscope_formatted(self):
return self.display_attr('memberofentryscope')
@@ -343,7 +343,7 @@ class MemberOfPlugin(Plugin):
self.remove_all('memberofentryscope')
def get_excludescope(self):
- return self.get_attr_vals('memberofentryscopeexcludesubtree')
+ return self.get_attr_vals_utf8_l('memberofentryscopeexcludesubtree')
def get_excludescope_formatted(self):
return self.display_attr('memberofentryscopeexcludesubtree')
@@ -768,7 +768,7 @@ class Plugins(DSLdapObjects):
# This is a map of plugin to type, so when we
# do a get / list / create etc, we can map to the correct
# instance.
- def __init__(self, instance):
+ def __init__(self, instance, basedn=None):
super(Plugins, self).__init__(instance=instance)
self._objectclasses = ['top', 'nsslapdplugin']
self._filterattrs = ['cn', 'nsslapd-pluginPath']
diff --git a/src/lib389/lib389/tests/cli/adm_instance_test.py
b/src/lib389/lib389/tests/cli/adm_instance_test.py
index 1c3d829..d8d2f41 100644
--- a/src/lib389/lib389/tests/cli/adm_instance_test.py
+++ b/src/lib389/lib389/tests/cli/adm_instance_test.py
@@ -14,7 +14,6 @@ from lib389 import DirSrv
from lib389.cli_base import LogCapture
-
def test_instance_list():
lc = LogCapture()
inst = DirSrv()
diff --git a/src/lib389/lib389/tests/cli/conf_backend_test.py
b/src/lib389/lib389/tests/cli/conf_backend_test.py
index da8ec73..3ed55aa 100644
--- a/src/lib389/lib389/tests/cli/conf_backend_test.py
+++ b/src/lib389/lib389/tests/cli/conf_backend_test.py
@@ -13,6 +13,9 @@ from lib389.cli_conf.backend import backend_list, backend_get,
backend_get_dn, b
from lib389.cli_base import LogCapture, FakeArgs
from lib389.tests.cli import topology
+from lib389.utils import ds_is_older
+pytestmark = pytest.mark.skipif(ds_is_older('1.4.0'), reason="Not
implemented")
+
# Topology is pulled from __init__.py
def test_backend_cli(topology):
#
@@ -23,7 +26,8 @@ def test_backend_cli(topology):
topology.logcap.flush()
# Add a backend
# We need to fake the args
- args.extra = ['dc=example,dc=com', 'userRoot']
+ 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)
diff --git a/src/lib389/lib389/tests/cli/conf_directory_manager_test.py
b/src/lib389/lib389/tests/cli/conf_directory_manager_test.py
new file mode 100644
index 0000000..96b0b17
--- /dev/null
+++ b/src/lib389/lib389/tests/cli/conf_directory_manager_test.py
@@ -0,0 +1,22 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2017 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import pytest
+
+from lib389.cli_conf.directory_manager import password_change
+
+from lib389.cli_base import LogCapture, FakeArgs
+from lib389.tests.cli import topology
+
+# Topology is pulled from __init__.py
+def test_directory_manager(topology):
+ #
+ args = FakeArgs()
+ args.password = 'password'
+ password_change(topology.standalone, None, topology.logcap.log, args)
+
diff --git a/src/lib389/lib389/tests/cli/conf_plugins/memberof_test.py
b/src/lib389/lib389/tests/cli/conf_plugins/memberof_test.py
index 339138f..903956d 100644
--- a/src/lib389/lib389/tests/cli/conf_plugins/memberof_test.py
+++ b/src/lib389/lib389/tests/cli/conf_plugins/memberof_test.py
@@ -56,24 +56,24 @@ def test_set_attr_with_illegal_value(topology):
def test_set_groupattr_with_legal_value(topology):
args = FakeArgs()
- args.value = "uniqueMember"
+ args.value = "uniquemember"
memberof_cli.add_groupattr(topology.standalone, None, topology.logcap.log, args)
assert topology.logcap.contains("successfully added memberOfGroupAttr
value")
topology.logcap.flush()
memberof_cli.display_groupattr(topology.standalone, None, topology.logcap.log, args)
- assert topology.logcap.contains(": uniqueMember")
+ assert topology.logcap.contains(": uniquemember")
topology.logcap.flush()
def test_set_groupattr_with_value_that_already_exists(topology):
plugin = MemberOfPlugin(topology.standalone)
# setup test
- if not "uniqueMember" in plugin.get_groupattr():
- plugin.add_groupattr("uniqueMember")
+ if not "uniquemember" in plugin.get_groupattr():
+ plugin.add_groupattr("uniquemember")
args = FakeArgs()
- args.value = "uniqueMember"
+ args.value = "uniquemember"
memberof_cli.add_groupattr(topology.standalone, None, topology.logcap.log, args)
assert topology.logcap.contains("already exists")
topology.logcap.flush()
@@ -89,18 +89,18 @@ def test_set_groupattr_with_illegal_value(topology):
def test_remove_groupattr_with_value_that_exists(topology):
plugin = MemberOfPlugin(topology.standalone)
# setup test
- if not "uniqueMember" in plugin.get_groupattr():
- plugin.add_groupattr("uniqueMember")
+ if not "uniquemember" in plugin.get_groupattr():
+ plugin.add_groupattr("uniquemember")
args = FakeArgs()
- args.value = "uniqueMember"
+ args.value = "uniquemember"
memberof_cli.remove_groupattr(topology.standalone, None, topology.logcap.log, args)
assert topology.logcap.contains("successfully removed memberOfGroupAttr
value")
topology.logcap.flush()
memberof_cli.display_groupattr(topology.standalone, None, topology.logcap.log, args)
- assert not topology.logcap.contains(": uniqueMember")
+ assert not topology.logcap.contains(": uniquemember")
topology.logcap.flush()
def test_remove_groupattr_with_value_that_doesnt_exist(topology):
@@ -361,14 +361,14 @@ def test_get_excludescope_when_not_set(topology):
def test_add_excludescope_with_legal_value(topology):
args = FakeArgs()
- args.value = "ou=People,dc=example,dc=com"
+ args.value = "ou=people,dc=example,dc=com"
memberof_cli.add_excludescope(topology.standalone, None, topology.logcap.log, args)
assert topology.logcap.contains("successfully added
memberOfEntryScopeExcludeSubtree value")
topology.logcap.flush()
args.value = None
memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log,
args)
- assert topology.logcap.contains(": ou=People,dc=example,dc=com")
+ assert topology.logcap.contains(": ou=people,dc=example,dc=com")
topology.logcap.flush()
args.value = "a=b"
@@ -378,7 +378,7 @@ def test_add_excludescope_with_legal_value(topology):
args.value = None
memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log,
args)
- assert topology.logcap.contains(": ou=People,dc=example,dc=com")
+ assert topology.logcap.contains(": ou=people,dc=example,dc=com")
assert topology.logcap.contains(": a=b")
topology.logcap.flush()
@@ -393,12 +393,12 @@ def test_add_excludescope_with_illegal_value(topology):
def test_add_excludescope_with_existing_value(topology):
plugin = MemberOfPlugin(topology.standalone)
# setup test
- if not "ou=People,dc=example,dc=com" in plugin.get_excludescope():
- plugin.add_excludescope("ou=People,dc=example,dc=com")
+ if not "ou=people,dc=example,dc=com" in plugin.get_excludescope():
+ plugin.add_excludescope("ou=people,dc=example,dc=com")
args = FakeArgs()
- args.value = "ou=People,dc=example,dc=com"
+ args.value = "ou=people,dc=example,dc=com"
memberof_cli.add_excludescope(topology.standalone, None, topology.logcap.log, args)
assert topology.logcap.contains('Value "{}" already
exists'.format(args.value))
topology.logcap.flush()
@@ -408,8 +408,8 @@ def test_remove_excludescope_with_existing_value(topology):
# setup test
if not "a=b" in plugin.get_excludescope():
plugin.add_excludescope("a=b")
- if not "ou=People,dc=example,dc=com" in plugin.get_excludescope():
- plugin.add_excludescope("ou=People,dc=example,dc=com")
+ if not "ou=people,dc=example,dc=com" in plugin.get_excludescope():
+ plugin.add_excludescope("ou=people,dc=example,dc=com")
args = FakeArgs()
@@ -420,7 +420,7 @@ def test_remove_excludescope_with_existing_value(topology):
args.value = None
memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log,
args)
- assert topology.logcap.contains(": ou=People,dc=example,dc=com")
+ assert topology.logcap.contains(": ou=people,dc=example,dc=com")
assert not topology.logcap.contains(": a=b")
topology.logcap.flush()
@@ -437,15 +437,15 @@ def test_remove_all_excludescope(topology):
# setup test
if not "a=b" in plugin.get_excludescope():
plugin.add_excludescope("a=b")
- if not "ou=People,dc=example,dc=com" in plugin.get_excludescope():
- plugin.add_excludescope("ou=People,dc=example,dc=com")
+ if not "ou=people,dc=example,dc=com" in plugin.get_excludescope():
+ plugin.add_excludescope("ou=people,dc=example,dc=com")
args = FakeArgs()
args.value = None
memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log,
args)
assert topology.logcap.contains(": a=b")
- assert topology.logcap.contains(": ou=People,dc=example,dc=com")
+ assert topology.logcap.contains(": ou=people,dc=example,dc=com")
topology.logcap.flush()
args.value = None
@@ -456,7 +456,7 @@ def test_remove_all_excludescope(topology):
args.value = None
memberof_cli.display_excludescope(topology.standalone, None, topology.logcap.log,
args)
assert not topology.logcap.contains(": a=b")
- assert not topology.logcap.contains(": ou=People,dc=example,dc=com")
+ assert not topology.logcap.contains(": ou=people,dc=example,dc=com")
topology.logcap.flush()
def test_add_entryscope_with_value_that_exists_in_excludescope(topology):
@@ -464,12 +464,12 @@ def
test_add_entryscope_with_value_that_exists_in_excludescope(topology):
# setup test
if not "dc=example,dc=com" in plugin.get_entryscope():
plugin.add_entryscope("dc=example,dc=com")
- if not "ou=People,dc=example,dc=com" in plugin.get_excludescope():
- plugin.add_excludescope("ou=People,dc=example,dc=com")
+ if not "ou=people,dc=example,dc=com" in plugin.get_excludescope():
+ plugin.add_excludescope("ou=people,dc=example,dc=com")
args = FakeArgs()
- args.value = "ou=People,dc=example,dc=com"
+ args.value = "ou=people,dc=example,dc=com"
memberof_cli.add_scope(topology.standalone, None, topology.logcap.log, args)
assert topology.logcap.contains("is also listed as an exclude suffix")
topology.logcap.flush()
@@ -479,12 +479,12 @@ def
test_add_excludescope_with_value_that_exists_in_entryscope(topology):
# setup test
if not "dc=example,dc=com" in plugin.get_entryscope():
plugin.add_entryscope("dc=example,dc=com")
- if not "ou=People,dc=example,dc=com" in plugin.get_excludescope():
- plugin.add_excludescope("ou=People,dc=example,dc=com")
+ if not "ou=people,dc=example,dc=com" in plugin.get_excludescope():
+ plugin.add_excludescope("ou=people,dc=example,dc=com")
args = FakeArgs()
- args.value = "ou=People,dc=example,dc=com"
+ args.value = "ou=people,dc=example,dc=com"
memberof_cli.add_scope(topology.standalone, None, topology.logcap.log, args)
assert topology.logcap.contains("is also listed as an exclude suffix")
topology.logcap.flush()
diff --git a/src/lib389/lib389/tests/cli/ctl_dbtasks_test.py
b/src/lib389/lib389/tests/cli/ctl_dbtasks_test.py
index f2c31e5..d77b72e 100644
--- a/src/lib389/lib389/tests/cli/ctl_dbtasks_test.py
+++ b/src/lib389/lib389/tests/cli/ctl_dbtasks_test.py
@@ -15,6 +15,9 @@ from lib389.cli_ctl.dbtasks import dbtasks_db2index, dbtasks_db2bak,
dbtasks_db2
from lib389.cli_base import LogCapture, FakeArgs
from lib389.tests.cli import topology, topology_be_latest
+from lib389.utils import ds_is_older
+pytestmark = pytest.mark.skipif(ds_is_older('1.4.0'), reason="Not
implemented")
+
def test_db2index(topology):
pass
diff --git a/src/lib389/lib389/tests/cli/idm_user_test.py
b/src/lib389/lib389/tests/cli/idm_user_test.py
new file mode 100644
index 0000000..da579b4
--- /dev/null
+++ b/src/lib389/lib389/tests/cli/idm_user_test.py
@@ -0,0 +1,90 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2017 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import pytest
+import ldap
+
+from lib389._constants import DEFAULT_SUFFIX, INSTALL_LATEST_CONFIG
+
+from lib389.cli_conf.backend import backend_create
+from lib389.cli_idm.initialise import initialise
+from lib389.cli_idm.user import get, create, delete, status, lock, unlock
+
+from lib389.cli_base import LogCapture, FakeArgs
+from lib389.tests.cli import topology
+
+from lib389.utils import ds_is_older
+pytestmark = pytest.mark.skipif(ds_is_older('1.4.0'), reason="Not
implemented")
+
+# Topology is pulled from __init__.py
+def test_user_tasks(topology):
+ #
+ be_args = FakeArgs()
+
+ be_args.cn = 'userRoot'
+ be_args.nsslapd_suffix = DEFAULT_SUFFIX
+ backend_create(topology.standalone, None, topology.logcap.log, be_args)
+
+ # And add the skeleton objects.
+ init_args = FakeArgs()
+ init_args.version = INSTALL_LATEST_CONFIG
+ initialise(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, init_args)
+
+ # First check that our test user isn't there:
+ topology.logcap.flush()
+ u_args = FakeArgs()
+ u_args.selector = 'testuser'
+ with pytest.raises(ldap.NO_SUCH_OBJECT):
+ get(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
+
+ # Create the user
+ topology.logcap.flush()
+ u_args.cn = 'testuser'
+ u_args.uid = 'testuser'
+ u_args.sn = 'testuser'
+ u_args.homeDirectory = '/home/testuser'
+ u_args.uidNumber = '5000'
+ u_args.gidNumber = '5000'
+ create(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
+
+ assert(topology.logcap.contains("Sucessfully created testuser"))
+ # Assert they exist
+ topology.logcap.flush()
+ get(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
+ assert(topology.logcap.contains('dn:
uid=testuser,ou=people,dc=example,dc=com'))
+
+ # Reset the password
+
+ # Lock the account, check status
+ topology.logcap.flush()
+ lock(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
+ assert(topology.logcap.contains('locked'))
+
+ topology.logcap.flush()
+ status(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
+ assert(topology.logcap.contains('locked: True'))
+
+ # Unlock check status
+ topology.logcap.flush()
+ unlock(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
+ assert(topology.logcap.contains('unlocked'))
+
+ topology.logcap.flush()
+ status(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
+ assert(topology.logcap.contains('locked: False'))
+
+ # Enroll a dummy cert
+
+ # Enroll a dummy sshkey
+
+ # Delete it
+ topology.logcap.flush()
+ u_args.dn = 'uid=testuser,ou=people,dc=example,dc=com'
+ delete(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args, warn=False)
+ assert(topology.logcap.contains('Sucessfully deleted
uid=testuser,ou=people,dc=example,dc=com'))
+
diff --git a/src/lib389/lib389/tests/configurations/config_001003006_test.py
b/src/lib389/lib389/tests/configurations/config_001003006_test.py
index 300122a..dfc8e81 100644
--- a/src/lib389/lib389/tests/configurations/config_001003006_test.py
+++ b/src/lib389/lib389/tests/configurations/config_001003006_test.py
@@ -18,15 +18,10 @@ from lib389 import DirSrv
from lib389._constants import *
from lib389.properties import *
-DEBUGGING = os.getenv('DEBUGGING', default=False)
-if DEBUGGING:
- logging.getLogger(__name__).setLevel(logging.DEBUG)
-else:
- logging.getLogger(__name__).setLevel(logging.INFO)
-log = logging.getLogger(__name__)
+from lib389.topologies import topology_st
-### WARNING:
-# We can't use topology here, as we need to force python install!
+from lib389.utils import ds_is_older
+pytestmark = pytest.mark.skipif(ds_is_older('1.4.0'), reason="Not
implemented")
REQUIRED_DNS = [
'dc=example,dc=com',
@@ -40,52 +35,6 @@ REQUIRED_DNS = [
'cn=Directory Administrators,dc=example,dc=com',
]
-class TopologyMain(object):
- def __init__(self, standalones=None, masters=None,
- consumers=None, hubs=None):
- if standalones:
- if isinstance(standalones, dict):
- self.ins = standalones
- else:
- self.standalone = standalones
- if masters:
- self.ms = masters
- if consumers:
- self.cs = consumers
- if hubs:
- self.hs = hubs
-
-(a)pytest.fixture(scope="module")
-def topology_st(request):
- """Create DS standalone instance"""
-
- if DEBUGGING:
- standalone = DirSrv(verbose=True)
- else:
- standalone = DirSrv(verbose=False)
- args_instance[SER_HOST] = HOST_STANDALONE1
- args_instance[SER_PORT] = PORT_STANDALONE1
- # args_instance[SER_SECURE_PORT] = SECUREPORT_STANDALONE1
- args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE1
- args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
- args_standalone = args_instance.copy()
- standalone.allocate(args_standalone)
- instance_standalone = standalone.exists()
- if instance_standalone:
- standalone.delete()
- standalone.create(pyinstall=True, version='001003006')
- standalone.open()
-
- def fin():
- if DEBUGGING:
- standalone.stop()
- else:
- standalone.delete()
-
- request.addfinalizer(fin)
-
- return TopologyMain(standalones=standalone)
-
def test_install_sample_entries(topology_st):
# Assert that our entries match.
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.