From c60142efda817f030a7495cd6fe4a19953e55afa Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 21 May 2013 13:40:27 +0200 Subject: Make an ipa-tests package Rename the 'tests' directory to 'ipa-tests', and create an ipa-tests RPM containing the test suite Part of the work for: https://fedorahosted.org/freeipa/ticket/3654 --- tests/__init__.py | 22 - tests/data.py | 38 - tests/i18n.py | 838 --------- tests/test_cmdline/cmdline.py | 70 - tests/test_cmdline/test_cli.py | 327 ---- tests/test_cmdline/test_help.py | 141 -- tests/test_cmdline/test_ipagetkeytab.py | 152 -- tests/test_install/0_reset.update | 5 - tests/test_install/1_add.update | 22 - tests/test_install/2_update.update | 3 - tests/test_install/3_update.update | 3 - tests/test_install/4_update.update | 4 - tests/test_install/5_update.update | 3 - tests/test_install/6_update.update | 3 - tests/test_install/8_badsyntax.update | 3 - tests/test_install/9_badsyntax.update | 3 - tests/test_install/__init__.py | 22 - tests/test_install/test_updates.py | 337 ---- tests/test_ipalib/__init__.py | 22 - tests/test_ipalib/test_backend.py | 272 --- tests/test_ipalib/test_base.py | 352 ---- tests/test_ipalib/test_capabilities.py | 33 - tests/test_ipalib/test_cli.py | 116 -- tests/test_ipalib/test_config.py | 609 ------ tests/test_ipalib/test_crud.py | 240 --- tests/test_ipalib/test_errors.py | 374 ---- tests/test_ipalib/test_frontend.py | 1188 ------------ tests/test_ipalib/test_messages.py | 89 - tests/test_ipalib/test_output.py | 89 - tests/test_ipalib/test_parameters.py | 1533 ---------------- tests/test_ipalib/test_plugable.py | 516 ------ tests/test_ipalib/test_rpc.py | 244 --- tests/test_ipalib/test_text.py | 334 ---- tests/test_ipalib/test_util.py | 26 - tests/test_ipalib/test_x509.py | 139 -- tests/test_ipapython/__init__.py | 22 - tests/test_ipapython/test_cookie.py | 478 ----- tests/test_ipapython/test_dn.py | 1937 -------------------- tests/test_ipapython/test_ipautil.py | 69 - tests/test_ipapython/test_keyring.py | 147 -- tests/test_ipapython/test_ssh.py | 76 - tests/test_ipaserver/__init__.py | 22 - tests/test_ipaserver/httptest.py | 52 - .../test_ipaserver/install/test_adtrustinstance.py | 59 - tests/test_ipaserver/test_changepw.py | 107 -- tests/test_ipaserver/test_ldap.py | 259 --- tests/test_ipaserver/test_rpcserver.py | 247 --- tests/test_pkcs10/__init__.py | 22 - tests/test_pkcs10/test0.csr | 12 - tests/test_pkcs10/test1.csr | 13 - tests/test_pkcs10/test2.csr | 15 - tests/test_pkcs10/test3.csr | 3 - tests/test_pkcs10/test4.csr | 4 - tests/test_pkcs10/test5.csr | 20 - tests/test_pkcs10/test_pkcs10.py | 124 -- tests/test_util.py | 367 ---- tests/test_xmlrpc/__init__.py | 22 - tests/test_xmlrpc/objectclasses.py | 163 -- tests/test_xmlrpc/test_attr.py | 562 ------ tests/test_xmlrpc/test_automember_plugin.py | 1095 ----------- tests/test_xmlrpc/test_automount_plugin.py | 582 ------ tests/test_xmlrpc/test_baseldap_plugin.py | 159 -- tests/test_xmlrpc/test_batch_plugin.py | 232 --- tests/test_xmlrpc/test_cert_plugin.py | 454 ----- tests/test_xmlrpc/test_config_plugin.py | 121 -- tests/test_xmlrpc/test_delegation_plugin.py | 300 --- tests/test_xmlrpc/test_dns_plugin.py | 1511 --------------- .../test_dns_realmdomains_integration.py | 168 -- tests/test_xmlrpc/test_external_members.py | 160 -- tests/test_xmlrpc/test_group_plugin.py | 1046 ----------- tests/test_xmlrpc/test_hbac_plugin.py | 497 ----- tests/test_xmlrpc/test_hbacsvcgroup_plugin.py | 256 --- tests/test_xmlrpc/test_hbactest_plugin.py | 217 --- tests/test_xmlrpc/test_host_plugin.py | 939 ---------- tests/test_xmlrpc/test_hostgroup_plugin.py | 313 ---- tests/test_xmlrpc/test_krbtpolicy.py | 150 -- tests/test_xmlrpc/test_nesting.py | 797 -------- tests/test_xmlrpc/test_netgroup_plugin.py | 1361 -------------- tests/test_xmlrpc/test_passwd_plugin.py | 69 - tests/test_xmlrpc/test_permission_plugin.py | 972 ---------- tests/test_xmlrpc/test_ping_plugin.py | 53 - tests/test_xmlrpc/test_privilege_plugin.py | 412 ----- tests/test_xmlrpc/test_pwpolicy_plugin.py | 244 --- tests/test_xmlrpc/test_range_plugin.py | 536 ------ tests/test_xmlrpc/test_realmdomains_plugin.py | 164 -- tests/test_xmlrpc/test_replace.py | 236 --- tests/test_xmlrpc/test_role_plugin.py | 625 ------- tests/test_xmlrpc/test_selfservice_plugin.py | 290 --- tests/test_xmlrpc/test_selinuxusermap_plugin.py | 934 ---------- tests/test_xmlrpc/test_service_plugin.py | 632 ------- tests/test_xmlrpc/test_sudocmd_plugin.py | 327 ---- tests/test_xmlrpc/test_sudocmdgroup_plugin.py | 693 ------- tests/test_xmlrpc/test_sudorule_plugin.py | 781 -------- tests/test_xmlrpc/test_trust_plugin.py | 159 -- tests/test_xmlrpc/test_user_plugin.py | 1837 ------------------- tests/test_xmlrpc/xmlrpc_test.py | 329 ---- tests/util.py | 637 ------- 97 files changed, 33262 deletions(-) delete mode 100644 tests/__init__.py delete mode 100644 tests/data.py delete mode 100755 tests/i18n.py delete mode 100644 tests/test_cmdline/cmdline.py delete mode 100644 tests/test_cmdline/test_cli.py delete mode 100644 tests/test_cmdline/test_help.py delete mode 100644 tests/test_cmdline/test_ipagetkeytab.py delete mode 100644 tests/test_install/0_reset.update delete mode 100644 tests/test_install/1_add.update delete mode 100644 tests/test_install/2_update.update delete mode 100644 tests/test_install/3_update.update delete mode 100644 tests/test_install/4_update.update delete mode 100644 tests/test_install/5_update.update delete mode 100644 tests/test_install/6_update.update delete mode 100644 tests/test_install/8_badsyntax.update delete mode 100644 tests/test_install/9_badsyntax.update delete mode 100644 tests/test_install/__init__.py delete mode 100644 tests/test_install/test_updates.py delete mode 100644 tests/test_ipalib/__init__.py delete mode 100644 tests/test_ipalib/test_backend.py delete mode 100644 tests/test_ipalib/test_base.py delete mode 100644 tests/test_ipalib/test_capabilities.py delete mode 100644 tests/test_ipalib/test_cli.py delete mode 100644 tests/test_ipalib/test_config.py delete mode 100644 tests/test_ipalib/test_crud.py delete mode 100644 tests/test_ipalib/test_errors.py delete mode 100644 tests/test_ipalib/test_frontend.py delete mode 100644 tests/test_ipalib/test_messages.py delete mode 100644 tests/test_ipalib/test_output.py delete mode 100644 tests/test_ipalib/test_parameters.py delete mode 100644 tests/test_ipalib/test_plugable.py delete mode 100644 tests/test_ipalib/test_rpc.py delete mode 100644 tests/test_ipalib/test_text.py delete mode 100644 tests/test_ipalib/test_util.py delete mode 100644 tests/test_ipalib/test_x509.py delete mode 100644 tests/test_ipapython/__init__.py delete mode 100644 tests/test_ipapython/test_cookie.py delete mode 100644 tests/test_ipapython/test_dn.py delete mode 100644 tests/test_ipapython/test_ipautil.py delete mode 100644 tests/test_ipapython/test_keyring.py delete mode 100644 tests/test_ipapython/test_ssh.py delete mode 100644 tests/test_ipaserver/__init__.py delete mode 100644 tests/test_ipaserver/httptest.py delete mode 100755 tests/test_ipaserver/install/test_adtrustinstance.py delete mode 100644 tests/test_ipaserver/test_changepw.py delete mode 100644 tests/test_ipaserver/test_ldap.py delete mode 100644 tests/test_ipaserver/test_rpcserver.py delete mode 100644 tests/test_pkcs10/__init__.py delete mode 100644 tests/test_pkcs10/test0.csr delete mode 100644 tests/test_pkcs10/test1.csr delete mode 100644 tests/test_pkcs10/test2.csr delete mode 100644 tests/test_pkcs10/test3.csr delete mode 100644 tests/test_pkcs10/test4.csr delete mode 100644 tests/test_pkcs10/test5.csr delete mode 100644 tests/test_pkcs10/test_pkcs10.py delete mode 100644 tests/test_util.py delete mode 100644 tests/test_xmlrpc/__init__.py delete mode 100644 tests/test_xmlrpc/objectclasses.py delete mode 100644 tests/test_xmlrpc/test_attr.py delete mode 100644 tests/test_xmlrpc/test_automember_plugin.py delete mode 100644 tests/test_xmlrpc/test_automount_plugin.py delete mode 100644 tests/test_xmlrpc/test_baseldap_plugin.py delete mode 100644 tests/test_xmlrpc/test_batch_plugin.py delete mode 100644 tests/test_xmlrpc/test_cert_plugin.py delete mode 100644 tests/test_xmlrpc/test_config_plugin.py delete mode 100644 tests/test_xmlrpc/test_delegation_plugin.py delete mode 100644 tests/test_xmlrpc/test_dns_plugin.py delete mode 100644 tests/test_xmlrpc/test_dns_realmdomains_integration.py delete mode 100644 tests/test_xmlrpc/test_external_members.py delete mode 100644 tests/test_xmlrpc/test_group_plugin.py delete mode 100644 tests/test_xmlrpc/test_hbac_plugin.py delete mode 100644 tests/test_xmlrpc/test_hbacsvcgroup_plugin.py delete mode 100644 tests/test_xmlrpc/test_hbactest_plugin.py delete mode 100644 tests/test_xmlrpc/test_host_plugin.py delete mode 100644 tests/test_xmlrpc/test_hostgroup_plugin.py delete mode 100644 tests/test_xmlrpc/test_krbtpolicy.py delete mode 100644 tests/test_xmlrpc/test_nesting.py delete mode 100644 tests/test_xmlrpc/test_netgroup_plugin.py delete mode 100644 tests/test_xmlrpc/test_passwd_plugin.py delete mode 100644 tests/test_xmlrpc/test_permission_plugin.py delete mode 100644 tests/test_xmlrpc/test_ping_plugin.py delete mode 100644 tests/test_xmlrpc/test_privilege_plugin.py delete mode 100644 tests/test_xmlrpc/test_pwpolicy_plugin.py delete mode 100644 tests/test_xmlrpc/test_range_plugin.py delete mode 100644 tests/test_xmlrpc/test_realmdomains_plugin.py delete mode 100644 tests/test_xmlrpc/test_replace.py delete mode 100644 tests/test_xmlrpc/test_role_plugin.py delete mode 100644 tests/test_xmlrpc/test_selfservice_plugin.py delete mode 100644 tests/test_xmlrpc/test_selinuxusermap_plugin.py delete mode 100644 tests/test_xmlrpc/test_service_plugin.py delete mode 100644 tests/test_xmlrpc/test_sudocmd_plugin.py delete mode 100644 tests/test_xmlrpc/test_sudocmdgroup_plugin.py delete mode 100644 tests/test_xmlrpc/test_sudorule_plugin.py delete mode 100644 tests/test_xmlrpc/test_trust_plugin.py delete mode 100644 tests/test_xmlrpc/test_user_plugin.py delete mode 100644 tests/test_xmlrpc/xmlrpc_test.py delete mode 100644 tests/util.py (limited to 'tests') diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 3dc405f01..000000000 --- a/tests/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Package containing all unit tests. -""" diff --git a/tests/data.py b/tests/data.py deleted file mode 100644 index 9332a53a5..000000000 --- a/tests/data.py +++ /dev/null @@ -1,38 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Data frequently used in the unit tests, especially Unicode related tests. -""" - -import struct - - -# A string that should have bytes 'x\00' through '\xff': -binary_bytes = ''.join(struct.pack('B', d) for d in xrange(256)) -assert '\x00' in binary_bytes and '\xff' in binary_bytes -assert type(binary_bytes) is str and len(binary_bytes) == 256 - -# A UTF-8 encoded str: -utf8_bytes = '\xd0\x9f\xd0\xb0\xd0\xb2\xd0\xb5\xd0\xbb' - -# The same UTF-8 data decoded (a unicode instance): -unicode_str = u'\u041f\u0430\u0432\u0435\u043b' -assert utf8_bytes.decode('UTF-8') == unicode_str -assert unicode_str.encode('UTF-8') == utf8_bytes diff --git a/tests/i18n.py b/tests/i18n.py deleted file mode 100755 index 9c8479bb0..000000000 --- a/tests/i18n.py +++ /dev/null @@ -1,838 +0,0 @@ -#!/usr/bin/python -# Authors: -# John Dennis -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -# WARNING: Do not import ipa modules, this is also used as a -# stand-alone script (invoked from install/po Makefile). -import optparse -import sys -import gettext -import locale -import re -import os -import traceback -import polib -from collections import namedtuple - -''' -We test our translations by taking the original untranslated string -(e.g. msgid) and prepend a prefix character and then append a suffix -character. The test consists of asserting that the first character in the -translated string is the prefix, the last character in the translated string -is the suffix and the everything between the first and last character exactly -matches the original msgid. - -We use unicode characters not in the ascii character set for the prefix and -suffix to enhance the test. To make reading the translated string easier the -prefix is the unicode right pointing arrow and the suffix left pointing arrow, -thus the translated string looks like the original string enclosed in -arrows. In ASCII art the string "foo" would render as: --->foo<-- -''' - -#------------------------------------------------------------------------------- - -verbose = False -print_traceback = False -pedantic = False -show_strings = True - -# Unicode right pointing arrow -prefix = u'\u2192' # utf-8 == '\xe2\x86\x92' -# Unicode left pointing arrow -suffix = u'\u2190' # utf-8 == '\xe2\x86\x90' - -page_width = 80 -section_seperator = '=' * page_width -entry_seperator = '-' * page_width - -#------------------------------------------------------------------------------- -# For efficiency compile these regexps just once -_substitution_regexps = [re.compile(r'%[srduoxf]\b'), # e.g. %s - re.compile(r'%\(\w+\)[srduoxf]\b'), # e.g. %(foo)s - re.compile(r'\$\w+'), # e.g. $foo - re.compile(r'\${\w+}'), # e.g. ${foo} - re.compile(r'\$\(\w+\)') # e.g. $(foo) - ] -# Python style substitution, e.g. %(foo)s -# where foo is the key and s is the format char -# group 1: whitespace between % and ( -# group 2: whitespace between ( and key -# group 3: whitespace between key and ) -# group 4: whitespace between ) and format char -# group 5: format char -_python_substitution_regexp = re.compile(r'%(\s*)\((\s*)\w+(\s*)\)(\s*)([srduoxf]\b)?') - -# Shell style substitution, e.g. $foo $(foo) ${foo} -# where foo is the variable -_shell_substitution_regexp = re.compile(r'\$(\s*)([({]?)(\s*)\w+(\s*)([)}]?)') -# group 1: whitespace between $ and delimiter -# group 2: begining delimiter -# group 3: whitespace between beginning delmiter and variable -# group 4: whitespace between variable and ending delimiter -# group 5: ending delimiter - -printf_fmt_re = re.compile( - r"%" # start - "(\d+\$)?" # fmt_arg (group 1) - "(([#0 +'I]|-(?!\d))*)" # flags (group 2) - "(([+-]?([1-9][0-9]*)?)|(\*|\*\d+\$))?" # width (group 4) - "(\.((-?\d*)|(\*|)|(\*\d+\$)))?" # precision (group 8) - "(h|hh|l|ll|L|j|z|t)?" # length (group 13) - "([diouxXeEfFgGaAcspnm%])") # conversion (group 14) - -#------------------------------------------------------------------------------- - -def get_prog_langs(entry): - ''' - Given an entry in a pot or po file return a set of the - programming languges it was found in. It needs to be a set - because the same msgid may appear in more than one file which may - be in different programming languages. - - Note: One might think you could use the c-format etc. flags to - attached to entry to make this determination, but you can't. Those - flags refer to the style of the string not the programming - language it came from. Also the flags are often omitted and/or are - inaccurate. - - For now we just look at the file extension. If we knew the path to - the file we could use other heuristics such as looking for the - shbang interpreter string. - - The set of possible language types witch might be returned are: - - * c - * python - - ''' - result = set() - - for location in entry.occurrences: - filename = location[0] - ext = os.path.splitext(filename)[1] - - if ext in ('.c', '.h', '.cxx', '.cpp', '.hxx'): - result.add('c') - elif ext in ('.py'): - result.add('python') - - return result - -def parse_printf_fmt(s): - ''' - Parse a printf style format string and return a list of format - conversions found in the string. - - Each conversion specification is introduced by the character %, and - ends with a conversion specifier. In between there may be (in this - order) zero or more flags, an optional minimum field width, an - optional precision and an optional length modifier. See "man 3 - printf" for details. - - Each item in the returned list is a dict whose keys are the - sub-parts of a conversion specification. The key and values are: - - fmt - The entire format conversion specification - fmt_arg - The positional index of the matching argument in the argument - list, e.g. %1$ indicates the first argument in the argument - will be read for this conversion, excludes the leading % but - includes the trailing $, 1$ is the fmt_arg in %1$. - flags - The flag characaters, e.g. 0 is the flag in %08d - width - The width field, e.g. 20 is the width in %20s - precision - The precisioin field, e.g. .2 is the precision in %8.2f - length - The length modifier field, e.g. l is the length modifier in %ld - conversion - The conversion specifier character, e.g. d is the conversion - specification character in %ld - - If the part is not found in the format it's value will be None. - ''' - - result = [] - - # get list of all matches, but skip escaped % - matches = [x for x in printf_fmt_re.finditer(s) if x.group(0) != "%%"] - - # build dict of each sub-part of the format, append to result - for match in matches: - parts = {} - parts['fmt'] = match.group(0) - parts['fmt_arg'] = match.group(1) - parts['flags'] = match.group(2) or None - parts['width'] = match.group(4) or None - parts['precision'] = match.group(8) - parts['length'] = match.group(13) - parts['conversion'] = match.group(14) - - result.append(parts) - - return result - -def validate_substitutions_match(s1, s2, s1_name='string1', s2_name='string2'): - ''' - Validate both s1 and s2 have the same number of substitution strings. - A substitution string would be something that looked like this: - - * %(foo)s - * $foo - * ${foo} - * $(foo) - - The substitutions may appear in any order in s1 and s2, however their - format must match exactly and the exact same number of each must exist - in both s1 and s2. - - A list of error diagnostics is returned explaining how s1 and s2 failed - the validation check. If the returned error list is empty then the - validation succeeded. - - :param s1: First string to validate - :param s2: First string to validate - :param s1_name: In diagnostic messages the name for s1 - :param s2_name: In diagnostic messages the name for s2 - :return: List of diagnostic error messages, if empty then success - ''' - errors = [] - - def get_subs(s): - ''' - Return a dict whoses keys are each unique substitution and whose - value is the count of how many times that substitution appeared. - ''' - subs = {} - for regexp in _substitution_regexps: - for match in regexp.finditer(s): - matched = match.group(0) - subs[matched] = subs.get(matched, 0) + 1 - return subs - - # Get the substitutions and their occurance counts - subs1 = get_subs(s1) - subs2 = get_subs(s2) - - # Form a set for each strings substitutions and - # do set subtraction and interesection - set1 = set(subs1.keys()) - set2 = set(subs2.keys()) - - missing1 = set2 - set1 - missing2 = set1 - set2 - common = set1 & set2 - - # Test for substitutions which are absent in either string - if missing1: - errors.append("The following substitutions are absent in %s: %s" % - (s1_name, ' '.join(missing1))) - - if missing2: - errors.append("The following substitutions are absent in %s: %s" % - (s2_name, ' '.join(missing2))) - - if pedantic: - # For the substitutions which are shared assure they occur an equal number of times - for sub in common: - if subs1[sub] != subs2[sub]: - errors.append("unequal occurances of '%s', %s has %d occurances, %s has %d occurances" % - (sub, s1_name, subs1[sub], s2_name, subs2[sub])) - - if errors: - if show_strings: - errors.append('>>> %s <<<' % s1_name) - errors.append(s1.rstrip()) - - errors.append('>>> %s <<<' % s2_name) - errors.append(s2.rstrip()) - return errors - - -def validate_substitution_syntax(s, s_name='string'): - ''' - If s has one or more substitution variables then validate they - are syntactically correct. - A substitution string would be something that looked like this: - - * %(foo)s - * $foo - * ${foo} - * $(foo) - - A list of error diagnostics is returned explaining how s1 and s2 failed - the validation check. If the returned error list is empty then the - validation succeeded. - - :param s: String to validate - :param s_name: In diagnostic messages the name for s - :return: List of diagnostic error messages, if empty then success - ''' - errors = [] - - # Look for Python style substitutions, e.g. %(foo)s - for match in _python_substitution_regexp.finditer(s): - if match.group(1): - errors.append("%s has whitespace between %% and key in '%s'" % - (s_name, match.group(0))) - if match.group(2) or match.group(3): - errors.append("%s has whitespace next to key in '%s'" % - (s_name, match.group(0))) - if match.group(4): - errors.append("%s has whitespace between key and format character in '%s'" % - (s_name, match.group(0))) - if not match.group(5): - errors.append("%s has no format character in '%s'" % - (s_name, match.group(0))) - - # Look for shell style substitutions, e.g. $foo $(foo) ${foo} - for match in _shell_substitution_regexp.finditer(s): - if match.group(1): - errors.append("%s has whitespace between $ and variable in '%s'" % - (s_name, match.group(0))) - if match.group(3) or (match.group(4) and match.group(5)): - errors.append("%s has whitespace next to variable in '%s'" % - (s_name, match.group(0))) - - beg_delimiter = match.group(2) - end_delimiter = match.group(5) - matched_delimiters = {'': '', '(': ')', '{': '}'} - if beg_delimiter is not None or end_delimiter is not None: - if matched_delimiters[beg_delimiter] != end_delimiter: - errors.append("%s variable delimiters do not match in '%s', begin delimiter='%s' end delimiter='%s'" % - (s_name, match.group(0), beg_delimiter, end_delimiter)) - - if errors: - if show_strings: - errors.append('>>> %s <<<' % s_name) - errors.append(s.rstrip()) - - return errors - - -def validate_positional_substitutions(s, prog_langs, s_name='string'): - ''' - We do not permit multiple positional substitutions in translation - strings (e.g. '%s') because they do not allow translators to reorder the - wording. Instead keyword substitutions should be used when there are - more than one. - ''' - errors = [] - - fmts = parse_printf_fmt(s) - n_fmts = len(fmts) - - errors = [] - if n_fmts > 1: - for i, fmt_parts in enumerate(fmts): - fmt = fmt_parts['fmt'] - fmt_arg = fmt_parts['fmt_arg'] - width = fmt_parts['width'] - - if width == '*': - errors.append("Error: * width arg in format '%s should be indexed" % fmt) - - if fmt_arg is None: - if 'c' in prog_langs: - errors.append("%s format '%s' is positional, should use indexed argument" % - (s_name, fmt)) - else: - errors.append("%s format '%s' is positional, should use keyword substitution" % - (s_name, fmt)) - - if errors: - if show_strings: - errors.append('>>> %s <<<' % s_name) - errors.append(s.rstrip()) - - return errors - -def validate_file(file_path, validation_mode, reference_pot=None): - ''' - Given a pot or po file scan all it's entries looking for problems - with variable substitutions. See the following functions for - details on how the validation is performed. - - * validate_substitutions_match() - * validate_substitution_syntax() - * validate_positional_substitutions() - - Returns the number of entries with errors. - - For po files, ``reference_pot`` gives a pot file to merge with (to recover - comments and file locations) - ''' - - def emit_messages(): - if n_warnings: - warning_lines.insert(0, section_seperator) - warning_lines.insert(1, "%d validation warnings in %s" % (n_warnings, file_path)) - print '\n'.join(warning_lines) - - if n_errors: - error_lines.insert(0, section_seperator) - error_lines.insert(1, "%d validation errors in %s" % (n_errors, file_path)) - print '\n'.join(error_lines) - - Result = namedtuple('ValidateFileResult', ['n_entries', 'n_msgids', 'n_msgstrs', 'n_warnings', 'n_errors']) - - warning_lines = [] - error_lines = [] - n_entries = 0 - n_msgids = 0 - n_msgstrs = 0 - n_entries = 0 - n_warnings = 0 - n_errors = 0 - n_plural_forms = 0 - - if not os.path.isfile(file_path): - error_lines.append(entry_seperator) - error_lines.append('file does not exist "%s"' % (file_path)) - n_errors += 1 - emit_messages() - return Result(n_entries=n_entries, n_msgids=n_msgids, n_msgstrs=n_msgstrs, n_warnings=n_warnings, n_errors=n_errors) - - try: - po = polib.pofile(file_path) - except Exception, e: - error_lines.append(entry_seperator) - error_lines.append('Unable to parse file "%s": %s' % (file_path, e)) - n_errors += 1 - emit_messages() - return Result(n_entries=n_entries, n_msgids=n_msgids, n_msgstrs=n_msgstrs, n_warnings=n_warnings, n_errors=n_errors) - - if validation_mode == 'po' and reference_pot: - # Merge the .pot file for comments and file locations - po.merge(reference_pot) - - if validation_mode == 'po': - plural_forms = po.metadata.get('Plural-Forms') - if not plural_forms: - error_lines.append(entry_seperator) - error_lines.append("%s: does not have Plural-Forms header" % file_path) - n_errors += 1 - match = re.search(r'\bnplurals\s*=\s*(\d+)', plural_forms) - if match: - n_plural_forms = int(match.group(1)) - else: - error_lines.append(entry_seperator) - error_lines.append("%s: does not specify integer nplurals in Plural-Forms header" % file_path) - n_errors += 1 - - n_entries = len(po) - for entry in po: - entry_warnings = [] - entry_errors = [] - have_msgid = entry.msgid.strip() != '' - have_msgid_plural = entry.msgid_plural.strip() != '' - have_msgstr = entry.msgstr.strip() != '' - - if have_msgid: - n_msgids += 1 - if have_msgid_plural: - n_msgids += 1 - if have_msgstr: - n_msgstrs += 1 - - if validation_mode == 'pot': - prog_langs = get_prog_langs(entry) - if have_msgid: - errors = validate_positional_substitutions(entry.msgid, prog_langs, 'msgid') - entry_errors.extend(errors) - if have_msgid_plural: - errors = validate_positional_substitutions(entry.msgid_plural, prog_langs, 'msgid_plural') - entry_errors.extend(errors) - elif validation_mode == 'po': - if have_msgid: - if have_msgstr: - errors = validate_substitutions_match(entry.msgid, entry.msgstr, 'msgid', 'msgstr') - entry_errors.extend(errors) - - if have_msgid_plural and have_msgstr: - n_plurals = 0 - for index, msgstr in entry.msgstr_plural.items(): - have_msgstr_plural = msgstr.strip() != '' - if have_msgstr_plural: - n_plurals += 1 - errors = validate_substitutions_match(entry.msgid_plural, msgstr, 'msgid_plural', 'msgstr_plural[%s]' % index) - entry_errors.extend(errors) - else: - entry_errors.append('msgstr_plural[%s] is empty' % (index)) - if n_plural_forms != n_plurals: - entry_errors.append('%d plural forms specified, but this entry has %d plurals' % (n_plural_forms, n_plurals)) - - if pedantic: - if have_msgid: - errors = validate_substitution_syntax(entry.msgid, 'msgid') - entry_warnings.extend(errors) - - if have_msgid_plural: - errors = validate_substitution_syntax(entry.msgid_plural, 'msgid_plural') - entry_warnings.extend(errors) - - errors = validate_substitutions_match(entry.msgid, entry.msgid_plural, 'msgid', 'msgid_plural') - entry_warnings.extend(errors) - - for index, msgstr in entry.msgstr_plural.items(): - have_msgstr_plural = msgstr.strip() != '' - if have_msgstr_plural: - errors = validate_substitution_syntax(msgstr, 'msgstr_plural[%s]' % index) - entry_warnings.extend(errors) - - if have_msgstr: - errors = validate_substitution_syntax(entry.msgstr, 'msgstr') - entry_warnings.extend(errors) - - if entry_warnings: - warning_lines.append(entry_seperator) - warning_lines.append('locations: %s' % (', '.join(["%s:%d" % (x[0], int(x[1])) for x in entry.occurrences]))) - warning_lines.extend(entry_warnings) - n_warnings += 1 - - if entry_errors: - error_lines.append(entry_seperator) - error_lines.append('locations: %s' % (', '.join(["%s:%d" % (x[0], int(x[1])) for x in entry.occurrences]))) - error_lines.extend(entry_errors) - n_errors += 1 - - emit_messages() - return Result(n_entries=n_entries, n_msgids=n_msgids, n_msgstrs=n_msgstrs, n_warnings=n_warnings, n_errors=n_errors) - - -#---------------------------------------------------------------------- -def create_po(pot_file, po_file, mo_file): - - if not os.path.isfile(pot_file): - print >>sys.stderr, 'file does not exist "%s"' % (pot_file) - return 1 - try: - po = polib.pofile(pot_file) - except Exception, e: - print >>sys.stderr, 'Unable to parse file "%s": %s' % (pot_file, e) - return 1 - - # Update the metadata in the po file header - # It's case insensitive so search the keys in a case insensitive manner - # - # We need to update the Plural-Forms otherwise gettext.py will raise the - # following error: - # - # raise ValueError, 'plural forms expression could be dangerous' - # - # It is demanding the rhs of plural= only contains the identifer 'n' - - for k,v in po.metadata.items(): - if k.lower() == 'plural-forms': - po.metadata[k] = 'nplurals=2; plural=(n != 1)' - break - - - # Iterate over all msgid's and form a the msgstr by prepending - # the prefix and appending the suffix - for entry in po: - if entry.msgid_plural: - entry.msgstr_plural = {0: prefix + entry.msgid + suffix, - 1: prefix + entry.msgid_plural + suffix} - else: - entry.msgstr = prefix + entry.msgid + suffix - - # Write out the po and mo files - po.save(po_file) - print "Wrote: %s" % (po_file) - - po.save_as_mofile(mo_file) - print "Wrote: %s" % (mo_file) - - return 0 - -#---------------------------------------------------------------------- - -def validate_unicode_edit(msgid, msgstr): - # Verify the first character is the test prefix - if msgstr[0] != prefix: - raise ValueError('First char in translated string "%s" not equal to prefix "%s"' % - (msgstr.encode('utf-8'), prefix.encode('utf-8'))) - - # Verify the last character is the test suffix - if msgstr[-1] != suffix: - raise ValueError('Last char in translated string "%s" not equal to suffix "%s"' % - (msgstr.encode('utf-8'), suffix.encode('utf-8'))) - - # Verify everything between the first and last character is the - # original untranslated string - if msgstr[1:-1] != msgid: - raise ValueError('Translated string "%s" minus the first & last character is not equal to msgid "%s"' % - (msgstr.encode('utf-8'), msgid)) - - if verbose: - msg = 'Success: message string "%s" maps to translated string "%s"' % (msgid, msgstr) - print msg.encode('utf-8') - - -def test_translations(po_file, lang, domain, locale_dir): - # The test installs the test message catalog under the xh_ZA - # (e.g. Zambia Xhosa) language by default. It would be nice to - # use a dummy language not associated with any real language, - # but the setlocale function demands the locale be a valid - # known locale, Zambia Xhosa is a reasonable choice :) - - os.environ['LANG'] = lang - - # Create a gettext translation object specifying our domain as - # 'ipa' and the locale_dir as 'test_locale' (i.e. where to - # look for the message catalog). Then use that translation - # object to obtain the translation functions. - - t = gettext.translation(domain, locale_dir) - - get_msgstr = t.ugettext - get_msgstr_plural = t.ungettext - - return po_file_iterate(po_file, get_msgstr, get_msgstr_plural) - -def po_file_iterate(po_file, get_msgstr, get_msgstr_plural): - try: - # Iterate over the msgid's - if not os.path.isfile(po_file): - print >>sys.stderr, 'file does not exist "%s"' % (po_file) - return 1 - try: - po = polib.pofile(po_file) - except Exception, e: - print >>sys.stderr, 'Unable to parse file "%s": %s' % (po_file, e) - return 1 - - n_entries = 0 - n_translations = 0 - n_valid = 0 - n_fail = 0 - for entry in po: - if entry.msgid_plural: - msgid = entry.msgid - msgid_plural = entry.msgid_plural - msgstr = get_msgstr_plural(msgid, msgid_plural, 1) - msgstr_plural = get_msgstr_plural(msgid, msgid_plural, 2) - - try: - n_translations += 1 - validate_unicode_edit(msgid, msgstr) - n_valid += 1 - except Exception, e: - n_fail += 1 - if print_traceback: - traceback.print_exc() - print >> sys.stderr, "ERROR: %s" % e - - try: - n_translations += 1 - validate_unicode_edit(msgid_plural, msgstr_plural) - n_valid += 1 - except Exception, e: - n_fail += 1 - if print_traceback: - traceback.print_exc() - print >> sys.stderr, "ERROR: %s" % e - - - else: - msgid = entry.msgid - msgstr = get_msgstr(msgid) - - try: - n_translations += 1 - validate_unicode_edit(msgid, msgstr) - n_valid += 1 - except Exception, e: - n_fail += 1 - if print_traceback: - traceback.print_exc() - print >> sys.stderr, "ERROR: %s" % e - - n_entries += 1 - - except Exception, e: - if print_traceback: - traceback.print_exc() - print >> sys.stderr, "ERROR: %s" % e - return 1 - - if not n_entries: - print >> sys.stderr, "ERROR: no translations found in %s" % (po_filename) - return 1 - - if n_fail: - print >> sys.stderr, "ERROR: %d failures out of %d translations" % (n_fail, n_entries) - return 1 - - print "%d translations in %d messages successfully tested" % (n_translations, n_entries) - return 0 - -#---------------------------------------------------------------------- - -usage =''' - -%prog --test-gettext -%prog --create-test -%prog --validate-pot [pot_file1, ...] -%prog --validate-po po_file1 [po_file2, ...] -''' - -def main(): - global verbose, print_traceback, pedantic, show_strings - - parser = optparse.OptionParser(usage=usage) - - mode_group = optparse.OptionGroup(parser, 'Operational Mode', - 'You must select one these modes to run in') - - mode_group.add_option('-g', '--test-gettext', action='store_const', const='test_gettext', dest='mode', - help='create the test translation file(s) and exercise them') - mode_group.add_option('-c', '--create-test', action='store_const', const='create_test', dest='mode', - help='create the test translation file(s)') - mode_group.add_option('-P', '--validate-pot', action='store_const', const='validate_pot', dest='mode', - help='validate pot file(s)') - mode_group.add_option('-p', '--validate-po', action='store_const', const='validate_po', dest='mode', - help='validate po file(s)') - - parser.add_option_group(mode_group) - parser.set_defaults(mode='') - - parser.add_option('-s', '--show-strings', action='store_true', dest='show_strings', default=False, - help='show the offending string when an error is detected') - parser.add_option('--pedantic', action='store_true', dest='pedantic', default=False, - help='be aggressive when validating') - parser.add_option('-v', '--verbose', action='store_true', dest='verbose', default=False, - help='be informative') - parser.add_option('--traceback', action='store_true', dest='print_traceback', default=False, - help='print the traceback when an exception occurs') - - param_group = optparse.OptionGroup(parser, 'Run Time Parameters', - 'These may be used to modify the run time defaults') - - param_group.add_option('--test-lang', action='store', dest='test_lang', default='test', - help="test po file uses this as it's basename (default=test)") - param_group.add_option('--lang', action='store', dest='lang', default='xh_ZA', - help='lang used for locale, MUST be a valid lang (default=xh_ZA)') - param_group.add_option('--domain', action='store', dest='domain', default='ipa', - help='translation domain used during test (default=ipa)') - param_group.add_option('--locale-dir', action='store', dest='locale_dir', default='test_locale', - help='locale directory used during test (default=test_locale)') - param_group.add_option('--pot-file', action='store', dest='pot_file', default='ipa.pot', - help='default pot file, used when validating pot file or generating test po and mo files (default=ipa.pot)') - - parser.add_option_group(param_group) - - options, args = parser.parse_args() - - verbose = options.verbose - print_traceback = options.print_traceback - pedantic = options.pedantic - show_strings = options.show_strings - - if not options.mode: - print >> sys.stderr, 'ERROR: no mode specified' - return 1 - - if options.mode == 'validate_pot' or options.mode == 'validate_po': - if options.mode == 'validate_pot': - files = args - if not files: - files = [options.pot_file] - validation_mode = 'pot' - reference_pot = None - elif options.mode == 'validate_po': - files = args - if not files: - print >> sys.stderr, 'ERROR: no po files specified' - return 1 - validation_mode = 'po' - reference_pot = polib.pofile(options.pot_file) - else: - print >> sys.stderr, 'ERROR: unknown validation mode "%s"' % (options.mode) - return 1 - - total_entries = 0 - total_msgids = 0 - total_msgstrs = 0 - total_warnings = 0 - total_errors = 0 - - for f in files: - result = validate_file(f, validation_mode, reference_pot) - total_entries += result.n_entries - total_msgids += result.n_msgids - total_msgstrs += result.n_msgstrs - total_warnings += result.n_warnings - total_errors += result.n_errors - print "%s: %d entries, %d msgid, %d msgstr, %d warnings %d errors" % \ - (f, result.n_entries, result.n_msgids, result.n_msgstrs, result.n_warnings, result.n_errors) - if total_errors: - print section_seperator - print "%d errors in %d files" % (total_errors, len(files)) - return 1 - else: - return 0 - - elif options.mode == 'create_test' or 'test_gettext': - po_file = '%s.po' % options.test_lang - pot_file = options.pot_file - - msg_dir = os.path.join(options.locale_dir, options.lang, 'LC_MESSAGES') - if not os.path.exists(msg_dir): - os.makedirs(msg_dir) - - mo_basename = '%s.mo' % options.domain - mo_file = os.path.join(msg_dir, mo_basename) - - result = create_po(pot_file, po_file, mo_file) - if result: - return result - - if options.mode == 'create_test': - return result - - # The test installs the test message catalog under the xh_ZA - # (e.g. Zambia Xhosa) language by default. It would be nice to - # use a dummy language not associated with any real language, - # but the setlocale function demands the locale be a valid - # known locale, Zambia Xhosa is a reasonable choice :) - - lang = options.lang - - # Create a gettext translation object specifying our domain as - # 'ipa' and the locale_dir as 'test_locale' (i.e. where to - # look for the message catalog). Then use that translation - # object to obtain the translation functions. - - domain = options.domain - locale_dir = options.locale_dir - - return test_translations(po_file, lang, domain, locale_dir) - - else: - print >> sys.stderr, 'ERROR: unknown mode "%s"' % (options.mode) - return 1 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tests/test_cmdline/cmdline.py b/tests/test_cmdline/cmdline.py deleted file mode 100644 index d86652bd1..000000000 --- a/tests/test_cmdline/cmdline.py +++ /dev/null @@ -1,70 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Base class for all cmdline tests -""" - -import nose -import krbV - -from ipalib import api -from ipalib import errors -from tests.test_xmlrpc.xmlrpc_test import XMLRPC_test -from ipaserver.plugins.ldap2 import ldap2 -from ipapython import ipautil - -# See if our LDAP server is up and we can talk to it over GSSAPI -ccache = krbV.default_context().default_ccache() - -try: - conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri, base_dn=api.env.basedn) - conn.connect(ccache=ccache) - conn.disconnect() - server_available = True -except errors.DatabaseError: - server_available = False -except Exception, e: - server_available = False - -class cmdline_test(XMLRPC_test): - """ - Base class for all command-line tests - """ - # some reasonable default command - command = '/bin/ls' - - def setUp(self): - # raise an error if the command is missing even if the remote - # server is not available. - if not ipautil.file_exists(self.command): - raise AssertionError( - 'Command %r not available' % self.command - ) - super(cmdline_test, self).setUp() - if not server_available: - raise nose.SkipTest( - 'Server not available: %r' % api.env.xmlrpc_uri - ) - - def tearDown(self): - """ - nose tear-down fixture. - """ - super(cmdline_test, self).tearDown() diff --git a/tests/test_cmdline/test_cli.py b/tests/test_cmdline/test_cli.py deleted file mode 100644 index bd1281e1d..000000000 --- a/tests/test_cmdline/test_cli.py +++ /dev/null @@ -1,327 +0,0 @@ -import shlex -import sys -import contextlib -import StringIO - -import nose - -from tests import util -from ipalib import api, errors -from ipapython.version import API_VERSION - - -class TestCLIParsing(object): - """Tests that commandlines are correctly parsed to Command keyword args - """ - def check_command(self, commandline, expected_command_name, **kw_expected): - argv = shlex.split(commandline) - executioner = api.Backend.cli - - cmd = executioner.get_command(argv) - kw_got = executioner.parse(cmd, argv[1:]) - kw_got = executioner.process_keyword_arguments(cmd, kw_got) - util.assert_deepequal(expected_command_name, cmd.name, 'Command name') - util.assert_deepequal(kw_expected, kw_got) - - def run_command(self, command_name, **kw): - """Run a command on the server""" - if not api.Backend.xmlclient.isconnected(): - api.Backend.xmlclient.connect(fallback=False) - try: - api.Command[command_name](**kw) - except errors.NetworkError: - raise nose.SkipTest('%r: Server not available: %r' % - (self.__module__, api.env.xmlrpc_uri)) - - @contextlib.contextmanager - def fake_stdin(self, string_in): - """Context manager that temporarily replaces stdin to read a string""" - old_stdin = sys.stdin - sys.stdin = StringIO.StringIO(string_in) - yield - sys.stdin = old_stdin - - def test_ping(self): - self.check_command('ping', 'ping', - version=API_VERSION) - - def test_user_show(self): - self.check_command('user-show admin', 'user_show', - uid=u'admin', - rights=False, - raw=False, - all=False, - version=API_VERSION) - - def test_user_show_underscore(self): - self.check_command('user_show admin', 'user_show', - uid=u'admin', - rights=False, - raw=False, - all=False, - version=API_VERSION) - - def test_group_add(self): - self.check_command('group-add tgroup1 --desc="Test group"', - 'group_add', - cn=u'tgroup1', - description=u'Test group', - nonposix=False, - external=False, - raw=False, - all=False, - version=API_VERSION) - - def test_sudocmdgroup_add_member(self): - # Test CSV splitting is not done - self.check_command( - # The following is as it would appear on the command line: - r'sudocmdgroup-add-member tcmdgroup1 --sudocmds=ab,c --sudocmds=d', - 'sudocmdgroup_add_member', - cn=u'tcmdgroup1', - sudocmd=[u'ab,c', u'd'], - raw=False, - all=False, - version=API_VERSION) - - def test_group_add_nonposix(self): - self.check_command('group-add tgroup1 --desc="Test group" --nonposix', - 'group_add', - cn=u'tgroup1', - description=u'Test group', - nonposix=True, - external=False, - raw=False, - all=False, - version=API_VERSION) - - def test_group_add_gid(self): - self.check_command('group-add tgroup1 --desc="Test group" --gid=1234', - 'group_add', - cn=u'tgroup1', - description=u'Test group', - gidnumber=u'1234', - nonposix=False, - external=False, - raw=False, - all=False, - version=API_VERSION) - - def test_group_add_interactive(self): - with self.fake_stdin('Test group\n'): - self.check_command('group-add tgroup1', 'group_add', - cn=u'tgroup1', - description=u'Test group', - nonposix=False, - external=False, - raw=False, - all=False, - version=API_VERSION) - - def test_dnsrecord_add(self): - self.check_command('dnsrecord-add test-example.com ns --a-rec=1.2.3.4', - 'dnsrecord_add', - dnszoneidnsname=u'test-example.com', - idnsname=u'ns', - arecord=u'1.2.3.4', - structured=False, - force=False, - raw=False, - all=False, - version=API_VERSION) - - def test_dnsrecord_del_all(self): - try: - self.run_command('dnszone_add', idnsname=u'test-example.com', - idnssoamname=u'ns.test-example.com', force=True) - except errors.NotFound: - raise nose.SkipTest('DNS is not configured') - try: - self.run_command('dnsrecord_add', - dnszoneidnsname=u'test-example.com', - idnsname=u'ns', arecord=u'1.2.3.4') - with self.fake_stdin('yes\n'): - self.check_command('dnsrecord_del test-example.com ns', - 'dnsrecord_del', - dnszoneidnsname=u'test-example.com', - idnsname=u'ns', - del_all=True, - structured=False, - version=API_VERSION) - with self.fake_stdin('YeS\n'): - self.check_command('dnsrecord_del test-example.com ns', - 'dnsrecord_del', - dnszoneidnsname=u'test-example.com', - idnsname=u'ns', - del_all=True, - structured=False, - version=API_VERSION) - finally: - self.run_command('dnszone_del', idnsname=u'test-example.com') - - def test_dnsrecord_del_one_by_one(self): - try: - self.run_command('dnszone_add', idnsname=u'test-example.com', - idnssoamname=u'ns.test-example.com', force=True) - except errors.NotFound: - raise nose.SkipTest('DNS is not configured') - try: - records = (u'1 1 E3B72BA346B90570EED94BE9334E34AA795CED23', - u'2 1 FD2693C1EFFC11A8D2BE57229212A04B45663791') - for record in records: - self.run_command('dnsrecord_add', - dnszoneidnsname=u'test-example.com', idnsname=u'ns', - sshfprecord=record) - with self.fake_stdin('no\nyes\nyes\n'): - self.check_command('dnsrecord_del test-example.com ns', - 'dnsrecord_del', - dnszoneidnsname=u'test-example.com', - idnsname=u'ns', - del_all=False, - sshfprecord=records, - structured=False, - version=API_VERSION) - finally: - self.run_command('dnszone_del', idnsname=u'test-example.com') - - def test_dnsrecord_add_ask_for_missing_fields(self): - sshfp_parts = (1, 1, u'E3B72BA346B90570EED94BE9334E34AA795CED23') - - with self.fake_stdin('SSHFP\n%d\n%d\n%s' % sshfp_parts): - self.check_command('dnsrecord-add test-example.com sshfp', - 'dnsrecord_add', - dnszoneidnsname=u'test-example.com', - idnsname=u'sshfp', - sshfp_part_fp_type=sshfp_parts[0], - sshfp_part_algorithm=sshfp_parts[1], - sshfp_part_fingerprint=sshfp_parts[2], - structured=False, - raw=False, - all=False, - force=False, - version=API_VERSION) - - # NOTE: when a DNS record part is passed via command line, it is not - # converted to its base type when transfered via wire - with self.fake_stdin('%d\n%s' % (sshfp_parts[1], sshfp_parts[2])): - self.check_command('dnsrecord-add test-example.com sshfp ' \ - '--sshfp-algorithm=%d' % sshfp_parts[0], - 'dnsrecord_add', - dnszoneidnsname=u'test-example.com', - idnsname=u'sshfp', - sshfp_part_fp_type=sshfp_parts[0], - sshfp_part_algorithm=unicode(sshfp_parts[1]), # passed via cmdline - sshfp_part_fingerprint=sshfp_parts[2], - structured=False, - raw=False, - all=False, - force=False, - version=API_VERSION) - - with self.fake_stdin(sshfp_parts[2]): - self.check_command('dnsrecord-add test-example.com sshfp ' \ - '--sshfp-algorithm=%d --sshfp-fp-type=%d' % (sshfp_parts[0], sshfp_parts[1]), - 'dnsrecord_add', - dnszoneidnsname=u'test-example.com', - idnsname=u'sshfp', - sshfp_part_fp_type=unicode(sshfp_parts[0]), # passed via cmdline - sshfp_part_algorithm=unicode(sshfp_parts[1]), # passed via cmdline - sshfp_part_fingerprint=sshfp_parts[2], - structured=False, - raw=False, - all=False, - force=False, - version=API_VERSION) - - def test_dnsrecord_del_comma(self): - try: - self.run_command( - 'dnszone_add', idnsname=u'test-example.com', - idnssoamname=u'ns.test-example.com', force=True) - except errors.NotFound: - raise nose.SkipTest('DNS is not configured') - try: - self.run_command( - 'dnsrecord_add', - dnszoneidnsname=u'test-example.com', - idnsname=u'test', - txtrecord=u'"A pretty little problem," said Holmes.') - with self.fake_stdin('no\nyes\n'): - self.check_command( - 'dnsrecord_del test-example.com test', - 'dnsrecord_del', - dnszoneidnsname=u'test-example.com', - idnsname=u'test', - del_all=False, - txtrecord=[u'"A pretty little problem," said Holmes.'], - structured=False, - version=API_VERSION) - finally: - self.run_command('dnszone_del', idnsname=u'test-example.com') - - def test_dnszone_add(self): - """ - Test dnszone-add with nameserver IP passed interatively - """ - # Pass IP of nameserver interactively for nameserver in zone - # (absolute name) - with self.fake_stdin('1.1.1.1\n'): - self.check_command( - 'dnszone_add example.com --name-server=ns.example.com. ' - '--admin-email=admin@example.com', - 'dnszone_add', - idnsname=u'example.com', - idnssoamname=u'ns.example.com.', - idnssoarname=u'admin@example.com', - ip_address=u'1.1.1.1', - idnssoaexpire=util.Fuzzy(type=int), - idnssoaserial=util.Fuzzy(type=int), - idnssoaretry=util.Fuzzy(type=int), - idnssoaminimum=util.Fuzzy(type=int), - idnssoarefresh=util.Fuzzy(type=int), - all=False, - raw=False, - force=False, - version=API_VERSION - ) - - # Pass IP of nameserver interactively for nameserver in zone - # (relative name) - with self.fake_stdin('1.1.1.1\n'): - self.check_command( - 'dnszone_add example.com --name-server=ns ' - '--admin-email=admin@example.com', - 'dnszone_add', - idnsname=u'example.com', - idnssoamname=u'ns', - idnssoarname=u'admin@example.com', - ip_address=u'1.1.1.1', - idnssoaexpire=util.Fuzzy(type=int), - idnssoaserial=util.Fuzzy(type=int), - idnssoaretry=util.Fuzzy(type=int), - idnssoaminimum=util.Fuzzy(type=int), - idnssoarefresh=util.Fuzzy(type=int), - all=False, - raw=False, - force=False, - version=API_VERSION - ) - - # Nameserver is outside the zone - no need to pass the IP - self.check_command( - 'dnszone_add example.com --name-server=ns.example.net. ' - '--admin-email=admin@example.com', - 'dnszone_add', - idnsname=u'example.com', - idnssoamname=u'ns.example.net.', - idnssoarname=u'admin@example.com', - idnssoaexpire=util.Fuzzy(type=int), - idnssoaserial=util.Fuzzy(type=int), - idnssoaretry=util.Fuzzy(type=int), - idnssoaminimum=util.Fuzzy(type=int), - idnssoarefresh=util.Fuzzy(type=int), - all=False, - raw=False, - force=False, - version=API_VERSION - ) diff --git a/tests/test_cmdline/test_help.py b/tests/test_cmdline/test_help.py deleted file mode 100644 index 4cf633683..000000000 --- a/tests/test_cmdline/test_help.py +++ /dev/null @@ -1,141 +0,0 @@ -# Authors: Petr Viktorin -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -import sys -import contextlib -import StringIO - -from nose.tools import assert_raises # pylint: disable=E0611 - -from ipalib import api, errors -from ipalib.plugins.user import user_add - - -class CLITestContext(object): - """Context manager that replaces stdout & stderr, and catches SystemExit - - Whatever was printed to the streams is available in ``stdout`` and - ``stderr`` attrributes once the with statement finishes. - - When exception is given, asserts that exception is raised. The exception - will be available in the ``exception`` attribute. - """ - def __init__(self, exception=None): - self.exception = exception - - def __enter__(self): - self.old_streams = sys.stdout, sys.stderr - self.stdout_fileobj = sys.stdout = StringIO.StringIO() - self.stderr_fileobj = sys.stderr = StringIO.StringIO() - return self - - def __exit__(self, exc_type, exc_value, traceback): - sys.stdout, sys.stderr = self.old_streams - self.stdout = self.stdout_fileobj.getvalue() - self.stderr = self.stderr_fileobj.getvalue() - self.stdout_fileobj.close() - self.stderr_fileobj.close() - if self.exception: - assert isinstance(exc_value, self.exception), exc_value - self.exception = exc_value - return True - - -def test_ipa_help(): - """Test that `ipa help` only writes to stdout""" - with CLITestContext() as ctx: - return_value = api.Backend.cli.run(['help']) - assert return_value == 0 - assert ctx.stderr == '' - - -def test_ipa_without_arguments(): - """Test that `ipa` errors out, and prints the help to stderr""" - with CLITestContext(exception=SystemExit) as ctx: - api.Backend.cli.run([]) - assert ctx.exception.code == 2 - assert ctx.stdout == '' - assert 'Error: Command not specified' in ctx.stderr - - with CLITestContext() as help_ctx: - api.Backend.cli.run(['help']) - assert help_ctx.stdout in ctx.stderr - - -def test_bare_topic(): - """Test that `ipa user` errors out, and prints the help to stderr - - This is because `user` is a topic, not a command, so `ipa user` doesn't - match our usage string. The help should be accessed using `ipa help user`. - """ - with CLITestContext(exception=errors.CommandError) as ctx: - api.Backend.cli.run(['user']) - assert ctx.exception.name == 'user' - assert ctx.stdout == '' - - with CLITestContext() as help_ctx: - return_value = api.Backend.cli.run(['help', 'user']) - assert return_value == 0 - assert help_ctx.stdout in ctx.stderr - - -def test_command_help(): - """Test that `help user-add` & `user-add -h` are equivalent and contain doc - """ - with CLITestContext() as help_ctx: - return_value = api.Backend.cli.run(['help', 'user-add']) - assert return_value == 0 - assert help_ctx.stderr == '' - - with CLITestContext(exception=SystemExit) as h_ctx: - api.Backend.cli.run(['user-add', '-h']) - assert h_ctx.exception.code == 0 - assert h_ctx.stderr == '' - - assert h_ctx.stdout == help_ctx.stdout - assert unicode(user_add.__doc__) in help_ctx.stdout - - -def test_ambiguous_command_or_topic(): - """Test that `help ping` & `ping -h` are NOT equivalent - - One is a topic, the other is a command - """ - with CLITestContext() as help_ctx: - return_value = api.Backend.cli.run(['help', 'ping']) - assert return_value == 0 - assert help_ctx.stderr == '' - - with CLITestContext(exception=SystemExit) as h_ctx: - api.Backend.cli.run(['ping', '-h']) - assert h_ctx.exception.code == 0 - assert h_ctx.stderr == '' - - assert h_ctx.stdout != help_ctx.stdout - -def test_multiline_description(): - """Test that all of a multi-line command description appears in output - """ - # This assumes trust_add has multiline doc. Ensure it is so. - assert '\n\n' in unicode(api.Command.trust_add.doc).strip() - - with CLITestContext(exception=SystemExit) as help_ctx: - return_value = api.Backend.cli.run(['trust-add', '-h']) - - assert unicode(api.Command.trust_add.doc).strip() in help_ctx.stdout diff --git a/tests/test_cmdline/test_ipagetkeytab.py b/tests/test_cmdline/test_ipagetkeytab.py deleted file mode 100644 index cb46fd23b..000000000 --- a/tests/test_cmdline/test_ipagetkeytab.py +++ /dev/null @@ -1,152 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test `ipa-getkeytab` -""" - -import os -import shutil -from cmdline import cmdline_test -from ipalib import api -from ipalib import errors -import tempfile -from ipapython import ipautil -import nose -import tempfile -import krbV -from ipaserver.plugins.ldap2 import ldap2 -from ipapython.dn import DN - -def use_keytab(principal, keytab): - try: - tmpdir = tempfile.mkdtemp(prefix = "tmp-") - ccache_file = 'FILE:%s/ccache' % tmpdir - krbcontext = krbV.default_context() - principal = str(principal) - keytab = krbV.Keytab(name=keytab, context=krbcontext) - principal = krbV.Principal(name=principal, context=krbcontext) - os.environ['KRB5CCNAME'] = ccache_file - ccache = krbV.CCache(name=ccache_file, context=krbcontext, primary_principal=principal) - ccache.init(principal) - ccache.init_creds_keytab(keytab=keytab, principal=principal) - conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri, base_dn=api.env.basedn) - conn.connect(ccache=ccache) - conn.disconnect() - except krbV.Krb5Error, e: - raise StandardError('Unable to bind to LDAP. Error initializing principal %s in %s: %s' % (principal.name, keytab, str(e))) - finally: - del os.environ['KRB5CCNAME'] - if tmpdir: - shutil.rmtree(tmpdir) - -class test_ipagetkeytab(cmdline_test): - """ - Test `ipa-getkeytab`. - """ - command = "ipa-client/ipa-getkeytab" - host_fqdn = u'ipatest.%s' % api.env.domain - service_princ = u'test/%s@%s' % (host_fqdn, api.env.realm) - [keytabfd, keytabname] = tempfile.mkstemp() - os.close(keytabfd) - - def test_0_setup(self): - """ - Create a host to test against. - """ - # Create the service - try: - api.Command['host_add'](self.host_fqdn, force=True) - except errors.DuplicateEntry: - # it already exists, no problem - pass - - def test_1_run(self): - """ - Create a keytab with `ipa-getkeytab` for a non-existent service. - """ - new_args = [self.command, - "-s", api.env.host, - "-p", "test/notfound.example.com", - "-k", self.keytabname, - ] - (out, err, rc) = ipautil.run(new_args, stdin=None, raiseonerr=False) - assert err == 'Operation failed! PrincipalName not found.\n\n' - - def test_2_run(self): - """ - Create a keytab with `ipa-getkeytab` for an existing service. - """ - # Create the service - try: - api.Command['service_add'](self.service_princ, force=True) - except errors.DuplicateEntry: - # it already exists, no problem - pass - - os.unlink(self.keytabname) - new_args = [self.command, - "-s", api.env.host, - "-p", self.service_princ, - "-k", self.keytabname, - ] - try: - (out, err, rc) = ipautil.run(new_args, None) - expected = 'Keytab successfully retrieved and stored in: %s\n' % ( - self.keytabname) - assert expected in err, 'Success message not in output:\n%s' % err - except ipautil.CalledProcessError, e: - assert (False) - - def test_3_use(self): - """ - Try to use the service keytab. - """ - use_keytab(self.service_princ, self.keytabname) - - def test_4_disable(self): - """ - Disable a kerberos principal - """ - # Verify that it has a principal key - entry = api.Command['service_show'](self.service_princ)['result'] - assert(entry['has_keytab'] == True) - - # Disable it - api.Command['service_disable'](self.service_princ) - - # Verify that it looks disabled - entry = api.Command['service_show'](self.service_princ)['result'] - assert(entry['has_keytab'] == False) - - def test_5_use_disabled(self): - """ - Try to use the disabled keytab - """ - try: - use_keytab(self.service_princ, self.keytabname) - except StandardError, errmsg: - assert('Unable to bind to LDAP. Error initializing principal' in str(errmsg)) - - def test_9_cleanup(self): - """ - Clean up test data - """ - # First create the host that will use this policy - os.unlink(self.keytabname) - api.Command['host_del'](self.host_fqdn) diff --git a/tests/test_install/0_reset.update b/tests/test_install/0_reset.update deleted file mode 100644 index bd6ee636d..000000000 --- a/tests/test_install/0_reset.update +++ /dev/null @@ -1,5 +0,0 @@ -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -deleteentry: - -dn: cn=test, cn=accounts, $SUFFIX -deleteentry: reset: nada diff --git a/tests/test_install/1_add.update b/tests/test_install/1_add.update deleted file mode 100644 index 2543a71f2..000000000 --- a/tests/test_install/1_add.update +++ /dev/null @@ -1,22 +0,0 @@ -# Add in a new place in the DIT for our test cases - -dn: cn=test, cn=accounts, $SUFFIX -add:objectClass: top -add:objectClass: nsContainer -add:cn: test - -# Add a test user -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -add:objectclass: top -add:objectclass: person -add:objectclass: posixaccount -add:objectclass: krbprincipalaux -add:objectclass: inetuser -add:homedirectory: /home/tuser -add:loginshell: /bin/bash -add:sn: User -add:uid: tuser -add:uidnumber: -1 -add:gidnumber: -1 -add:cn: Test User - diff --git a/tests/test_install/2_update.update b/tests/test_install/2_update.update deleted file mode 100644 index 0d4d38e0b..000000000 --- a/tests/test_install/2_update.update +++ /dev/null @@ -1,3 +0,0 @@ -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -add:gecos: Test User - diff --git a/tests/test_install/3_update.update b/tests/test_install/3_update.update deleted file mode 100644 index c938b43a3..000000000 --- a/tests/test_install/3_update.update +++ /dev/null @@ -1,3 +0,0 @@ -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -only:gecos: Test User New - diff --git a/tests/test_install/4_update.update b/tests/test_install/4_update.update deleted file mode 100644 index 0aef7494f..000000000 --- a/tests/test_install/4_update.update +++ /dev/null @@ -1,4 +0,0 @@ -# Replace the existing SINGLE-VALUE gecos with a new value thru add -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -add:gecos: Test User New2 - diff --git a/tests/test_install/5_update.update b/tests/test_install/5_update.update deleted file mode 100644 index b0a7190ea..000000000 --- a/tests/test_install/5_update.update +++ /dev/null @@ -1,3 +0,0 @@ -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -add:cn: Test User New - diff --git a/tests/test_install/6_update.update b/tests/test_install/6_update.update deleted file mode 100644 index d398c1d4d..000000000 --- a/tests/test_install/6_update.update +++ /dev/null @@ -1,3 +0,0 @@ -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -remove:cn: Test User New - diff --git a/tests/test_install/8_badsyntax.update b/tests/test_install/8_badsyntax.update deleted file mode 100644 index 1e878964c..000000000 --- a/tests/test_install/8_badsyntax.update +++ /dev/null @@ -1,3 +0,0 @@ -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -bogus:cn: Test User New - diff --git a/tests/test_install/9_badsyntax.update b/tests/test_install/9_badsyntax.update deleted file mode 100644 index fd6d4580b..000000000 --- a/tests/test_install/9_badsyntax.update +++ /dev/null @@ -1,3 +0,0 @@ -dn: uid=tuser, cn=test, cn=accounts, $SUFFIX -add:cn - diff --git a/tests/test_install/__init__.py b/tests/test_install/__init__.py deleted file mode 100644 index 0ca31f1e3..000000000 --- a/tests/test_install/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Package containing LDAP updates unit tests. -""" diff --git a/tests/test_install/test_updates.py b/tests/test_install/test_updates.py deleted file mode 100644 index b974aa397..000000000 --- a/tests/test_install/test_updates.py +++ /dev/null @@ -1,337 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipaserver/install/ldapupdate.py` module. -""" - -import unittest -import os - -import nose - -from ipalib import api -from ipalib import errors -from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax -from ipaserver.install import installutils -from ipapython import ipautil, ipaldap -from ipapython.dn import DN - -""" -The updater works through files only so this is just a thin-wrapper controlling -which file we test at any given point. - -IMPORTANT NOTE: It is easy for these tests to get out of sync. Any changes -made to the update files may require changes to the test cases as well. -Some cases pull records from LDAP and do comparisons to ensure that updates -have occurred as expected. - -The DM password needs to be set in ~/.ipa/.dmpw -""" - -class test_update(unittest.TestCase): - """ - Test the LDAP updater. - """ - - def setUp(self): - fqdn = installutils.get_fqdn() - pwfile = api.env.dot_ipa + os.sep + ".dmpw" - if ipautil.file_exists(pwfile): - fp = open(pwfile, "r") - self.dm_password = fp.read().rstrip() - fp.close() - else: - raise nose.SkipTest("No directory manager password") - self.updater = LDAPUpdate(dm_password=self.dm_password, sub_dict={}, live_run=True) - self.ld = ipaldap.IPAdmin(fqdn) - self.ld.do_simple_bind(bindpw=self.dm_password) - if ipautil.file_exists("0_reset.update"): - self.testdir="./" - elif ipautil.file_exists("tests/test_install/0_reset.update"): - self.testdir= "./tests/test_install/" - else: - raise nose.SkipTest("Unable to find test update files") - - self.container_dn = DN(self.updater._template_str('cn=test, cn=accounts, $SUFFIX')) - self.user_dn = DN(self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX')) - - def tearDown(self): - if self.ld: - self.ld.unbind() - - def test_0_reset(self): - """ - Reset the updater test data to a known initial state (test_0_reset) - """ - try: - modified = self.updater.update([self.testdir + "0_reset.update"]) - except errors.NotFound: - # Just means the entry doesn't exist yet - modified = True - - self.assertTrue(modified) - - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - - def test_1_add(self): - """ - Test the updater with an add directive (test_1_add) - """ - modified = self.updater.update([self.testdir + "1_add.update"]) - - self.assertTrue(modified) - - entries = self.ld.get_entries( - self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - - objectclasses = entry.get('objectclass') - for item in ('top', 'nsContainer'): - self.assertTrue(item in objectclasses) - - self.assertEqual(entry.single_value('cn'), 'test') - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - - objectclasses = entry.get('objectclass') - for item in ('top', 'person', 'posixaccount', 'krbprincipalaux', 'inetuser'): - self.assertTrue(item in objectclasses) - - self.assertEqual(entry.single_value('loginshell'), '/bin/bash') - self.assertEqual(entry.single_value('sn'), 'User') - self.assertEqual(entry.single_value('uid'), 'tuser') - self.assertEqual(entry.single_value('cn'), 'Test User') - - - def test_2_update(self): - """ - Test the updater when adding an attribute to an existing entry (test_2_update) - """ - modified = self.updater.update([self.testdir + "2_update.update"]) - self.assertTrue(modified) - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - self.assertEqual(entry.single_value('gecos'), 'Test User') - - def test_3_update(self): - """ - Test the updater forcing an attribute to a given value (test_3_update) - """ - modified = self.updater.update([self.testdir + "3_update.update"]) - self.assertTrue(modified) - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - self.assertEqual(entry.single_value('gecos'), 'Test User New') - - def test_4_update(self): - """ - Test the updater adding a new value to a single-valued attribute (test_4_update) - """ - modified = self.updater.update([self.testdir + "4_update.update"]) - self.assertTrue(modified) - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - self.assertEqual(entry.single_value('gecos'), 'Test User New2') - - def test_5_update(self): - """ - Test the updater adding a new value to a multi-valued attribute (test_5_update) - """ - modified = self.updater.update([self.testdir + "5_update.update"]) - self.assertTrue(modified) - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - self.assertEqual(sorted(entry.get('cn')), sorted(['Test User', 'Test User New'])) - - def test_6_update(self): - """ - Test the updater removing a value from a multi-valued attribute (test_6_update) - """ - modified = self.updater.update([self.testdir + "6_update.update"]) - self.assertTrue(modified) - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - self.assertEqual(sorted(entry.get('cn')), sorted(['Test User'])) - - def test_6_update_1(self): - """ - Test the updater removing a non-existent value from a multi-valued attribute (test_6_update_1) - """ - modified = self.updater.update([self.testdir + "6_update.update"]) - self.assertFalse(modified) - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - self.assertEqual(sorted(entry.get('cn')), sorted(['Test User'])) - - def test_7_cleanup(self): - """ - Reset the test data to a known initial state (test_7_cleanup) - """ - try: - modified = self.updater.update([self.testdir + "0_reset.update"]) - except errors.NotFound: - # Just means the entry doesn't exist yet - modified = True - - self.assertTrue(modified) - - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - - def test_8_badsyntax(self): - """ - Test the updater with an unknown keyword (test_8_badsyntax) - """ - with self.assertRaises(BadSyntax): - modified = self.updater.update([self.testdir + "8_badsyntax.update"]) - - def test_9_badsyntax(self): - """ - Test the updater with an incomplete line (test_9_badsyntax) - """ - with self.assertRaises(BadSyntax): - modified = self.updater.update([self.testdir + "9_badsyntax.update"]) - - def test_from_dict(self): - """ - Test updating from a dict. - - This replicates what was done in test 1. - """ - - # First make sure we're clean - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - - - update = { - self.container_dn: - {'dn': self.container_dn, - 'updates': ['add:objectClass: top', - 'add:objectClass: nsContainer', - 'add:cn: test' - ], - }, - self.user_dn: - {'dn': self.user_dn, - 'updates': ['add:objectclass: top', - 'add:objectclass: person', - 'add:objectclass: posixaccount', - 'add:objectclass: krbprincipalaux', - 'add:objectclass: inetuser', - 'add:homedirectory: /home/tuser', - 'add:loginshell: /bin/bash', - 'add:sn: User', - 'add:uid: tuser', - 'add:uidnumber: 999', - 'add:gidnumber: 999', - 'add:cn: Test User', - ], - }, - } - - modified = self.updater.update_from_dict(update) - self.assertTrue(modified) - - entries = self.ld.get_entries( - self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - - objectclasses = entry.get('objectclass') - for item in ('top', 'nsContainer'): - self.assertTrue(item in objectclasses) - - self.assertEqual(entry.single_value('cn'), 'test') - - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - self.assertEqual(len(entries), 1) - entry = entries[0] - - objectclasses = entry.get('objectclass') - for item in ('top', 'person', 'posixaccount', 'krbprincipalaux', 'inetuser'): - self.assertTrue(item in objectclasses) - - self.assertEqual(entry.single_value('loginshell'), '/bin/bash') - self.assertEqual(entry.single_value('sn'), 'User') - self.assertEqual(entry.single_value('uid'), 'tuser') - self.assertEqual(entry.single_value('cn'), 'Test User') - - # Now delete - - update = { - self.container_dn: - {'dn': self.container_dn, - 'deleteentry': None, - }, - self.user_dn: - {'dn': self.user_dn, - 'deleteentry': 'deleteentry: reset: nada', - }, - } - - modified = self.updater.update_from_dict(update) - self.assertTrue(modified) - - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.container_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) - - with self.assertRaises(errors.NotFound): - entries = self.ld.get_entries( - self.user_dn, self.ld.SCOPE_BASE, 'objectclass=*', ['*']) diff --git a/tests/test_ipalib/__init__.py b/tests/test_ipalib/__init__.py deleted file mode 100644 index 4e4c605cd..000000000 --- a/tests/test_ipalib/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Sub-package containing unit tests for `ipalib` package. -""" diff --git a/tests/test_ipalib/test_backend.py b/tests/test_ipalib/test_backend.py deleted file mode 100644 index e18c8d382..000000000 --- a/tests/test_ipalib/test_backend.py +++ /dev/null @@ -1,272 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.backend` module. -""" - -import threading -from tests.util import ClassChecker, raises, create_test_api -from tests.data import unicode_str -from ipalib.request import context, Connection -from ipalib.frontend import Command -from ipalib import backend, plugable, errors, base -from ipapython.version import API_VERSION - - - -class test_Backend(ClassChecker): - """ - Test the `ipalib.backend.Backend` class. - """ - - _cls = backend.Backend - - def test_class(self): - assert self.cls.__bases__ == (plugable.Plugin,) - - -class Disconnect(object): - called = False - - def __init__(self, id=None): - self.id = id - - def __call__(self): - assert self.called is False - self.called = True - if self.id is not None: - delattr(context, self.id) - - -class test_Connectible(ClassChecker): - """ - Test the `ipalib.backend.Connectible` class. - """ - - _cls = backend.Connectible - - def test_connect(self): - """ - Test the `ipalib.backend.Connectible.connect` method. - """ - # Test that connection is created: - class example(self.cls): - def create_connection(self, *args, **kw): - object.__setattr__(self, 'args', args) - object.__setattr__(self, 'kw', kw) - return 'The connection.' - o = example() - args = ('Arg1', 'Arg2', 'Arg3') - kw = dict(key1='Val1', key2='Val2', key3='Val3') - assert not hasattr(context, 'example') - assert o.connect(*args, **kw) is None - conn = context.example - assert type(conn) is Connection - assert o.args == args - assert o.kw == kw - assert conn.conn == 'The connection.' - assert conn.disconnect == o.disconnect - - # Test that StandardError is raised if already connected: - m = "connect: 'context.%s' already exists in thread %r" - e = raises(StandardError, o.connect, *args, **kw) - assert str(e) == m % ('example', threading.currentThread().getName()) - - # Double check that it works after deleting context.example: - del context.example - assert o.connect(*args, **kw) is None - - def test_create_connection(self): - """ - Test the `ipalib.backend.Connectible.create_connection` method. - """ - class example(self.cls): - pass - for klass in (self.cls, example): - o = klass() - e = raises(NotImplementedError, o.create_connection) - assert str(e) == '%s.create_connection()' % klass.__name__ - - def test_disconnect(self): - """ - Test the `ipalib.backend.Connectible.disconnect` method. - """ - class example(self.cls): - destroy_connection = Disconnect() - o = example() - - m = "disconnect: 'context.%s' does not exist in thread %r" - e = raises(StandardError, o.disconnect) - assert str(e) == m % ('example', threading.currentThread().getName()) - - context.example = 'The connection.' - assert o.disconnect() is None - assert example.destroy_connection.called is True - - def test_destroy_connection(self): - """ - Test the `ipalib.backend.Connectible.destroy_connection` method. - """ - class example(self.cls): - pass - for klass in (self.cls, example): - o = klass() - e = raises(NotImplementedError, o.destroy_connection) - assert str(e) == '%s.destroy_connection()' % klass.__name__ - - def test_isconnected(self): - """ - Test the `ipalib.backend.Connectible.isconnected` method. - """ - class example(self.cls): - pass - for klass in (self.cls, example): - o = klass() - assert o.isconnected() is False - conn = 'whatever' - setattr(context, klass.__name__, conn) - assert o.isconnected() is True - delattr(context, klass.__name__) - - def test_conn(self): - """ - Test the `ipalib.backend.Connectible.conn` property. - """ - msg = 'no context.%s in thread %r' - class example(self.cls): - pass - for klass in (self.cls, example): - o = klass() - e = raises(AttributeError, getattr, o, 'conn') - assert str(e) == msg % ( - klass.__name__, threading.currentThread().getName() - ) - conn = Connection('The connection.', Disconnect()) - setattr(context, klass.__name__, conn) - assert o.conn is conn.conn - delattr(context, klass.__name__) - - -class test_Executioner(ClassChecker): - """ - Test the `ipalib.backend.Executioner` class. - """ - _cls = backend.Executioner - - def test_execute(self): - """ - Test the `ipalib.backend.Executioner.execute` method. - """ - (api, home) = create_test_api(in_server=True) - - class echo(Command): - takes_args = ('arg1', 'arg2+') - takes_options = ('option1?', 'option2?') - def execute(self, *args, **options): - assert type(args[1]) is tuple - return dict(result=args + (options,)) - api.register(echo) - - class good(Command): - def execute(self, **options): - raise errors.ValidationError( - name='nurse', - error=u'Not naughty!', - ) - api.register(good) - - class bad(Command): - def execute(self, **options): - raise ValueError('This is private.') - api.register(bad) - - class with_name(Command): - """ - Test that a kwarg named 'name' can be used. - """ - takes_options = 'name' - def execute(self, **options): - return dict(result=options['name'].upper()) - api.register(with_name) - - api.finalize() - o = self.cls() - o.set_api(api) - o.finalize() - - # Test that CommandError is raised: - conn = Connection('The connection.', Disconnect('someconn')) - context.someconn = conn - print str(context.__dict__.keys()) - e = raises(errors.CommandError, o.execute, 'nope') - assert e.name == 'nope' - assert conn.disconnect.called is True # Make sure destroy_context() was called - print str(context.__dict__.keys()) - assert context.__dict__.keys() == [] - - # Test with echo command: - arg1 = unicode_str - arg2 = (u'Hello', unicode_str, u'world!') - args = (arg1,) + arg2 - options = dict(option1=u'How are you?', option2=unicode_str, - version=API_VERSION) - - conn = Connection('The connection.', Disconnect('someconn')) - context.someconn = conn - print o.execute('echo', arg1, arg2, **options) - print dict( - result=(arg1, arg2, options) - ) - assert o.execute('echo', arg1, arg2, **options) == dict( - result=(arg1, arg2, options) - ) - assert conn.disconnect.called is True # Make sure destroy_context() was called - assert context.__dict__.keys() == [] - - conn = Connection('The connection.', Disconnect('someconn')) - context.someconn = conn - assert o.execute('echo', *args, **options) == dict( - result=(arg1, arg2, options) - ) - assert conn.disconnect.called is True # Make sure destroy_context() was called - assert context.__dict__.keys() == [] - - # Test with good command: - conn = Connection('The connection.', Disconnect('someconn')) - context.someconn = conn - e = raises(errors.ValidationError, o.execute, 'good') - assert e.name == 'nurse' - assert e.error == u'Not naughty!' - assert conn.disconnect.called is True # Make sure destroy_context() was called - assert context.__dict__.keys() == [] - - # Test with bad command: - conn = Connection('The connection.', Disconnect('someconn')) - context.someconn = conn - e = raises(errors.InternalError, o.execute, 'bad') - assert conn.disconnect.called is True # Make sure destroy_context() was called - assert context.__dict__.keys() == [] - - # Test with option 'name': - conn = Connection('The connection.', Disconnect('someconn')) - context.someconn = conn - expected = dict(result=u'TEST') - assert expected == o.execute('with_name', name=u'test', - version=API_VERSION) diff --git a/tests/test_ipalib/test_base.py b/tests/test_ipalib/test_base.py deleted file mode 100644 index 78c8be032..000000000 --- a/tests/test_ipalib/test_base.py +++ /dev/null @@ -1,352 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.base` module. -""" - -from tests.util import ClassChecker, raises -from ipalib.constants import NAME_REGEX, NAME_ERROR -from ipalib.constants import TYPE_ERROR, SET_ERROR, DEL_ERROR, OVERRIDE_ERROR -from ipalib import base - - -class test_ReadOnly(ClassChecker): - """ - Test the `ipalib.base.ReadOnly` class - """ - _cls = base.ReadOnly - - def test_lock(self): - """ - Test the `ipalib.base.ReadOnly.__lock__` method. - """ - o = self.cls() - assert o._ReadOnly__locked is False - o.__lock__() - assert o._ReadOnly__locked is True - e = raises(AssertionError, o.__lock__) # Can only be locked once - assert str(e) == '__lock__() can only be called once' - assert o._ReadOnly__locked is True # This should still be True - - def test_islocked(self): - """ - Test the `ipalib.base.ReadOnly.__islocked__` method. - """ - o = self.cls() - assert o.__islocked__() is False - o.__lock__() - assert o.__islocked__() is True - - def test_setattr(self): - """ - Test the `ipalib.base.ReadOnly.__setattr__` method. - """ - o = self.cls() - o.attr1 = 'Hello, world!' - assert o.attr1 == 'Hello, world!' - o.__lock__() - for name in ('attr1', 'attr2'): - e = raises(AttributeError, setattr, o, name, 'whatever') - assert str(e) == SET_ERROR % ('ReadOnly', name, 'whatever') - assert o.attr1 == 'Hello, world!' - - def test_delattr(self): - """ - Test the `ipalib.base.ReadOnly.__delattr__` method. - """ - o = self.cls() - o.attr1 = 'Hello, world!' - o.attr2 = 'How are you?' - assert o.attr1 == 'Hello, world!' - assert o.attr2 == 'How are you?' - del o.attr1 - assert not hasattr(o, 'attr1') - o.__lock__() - e = raises(AttributeError, delattr, o, 'attr2') - assert str(e) == DEL_ERROR % ('ReadOnly', 'attr2') - assert o.attr2 == 'How are you?' - - -def test_lock(): - """ - Test the `ipalib.base.lock` function - """ - f = base.lock - - # Test with ReadOnly instance: - o = base.ReadOnly() - assert o.__islocked__() is False - assert f(o) is o - assert o.__islocked__() is True - e = raises(AssertionError, f, o) - assert str(e) == 'already locked: %r' % o - - # Test with another class implemented locking protocol: - class Lockable(object): - __locked = False - def __lock__(self): - self.__locked = True - def __islocked__(self): - return self.__locked - o = Lockable() - assert o.__islocked__() is False - assert f(o) is o - assert o.__islocked__() is True - e = raises(AssertionError, f, o) - assert str(e) == 'already locked: %r' % o - - # Test with a class incorrectly implementing the locking protocol: - class Broken(object): - def __lock__(self): - pass - def __islocked__(self): - return False - o = Broken() - e = raises(AssertionError, f, o) - assert str(e) == 'failed to lock: %r' % o - - -def test_islocked(): - """ - Test the `ipalib.base.islocked` function. - """ - f = base.islocked - - # Test with ReadOnly instance: - o = base.ReadOnly() - assert f(o) is False - o.__lock__() - assert f(o) is True - - # Test with another class implemented locking protocol: - class Lockable(object): - __locked = False - def __lock__(self): - self.__locked = True - def __islocked__(self): - return self.__locked - o = Lockable() - assert f(o) is False - o.__lock__() - assert f(o) is True - - # Test with a class incorrectly implementing the locking protocol: - class Broken(object): - __lock__ = False - def __islocked__(self): - return False - o = Broken() - e = raises(AssertionError, f, o) - assert str(e) == 'no __lock__() method: %r' % o - - -def test_check_name(): - """ - Test the `ipalib.base.check_name` function. - """ - f = base.check_name - okay = [ - 'user_add', - 'stuff2junk', - 'sixty9', - ] - nope = [ - '_user_add', - '__user_add', - 'user_add_', - 'user_add__', - '_user_add_', - '__user_add__', - '60nine', - ] - for name in okay: - assert name is f(name) - e = raises(TypeError, f, unicode(name)) - assert str(e) == TYPE_ERROR % ('name', str, unicode(name), unicode) - for name in nope: - e = raises(ValueError, f, name) - assert str(e) == NAME_ERROR % (NAME_REGEX, name) - for name in okay: - e = raises(ValueError, f, name.upper()) - assert str(e) == NAME_ERROR % (NAME_REGEX, name.upper()) - - -def membername(i): - return 'member%03d' % i - - -class DummyMember(object): - def __init__(self, i): - self.i = i - self.name = membername(i) - - -def gen_members(*indexes): - return tuple(DummyMember(i) for i in indexes) - - -class test_NameSpace(ClassChecker): - """ - Test the `ipalib.base.NameSpace` class. - """ - _cls = base.NameSpace - - def new(self, count, sort=True): - members = tuple(DummyMember(i) for i in xrange(count, 0, -1)) - assert len(members) == count - o = self.cls(members, sort=sort) - return (o, members) - - def test_init(self): - """ - Test the `ipalib.base.NameSpace.__init__` method. - """ - o = self.cls([]) - assert len(o) == 0 - assert list(o) == [] - assert list(o()) == [] - - # Test members as attribute and item: - for cnt in (3, 42): - for sort in (True, False): - (o, members) = self.new(cnt, sort=sort) - assert len(members) == cnt - for m in members: - assert getattr(o, m.name) is m - assert o[m.name] is m - - # Test that TypeError is raised if sort is not a bool: - e = raises(TypeError, self.cls, [], sort=None) - assert str(e) == TYPE_ERROR % ('sort', bool, None, type(None)) - - # Test that AttributeError is raised with duplicate member name: - members = gen_members(0, 1, 2, 1, 3) - e = raises(AttributeError, self.cls, members) - assert str(e) == OVERRIDE_ERROR % ( - 'NameSpace', membername(1), members[1], members[3] - ) - - def test_len(self): - """ - Test the `ipalib.base.NameSpace.__len__` method. - """ - for count in (5, 18, 127): - (o, members) = self.new(count) - assert len(o) == count - (o, members) = self.new(count, sort=False) - assert len(o) == count - - def test_iter(self): - """ - Test the `ipalib.base.NameSpace.__iter__` method. - """ - (o, members) = self.new(25) - assert list(o) == sorted(m.name for m in members) - (o, members) = self.new(25, sort=False) - assert list(o) == list(m.name for m in members) - - def test_call(self): - """ - Test the `ipalib.base.NameSpace.__call__` method. - """ - (o, members) = self.new(25) - assert list(o()) == sorted(members, key=lambda m: m.name) - (o, members) = self.new(25, sort=False) - assert tuple(o()) == members - - def test_contains(self): - """ - Test the `ipalib.base.NameSpace.__contains__` method. - """ - yes = (99, 3, 777) - no = (9, 333, 77) - for sort in (True, False): - members = gen_members(*yes) - o = self.cls(members, sort=sort) - for i in yes: - assert membername(i) in o - assert membername(i).upper() not in o - for i in no: - assert membername(i) not in o - - def test_getitem(self): - """ - Test the `ipalib.base.NameSpace.__getitem__` method. - """ - cnt = 17 - for sort in (True, False): - (o, members) = self.new(cnt, sort=sort) - assert len(members) == cnt - if sort is True: - members = tuple(sorted(members, key=lambda m: m.name)) - - # Test str keys: - for m in members: - assert o[m.name] is m - e = raises(KeyError, o.__getitem__, 'nope') - - # Test int indexes: - for i in xrange(cnt): - assert o[i] is members[i] - e = raises(IndexError, o.__getitem__, cnt) - - # Test negative int indexes: - for i in xrange(1, cnt + 1): - assert o[-i] is members[-i] - e = raises(IndexError, o.__getitem__, -(cnt + 1)) - - # Test slicing: - assert o[3:] == members[3:] - assert o[:10] == members[:10] - assert o[3:10] == members[3:10] - assert o[-9:] == members[-9:] - assert o[:-4] == members[:-4] - assert o[-9:-4] == members[-9:-4] - - # Test that TypeError is raised with wrong type - e = raises(TypeError, o.__getitem__, 3.0) - assert str(e) == TYPE_ERROR % ('key', (str, int, slice), 3.0, float) - - def test_repr(self): - """ - Test the `ipalib.base.NameSpace.__repr__` method. - """ - for cnt in (0, 1, 2): - for sort in (True, False): - (o, members) = self.new(cnt, sort=sort) - if cnt == 1: - assert repr(o) == \ - 'NameSpace(<%d member>, sort=%r)' % (cnt, sort) - else: - assert repr(o) == \ - 'NameSpace(<%d members>, sort=%r)' % (cnt, sort) - - def test_todict(self): - """ - Test the `ipalib.base.NameSpace.__todict__` method. - """ - for cnt in (3, 101): - for sort in (True, False): - (o, members) = self.new(cnt, sort=sort) - d = o.__todict__() - assert d == dict((m.name, m) for m in members) - - # Test that a copy is returned: - assert o.__todict__() is not d diff --git a/tests/test_ipalib/test_capabilities.py b/tests/test_ipalib/test_capabilities.py deleted file mode 100644 index 21e53c2dc..000000000 --- a/tests/test_ipalib/test_capabilities.py +++ /dev/null @@ -1,33 +0,0 @@ -# Authors: -# Petr Viktorin -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.errors` module. -""" - -from ipalib.capabilities import capabilities, client_has_capability - - -def test_client_has_capability(): - assert capabilities['messages'] == u'2.52' - assert client_has_capability(u'2.52', 'messages') - assert client_has_capability(u'2.60', 'messages') - assert client_has_capability(u'3.0', 'messages') - assert not client_has_capability(u'2.11', 'messages') - assert not client_has_capability(u'0.1', 'messages') diff --git a/tests/test_ipalib/test_cli.py b/tests/test_ipalib/test_cli.py deleted file mode 100644 index 0a6eeee1f..000000000 --- a/tests/test_ipalib/test_cli.py +++ /dev/null @@ -1,116 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.cli` module. -""" - -from tests.util import raises, get_api, ClassChecker -from ipalib import cli, plugable, frontend, backend - - -class test_textui(ClassChecker): - _cls = cli.textui - - def test_max_col_width(self): - """ - Test the `ipalib.cli.textui.max_col_width` method. - """ - o = self.cls() - e = raises(TypeError, o.max_col_width, 'hello') - assert str(e) == 'rows: need %r or %r; got %r' % (list, tuple, 'hello') - rows = [ - 'hello', - 'naughty', - 'nurse', - ] - assert o.max_col_width(rows) == len('naughty') - rows = ( - ( 'a', 'bbb', 'ccccc'), - ('aa', 'bbbb', 'cccccc'), - ) - assert o.max_col_width(rows, col=0) == 2 - assert o.max_col_width(rows, col=1) == 4 - assert o.max_col_width(rows, col=2) == 6 - - -def test_to_cli(): - """ - Test the `ipalib.cli.to_cli` function. - """ - f = cli.to_cli - assert f('initialize') == 'initialize' - assert f('user_add') == 'user-add' - - -def test_from_cli(): - """ - Test the `ipalib.cli.from_cli` function. - """ - f = cli.from_cli - assert f('initialize') == 'initialize' - assert f('user-add') == 'user_add' - - -def get_cmd_name(i): - return 'cmd_%d' % i - - -class DummyCommand(object): - def __init__(self, name): - self.__name = name - - def __get_name(self): - return self.__name - name = property(__get_name) - - -class DummyAPI(object): - def __init__(self, cnt): - self.__cmd = plugable.NameSpace(self.__cmd_iter(cnt)) - - def __get_cmd(self): - return self.__cmd - Command = property(__get_cmd) - - def __cmd_iter(self, cnt): - for i in xrange(cnt): - yield DummyCommand(get_cmd_name(i)) - - def finalize(self): - pass - - def register(self, *args, **kw): - pass - - -config_cli = """ -[global] - -from_cli_conf = set in cli.conf -""" - -config_default = """ -[global] - -from_default_conf = set in default.conf - -# Make sure cli.conf is loaded first: -from_cli_conf = overridden in default.conf -""" diff --git a/tests/test_ipalib/test_config.py b/tests/test_ipalib/test_config.py deleted file mode 100644 index e729a6284..000000000 --- a/tests/test_ipalib/test_config.py +++ /dev/null @@ -1,609 +0,0 @@ -# Authors: -# Martin Nagy -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.config` module. -""" - -import os -from os import path -import sys -import socket -from tests.util import raises, setitem, delitem, ClassChecker -from tests.util import getitem, setitem, delitem -from tests.util import TempDir, TempHome -from ipalib.constants import TYPE_ERROR, OVERRIDE_ERROR, SET_ERROR, DEL_ERROR -from ipalib.constants import NAME_REGEX, NAME_ERROR -from ipalib import config, constants, base - - -# Valid environment variables in (key, raw, value) tuples: -# key: the name of the environment variable -# raw: the value being set (possibly a string repr) -# value: the expected value after the lightweight conversion -good_vars = ( - ('a_string', u'Hello world!', u'Hello world!'), - ('trailing_whitespace', u' value ', u'value'), - ('an_int', 42, 42), - ('int_repr', ' 42 ', 42), - ('a_float', 3.14, 3.14), - ('float_repr', ' 3.14 ', 3.14), - ('true', True, True), - ('true_repr', ' True ', True), - ('false', False, False), - ('false_repr', ' False ', False), - ('none', None, None), - ('none_repr', ' None ', None), - ('empty', '', None), - - # These verify that the implied conversion is case-sensitive: - ('not_true', u' true ', u'true'), - ('not_false', u' false ', u'false'), - ('not_none', u' none ', u'none'), -) - - -bad_names = ( - ('CamelCase', u'value'), - ('_leading_underscore', u'value'), - ('trailing_underscore_', u'value'), -) - - -# Random base64-encoded data to simulate a misbehaving config file. -config_bad = """ -/9j/4AAQSkZJRgABAQEAlgCWAAD//gAIT2xpdmVy/9sAQwAQCwwODAoQDg0OEhEQExgoGhgWFhgx -IyUdKDozPTw5Mzg3QEhcTkBEV0U3OFBtUVdfYmdoZz5NcXlwZHhcZWdj/8AACwgAlgB0AQERAP/E -ABsAAAEFAQEAAAAAAAAAAAAAAAQAAQIDBQYH/8QAMhAAAgICAAUDBAIABAcAAAAAAQIAAwQRBRIh -MUEGE1EiMmFxFIEVI0LBFjNSYnKRof/aAAgBAQAAPwDCtzmNRr1o/MEP1D6f7kdkRakgBsAtoQhk -xls/y3Z113I11mhiUc1ewCf1Oq4anJgINdhLhQoextfedmYrenfcvdzaFQnYAE08XhONTWEK8+js -Fpo1oqAKoAA8CWjoJJTHM8kJ5jsiOiszAKD1+IV/hmW76rosbfnlh1Pp3Mah2srCnXQE9YXiel/c -p5r7uVj2CwxPTuFjjmdLbteNwmrLwsYe3TjsD8cmjKV43ycy+3o76D4llFuXmuCoZEPczXVOSsLv -f5lgGpNZLxJL2jnvMar0/wAOp6jHDH/uO4RViY9f/KpRdfC6k3R9fRyj+pRZVkWKqF10e+hCKaFq -XlH/ALlmhK7Met/uUGZ5ow8XL57lU8/Yt4lx4jUOJphLobTe/wDaHeZLxHXtJEya9o5lFzCqpmPY -CUYoPtDfc9TLj0G5jZvHaMFirAs++oEHq9U4rbNiMp8a6wO/1Zbzn2alC+Nx8P1JfdeBboA+AILx -rin8pfbA1ynvKuFUXZOXXkLbzOp2R56andL2G45MmO0RPWWLEe8GzaffoKb/ADI44Pt9ZXxAuuFa -axtgp0BOSPCcviNX8n3Aw8KTNHB4FiY9StkobLWHVSeghq8M4bkAhKKyV6Hl8RV8MwMZG1Uuz3Jn -IcUQJlMFGlJ6D4hfpymy7iChHKqvVtefxO7Ai1txLBIn7pcojN3jGVhQO0ZgCNfM5ZHycTLycSkr -yhtqD4Bmrfw5cuqsm6xHXyp1seRLcHCp4dQy1bOzslj1MzeJ5dVFnuMVdgOiHxOWzrmyMg2Nrbde -k3vR2OTddcd6A5R8GdZqOo67k4wXrLAQPMRKnzImMZEzm+P1nFz6cxQeVujagWR6jsYiqivlH/Ux -1M+7jWY30i7QHx1gF11tjGyxiSfmVc+503pPidVROHYNNY21b/adVZZySo3uOo1qIZQYd9RCzfYm -TUk/qW71LjGkTA+IYiZmM1T9N9j8Gee5+McXJem0/Wp8GUK6KOi7b5MgzFjsxpJHZGDKSCOxE3cD -OvsxbbLc9lsT7Vc73KX4ln3q1ZyVrPx2J/uAjLyan37z7B+Zp4vqPJqKi0K4EvzvUt1qBMdfb+T5 -gycfzkXXuc35InfE6nO8Y9SjFc1Yqh2Hdj2mH/xFxR26XgD/AMRJf45mWMqW5bBD3KqAZlZtb++7 -kEqTsHe//sG1CcTBvy7OWpD+Sewhz8CyKCTYAQPiGV0LVWPdxqQNADQ6zL4nWq2gopU6+ofmA8x3 -1MlvfeIGbnBeCHitRt94IFbRGus2U9H08v13sT+BNHjeX/D4bY4OmP0rPPbHLMWJ2Yy2EDQjVsos -BdeYDx8wo5L5KpSdLWPAE1+G8NrFtBKgOAXPTf6mzViql5ZBoE87eJZkKbOQ8m+Yjf5EBzcO621y -GCqD0H41Obzq7U6vzM577HTXgzPPeOIvM1eB59nD8xXVj7bHTr8iej1MtlauvUMNgzi/V2ctliYy -HYTq37nMExpZXRZYpZVJUdzNjg+FXYwZgdhv6nVVUJU/uH7iNf1CARrtF0IB113M7jTNVjFl2xJA -5ROey88OrVOugOy67TDs+89NRKdSYILdRC8ZQVJ+PHyJs4fqe3EoFPLzBexPxOdusa2xndiWY7JM -qMUNrzOTAfHC9XO9/E3vT9blVJB0o2Zu3MAoYrsL13Ii0Muw3XvJG9KkDOeqjf6gWcw5A33XN9nX -tOeyMRFWy3Jch+bX7mXmCsW/5RBXUoHaOIRi2asAJ0IRbjqzll3o/EAaRiltDojgv2E1aePmhEWq -rsNHZ7wir1K/8Y1vUCSCAd+IXiZ9b1gLYvN07trXTUD4rxN2TkUgEts8p2NDtD0t5MVGchr2Xe99 -hMPNvD1LX5J2TuZhGyYwBijjfiHU5bJXrnYfqBRtRtSbIBWG3+xI6HiLUWz8xA9RuaVNrMAPfB5x -r6v9MLr4S1il7LaxyjY69Jl5eG+Kyhiv1jYIMGYMO8etGscKoJJ8Cbp4bVg4ivaq22t3G/tmRYo5 -zyjQ+JRFFET01GB0Yid9YiYh1l9KgEHqT8Tco/hewA/NzgdQdwTNGNTY3uU2crL9HN00ZlovNzfV -oCanBrBRk1rpCHPUkQjjYoW4GtwAw30MDpuxvbAvpJceR5mXFFEY0W4o4mpg0XNXutQxPUHxLb8q -7mRDyszLr6esz8u++9wL2LcvQb8RXCkhBV3A6mR5rEVSrdFPT8SBLMdsdmWe6P8AUAx+TB4oooxi -i1Jmt0+5dfuOLbANB2H6MjzNzc2zv5ji1g2+5/MYnbb+Yh+T0kubUY940UUbUWtRpJN8w1CfebkK -WfUu+/mDOAGOjsRo0UkIo+pPl6Rckl7ehuR1INGAj9u0kW2nXvK45YlQp1odukaICSAjgSQWf//Z -""" - - -# A config file that tries to override some standard vars: -config_override = """ -[global] - -key0 = var0 -home = /home/sweet/home -key1 = var1 -site_packages = planet -key2 = var2 -key3 = var3 -""" - - -# A config file that tests the automatic type conversion -config_good = """ -[global] - -string = Hello world! -null = None -yes = True -no = False -number = 42 -floating = 3.14 -""" - - -# A default config file to make sure it does not overwrite the explicit one -config_default = """ -[global] - -yes = Hello -not_in_other = foo_bar -""" - - -class test_Env(ClassChecker): - """ - Test the `ipalib.config.Env` class. - """ - - _cls = config.Env - - def test_init(self): - """ - Test the `ipalib.config.Env.__init__` method. - """ - o = self.cls() - assert list(o) == [] - assert len(o) == 0 - assert o.__islocked__() is False - - def test_lock(self): - """ - Test the `ipalib.config.Env.__lock__` method. - """ - o = self.cls() - assert o.__islocked__() is False - o.__lock__() - assert o.__islocked__() is True - e = raises(StandardError, o.__lock__) - assert str(e) == 'Env.__lock__() already called' - - # Also test with base.lock() function: - o = self.cls() - assert o.__islocked__() is False - assert base.lock(o) is o - assert o.__islocked__() is True - e = raises(AssertionError, base.lock, o) - assert str(e) == 'already locked: %r' % o - - def test_islocked(self): - """ - Test the `ipalib.config.Env.__islocked__` method. - """ - o = self.cls() - assert o.__islocked__() is False - assert base.islocked(o) is False - o.__lock__() - assert o.__islocked__() is True - assert base.islocked(o) is True - - def test_setattr(self): - """ - Test the `ipalib.config.Env.__setattr__` method. - """ - o = self.cls() - for (name, raw, value) in good_vars: - # Test setting the value: - setattr(o, name, raw) - result = getattr(o, name) - assert type(result) is type(value) - assert result == value - assert result is o[name] - - # Test that value cannot be overridden once set: - e = raises(AttributeError, setattr, o, name, raw) - assert str(e) == OVERRIDE_ERROR % ('Env', name, value, raw) - - # Test that values cannot be set once locked: - o = self.cls() - o.__lock__() - for (name, raw, value) in good_vars: - e = raises(AttributeError, setattr, o, name, raw) - assert str(e) == SET_ERROR % ('Env', name, raw) - - # Test that name is tested with check_name(): - o = self.cls() - for (name, value) in bad_names: - e = raises(ValueError, setattr, o, name, value) - assert str(e) == NAME_ERROR % (NAME_REGEX, name) - - def test_setitem(self): - """ - Test the `ipalib.config.Env.__setitem__` method. - """ - o = self.cls() - for (key, raw, value) in good_vars: - # Test setting the value: - o[key] = raw - result = o[key] - assert type(result) is type(value) - assert result == value - assert result is getattr(o, key) - - # Test that value cannot be overridden once set: - e = raises(AttributeError, o.__setitem__, key, raw) - assert str(e) == OVERRIDE_ERROR % ('Env', key, value, raw) - - # Test that values cannot be set once locked: - o = self.cls() - o.__lock__() - for (key, raw, value) in good_vars: - e = raises(AttributeError, o.__setitem__, key, raw) - assert str(e) == SET_ERROR % ('Env', key, raw) - - # Test that name is tested with check_name(): - o = self.cls() - for (key, value) in bad_names: - e = raises(ValueError, o.__setitem__, key, value) - assert str(e) == NAME_ERROR % (NAME_REGEX, key) - - def test_getitem(self): - """ - Test the `ipalib.config.Env.__getitem__` method. - """ - o = self.cls() - value = u'some value' - o.key = value - assert o.key is value - assert o['key'] is value - for name in ('one', 'two'): - e = raises(KeyError, getitem, o, name) - assert str(e) == repr(name) - - def test_delattr(self): - """ - Test the `ipalib.config.Env.__delattr__` method. - - This also tests that ``__delitem__`` is not implemented. - """ - o = self.cls() - o.one = 1 - assert o.one == 1 - for key in ('one', 'two'): - e = raises(AttributeError, delattr, o, key) - assert str(e) == DEL_ERROR % ('Env', key) - e = raises(AttributeError, delitem, o, key) - assert str(e) == '__delitem__' - - def test_contains(self): - """ - Test the `ipalib.config.Env.__contains__` method. - """ - o = self.cls() - items = [ - ('one', 1), - ('two', 2), - ('three', 3), - ('four', 4), - ] - for (key, value) in items: - assert key not in o - o[key] = value - assert key in o - - def test_len(self): - """ - Test the `ipalib.config.Env.__len__` method. - """ - o = self.cls() - assert len(o) == 0 - for i in xrange(1, 11): - key = 'key%d' % i - value = u'value %d' % i - o[key] = value - assert o[key] is value - assert len(o) == i - - def test_iter(self): - """ - Test the `ipalib.config.Env.__iter__` method. - """ - o = self.cls() - default_keys = tuple(o) - keys = ('one', 'two', 'three', 'four', 'five') - for key in keys: - o[key] = 'the value' - assert list(o) == sorted(keys + default_keys) - - def test_merge(self): - """ - Test the `ipalib.config.Env._merge` method. - """ - group1 = ( - ('key1', u'value 1'), - ('key2', u'value 2'), - ('key3', u'value 3'), - ('key4', u'value 4'), - ) - group2 = ( - ('key0', u'Value 0'), - ('key2', u'Value 2'), - ('key4', u'Value 4'), - ('key5', u'Value 5'), - ) - o = self.cls() - assert o._merge(**dict(group1)) == (4, 4) - assert len(o) == 4 - assert list(o) == list(key for (key, value) in group1) - for (key, value) in group1: - assert getattr(o, key) is value - assert o[key] is value - assert o._merge(**dict(group2)) == (2, 4) - assert len(o) == 6 - expected = dict(group2) - expected.update(dict(group1)) - assert list(o) == sorted(expected) - assert expected['key2'] == 'value 2' # And not 'Value 2' - for (key, value) in expected.iteritems(): - assert getattr(o, key) is value - assert o[key] is value - assert o._merge(**expected) == (0, 6) - assert len(o) == 6 - assert list(o) == sorted(expected) - - def test_merge_from_file(self): - """ - Test the `ipalib.config.Env._merge_from_file` method. - """ - tmp = TempDir() - assert callable(tmp.join) - - # Test a config file that doesn't exist - no_exist = tmp.join('no_exist.conf') - assert not path.exists(no_exist) - o = self.cls() - o._bootstrap() - keys = tuple(o) - orig = dict((k, o[k]) for k in o) - assert o._merge_from_file(no_exist) is None - assert tuple(o) == keys - - # Test an empty config file - empty = tmp.touch('empty.conf') - assert path.isfile(empty) - assert o._merge_from_file(empty) == (0, 0) - assert tuple(o) == keys - - # Test a mal-formed config file: - bad = tmp.join('bad.conf') - open(bad, 'w').write(config_bad) - assert path.isfile(bad) - assert o._merge_from_file(bad) is None - assert tuple(o) == keys - - # Test a valid config file that tries to override - override = tmp.join('override.conf') - open(override, 'w').write(config_override) - assert path.isfile(override) - assert o._merge_from_file(override) == (4, 6) - for (k, v) in orig.items(): - assert o[k] is v - assert list(o) == sorted(keys + ('key0', 'key1', 'key2', 'key3', 'config_loaded')) - for i in xrange(4): - assert o['key%d' % i] == ('var%d' % i) - keys = tuple(o) - - # Test a valid config file with type conversion - good = tmp.join('good.conf') - open(good, 'w').write(config_good) - assert path.isfile(good) - assert o._merge_from_file(good) == (6, 6) - added = ('string', 'null', 'yes', 'no', 'number', 'floating') - assert list(o) == sorted(keys + added) - assert o.string == 'Hello world!' - assert o.null is None - assert o.yes is True - assert o.no is False - assert o.number == 42 - assert o.floating == 3.14 - - def new(self, in_tree=False): - """ - Set os.environ['HOME'] to a tempdir. - - Returns tuple with new Env instance and the TempHome instance. This - helper method is used in testing the bootstrap related methods below. - """ - home = TempHome() - o = self.cls() - if in_tree: - o.in_tree = True - return (o, home) - - def bootstrap(self, **overrides): - """ - Helper method used in testing bootstrap related methods below. - """ - (o, home) = self.new() - assert o._isdone('_bootstrap') is False - o._bootstrap(**overrides) - assert o._isdone('_bootstrap') is True - e = raises(StandardError, o._bootstrap) - assert str(e) == 'Env._bootstrap() already called' - return (o, home) - - def test_bootstrap(self): - """ - Test the `ipalib.config.Env._bootstrap` method. - """ - # Test defaults created by _bootstrap(): - (o, home) = self.new() - o._bootstrap() - ipalib = path.dirname(path.abspath(config.__file__)) - assert o.ipalib == ipalib - assert o.site_packages == path.dirname(ipalib) - assert o.script == path.abspath(sys.argv[0]) - assert o.bin == path.dirname(path.abspath(sys.argv[0])) - assert o.home == home.path - assert o.dot_ipa == home.join('.ipa') - assert o.in_tree is False - assert o.context == 'default' - assert o.confdir == '/etc/ipa' - assert o.conf == '/etc/ipa/default.conf' - assert o.conf_default == o.conf - - # Test overriding values created by _bootstrap() - (o, home) = self.bootstrap(in_tree='True', context='server') - assert o.in_tree is True - assert o.context == 'server' - assert o.conf == home.join('.ipa', 'server.conf') - (o, home) = self.bootstrap(conf='/my/wacky/whatever.conf') - assert o.in_tree is False - assert o.context == 'default' - assert o.conf == '/my/wacky/whatever.conf' - assert o.conf_default == '/etc/ipa/default.conf' - (o, home) = self.bootstrap(conf_default='/my/wacky/default.conf') - assert o.in_tree is False - assert o.context == 'default' - assert o.conf == '/etc/ipa/default.conf' - assert o.conf_default == '/my/wacky/default.conf' - - # Test various overrides and types conversion - kw = dict( - yes=True, - no=False, - num=42, - msg='Hello, world!', - ) - override = dict( - (k, u' %s ' % v) for (k, v) in kw.items() - ) - (o, home) = self.new() - for key in kw: - assert key not in o - o._bootstrap(**override) - for (key, value) in kw.items(): - assert getattr(o, key) == value - assert o[key] == value - - def finalize_core(self, ctx, **defaults): - """ - Helper method used in testing `Env._finalize_core`. - """ - # We must force in_tree=True so we don't load possible config files in - # /etc/ipa/, whose contents could break this test: - (o, home) = self.new(in_tree=True) - if ctx: - o.context = ctx - - # Check that calls cascade down the chain: - set_here = ('in_server', 'logdir', 'log') - assert o._isdone('_bootstrap') is False - assert o._isdone('_finalize_core') is False - assert o._isdone('_finalize') is False - for key in set_here: - assert key not in o - o._finalize_core(**defaults) - assert o._isdone('_bootstrap') is True - assert o._isdone('_finalize_core') is True - assert o._isdone('_finalize') is False # Should not cascade - for key in set_here: - assert key in o - - # Check that it can't be called twice: - e = raises(StandardError, o._finalize_core) - assert str(e) == 'Env._finalize_core() already called' - - return (o, home) - - def test_finalize_core(self): - """ - Test the `ipalib.config.Env._finalize_core` method. - """ - # Test that correct defaults are generated: - (o, home) = self.finalize_core(None) - assert o.in_server is False - assert o.logdir == home.join('.ipa', 'log') - assert o.log == home.join('.ipa', 'log', 'default.log') - - # Test with context='server' - (o, home) = self.finalize_core('server') - assert o.in_server is True - assert o.logdir == home.join('.ipa', 'log') - assert o.log == home.join('.ipa', 'log', 'server.log') - - # Test that **defaults can't set in_server, logdir, nor log: - (o, home) = self.finalize_core(None, - in_server='IN_SERVER', - logdir='LOGDIR', - log='LOG', - ) - assert o.in_server is False - assert o.logdir == home.join('.ipa', 'log') - assert o.log == home.join('.ipa', 'log', 'default.log') - - # Test loading config file, plus test some in-tree stuff - (o, home) = self.bootstrap(in_tree=True, context='server') - for key in ('yes', 'no', 'number'): - assert key not in o - home.write(config_good, '.ipa', 'server.conf') - home.write(config_default, '.ipa', 'default.conf') - o._finalize_core() - assert o.in_tree is True - assert o.context == 'server' - assert o.in_server is True - assert o.logdir == home.join('.ipa', 'log') - assert o.log == home.join('.ipa', 'log', 'server.log') - assert o.yes is True - assert o.no is False - assert o.number == 42 - assert o.not_in_other == 'foo_bar' - - # Test using DEFAULT_CONFIG: - defaults = dict(constants.DEFAULT_CONFIG) - (o, home) = self.finalize_core(None, **defaults) - assert list(o) == sorted(defaults) - for (key, value) in defaults.items(): - if value is object: - continue - if key == 'mode': - continue - assert o[key] == value, '%r is %r; should be %r' % (key, o[key], value) - - def test_finalize(self): - """ - Test the `ipalib.config.Env._finalize` method. - """ - # Check that calls cascade up the chain: - (o, home) = self.new(in_tree=True) - assert o._isdone('_bootstrap') is False - assert o._isdone('_finalize_core') is False - assert o._isdone('_finalize') is False - o._finalize() - assert o._isdone('_bootstrap') is True - assert o._isdone('_finalize_core') is True - assert o._isdone('_finalize') is True - - # Check that it can't be called twice: - e = raises(StandardError, o._finalize) - assert str(e) == 'Env._finalize() already called' - - # Check that _finalize() calls __lock__() - (o, home) = self.new(in_tree=True) - assert o.__islocked__() is False - o._finalize() - assert o.__islocked__() is True - e = raises(StandardError, o.__lock__) - assert str(e) == 'Env.__lock__() already called' - - # Check that **lastchance works - (o, home) = self.finalize_core(None) - key = 'just_one_more_key' - value = u'with one more value' - lastchance = {key: value} - assert key not in o - assert o._isdone('_finalize') is False - o._finalize(**lastchance) - assert key in o - assert o[key] is value diff --git a/tests/test_ipalib/test_crud.py b/tests/test_ipalib/test_crud.py deleted file mode 100644 index b19605be7..000000000 --- a/tests/test_ipalib/test_crud.py +++ /dev/null @@ -1,240 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.crud` module. -""" - -from tests.util import read_only, raises, get_api, ClassChecker -from ipalib import crud, frontend, plugable, config -from ipalib.parameters import Str - - -class CrudChecker(ClassChecker): - """ - Class for testing base classes in `ipalib.crud`. - """ - - def get_api(self, args=tuple(), options=tuple()): - """ - Return a finalized `ipalib.plugable.API` instance. - """ - (api, home) = get_api() - class user(frontend.Object): - takes_params = ( - 'givenname', - Str('sn', flags='no_update'), - Str('uid', primary_key=True), - 'initials', - Str('uidnumber', flags=['no_create', 'no_search']) - ) - class user_verb(self.cls): - takes_args = args - takes_options = options - api.register(user) - api.register(user_verb) - api.finalize() - return api - - -class test_Create(CrudChecker): - """ - Test the `ipalib.crud.Create` class. - """ - - _cls = crud.Create - - def test_get_args(self): - """ - Test the `ipalib.crud.Create.get_args` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.args) == ['uid'] - assert api.Method.user_verb.args.uid.required is True - - def test_get_options(self): - """ - Test the `ipalib.crud.Create.get_options` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.options) == \ - ['givenname', 'sn', 'initials', 'all', 'raw', 'version'] - for param in api.Method.user_verb.options(): - if param.name != 'version': - assert param.required is True - api = self.get_api(options=('extra?',)) - assert list(api.Method.user_verb.options) == \ - ['givenname', 'sn', 'initials', 'extra', 'all', 'raw', 'version'] - assert api.Method.user_verb.options.extra.required is False - - -class test_Update(CrudChecker): - """ - Test the `ipalib.crud.Update` class. - """ - - _cls = crud.Update - - def test_get_args(self): - """ - Test the `ipalib.crud.Update.get_args` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.args) == ['uid'] - assert api.Method.user_verb.args.uid.required is True - - def test_get_options(self): - """ - Test the `ipalib.crud.Update.get_options` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.options) == \ - ['givenname', 'initials', 'uidnumber', 'all', 'raw', 'version'] - for param in api.Method.user_verb.options(): - if param.name in ['all', 'raw']: - assert param.required is True - else: - assert param.required is False - - -class test_Retrieve(CrudChecker): - """ - Test the `ipalib.crud.Retrieve` class. - """ - - _cls = crud.Retrieve - - def test_get_args(self): - """ - Test the `ipalib.crud.Retrieve.get_args` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.args) == ['uid'] - assert api.Method.user_verb.args.uid.required is True - - def test_get_options(self): - """ - Test the `ipalib.crud.Retrieve.get_options` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.options) == ['all', 'raw', 'version'] - - -class test_Delete(CrudChecker): - """ - Test the `ipalib.crud.Delete` class. - """ - - _cls = crud.Delete - - def test_get_args(self): - """ - Test the `ipalib.crud.Delete.get_args` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.args) == ['uid'] - assert api.Method.user_verb.args.uid.required is True - - def test_get_options(self): - """ - Test the `ipalib.crud.Delete.get_options` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.options) == ['version'] - assert len(api.Method.user_verb.options) == 1 - - -class test_Search(CrudChecker): - """ - Test the `ipalib.crud.Search` class. - """ - - _cls = crud.Search - - def test_get_args(self): - """ - Test the `ipalib.crud.Search.get_args` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.args) == ['criteria'] - assert api.Method.user_verb.args.criteria.required is False - - def test_get_options(self): - """ - Test the `ipalib.crud.Search.get_options` method. - """ - api = self.get_api() - assert list(api.Method.user_verb.options) == \ - ['givenname', 'sn', 'uid', 'initials', 'all', 'raw', 'version'] - for param in api.Method.user_verb.options(): - if param.name in ['all', 'raw']: - assert param.required is True - else: - assert param.required is False - - -class test_CrudBackend(ClassChecker): - """ - Test the `ipalib.crud.CrudBackend` class. - """ - - _cls = crud.CrudBackend - - def get_subcls(self): - class ldap(self.cls): - pass - return ldap - - def check_method(self, name, *args): - o = self.cls() - e = raises(NotImplementedError, getattr(o, name), *args) - assert str(e) == 'CrudBackend.%s()' % name - sub = self.subcls() - e = raises(NotImplementedError, getattr(sub, name), *args) - assert str(e) == 'ldap.%s()' % name - - def test_create(self): - """ - Test the `ipalib.crud.CrudBackend.create` method. - """ - self.check_method('create') - - def test_retrieve(self): - """ - Test the `ipalib.crud.CrudBackend.retrieve` method. - """ - self.check_method('retrieve', 'primary key', 'attribute') - - def test_update(self): - """ - Test the `ipalib.crud.CrudBackend.update` method. - """ - self.check_method('update', 'primary key') - - def test_delete(self): - """ - Test the `ipalib.crud.CrudBackend.delete` method. - """ - self.check_method('delete', 'primary key') - - def test_search(self): - """ - Test the `ipalib.crud.CrudBackend.search` method. - """ - self.check_method('search') diff --git a/tests/test_ipalib/test_errors.py b/tests/test_ipalib/test_errors.py deleted file mode 100644 index 49bed7104..000000000 --- a/tests/test_ipalib/test_errors.py +++ /dev/null @@ -1,374 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.errors` module. -""" - -import re -import inspect - -from tests.util import assert_equal, raises -from ipalib import errors, text -from ipalib.constants import TYPE_ERROR - - -class PrivateExceptionTester(object): - _klass = None - __klass = None - - def __get_klass(self): - if self.__klass is None: - self.__klass = self._klass - assert issubclass(self.__klass, StandardError) - assert issubclass(self.__klass, errors.PrivateError) - assert not issubclass(self.__klass, errors.PublicError) - return self.__klass - klass = property(__get_klass) - - def new(self, **kw): - for (key, value) in kw.iteritems(): - assert not hasattr(self.klass, key), key - inst = self.klass(**kw) - assert isinstance(inst, StandardError) - assert isinstance(inst, errors.PrivateError) - assert isinstance(inst, self.klass) - assert not isinstance(inst, errors.PublicError) - for (key, value) in kw.iteritems(): - assert getattr(inst, key) is value - assert str(inst) == self.klass.format % kw - assert inst.message == str(inst) - return inst - - -class test_PrivateError(PrivateExceptionTester): - """ - Test the `ipalib.errors.PrivateError` exception. - """ - _klass = errors.PrivateError - - def test_init(self): - """ - Test the `ipalib.errors.PrivateError.__init__` method. - """ - inst = self.klass(key1='Value 1', key2='Value 2') - assert inst.key1 == 'Value 1' - assert inst.key2 == 'Value 2' - assert str(inst) == '' - - # Test subclass and use of format: - class subclass(self.klass): - format = '%(true)r %(text)r %(number)r' - - kw = dict(true=True, text='Hello!', number=18) - inst = subclass(**kw) - assert inst.true is True - assert inst.text is kw['text'] - assert inst.number is kw['number'] - assert str(inst) == subclass.format % kw - - # Test via PrivateExceptionTester.new() - inst = self.new(**kw) - assert isinstance(inst, self.klass) - assert inst.true is True - assert inst.text is kw['text'] - assert inst.number is kw['number'] - - -class test_SubprocessError(PrivateExceptionTester): - """ - Test the `ipalib.errors.SubprocessError` exception. - """ - - _klass = errors.SubprocessError - - def test_init(self): - """ - Test the `ipalib.errors.SubprocessError.__init__` method. - """ - inst = self.new(returncode=1, argv=('/bin/false',)) - assert inst.returncode == 1 - assert inst.argv == ('/bin/false',) - assert str(inst) == "return code 1 from ('/bin/false',)" - assert inst.message == str(inst) - - -class test_PluginSubclassError(PrivateExceptionTester): - """ - Test the `ipalib.errors.PluginSubclassError` exception. - """ - - _klass = errors.PluginSubclassError - - def test_init(self): - """ - Test the `ipalib.errors.PluginSubclassError.__init__` method. - """ - inst = self.new(plugin='bad', bases=('base1', 'base2')) - assert inst.plugin == 'bad' - assert inst.bases == ('base1', 'base2') - assert str(inst) == \ - "'bad' not subclass of any base in ('base1', 'base2')" - assert inst.message == str(inst) - - -class test_PluginDuplicateError(PrivateExceptionTester): - """ - Test the `ipalib.errors.PluginDuplicateError` exception. - """ - - _klass = errors.PluginDuplicateError - - def test_init(self): - """ - Test the `ipalib.errors.PluginDuplicateError.__init__` method. - """ - inst = self.new(plugin='my_plugin') - assert inst.plugin == 'my_plugin' - assert str(inst) == "'my_plugin' was already registered" - assert inst.message == str(inst) - - -class test_PluginOverrideError(PrivateExceptionTester): - """ - Test the `ipalib.errors.PluginOverrideError` exception. - """ - - _klass = errors.PluginOverrideError - - def test_init(self): - """ - Test the `ipalib.errors.PluginOverrideError.__init__` method. - """ - inst = self.new(base='Base', name='cmd', plugin='my_cmd') - assert inst.base == 'Base' - assert inst.name == 'cmd' - assert inst.plugin == 'my_cmd' - assert str(inst) == "unexpected override of Base.cmd with 'my_cmd'" - assert inst.message == str(inst) - - -class test_PluginMissingOverrideError(PrivateExceptionTester): - """ - Test the `ipalib.errors.PluginMissingOverrideError` exception. - """ - - _klass = errors.PluginMissingOverrideError - - def test_init(self): - """ - Test the `ipalib.errors.PluginMissingOverrideError.__init__` method. - """ - inst = self.new(base='Base', name='cmd', plugin='my_cmd') - assert inst.base == 'Base' - assert inst.name == 'cmd' - assert inst.plugin == 'my_cmd' - assert str(inst) == "Base.cmd not registered, cannot override with 'my_cmd'" - assert inst.message == str(inst) - - - -############################################################################## -# Unit tests for public errors: - -class PublicExceptionTester(object): - _klass = None - __klass = None - - def __get_klass(self): - if self.__klass is None: - self.__klass = self._klass - assert issubclass(self.__klass, StandardError) - assert issubclass(self.__klass, errors.PublicError) - assert not issubclass(self.__klass, errors.PrivateError) - assert type(self.__klass.errno) is int - assert 900 <= self.__klass.errno <= 5999 - return self.__klass - klass = property(__get_klass) - - def new(self, format=None, message=None, **kw): - # Test that TypeError is raised if message isn't unicode: - e = raises(TypeError, self.klass, message='The message') - assert str(e) == TYPE_ERROR % ('message', unicode, 'The message', str) - - # Test the instance: - for (key, value) in kw.iteritems(): - assert not hasattr(self.klass, key), key - inst = self.klass(format=format, message=message, **kw) - for required_class in self.required_classes: - assert isinstance(inst, required_class) - assert isinstance(inst, self.klass) - assert not isinstance(inst, errors.PrivateError) - for (key, value) in kw.iteritems(): - assert getattr(inst, key) is value - return inst - - -class test_PublicError(PublicExceptionTester): - """ - Test the `ipalib.errors.PublicError` exception. - """ - _klass = errors.PublicError - required_classes = StandardError, errors.PublicError - - def test_init(self): - message = u'The translated, interpolated message' - format = 'key=%(key1)r and key2=%(key2)r' - uformat = u'Translated key=%(key1)r and key2=%(key2)r' - val1 = 'Value 1' - val2 = 'Value 2' - kw = dict(key1=val1, key2=val2) - - # Test with format=str, message=None - inst = self.klass(format, **kw) - assert inst.format is format - assert_equal(inst.message, format % kw) - assert inst.forwarded is False - assert inst.key1 is val1 - assert inst.key2 is val2 - - # Test with format=None, message=unicode - inst = self.klass(message=message, **kw) - assert inst.format is None - assert inst.message is message - assert inst.strerror is message - assert inst.forwarded is True - assert inst.key1 is val1 - assert inst.key2 is val2 - - # Test with format=None, message=str - e = raises(TypeError, self.klass, message='the message', **kw) - assert str(e) == TYPE_ERROR % ('message', unicode, 'the message', str) - - # Test with format=None, message=None - e = raises(ValueError, self.klass, **kw) - assert (str(e) == '%s.format is None yet format=None, message=None' % - self.klass.__name__) - - - ###################################### - # Test via PublicExceptionTester.new() - - # Test with format=str, message=None - inst = self.new(format, **kw) - assert isinstance(inst, self.klass) - assert inst.format is format - assert_equal(inst.message, format % kw) - assert inst.forwarded is False - assert inst.key1 is val1 - assert inst.key2 is val2 - - # Test with format=None, message=unicode - inst = self.new(message=message, **kw) - assert isinstance(inst, self.klass) - assert inst.format is None - assert inst.message is message - assert inst.strerror is message - assert inst.forwarded is True - assert inst.key1 is val1 - assert inst.key2 is val2 - - - ################## - # Test a subclass: - class subclass(self.klass): - format = '%(true)r %(text)r %(number)r' - - uformat = u'Translated %(true)r %(text)r %(number)r' - kw = dict(true=True, text='Hello!', number=18) - - # Test with format=str, message=None - e = raises(ValueError, subclass, format, **kw) - assert str(e) == 'non-generic %r needs format=None; got format=%r' % ( - 'subclass', format) - - # Test with format=None, message=None: - inst = subclass(**kw) - assert inst.format is subclass.format - assert_equal(inst.message, subclass.format % kw) - assert inst.forwarded is False - assert inst.true is True - assert inst.text is kw['text'] - assert inst.number is kw['number'] - - # Test with format=None, message=unicode: - inst = subclass(message=message, **kw) - assert inst.format is subclass.format - assert inst.message is message - assert inst.strerror is message - assert inst.forwarded is True - assert inst.true is True - assert inst.text is kw['text'] - assert inst.number is kw['number'] - - # Test with instructions: - # first build up "instructions", then get error and search for - # lines of instructions appended to the end of the strerror - # despite the parameter 'instructions' not existing in the format - instructions = u"The quick brown fox jumps over the lazy dog".split() - # this expression checks if each word of instructions - # exists in a string as a separate line, with right order - regexp = re.compile('(?ims).*' + - ''.join(map(lambda x: '(%s).*' % (x), - instructions)) + - '$') - inst = subclass(instructions=instructions, **kw) - assert inst.format is subclass.format - assert_equal(inst.instructions, instructions) - inst_match = regexp.match(inst.strerror).groups() - assert_equal(list(inst_match),list(instructions)) - - -class BaseMessagesTest(object): - """Generic test for all of a module's errors or messages - """ - def test_public_messages(self): - i = 0 - for klass in self.message_list: - for required_class in self.required_classes: - assert issubclass(klass, required_class) - assert type(klass.errno) is int - assert klass.errno in self.errno_range - doc = inspect.getdoc(klass) - assert doc is not None, 'need class docstring for %s' % klass.__name__ - m = re.match(r'^\*{2}(\d+)\*{2} ', doc) - assert m is not None, "need '**ERRNO**' in %s docstring" % klass.__name__ - errno = int(m.group(1)) - assert errno == klass.errno, ( - 'docstring=%r but errno=%r in %s' % (errno, klass.errno, klass.__name__) - ) - self.extratest(klass) - - # Test format - if klass.format is not None: - assert klass.format is self.texts[i] - i += 1 - - def extratest(self, cls): - pass - - -class test_PublicErrors(object): - message_list = errors.public_errors - errno_range = xrange(900, 5999) - required_classes = (StandardError, errors.PublicError) - texts = errors._texts - - def extratest(self, cls): - assert not issubclass(cls, errors.PrivateError) diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py deleted file mode 100644 index 3a540608d..000000000 --- a/tests/test_ipalib/test_frontend.py +++ /dev/null @@ -1,1188 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.frontend` module. -""" - -from tests.util import raises, getitem, no_set, no_del, read_only -from tests.util import check_TypeError, ClassChecker, create_test_api -from tests.util import assert_equal -from ipalib.constants import TYPE_ERROR -from ipalib.base import NameSpace -from ipalib import frontend, backend, plugable, errors, parameters, config -from ipalib import output, messages -from ipalib.parameters import Str -from ipapython.version import API_VERSION - -def test_RULE_FLAG(): - assert frontend.RULE_FLAG == 'validation_rule' - - -def test_rule(): - """ - Test the `ipalib.frontend.rule` function. - """ - flag = frontend.RULE_FLAG - rule = frontend.rule - def my_func(): - pass - assert not hasattr(my_func, flag) - rule(my_func) - assert getattr(my_func, flag) is True - @rule - def my_func2(): - pass - assert getattr(my_func2, flag) is True - - -def test_is_rule(): - """ - Test the `ipalib.frontend.is_rule` function. - """ - is_rule = frontend.is_rule - flag = frontend.RULE_FLAG - - class no_call(object): - def __init__(self, value): - if value is not None: - assert value in (True, False) - setattr(self, flag, value) - - class call(no_call): - def __call__(self): - pass - - assert is_rule(call(True)) - assert not is_rule(no_call(True)) - assert not is_rule(call(False)) - assert not is_rule(call(None)) - - -class test_HasParam(ClassChecker): - """ - Test the `ipalib.frontend.Command` class. - """ - - _cls = frontend.HasParam - - def test_get_param_iterable(self): - """ - Test the `ipalib.frontend.HasParam._get_param_iterable` method. - """ - class WithTuple(self.cls): - takes_stuff = ('one', 'two') - o = WithTuple() - assert o._get_param_iterable('stuff') is WithTuple.takes_stuff - - junk = ('three', 'four') - class WithCallable(self.cls): - def takes_stuff(self): - return junk - o = WithCallable() - assert o._get_param_iterable('stuff') is junk - - class WithParam(self.cls): - takes_stuff = parameters.Str('five') - o = WithParam() - assert o._get_param_iterable('stuff') == (WithParam.takes_stuff,) - - class WithStr(self.cls): - takes_stuff = 'six' - o = WithStr() - assert o._get_param_iterable('stuff') == ('six',) - - class Wrong(self.cls): - takes_stuff = ['seven', 'eight'] - o = Wrong() - e = raises(TypeError, o._get_param_iterable, 'stuff') - assert str(e) == '%s.%s must be a tuple, callable, or spec; got %r' % ( - 'Wrong', 'takes_stuff', Wrong.takes_stuff - ) - - def test_filter_param_by_context(self): - """ - Test the `ipalib.frontend.HasParam._filter_param_by_context` method. - """ - class Example(self.cls): - def get_stuff(self): - return ( - 'one', # Make sure create_param() is called for each spec - 'two', - parameters.Str('three', include='cli'), - parameters.Str('four', exclude='server'), - parameters.Str('five', exclude=['whatever', 'cli']), - ) - o = Example() - - # Test when env is None: - params = list(o._filter_param_by_context('stuff')) - assert list(p.name for p in params) == [ - 'one', 'two', 'three', 'four', 'five' - ] - for p in params: - assert type(p) is parameters.Str - - # Test when env.context == 'cli': - cli = config.Env(context='cli') - assert cli.context == 'cli' - params = list(o._filter_param_by_context('stuff', cli)) - assert list(p.name for p in params) == ['one', 'two', 'three', 'four'] - for p in params: - assert type(p) is parameters.Str - - # Test when env.context == 'server' - server = config.Env(context='server') - assert server.context == 'server' - params = list(o._filter_param_by_context('stuff', server)) - assert list(p.name for p in params) == ['one', 'two', 'five'] - for p in params: - assert type(p) is parameters.Str - - # Test with no get_stuff: - class Missing(self.cls): - pass - o = Missing() - gen = o._filter_param_by_context('stuff') - e = raises(NotImplementedError, list, gen) - assert str(e) == 'Missing.get_stuff()' - - # Test when get_stuff is not callable: - class NotCallable(self.cls): - get_stuff = ('one', 'two') - o = NotCallable() - gen = o._filter_param_by_context('stuff') - e = raises(TypeError, list, gen) - assert str(e) == '%s.%s must be a callable; got %r' % ( - 'NotCallable', 'get_stuff', NotCallable.get_stuff - ) - - -class test_Command(ClassChecker): - """ - Test the `ipalib.frontend.Command` class. - """ - - _cls = frontend.Command - - def get_subcls(self): - """ - Return a standard subclass of `ipalib.frontend.Command`. - """ - class Rule(object): - def __init__(self, name): - self.name = name - - def __call__(self, _, value): - if value != self.name: - return _('must equal %r') % self.name - - default_from = parameters.DefaultFrom( - lambda arg: arg, - 'default_from' - ) - normalizer = lambda value: value.lower() - - class example(self.cls): - takes_options = ( - parameters.Str('option0', Rule('option0'), - normalizer=normalizer, - default_from=default_from, - ), - parameters.Str('option1', Rule('option1'), - normalizer=normalizer, - default_from=default_from, - ), - ) - return example - - def get_instance(self, args=tuple(), options=tuple()): - """ - Helper method used to test args and options. - """ - class example(self.cls): - takes_args = args - takes_options = options - o = example() - o.finalize() - return o - - def test_class(self): - """ - Test the `ipalib.frontend.Command` class. - """ - assert self.cls.takes_options == tuple() - assert self.cls.takes_args == tuple() - - def test_get_args(self): - """ - Test the `ipalib.frontend.Command.get_args` method. - """ - assert list(self.cls().get_args()) == [] - args = ('login', 'stuff') - o = self.get_instance(args=args) - assert tuple(o.get_args()) == args - - def test_get_options(self): - """ - Test the `ipalib.frontend.Command.get_options` method. - """ - options = list(self.cls().get_options()) - assert len(options) == 1 - assert options[0].name == 'version' - options = ('verbose', 'debug') - o = self.get_instance(options=options) - assert len(tuple(o.get_options())) == 3 - assert 'verbose' in tuple(o.get_options()) - assert 'debug' in tuple(o.get_options()) - - def test_args(self): - """ - Test the ``ipalib.frontend.Command.args`` instance attribute. - """ - assert self.cls().args is None - o = self.cls() - o.finalize() - assert type(o.args) is plugable.NameSpace - assert len(o.args) == 0 - args = ('destination', 'source?') - ns = self.get_instance(args=args).args - assert type(ns) is plugable.NameSpace - assert len(ns) == len(args) - assert list(ns) == ['destination', 'source'] - assert type(ns.destination) is parameters.Str - assert type(ns.source) is parameters.Str - assert ns.destination.required is True - assert ns.destination.multivalue is False - assert ns.source.required is False - assert ns.source.multivalue is False - - # Test TypeError: - e = raises(TypeError, self.get_instance, args=(u'whatever',)) - assert str(e) == TYPE_ERROR % ( - 'spec', (str, parameters.Param), u'whatever', unicode) - - # Test ValueError, required after optional: - e = raises(ValueError, self.get_instance, args=('arg1?', 'arg2')) - assert str(e) == 'arg2: required argument after optional' - - # Test ValueError, scalar after multivalue: - e = raises(ValueError, self.get_instance, args=('arg1+', 'arg2')) - assert str(e) == 'arg2: only final argument can be multivalue' - - def test_max_args(self): - """ - Test the ``ipalib.frontend.Command.max_args`` instance attribute. - """ - o = self.get_instance() - assert o.max_args == 0 - o = self.get_instance(args=('one?',)) - assert o.max_args == 1 - o = self.get_instance(args=('one', 'two?')) - assert o.max_args == 2 - o = self.get_instance(args=('one', 'multi+',)) - assert o.max_args is None - o = self.get_instance(args=('one', 'multi*',)) - assert o.max_args is None - - def test_options(self): - """ - Test the ``ipalib.frontend.Command.options`` instance attribute. - """ - assert self.cls().options is None - o = self.cls() - o.finalize() - assert type(o.options) is plugable.NameSpace - assert len(o.options) == 1 - options = ('target', 'files*') - ns = self.get_instance(options=options).options - assert type(ns) is plugable.NameSpace - assert len(ns) == len(options) + 1 - assert list(ns) == ['target', 'files', 'version'] - assert type(ns.target) is parameters.Str - assert type(ns.files) is parameters.Str - assert ns.target.required is True - assert ns.target.multivalue is False - assert ns.files.required is False - assert ns.files.multivalue is True - - def test_output(self): - """ - Test the ``ipalib.frontend.Command.output`` instance attribute. - """ - inst = self.cls() - assert inst.output is None - inst.finalize() - assert type(inst.output) is plugable.NameSpace - assert list(inst.output) == ['result'] - assert type(inst.output.result) is output.Output - - def test_iter_output(self): - """ - Test the ``ipalib.frontend.Command._iter_output`` instance attribute. - """ - class Example(self.cls): - pass - inst = Example() - - inst.has_output = tuple() - assert list(inst._iter_output()) == [] - - wrong = ['hello', 'world'] - inst.has_output = wrong - e = raises(TypeError, list, inst._iter_output()) - assert str(e) == 'Example.has_output: need a %r; got a %r: %r' % ( - tuple, list, wrong - ) - - wrong = ('hello', 17) - inst.has_output = wrong - e = raises(TypeError, list, inst._iter_output()) - assert str(e) == 'Example.has_output[1]: need a %r; got a %r: %r' % ( - (str, output.Output), int, 17 - ) - - okay = ('foo', output.Output('bar'), 'baz') - inst.has_output = okay - items = list(inst._iter_output()) - assert len(items) == 3 - assert list(o.name for o in items) == ['foo', 'bar', 'baz'] - for o in items: - assert type(o) is output.Output - - def test_soft_validate(self): - """ - Test the `ipalib.frontend.Command.soft_validate` method. - """ - class user_add(frontend.Command): - takes_args = parameters.Str('uid', - normalizer=lambda value: value.lower(), - default_from=lambda givenname, sn: givenname[0] + sn, - ) - - takes_options = ('givenname', 'sn') - - cmd = user_add() - cmd.env = config.Env(context='cli') - cmd.finalize() - assert list(cmd.params) == ['givenname', 'sn', 'uid', 'version'] - ret = cmd.soft_validate({}) - assert sorted(ret['values']) == ['version'] - assert sorted(ret['errors']) == ['givenname', 'sn', 'uid'] - assert cmd.soft_validate(dict(givenname=u'First', sn=u'Last')) == dict( - values=dict(givenname=u'First', sn=u'Last', uid=u'flast', - version=None), - errors=dict(), - ) - - def test_convert(self): - """ - Test the `ipalib.frontend.Command.convert` method. - """ - kw = dict( - option0=u'1.5', - option1=u'7', - ) - o = self.subcls() - o.finalize() - for (key, value) in o.convert(**kw).iteritems(): - assert_equal(unicode(kw[key]), value) - - def test_normalize(self): - """ - Test the `ipalib.frontend.Command.normalize` method. - """ - kw = dict( - option0=u'OPTION0', - option1=u'OPTION1', - ) - norm = dict((k, v.lower()) for (k, v) in kw.items()) - sub = self.subcls() - sub.finalize() - assert sub.normalize(**kw) == norm - - def test_get_default(self): - """ - Test the `ipalib.frontend.Command.get_default` method. - """ - # FIXME: Add an updated unit tests for get_default() - - def test_default_from_chaining(self): - """ - Test chaining of parameters through default_from. - """ - class my_cmd(self.cls): - takes_options = ( - Str('option0'), - Str('option1', default_from=lambda option0: option0), - Str('option2', default_from=lambda option1: option1), - ) - - def run(self, *args, **options): - return dict(result=options) - - kw = dict(option0=u'some value') - - (api, home) = create_test_api() - api.finalize() - o = my_cmd() - o.set_api(api) - o.finalize() - e = o(**kw) - assert type(e) is dict - assert 'result' in e - assert 'option2' in e['result'] - assert e['result']['option2'] == u'some value' - - def test_validate(self): - """ - Test the `ipalib.frontend.Command.validate` method. - """ - - sub = self.subcls() - sub.env = config.Env(context='cli') - sub.finalize() - - # Check with valid values - okay = dict( - option0=u'option0', - option1=u'option1', - another_option='some value', - version=API_VERSION, - ) - sub.validate(**okay) - - # Check with an invalid value - fail = dict(okay) - fail['option0'] = u'whatever' - e = raises(errors.ValidationError, sub.validate, **fail) - assert_equal(e.name, 'option0') - assert_equal(e.value, u'whatever') - assert_equal(e.error, u"must equal 'option0'") - assert e.rule.__class__.__name__ == 'Rule' - assert e.index is None - - # Check with a missing required arg - fail = dict(okay) - fail.pop('option1') - e = raises(errors.RequirementError, sub.validate, **fail) - assert e.name == 'option1' - - def test_execute(self): - """ - Test the `ipalib.frontend.Command.execute` method. - """ - o = self.cls() - e = raises(NotImplementedError, o.execute) - assert str(e) == 'Command.execute()' - - def test_args_options_2_params(self): - """ - Test the `ipalib.frontend.Command.args_options_2_params` method. - """ - - # Test that ZeroArgumentError is raised: - o = self.get_instance() - e = raises(errors.ZeroArgumentError, o.args_options_2_params, 1) - assert e.name == 'example' - - # Test that MaxArgumentError is raised (count=1) - o = self.get_instance(args=('one?',)) - e = raises(errors.MaxArgumentError, o.args_options_2_params, 1, 2) - assert e.name == 'example' - assert e.count == 1 - assert str(e) == "command 'example' takes at most 1 argument" - - # Test that MaxArgumentError is raised (count=2) - o = self.get_instance(args=('one', 'two?')) - e = raises(errors.MaxArgumentError, o.args_options_2_params, 1, 2, 3) - assert e.name == 'example' - assert e.count == 2 - assert str(e) == "command 'example' takes at most 2 arguments" - - # Test that OptionError is raised when an extra option is given: - o = self.get_instance() - e = raises(errors.OptionError, o.args_options_2_params, bad_option=True) - assert e.option == 'bad_option' - - # Test that OverlapError is raised: - o = self.get_instance(args=('one', 'two'), options=('three', 'four')) - e = raises(errors.OverlapError, o.args_options_2_params, - 1, 2, three=3, two=2, four=4, one=1) - assert e.names == ['one', 'two'] - - # Test the permutations: - o = self.get_instance(args=('one', 'two*'), options=('three', 'four')) - mthd = o.args_options_2_params - assert mthd() == dict() - assert mthd(1) == dict(one=1) - assert mthd(1, 2) == dict(one=1, two=(2,)) - assert mthd(1, 21, 22, 23) == dict(one=1, two=(21, 22, 23)) - assert mthd(1, (21, 22, 23)) == dict(one=1, two=(21, 22, 23)) - assert mthd(three=3, four=4) == dict(three=3, four=4) - assert mthd(three=3, four=4, one=1, two=2) == \ - dict(one=1, two=2, three=3, four=4) - assert mthd(1, 21, 22, 23, three=3, four=4) == \ - dict(one=1, two=(21, 22, 23), three=3, four=4) - assert mthd(1, (21, 22, 23), three=3, four=4) == \ - dict(one=1, two=(21, 22, 23), three=3, four=4) - - def test_args_options_2_entry(self): - """ - Test `ipalib.frontend.Command.args_options_2_entry` method. - """ - class my_cmd(self.cls): - takes_args = ( - parameters.Str('one', attribute=True), - parameters.Str('two', attribute=False), - ) - takes_options = ( - parameters.Str('three', attribute=True, multivalue=True), - parameters.Str('four', attribute=True, multivalue=False), - ) - - def run(self, *args, **kw): - return self.args_options_2_entry(*args, **kw) - - args = ('one', 'two') - kw = dict(three=('three1', 'three2'), four='four') - - (api, home) = create_test_api() - api.finalize() - o = my_cmd() - o.set_api(api) - o.finalize() - e = o.run(*args, **kw) - assert type(e) is dict - assert 'one' in e - assert 'two' not in e - assert 'three' in e - assert 'four' in e - assert e['one'] == 'one' - assert e['three'] == ['three1', 'three2'] - assert e['four'] == 'four' - - def test_params_2_args_options(self): - """ - Test the `ipalib.frontend.Command.params_2_args_options` method. - """ - o = self.get_instance(args='one', options='two') - assert o.params_2_args_options() == ((None,), {}) - assert o.params_2_args_options(one=1) == ((1,), {}) - assert o.params_2_args_options(two=2) == ((None,), dict(two=2)) - assert o.params_2_args_options(two=2, one=1) == ((1,), dict(two=2)) - - def test_run(self): - """ - Test the `ipalib.frontend.Command.run` method. - """ - class my_cmd(self.cls): - def execute(self, *args, **kw): - return ('execute', args, kw) - - def forward(self, *args, **kw): - return ('forward', args, kw) - - args = ('Hello,', 'world,') - kw = dict(how_are='you', on_this='fine day?', version=API_VERSION) - - # Test in server context: - (api, home) = create_test_api(in_server=True) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - out = o.run(*args, **kw) - assert ('execute', args, kw) == out - - # Test in non-server context - (api, home) = create_test_api(in_server=False) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - assert ('forward', args, kw) == o.run(*args, **kw) - - def test_messages(self): - """ - Test correct handling of messages - """ - class TestMessage(messages.PublicMessage): - type = 'info' - format = 'This is a message.' - errno = 1234 - - class my_cmd(self.cls): - def execute(self, *args, **kw): - result = {'name': 'execute'} - messages.add_message(kw['version'], result, TestMessage()) - return result - - def forward(self, *args, **kw): - result = {'name': 'forward'} - messages.add_message(kw['version'], result, TestMessage()) - return result - - args = ('Hello,', 'world,') - kw = dict(how_are='you', on_this='fine day?', version=API_VERSION) - - expected = [TestMessage().to_dict()] - - # Test in server context: - (api, home) = create_test_api(in_server=True) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - assert {'name': 'execute', 'messages': expected} == o.run(*args, **kw) - - # Test in non-server context - (api, home) = create_test_api(in_server=False) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - assert {'name': 'forward', 'messages': expected} == o.run(*args, **kw) - - def test_validate_output_basic(self): - """ - Test the `ipalib.frontend.Command.validate_output` method. - """ - class Example(self.cls): - has_output = ('foo', 'bar', 'baz') - - inst = Example() - inst.finalize() - - # Test with wrong type: - wrong = ('foo', 'bar', 'baz') - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): need a %r; got a %r: %r' % ( - 'Example', dict, tuple, wrong - ) - - # Test with a missing keys: - wrong = dict(bar='hello') - e = raises(ValueError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): missing keys %r in %r' % ( - 'Example', ['baz', 'foo'], wrong - ) - - # Test with extra keys: - wrong = dict(foo=1, bar=2, baz=3, fee=4, azz=5) - e = raises(ValueError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): unexpected keys %r in %r' % ( - 'Example', ['azz', 'fee'], wrong - ) - - # Test with different keys: - wrong = dict(baz=1, xyzzy=2, quux=3) - e = raises(ValueError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): missing keys %r in %r' % ( - 'Example', ['bar', 'foo'], wrong - ), str(e) - - def test_validate_output_per_type(self): - """ - Test `ipalib.frontend.Command.validate_output` per-type validation. - """ - - class Complex(self.cls): - has_output = ( - output.Output('foo', int), - output.Output('bar', list), - ) - inst = Complex() - inst.finalize() - - wrong = dict(foo=17.9, bar=[18]) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == '%s:\n output[%r]: need %r; got %r: %r' % ( - 'Complex.validate_output()', 'foo', int, float, 17.9 - ) - - wrong = dict(foo=18, bar=17) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == '%s:\n output[%r]: need %r; got %r: %r' % ( - 'Complex.validate_output()', 'bar', list, int, 17 - ) - - def test_validate_output_nested(self): - """ - Test `ipalib.frontend.Command.validate_output` nested validation. - """ - - class Subclass(output.ListOfEntries): - pass - - # Test nested validation: - class nested(self.cls): - has_output = ( - output.Output('hello', int), - Subclass('world'), - ) - inst = nested() - inst.finalize() - okay = dict(foo='bar') - nope = ('aye', 'bee') - - wrong = dict(hello=18, world=[okay, nope, okay]) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == output.emsg % ( - 'nested', 'Subclass', 'world', 1, dict, tuple, nope - ) - - wrong = dict(hello=18, world=[okay, okay, okay, okay, nope]) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == output.emsg % ( - 'nested', 'Subclass', 'world', 4, dict, tuple, nope - ) - - def test_get_output_params(self): - """ - Test the `ipalib.frontend.Command.get_output_params` method. - """ - class example(self.cls): - has_output_params = ( - 'one', - 'two', - 'three', - ) - takes_args = ( - 'foo', - ) - takes_options = ( - Str('bar', flags='no_output'), - 'baz', - ) - - inst = example() - assert list(inst.get_output_params()) == ['one', 'two', 'three'] - inst.finalize() - assert list(inst.get_output_params()) == [ - 'one', 'two', 'three', inst.params.foo, inst.params.baz - ] - assert list(inst.output_params) == ['one', 'two', 'three', 'foo', 'baz'] - - -class test_LocalOrRemote(ClassChecker): - """ - Test the `ipalib.frontend.LocalOrRemote` class. - """ - _cls = frontend.LocalOrRemote - - def test_init(self): - """ - Test the `ipalib.frontend.LocalOrRemote.__init__` method. - """ - o = self.cls() - o.finalize() - assert list(o.args) == [] - assert list(o.options) == ['server', 'version'] - op = o.options.server - assert op.required is False - assert op.default is False - - def test_run(self): - """ - Test the `ipalib.frontend.LocalOrRemote.run` method. - """ - class example(self.cls): - takes_args = 'key?' - - def forward(self, *args, **options): - return dict(result=('forward', args, options)) - - def execute(self, *args, **options): - return dict(result=('execute', args, options)) - - # Test when in_server=False: - (api, home) = create_test_api(in_server=False) - api.register(example) - api.finalize() - cmd = api.Command.example - assert cmd(version=u'2.47') == dict( - result=('execute', (None,), dict(version=u'2.47', server=False)) - ) - assert cmd(u'var', version=u'2.47') == dict( - result=('execute', (u'var',), dict(version=u'2.47', server=False)) - ) - assert cmd(server=True, version=u'2.47') == dict( - result=('forward', (None,), dict(version=u'2.47', server=True)) - ) - assert cmd(u'var', server=True, version=u'2.47') == dict( - result=('forward', (u'var',), dict(version=u'2.47', server=True)) - ) - - # Test when in_server=True (should always call execute): - (api, home) = create_test_api(in_server=True) - api.register(example) - api.finalize() - cmd = api.Command.example - assert cmd(version=u'2.47') == dict( - result=('execute', (None,), dict(version=u'2.47', server=False)) - ) - assert cmd(u'var', version=u'2.47') == dict( - result=('execute', (u'var',), dict(version=u'2.47', server=False)) - ) - assert cmd(server=True, version=u'2.47') == dict( - result=('execute', (None,), dict(version=u'2.47', server=True)) - ) - assert cmd(u'var', server=True, version=u'2.47') == dict( - result=('execute', (u'var',), dict(version=u'2.47', server=True)) - ) - - -class test_Object(ClassChecker): - """ - Test the `ipalib.frontend.Object` class. - """ - _cls = frontend.Object - - def test_class(self): - """ - Test the `ipalib.frontend.Object` class. - """ - assert self.cls.backend is None - assert self.cls.methods is None - assert self.cls.properties is None - assert self.cls.params is None - assert self.cls.params_minus_pk is None - assert self.cls.takes_params == tuple() - - def test_init(self): - """ - Test the `ipalib.frontend.Object.__init__` method. - """ - o = self.cls() - assert o.backend is None - assert o.methods is None - assert o.properties is None - assert o.params is None - assert o.params_minus_pk is None - assert o.properties is None - - def test_set_api(self): - """ - Test the `ipalib.frontend.Object.set_api` method. - """ - # Setup for test: - class DummyAttribute(object): - def __init__(self, obj_name, attr_name, name=None): - self.obj_name = obj_name - self.attr_name = attr_name - if name is None: - self.name = '%s_%s' % (obj_name, attr_name) - else: - self.name = name - self.param = frontend.create_param(attr_name) - - def __clone__(self, attr_name): - return self.__class__( - self.obj_name, - self.attr_name, - getattr(self, attr_name) - ) - - def get_attributes(cnt, format): - for name in ['other', 'user', 'another']: - for i in xrange(cnt): - yield DummyAttribute(name, format % i) - - cnt = 10 - formats = dict( - methods='method_%d', - properties='property_%d', - ) - - - _d = dict( - Method=plugable.NameSpace( - get_attributes(cnt, formats['methods']) - ), - Property=plugable.NameSpace( - get_attributes(cnt, formats['properties']) - ), - ) - api = plugable.MagicDict(_d) - assert len(api.Method) == cnt * 3 - assert len(api.Property) == cnt * 3 - - class user(self.cls): - pass - - # Actually perform test: - o = user() - o.set_api(api) - assert read_only(o, 'api') is api - for name in ['methods', 'properties']: - namespace = getattr(o, name) - assert isinstance(namespace, plugable.NameSpace) - assert len(namespace) == cnt - f = formats[name] - for i in xrange(cnt): - attr_name = f % i - attr = namespace[attr_name] - assert isinstance(attr, DummyAttribute) - assert attr is getattr(namespace, attr_name) - assert attr.obj_name == 'user' - assert attr.attr_name == attr_name - assert attr.name == '%s_%s' % ('user', attr_name) - - # Test params instance attribute - o = self.cls() - o.set_api(api) - ns = o.params - assert type(ns) is plugable.NameSpace - assert len(ns) == 0 - class example(self.cls): - takes_params = ('banana', 'apple') - o = example() - o.set_api(api) - ns = o.params - assert type(ns) is plugable.NameSpace - assert len(ns) == 2, repr(ns) - assert list(ns) == ['banana', 'apple'] - for p in ns(): - assert type(p) is parameters.Str - assert p.required is True - assert p.multivalue is False - - def test_primary_key(self): - """ - Test the `ipalib.frontend.Object.primary_key` attribute. - """ - (api, home) = create_test_api() - api.finalize() - - # Test with no primary keys: - class example1(self.cls): - takes_params = ( - 'one', - 'two', - ) - o = example1() - o.set_api(api) - assert o.primary_key is None - - # Test with 1 primary key: - class example2(self.cls): - takes_params = ( - 'one', - 'two', - parameters.Str('three', primary_key=True), - 'four', - ) - o = example2() - o.set_api(api) - pk = o.primary_key - assert type(pk) is parameters.Str - assert pk.name == 'three' - assert pk.primary_key is True - assert o.params[2] is o.primary_key - assert isinstance(o.params_minus_pk, plugable.NameSpace) - assert list(o.params_minus_pk) == ['one', 'two', 'four'] - - # Test with multiple primary_key: - class example3(self.cls): - takes_params = ( - parameters.Str('one', primary_key=True), - parameters.Str('two', primary_key=True), - 'three', - parameters.Str('four', primary_key=True), - ) - o = example3() - o.set_api(api) - e = raises(ValueError, o.finalize) - assert str(e) == \ - 'example3 (Object) has multiple primary keys: one, two, four' - - def test_backend(self): - """ - Test the `ipalib.frontend.Object.backend` attribute. - """ - (api, home) = create_test_api() - class ldap(backend.Backend): - whatever = 'It worked!' - api.register(ldap) - class user(frontend.Object): - backend_name = 'ldap' - api.register(user) - api.finalize() - b = api.Object.user.backend - assert isinstance(b, ldap) - assert b.whatever == 'It worked!' - - def test_get_dn(self): - """ - Test the `ipalib.frontend.Object.get_dn` method. - """ - o = self.cls() - e = raises(NotImplementedError, o.get_dn, 'primary key') - assert str(e) == 'Object.get_dn()' - class user(self.cls): - pass - o = user() - e = raises(NotImplementedError, o.get_dn, 'primary key') - assert str(e) == 'user.get_dn()' - - def test_params_minus(self): - """ - Test the `ipalib.frontend.Object.params_minus` method. - """ - class example(self.cls): - takes_params = ('one', 'two', 'three', 'four') - o = example() - (api, home) = create_test_api() - o.set_api(api) - p = o.params - assert tuple(o.params_minus()) == tuple(p()) - assert tuple(o.params_minus([])) == tuple(p()) - assert tuple(o.params_minus('two', 'three')) == (p.one, p.four) - assert tuple(o.params_minus(['two', 'three'])) == (p.one, p.four) - assert tuple(o.params_minus(p.two, p.three)) == (p.one, p.four) - assert tuple(o.params_minus([p.two, p.three])) == (p.one, p.four) - ns = NameSpace([p.two, p.three]) - assert tuple(o.params_minus(ns)) == (p.one, p.four) - - -class test_Attribute(ClassChecker): - """ - Test the `ipalib.frontend.Attribute` class. - """ - _cls = frontend.Attribute - - def test_class(self): - """ - Test the `ipalib.frontend.Attribute` class. - """ - assert self.cls.__bases__ == (plugable.Plugin,) - assert type(self.cls.obj) is property - assert type(self.cls.obj_name) is property - assert type(self.cls.attr_name) is property - - def test_init(self): - """ - Test the `ipalib.frontend.Attribute.__init__` method. - """ - class user_add(self.cls): - pass - o = user_add() - assert read_only(o, 'obj') is None - assert read_only(o, 'obj_name') == 'user' - assert read_only(o, 'attr_name') == 'add' - - def test_set_api(self): - """ - Test the `ipalib.frontend.Attribute.set_api` method. - """ - user_obj = 'The user frontend.Object instance' - class api(object): - Object = dict(user=user_obj) - class user_add(self.cls): - pass - o = user_add() - assert read_only(o, 'api') is None - assert read_only(o, 'obj') is None - o.set_api(api) - assert read_only(o, 'api') is api - assert read_only(o, 'obj') is user_obj - - -class test_Method(ClassChecker): - """ - Test the `ipalib.frontend.Method` class. - """ - _cls = frontend.Method - - def get_api(self, args=tuple(), options=tuple()): - """ - Return a finalized `ipalib.plugable.API` instance. - """ - (api, home) = create_test_api() - class user(frontend.Object): - takes_params = ( - 'givenname', - 'sn', - frontend.Param('uid', primary_key=True), - 'initials', - ) - class user_verb(self.cls): - takes_args = args - takes_options = options - api.register(user) - api.register(user_verb) - api.finalize() - return api - - def test_class(self): - """ - Test the `ipalib.frontend.Method` class. - """ - assert self.cls.__bases__ == (frontend.Attribute, frontend.Command) - - def test_init(self): - """ - Test the `ipalib.frontend.Method.__init__` method. - """ - class user_add(self.cls): - pass - o = user_add() - assert o.name == 'user_add' - assert o.obj_name == 'user' - assert o.attr_name == 'add' - - -class test_Property(ClassChecker): - """ - Test the `ipalib.frontend.Property` class. - """ - _cls = frontend.Property - - def get_subcls(self): - """ - Return a standard subclass of `ipalib.frontend.Property`. - """ - class user_givenname(self.cls): - 'User first name' - - @frontend.rule - def rule0_lowercase(self, value): - if not value.islower(): - return 'Must be lowercase' - return user_givenname - - def test_class(self): - """ - Test the `ipalib.frontend.Property` class. - """ - assert self.cls.__bases__ == (frontend.Attribute,) - assert self.cls.klass is parameters.Str - - def test_init(self): - """ - Test the `ipalib.frontend.Property.__init__` method. - """ - o = self.subcls() - assert len(o.rules) == 1 - assert o.rules[0].__name__ == 'rule0_lowercase' - param = o.param - assert isinstance(param, parameters.Str) - assert param.name == 'givenname' - assert unicode(param.doc) == u'User first name' diff --git a/tests/test_ipalib/test_messages.py b/tests/test_ipalib/test_messages.py deleted file mode 100644 index ebc400ee2..000000000 --- a/tests/test_ipalib/test_messages.py +++ /dev/null @@ -1,89 +0,0 @@ -# Authors: -# Petr Viktorin -# -# Copyright (C) 1012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.messages` module. -""" - -from ipalib import messages -from ipalib.capabilities import capabilities -from tests.test_ipalib import test_errors - - -class HelloMessage(messages.PublicMessage): - type = 'info' - format = '%(greeting)s, %(object)s!' - errno = 1234 - - -class test_PublicMessage(test_errors.test_PublicError): - """Test public messages""" - # The messages are a lot like public errors; defer testing to that. - klass = messages.PublicMessage - required_classes = (UserWarning, messages.PublicMessage) - - -class test_PublicMessages(test_errors.BaseMessagesTest): - message_list = messages.public_messages - errno_range = xrange(10000, 19999) - required_classes = (UserWarning, messages.PublicMessage) - texts = messages._texts - - def extratest(self, cls): - if cls is not messages.PublicMessage: - assert cls.type in ('debug', 'info', 'warning', 'error') - - -def test_to_dict(): - expected = dict( - name='HelloMessage', - type='info', - message='Hello, world!', - code=1234, - ) - - assert HelloMessage(greeting='Hello', object='world').to_dict() == expected - - -def test_add_message(): - result = {} - - assert capabilities['messages'] == u'2.52' - - messages.add_message(u'2.52', result, - HelloMessage(greeting='Hello', object='world')) - messages.add_message(u'2.1', result, - HelloMessage(greeting="'Lo", object='version')) - messages.add_message(u'2.60', result, - HelloMessage(greeting='Hi', object='version')) - - assert result == {'messages': [ - dict( - name='HelloMessage', - type='info', - message='Hello, world!', - code=1234, - ), - dict( - name='HelloMessage', - type='info', - message='Hi, version!', - code=1234, - ) - ]} diff --git a/tests/test_ipalib/test_output.py b/tests/test_ipalib/test_output.py deleted file mode 100644 index 741b83642..000000000 --- a/tests/test_ipalib/test_output.py +++ /dev/null @@ -1,89 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.output` module. -""" - -from tests.util import raises, ClassChecker -from ipalib import output -from ipalib.frontend import Command -from ipalib import _ - -class test_Output(ClassChecker): - """ - Test the `ipalib.output.Output` class. - """ - - _cls = output.Output - - def test_init(self): - """ - Test the `ipalib.output.Output.__init__` method. - """ - o = self.cls('result') - assert o.name == 'result' - assert o.type is None - assert o.doc is None - - def test_repr(self): - """ - Test the `ipalib.output.Output.__repr__` method. - """ - o = self.cls('aye') - assert repr(o) == "Output('aye', None, None)" - o = self.cls('aye', type=int, doc='An A, aye?') - assert repr(o) == "Output('aye', %r, 'An A, aye?')" % int - - class Entry(self.cls): - pass - o = Entry('aye') - assert repr(o) == "Entry('aye', None, None)" - o = Entry('aye', type=int, doc='An A, aye?') - assert repr(o) == "Entry('aye', %r, 'An A, aye?')" % int - - -class test_ListOfEntries(ClassChecker): - """ - Test the `ipalib.output.ListOfEntries` class. - """ - - _cls = output.ListOfEntries - - def test_validate(self): - """ - Test the `ipalib.output.ListOfEntries.validate` method. - """ - class example(Command): - pass - cmd = example() - inst = self.cls('stuff') - - okay = dict(foo='bar') - nope = ('aye', 'bee') - - e = raises(TypeError, inst.validate, cmd, [okay, okay, nope]) - assert str(e) == output.emsg % ( - 'example', 'ListOfEntries', 'stuff', 2, dict, tuple, nope - ) - - e = raises(TypeError, inst.validate, cmd, [nope, okay, nope]) - assert str(e) == output.emsg % ( - 'example', 'ListOfEntries', 'stuff', 0, dict, tuple, nope - ) diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py deleted file mode 100644 index 192db3da7..000000000 --- a/tests/test_ipalib/test_parameters.py +++ /dev/null @@ -1,1533 +0,0 @@ -# -*- coding: utf-8 -*- -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.parameters` module. -""" - -import re -import sys -from types import NoneType -from decimal import Decimal -from inspect import isclass -from tests.util import raises, ClassChecker, read_only -from tests.util import dummy_ugettext, assert_equal -from tests.data import binary_bytes, utf8_bytes, unicode_str -from ipalib import parameters, text, errors, config -from ipalib.constants import TYPE_ERROR, CALLABLE_ERROR, NULLS -from ipalib.errors import ValidationError, ConversionError -from ipalib import _ -from xmlrpclib import MAXINT, MININT - -class test_DefaultFrom(ClassChecker): - """ - Test the `ipalib.parameters.DefaultFrom` class. - """ - _cls = parameters.DefaultFrom - - def test_init(self): - """ - Test the `ipalib.parameters.DefaultFrom.__init__` method. - """ - def callback(*args): - return args - keys = ('givenname', 'sn') - o = self.cls(callback, *keys) - assert read_only(o, 'callback') is callback - assert read_only(o, 'keys') == keys - lam = lambda first, last: first[0] + last - o = self.cls(lam) - assert read_only(o, 'keys') == ('first', 'last') - - # Test that TypeError is raised when callback isn't callable: - e = raises(TypeError, self.cls, 'whatever') - assert str(e) == CALLABLE_ERROR % ('callback', 'whatever', str) - - # Test that TypeError is raised when a key isn't an str: - e = raises(TypeError, self.cls, callback, 'givenname', 17) - assert str(e) == TYPE_ERROR % ('keys', str, 17, int) - - # Test that ValueError is raised when inferring keys from a callback - # which has *args: - e = raises(ValueError, self.cls, lambda foo, *args: None) - assert str(e) == "callback: variable-length argument list not allowed" - - # Test that ValueError is raised when inferring keys from a callback - # which has **kwargs: - e = raises(ValueError, self.cls, lambda foo, **kwargs: None) - assert str(e) == "callback: variable-length argument list not allowed" - - def test_repr(self): - """ - Test the `ipalib.parameters.DefaultFrom.__repr__` method. - """ - def stuff(one, two): - pass - - o = self.cls(stuff) - assert repr(o) == "DefaultFrom(stuff, 'one', 'two')" - - o = self.cls(stuff, 'aye', 'bee', 'see') - assert repr(o) == "DefaultFrom(stuff, 'aye', 'bee', 'see')" - - cb = lambda first, last: first[0] + last - - o = self.cls(cb) - assert repr(o) == "DefaultFrom(, 'first', 'last')" - - o = self.cls(cb, 'aye', 'bee', 'see') - assert repr(o) == "DefaultFrom(, 'aye', 'bee', 'see')" - - def test_call(self): - """ - Test the `ipalib.parameters.DefaultFrom.__call__` method. - """ - def callback(givenname, sn): - return givenname[0] + sn[0] - keys = ('givenname', 'sn') - o = self.cls(callback, *keys) - kw = dict( - givenname='John', - sn='Public', - hello='world', - ) - assert o(**kw) == 'JP' - assert o() is None - for key in ('givenname', 'sn'): - kw_copy = dict(kw) - del kw_copy[key] - assert o(**kw_copy) is None - - # Test using implied keys: - o = self.cls(lambda first, last: first[0] + last) - assert o(first='john', last='doe') == 'jdoe' - assert o(first='', last='doe') is None - assert o(one='john', two='doe') is None - - # Test that co_varnames slice is used: - def callback2(first, last): - letter = first[0] - return letter + last - o = self.cls(callback2) - assert o.keys == ('first', 'last') - assert o(first='john', last='doe') == 'jdoe' - - -def test_parse_param_spec(): - """ - Test the `ipalib.parameters.parse_param_spec` function. - """ - f = parameters.parse_param_spec - assert f('name') == ('name', dict(required=True, multivalue=False)) - assert f('name?') == ('name', dict(required=False, multivalue=False)) - assert f('name*') == ('name', dict(required=False, multivalue=True)) - assert f('name+') == ('name', dict(required=True, multivalue=True)) - - # Make sure other "funny" endings are *not* treated special: - assert f('name^') == ('name^', dict(required=True, multivalue=False)) - - # Test that TypeError is raised if spec isn't an str: - e = raises(TypeError, f, u'name?') - assert str(e) == TYPE_ERROR % ('spec', str, u'name?', unicode) - - -class DummyRule(object): - def __init__(self, error=None): - assert error is None or type(error) is unicode - self.error = error - self.reset() - - def __call__(self, *args): - self.calls.append(args) - return self.error - - def reset(self): - self.calls = [] - - -class test_Param(ClassChecker): - """ - Test the `ipalib.parameters.Param` class. - """ - _cls = parameters.Param - - def test_init(self): - """ - Test the `ipalib.parameters.Param.__init__` method. - """ - name = 'my_param' - o = self.cls(name) - assert o.param_spec is name - assert o.name is name - assert o.nice == "Param('my_param')" - assert o.password is False - assert o.__islocked__() is True - - # Test default rules: - assert o.rules == tuple() - assert o.class_rules == tuple() - assert o.all_rules == tuple() - - # Test default kwarg values: - assert o.cli_name is name - assert o.label.msg == 'my_param' - assert o.doc.msg == 'my_param' - assert o.required is True - assert o.multivalue is False - assert o.primary_key is False - assert o.normalizer is None - assert o.default is None - assert o.default_from is None - assert o.autofill is False - assert o.query is False - assert o.attribute is False - assert o.include is None - assert o.exclude is None - assert o.flags == frozenset() - assert o.sortorder == 2 - assert o.csv is False - - # Test that doc defaults from label: - o = self.cls('my_param', doc=_('Hello world')) - assert o.label.msg == 'my_param' - assert o.doc.msg == 'Hello world' - - o = self.cls('my_param', label='My Param') - assert o.label == 'My Param' - assert o.doc == 'My Param' - - - # Test that ValueError is raised when a kwarg from a subclass - # conflicts with an attribute: - class Subclass(self.cls): - kwargs = self.cls.kwargs + ( - ('convert', callable, None), - ) - e = raises(ValueError, Subclass, name) - assert str(e) == "kwarg 'convert' conflicts with attribute on Subclass" - - # Test type validation of keyword arguments: - class Subclass(self.cls): - kwargs = self.cls.kwargs + ( - ('extra1', bool, True), - ('extra2', str, 'Hello'), - ('extra3', (int, float), 42), - ('extra4', callable, lambda whatever: whatever + 7), - ) - o = Subclass('my_param') # Test with no **kw: - for (key, kind, default) in o.kwargs: - # Test with a type invalid for all: - value = object() - kw = {key: value} - e = raises(TypeError, Subclass, 'my_param', **kw) - if kind is callable: - assert str(e) == CALLABLE_ERROR % (key, value, type(value)) - else: - assert str(e) == TYPE_ERROR % (key, kind, value, type(value)) - # Test with None: - kw = {key: None} - Subclass('my_param', **kw) - - # Test when using unknown kwargs: - e = raises(TypeError, self.cls, 'my_param', - flags=['hello', 'world'], - whatever=u'Hooray!', - ) - assert str(e) == \ - "Param('my_param'): takes no such kwargs: 'whatever'" - e = raises(TypeError, self.cls, 'my_param', great='Yes', ape='he is!') - assert str(e) == \ - "Param('my_param'): takes no such kwargs: 'ape', 'great'" - - # Test that ValueError is raised if you provide both include and - # exclude: - e = raises(ValueError, self.cls, 'my_param', - include=['server', 'foo'], - exclude=['client', 'bar'], - ) - assert str(e) == '%s: cannot have both %s=%r and %s=%r' % ( - "Param('my_param')", - 'include', frozenset(['server', 'foo']), - 'exclude', frozenset(['client', 'bar']), - ) - - # Test that ValueError is raised if csv is set and multivalue is not set: - e = raises(ValueError, self.cls, 'my_param', csv=True) - assert str(e) == '%s: cannot have csv without multivalue' % "Param('my_param')" - - # Test that default_from gets set: - call = lambda first, last: first[0] + last - o = self.cls('my_param', default_from=call) - assert type(o.default_from) is parameters.DefaultFrom - assert o.default_from.callback is call - - def test_repr(self): - """ - Test the `ipalib.parameters.Param.__repr__` method. - """ - for name in ['name', 'name?', 'name*', 'name+']: - o = self.cls(name) - assert repr(o) == 'Param(%r)' % name - o = self.cls('name', required=False) - assert repr(o) == "Param('name', required=False)" - o = self.cls('name', multivalue=True) - assert repr(o) == "Param('name', multivalue=True)" - - def test_use_in_context(self): - """ - Test the `ipalib.parameters.Param.use_in_context` method. - """ - set1 = ('one', 'two', 'three') - set2 = ('four', 'five', 'six') - param1 = self.cls('param1') - param2 = self.cls('param2', include=set1) - param3 = self.cls('param3', exclude=set2) - for context in set1: - env = config.Env() - env.context = context - assert param1.use_in_context(env) is True, context - assert param2.use_in_context(env) is True, context - assert param3.use_in_context(env) is True, context - for context in set2: - env = config.Env() - env.context = context - assert param1.use_in_context(env) is True, context - assert param2.use_in_context(env) is False, context - assert param3.use_in_context(env) is False, context - - def test_safe_value(self): - """ - Test the `ipalib.parameters.Param.safe_value` method. - """ - values = (unicode_str, binary_bytes, utf8_bytes) - o = self.cls('my_param') - for value in values: - assert o.safe_value(value) is value - assert o.safe_value(None) is None - p = parameters.Password('my_passwd') - for value in values: - assert_equal(p.safe_value(value), u'********') - assert p.safe_value(None) is None - - def test_clone(self): - """ - Test the `ipalib.parameters.Param.clone` method. - """ - # Test with the defaults - orig = self.cls('my_param') - clone = orig.clone() - assert clone is not orig - assert type(clone) is self.cls - assert clone.name is orig.name - for (key, kind, default) in self.cls.kwargs: - assert getattr(clone, key) is getattr(orig, key) - - # Test with a param spec: - orig = self.cls('my_param*') - assert orig.param_spec == 'my_param*' - clone = orig.clone() - assert clone.param_spec == 'my_param' - assert clone is not orig - assert type(clone) is self.cls - for (key, kind, default) in self.cls.kwargs: - assert getattr(clone, key) is getattr(orig, key) - - # Test with overrides: - orig = self.cls('my_param*') - assert orig.required is False - assert orig.multivalue is True - clone = orig.clone(required=True) - assert clone is not orig - assert type(clone) is self.cls - assert clone.required is True - assert clone.multivalue is True - assert clone.param_spec == 'my_param' - assert clone.name == 'my_param' - - def test_clone_rename(self): - """ - Test the `ipalib.parameters.Param.clone` method. - """ - new_name = 'my_new_param' - - # Test with the defaults - orig = self.cls('my_param') - clone = orig.clone_rename(new_name) - assert clone is not orig - assert type(clone) is self.cls - assert clone.name == new_name - for (key, kind, default) in self.cls.kwargs: - assert getattr(clone, key) is getattr(orig, key) - - # Test with overrides: - orig = self.cls('my_param*') - assert orig.required is False - assert orig.multivalue is True - clone = orig.clone_rename(new_name, required=True) - assert clone is not orig - assert type(clone) is self.cls - assert clone.required is True - assert clone.multivalue is True - assert clone.param_spec == new_name - assert clone.name == new_name - - - def test_convert(self): - """ - Test the `ipalib.parameters.Param.convert` method. - """ - okay = ('Hello', u'Hello', 0, 4.2, True, False, unicode_str) - class Subclass(self.cls): - def _convert_scalar(self, value, index=None): - return value - - # Test when multivalue=False: - o = Subclass('my_param') - for value in NULLS: - assert o.convert(value) is None - assert o.convert(None) is None - for value in okay: - assert o.convert(value) is value - - # Test when multivalue=True: - o = Subclass('my_param', multivalue=True) - for value in NULLS: - assert o.convert(value) is None - assert o.convert(okay) == okay - assert o.convert(NULLS) is None - assert o.convert(okay + NULLS) == okay - assert o.convert(NULLS + okay) == okay - for value in okay: - assert o.convert(value) == (value,) - assert o.convert([None, value]) == (value,) - assert o.convert([value, None]) == (value,) - - def test_convert_scalar(self): - """ - Test the `ipalib.parameters.Param._convert_scalar` method. - """ - dummy = dummy_ugettext() - - # Test with correct type: - o = self.cls('my_param') - assert o._convert_scalar(None) is None - assert dummy.called() is False - # Test with incorrect type - e = raises(errors.ConversionError, o._convert_scalar, 'hello', index=17) - - def test_validate(self): - """ - Test the `ipalib.parameters.Param.validate` method. - """ - - # Test in default state (with no rules, no kwarg): - o = self.cls('my_param') - e = raises(errors.RequirementError, o.validate, None, 'cli') - assert e.name == 'my_param' - - # Test in default state that cli_name gets returned in the exception - # when context == 'cli' - o = self.cls('my_param', cli_name='short') - e = raises(errors.RequirementError, o.validate, None, 'cli') - assert e.name == 'short' - - # Test with required=False - o = self.cls('my_param', required=False) - assert o.required is False - assert o.validate(None, 'cli') is None - - # Test with query=True: - o = self.cls('my_param', query=True) - assert o.query is True - e = raises(errors.RequirementError, o.validate, None, 'cli') - assert_equal(e.name, 'my_param') - - # Test with multivalue=True: - o = self.cls('my_param', multivalue=True) - e = raises(TypeError, o.validate, [], 'cli') - assert str(e) == TYPE_ERROR % ('value', tuple, [], list) - e = raises(ValueError, o.validate, tuple(), 'cli') - assert str(e) == 'value: empty tuple must be converted to None' - - # Test with wrong (scalar) type: - e = raises(TypeError, o.validate, (None, None, 42, None), 'cli') - assert str(e) == TYPE_ERROR % ('my_param', NoneType, 42, int) - o = self.cls('my_param') - e = raises(TypeError, o.validate, 'Hello', 'cli') - assert str(e) == TYPE_ERROR % ('my_param', NoneType, 'Hello', str) - - class Example(self.cls): - type = int - - # Test with some rules and multivalue=False - pass1 = DummyRule() - pass2 = DummyRule() - fail = DummyRule(u'no good') - o = Example('example', pass1, pass2) - assert o.multivalue is False - assert o.validate(11, 'cli') is None - assert pass1.calls == [(text.ugettext, 11)] - assert pass2.calls == [(text.ugettext, 11)] - pass1.reset() - pass2.reset() - o = Example('example', pass1, pass2, fail) - e = raises(errors.ValidationError, o.validate, 42, 'cli') - assert e.name == 'example' - assert e.error == u'no good' - assert e.index is None - assert pass1.calls == [(text.ugettext, 42)] - assert pass2.calls == [(text.ugettext, 42)] - assert fail.calls == [(text.ugettext, 42)] - - # Test with some rules and multivalue=True - pass1 = DummyRule() - pass2 = DummyRule() - fail = DummyRule(u'this one is not good') - o = Example('example', pass1, pass2, multivalue=True) - assert o.multivalue is True - assert o.validate((3, 9), 'cli') is None - assert pass1.calls == [ - (text.ugettext, 3), - (text.ugettext, 9), - ] - assert pass2.calls == [ - (text.ugettext, 3), - (text.ugettext, 9), - ] - pass1.reset() - pass2.reset() - o = Example('multi_example', pass1, pass2, fail, multivalue=True) - assert o.multivalue is True - e = raises(errors.ValidationError, o.validate, (3, 9), 'cli') - assert e.name == 'multi_example' - assert e.error == u'this one is not good' - assert e.index == 0 - assert pass1.calls == [(text.ugettext, 3)] - assert pass2.calls == [(text.ugettext, 3)] - assert fail.calls == [(text.ugettext, 3)] - - def test_validate_scalar(self): - """ - Test the `ipalib.parameters.Param._validate_scalar` method. - """ - class MyParam(self.cls): - type = bool - okay = DummyRule() - o = MyParam('my_param', okay) - - # Test that TypeError is appropriately raised: - e = raises(TypeError, o._validate_scalar, 0) - assert str(e) == TYPE_ERROR % ('my_param', bool, 0, int) - e = raises(TypeError, o._validate_scalar, 'Hi', index=4) - assert str(e) == TYPE_ERROR % ('my_param', bool, 'Hi', str) - e = raises(TypeError, o._validate_scalar, True, index=3.0) - assert str(e) == TYPE_ERROR % ('index', int, 3.0, float) - - # Test with passing rule: - assert o._validate_scalar(True, index=None) is None - assert o._validate_scalar(False, index=None) is None - assert okay.calls == [ - (text.ugettext, True), - (text.ugettext, False), - ] - - # Test with a failing rule: - okay = DummyRule() - fail = DummyRule(u'this describes the error') - o = MyParam('my_param', okay, fail) - e = raises(errors.ValidationError, o._validate_scalar, True) - assert e.name == 'my_param' - assert e.error == u'this describes the error' - assert e.index is None - e = raises(errors.ValidationError, o._validate_scalar, False, index=2) - assert e.name == 'my_param' - assert e.error == u'this describes the error' - assert e.index == 2 - assert okay.calls == [ - (text.ugettext, True), - (text.ugettext, False), - ] - assert fail.calls == [ - (text.ugettext, True), - (text.ugettext, False), - ] - - def test_get_default(self): - """ - Test the `ipalib.parameters.Param.get_default` method. - """ - class PassThrough(object): - value = None - - def __call__(self, value): - assert self.value is None - assert value is not None - self.value = value - return value - - def reset(self): - assert self.value is not None - self.value = None - - class Str(self.cls): - type = unicode - - def __init__(self, name, **kw): - self._convert_scalar = PassThrough() - super(Str, self).__init__(name, **kw) - - # Test with only a static default: - o = Str('my_str', - normalizer=PassThrough(), - default=u'Static Default', - ) - assert_equal(o.get_default(), u'Static Default') - assert o._convert_scalar.value is None - assert o.normalizer.value is None - - # Test with default_from: - o = Str('my_str', - normalizer=PassThrough(), - default=u'Static Default', - default_from=lambda first, last: first[0] + last, - ) - assert_equal(o.get_default(), u'Static Default') - assert o._convert_scalar.value is None - assert o.normalizer.value is None - default = o.get_default(first=u'john', last='doe') - assert_equal(default, u'jdoe') - assert o._convert_scalar.value is default - assert o.normalizer.value is default - - -class test_Flag(ClassChecker): - """ - Test the `ipalib.parameters.Flag` class. - """ - _cls = parameters.Flag - - def test_init(self): - """ - Test the `ipalib.parameters.Flag.__init__` method. - """ - # Test with no kwargs: - o = self.cls('my_flag') - assert o.type is bool - assert isinstance(o, parameters.Bool) - assert o.autofill is True - assert o.default is False - - # Test that TypeError is raise if default is not a bool: - e = raises(TypeError, self.cls, 'my_flag', default=None) - assert str(e) == TYPE_ERROR % ('default', bool, None, NoneType) - - # Test with autofill=False, default=True - o = self.cls('my_flag', autofill=False, default=True) - assert o.autofill is True - assert o.default is True - - # Test when cloning: - orig = self.cls('my_flag') - for clone in [orig.clone(), orig.clone(autofill=False)]: - assert clone.autofill is True - assert clone.default is False - assert clone is not orig - assert type(clone) is self.cls - - # Test when cloning with default=True/False - orig = self.cls('my_flag') - assert orig.clone().default is False - assert orig.clone(default=True).default is True - orig = self.cls('my_flag', default=True) - assert orig.clone().default is True - assert orig.clone(default=False).default is False - - -class test_Data(ClassChecker): - """ - Test the `ipalib.parameters.Data` class. - """ - _cls = parameters.Data - - def test_init(self): - """ - Test the `ipalib.parameters.Data.__init__` method. - """ - o = self.cls('my_data') - assert o.type is NoneType - assert o.password is False - assert o.rules == tuple() - assert o.class_rules == tuple() - assert o.all_rules == tuple() - assert o.minlength is None - assert o.maxlength is None - assert o.length is None - assert o.pattern is None - - # Test mixing length with minlength or maxlength: - o = self.cls('my_data', length=5) - assert o.length == 5 - permutations = [ - dict(minlength=3), - dict(maxlength=7), - dict(minlength=3, maxlength=7), - ] - for kw in permutations: - o = self.cls('my_data', **kw) - for (key, value) in kw.iteritems(): - assert getattr(o, key) == value - e = raises(ValueError, self.cls, 'my_data', length=5, **kw) - assert str(e) == \ - "Data('my_data'): cannot mix length with minlength or maxlength" - - # Test when minlength or maxlength are less than 1: - e = raises(ValueError, self.cls, 'my_data', minlength=0) - assert str(e) == "Data('my_data'): minlength must be >= 1; got 0" - e = raises(ValueError, self.cls, 'my_data', maxlength=0) - assert str(e) == "Data('my_data'): maxlength must be >= 1; got 0" - - # Test when minlength > maxlength: - e = raises(ValueError, self.cls, 'my_data', minlength=22, maxlength=15) - assert str(e) == \ - "Data('my_data'): minlength > maxlength (minlength=22, maxlength=15)" - - # Test when minlength == maxlength - e = raises(ValueError, self.cls, 'my_data', minlength=7, maxlength=7) - assert str(e) == \ - "Data('my_data'): minlength == maxlength; use length=7 instead" - - -class test_Bytes(ClassChecker): - """ - Test the `ipalib.parameters.Bytes` class. - """ - _cls = parameters.Bytes - - def test_init(self): - """ - Test the `ipalib.parameters.Bytes.__init__` method. - """ - o = self.cls('my_bytes') - assert o.type is str - assert o.password is False - assert o.rules == tuple() - assert o.class_rules == tuple() - assert o.all_rules == tuple() - assert o.minlength is None - assert o.maxlength is None - assert o.length is None - assert o.pattern is None - assert o.re is None - - # Test mixing length with minlength or maxlength: - o = self.cls('my_bytes', length=5) - assert o.length == 5 - assert len(o.class_rules) == 1 - assert len(o.rules) == 0 - assert len(o.all_rules) == 1 - permutations = [ - dict(minlength=3), - dict(maxlength=7), - dict(minlength=3, maxlength=7), - ] - for kw in permutations: - o = self.cls('my_bytes', **kw) - assert len(o.class_rules) == len(kw) - assert len(o.rules) == 0 - assert len(o.all_rules) == len(kw) - for (key, value) in kw.iteritems(): - assert getattr(o, key) == value - e = raises(ValueError, self.cls, 'my_bytes', length=5, **kw) - assert str(e) == \ - "Bytes('my_bytes'): cannot mix length with minlength or maxlength" - - # Test when minlength or maxlength are less than 1: - e = raises(ValueError, self.cls, 'my_bytes', minlength=0) - assert str(e) == "Bytes('my_bytes'): minlength must be >= 1; got 0" - e = raises(ValueError, self.cls, 'my_bytes', maxlength=0) - assert str(e) == "Bytes('my_bytes'): maxlength must be >= 1; got 0" - - # Test when minlength > maxlength: - e = raises(ValueError, self.cls, 'my_bytes', minlength=22, maxlength=15) - assert str(e) == \ - "Bytes('my_bytes'): minlength > maxlength (minlength=22, maxlength=15)" - - # Test when minlength == maxlength - e = raises(ValueError, self.cls, 'my_bytes', minlength=7, maxlength=7) - assert str(e) == \ - "Bytes('my_bytes'): minlength == maxlength; use length=7 instead" - - def test_rule_minlength(self): - """ - Test the `ipalib.parameters.Bytes._rule_minlength` method. - """ - o = self.cls('my_bytes', minlength=3) - assert o.minlength == 3 - rule = o._rule_minlength - translation = u'minlength=%(minlength)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in ('abc', 'four', '12345'): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in ('', 'a', '12'): - assert_equal( - rule(dummy, value), - translation % dict(minlength=3) - ) - assert dummy.message == 'must be at least %(minlength)d bytes' - assert dummy.called() is True - dummy.reset() - - def test_rule_maxlength(self): - """ - Test the `ipalib.parameters.Bytes._rule_maxlength` method. - """ - o = self.cls('my_bytes', maxlength=4) - assert o.maxlength == 4 - rule = o._rule_maxlength - translation = u'maxlength=%(maxlength)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in ('ab', '123', 'four'): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in ('12345', 'sixsix'): - assert_equal( - rule(dummy, value), - translation % dict(maxlength=4) - ) - assert dummy.message == 'can be at most %(maxlength)d bytes' - assert dummy.called() is True - dummy.reset() - - def test_rule_length(self): - """ - Test the `ipalib.parameters.Bytes._rule_length` method. - """ - o = self.cls('my_bytes', length=4) - assert o.length == 4 - rule = o._rule_length - translation = u'length=%(length)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in ('1234', 'four'): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in ('ab', '123', '12345', 'sixsix'): - assert_equal( - rule(dummy, value), - translation % dict(length=4), - ) - assert dummy.message == 'must be exactly %(length)d bytes' - assert dummy.called() is True - dummy.reset() - - def test_rule_pattern(self): - """ - Test the `ipalib.parameters.Bytes._rule_pattern` method. - """ - # Test our assumptions about Python re module and Unicode: - pat = '\w+$' - r = re.compile(pat) - assert r.match('Hello_World') is not None - assert r.match(utf8_bytes) is None - assert r.match(binary_bytes) is None - - # Create instance: - o = self.cls('my_bytes', pattern=pat) - assert o.pattern is pat - rule = o._rule_pattern - translation = u'pattern=%(pattern)r' - dummy = dummy_ugettext(translation) - - # Test with passing values: - for value in ('HELLO', 'hello', 'Hello_World'): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in ('Hello!', 'Hello World', utf8_bytes, binary_bytes): - assert_equal( - rule(dummy, value), - translation % dict(pattern=pat), - ) - assert_equal(dummy.message, 'must match pattern "%(pattern)s"') - assert dummy.called() is True - dummy.reset() - - -class test_Str(ClassChecker): - """ - Test the `ipalib.parameters.Str` class. - """ - _cls = parameters.Str - - def test_init(self): - """ - Test the `ipalib.parameters.Str.__init__` method. - """ - o = self.cls('my_str') - assert o.type is unicode - assert o.password is False - assert o.minlength is None - assert o.maxlength is None - assert o.length is None - assert o.pattern is None - - def test_convert_scalar(self): - """ - Test the `ipalib.parameters.Str._convert_scalar` method. - """ - o = self.cls('my_str') - mthd = o._convert_scalar - for value in (u'Hello', 42, 1.2, unicode_str): - assert mthd(value) == unicode(value) - bad = [True, 'Hello', dict(one=1), utf8_bytes] - for value in bad: - e = raises(errors.ConversionError, mthd, value) - assert e.name == 'my_str' - assert e.index is None - assert_equal(unicode(e.error), u'must be Unicode text') - e = raises(errors.ConversionError, mthd, value, index=18) - assert e.name == 'my_str' - assert e.index == 18 - assert_equal(unicode(e.error), u'must be Unicode text') - bad = [(u'Hello',), [42.3]] - for value in bad: - e = raises(errors.ConversionError, mthd, value) - assert e.name == 'my_str' - assert e.index is None - assert_equal(unicode(e.error), u'Only one value is allowed') - assert o.convert(None) is None - - def test_rule_minlength(self): - """ - Test the `ipalib.parameters.Str._rule_minlength` method. - """ - o = self.cls('my_str', minlength=3) - assert o.minlength == 3 - rule = o._rule_minlength - translation = u'minlength=%(minlength)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in (u'abc', u'four', u'12345'): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (u'', u'a', u'12'): - assert_equal( - rule(dummy, value), - translation % dict(minlength=3) - ) - assert dummy.message == 'must be at least %(minlength)d characters' - assert dummy.called() is True - dummy.reset() - - def test_rule_maxlength(self): - """ - Test the `ipalib.parameters.Str._rule_maxlength` method. - """ - o = self.cls('my_str', maxlength=4) - assert o.maxlength == 4 - rule = o._rule_maxlength - translation = u'maxlength=%(maxlength)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in (u'ab', u'123', u'four'): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (u'12345', u'sixsix'): - assert_equal( - rule(dummy, value), - translation % dict(maxlength=4) - ) - assert dummy.message == 'can be at most %(maxlength)d characters' - assert dummy.called() is True - dummy.reset() - - def test_rule_length(self): - """ - Test the `ipalib.parameters.Str._rule_length` method. - """ - o = self.cls('my_str', length=4) - assert o.length == 4 - rule = o._rule_length - translation = u'length=%(length)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in (u'1234', u'four'): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (u'ab', u'123', u'12345', u'sixsix'): - assert_equal( - rule(dummy, value), - translation % dict(length=4), - ) - assert dummy.message == 'must be exactly %(length)d characters' - assert dummy.called() is True - dummy.reset() - - def test_rule_pattern(self): - """ - Test the `ipalib.parameters.Str._rule_pattern` method. - """ - # Test our assumptions about Python re module and Unicode: - pat = '\w{5}$' - r1 = re.compile(pat) - r2 = re.compile(pat, re.UNICODE) - assert r1.match(unicode_str) is None - assert r2.match(unicode_str) is not None - - # Create instance: - o = self.cls('my_str', pattern=pat) - assert o.pattern is pat - rule = o._rule_pattern - translation = u'pattern=%(pattern)r' - dummy = dummy_ugettext(translation) - - # Test with passing values: - for value in (u'HELLO', u'hello', unicode_str): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (u'H LLO', u'***lo', unicode_str + unicode_str): - assert_equal( - rule(dummy, value), - translation % dict(pattern=pat), - ) - assert_equal(dummy.message, 'must match pattern "%(pattern)s"') - assert dummy.called() is True - dummy.reset() - - -class test_Password(ClassChecker): - """ - Test the `ipalib.parameters.Password` class. - """ - _cls = parameters.Password - - def test_init(self): - """ - Test the `ipalib.parameters.Password.__init__` method. - """ - o = self.cls('my_password') - assert o.type is unicode - assert o.minlength is None - assert o.maxlength is None - assert o.length is None - assert o.pattern is None - assert o.password is True - - def test_convert_scalar(self): - """ - Test the `ipalib.parameters.Password._convert_scalar` method. - """ - o = self.cls('my_password') - e = raises(errors.PasswordMismatch, o._convert_scalar, [u'one', u'two']) - assert e.name == 'my_password' - assert e.index is None - assert o._convert_scalar([u'one', u'one']) == u'one' - assert o._convert_scalar(u'one') == u'one' - - -class test_StrEnum(ClassChecker): - """ - Test the `ipalib.parameters.StrEnum` class. - """ - _cls = parameters.StrEnum - - def test_init(self): - """ - Test the `ipalib.parameters.StrEnum.__init__` method. - """ - values = (u'Hello', u'naughty', u'nurse!') - o = self.cls('my_strenum', values=values) - assert o.type is unicode - assert o.values is values - assert o.class_rules == (o._rule_values,) - assert o.rules == tuple() - assert o.all_rules == (o._rule_values,) - - badvalues = (u'Hello', 'naughty', u'nurse!') - e = raises(TypeError, self.cls, 'my_enum', values=badvalues) - assert str(e) == TYPE_ERROR % ( - "StrEnum('my_enum') values[1]", unicode, 'naughty', str - ) - - # Test that ValueError is raised when list of values is empty - badvalues = tuple() - e = raises(ValueError, self.cls, 'empty_enum', values=badvalues) - assert_equal(str(e), "StrEnum('empty_enum'): list of values must not " - "be empty") - - def test_rules_values(self): - """ - Test the `ipalib.parameters.StrEnum._rule_values` method. - """ - values = (u'Hello', u'naughty', u'nurse!') - o = self.cls('my_enum', values=values) - rule = o._rule_values - translation = u"values='Hello', 'naughty', 'nurse!'" - dummy = dummy_ugettext(translation) - - # Test with passing values: - for v in values: - assert rule(dummy, v) is None - assert dummy.called() is False - - # Test with failing values: - for val in (u'Howdy', u'quiet', u'library!'): - assert_equal( - rule(dummy, val), - translation % dict(values=values), - ) - assert_equal(dummy.message, "must be one of %(values)s") - dummy.reset() - - # test a special case when we have just one allowed value - values = (u'Hello', ) - o = self.cls('my_enum', values=values) - rule = o._rule_values - translation = u"value='Hello'" - dummy = dummy_ugettext(translation) - - for val in (u'Howdy', u'quiet', u'library!'): - assert_equal( - rule(dummy, val), - translation % dict(values=values), - ) - assert_equal(dummy.message, "must be '%(value)s'") - dummy.reset() - - -class test_Number(ClassChecker): - """ - Test the `ipalib.parameters.Number` class. - """ - _cls = parameters.Number - - def test_init(self): - """ - Test the `ipalib.parameters.Number.__init__` method. - """ - o = self.cls('my_number') - assert o.type is NoneType - assert o.password is False - assert o.rules == tuple() - assert o.class_rules == tuple() - assert o.all_rules == tuple() - - - -class test_Int(ClassChecker): - """ - Test the `ipalib.parameters.Int` class. - """ - _cls = parameters.Int - - def test_init(self): - """ - Test the `ipalib.parameters.Int.__init__` method. - """ - # Test with no kwargs: - o = self.cls('my_number') - assert o.type is int - assert isinstance(o, parameters.Int) - assert o.minvalue == int(MININT) - assert o.maxvalue == int(MAXINT) - - # Test when min > max: - e = raises(ValueError, self.cls, 'my_number', minvalue=22, maxvalue=15) - assert str(e) == \ - "Int('my_number'): minvalue > maxvalue (minvalue=22, maxvalue=15)" - - def test_rule_minvalue(self): - """ - Test the `ipalib.parameters.Int._rule_minvalue` method. - """ - o = self.cls('my_number', minvalue=3) - assert o.minvalue == 3 - rule = o._rule_minvalue - translation = u'minvalue=%(minvalue)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in (4, 99, 1001): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (-1, 0, 2): - assert_equal( - rule(dummy, value), - translation % dict(minvalue=3) - ) - assert dummy.message == 'must be at least %(minvalue)d' - assert dummy.called() is True - dummy.reset() - - def test_rule_maxvalue(self): - """ - Test the `ipalib.parameters.Int._rule_maxvalue` method. - """ - o = self.cls('my_number', maxvalue=4) - assert o.maxvalue == 4 - rule = o._rule_maxvalue - translation = u'maxvalue=%(maxvalue)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in (-1, 0, 4): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (5, 99, 1009): - assert_equal( - rule(dummy, value), - translation % dict(maxvalue=4) - ) - assert dummy.message == 'can be at most %(maxvalue)d' - assert dummy.called() is True - dummy.reset() - - def test_convert_scalar(self): - """ - Test the `ipalib.parameters.Int._convert_scalar` method. - Assure radix prefixes work, str objects fail, - floats (native & string) are truncated, - large magnitude values are promoted to long, - empty strings & invalid numerical representations fail - """ - o = self.cls('my_number') - # Assure invalid inputs raise error - for bad in ['hello', u'hello', True, None, u'', u'.']: - e = raises(errors.ConversionError, o._convert_scalar, bad) - assert e.name == 'my_number' - assert e.index is None - # Assure large magnatude values are handled correctly - assert type(o._convert_scalar(sys.maxint*2)) == long - assert o._convert_scalar(sys.maxint*2) == sys.maxint*2 - assert o._convert_scalar(unicode(sys.maxint*2)) == sys.maxint*2 - assert o._convert_scalar(long(16)) == 16 - # Assure normal conversions produce expected result - assert o._convert_scalar(u'16.99') == 16 - assert o._convert_scalar(16.99) == 16 - assert o._convert_scalar(u'16') == 16 - assert o._convert_scalar(u'0x10') == 16 - assert o._convert_scalar(u'020') == 16 - -class test_Decimal(ClassChecker): - """ - Test the `ipalib.parameters.Decimal` class. - """ - _cls = parameters.Decimal - - def test_init(self): - """ - Test the `ipalib.parameters.Decimal.__init__` method. - """ - # Test with no kwargs: - o = self.cls('my_number') - assert o.type is Decimal - assert isinstance(o, parameters.Decimal) - assert o.minvalue is None - assert o.maxvalue is None - - # Test when min > max: - e = raises(ValueError, self.cls, 'my_number', minvalue=Decimal('22.5'), maxvalue=Decimal('15.1')) - assert str(e) == \ - "Decimal('my_number'): minvalue > maxvalue (minvalue=22.5, maxvalue=15.1)" - - def test_rule_minvalue(self): - """ - Test the `ipalib.parameters.Decimal._rule_minvalue` method. - """ - o = self.cls('my_number', minvalue='3.1') - assert o.minvalue == Decimal('3.1') - rule = o._rule_minvalue - translation = u'minvalue=%(minvalue)s' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in (Decimal('3.2'), Decimal('99.0')): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (Decimal('-1.2'), Decimal('0.0'), Decimal('3.0')): - assert_equal( - rule(dummy, value), - translation % dict(minvalue=Decimal('3.1')) - ) - assert dummy.message == 'must be at least %(minvalue)s' - assert dummy.called() is True - dummy.reset() - - def test_rule_maxvalue(self): - """ - Test the `ipalib.parameters.Decimal._rule_maxvalue` method. - """ - o = self.cls('my_number', maxvalue='4.7') - assert o.maxvalue == Decimal('4.7') - rule = o._rule_maxvalue - translation = u'maxvalue=%(maxvalue)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - - # Test with passing values: - for value in (Decimal('-1.0'), Decimal('0.1'), Decimal('4.2')): - assert rule(dummy, value) is None - assert dummy.called() is False - - # Test with failing values: - for value in (Decimal('5.3'), Decimal('99.9')): - assert_equal( - rule(dummy, value), - translation % dict(maxvalue=Decimal('4.7')) - ) - assert dummy.message == 'can be at most %(maxvalue)s' - assert dummy.called() is True - dummy.reset() - - def test_precision(self): - """ - Test the `ipalib.parameters.Decimal` precision attribute - """ - # precission is None - param = self.cls('my_number') - - for value in (Decimal('0'), Decimal('4.4'), Decimal('4.67')): - assert_equal( - param(value), - value) - - # precision is 0 - param = self.cls('my_number', precision=0) - for original,expected in ((Decimal('0'), '0'), - (Decimal('1.1'), '1'), - (Decimal('4.67'), '5')): - assert_equal( - str(param(original)), - expected) - - # precision is 1 - param = self.cls('my_number', precision=1) - for original,expected in ((Decimal('0'), '0.0'), - (Decimal('1.1'), '1.1'), - (Decimal('4.67'), '4.7')): - assert_equal( - str(param(original)), - expected) - - # value has too many digits - param = self.cls('my_number', precision=1) - e = raises(ConversionError, param, '123456789012345678901234567890') - - assert str(e) == \ - "invalid 'my_number': quantize result has too many digits for current context" - - def test_exponential(self): - """ - Test the `ipalib.parameters.Decimal` exponential attribute - """ - param = self.cls('my_number', exponential=True) - for original,expected in ((Decimal('0'), '0'), - (Decimal('1E3'), '1E+3'), - (Decimal('3.4E2'), '3.4E+2')): - assert_equal( - str(param(original)), - expected) - - - param = self.cls('my_number', exponential=False) - for original,expected in ((Decimal('0'), '0'), - (Decimal('1E3'), '1000'), - (Decimal('3.4E2'), '340')): - assert_equal( - str(param(original)), - expected) - - def test_numberclass(self): - """ - Test the `ipalib.parameters.Decimal` numberclass attribute - """ - # test default value: '-Normal', '+Zero', '+Normal' - param = self.cls('my_number') - for value,raises_verror in ((Decimal('0'), False), - (Decimal('-0'), True), - (Decimal('1E8'), False), - (Decimal('-1.1'), False), - (Decimal('-Infinity'), True), - (Decimal('+Infinity'), True), - (Decimal('NaN'), True)): - if raises_verror: - raises(ValidationError, param, value) - else: - param(value) - - - param = self.cls('my_number', exponential=True, - numberclass=('-Normal', '+Zero', '+Infinity')) - for value,raises_verror in ((Decimal('0'), False), - (Decimal('-0'), True), - (Decimal('1E8'), True), - (Decimal('-1.1'), False), - (Decimal('-Infinity'), True), - (Decimal('+Infinity'), False), - (Decimal('NaN'), True)): - if raises_verror: - raises(ValidationError, param, value) - else: - param(value) - -class test_AccessTime(ClassChecker): - """ - Test the `ipalib.parameters.AccessTime` class. - """ - _cls = parameters.AccessTime - - def test_init(self): - """ - Test the `ipalib.parameters.AccessTime.__init__` method. - """ - # Test with no kwargs: - o = self.cls('my_time') - assert o.type is unicode - assert isinstance(o, parameters.AccessTime) - assert o.multivalue is False - translation = u'length=%(length)r' - dummy = dummy_ugettext(translation) - assert dummy.translation is translation - rule = o._rule_required - - # Check some good rules - for value in (u'absolute 201012161032 ~ 201012161033', - u'periodic monthly week 2 day Sat,Sun 0900-1300', - u'periodic yearly month 4 day 1-31 0800-1400', - u'periodic weekly day 7 0800-1400', - u'periodic daily 0800-1400', - ): - assert rule(dummy, value) is None - assert dummy.called() is False - - # And some bad ones - for value in (u'absolute 201012161032 - 201012161033', - u'absolute 201012161032 ~', - u'periodic monthly day Sat,Sun 0900-1300', - u'periodical yearly month 4 day 1-31 0800-1400', - u'periodic weekly day 8 0800-1400', - ): - e = raises(ValidationError, o._rule_required, None, value) - -def test_create_param(): - """ - Test the `ipalib.parameters.create_param` function. - """ - f = parameters.create_param - - # Test that Param instances are returned unchanged: - params = ( - parameters.Param('one?'), - parameters.Int('two+'), - parameters.Str('three*'), - parameters.Bytes('four'), - ) - for p in params: - assert f(p) is p - - # Test that the spec creates an Str instance: - for spec in ('one?', 'two+', 'three*', 'four'): - (name, kw) = parameters.parse_param_spec(spec) - p = f(spec) - assert p.param_spec is spec - assert p.name == name - assert p.required is kw['required'] - assert p.multivalue is kw['multivalue'] - - # Test that TypeError is raised when spec is neither a Param nor a str: - for spec in (u'one', 42, parameters.Param, parameters.Str): - e = raises(TypeError, f, spec) - assert str(e) == \ - TYPE_ERROR % ('spec', (str, parameters.Param), spec, type(spec)) - - -def test_messages(): - """ - Test module level message in `ipalib.parameters`. - """ - for name in dir(parameters): - if name.startswith('_'): - continue - attr = getattr(parameters, name) - if not (isclass(attr) and issubclass(attr, parameters.Param)): - continue - assert type(attr.type_error) is str - assert attr.type_error in parameters.__messages - - -class test_IA5Str(ClassChecker): - """ - Test the `ipalib.parameters.IA5Str` class. - """ - _cls = parameters.IA5Str - - def test_convert_scalar(self): - """ - Test the `ipalib.parameters.IA5Str._convert_scalar` method. - """ - o = self.cls('my_str') - mthd = o._convert_scalar - for value in (u'Hello', 42, 1.2): - assert mthd(value) == unicode(value) - bad = ['Helloá'] - for value in bad: - e = raises(errors.ConversionError, mthd, value) - assert e.name == 'my_str' - assert e.index is None - assert_equal(e.error, "The character '\\xc3' is not allowed.") diff --git a/tests/test_ipalib/test_plugable.py b/tests/test_ipalib/test_plugable.py deleted file mode 100644 index 3355e057a..000000000 --- a/tests/test_ipalib/test_plugable.py +++ /dev/null @@ -1,516 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.plugable` module. -""" - -import inspect -from tests.util import raises, no_set, no_del, read_only -from tests.util import getitem, setitem, delitem -from tests.util import ClassChecker, create_test_api -from ipalib import plugable, errors, text - - -class test_SetProxy(ClassChecker): - """ - Test the `ipalib.plugable.SetProxy` class. - """ - _cls = plugable.SetProxy - - def test_class(self): - """ - Test the `ipalib.plugable.SetProxy` class. - """ - assert self.cls.__bases__ == (plugable.ReadOnly,) - - def test_init(self): - """ - Test the `ipalib.plugable.SetProxy.__init__` method. - """ - okay = (set, frozenset, dict) - fail = (list, tuple) - for t in okay: - self.cls(t()) - raises(TypeError, self.cls, t) - for t in fail: - raises(TypeError, self.cls, t()) - raises(TypeError, self.cls, t) - - def test_SetProxy(self): - """ - Test container emulation of `ipalib.plugable.SetProxy` class. - """ - def get_key(i): - return 'key_%d' % i - - cnt = 10 - target = set() - proxy = self.cls(target) - for i in xrange(cnt): - key = get_key(i) - - # Check initial state - assert len(proxy) == len(target) - assert list(proxy) == sorted(target) - assert key not in proxy - assert key not in target - - # Add and test again - target.add(key) - assert len(proxy) == len(target) - assert list(proxy) == sorted(target) - assert key in proxy - assert key in target - - -class test_DictProxy(ClassChecker): - """ - Test the `ipalib.plugable.DictProxy` class. - """ - _cls = plugable.DictProxy - - def test_class(self): - """ - Test the `ipalib.plugable.DictProxy` class. - """ - assert self.cls.__bases__ == (plugable.SetProxy,) - - def test_init(self): - """ - Test the `ipalib.plugable.DictProxy.__init__` method. - """ - self.cls(dict()) - raises(TypeError, self.cls, dict) - fail = (set, frozenset, list, tuple) - for t in fail: - raises(TypeError, self.cls, t()) - raises(TypeError, self.cls, t) - - def test_DictProxy(self): - """ - Test container emulation of `ipalib.plugable.DictProxy` class. - """ - def get_kv(i): - return ( - 'key_%d' % i, - 'val_%d' % i, - ) - cnt = 10 - target = dict() - proxy = self.cls(target) - for i in xrange(cnt): - (key, val) = get_kv(i) - - # Check initial state - assert len(proxy) == len(target) - assert list(proxy) == sorted(target) - assert list(proxy()) == [target[k] for k in sorted(target)] - assert key not in proxy - raises(KeyError, getitem, proxy, key) - - # Add and test again - target[key] = val - assert len(proxy) == len(target) - assert list(proxy) == sorted(target) - assert list(proxy()) == [target[k] for k in sorted(target)] - - # Verify TypeError is raised trying to set/del via proxy - raises(TypeError, setitem, proxy, key, val) - raises(TypeError, delitem, proxy, key) - - -class test_MagicDict(ClassChecker): - """ - Test the `ipalib.plugable.MagicDict` class. - """ - _cls = plugable.MagicDict - - def test_class(self): - """ - Test the `ipalib.plugable.MagicDict` class. - """ - assert self.cls.__bases__ == (plugable.DictProxy,) - for non_dict in ('hello', 69, object): - raises(TypeError, self.cls, non_dict) - - def test_MagicDict(self): - """ - Test container emulation of `ipalib.plugable.MagicDict` class. - """ - cnt = 10 - keys = [] - d = dict() - dictproxy = self.cls(d) - for i in xrange(cnt): - key = 'key_%d' % i - val = 'val_%d' % i - keys.append(key) - - # Test thet key does not yet exist - assert len(dictproxy) == i - assert key not in dictproxy - assert not hasattr(dictproxy, key) - raises(KeyError, getitem, dictproxy, key) - raises(AttributeError, getattr, dictproxy, key) - - # Test that items/attributes cannot be set on dictproxy: - raises(TypeError, setitem, dictproxy, key, val) - raises(AttributeError, setattr, dictproxy, key, val) - - # Test that additions in d are reflected in dictproxy: - d[key] = val - assert len(dictproxy) == i + 1 - assert key in dictproxy - assert hasattr(dictproxy, key) - assert dictproxy[key] is val - assert read_only(dictproxy, key) is val - - # Test __iter__ - assert list(dictproxy) == keys - - for key in keys: - # Test that items cannot be deleted through dictproxy: - raises(TypeError, delitem, dictproxy, key) - raises(AttributeError, delattr, dictproxy, key) - - # Test that deletions in d are reflected in dictproxy - del d[key] - assert len(dictproxy) == len(d) - assert key not in dictproxy - raises(KeyError, getitem, dictproxy, key) - raises(AttributeError, getattr, dictproxy, key) - - -class test_Plugin(ClassChecker): - """ - Test the `ipalib.plugable.Plugin` class. - """ - _cls = plugable.Plugin - - def test_class(self): - """ - Test the `ipalib.plugable.Plugin` class. - """ - assert self.cls.__bases__ == (plugable.ReadOnly,) - assert type(self.cls.api) is property - - def test_init(self): - """ - Test the `ipalib.plugable.Plugin.__init__` method. - """ - o = self.cls() - assert o.name == 'Plugin' - assert o.module == 'ipalib.plugable' - assert o.fullname == 'ipalib.plugable.Plugin' - assert isinstance(o.doc, text.Gettext) - class some_subclass(self.cls): - """ - Do sub-classy things. - - Although it doesn't know how to comport itself and is not for mixed - company, this class *is* useful as we all need a little sub-class - now and then. - - One more paragraph. - """ - o = some_subclass() - assert o.name == 'some_subclass' - assert o.module == __name__ - assert o.fullname == '%s.some_subclass' % __name__ - assert o.summary == 'Do sub-classy things.' - assert isinstance(o.doc, text.Gettext) - class another_subclass(self.cls): - pass - o = another_subclass() - assert o.summary == '<%s>' % o.fullname - - # Test that Plugin makes sure the subclass hasn't defined attributes - # whose names conflict with the logger methods set in Plugin.__init__(): - class check(self.cls): - info = 'whatever' - e = raises(StandardError, check) - assert str(e) == \ - "info is already bound to tests.test_ipalib.test_plugable.check()" - - def test_set_api(self): - """ - Test the `ipalib.plugable.Plugin.set_api` method. - """ - api = 'the api instance' - o = self.cls() - assert o.api is None - e = raises(AssertionError, o.set_api, None) - assert str(e) == 'set_api() argument cannot be None' - o.set_api(api) - assert o.api is api - e = raises(AssertionError, o.set_api, api) - assert str(e) == 'set_api() can only be called once' - - def test_finalize(self): - """ - Test the `ipalib.plugable.Plugin.finalize` method. - """ - o = self.cls() - assert not o.__islocked__() - o.finalize() - assert o.__islocked__() - - def test_call(self): - """ - Test the `ipalib.plugable.Plugin.call` method. - """ - o = self.cls() - o.call('/bin/true') is None - e = raises(errors.SubprocessError, o.call, '/bin/false') - assert e.returncode == 1 - assert e.argv == ('/bin/false',) - - -def test_Registrar(): - """ - Test the `ipalib.plugable.Registrar` class - """ - class Base1(object): - pass - class Base2(object): - pass - class Base3(object): - pass - class plugin1(Base1): - pass - class plugin2(Base2): - pass - class plugin3(Base3): - pass - - # Test creation of Registrar: - r = plugable.Registrar(Base1, Base2) - - # Test __iter__: - assert list(r) == ['Base1', 'Base2'] - - # Test __hasitem__, __getitem__: - for base in [Base1, Base2]: - name = base.__name__ - assert name in r - assert r[name] is base - magic = getattr(r, name) - assert type(magic) is plugable.MagicDict - assert len(magic) == 0 - - # Check that TypeError is raised trying to register something that isn't - # a class: - p = plugin1() - e = raises(TypeError, r, p) - assert str(e) == 'plugin must be a class; got %r' % p - - # Check that SubclassError is raised trying to register a class that is - # not a subclass of an allowed base: - e = raises(errors.PluginSubclassError, r, plugin3) - assert e.plugin is plugin3 - - # Check that registration works - r(plugin1) - assert len(r.Base1) == 1 - assert r.Base1['plugin1'] is plugin1 - assert r.Base1.plugin1 is plugin1 - - # Check that DuplicateError is raised trying to register exact class - # again: - e = raises(errors.PluginDuplicateError, r, plugin1) - assert e.plugin is plugin1 - - # Check that OverrideError is raised trying to register class with same - # name and same base: - orig1 = plugin1 - class base1_extended(Base1): - pass - class plugin1(base1_extended): - pass - e = raises(errors.PluginOverrideError, r, plugin1) - assert e.base == 'Base1' - assert e.name == 'plugin1' - assert e.plugin is plugin1 - - # Check that overriding works - r(plugin1, override=True) - assert len(r.Base1) == 1 - assert r.Base1.plugin1 is plugin1 - assert r.Base1.plugin1 is not orig1 - - # Check that MissingOverrideError is raised trying to override a name - # not yet registerd: - e = raises(errors.PluginMissingOverrideError, r, plugin2, override=True) - assert e.base == 'Base2' - assert e.name == 'plugin2' - assert e.plugin is plugin2 - - # Test that another plugin can be registered: - assert len(r.Base2) == 0 - r(plugin2) - assert len(r.Base2) == 1 - assert r.Base2.plugin2 is plugin2 - - # Setup to test more registration: - class plugin1a(Base1): - pass - r(plugin1a) - - class plugin1b(Base1): - pass - r(plugin1b) - - class plugin2a(Base2): - pass - r(plugin2a) - - class plugin2b(Base2): - pass - r(plugin2b) - - # Again test __hasitem__, __getitem__: - for base in [Base1, Base2]: - name = base.__name__ - assert name in r - assert r[name] is base - magic = getattr(r, name) - assert len(magic) == 3 - for key in magic: - klass = magic[key] - assert getattr(magic, key) is klass - assert issubclass(klass, base) - - -class test_API(ClassChecker): - """ - Test the `ipalib.plugable.API` class. - """ - - _cls = plugable.API - - def test_API(self): - """ - Test the `ipalib.plugable.API` class. - """ - assert issubclass(plugable.API, plugable.ReadOnly) - - # Setup the test bases, create the API: - class base0(plugable.Plugin): - def method(self, n): - return n - - class base1(plugable.Plugin): - def method(self, n): - return n + 1 - - api = plugable.API(base0, base1) - api.env.mode = 'unit_test' - api.env.in_tree = True - r = api.register - assert isinstance(r, plugable.Registrar) - assert read_only(api, 'register') is r - - class base0_plugin0(base0): - pass - r(base0_plugin0) - - class base0_plugin1(base0): - pass - r(base0_plugin1) - - class base0_plugin2(base0): - pass - r(base0_plugin2) - - class base1_plugin0(base1): - pass - r(base1_plugin0) - - class base1_plugin1(base1): - pass - r(base1_plugin1) - - class base1_plugin2(base1): - pass - r(base1_plugin2) - - # Test API instance: - assert api.isdone('bootstrap') is False - assert api.isdone('finalize') is False - api.finalize() - assert api.isdone('bootstrap') is True - assert api.isdone('finalize') is True - - def get_base_name(b): - return 'base%d' % b - - - def get_plugin_name(b, p): - return 'base%d_plugin%d' % (b, p) - - for b in xrange(2): - base_name = get_base_name(b) - base = locals()[base_name] - ns = getattr(api, base_name) - assert isinstance(ns, plugable.NameSpace) - assert read_only(api, base_name) is ns - assert len(ns) == 3 - for p in xrange(3): - plugin_name = get_plugin_name(b, p) - plugin = locals()[plugin_name] - inst = ns[plugin_name] - assert isinstance(inst, base) - assert isinstance(inst, plugin) - assert inst.name == plugin_name - assert read_only(ns, plugin_name) is inst - assert inst.method(7) == 7 + b - - # Test that calling finilize again raises AssertionError: - e = raises(StandardError, api.finalize) - assert str(e) == 'API.finalize() already called', str(e) - - def test_bootstrap(self): - """ - Test the `ipalib.plugable.API.bootstrap` method. - """ - (o, home) = create_test_api() - assert o.env._isdone('_bootstrap') is False - assert o.env._isdone('_finalize_core') is False - assert o.isdone('bootstrap') is False - o.bootstrap(my_test_override='Hello, world!') - assert o.isdone('bootstrap') is True - assert o.env._isdone('_bootstrap') is True - assert o.env._isdone('_finalize_core') is True - assert o.env.my_test_override == 'Hello, world!' - e = raises(StandardError, o.bootstrap) - assert str(e) == 'API.bootstrap() already called' - - def test_load_plugins(self): - """ - Test the `ipalib.plugable.API.load_plugins` method. - """ - (o, home) = create_test_api() - assert o.isdone('bootstrap') is False - assert o.isdone('load_plugins') is False - o.load_plugins() - assert o.isdone('bootstrap') is True - assert o.isdone('load_plugins') is True - e = raises(StandardError, o.load_plugins) - assert str(e) == 'API.load_plugins() already called' diff --git a/tests/test_ipalib/test_rpc.py b/tests/test_ipalib/test_rpc.py deleted file mode 100644 index f8f078ddb..000000000 --- a/tests/test_ipalib/test_rpc.py +++ /dev/null @@ -1,244 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.rpc` module. -""" - -import threading -from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy -from tests.util import raises, assert_equal, PluginTester, DummyClass -from tests.data import binary_bytes, utf8_bytes, unicode_str -from ipalib.frontend import Command -from ipalib.request import context, Connection -from ipalib import rpc, errors - - -std_compound = (binary_bytes, utf8_bytes, unicode_str) - - -def dump_n_load(value): - (param, method) = loads( - dumps((value,), allow_none=True) - ) - return param[0] - - -def round_trip(value): - return rpc.xml_unwrap( - dump_n_load(rpc.xml_wrap(value)) - ) - - -def test_round_trip(): - """ - Test `ipalib.rpc.xml_wrap` and `ipalib.rpc.xml_unwrap`. - - This tests the two functions together with ``xmlrpclib.dumps()`` and - ``xmlrpclib.loads()`` in a full wrap/dumps/loads/unwrap round trip. - """ - # We first test that our assumptions about xmlrpclib module in the Python - # standard library are correct: - assert_equal(dump_n_load(utf8_bytes), unicode_str) - assert_equal(dump_n_load(unicode_str), unicode_str) - assert_equal(dump_n_load(Binary(binary_bytes)).data, binary_bytes) - assert isinstance(dump_n_load(Binary(binary_bytes)), Binary) - assert type(dump_n_load('hello')) is str - assert type(dump_n_load(u'hello')) is str - assert_equal(dump_n_load(''), '') - assert_equal(dump_n_load(u''), '') - assert dump_n_load(None) is None - - # Now we test our wrap and unwrap methods in combination with dumps, loads: - # All str should come back str (because they get wrapped in - # xmlrpclib.Binary(). All unicode should come back unicode because str - # explicity get decoded by rpc.xml_unwrap() if they weren't already - # decoded by xmlrpclib.loads(). - assert_equal(round_trip(utf8_bytes), utf8_bytes) - assert_equal(round_trip(unicode_str), unicode_str) - assert_equal(round_trip(binary_bytes), binary_bytes) - assert type(round_trip('hello')) is str - assert type(round_trip(u'hello')) is unicode - assert_equal(round_trip(''), '') - assert_equal(round_trip(u''), u'') - assert round_trip(None) is None - compound = [utf8_bytes, None, binary_bytes, (None, unicode_str), - dict(utf8=utf8_bytes, chars=unicode_str, data=binary_bytes) - ] - assert round_trip(compound) == tuple(compound) - - -def test_xml_wrap(): - """ - Test the `ipalib.rpc.xml_wrap` function. - """ - f = rpc.xml_wrap - assert f([]) == tuple() - assert f({}) == dict() - b = f('hello') - assert isinstance(b, Binary) - assert b.data == 'hello' - u = f(u'hello') - assert type(u) is unicode - assert u == u'hello' - value = f([dict(one=False, two=u'hello'), None, 'hello']) - - -def test_xml_unwrap(): - """ - Test the `ipalib.rpc.xml_unwrap` function. - """ - f = rpc.xml_unwrap - assert f([]) == tuple() - assert f({}) == dict() - value = f(Binary(utf8_bytes)) - assert type(value) is str - assert value == utf8_bytes - assert f(utf8_bytes) == unicode_str - assert f(unicode_str) == unicode_str - value = f([True, Binary('hello'), dict(one=1, two=utf8_bytes, three=None)]) - assert value == (True, 'hello', dict(one=1, two=unicode_str, three=None)) - assert type(value[1]) is str - assert type(value[2]['two']) is unicode - - -def test_xml_dumps(): - """ - Test the `ipalib.rpc.xml_dumps` function. - """ - f = rpc.xml_dumps - params = (binary_bytes, utf8_bytes, unicode_str, None) - - # Test serializing an RPC request: - data = f(params, 'the_method') - (p, m) = loads(data) - assert_equal(m, u'the_method') - assert type(p) is tuple - assert rpc.xml_unwrap(p) == params - - # Test serializing an RPC response: - data = f((params,), methodresponse=True) - (tup, m) = loads(data) - assert m is None - assert len(tup) == 1 - assert type(tup) is tuple - assert rpc.xml_unwrap(tup[0]) == params - - # Test serializing an RPC response containing a Fault: - fault = Fault(69, unicode_str) - data = f(fault, methodresponse=True) - e = raises(Fault, loads, data) - assert e.faultCode == 69 - assert_equal(e.faultString, unicode_str) - - -def test_xml_loads(): - """ - Test the `ipalib.rpc.xml_loads` function. - """ - f = rpc.xml_loads - params = (binary_bytes, utf8_bytes, unicode_str, None) - wrapped = rpc.xml_wrap(params) - - # Test un-serializing an RPC request: - data = dumps(wrapped, 'the_method', allow_none=True) - (p, m) = f(data) - assert_equal(m, u'the_method') - assert_equal(p, params) - - # Test un-serializing an RPC response: - data = dumps((wrapped,), methodresponse=True, allow_none=True) - (tup, m) = f(data) - assert m is None - assert len(tup) == 1 - assert type(tup) is tuple - assert_equal(tup[0], params) - - # Test un-serializing an RPC response containing a Fault: - for error in (unicode_str, u'hello'): - fault = Fault(69, error) - data = dumps(fault, methodresponse=True, allow_none=True, encoding='UTF-8') - e = raises(Fault, f, data) - assert e.faultCode == 69 - assert_equal(e.faultString, error) - assert type(e.faultString) is unicode - - -class test_xmlclient(PluginTester): - """ - Test the `ipalib.rpc.xmlclient` plugin. - """ - _plugin = rpc.xmlclient - - def test_forward(self): - """ - Test the `ipalib.rpc.xmlclient.forward` method. - """ - class user_add(Command): - pass - - # Test that ValueError is raised when forwarding a command that is not - # in api.Command: - (o, api, home) = self.instance('Backend', in_server=False) - e = raises(ValueError, o.forward, 'user_add') - assert str(e) == '%s.forward(): %r not in api.Command' % ( - 'xmlclient', 'user_add' - ) - - (o, api, home) = self.instance('Backend', user_add, in_server=False) - args = (binary_bytes, utf8_bytes, unicode_str) - kw = dict(one=binary_bytes, two=utf8_bytes, three=unicode_str) - params = [args, kw] - result = (unicode_str, binary_bytes, utf8_bytes) - conn = DummyClass( - ( - 'user_add', - rpc.xml_wrap(params), - {}, - rpc.xml_wrap(result), - ), - ( - 'user_add', - rpc.xml_wrap(params), - {}, - Fault(3007, u"'four' is required"), # RequirementError - ), - ( - 'user_add', - rpc.xml_wrap(params), - {}, - Fault(700, u'no such error'), # There is no error 700 - ), - - ) - context.xmlclient = Connection(conn, lambda: None) - - # Test with a successful return value: - assert o.forward('user_add', *args, **kw) == result - - # Test with an errno the client knows: - e = raises(errors.RequirementError, o.forward, 'user_add', *args, **kw) - assert_equal(e.args[0], u"'four' is required") - - # Test with an errno the client doesn't know - e = raises(errors.UnknownError, o.forward, 'user_add', *args, **kw) - assert_equal(e.code, 700) - assert_equal(e.error, u'no such error') - - assert context.xmlclient.conn._calledall() is True diff --git a/tests/test_ipalib/test_text.py b/tests/test_ipalib/test_text.py deleted file mode 100644 index 9f60785ff..000000000 --- a/tests/test_ipalib/test_text.py +++ /dev/null @@ -1,334 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty contextrmation -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.text` module. -""" - -import os -import shutil -import tempfile -import re -import nose -import locale -from tests.util import raises, assert_equal -from tests.i18n import create_po, po_file_iterate -from ipalib.request import context -from ipalib import request -from ipalib import text -from ipapython.ipautil import file_exists - -singular = '%(count)d goose makes a %(dish)s' -plural = '%(count)d geese make a %(dish)s' - - -def test_create_translation(): - f = text.create_translation - key = ('foo', None) - t = f(key) - assert context.__dict__[key] is t - - -class test_TestLang(object): - def setUp(self): - self.tmp_dir = None - self.saved_lang = None - - self.lang = 'xh_ZA' - self.domain = 'ipa' - - self.ipa_i18n_dir = os.path.join(os.path.dirname(__file__), '../../install/po') - - self.pot_basename = '%s.pot' % self.domain - self.po_basename = '%s.po' % self.lang - self.mo_basename = '%s.mo' % self.domain - - self.tmp_dir = tempfile.mkdtemp() - self.saved_lang = os.environ['LANG'] - - self.locale_dir = os.path.join(self.tmp_dir, 'test_locale') - self.msg_dir = os.path.join(self.locale_dir, self.lang, 'LC_MESSAGES') - - if not os.path.exists(self.msg_dir): - os.makedirs(self.msg_dir) - - self.pot_file = os.path.join(self.ipa_i18n_dir, self.pot_basename) - self.mo_file = os.path.join(self.msg_dir, self.mo_basename) - self.po_file = os.path.join(self.tmp_dir, self.po_basename) - - result = create_po(self.pot_file, self.po_file, self.mo_file) - if result: - raise nose.SkipTest('Unable to create po file "%s" & mo file "%s" from pot file "%s"' % - (self.po_file, self.mo_file, self.pot_file)) - - if not file_exists(self.po_file): - raise nose.SkipTest('Test po file unavailable, run "make test" in install/po') - - if not file_exists(self.mo_file): - raise nose.SkipTest('Test mo file unavailable, run "make test" in install/po') - - self.po_file_iterate = po_file_iterate - - def tearDown(self): - if self.saved_lang is not None: - os.environ['LANG'] = self.saved_lang - - if self.tmp_dir is not None: - shutil.rmtree(self.tmp_dir) - - def test_test_lang(self): - print "test_test_lang" - # The test installs the test message catalog under the xh_ZA - # (e.g. Zambia Xhosa) language by default. It would be nice to - # use a dummy language not associated with any real language, - # but the setlocale function demands the locale be a valid - # known locale, Zambia Xhosa is a reasonable choice :) - - os.environ['LANG'] = self.lang - - # Create a gettext translation object specifying our domain as - # 'ipa' and the locale_dir as 'test_locale' (i.e. where to - # look for the message catalog). Then use that translation - # object to obtain the translation functions. - - def get_msgstr(msg): - gt = text.GettextFactory(localedir=self.locale_dir)(msg) - return unicode(gt) - - def get_msgstr_plural(singular, plural, count): - ng = text.NGettextFactory(localedir=self.locale_dir)(singular, plural, count) - return ng(count) - - result = self.po_file_iterate(self.po_file, get_msgstr, get_msgstr_plural) - assert result == 0 - -class test_LazyText(object): - - klass = text.LazyText - - def test_init(self): - inst = self.klass('foo', 'bar') - assert inst.domain == 'foo' - assert inst.localedir == 'bar' - assert inst.key == ('foo', 'bar') - - -class test_FixMe(object): - klass = text.FixMe - - def test_init(self): - inst = self.klass('user.label') - assert inst.msg == 'user.label' - assert inst.domain is None - assert inst.localedir is None - - def test_repr(self): - inst = self.klass('user.label') - assert repr(inst) == "FixMe('user.label')" - - def test_unicode(self): - inst = self.klass('user.label') - assert unicode(inst) == u'' - assert type(unicode(inst)) is unicode - - -class test_Gettext(object): - - klass = text.Gettext - - def test_init(self): - inst = self.klass('what up?', 'foo', 'bar') - assert inst.domain == 'foo' - assert inst.localedir == 'bar' - assert inst.msg is 'what up?' - assert inst.args == ('what up?', 'foo', 'bar') - - def test_repr(self): - inst = self.klass('foo', 'bar', 'baz') - assert repr(inst) == "Gettext('foo', domain='bar', localedir='baz')" - - def test_unicode(self): - inst = self.klass('what up?', 'foo', 'bar') - assert unicode(inst) == u'what up?' - - def test_mod(self): - inst = self.klass('hello %(adj)s nurse', 'foo', 'bar') - assert inst % dict(adj='naughty', stuff='junk') == 'hello naughty nurse' - - def test_eq(self): - inst1 = self.klass('what up?', 'foo', 'bar') - inst2 = self.klass('what up?', 'foo', 'bar') - inst3 = self.klass('Hello world', 'foo', 'bar') - inst4 = self.klass('what up?', 'foo', 'baz') - - assert (inst1 == inst1) is True - assert (inst1 == inst2) is True - assert (inst1 == inst3) is False - assert (inst1 == inst4) is False - - # Test with args flipped - assert (inst2 == inst1) is True - assert (inst3 == inst1) is False - assert (inst4 == inst1) is False - - def test_ne(self): - inst1 = self.klass('what up?', 'foo', 'bar') - inst2 = self.klass('what up?', 'foo', 'bar') - inst3 = self.klass('Hello world', 'foo', 'bar') - inst4 = self.klass('what up?', 'foo', 'baz') - - assert (inst1 != inst2) is False - assert (inst1 != inst2) is False - assert (inst1 != inst3) is True - assert (inst1 != inst4) is True - - # Test with args flipped - assert (inst2 != inst1) is False - assert (inst3 != inst1) is True - assert (inst4 != inst1) is True - - -class test_NGettext(object): - - klass = text.NGettext - - def test_init(self): - inst = self.klass(singular, plural, 'foo', 'bar') - assert inst.singular is singular - assert inst.plural is plural - assert inst.domain == 'foo' - assert inst.localedir == 'bar' - assert inst.args == (singular, plural, 'foo', 'bar') - - def test_repr(self): - inst = self.klass('sig', 'plu', 'foo', 'bar') - assert repr(inst) == \ - "NGettext('sig', 'plu', domain='foo', localedir='bar')" - - def test_call(self): - inst = self.klass(singular, plural, 'foo', 'bar') - assert inst(0) == plural - assert inst(1) == singular - assert inst(2) == plural - assert inst(3) == plural - - def test_mod(self): - inst = self.klass(singular, plural, 'foo', 'bar') - assert inst % dict(count=0, dish='frown') == '0 geese make a frown' - assert inst % dict(count=1, dish='stew') == '1 goose makes a stew' - assert inst % dict(count=2, dish='pie') == '2 geese make a pie' - - def test_eq(self): - inst1 = self.klass(singular, plural, 'foo', 'bar') - inst2 = self.klass(singular, plural, 'foo', 'bar') - inst3 = self.klass(singular, '%(count)d thingies', 'foo', 'bar') - inst4 = self.klass(singular, plural, 'foo', 'baz') - - assert (inst1 == inst1) is True - assert (inst1 == inst2) is True - assert (inst1 == inst3) is False - assert (inst1 == inst4) is False - - # Test with args flipped - assert (inst2 == inst1) is True - assert (inst3 == inst1) is False - assert (inst4 == inst1) is False - - def test_ne(self): - inst1 = self.klass(singular, plural, 'foo', 'bar') - inst2 = self.klass(singular, plural, 'foo', 'bar') - inst3 = self.klass(singular, '%(count)d thingies', 'foo', 'bar') - inst4 = self.klass(singular, plural, 'foo', 'baz') - - assert (inst1 != inst2) is False - assert (inst1 != inst2) is False - assert (inst1 != inst3) is True - assert (inst1 != inst4) is True - - # Test with args flipped - assert (inst2 != inst1) is False - assert (inst3 != inst1) is True - assert (inst4 != inst1) is True - - -class test_GettextFactory(object): - - klass = text.GettextFactory - - def test_init(self): - # Test with defaults: - inst = self.klass() - assert inst.domain == 'ipa' - assert inst.localedir is None - - # Test with overrides: - inst = self.klass('foo', 'bar') - assert inst.domain == 'foo' - assert inst.localedir == 'bar' - - def test_repr(self): - # Test with defaults: - inst = self.klass() - assert repr(inst) == "GettextFactory(domain='ipa', localedir=None)" - - # Test with overrides: - inst = self.klass('foo', 'bar') - assert repr(inst) == "GettextFactory(domain='foo', localedir='bar')" - - def test_call(self): - inst = self.klass('foo', 'bar') - g = inst('what up?') - assert type(g) is text.Gettext - assert g.msg is 'what up?' - assert g.domain == 'foo' - assert g.localedir == 'bar' - - -class test_NGettextFactory(object): - - klass = text.NGettextFactory - - def test_init(self): - # Test with defaults: - inst = self.klass() - assert inst.domain == 'ipa' - assert inst.localedir is None - - # Test with overrides: - inst = self.klass('foo', 'bar') - assert inst.domain == 'foo' - assert inst.localedir == 'bar' - - def test_repr(self): - # Test with defaults: - inst = self.klass() - assert repr(inst) == "NGettextFactory(domain='ipa', localedir=None)" - - # Test with overrides: - inst = self.klass('foo', 'bar') - assert repr(inst) == "NGettextFactory(domain='foo', localedir='bar')" - - def test_call(self): - inst = self.klass('foo', 'bar') - ng = inst(singular, plural, 7) - assert type(ng) is text.NGettext - assert ng.singular is singular - assert ng.plural is plural - assert ng.domain == 'foo' - assert ng.localedir == 'bar' diff --git a/tests/test_ipalib/test_util.py b/tests/test_ipalib/test_util.py deleted file mode 100644 index 9d19dfb2c..000000000 --- a/tests/test_ipalib/test_util.py +++ /dev/null @@ -1,26 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.util` module. -""" - -from ipalib import util - - diff --git a/tests/test_ipalib/test_x509.py b/tests/test_ipalib/test_x509.py deleted file mode 100644 index cf076313e..000000000 --- a/tests/test_ipalib/test_x509.py +++ /dev/null @@ -1,139 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.x509` module. -""" - -import os -from os import path -import sys -from tests.util import raises, setitem, delitem, ClassChecker -from tests.util import getitem, setitem, delitem -from tests.util import TempDir, TempHome -from ipalib.constants import TYPE_ERROR, OVERRIDE_ERROR, SET_ERROR, DEL_ERROR -from ipalib.constants import NAME_REGEX, NAME_ERROR -import base64 -from ipalib import x509 -from nss.error import NSPRError -from ipapython.dn import DN - -# certutil - - -# certificate for CN=ipa.example.com,O=IPA -goodcert = 'MIICAjCCAWugAwIBAgICBEUwDQYJKoZIhvcNAQEFBQAwKTEnMCUGA1UEAxMeSVBBIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDYyNTEzMDA0MloXDTE1MDYyNTEzMDA0MlowKDEMMAoGA1UEChMDSVBBMRgwFgYDVQQDEw9pcGEuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJcZ+H6+cQaN/BlzR8OYkVeJgaU5tCaV9FF1m7Ws/ftPtTJUaSL1ncp6603rjA4tH1aa/B8i8xdC46+ZbY2au8b9ryGcOsx2uaRpNLEQ2Fy//q1kQC8oM+iD8Nd6osF0a2wnugsgnJHPuJzhViaWxYgzk5DRdP81debokF3f3FX/AgMBAAGjOjA4MBEGCWCGSAGG+EIBAQQEAwIGQDATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADgYEALD6X9V9w381AzzQPcHsjIjiX3B/AF9RCGocKZUDXkdDhsD9NZ3PLPEf1AMjkraKG963HPB8scyiBbbSuSh6m7TCp0eDgRpo77zNuvd3U4Qpm0Qk+KEjtHQDjNNG6N4ZnCQPmjFPScElvc/GgW7XMbywJy2euF+3/Uip8cnPgSH4=' - -# The base64-encoded string 'bad cert' -badcert = 'YmFkIGNlcnQ=' - -class test_x509(object): - """ - Test `ipalib.x509` - - I created the contents of this certificate with a self-signed CA with: - % certutil -R -s "CN=ipa.example.com,O=IPA" -d . -a -o example.csr - % ./ipa host-add ipa.example.com - % ./ipa cert-request --add --principal=test/ipa.example.com example.csr - """ - - def test_1_load_base64_cert(self): - """ - Test loading a base64-encoded certificate. - """ - - # Load a good cert - cert = x509.load_certificate(goodcert) - - # Load a good cert with headers - newcert = '-----BEGIN CERTIFICATE-----' + goodcert + '-----END CERTIFICATE-----' - cert = x509.load_certificate(newcert) - - # Load a good cert with bad headers - newcert = '-----BEGIN CERTIFICATE-----' + goodcert - try: - cert = x509.load_certificate(newcert) - except TypeError: - pass - - # Load a bad cert - try: - cert = x509.load_certificate(badcert) - except NSPRError: - pass - - def test_1_load_der_cert(self): - """ - Test loading a DER certificate. - """ - - der = base64.b64decode(goodcert) - - # Load a good cert - cert = x509.load_certificate(der, x509.DER) - - def test_2_get_subject(self): - """ - Test retrieving the subject - """ - subject = x509.get_subject(goodcert) - assert DN(str(subject)) == DN(('CN','ipa.example.com'),('O','IPA')) - - der = base64.b64decode(goodcert) - subject = x509.get_subject(der, x509.DER) - assert DN(str(subject)) == DN(('CN','ipa.example.com'),('O','IPA')) - - # We should be able to pass in a tuple/list of certs too - subject = x509.get_subject((goodcert)) - assert DN(str(subject)) == DN(('CN','ipa.example.com'),('O','IPA')) - - subject = x509.get_subject([goodcert]) - assert DN(str(subject)) == DN(('CN','ipa.example.com'),('O','IPA')) - - def test_2_get_serial_number(self): - """ - Test retrieving the serial number - """ - serial = x509.get_serial_number(goodcert) - assert serial == 1093 - - der = base64.b64decode(goodcert) - serial = x509.get_serial_number(der, x509.DER) - assert serial == 1093 - - # We should be able to pass in a tuple/list of certs too - serial = x509.get_serial_number((goodcert)) - assert serial == 1093 - - serial = x509.get_serial_number([goodcert]) - assert serial == 1093 - - def test_3_cert_contents(self): - """ - Test the contents of a certificate - """ - # Verify certificate contents. This exercises python-nss more than - # anything but confirms our usage of it. - - cert = x509.load_certificate(goodcert) - - assert DN(str(cert.subject)) == DN(('CN','ipa.example.com'),('O','IPA')) - assert DN(str(cert.issuer)) == DN(('CN','IPA Test Certificate Authority')) - assert cert.serial_number == 1093 - assert cert.valid_not_before_str == 'Fri Jun 25 13:00:42 2010 UTC' - assert cert.valid_not_after_str == 'Thu Jun 25 13:00:42 2015 UTC' diff --git a/tests/test_ipapython/__init__.py b/tests/test_ipapython/__init__.py deleted file mode 100644 index fa0e44bb5..000000000 --- a/tests/test_ipapython/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Jan Cholasta -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Sub-package containing unit tests for `ipapython` package. -""" diff --git a/tests/test_ipapython/test_cookie.py b/tests/test_ipapython/test_cookie.py deleted file mode 100644 index b8a2d36da..000000000 --- a/tests/test_ipapython/test_cookie.py +++ /dev/null @@ -1,478 +0,0 @@ -# Authors: -# John Dennis -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import unittest -import time -import datetime -import email.utils -import calendar -from ipapython.cookie import Cookie - -class TestParse(unittest.TestCase): - - def test_parse(self): - # Empty string - s = '' - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 0) - - # Invalid single token - s = 'color' - with self.assertRaises(ValueError): - cookies = Cookie.parse(s) - - # Invalid single token that's keyword - s = 'HttpOnly' - with self.assertRaises(ValueError): - cookies = Cookie.parse(s) - - # Invalid key/value pair whose key is a keyword - s = 'domain=example.com' - with self.assertRaises(ValueError): - cookies = Cookie.parse(s) - - # 1 cookie with name/value - s = 'color=blue' - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 1) - cookie = cookies[0] - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue") - self.assertEqual(cookie.http_cookie(), "color=blue;") - - # 1 cookie with whose value is quoted - # Use "get by name" utility to extract specific cookie - s = 'color="blue"' - cookie = Cookie.get_named_cookie_from_string(s, 'color') - self.assertIsNotNone(cookie) - self.assertIsNotNone(cookie, Cookie) - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue") - self.assertEqual(cookie.http_cookie(), "color=blue;") - - # 1 cookie with name/value and domain, path attributes. - # Change up the whitespace a bit. - s = 'color =blue; domain= example.com ; path = /toplevel ' - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 1) - cookie = cookies[0] - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, 'example.com') - self.assertEqual(cookie.path, '/toplevel') - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue; Domain=example.com; Path=/toplevel") - self.assertEqual(cookie.http_cookie(), "color=blue;") - - # 2 cookies, various attributes - s = 'color=blue; Max-Age=3600; temperature=hot; HttpOnly' - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 2) - cookie = cookies[0] - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, 3600) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue; Max-Age=3600") - self.assertEqual(cookie.http_cookie(), "color=blue;") - cookie = cookies[1] - self.assertEqual(cookie.key, 'temperature') - self.assertEqual(cookie.value, 'hot') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, True) - self.assertEqual(str(cookie), "temperature=hot; HttpOnly") - self.assertEqual(cookie.http_cookie(), "temperature=hot;") - -class TestExpires(unittest.TestCase): - - def setUp(self): - # Force microseconds to zero because cookie timestamps only have second resolution - self.now = datetime.datetime.utcnow().replace(microsecond=0) - self.now_timestamp = calendar.timegm(self.now.utctimetuple()) - self.now_string = email.utils.formatdate(self.now_timestamp, usegmt=True) - - self.max_age = 3600 # 1 hour - self.age_expiration = self.now + datetime.timedelta(seconds=self.max_age) - self.age_timestamp = calendar.timegm(self.age_expiration.utctimetuple()) - self.age_string = email.utils.formatdate(self.age_timestamp, usegmt=True) - - self.expires = self.now + datetime.timedelta(days=1) # 1 day - self.expires_timestamp = calendar.timegm(self.expires.utctimetuple()) - self.expires_string = email.utils.formatdate(self.expires_timestamp, usegmt=True) - - def test_expires(self): - # 1 cookie with name/value and no Max-Age and no Expires - s = 'color=blue;' - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 1) - cookie = cookies[0] - # Force timestamp to known value - cookie.timestamp = self.now - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue") - self.assertEqual(cookie.get_expiration(), None) - # Normalize - self.assertEqual(cookie.normalize_expiration(), None) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, None) - self.assertEqual(str(cookie), "color=blue") - - # 1 cookie with name/value and Max-Age - s = 'color=blue; max-age=%d' % (self.max_age) - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 1) - cookie = cookies[0] - # Force timestamp to known value - cookie.timestamp = self.now - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, self.max_age) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue; Max-Age=%d" % (self.max_age)) - self.assertEqual(cookie.get_expiration(), self.age_expiration) - # Normalize - self.assertEqual(cookie.normalize_expiration(), self.age_expiration) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, self.age_expiration) - self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.age_string)) - - - # 1 cookie with name/value and Expires - s = 'color=blue; Expires=%s' % (self.expires_string) - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 1) - cookie = cookies[0] - # Force timestamp to known value - cookie.timestamp = self.now - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, self.expires) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.expires_string)) - self.assertEqual(cookie.get_expiration(), self.expires) - # Normalize - self.assertEqual(cookie.normalize_expiration(), self.expires) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, self.expires) - self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.expires_string)) - - # 1 cookie with name/value witht both Max-Age and Expires, Max-Age takes precedence - s = 'color=blue; Expires=%s; max-age=%d' % (self.expires_string, self.max_age) - cookies = Cookie.parse(s) - self.assertEqual(len(cookies), 1) - cookie = cookies[0] - # Force timestamp to known value - cookie.timestamp = self.now - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, self.max_age) - self.assertEqual(cookie.expires, self.expires) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue; Max-Age=%d; Expires=%s" % (self.max_age, self.expires_string)) - self.assertEqual(cookie.get_expiration(), self.age_expiration) - # Normalize - self.assertEqual(cookie.normalize_expiration(), self.age_expiration) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, self.age_expiration) - self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.age_string)) - - # Verify different types can be assigned to the timestamp and - # expires attribute. - - cookie = Cookie('color', 'blue') - cookie.timestamp = self.now - self.assertEqual(cookie.timestamp, self.now) - cookie.timestamp = self.now_timestamp - self.assertEqual(cookie.timestamp, self.now) - cookie.timestamp = self.now_string - self.assertEqual(cookie.timestamp, self.now) - - self.assertEqual(cookie.expires, None) - - cookie.expires = self.expires - self.assertEqual(cookie.expires, self.expires) - cookie.expires = self.expires_timestamp - self.assertEqual(cookie.expires, self.expires) - cookie.expires = self.expires_string - self.assertEqual(cookie.expires, self.expires) - -class TestInvalidAttributes(unittest.TestCase): - def test_invalid(self): - # Invalid Max-Age - s = 'color=blue; Max-Age=over-the-hill' - with self.assertRaises(ValueError): - cookies = Cookie.parse(s) - - cookie = Cookie('color', 'blue') - with self.assertRaises(ValueError): - cookie.max_age = 'over-the-hill' - - # Invalid Expires - s = 'color=blue; Expires=Sun, 06 Xxx 1994 08:49:37 GMT' - with self.assertRaises(ValueError): - cookies = Cookie.parse(s) - - cookie = Cookie('color', 'blue') - with self.assertRaises(ValueError): - cookie.expires = 'Sun, 06 Xxx 1994 08:49:37 GMT' - - -class TestAttributes(unittest.TestCase): - def test_attributes(self): - cookie = Cookie('color', 'blue') - self.assertEqual(cookie.key, 'color') - self.assertEqual(cookie.value, 'blue') - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - self.assertEqual(cookie.max_age, None) - self.assertEqual(cookie.expires, None) - self.assertEqual(cookie.secure, None) - self.assertEqual(cookie.httponly, None) - - cookie.domain = 'example.com' - self.assertEqual(cookie.domain, 'example.com') - cookie.domain = None - self.assertEqual(cookie.domain, None) - - cookie.path = '/toplevel' - self.assertEqual(cookie.path, '/toplevel') - cookie.path = None - self.assertEqual(cookie.path, None) - - cookie.max_age = 400 - self.assertEqual(cookie.max_age, 400) - cookie.max_age = None - self.assertEqual(cookie.max_age, None) - - cookie.expires = 'Sun, 06 Nov 1994 08:49:37 GMT' - self.assertEqual(cookie.expires, datetime.datetime(1994, 11, 6, 8, 49, 37)) - cookie.expires = None - self.assertEqual(cookie.expires, None) - - cookie.secure = True - self.assertEqual(cookie.secure, True) - self.assertEqual(str(cookie), "color=blue; Secure") - cookie.secure = False - self.assertEqual(cookie.secure, False) - self.assertEqual(str(cookie), "color=blue") - cookie.secure = None - self.assertEqual(cookie.secure, None) - self.assertEqual(str(cookie), "color=blue") - - cookie.httponly = True - self.assertEqual(cookie.httponly, True) - self.assertEqual(str(cookie), "color=blue; HttpOnly") - cookie.httponly = False - self.assertEqual(cookie.httponly, False) - self.assertEqual(str(cookie), "color=blue") - cookie.httponly = None - self.assertEqual(cookie.httponly, None) - self.assertEqual(str(cookie), "color=blue") - - -class TestHTTPReturn(unittest.TestCase): - def setUp(self): - self.url = 'http://www.foo.bar.com/one/two' - - def test_no_attributes(self): - cookie = Cookie('color', 'blue') - self.assertTrue(cookie.http_return_ok(self.url)) - - def test_domain(self): - cookie = Cookie('color', 'blue', domain='www.foo.bar.com') - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', domain='.foo.bar.com') - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', domain='.bar.com') - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', domain='bar.com') - with self.assertRaises(Cookie.URLMismatch): - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', domain='bogus.com') - with self.assertRaises(Cookie.URLMismatch): - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', domain='www.foo.bar.com') - with self.assertRaises(Cookie.URLMismatch): - self.assertTrue(cookie.http_return_ok('http://192.168.1.1/one/two')) - - def test_path(self): - cookie = Cookie('color', 'blue') - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', path='/') - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', path='/one') - self.assertTrue(cookie.http_return_ok(self.url)) - - cookie = Cookie('color', 'blue', path='/oneX') - with self.assertRaises(Cookie.URLMismatch): - self.assertTrue(cookie.http_return_ok(self.url)) - - def test_expires(self): - now = datetime.datetime.utcnow().replace(microsecond=0) - - # expires 1 day from now - expires = now + datetime.timedelta(days=1) - - cookie = Cookie('color', 'blue', expires=expires) - self.assertTrue(cookie.http_return_ok(self.url)) - - # expired 1 day ago - expires = now + datetime.timedelta(days=-1) - cookie = Cookie('color', 'blue', expires=expires) - with self.assertRaises(Cookie.Expired): - self.assertTrue(cookie.http_return_ok(self.url)) - - - def test_httponly(self): - cookie = Cookie('color', 'blue', httponly=True) - self.assertTrue(cookie.http_return_ok('http://example.com')) - self.assertTrue(cookie.http_return_ok('https://example.com')) - - with self.assertRaises(Cookie.URLMismatch): - self.assertTrue(cookie.http_return_ok('ftp://example.com')) - - def test_secure(self): - cookie = Cookie('color', 'blue', secure=True) - self.assertTrue(cookie.http_return_ok('https://Xexample.com')) - - with self.assertRaises(Cookie.URLMismatch): - self.assertTrue(cookie.http_return_ok('http://Xexample.com')) - -class TestNormalization(unittest.TestCase): - def setUp(self): - # Force microseconds to zero because cookie timestamps only have second resolution - self.now = datetime.datetime.utcnow().replace(microsecond=0) - self.now_timestamp = calendar.timegm(self.now.utctimetuple()) - self.now_string = email.utils.formatdate(self.now_timestamp, usegmt=True) - - self.max_age = 3600 # 1 hour - self.age_expiration = self.now + datetime.timedelta(seconds=self.max_age) - self.age_timestamp = calendar.timegm(self.age_expiration.utctimetuple()) - self.age_string = email.utils.formatdate(self.age_timestamp, usegmt=True) - - self.expires = self.now + datetime.timedelta(days=1) # 1 day - self.expires_timestamp = calendar.timegm(self.expires.utctimetuple()) - self.expires_string = email.utils.formatdate(self.expires_timestamp, usegmt=True) - - def test_path_normalization(self): - self.assertEqual(Cookie.normalize_url_path(''), '/') - self.assertEqual(Cookie.normalize_url_path('foo'), '/') - self.assertEqual(Cookie.normalize_url_path('foo/'), '/') - self.assertEqual(Cookie.normalize_url_path('/foo'), '/') - self.assertEqual(Cookie.normalize_url_path('/foo/'), '/foo') - self.assertEqual(Cookie.normalize_url_path('/Foo/bar'), '/foo') - self.assertEqual(Cookie.normalize_url_path('/foo/baR/'), '/foo/bar') - - def test_normalization(self): - cookie = Cookie('color', 'blue', expires=self.expires) - cookie.timestamp = self.now_timestamp - - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - - url = 'http://example.COM/foo' - cookie.normalize(url) - self.assertEqual(cookie.domain, 'example.com') - self.assertEqual(cookie.path, '/') - self.assertEqual(cookie.expires, self.expires) - - cookie = Cookie('color', 'blue', max_age=self.max_age) - cookie.timestamp = self.now_timestamp - - self.assertEqual(cookie.domain, None) - self.assertEqual(cookie.path, None) - - url = 'http://example.com/foo/' - cookie.normalize(url) - self.assertEqual(cookie.domain, 'example.com') - self.assertEqual(cookie.path, '/foo') - self.assertEqual(cookie.expires, self.age_expiration) - - cookie = Cookie('color', 'blue') - url = 'http://example.com/foo' - cookie.normalize(url) - self.assertEqual(cookie.domain, 'example.com') - self.assertEqual(cookie.path, '/') - - cookie = Cookie('color', 'blue') - url = 'http://example.com/foo/bar' - cookie.normalize(url) - self.assertEqual(cookie.domain, 'example.com') - self.assertEqual(cookie.path, '/foo') - - cookie = Cookie('color', 'blue') - url = 'http://example.com/foo/bar/' - cookie.normalize(url) - self.assertEqual(cookie.domain, 'example.com') - self.assertEqual(cookie.path, '/foo/bar') - - -#------------------------------------------------------------------------------- -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_ipapython/test_dn.py b/tests/test_ipapython/test_dn.py deleted file mode 100644 index cdeab9374..000000000 --- a/tests/test_ipapython/test_dn.py +++ /dev/null @@ -1,1937 +0,0 @@ -#!/usr/bin/python - -import unittest -from ipapython.dn import * - -def default_rdn_attr_arg(i): - return 'a%d' % i - -def default_rdn_value_arg(i): - return str(i) - -def alt_rdn_attr_arg(i): - return 'b%d' % i - -def alt_rdn_value_arg(i): - return str(i*10) - -def make_rdn_args(low, high, kind, attr=None, value=None): - result=[] - for i in range(low, high): - if attr is None: - new_attr = default_rdn_attr_arg(i) - elif callable(attr): - new_attr = attr(i) - else: - new_attr = attr - - if value is None: - new_value = default_rdn_value_arg(i) - elif callable(value): - new_value = value(i) - else: - new_value = value - - if kind == 'tuple': - result.append((new_attr, new_value)) - elif kind == 'list': - result.append([new_attr, new_value]) - elif kind == 'RDN': - result.append(RDN((new_attr, new_value))) - else: - raise ValueError("Unknown kind = %s" % kind) - - return result - -def expected_class(klass, component): - if klass is AVA: - if component == 'self': - return AVA - - elif klass is EditableAVA: - if component == 'self': - return EditableAVA - - elif klass is RDN: - if component == 'self': - return RDN - elif component == 'AVA': - return AVA - - elif klass is EditableRDN: - if component == 'self': - return EditableRDN - elif component == 'AVA': - return EditableAVA - - elif klass is DN: - if component == 'self': - return DN - elif component == 'AVA': - return AVA - elif component == 'RDN': - return RDN - - elif klass is EditableDN: - if component == 'self': - return EditableDN - elif component == 'AVA': - return EditableAVA - elif component == 'RDN': - return EditableRDN - - raise ValueError("class %s with component '%s' unknown" % (klass.__name__, component)) - - -class TestAVA(unittest.TestCase): - def setUp(self): - self.attr1 = 'cn' - self.value1 = 'Bob' - self.str_ava1 = '%s=%s' % (self.attr1, self.value1) - self.ava1 = AVA(self.attr1, self.value1) - - self.attr2 = 'ou' - self.value2 = 'People' - self.str_ava2 = '%s=%s' % (self.attr2, self.value2) - self.ava2 = AVA(self.attr2, self.value2) - - self.attr3 = 'c' - self.value3 = 'US' - self.str_ava3 = '%s=%s' % (self.attr3, self.value3) - self.ava3 = AVA(self.attr3, self.value3) - - def assertExpectedClass(self, klass, obj, component): - self.assertIs(obj.__class__, expected_class(klass, component)) - - def test_create(self): - for AVA_class in (AVA, EditableAVA): - # Create with attr,value pair - ava1 = AVA_class(self.attr1, self.value1) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1, self.ava1) - - # Create with "attr=value" string - ava1 = AVA_class(self.str_ava1) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1, self.ava1) - - # Create with tuple (attr, value) - ava1 = AVA_class((self.attr1, self.value1)) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1, self.ava1) - - # Create with list [attr, value] - ava1 = AVA_class([self.attr1, self.value1]) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1, self.ava1) - - # Create with no args should fail - with self.assertRaises(TypeError): - AVA_class() - - # Create with more than 2 args should fail - with self.assertRaises(TypeError): - AVA_class(self.attr1, self.value1, self.attr1) - - # Create with 1 arg which is not string should fail - with self.assertRaises(TypeError): - AVA_class(1) - - # Create with malformed AVA_class string should fail - with self.assertRaises(ValueError): - AVA_class("cn") - - # Create with non-string parameters, should convert - ava1 = AVA_class(1, self.value1) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1.attr, u'1') - - ava1 = AVA_class((1, self.value1)) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1.attr, u'1') - - ava1 = AVA_class(self.attr1, 1) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1.value, u'1') - - ava1 = AVA_class((self.attr1, 1)) - self.assertExpectedClass(AVA_class, ava1, 'self') - self.assertEqual(ava1.value, u'1') - - def test_indexing(self): - for AVA_class in (AVA, EditableAVA): - ava1 = AVA_class(self.ava1) - - self.assertEqual(ava1[self.attr1], self.value1) - - with self.assertRaises(KeyError): - ava1['foo'] - - with self.assertRaises(TypeError): - ava1[0] - - def test_properties(self): - for AVA_class in (AVA, EditableAVA): - ava1 = AVA_class(self.ava1) - - self.assertEqual(ava1.attr, self.attr1) - self.assertIsInstance(ava1.attr, unicode) - - self.assertEqual(ava1.value, self.value1) - self.assertIsInstance(ava1.value, unicode) - - def test_str(self): - for AVA_class in (AVA, EditableAVA): - ava1 = AVA_class(self.ava1) - - self.assertEqual(str(ava1), self.str_ava1) - self.assertIsInstance(str(ava1), str) - - def test_cmp(self): - for AVA_class in (AVA, EditableAVA): - # Equality - ava1 = AVA_class(self.attr1, self.value1) - - self.assertTrue(ava1 == self.ava1) - self.assertFalse(ava1 != self.ava1) - - self.assertTrue(ava1 == self.str_ava1) - self.assertFalse(ava1 != self.str_ava1) - - result = cmp(ava1, self.ava1) - self.assertEqual(result, 0) - - # Upper case attr should still be equal - ava1 = AVA_class(self.attr1.upper(), self.value1) - - self.assertFalse(ava1.attr == self.attr1) - self.assertTrue(ava1.value == self.value1) - self.assertTrue(ava1 == self.ava1) - self.assertFalse(ava1 != self.ava1) - - result = cmp(ava1, self.ava1) - self.assertEqual(result, 0) - - # Upper case value should still be equal - ava1 = AVA_class(self.attr1, self.value1.upper()) - - self.assertTrue(ava1.attr == self.attr1) - self.assertFalse(ava1.value == self.value1) - self.assertTrue(ava1 == self.ava1) - self.assertFalse(ava1 != self.ava1) - - result = cmp(ava1, self.ava1) - self.assertEqual(result, 0) - - # Make ava1's attr greater - if AVA_class.is_mutable: - ava1.attr = self.attr1 + "1" - else: - with self.assertRaises(AttributeError): - ava1.attr = self.attr1 + "1" - ava1 = AVA_class(self.attr1 + "1", self.value1.upper()) - - self.assertFalse(ava1 == self.ava1) - self.assertTrue(ava1 != self.ava1) - - result = cmp(ava1, self.ava1) - self.assertEqual(result, 1) - - result = cmp(self.ava1, ava1) - self.assertEqual(result, -1) - - # Reset ava1's attr, should be equal again - if AVA_class.is_mutable: - ava1.attr = self.attr1 - else: - with self.assertRaises(AttributeError): - ava1.attr = self.attr1 - ava1 = AVA_class(self.attr1, self.value1.upper()) - - result = cmp(ava1, self.ava1) - self.assertEqual(result, 0) - - # Make ava1's value greater - # attr will be equal, this tests secondary comparision component - if AVA_class.is_mutable: - ava1.value = self.value1 + "1" - else: - with self.assertRaises(AttributeError): - ava1.value = self.value1 + "1" - ava1 = AVA_class(self.attr1, self.value1 + "1") - - result = cmp(ava1, self.ava1) - self.assertEqual(result, 1) - - result = cmp(self.ava1, ava1) - self.assertEqual(result, -1) - - def test_hashing(self): - # create AVA's that are equal but differ in case - immutable_ava1 = AVA((self.attr1.lower(), self.value1.upper())) - immutable_ava2 = AVA((self.attr1.upper(), self.value1.lower())) - - mutable_ava1 = EditableAVA((self.attr1.lower(), self.value1.upper())) - mutable_ava2 = EditableAVA((self.attr1.upper(), self.value1.lower())) - - # Immutable AVA's that are equal should hash to the same value. - # Mutable AVA's should not be hashable. - - self.assertEqual(immutable_ava1, immutable_ava2) - self.assertEqual(immutable_ava1, mutable_ava1) - self.assertEqual(immutable_ava1, mutable_ava2) - self.assertEqual(mutable_ava1, immutable_ava2) - - # Good, everyone's equal, now verify their hash values - - self.assertEqual(hash(immutable_ava1), hash(immutable_ava2)) - with self.assertRaises(TypeError): - hash(mutable_ava1) - with self.assertRaises(TypeError): - hash(mutable_ava2) - - # Different immutable AVA objects with the same value should - # map to 1 common key and 1 member in a set. The key and - # member are based on the object's value. - # - # Mutable AVA objects should be unhashable. - - for AVA_class in (AVA, EditableAVA): - ava1_a = AVA_class(self.ava1) - ava1_b = AVA_class(self.ava1) - - ava2_a = AVA_class(self.ava2) - ava2_b = AVA_class(self.ava2) - - ava3_a = AVA_class(self.ava3) - ava3_b = AVA_class(self.ava3) - - self.assertEqual(ava1_a, ava1_b) - self.assertEqual(ava2_a, ava2_b) - self.assertEqual(ava3_a, ava3_b) - - d = dict() - s = set() - - if AVA_class.is_mutable: - with self.assertRaises(TypeError): - d[ava1_a] = str(ava1_a) - with self.assertRaises(TypeError): - d[ava1_b] = str(ava1_b) - with self.assertRaises(TypeError): - d[ava2_a] = str(ava2_a) - with self.assertRaises(TypeError): - d[ava2_b] = str(ava2_b) - - with self.assertRaises(TypeError): - s.add(ava1_a) - with self.assertRaises(TypeError): - s.add(ava1_b) - with self.assertRaises(TypeError): - s.add(ava2_a) - with self.assertRaises(TypeError): - s.add(ava2_b) - else: - d[ava1_a] = str(ava1_a) - d[ava1_b] = str(ava1_b) - d[ava2_a] = str(ava2_a) - d[ava2_b] = str(ava2_b) - - s.add(ava1_a) - s.add(ava1_b) - s.add(ava2_a) - s.add(ava2_b) - - self.assertEqual(len(d), 2) - self.assertEqual(len(s), 2) - self.assertEqual(sorted(d.keys()), sorted([ava1_a, ava2_a])) - self.assertEqual(sorted(s), sorted([ava1_a, ava2_a])) - - self.assertTrue(ava1_a in d) - self.assertTrue(ava1_b in d) - self.assertTrue(ava2_a in d) - self.assertTrue(ava2_b in d) - self.assertFalse(ava3_a in d) - self.assertFalse(ava3_b in d) - - self.assertTrue(d.has_key(ava1_a)) - self.assertTrue(d.has_key(ava1_b)) - self.assertTrue(d.has_key(ava2_a)) - self.assertTrue(d.has_key(ava2_b)) - self.assertFalse(d.has_key(ava3_a)) - self.assertFalse(d.has_key(ava3_b)) - - self.assertTrue(ava1_a in s) - self.assertTrue(ava1_b in s) - self.assertTrue(ava2_a in s) - self.assertTrue(ava2_b in s) - self.assertFalse(ava3_a in s) - self.assertFalse(ava3_b in s) - - def test_coerce(self): - # Coerce an immutable to a mutable - immutable_ava1 = AVA(self.ava1) - mutable_ava1 = EditableAVA(immutable_ava1) - self.assertEqual(mutable_ava1, self.ava1) - self.assertEqual(mutable_ava1, immutable_ava1) - - # Coerce a mutable to an immutable - mutable_ava1 = EditableAVA(self.ava1) - immutable_ava1 = AVA(mutable_ava1) - self.assertEqual(immutable_ava1, self.ava1) - self.assertEqual(immutable_ava1, mutable_ava1) - -class TestRDN(unittest.TestCase): - def setUp(self): - # ava1 must sort before ava2 - self.attr1 = 'cn' - self.value1 = 'Bob' - self.str_ava1 = '%s=%s' % (self.attr1, self.value1) - self.ava1 = AVA(self.attr1, self.value1) - - self.str_rdn1 = '%s=%s' % (self.attr1, self.value1) - self.rdn1 = RDN((self.attr1, self.value1)) - - self.attr2 = 'ou' - self.value2 = 'people' - self.str_ava2 = '%s=%s' % (self.attr2, self.value2) - self.ava2 = AVA(self.attr2, self.value2) - - self.str_rdn2 = '%s=%s' % (self.attr2, self.value2) - self.rdn2 = RDN((self.attr2, self.value2)) - - self.str_ava3 = '%s=%s+%s=%s' % (self.attr1, self.value1, self.attr2, self.value2) - - self.str_rdn3 = '%s=%s+%s=%s' % (self.attr1, self.value1, self.attr2, self.value2) - self.rdn3 = RDN(self.ava1, self.ava2) - - def assertExpectedClass(self, klass, obj, component): - self.assertIs(obj.__class__, expected_class(klass, component)) - - def test_create(self): - for RDN_class in (RDN, EditableRDN): - # Create with single attr,value pair - rdn1 = RDN_class((self.attr1, self.value1)) - - - self.assertEqual(len(rdn1), 1) - self.assertEqual(rdn1, self.rdn1) - self.assertExpectedClass(RDN_class, rdn1, 'self') - for i in range(0, len(rdn1)): - self.assertExpectedClass(RDN_class, rdn1[i], 'AVA') - self.assertEqual(rdn1[0], self.ava1) - - # Create with multiple attr,value pairs - rdn3 = RDN_class((self.attr1, self.value1), (self.attr2, self.value2)) - self.assertEqual(len(rdn3), 2) - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - self.assertEqual(rdn3[0], self.ava1) - self.assertEqual(rdn3[1], self.ava2) - - # Create with multiple attr,value pairs passed as lists - rdn3 = RDN_class([self.attr1, self.value1], [self.attr2, self.value2]) - self.assertEqual(len(rdn3), 2) - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - self.assertEqual(rdn3[0], self.ava1) - self.assertEqual(rdn3[1], self.ava2) - - # Create with multiple attr,value pairs but reverse - # constructor parameter ordering. RDN canonical ordering - # should remain the same - rdn3 = RDN_class((self.attr2, self.value2), (self.attr1, self.value1)) - self.assertEqual(len(rdn3), 2) - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - self.assertEqual(rdn3[0], self.ava1) - self.assertEqual(rdn3[1], self.ava2) - - # Create with single AVA object - rdn1 = RDN_class(self.ava1) - self.assertEqual(len(rdn1), 1) - self.assertEqual(rdn1, self.rdn1) - self.assertExpectedClass(RDN_class, rdn1, 'self') - for i in range(0, len(rdn1)): - self.assertExpectedClass(RDN_class, rdn1[i], 'AVA') - self.assertEqual(rdn1[0], self.ava1) - - # Create with multiple AVA objects - rdn3 = RDN_class(self.ava1, self.ava2) - self.assertEqual(len(rdn3), 2) - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - self.assertEqual(rdn3[0], self.ava1) - self.assertEqual(rdn3[1], self.ava2) - - - # Create with multiple AVA objects but reverse constructor - # parameter ordering. RDN canonical ordering should remain - # the same - rdn3 = RDN_class(self.ava2, self.ava1) - self.assertEqual(len(rdn3), 2) - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - self.assertEqual(rdn3[0], self.ava1) - self.assertEqual(rdn3[1], self.ava2) - - # Create with single string with 1 AVA - rdn1 = RDN_class(self.str_rdn1) - self.assertEqual(len(rdn1), 1) - self.assertEqual(rdn1, self.rdn1) - self.assertExpectedClass(RDN_class, rdn1, 'self') - for i in range(0, len(rdn1)): - self.assertExpectedClass(RDN_class, rdn1[i], 'AVA') - self.assertEqual(rdn1[0], self.ava1) - - # Create with single string with 2 AVA's - rdn3 = RDN_class(self.str_rdn3) - self.assertEqual(len(rdn3), 2) - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - self.assertEqual(rdn3[0], self.ava1) - self.assertEqual(rdn3[1], self.ava2) - - def test_properties(self): - for RDN_class in (RDN, EditableRDN): - rdn1 = RDN_class(self.rdn1) - rdn2 = RDN_class(self.rdn2) - rdn3 = RDN_class(self.rdn3) - - self.assertEqual(rdn1.attr, self.attr1) - self.assertIsInstance(rdn1.attr, unicode) - - self.assertEqual(rdn1.value, self.value1) - self.assertIsInstance(rdn1.value, unicode) - - self.assertEqual(rdn2.attr, self.attr2) - self.assertIsInstance(rdn2.attr, unicode) - - self.assertEqual(rdn2.value, self.value2) - self.assertIsInstance(rdn2.value, unicode) - - self.assertEqual(rdn3.attr, self.attr1) - self.assertIsInstance(rdn3.attr, unicode) - - self.assertEqual(rdn3.value, self.value1) - self.assertIsInstance(rdn3.value, unicode) - - def test_str(self): - for RDN_class in (RDN, EditableRDN): - rdn1 = RDN_class(self.rdn1) - rdn2 = RDN_class(self.rdn2) - rdn3 = RDN_class(self.rdn3) - - self.assertEqual(str(rdn1), self.str_rdn1) - self.assertIsInstance(str(rdn1), str) - - self.assertEqual(str(rdn2), self.str_rdn2) - self.assertIsInstance(str(rdn2), str) - - self.assertEqual(str(rdn3), self.str_rdn3) - self.assertIsInstance(str(rdn3), str) - - def test_cmp(self): - for RDN_class in (RDN, EditableRDN): - # Equality - rdn1 = RDN_class((self.attr1, self.value1)) - - self.assertTrue(rdn1 == self.rdn1) - self.assertFalse(rdn1 != self.rdn1) - - self.assertTrue(rdn1 == self.str_rdn1) - self.assertFalse(rdn1 != self.str_rdn1) - - result = cmp(rdn1, self.rdn1) - self.assertEqual(result, 0) - - # Make rdn1's attr greater - if RDN_class.is_mutable: - rdn1.attr = self.attr1 + "1" - else: - rdn1 = RDN_class((self.attr1 + "1", self.value1)) - - self.assertFalse(rdn1 == self.rdn1) - self.assertTrue(rdn1 != self.rdn1) - - result = cmp(rdn1, self.rdn1) - self.assertEqual(result, 1) - - result = cmp(self.rdn1, rdn1) - self.assertEqual(result, -1) - - # Reset rdn1's attr, should be equal again - if RDN_class.is_mutable: - rdn1.attr = self.attr1 - else: - rdn1 = RDN_class((self.attr1, self.value1)) - - result = cmp(rdn1, self.rdn1) - self.assertEqual(result, 0) - - # Make rdn1's value greater - # attr will be equal, this tests secondary comparision component - if RDN_class.is_mutable: - rdn1.value = self.value1 + "1" - else: - rdn1 = RDN_class((self.attr1, self.value1 + "1")) - - result = cmp(rdn1, self.rdn1) - self.assertEqual(result, 1) - - result = cmp(self.rdn1, rdn1) - self.assertEqual(result, -1) - - # Make sure rdn's with more ava's are greater - result = cmp(self.rdn1, self.rdn3) - self.assertEqual(result, -1) - result = cmp(self.rdn3, self.rdn1) - self.assertEqual(result, 1) - - def test_indexing(self): - for RDN_class in (RDN, EditableRDN): - rdn1 = RDN_class(self.rdn1) - rdn2 = RDN_class(self.rdn2) - rdn3 = RDN_class(self.rdn3) - - self.assertEqual(rdn1[0], self.ava1) - self.assertEqual(rdn1[self.ava1.attr], self.ava1.value) - with self.assertRaises(KeyError): - rdn1['foo'] - - self.assertEqual(rdn2[0], self.ava2) - self.assertEqual(rdn2[self.ava2.attr], self.ava2.value) - with self.assertRaises(KeyError): - rdn2['foo'] - - self.assertEqual(rdn3[0], self.ava1) - self.assertEqual(rdn3[self.ava1.attr], self.ava1.value) - self.assertEqual(rdn3[1], self.ava2) - self.assertEqual(rdn3[self.ava2.attr], self.ava2.value) - with self.assertRaises(KeyError): - rdn3['foo'] - - self.assertEqual(rdn1.attr, self.attr1) - self.assertEqual(rdn1.value, self.value1) - - with self.assertRaises(TypeError): - rdn3[1.0] - - # Slices - self.assertEqual(rdn3[0:1], [self.ava1]) - self.assertEqual(rdn3[:], [self.ava1, self.ava2]) - - def test_assignments(self): - for RDN_class in (RDN, EditableRDN): - rdn = RDN_class((self.attr1, self.value1)) - if RDN_class.is_mutable: - rdn[0] = self.ava2 - self.assertEqual(rdn, self.rdn2) - else: - with self.assertRaises(TypeError): - rdn[0] = self.ava2 - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - rdn = RDN_class((self.attr1, self.value1)) - if RDN_class.is_mutable: - rdn[0] = (self.attr2, self.value2) - self.assertEqual(rdn, self.rdn2) - else: - with self.assertRaises(TypeError): - rdn[0] = (self.attr2, self.value2) - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - rdn = RDN_class((self.attr1, self.value1)) - if RDN_class.is_mutable: - rdn[self.attr1] = self.str_ava2 - self.assertEqual(rdn[0], self.ava2) - else: - with self.assertRaises(TypeError): - rdn[self.attr1] = self.str_ava2 - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - # Can't assign multiples to single entry - rdn = RDN_class((self.attr1, self.value1)) - with self.assertRaises(TypeError): - rdn[self.attr1] = self.str_ava3 - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - rdn = RDN_class((self.attr1, self.value1)) - with self.assertRaises(TypeError): - rdn[self.attr1] = (self.attr1, self.value1, self.attr2, self.value2) - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - rdn = RDN_class((self.attr1, self.value1)) - with self.assertRaises(TypeError): - rdn[self.attr1] = [(self.attr1, self.value1), (self.attr2, self.value2)] - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - # Slices - rdn = RDN_class((self.attr1, self.value1)) - self.assertEqual(rdn, self.rdn1) - if RDN_class.is_mutable: - rdn[0:1] = [self.ava2] - self.assertEqual(rdn, self.rdn2) - else: - with self.assertRaises(TypeError): - rdn[0:1] = [self.ava2] - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - rdn = RDN_class((self.attr1, self.value1)) - self.assertEqual(rdn, self.rdn1) - if RDN_class.is_mutable: - rdn[:] = [(self.attr2, self.value2)] - self.assertEqual(rdn, self.rdn2) - else: - with self.assertRaises(TypeError): - rdn[:] = [(self.attr2, self.value2)] - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - rdn = RDN_class((self.attr1, self.value1)) - self.assertEqual(rdn, self.rdn1) - if RDN_class.is_mutable: - rdn[:] = [(self.attr1, self.value1),(self.attr2, self.value2)] - self.assertEqual(rdn, self.rdn3) - else: - with self.assertRaises(TypeError): - rdn[:] = [(self.attr1, self.value1),(self.attr2, self.value2)] - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - rdn = RDN_class((self.attr1, self.value1)) - self.assertEqual(rdn, self.rdn1) - if RDN_class.is_mutable: - rdn[0:1] = [(self.attr1, self.value1), (self.attr2, self.value2)] - self.assertEqual(rdn, self.rdn3) - else: - with self.assertRaises(TypeError): - rdn[0:1] = [(self.attr1, self.value1), (self.attr2, self.value2)] - self.assertExpectedClass(RDN_class, rdn, 'self') - for i in range(0, len(rdn)): - self.assertExpectedClass(RDN_class, rdn[i], 'AVA') - - - def test_iter(self): - for RDN_class in (RDN, EditableRDN): - rdn1 = RDN_class(self.rdn1) - rdn2 = RDN_class(self.rdn2) - rdn3 = RDN_class(self.rdn3) - - self.assertEqual(len(rdn1), 1) - self.assertEqual(rdn1[:], [self.ava1]) - for i, ava in enumerate(rdn1): - if i == 0: - self.assertEqual(ava, self.ava1) - else: - self.fail("got iteration index %d, but len=%d" % (i, len(rdn1))) - - self.assertEqual(len(rdn2), 1) - self.assertEqual(rdn2[:], [self.ava2]) - for i, ava in enumerate(rdn2): - if i == 0: - self.assertEqual(ava, self.ava2) - else: - self.fail("got iteration index %d, but len=%d" % (i, len(rdn2))) - - self.assertEqual(len(rdn3), 2) - self.assertEqual(rdn3[:], [self.ava1, self.ava2]) - for i, ava in enumerate(rdn3): - if i == 0: - self.assertEqual(ava, self.ava1) - elif i == 1: - self.assertEqual(ava, self.ava2) - else: - self.fail("got iteration index %d, but len=%d" % (i, len(rdn3))) - - - def test_concat(self): - for RDN_class in (RDN, EditableRDN): - rdn1 = RDN_class((self.attr1, self.value1)) - rdn2 = RDN_class((self.attr2, self.value2)) - - # in-place addtion - - # Note: If __iadd__ is not available Python will emulate += by - # replacing the lhs object with the result of __add__ (if available). - # Thus += works for both immutable and mutable RDN,DN object, the only - # difference is an immutable without __iadd__ will have a different object - # on the lhs after the operator evaluates. - - rdn1 += rdn2 - self.assertEqual(rdn1, self.rdn3) - self.assertExpectedClass(RDN_class, rdn1, 'self') - for i in range(0, len(rdn1)): - self.assertExpectedClass(RDN_class, rdn1[i], 'AVA') - - rdn1 = RDN_class((self.attr1, self.value1)) - rdn1 += self.ava2 - self.assertEqual(rdn1, self.rdn3) - self.assertExpectedClass(RDN_class, rdn1, 'self') - for i in range(0, len(rdn1)): - self.assertExpectedClass(RDN_class, rdn1[i], 'AVA') - - rdn1 = RDN_class((self.attr1, self.value1)) - rdn1 += self.str_ava2 - self.assertEqual(rdn1, self.rdn3) - self.assertExpectedClass(RDN_class, rdn1, 'self') - for i in range(0, len(rdn1)): - self.assertExpectedClass(RDN_class, rdn1[i], 'AVA') - - # concatenation - rdn1 = RDN_class((self.attr1, self.value1)) - rdn3 = rdn1 + rdn2 - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - - rdn3 = rdn1 + self.ava2 - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - - rdn3 = rdn1 + self.str_ava2 - self.assertEqual(rdn3, self.rdn3) - self.assertExpectedClass(RDN_class, rdn3, 'self') - for i in range(0, len(rdn3)): - self.assertExpectedClass(RDN_class, rdn3[i], 'AVA') - - - def test_hashing(self): - # create RDN's that are equal but differ in case - immutable_rdn1 = RDN((self.attr1.lower(), self.value1.upper())) - immutable_rdn2 = RDN((self.attr1.upper(), self.value1.lower())) - - mutable_rdn1 = EditableRDN((self.attr1.lower(), self.value1.upper())) - mutable_rdn2 = EditableRDN((self.attr1.upper(), self.value1.lower())) - - # Immutable RDN's that are equal should hash to the same value. - # Mutable RDN's should not be hashable. - - self.assertEqual(immutable_rdn1, immutable_rdn2) - self.assertEqual(immutable_rdn1, mutable_rdn1) - self.assertEqual(immutable_rdn1, mutable_rdn2) - self.assertEqual(mutable_rdn1, immutable_rdn2) - - # Good, everyone's equal, now verify their hash values - - self.assertEqual(hash(immutable_rdn1), hash(immutable_rdn2)) - with self.assertRaises(TypeError): - hash(mutable_rdn1) - with self.assertRaises(TypeError): - hash(mutable_rdn2) - - def test_coerce(self): - # Coerce an immutable to a mutable - immutable_rdn3 = RDN(self.rdn3) - mutable_rdn3 = EditableRDN(immutable_rdn3) - self.assertEqual(mutable_rdn3, self.rdn3) - self.assertEqual(mutable_rdn3, immutable_rdn3) - - # Coerce a mutable to an immutable - mutable_rdn3 = EditableRDN(self.rdn3) - immutable_rdn3 = RDN(mutable_rdn3) - self.assertEqual(immutable_rdn3, self.rdn3) - self.assertEqual(immutable_rdn3, mutable_rdn3) - -class TestDN(unittest.TestCase): - def setUp(self): - # ava1 must sort before ava2 - self.attr1 = 'cn' - self.value1 = 'Bob' - self.str_ava1 = '%s=%s' % (self.attr1, self.value1) - self.ava1 = AVA(self.attr1, self.value1) - - self.str_rdn1 = '%s=%s' % (self.attr1, self.value1) - self.rdn1 = RDN((self.attr1, self.value1)) - - self.attr2 = 'ou' - self.value2 = 'people' - self.str_ava2 = '%s=%s' % (self.attr2, self.value2) - self.ava2 = AVA(self.attr2, self.value2) - - self.str_rdn2 = '%s=%s' % (self.attr2, self.value2) - self.rdn2 = RDN((self.attr2, self.value2)) - - self.str_dn1 = self.str_rdn1 - self.dn1 = DN(self.rdn1) - - self.str_dn2 = self.str_rdn2 - self.dn2 = DN(self.rdn2) - - self.str_dn3 = '%s,%s' % (self.str_rdn1, self.str_rdn2) - self.dn3 = DN(self.rdn1, self.rdn2) - - self.base_rdn1 = RDN(('dc', 'redhat')) - self.base_rdn2 = RDN(('dc', 'com')) - self.base_dn = DN(self.base_rdn1, self.base_rdn2) - - self.container_rdn1 = RDN(('cn', 'sudorules')) - self.container_rdn2 = RDN(('cn', 'sudo')) - self.container_dn = DN(self.container_rdn1, self.container_rdn2) - - self.base_container_dn = DN((self.attr1, self.value1), - self.container_dn, self.base_dn) - - - def assertExpectedClass(self, klass, obj, component): - self.assertIs(obj.__class__, expected_class(klass, component)) - - def test_create(self): - for DN_class in (DN, EditableDN): - # Create with single attr,value pair - dn1 = DN_class((self.attr1, self.value1)) - self.assertEqual(len(dn1), 1) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[0].attr, unicode) - self.assertIsInstance(dn1[0].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - - # Create with single attr,value pair passed as a tuple - dn1 = DN_class((self.attr1, self.value1)) - self.assertEqual(len(dn1), 1) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - - # Creation with multiple attr,value string pairs should fail - with self.assertRaises(ValueError): - dn1 = DN_class(self.attr1, self.value1, self.attr2, self.value2) - - # Create with multiple attr,value pairs passed as tuples & lists - dn1 = DN_class((self.attr1, self.value1), [self.attr2, self.value2]) - self.assertEqual(len(dn1), 2) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - self.assertEqual(dn1[1], self.rdn2) - - # Create with multiple attr,value pairs passed as tuple and RDN - dn1 = DN_class((self.attr1, self.value1), RDN((self.attr2, self.value2))) - self.assertEqual(len(dn1), 2) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - self.assertEqual(dn1[1], self.rdn2) - - # Create with multiple attr,value pairs but reverse - # constructor parameter ordering. RDN ordering should also be - # reversed because DN's are a ordered sequence of RDN's - dn1 = DN_class((self.attr2, self.value2), (self.attr1, self.value1)) - self.assertEqual(len(dn1), 2) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn2) - self.assertEqual(dn1[1], self.rdn1) - - # Create with single RDN object - dn1 = DN_class(self.rdn1) - self.assertEqual(len(dn1), 1) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - - # Create with multiple RDN objects, assure ordering is preserved. - dn1 = DN_class(self.rdn1, self.rdn2) - self.assertEqual(len(dn1), 2) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - self.assertEqual(dn1[1], self.rdn2) - - # Create with multiple RDN objects in different order, assure - # ordering is preserved. - dn1 = DN_class(self.rdn2, self.rdn1) - self.assertEqual(len(dn1), 2) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn2) - self.assertEqual(dn1[1], self.rdn1) - - # Create with single string with 1 RDN - dn1 = DN_class(self.str_rdn1) - self.assertEqual(len(dn1), 1) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - - # Create with single string with 2 RDN's - dn1 = DN_class(self.str_dn3) - self.assertEqual(len(dn1), 2) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - self.assertIsInstance(dn1[i].attr, unicode) - self.assertIsInstance(dn1[i].value, unicode) - self.assertEqual(dn1[0], self.rdn1) - self.assertEqual(dn1[1], self.rdn2) - - # Create with RDN, and 2 DN's (e.g. attr + container + base) - dn1 = DN_class((self.attr1, self.value1), self.container_dn, self.base_dn) - self.assertEqual(len(dn1), 5) - dn_str = ','.join([str(self.rdn1), - str(self.container_rdn1), str(self.container_rdn2), - str(self.base_rdn1), str(self.base_rdn2)]) - self.assertEqual(str(dn1), dn_str) - - def test_str(self): - for DN_class in (DN, EditableDN): - dn1 = DN_class(self.dn1) - dn2 = DN_class(self.dn2) - dn3 = DN_class(self.dn3) - - self.assertEqual(str(dn1), self.str_dn1) - self.assertIsInstance(str(dn1), str) - - self.assertEqual(str(dn2), self.str_dn2) - self.assertIsInstance(str(dn2), str) - - self.assertEqual(str(dn3), self.str_dn3) - self.assertIsInstance(str(dn3), str) - - def test_cmp(self): - for DN_class in (DN, EditableDN): - # Equality - dn1 = DN_class((self.attr1, self.value1)) - - self.assertTrue(dn1 == self.dn1) - self.assertFalse(dn1 != self.dn1) - - self.assertTrue(dn1 == self.str_dn1) - self.assertFalse(dn1 != self.str_dn1) - - result = cmp(dn1, self.dn1) - self.assertEqual(result, 0) - - # Make dn1's attr greater - if DN_class.is_mutable: - dn1[0].attr = self.attr1 + "1" - else: - with self.assertRaises(AttributeError): - dn1[0].attr = self.attr1 + "1" - dn1 = DN_class((self.attr1 + "1", self.value1)) - - self.assertFalse(dn1 == self.dn1) - self.assertTrue(dn1 != self.dn1) - - result = cmp(dn1, self.dn1) - self.assertEqual(result, 1) - - result = cmp(self.dn1, dn1) - self.assertEqual(result, -1) - - # Reset dn1's attr, should be equal again - if DN_class.is_mutable: - dn1[0].attr = self.attr1 - else: - with self.assertRaises(AttributeError): - dn1[0].attr = self.attr1 - dn1 = DN_class((self.attr1, self.value1)) - - result = cmp(dn1, self.dn1) - self.assertEqual(result, 0) - - # Make dn1's value greater - # attr will be equal, this tests secondary comparision component - if DN_class.is_mutable: - dn1[0].value = self.value1 + "1" - else: - with self.assertRaises(AttributeError): - dn1[0].value = self.value1 + "1" - dn1 = DN_class((self.attr1, self.value1 + "1")) - - result = cmp(dn1, self.dn1) - self.assertEqual(result, 1) - - result = cmp(self.dn1, dn1) - self.assertEqual(result, -1) - - # Make sure dn's with more rdn's are greater - result = cmp(self.dn1, self.dn3) - self.assertEqual(result, -1) - result = cmp(self.dn3, self.dn1) - self.assertEqual(result, 1) - - - # Test startswith, endswith - container_dn = DN_class(self.container_dn) - base_container_dn = DN_class(self.base_container_dn) - - self.assertTrue(base_container_dn.startswith(self.rdn1)) - self.assertTrue(base_container_dn.startswith(self.dn1)) - self.assertTrue(base_container_dn.startswith(self.dn1 + container_dn)) - self.assertFalse(base_container_dn.startswith(self.dn2)) - self.assertFalse(base_container_dn.startswith(self.rdn2)) - self.assertTrue(base_container_dn.startswith((self.dn1))) - self.assertTrue(base_container_dn.startswith((self.rdn1))) - self.assertFalse(base_container_dn.startswith((self.rdn2))) - self.assertTrue(base_container_dn.startswith((self.rdn2, self.rdn1))) - self.assertTrue(base_container_dn.startswith((self.dn1, self.dn2))) - - self.assertTrue(base_container_dn.endswith(self.base_dn)) - self.assertTrue(base_container_dn.endswith(container_dn + self.base_dn)) - self.assertFalse(base_container_dn.endswith(DN(self.base_rdn1))) - self.assertTrue(base_container_dn.endswith(DN(self.base_rdn2))) - self.assertTrue(base_container_dn.endswith((DN(self.base_rdn1), DN(self.base_rdn2)))) - - # Test "in" membership - self.assertTrue(self.container_rdn1 in container_dn) - self.assertTrue(container_dn in container_dn) - self.assertFalse(self.base_rdn1 in container_dn) - - self.assertTrue(self.container_rdn1 in base_container_dn) - self.assertTrue(container_dn in base_container_dn) - self.assertTrue(container_dn + self.base_dn in - base_container_dn) - self.assertTrue(self.dn1 + container_dn + self.base_dn in - base_container_dn) - self.assertTrue(self.dn1 + container_dn + self.base_dn == - base_container_dn) - - self.assertFalse(self.container_rdn1 in self.base_dn) - - def test_indexing(self): - for DN_class in (DN, EditableDN): - dn1 = DN_class(self.dn1) - dn2 = DN_class(self.dn2) - dn3 = DN_class(self.dn3) - - self.assertEqual(dn1[0], self.rdn1) - self.assertEqual(dn1[self.rdn1.attr], self.rdn1.value) - with self.assertRaises(KeyError): - dn1['foo'] - - self.assertEqual(dn2[0], self.rdn2) - self.assertEqual(dn2[self.rdn2.attr], self.rdn2.value) - with self.assertRaises(KeyError): - dn2['foo'] - - self.assertEqual(dn3[0], self.rdn1) - self.assertEqual(dn3[self.rdn1.attr], self.rdn1.value) - self.assertEqual(dn3[1], self.rdn2) - self.assertEqual(dn3[self.rdn2.attr], self.rdn2.value) - with self.assertRaises(KeyError): - dn3['foo'] - - with self.assertRaises(TypeError): - dn3[1.0] - - def test_assignments(self): - for DN_class in (DN, EditableDN): - dn_low = 0 - dn_high = 6 - - rdn_args = make_rdn_args(dn_low, dn_high, 'tuple', - default_rdn_attr_arg, default_rdn_value_arg) - dn1 = DN_class(*rdn_args) - - rdn_args = make_rdn_args(dn_low, dn_high, 'list', - default_rdn_attr_arg, default_rdn_value_arg) - dn2 = DN_class(*rdn_args) - - rdn_args = make_rdn_args(dn_low, dn_high, 'RDN', - default_rdn_attr_arg, default_rdn_value_arg) - dn3 = DN_class(*rdn_args) - - self.assertEqual(dn1, dn2) - self.assertEqual(dn1, dn3) - - for i in range(dn_low, dn_high): - attr = default_rdn_attr_arg(i) - value = default_rdn_value_arg(i) - - self.assertEqual(dn1[i].attr, attr) - self.assertEqual(dn1[i].value, value) - self.assertEqual(dn1[attr], value) - self.assertExpectedClass(DN_class, dn1, 'self') - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - - self.assertEqual(dn2[i].attr, attr) - self.assertEqual(dn2[i].value, value) - self.assertEqual(dn2[attr], value) - self.assertExpectedClass(DN_class, dn2, 'self') - self.assertExpectedClass(DN_class, dn2[i], 'RDN') - for j in range(0, len(dn2[i])): - self.assertExpectedClass(DN_class, dn2[i][j], 'AVA') - - self.assertEqual(dn3[i].attr, attr) - self.assertEqual(dn3[i].value, value) - self.assertEqual(dn3[attr], value) - self.assertExpectedClass(DN_class, dn3, 'self') - self.assertExpectedClass(DN_class, dn3[i], 'RDN') - for j in range(0, len(dn3[i])): - self.assertExpectedClass(DN_class, dn3[i][j], 'AVA') - - - for i in range(dn_low, dn_high): - if i % 2: - orig_attr = default_rdn_attr_arg(i) - attr = alt_rdn_attr_arg(i) - value = alt_rdn_value_arg(i) - - if DN_class.is_mutable: - dn1[i] = attr, value - else: - with self.assertRaises(TypeError): - dn1[i] = attr, value - - if DN_class.is_mutable: - dn2[orig_attr] = (attr, value) - else: - with self.assertRaises(TypeError): - dn2[orig_attr] = (attr, value) - - if DN_class.is_mutable: - dn3[i] = RDN((attr, value)) - else: - with self.assertRaises(TypeError): - dn3[i] = RDN((attr, value)) - - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - - self.assertExpectedClass(DN_class, dn2, 'self') - for i in range(0, len(dn2)): - self.assertExpectedClass(DN_class, dn2[i], 'RDN') - for j in range(0, len(dn2[i])): - self.assertExpectedClass(DN_class, dn2[i][j], 'AVA') - - self.assertExpectedClass(DN_class, dn3, 'self') - for i in range(0, len(dn3)): - self.assertExpectedClass(DN_class, dn3[i], 'RDN') - for j in range(0, len(dn3[i])): - self.assertExpectedClass(DN_class, dn3[i][j], 'AVA') - - - if DN_class.is_mutable: - self.assertEqual(dn1, dn2) - self.assertEqual(dn1, dn3) - - for i in range(dn_low, dn_high): - if i % 2: - attr = alt_rdn_attr_arg(i) - value = alt_rdn_value_arg(i) - else: - attr = default_rdn_attr_arg(i) - value = default_rdn_value_arg(i) - self.assertEqual(dn1[i].attr, attr) - self.assertEqual(dn1[i].value, value) - self.assertEqual(dn1[attr], value) - - # Slices - slice_low = 2 - slice_high = 4 - slice_interval = range(slice_low, slice_high) - - # Slices - # Assign via tuple - rdn_args = make_rdn_args(dn_low, dn_high, 'tuple', - default_rdn_attr_arg, default_rdn_value_arg) - dn = DN_class(*rdn_args) - - dn_slice = make_rdn_args(slice_low, slice_high, 'tuple', - alt_rdn_attr_arg, alt_rdn_value_arg) - - if DN_class.is_mutable: - dn[slice_low:slice_high] = dn_slice - for i in range(dn_low, dn_high): - if i in slice_interval: - attr = alt_rdn_attr_arg(i) - value = alt_rdn_value_arg(i) - else: - attr = default_rdn_attr_arg(i) - value = default_rdn_value_arg(i) - self.assertEqual(dn[i].attr, attr) - self.assertEqual(dn[i].value, value) - self.assertEqual(dn[attr], value) - - query_slice = dn[slice_low:slice_high] - for i, query_rdn in enumerate(query_slice): - slice_rdn = RDN(dn_slice[i]) - self.assertEqual(slice_rdn, query_rdn) - else: - with self.assertRaises(TypeError): - dn[slice_low:slice_high] = dn_slice - - - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - # insert - dn = DN_class(self.rdn2) - - if DN_class.is_mutable: - dn.insert(0, self.rdn1) - self.assertEqual(dn, self.dn3) - else: - with self.assertRaises(AttributeError): - dn.insert(0, self.rdn1) - - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - dn = DN_class(self.rdn1) - - if DN_class.is_mutable: - dn.insert(1, (self.attr2, self.value2)) - self.assertEqual(dn, self.dn3) - else: - with self.assertRaises(AttributeError): - dn.insert(1, (self.attr2, self.value2)) - - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - # Slices - # Assign via RDN - rdn_args = make_rdn_args(dn_low, dn_high, 'tuple', - default_rdn_attr_arg, default_rdn_value_arg) - dn = DN_class(*rdn_args) - - dn_slice = make_rdn_args(slice_low, slice_high, 'RDN', - alt_rdn_attr_arg, alt_rdn_value_arg) - - if DN_class.is_mutable: - dn[slice_low:slice_high] = dn_slice - for i in range(dn_low, dn_high): - if i in slice_interval: - attr = alt_rdn_attr_arg(i) - value = alt_rdn_value_arg(i) - else: - attr = default_rdn_attr_arg(i) - value = default_rdn_value_arg(i) - self.assertEqual(dn[i].value, value) - self.assertEqual(dn[attr], value) - - query_slice = dn[slice_low:slice_high] - for i, query_rdn in enumerate(query_slice): - slice_rdn = dn_slice[i] - self.assertEqual(slice_rdn, query_rdn) - else: - with self.assertRaises(TypeError): - dn[slice_low:slice_high] = dn_slice - - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - def test_iter(self): - for DN_class in (DN, EditableDN): - dn1 = DN_class(self.dn1) - dn2 = DN_class(self.dn2) - dn3 = DN_class(self.dn3) - - self.assertEqual(len(dn1), 1) - self.assertEqual(dn1[:], [self.rdn1]) - for i, ava in enumerate(dn1): - if i == 0: - self.assertEqual(ava, self.rdn1) - else: - self.fail("got iteration index %d, but len=%d" % (i, len(self.rdn1))) - - self.assertEqual(len(dn2), 1) - self.assertEqual(dn2[:], [self.rdn2]) - for i, ava in enumerate(dn2): - if i == 0: - self.assertEqual(ava, self.rdn2) - else: - self.fail("got iteration index %d, but len=%d" % (i, len(self.rdn2))) - - self.assertEqual(len(dn3), 2) - self.assertEqual(dn3[:], [self.rdn1, self.rdn2]) - for i, ava in enumerate(dn3): - if i == 0: - self.assertEqual(ava, self.rdn1) - elif i == 1: - self.assertEqual(ava, self.rdn2) - else: - self.fail("got iteration index %d, but len=%d" % (i, len(dn3))) - - - def test_concat(self): - for DN_class in (DN, EditableDN): - dn1 = DN_class((self.attr1, self.value1)) - dn2 = DN_class([self.attr2, self.value2]) - - # in-place addtion - - # Note: If __iadd__ is not available Python will emulate += by - # replacing the lhs object with the result of __add__ (if available). - # Thus += works for both immutable and mutable RDN,DN object, the only - # difference is an immutable without __iadd__ will have a different object - # on the lhs after the operator evaluates. - - dn1 += dn2 - self.assertEqual(dn1, self.dn3) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - - - dn1 = DN_class((self.attr1, self.value1)) - dn1 += self.rdn2 - self.assertEqual(dn1, self.dn3) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - - - dn1 = DN_class((self.attr1, self.value1)) - dn1 += self.dn2 - self.assertEqual(dn1, self.dn3) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - - - dn1 = DN_class((self.attr1, self.value1)) - dn1 += self.str_dn2 - self.assertEqual(dn1, self.dn3) - self.assertExpectedClass(DN_class, dn1, 'self') - for i in range(0, len(dn1)): - self.assertExpectedClass(DN_class, dn1[i], 'RDN') - for j in range(0, len(dn1[i])): - self.assertExpectedClass(DN_class, dn1[i][j], 'AVA') - - - # concatenation - dn1 = DN_class((self.attr1, self.value1)) - dn3 = dn1 + dn2 - self.assertEqual(dn3, self.dn3) - self.assertExpectedClass(DN_class, dn3, 'self') - for i in range(0, len(dn3)): - self.assertExpectedClass(DN_class, dn3[i], 'RDN') - for j in range(0, len(dn3[i])): - self.assertExpectedClass(DN_class, dn3[i][j], 'AVA') - - - dn1 = DN_class((self.attr1, self.value1)) - dn3 = dn1 + self.rdn2 - self.assertEqual(dn3, self.dn3) - self.assertExpectedClass(DN_class, dn3, 'self') - for i in range(0, len(dn3)): - self.assertExpectedClass(DN_class, dn3[i], 'RDN') - for j in range(0, len(dn3[i])): - self.assertExpectedClass(DN_class, dn3[i][j], 'AVA') - - dn3 = dn1 + self.str_rdn2 - self.assertEqual(dn3, self.dn3) - self.assertExpectedClass(DN_class, dn3, 'self') - for i in range(0, len(dn3)): - self.assertExpectedClass(DN_class, dn3[i], 'RDN') - self.assertExpectedClass(DN_class, dn3[i][0], 'AVA') - - dn3 = dn1 + self.str_dn2 - self.assertEqual(dn3, self.dn3) - self.assertExpectedClass(DN_class, dn3, 'self') - self.assertExpectedClass(DN_class, dn3, 'self') - for i in range(0, len(dn3)): - self.assertExpectedClass(DN_class, dn3[i], 'RDN') - for j in range(0, len(dn3[i])): - self.assertExpectedClass(DN_class, dn3[i][j], 'AVA') - - dn3 = dn1 + self.dn2 - self.assertEqual(dn3, self.dn3) - self.assertExpectedClass(DN_class, dn3, 'self') - self.assertExpectedClass(DN_class, dn3, 'self') - for i in range(0, len(dn3)): - self.assertExpectedClass(DN_class, dn3[i], 'RDN') - for j in range(0, len(dn3[i])): - self.assertExpectedClass(DN_class, dn3[i][j], 'AVA') - - def test_find(self): - for DN_class in (DN, EditableDN): - # -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 - dn = DN_class('t=0,t=1,cn=bob,t=3,t=4,t=5,cn=bob,t=7,t=8,t=9') - pat = DN_class('cn=bob') - - # forward - self.assertEqual(dn.find(pat), 2) - self.assertEqual(dn.find(pat, 1), 2) - self.assertEqual(dn.find(pat, 1, 3), 2) - self.assertEqual(dn.find(pat, 2, 3), 2) - self.assertEqual(dn.find(pat, 6), 6) - - self.assertEqual(dn.find(pat, 7), -1) - self.assertEqual(dn.find(pat, 1, 2), -1) - - with self.assertRaises(ValueError): - self.assertEqual(dn.index(pat, 7), -1) - with self.assertRaises(ValueError): - self.assertEqual(dn.index(pat, 1, 2), -1) - - # reverse - self.assertEqual(dn.rfind(pat), 6) - self.assertEqual(dn.rfind(pat, -4), 6) - self.assertEqual(dn.rfind(pat, 6), 6) - self.assertEqual(dn.rfind(pat, 6, 8), 6) - self.assertEqual(dn.rfind(pat, 6, 8), 6) - self.assertEqual(dn.rfind(pat, -8), 6) - self.assertEqual(dn.rfind(pat, -8, -4), 6) - self.assertEqual(dn.rfind(pat, -8, -5), 2) - - self.assertEqual(dn.rfind(pat, 7), -1) - self.assertEqual(dn.rfind(pat, -3), -1) - - with self.assertRaises(ValueError): - self.assertEqual(dn.rindex(pat, 7), -1) - with self.assertRaises(ValueError): - self.assertEqual(dn.rindex(pat, -3), -1) - - - def test_replace(self): - for DN_class in (DN, EditableDN): - dn = DN_class('t=0,t=1,t=2,t=3,t=4,t=5,t=6,t=7,t=8,t=9') - pat = DN('cn=bob') - replacement = DN('cn=bob') - - if DN_class.is_mutable: - n_replaced = dn.replace(pat, replacement) - self.assertEqual(n_replaced, 0) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - pat = DN('t=2') - if DN_class.is_mutable: - expected_dn = DN('t=0,t=1,cn=bob,t=3,t=4,t=5,t=6,t=7,t=8,t=9') - n_replaced = dn.replace(pat, replacement) - self.assertEqual(n_replaced, 1) - self.assertEqual(dn, expected_dn) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - dn = DN_class('t=0,t=1,t=2,t=3,t=4,t=5,t=6,t=7,t=2,t=9') - if DN_class.is_mutable: - expected_dn = DN('t=0,t=1,cn=bob,t=3,t=4,t=5,t=6,t=7,t=2,t=9') - n_replaced = dn.replace(pat, replacement, 1) - self.assertEqual(n_replaced, 1) - self.assertEqual(dn, expected_dn) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement, 1) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - dn = DN_class('t=0,t=1,t=2,t=3,t=4,t=5,t=6,t=7,t=2,t=9') - if DN_class.is_mutable: - expected_dn = DN('t=0,t=1,cn=bob,t=3,t=4,t=5,t=6,t=7,t=2,t=9') - n_replaced = dn.replace(pat, replacement, 1) - self.assertEqual(n_replaced, 1) - self.assertEqual(dn, expected_dn) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement, 1) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - replacement = DN('cn=bob,ou=people') - - dn = DN_class('t=0,t=1,t=2,t=3,t=4,t=5,t=6,t=7,t=2,t=9') - if DN_class.is_mutable: - expected_dn = DN('t=0,t=1,cn=bob,ou=people,t=3,t=4,t=5,t=6,t=7,t=2,t=9') - n_replaced = dn.replace(pat, replacement, 1) - self.assertEqual(n_replaced, 1) - self.assertEqual(dn, expected_dn) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement, 1) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - dn = DN_class('t=0,t=1,t=2,t=3,t=4,t=5,t=6,t=7,t=2,t=9') - if DN_class.is_mutable: - expected_dn = DN('t=0,t=1,cn=bob,ou=people,t=3,t=4,t=5,t=6,t=7,cn=bob,ou=people,t=9') - n_replaced = dn.replace(pat, replacement) - self.assertEqual(n_replaced, 2) - self.assertEqual(dn, expected_dn) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - pat = DN('t=3,t=4') - replacement = DN('cn=bob') - dn = DN_class('t=0,t=1,t=2,t=3,t=4,t=5,t=6,t=7,t=8,t=9') - if DN_class.is_mutable: - expected_dn = DN('t=0,t=1,t=2,cn=bob,t=5,t=6,t=7,t=8,t=9') - n_replaced = dn.replace(pat, replacement) - self.assertEqual(n_replaced, 1) - self.assertEqual(dn, expected_dn) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - pat = DN('t=3,t=4') - replacement = DN('cn=bob,ou=people') - dn = DN_class('t=0,t=1,t=2,t=3,t=4,t=5,t=6,t=7,t=8,t=9') - if DN_class.is_mutable: - expected_dn = DN('t=0,t=1,t=2,cn=bob,ou=people,t=5,t=6,t=7,t=8,t=9') - n_replaced = dn.replace(pat, replacement) - self.assertEqual(n_replaced, 1) - self.assertEqual(dn, expected_dn) - else: - with self.assertRaises(AttributeError): - n_replaced = dn.replace(pat, replacement) - self.assertExpectedClass(DN_class, dn, 'self') - for i in range(0, len(dn)): - self.assertExpectedClass(DN_class, dn[i], 'RDN') - for j in range(0, len(dn[i])): - self.assertExpectedClass(DN_class, dn[i][j], 'AVA') - - def test_hashing(self): - # create DN's that are equal but differ in case - immutable_dn1 = DN((self.attr1.lower(), self.value1.upper())) - immutable_dn2 = DN((self.attr1.upper(), self.value1.lower())) - - mutable_dn1 = EditableDN((self.attr1.lower(), self.value1.upper())) - mutable_dn2 = EditableDN((self.attr1.upper(), self.value1.lower())) - - # Immutable DN's that are equal should hash to the same value. - # Mutable DN's should not be hashable. - - self.assertEqual(immutable_dn1, immutable_dn2) - self.assertEqual(immutable_dn1, mutable_dn1) - self.assertEqual(immutable_dn1, mutable_dn2) - self.assertEqual(mutable_dn1, immutable_dn2) - - # Good, everyone's equal, now verify their hash values - - self.assertEqual(hash(immutable_dn1), hash(immutable_dn2)) - with self.assertRaises(TypeError): - hash(mutable_dn1) - with self.assertRaises(TypeError): - hash(mutable_dn2) - - # Different immutable DN objects with the same value should - # map to 1 common key and 1 member in a set. The key and - # member are based on the object's value. - # - # Mutable DN objects should be unhashable. - - for DN_class in (DN, EditableDN): - dn1_a = DN_class(self.dn1) - dn1_b = DN_class(self.dn1) - - dn2_a = DN_class(self.dn2) - dn2_b = DN_class(self.dn2) - - dn3_a = DN_class(self.dn3) - dn3_b = DN_class(self.dn3) - - self.assertEqual(dn1_a, dn1_b) - self.assertEqual(dn2_a, dn2_b) - self.assertEqual(dn3_a, dn3_b) - - d = dict() - s = set() - - if DN_class.is_mutable: - with self.assertRaises(TypeError): - d[dn1_a] = str(dn1_a) - with self.assertRaises(TypeError): - d[dn1_b] = str(dn1_b) - with self.assertRaises(TypeError): - d[dn2_a] = str(dn2_a) - with self.assertRaises(TypeError): - d[dn2_b] = str(dn2_b) - - with self.assertRaises(TypeError): - s.add(dn1_a) - with self.assertRaises(TypeError): - s.add(dn1_b) - with self.assertRaises(TypeError): - s.add(dn2_a) - with self.assertRaises(TypeError): - s.add(dn2_b) - else: - d[dn1_a] = str(dn1_a) - d[dn1_b] = str(dn1_b) - d[dn2_a] = str(dn2_a) - d[dn2_b] = str(dn2_b) - - s.add(dn1_a) - s.add(dn1_b) - s.add(dn2_a) - s.add(dn2_b) - - self.assertEqual(len(d), 2) - self.assertEqual(len(s), 2) - self.assertEqual(sorted(d.keys()), sorted([dn1_a, dn2_a])) - self.assertEqual(sorted(s), sorted([dn1_a, dn2_a])) - - self.assertTrue(dn1_a in d) - self.assertTrue(dn1_b in d) - self.assertTrue(dn2_a in d) - self.assertTrue(dn2_b in d) - self.assertFalse(dn3_a in d) - self.assertFalse(dn3_b in d) - - self.assertTrue(d.has_key(dn1_a)) - self.assertTrue(d.has_key(dn1_b)) - self.assertTrue(d.has_key(dn2_a)) - self.assertTrue(d.has_key(dn2_b)) - self.assertFalse(d.has_key(dn3_a)) - self.assertFalse(d.has_key(dn3_b)) - - self.assertTrue(dn1_a in s) - self.assertTrue(dn1_b in s) - self.assertTrue(dn2_a in s) - self.assertTrue(dn2_b in s) - self.assertFalse(dn3_a in s) - self.assertFalse(dn3_b in s) - - def test_coerce(self): - # Coerce an immutable to a mutable - immutable_dn3 = DN(self.dn3) - mutable_dn3 = EditableDN(immutable_dn3) - self.assertEqual(mutable_dn3, self.dn3) - self.assertEqual(mutable_dn3, immutable_dn3) - - # Coerce a mutable to an immutable - mutable_dn3 = EditableDN(self.dn3) - immutable_dn3 = DN(mutable_dn3) - self.assertEqual(immutable_dn3, self.dn3) - self.assertEqual(immutable_dn3, mutable_dn3) - -class TestEscapes(unittest.TestCase): - def setUp(self): - self.privilege = 'R,W privilege' - self.dn_str_hex_escape = 'cn=R\\2cW privilege,cn=privileges,cn=pbac,dc=idm,dc=lab,dc=bos,dc=redhat,dc=com' - self.dn_str_backslash_escape = 'cn=R\\,W privilege,cn=privileges,cn=pbac,dc=idm,dc=lab,dc=bos,dc=redhat,dc=com' - - def test_escape(self): - for DN_class in (DN, EditableDN): - dn = DN_class(self.dn_str_hex_escape) - self.assertEqual(dn['cn'], self.privilege) - self.assertEqual(dn[0].value, self.privilege) - - dn = DN_class(self.dn_str_backslash_escape) - self.assertEqual(dn['cn'], self.privilege) - self.assertEqual(dn[0].value, self.privilege) - -class TestInternationalization(unittest.TestCase): - def setUp(self): - # Hello in Arabic - self.arabic_hello_utf8 = '\xd9\x85\xd9\x83\xd9\x8a\xd9\x84' + \ - '\xd8\xb9\x20\xd9\x85\xd8\xa7\xd9' + \ - '\x84\xd9\x91\xd8\xb3\xd9\x84\xd8\xa7' - - self.arabic_hello_unicode = self.arabic_hello_utf8.decode('utf-8') - - def test_i18n(self): - self.assertEqual(self.arabic_hello_utf8, - self.arabic_hello_unicode.encode('utf-8')) - - # AVA's - # test attr i18n - for AVA_class in (AVA, EditableAVA): - ava1 = AVA_class(self.arabic_hello_unicode, 'foo') - self.assertIsInstance(ava1.attr, unicode) - self.assertIsInstance(ava1.value, unicode) - self.assertEqual(ava1.attr, self.arabic_hello_unicode) - self.assertEqual(str(ava1), self.arabic_hello_utf8+'=foo') - - ava1 = AVA_class(self.arabic_hello_utf8, 'foo') - self.assertIsInstance(ava1.attr, unicode) - self.assertIsInstance(ava1.value, unicode) - self.assertEqual(ava1.attr, self.arabic_hello_unicode) - self.assertEqual(str(ava1), self.arabic_hello_utf8+'=foo') - - # test value i18n - ava1 = AVA_class('cn', self.arabic_hello_unicode) - self.assertIsInstance(ava1.attr, unicode) - self.assertIsInstance(ava1.value, unicode) - self.assertEqual(ava1.value, self.arabic_hello_unicode) - self.assertEqual(str(ava1), 'cn='+self.arabic_hello_utf8) - - ava1 = AVA_class('cn', self.arabic_hello_utf8) - self.assertIsInstance(ava1.attr, unicode) - self.assertIsInstance(ava1.value, unicode) - self.assertEqual(ava1.value, self.arabic_hello_unicode) - self.assertEqual(str(ava1), 'cn='+self.arabic_hello_utf8) - - # RDN's - # test attr i18n - for RDN_class in (RDN, EditableRDN): - rdn1 = RDN_class((self.arabic_hello_unicode, 'foo')) - self.assertIsInstance(rdn1.attr, unicode) - self.assertIsInstance(rdn1.value, unicode) - self.assertEqual(rdn1.attr, self.arabic_hello_unicode) - self.assertEqual(str(rdn1), self.arabic_hello_utf8+'=foo') - - rdn1 = RDN_class((self.arabic_hello_utf8, 'foo')) - self.assertIsInstance(rdn1.attr, unicode) - self.assertIsInstance(rdn1.value, unicode) - self.assertEqual(rdn1.attr, self.arabic_hello_unicode) - self.assertEqual(str(rdn1), self.arabic_hello_utf8+'=foo') - - # test value i18n - rdn1 = RDN_class(('cn', self.arabic_hello_unicode)) - self.assertIsInstance(rdn1.attr, unicode) - self.assertIsInstance(rdn1.value, unicode) - self.assertEqual(rdn1.value, self.arabic_hello_unicode) - self.assertEqual(str(rdn1), 'cn='+self.arabic_hello_utf8) - - rdn1 = RDN_class(('cn', self.arabic_hello_utf8)) - self.assertIsInstance(rdn1.attr, unicode) - self.assertIsInstance(rdn1.value, unicode) - self.assertEqual(rdn1.value, self.arabic_hello_unicode) - self.assertEqual(str(rdn1), 'cn='+self.arabic_hello_utf8) - - # DN's - # test attr i18n - for DN_class in (DN, EditableDN): - dn1 = DN_class((self.arabic_hello_unicode, 'foo')) - self.assertIsInstance(dn1[0].attr, unicode) - self.assertIsInstance(dn1[0].value, unicode) - self.assertEqual(dn1[0].attr, self.arabic_hello_unicode) - self.assertEqual(str(dn1), self.arabic_hello_utf8+'=foo') - - dn1 = DN_class((self.arabic_hello_utf8, 'foo')) - self.assertIsInstance(dn1[0].attr, unicode) - self.assertIsInstance(dn1[0].value, unicode) - self.assertEqual(dn1[0].attr, self.arabic_hello_unicode) - self.assertEqual(str(dn1), self.arabic_hello_utf8+'=foo') - - # test value i18n - dn1 = DN_class(('cn', self.arabic_hello_unicode)) - self.assertIsInstance(dn1[0].attr, unicode) - self.assertIsInstance(dn1[0].value, unicode) - self.assertEqual(dn1[0].value, self.arabic_hello_unicode) - self.assertEqual(str(dn1), 'cn='+self.arabic_hello_utf8) - - dn1 = DN_class(('cn', self.arabic_hello_utf8)) - self.assertIsInstance(dn1[0].attr, unicode) - self.assertIsInstance(dn1[0].value, unicode) - self.assertEqual(dn1[0].value, self.arabic_hello_unicode) - self.assertEqual(str(dn1), 'cn='+self.arabic_hello_utf8) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_ipapython/test_ipautil.py b/tests/test_ipapython/test_ipautil.py deleted file mode 100644 index 650e1ce95..000000000 --- a/tests/test_ipapython/test_ipautil.py +++ /dev/null @@ -1,69 +0,0 @@ -# Authors: -# Jan Cholasta -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipapython/ipautil.py` module. -""" - -import nose - -from ipapython import ipautil - -class CheckIPAddress: - def __init__(self, addr): - self.description = "Test IP address parsing and verification (%s)" % addr - - def __call__(self, addr, words=None, prefixlen=None): - try: - ip = ipautil.CheckedIPAddress(addr, match_local=False) - assert ip.words == words and ip.prefixlen == prefixlen - except: - assert words is None and prefixlen is None - -def test_ip_address(): - addrs = [ - ('10.11.12.13', (10, 11, 12, 13), 8), - ('10.11.12.13/14', (10, 11, 12, 13), 14), - ('10.11.12.13%zoneid',), - ('10.11.12.13%zoneid/14',), - ('10.11.12.1337',), - ('10.11.12.13/33',), - ('127.0.0.1',), - ('241.1.2.3',), - ('169.254.1.2',), - ('10.11.12.0/24',), - ('224.5.6.7',), - ('10.11.12.255/24',), - - ('2001::1', (0x2001, 0, 0, 0, 0, 0, 0, 1), 64), - ('2001::1/72', (0x2001, 0, 0, 0, 0, 0, 0, 1), 72), - ('2001::1%zoneid', (0x2001, 0, 0, 0, 0, 0, 0, 1), 64), - ('2001::1%zoneid/72',), - ('2001::1beef',), - ('2001::1/129',), - ('::1',), - ('6789::1',), - ('fe89::1',), - ('2001::/64',), - ('ff01::1',), - - ('junk',) - ] - - for addr in addrs: - yield (CheckIPAddress(addr[0]),) + addr diff --git a/tests/test_ipapython/test_keyring.py b/tests/test_ipapython/test_keyring.py deleted file mode 100644 index 568fd5ee1..000000000 --- a/tests/test_ipapython/test_keyring.py +++ /dev/null @@ -1,147 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `kernel_keyring.py` module. -""" - -from nose.tools import raises, assert_raises # pylint: disable=E0611 -from ipapython import kernel_keyring - -TEST_KEY = 'ipa_test' -TEST_VALUE = 'abc123' -UPDATE_VALUE = '123abc' - -SIZE_256 = 'abcdefgh' * 32 -SIZE_512 = 'abcdefgh' * 64 -SIZE_1024 = 'abcdefgh' * 128 - -class test_keyring(object): - """ - Test the kernel keyring interface - """ - - def setUp(self): - try: - kernel_keyring.del_key(TEST_KEY) - except ValueError: - pass - try: - kernel_keyring.del_key(SIZE_256) - except ValueError: - pass - - def test_01(self): - """ - Add a new key and value, then remove it - """ - kernel_keyring.add_key(TEST_KEY, TEST_VALUE) - result = kernel_keyring.read_key(TEST_KEY) - assert(result == TEST_VALUE) - - kernel_keyring.del_key(TEST_KEY) - - # Make sure it is gone - try: - result = kernel_keyring.read_key(TEST_KEY) - except ValueError, e: - assert e.message == 'key %s not found' % TEST_KEY - - def test_02(self): - """ - Delete a non_existent key - """ - try: - kernel_keyring.del_key(TEST_KEY) - raise AssertionError('key should not have been deleted') - except ValueError: - pass - - @raises(ValueError) - def test_03(self): - """ - Add a duplicate key - """ - kernel_keyring.add_key(TEST_KEY, TEST_VALUE) - kernel_keyring.add_key(TEST_KEY, TEST_VALUE) - - def test_04(self): - """ - Update the value in a key - """ - kernel_keyring.update_key(TEST_KEY, UPDATE_VALUE) - result = kernel_keyring.read_key(TEST_KEY) - assert(result == UPDATE_VALUE) - - # Now update it 10 times - for i in xrange(10): - kernel_keyring.update_key(TEST_KEY, 'test %d' % i) - result = kernel_keyring.read_key(TEST_KEY) - assert(result == 'test %d' % i) - - kernel_keyring.del_key(TEST_KEY) - - @raises(ValueError) - def test_05(self): - """ - Read a non-existent key - """ - result = kernel_keyring.read_key(TEST_KEY) - - def test_06(self): - """ - See if a key is available - """ - kernel_keyring.add_key(TEST_KEY, TEST_VALUE) - - result = kernel_keyring.has_key(TEST_KEY) - assert(result == True) - kernel_keyring.del_key(TEST_KEY) - - result = kernel_keyring.has_key(TEST_KEY) - assert(result == False) - - def test_07(self): - """ - Test a 256-byte key - """ - kernel_keyring.add_key(SIZE_256, TEST_VALUE) - result = kernel_keyring.read_key(SIZE_256) - assert(result == TEST_VALUE) - - kernel_keyring.del_key(SIZE_256) - - def test_08(self): - """ - Test 512-bytes of data - """ - kernel_keyring.add_key(TEST_KEY, SIZE_512) - result = kernel_keyring.read_key(TEST_KEY) - assert(result == SIZE_512) - - kernel_keyring.del_key(TEST_KEY) - - def test_09(self): - """ - Test 1k bytes of data - """ - kernel_keyring.add_key(TEST_KEY, SIZE_1024) - result = kernel_keyring.read_key(TEST_KEY) - assert(result == SIZE_1024) - - kernel_keyring.del_key(TEST_KEY) diff --git a/tests/test_ipapython/test_ssh.py b/tests/test_ipapython/test_ssh.py deleted file mode 100644 index 2640af50d..000000000 --- a/tests/test_ipapython/test_ssh.py +++ /dev/null @@ -1,76 +0,0 @@ -# Authors: -# Jan Cholasta -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipapython/ssh.py` module. -""" - -import base64 -import nose - -from ipapython import ssh - -class CheckPublicKey: - def __init__(self, pk): - self.description = "Test SSH public key parsing (%s)" % repr(pk) - - def __call__(self, pk, out): - try: - parsed = ssh.SSHPublicKey(pk) - assert parsed.openssh() == out - except Exception, e: - assert type(e) is out - -def test_public_key_parsing(): - b64 = 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDGAX3xAeLeaJggwTqMjxNwa6XHBUAikXPGMzEpVrlLDCZtv00djsFTBi38PkgxBJVkgRWMrcBsr/35lq7P6w8KGIwA8GI48Z0qBS2NBMJ2u9WQ2hjLN6GdMlo77O0uJY3251p12pCVIS/bHRSq8kHO2No8g7KA9fGGcagPfQH+ee3t7HUkpbQkFTmbPPN++r3V8oVUk5LxbryB3UIIVzNmcSIn3JrXynlvui4MixvrtX6zx+O/bBo68o8/eZD26QrahVbA09fivrn/4h3TM019Eu/c2jOdckfU3cHUV/3Tno5d6JicibyaoDDK7S/yjdn5jhaz8MSEayQvFkZkiF0L' - raw = base64.b64decode(b64) - openssh = 'ssh-rsa %s' % b64 - - pks = [ - ('\xff', UnicodeDecodeError), - - (raw, openssh), - ('\0\0\0\x04none', u'none AAAABG5vbmU='), - ('\0\0\0', ValueError), - ('\0\0\0\0', ValueError), - ('\0\0\0\x01', ValueError), - ('\0\0\0\x01\xff', ValueError), - - (b64, openssh), - (unicode(b64), openssh), - (u'\n%s\n\n' % b64, openssh), - (u'AAAABG5vbmU=', u'none AAAABG5vbmU='), - (u'AAAAB', ValueError), - - (openssh, openssh), - (unicode(openssh), openssh), - (u'none AAAABG5vbmU=', u'none AAAABG5vbmU='), - (u'\t \t ssh-rsa \t \t%s\t \tthis is a comment\t \t ' % b64, - u'%s this is a comment' % openssh), - (u'opt3,opt2="\tx ",opt1,opt2="\\"x " %s comment ' % openssh, - u'opt1,opt2="\\"x ",opt3 %s comment' % openssh), - (u'ssh-rsa\n%s' % b64, ValueError), - (u'ssh-rsa\t%s' % b64, ValueError), - (u'vanitas %s' % b64, ValueError), - (u'@opt %s' % openssh, ValueError), - (u'opt=val %s' % openssh, ValueError), - (u'opt, %s' % openssh, ValueError), - ] - - for pk in pks: - yield (CheckPublicKey(pk[0]),) + pk diff --git a/tests/test_ipaserver/__init__.py b/tests/test_ipaserver/__init__.py deleted file mode 100644 index 2192cc291..000000000 --- a/tests/test_ipaserver/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Sub-package containing unit tests for `ipaserver` package. -""" diff --git a/tests/test_ipaserver/httptest.py b/tests/test_ipaserver/httptest.py deleted file mode 100644 index 7f1b5b136..000000000 --- a/tests/test_ipaserver/httptest.py +++ /dev/null @@ -1,52 +0,0 @@ -# Authors: -# Martin Kosek -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Base class for HTTP request tests -""" - -import urllib -import httplib - -from ipalib import api - -class Unauthorized_HTTP_test(object): - """ - Base class for simple HTTP request tests executed against URI - with no required authorization - """ - app_uri = '' - host = api.env.host - content_type = 'application/x-www-form-urlencoded' - - def send_request(self, method='POST', params=None): - """ - Send a request to HTTP server - - :param key When not None, overrides default app_uri - """ - if params is not None: - params = urllib.urlencode(params, True) - url = 'https://' + self.host + self.app_uri - - headers = {'Content-Type' : self.content_type, - 'Referer' : url} - - conn = httplib.HTTPSConnection(self.host) - conn.request(method, self.app_uri, params, headers) - return conn.getresponse() diff --git a/tests/test_ipaserver/install/test_adtrustinstance.py b/tests/test_ipaserver/install/test_adtrustinstance.py deleted file mode 100755 index 9a62f87ce..000000000 --- a/tests/test_ipaserver/install/test_adtrustinstance.py +++ /dev/null @@ -1,59 +0,0 @@ -# Authors: -# Sumit Bose -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test `adtrustinstance` -""" - -import os -import nose - -from ipaserver.install import adtrustinstance - -class test_adtrustinstance: - """ - Test `adtrustinstance`. - """ - - def test_make_netbios_name(self): - s = adtrustinstance.make_netbios_name("ABCDEF") - assert s == 'ABCDEF' and isinstance(s, str) - s = adtrustinstance.make_netbios_name(U"ABCDEF") - assert s == 'ABCDEF' and isinstance(s, unicode) - s = adtrustinstance.make_netbios_name("abcdef") - assert s == 'ABCDEF' - s = adtrustinstance.make_netbios_name("abc.def") - assert s == 'ABC' - s = adtrustinstance.make_netbios_name("abcdefghijklmnopqr.def") - assert s == 'ABCDEFGHIJKLMNO' - s = adtrustinstance.make_netbios_name("A!$%B&/()C=?+*D") - assert s == 'ABCD' - s = adtrustinstance.make_netbios_name("!$%&/()=?+*") - assert not s - - def test_check_netbios_name(self): - assert adtrustinstance.check_netbios_name("ABCDEF") - assert not adtrustinstance.check_netbios_name("abcdef") - assert adtrustinstance.check_netbios_name("ABCDE12345ABCDE") - assert not adtrustinstance.check_netbios_name("ABCDE12345ABCDE1") - assert not adtrustinstance.check_netbios_name("") - - assert adtrustinstance.check_netbios_name(U"ABCDEF") - assert not adtrustinstance.check_netbios_name(U"abcdef") - assert adtrustinstance.check_netbios_name(U"ABCDE12345ABCDE") - assert not adtrustinstance.check_netbios_name(U"ABCDE12345ABCDE1") diff --git a/tests/test_ipaserver/test_changepw.py b/tests/test_ipaserver/test_changepw.py deleted file mode 100644 index 4491e0b6e..000000000 --- a/tests/test_ipaserver/test_changepw.py +++ /dev/null @@ -1,107 +0,0 @@ -# Authors: -# Martin Kosek -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import nose - -from httptest import Unauthorized_HTTP_test -from tests.test_xmlrpc.xmlrpc_test import XMLRPC_test -from tests.util import assert_equal, assert_not_equal -from ipalib import api, errors -from ipapython.dn import DN -import ldap - -testuser = u'tuser' -old_password = u'old_password' -new_password = u'new_password' - -class test_changepw(XMLRPC_test, Unauthorized_HTTP_test): - app_uri = '/ipa/session/change_password' - - def setUp(self): - super(test_changepw, self).setUp() - try: - api.Command['user_add'](uid=testuser, givenname=u'Test', sn=u'User') - api.Command['passwd'](testuser, password=u'old_password') - except errors.ExecutionError, e: - raise nose.SkipTest( - 'Cannot set up test user: %s' % e - ) - - def tearDown(self): - try: - api.Command['user_del']([testuser]) - except errors.NotFound: - pass - super(test_changepw, self).tearDown() - - def _changepw(self, user, old_password, new_password): - return self.send_request(params={'user': str(user), - 'old_password' : str(old_password), - 'new_password' : str(new_password)}, - ) - - def _checkpw(self, user, password): - dn = str(DN(('uid', user), api.env.container_user, api.env.basedn)) - conn = ldap.initialize(api.env.ldap_uri) - try: - conn.simple_bind_s(dn, password) - finally: - conn.unbind_s() - - def test_bad_options(self): - for params in (None, # no params - {'user': 'foo'}, # missing options - {'user': 'foo', - 'old_password' : 'old'}, # missing option - {'user': 'foo', - 'old_password' : 'old', - 'new_password' : ''}, # empty option - ): - response = self.send_request(params=params) - assert_equal(response.status, 400) - assert_equal(response.reason, 'Bad Request') - - def test_invalid_auth(self): - response = self._changepw(testuser, 'wrongpassword', 'new_password') - - assert_equal(response.status, 200) - assert_equal(response.getheader('X-IPA-Pwchange-Result'), 'invalid-password') - - # make sure that password is NOT changed - self._checkpw(testuser, old_password) - - def test_pwpolicy_error(self): - response = self._changepw(testuser, old_password, '1') - - assert_equal(response.status, 200) - assert_equal(response.getheader('X-IPA-Pwchange-Result'), 'policy-error') - assert_equal(response.getheader('X-IPA-Pwchange-Policy-Error'), - 'Constraint violation: Password is too short') - - # make sure that password is NOT changed - self._checkpw(testuser, old_password) - - def test_pwpolicy_success(self): - response = self._changepw(testuser, old_password, new_password) - - assert_equal(response.status, 200) - assert_equal(response.getheader('X-IPA-Pwchange-Result'), 'ok') - - # make sure that password IS changed - self._checkpw(testuser, new_password) diff --git a/tests/test_ipaserver/test_ldap.py b/tests/test_ipaserver/test_ldap.py deleted file mode 100644 index 21363f2ef..000000000 --- a/tests/test_ipaserver/test_ldap.py +++ /dev/null @@ -1,259 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Test some simple LDAP requests using the ldap2 backend - -# This fetches a certificate from a host principal so we can ensure that the -# schema is working properly. We know this because the schema will tell the -# encoder not to utf-8 encode binary attributes. - -# The DM password needs to be set in ~/.ipa/.dmpw - -import os - -import nose -from nose.tools import assert_raises # pylint: disable=E0611 -import nss.nss as nss - -from ipaserver.plugins.ldap2 import ldap2 -from ipalib.plugins.service import service, service_show -from ipalib.plugins.host import host -from ipalib import api, x509, create_api, errors -from ipapython import ipautil -from ipapython.dn import DN - -class test_ldap(object): - """ - Test various LDAP client bind methods. - """ - - def setUp(self): - self.conn = None - self.ldapuri = 'ldap://%s' % ipautil.format_netloc(api.env.host) - self.ccache = '/tmp/krb5cc_%d' % os.getuid() - nss.nss_init_nodb() - self.dn = DN(('krbprincipalname','ldap/%s@%s' % (api.env.host, api.env.realm)), - ('cn','services'),('cn','accounts'),api.env.basedn) - - def tearDown(self): - if self.conn and self.conn.isconnected(): - self.conn.disconnect() - - def test_anonymous(self): - """ - Test an anonymous LDAP bind using ldap2 - """ - self.conn = ldap2(shared_instance=False, ldap_uri=self.ldapuri) - self.conn.connect() - (dn, entry_attrs) = self.conn.get_entry(self.dn, ['usercertificate']) - cert = entry_attrs.get('usercertificate') - cert = cert[0] - serial = unicode(x509.get_serial_number(cert, x509.DER)) - assert serial is not None - - def test_GSSAPI(self): - """ - Test a GSSAPI LDAP bind using ldap2 - """ - if not ipautil.file_exists(self.ccache): - raise nose.SkipTest('Missing ccache %s' % self.ccache) - self.conn = ldap2(shared_instance=False, ldap_uri=self.ldapuri) - self.conn.connect(ccache='FILE:%s' % self.ccache) - (dn, entry_attrs) = self.conn.get_entry(self.dn, ['usercertificate']) - cert = entry_attrs.get('usercertificate') - cert = cert[0] - serial = unicode(x509.get_serial_number(cert, x509.DER)) - assert serial is not None - - def test_simple(self): - """ - Test a simple LDAP bind using ldap2 - """ - pwfile = api.env.dot_ipa + os.sep + ".dmpw" - if ipautil.file_exists(pwfile): - fp = open(pwfile, "r") - dm_password = fp.read().rstrip() - fp.close() - else: - raise nose.SkipTest("No directory manager password in %s" % pwfile) - self.conn = ldap2(shared_instance=False, ldap_uri=self.ldapuri) - self.conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password) - (dn, entry_attrs) = self.conn.get_entry(self.dn, ['usercertificate']) - cert = entry_attrs.get('usercertificate') - cert = cert[0] - serial = unicode(x509.get_serial_number(cert, x509.DER)) - assert serial is not None - - def test_Backend(self): - """ - Test using the ldap2 Backend directly (ala ipa-server-install) - """ - - # Create our own api because the one generated for the tests is - # a client-only api. Then we register in the commands and objects - # we need for the test. - myapi = create_api(mode=None) - myapi.bootstrap(context='cli', in_server=True, in_tree=True) - myapi.register(ldap2) - myapi.register(host) - myapi.register(service) - myapi.register(service_show) - myapi.finalize() - - pwfile = api.env.dot_ipa + os.sep + ".dmpw" - if ipautil.file_exists(pwfile): - fp = open(pwfile, "r") - dm_password = fp.read().rstrip() - fp.close() - else: - raise nose.SkipTest("No directory manager password in %s" % pwfile) - myapi.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password) - - result = myapi.Command['service_show']('ldap/%s@%s' % (api.env.host, api.env.realm,)) - entry_attrs = result['result'] - cert = entry_attrs.get('usercertificate') - cert = cert[0] - serial = unicode(x509.get_serial_number(cert, x509.DER)) - assert serial is not None - - def test_autobind(self): - """ - Test an autobind LDAP bind using ldap2 - """ - ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % api.env.realm.replace('.','-') - self.conn = ldap2(shared_instance=False, ldap_uri=ldapuri) - try: - self.conn.connect(autobind=True) - except errors.ACIError: - raise nose.SkipTest("Only executed as root") - (dn, entry_attrs) = self.conn.get_entry(self.dn, ['usercertificate']) - cert = entry_attrs.get('usercertificate') - cert = cert[0] - serial = unicode(x509.get_serial_number(cert, x509.DER)) - assert serial is not None - - -class test_LDAPEntry(object): - """ - Test the LDAPEntry class - """ - cn1 = [u'test1'] - cn2 = [u'test2'] - dn1 = DN(('cn', cn1[0])) - dn2 = DN(('cn', cn2[0])) - - def setUp(self): - self.ldapuri = 'ldap://%s' % ipautil.format_netloc(api.env.host) - self.conn = ldap2(shared_instance=False, ldap_uri=self.ldapuri) - self.conn.connect() - - self.entry = self.conn.make_entry(self.dn1, cn=self.cn1) - - def tearDown(self): - if self.conn and self.conn.isconnected(): - self.conn.disconnect() - - def test_entry(self): - e = self.entry - assert e.dn is self.dn1 - assert u'cn' in e - assert u'cn' in e.keys() - assert 'CN' in e - assert 'CN' not in e.keys() - assert 'commonName' in e - assert 'commonName' not in e.keys() - assert e['CN'] is self.cn1 - assert e['CN'] is e[u'cn'] - - e.dn = self.dn2 - assert e.dn is self.dn2 - - def test_set_attr(self): - e = self.entry - e['commonName'] = self.cn2 - assert u'cn' in e - assert u'cn' not in e.keys() - assert 'CN' in e - assert 'CN' not in e.keys() - assert 'commonName' in e - assert 'commonName' in e.keys() - assert e['CN'] is self.cn2 - assert e['CN'] is e[u'cn'] - - def test_del_attr(self): - e = self.entry - del e['CN'] - assert 'CN' not in e - assert 'CN' not in e.keys() - assert u'cn' not in e - assert u'cn' not in e.keys() - assert 'commonName' not in e - assert 'commonName' not in e.keys() - - def test_popitem(self): - e = self.entry - assert e.popitem() == ('cn', self.cn1) - e.keys() == [] - - def test_setdefault(self): - e = self.entry - assert e.setdefault('cn', self.cn2) == self.cn1 - assert e['cn'] == self.cn1 - assert e.setdefault('xyz', self.cn2) == self.cn2 - assert e['xyz'] == self.cn2 - - def test_update(self): - e = self.entry - e.update({'cn': self.cn2}, xyz=self.cn2) - assert e['cn'] == self.cn2 - assert e['xyz'] == self.cn2 - - def test_pop(self): - e = self.entry - assert e.pop('cn') == self.cn1 - assert 'cn' not in e - assert e.pop('cn', 'default') is 'default' - with assert_raises(KeyError): - e.pop('cn') - - def test_clear(self): - e = self.entry - e.clear() - assert not e - assert 'cn' not in e - - def test_has_key(self): - e = self.entry - assert not e.has_key('xyz') - assert e.has_key('cn') - assert e.has_key('COMMONNAME') - - def test_get(self): - e = self.entry - assert e.get('cn') == self.cn1 - assert e.get('commonname') == self.cn1 - assert e.get('COMMONNAME', 'default') == self.cn1 - assert e.get('bad key', 'default') == 'default' - - def test_single_value(self): - e = self.entry - assert e.single_value('cn') == self.cn1[0] - assert e.single_value('commonname') == self.cn1[0] - assert e.single_value('COMMONNAME', 'default') == self.cn1[0] - assert e.single_value('bad key', 'default') == 'default' diff --git a/tests/test_ipaserver/test_rpcserver.py b/tests/test_ipaserver/test_rpcserver.py deleted file mode 100644 index a75a85e09..000000000 --- a/tests/test_ipaserver/test_rpcserver.py +++ /dev/null @@ -1,247 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipaserver.rpc` module. -""" - -import json - -from tests.util import create_test_api, assert_equal, raises, PluginTester -from tests.data import unicode_str -from ipalib import errors, Command -from ipaserver import rpcserver - - -class StartResponse(object): - def __init__(self): - self.reset() - - def reset(self): - self.status = None - self.headers = None - - def __call__(self, status, headers): - assert self.status is None - assert self.headers is None - assert isinstance(status, str) - assert isinstance(headers, list) - self.status = status - self.headers = headers - - -def test_not_found(): - f = rpcserver.HTTP_Status() - t = rpcserver._not_found_template - s = StartResponse() - - # Test with an innocent URL: - url = '/ipa/foo/stuff' - assert_equal( - f.not_found(None, s, url, None), - [t % dict(url='/ipa/foo/stuff')] - ) - assert s.status == '404 Not Found' - assert s.headers == [('Content-Type', 'text/html; charset=utf-8')] - - # Test when URL contains any of '<>&' - s.reset() - url =' ' + '' - assert_equal( - f.not_found(None, s, url, None), - [t % dict(url='&nbsp;<script>do_bad_stuff();</script>')] - ) - assert s.status == '404 Not Found' - assert s.headers == [('Content-Type', 'text/html; charset=utf-8')] - - -def test_bad_request(): - f = rpcserver.HTTP_Status() - t = rpcserver._bad_request_template - s = StartResponse() - - assert_equal( - f.bad_request(None, s, 'illegal request'), - [t % dict(message='illegal request')] - ) - assert s.status == '400 Bad Request' - assert s.headers == [('Content-Type', 'text/html; charset=utf-8')] - - -def test_internal_error(): - f = rpcserver.HTTP_Status() - t = rpcserver._internal_error_template - s = StartResponse() - - assert_equal( - f.internal_error(None, s, 'request failed'), - [t % dict(message='request failed')] - ) - assert s.status == '500 Internal Server Error' - assert s.headers == [('Content-Type', 'text/html; charset=utf-8')] - - -def test_unauthorized_error(): - f = rpcserver.HTTP_Status() - t = rpcserver._unauthorized_template - s = StartResponse() - - assert_equal( - f.unauthorized(None, s, 'unauthorized', 'password-expired'), - [t % dict(message='unauthorized')] - ) - assert s.status == '401 Unauthorized' - assert s.headers == [('Content-Type', 'text/html; charset=utf-8'), - ('X-IPA-Rejection-Reason', 'password-expired')] - - -def test_params_2_args_options(): - """ - Test the `ipaserver.rpcserver.params_2_args_options` function. - """ - f = rpcserver.params_2_args_options - args = ('Hello', u'world!') - options = dict(one=1, two=u'Two', three='Three') - assert f(tuple()) == (tuple(), dict()) - assert f([args]) == (args, dict()) - assert f([args, options]) == (args, options) - - -class test_session(object): - klass = rpcserver.wsgi_dispatch - - def test_route(self): - def app1(environ, start_response): - return ( - 'from 1', - [environ[k] for k in ('SCRIPT_NAME', 'PATH_INFO')] - ) - - def app2(environ, start_response): - return ( - 'from 2', - [environ[k] for k in ('SCRIPT_NAME', 'PATH_INFO')] - ) - - inst = self.klass() - inst.mount(app1, '/foo/stuff') - inst.mount(app2, '/bar') - - d = dict(SCRIPT_NAME='/ipa', PATH_INFO='/foo/stuff') - assert inst.route(d, None) == ('from 1', ['/ipa', '/foo/stuff']) - - d = dict(SCRIPT_NAME='/ipa', PATH_INFO='/bar') - assert inst.route(d, None) == ('from 2', ['/ipa', '/bar']) - - def test_mount(self): - def app1(environ, start_response): - pass - - def app2(environ, start_response): - pass - - # Test that mount works: - inst = self.klass() - inst.mount(app1, 'foo') - assert inst['foo'] is app1 - assert list(inst) == ['foo'] - - # Test that StandardError is raise if trying override a mount: - e = raises(StandardError, inst.mount, app2, 'foo') - assert str(e) == '%s.mount(): cannot replace %r with %r at %r' % ( - 'wsgi_dispatch', app1, app2, 'foo' - ) - - # Test mounting a second app: - inst.mount(app2, 'bar') - assert inst['bar'] is app2 - assert list(inst) == ['bar', 'foo'] - - -class test_xmlserver(PluginTester): - """ - Test the `ipaserver.rpcserver.xmlserver` plugin. - """ - - _plugin = rpcserver.xmlserver - - def test_marshaled_dispatch(self): # FIXME - (o, api, home) = self.instance('Backend', in_server=True) - - -class test_jsonserver(PluginTester): - """ - Test the `ipaserver.rpcserver.jsonserver` plugin. - """ - - _plugin = rpcserver.jsonserver - - def test_unmarshal(self): - """ - Test the `ipaserver.rpcserver.jsonserver.unmarshal` method. - """ - (o, api, home) = self.instance('Backend', in_server=True) - - # Test with invalid JSON-data: - e = raises(errors.JSONError, o.unmarshal, 'this wont work') - assert isinstance(e.error, ValueError) - assert unicode(e.error) == 'No JSON object could be decoded' - - # Test with non-dict type: - e = raises(errors.JSONError, o.unmarshal, json.dumps([1, 2, 3])) - assert unicode(e.error) == 'Request must be a dict' - - params = [[1, 2], dict(three=3, four=4)] - # Test with missing method: - d = dict(params=params, id=18) - e = raises(errors.JSONError, o.unmarshal, json.dumps(d)) - assert unicode(e.error) == 'Request is missing "method"' - - # Test with missing params: - d = dict(method='echo', id=18) - e = raises(errors.JSONError, o.unmarshal, json.dumps(d)) - assert unicode(e.error) == 'Request is missing "params"' - - # Test with non-list params: - for p in ('hello', dict(args=tuple(), options=dict())): - d = dict(method='echo', id=18, params=p) - e = raises(errors.JSONError, o.unmarshal, json.dumps(d)) - assert unicode(e.error) == 'params must be a list' - - # Test with other than 2 params: - for p in ([], [tuple()], [None, dict(), tuple()]): - d = dict(method='echo', id=18, params=p) - e = raises(errors.JSONError, o.unmarshal, json.dumps(d)) - assert unicode(e.error) == 'params must contain [args, options]' - - # Test when args is not a list: - d = dict(method='echo', id=18, params=['args', dict()]) - e = raises(errors.JSONError, o.unmarshal, json.dumps(d)) - assert unicode(e.error) == 'params[0] (aka args) must be a list' - - # Test when options is not a dict: - d = dict(method='echo', id=18, params=[('hello', 'world'), 'options']) - e = raises(errors.JSONError, o.unmarshal, json.dumps(d)) - assert unicode(e.error) == 'params[1] (aka options) must be a dict' - - # Test with valid values: - args = [u'jdoe'] - options = dict(givenname=u'John', sn='Doe') - d = dict(method=u'user_add', params=[args, options], id=18) - assert o.unmarshal(json.dumps(d)) == (u'user_add', args, options, 18) diff --git a/tests/test_pkcs10/__init__.py b/tests/test_pkcs10/__init__.py deleted file mode 100644 index cd03658cf..000000000 --- a/tests/test_pkcs10/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Sub-package containing unit tests for `pkcs10` package. -""" diff --git a/tests/test_pkcs10/test0.csr b/tests/test_pkcs10/test0.csr deleted file mode 100644 index eadfb70b4..000000000 --- a/tests/test_pkcs10/test0.csr +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIIBjjCB+AIBADBPMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEQ -MA4GA1UEChMHRXhhbXBsZTEZMBcGA1UEAxMQdGVzdC5leGFtcGxlLmNvbTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyxsN5dmvyKiw+5nyrcO3a61sivZRg+ja -kyNIyUo+tIUiYwTdpPESAHTWRlk0XhydauAkWfOIN7pR3a5Z+kQw8W7F+DuZze2M -6wRNmN+NTrTlqnKOiMHBXhIM0Qxrx68GDctYqtnKTVT94FvvLl9XYVdUEi2ePTc2 -Nyfr1z66+W0CAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAIf3r+Y6WHrFnttUqDow -9/UCHtCeQlQoJqjjxi5wcjbkGwTgHbx/BPOd/8OVaHElboMXLGaZx+L/eFO6E9Yg -mDOYv3OsibDFGaEhJrU8EnfuFZKnbrGeSC9Hkqrq+3OjqacaPla5N7MHKbfLY377 -ddbOHKzR0sURZ+ro4z3fATW2 ------END NEW CERTIFICATE REQUEST----- - diff --git a/tests/test_pkcs10/test1.csr b/tests/test_pkcs10/test1.csr deleted file mode 100644 index 0dad3ae1e..000000000 --- a/tests/test_pkcs10/test1.csr +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIIBwDCCASkCAQAwTzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx -EDAOBgNVBAoTB0V4YW1wbGUxGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wgZ8w -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMK+3uy1CGwek8jutw4UO62YTpkmStlw -cKPEjTER7Ra1a1wyWJTo1mMnPhVia0GODeq8ERPgcIckCVogBu8+gL6g8NevaBNv -ij1XWU08BEQqmoqAkrFiI8EdDckKYrSoXo2cg1fiTGzlG8AWtr5eT0op5jBBo0J6 -qXX5Sf6e+n+nAgMBAAGgMTAvBgkqhkiG9w0BCQ4xIjAgMB4GA1UdEQQXMBWCE3Rl -c3Rsb3cuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEAwRDa7ZOaym9mAUH7 -hudbvsRkqXHehgf51uMUq0OC9hQ6vPLWqUMAod05lxn3Tnvq6a/fVK0ybgCH5Ld7 -qpAcUruYdj7YxkFfuBc1dpAK6h94rVsJXFCWIMEZm9Fe7n5RERjhO6h2IRSXBHFz -QIszvqBamm/W1ONKdQSM2g+M4BQ= ------END NEW CERTIFICATE REQUEST----- - diff --git a/tests/test_pkcs10/test2.csr b/tests/test_pkcs10/test2.csr deleted file mode 100644 index ccc47f890..000000000 --- a/tests/test_pkcs10/test2.csr +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIICETCCAXoCAQAwTzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx -EDAOBgNVBAoTB0V4YW1wbGUxGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wgZ8w -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOXfP8LeiU7g6wLCclgkT1lVskK+Lxm1 -6ijE4LmEQBk5nn2P46im+E/UOgTddbDo5cdJlkoCnqXkO4RkqJckXYDxfI34KL3C -CRFPvOa5Sg02m1x5Rg3boZfS6NciP62lRp0SI+0TCt3F16wYZxMahVIOXjbJ6Lu5 -mGjNn7XaWJhFAgMBAAGggYEwfwYJKoZIhvcNAQkOMXIwcDAeBgNVHREEFzAVghN0 -ZXN0bG93LmV4YW1wbGUuY29tME4GA1UdHwRHMEUwQ6BBoD+GHGh0dHA6Ly9jYS5l -eGFtcGxlLmNvbS9teS5jcmyGH2h0dHA6Ly9vdGhlci5leGFtcGxlLmNvbS9teS5j -cmwwDQYJKoZIhvcNAQEFBQADgYEAkv8pppcgGhX7erJmvg9r2UHrRriuKaOYgKZQ -lf/eBt2N0L2mV4QvCY82H7HWuE+7T3mra9ikfvz0nYkPJQe2gntjZzECE0Jt5LWR -UZOFwX8N6wrX11U2xu0NlvsbjU6siWd6OZjZ1p5/V330lzut/q3CNzaAcW1Fx3wL -sV5SXSw= ------END NEW CERTIFICATE REQUEST----- - diff --git a/tests/test_pkcs10/test3.csr b/tests/test_pkcs10/test3.csr deleted file mode 100644 index 82c84d154..000000000 --- a/tests/test_pkcs10/test3.csr +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -VGhpcyBpcyBhbiBpbnZhbGlkIENTUg== ------END NEW CERTIFICATE REQUEST----- diff --git a/tests/test_pkcs10/test4.csr b/tests/test_pkcs10/test4.csr deleted file mode 100644 index 9f08b802b..000000000 --- a/tests/test_pkcs10/test4.csr +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -Invalidate data ------END NEW CERTIFICATE REQUEST----- - diff --git a/tests/test_pkcs10/test5.csr b/tests/test_pkcs10/test5.csr deleted file mode 100644 index 41c3c1f3d..000000000 --- a/tests/test_pkcs10/test5.csr +++ /dev/null @@ -1,20 +0,0 @@ - -Certificate request generated by Netscape certutil -Phone: (not specified) - -Common Name: test.example.com -Email: (not specified) -Organization: IPA -State: (not specified) -Country: (not specified) - ------BEGIN NEW CERTIFICATE REQUEST----- -MIIBaDCB0gIBADApMQwwCgYDVQQKEwNJUEExGTAXBgNVBAMTEHRlc3QuZXhhbXBs -ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPnSCLwl7IytP2HC7+zv -nI2fe6oRCE/J8K1jIoiqS9engx3Yfe4kaXWWzcwmuUV57VhUmWDEQIbSREPdrVSi -tWC55ilGmPOAEw+mP4qg6Ctb+d8Egmy1JVrpIYCLNXvEd3dAaimB0J+K3hKFRyHI -2MzrIuFqqohRijkDLwB8oVVdAgMBAAGgADANBgkqhkiG9w0BAQUFAAOBgQACt37K -j+RMEbqG8s0Uxs3FhcfiAx8Do99CDizY/b7hZEgMyG4dLmm+vSCBbxBrG5oMlxJD -dxnpk0PQSknNkJVrCS/J1OTpOPRTi4VKATT3tHJAfDbWZTwcSelUCLQ4lREiuT3D -WP4vKrLIxDJDb+/mwuV7WWo34E6MD9iTB1xINg== ------END NEW CERTIFICATE REQUEST----- diff --git a/tests/test_pkcs10/test_pkcs10.py b/tests/test_pkcs10/test_pkcs10.py deleted file mode 100644 index 381bf9e86..000000000 --- a/tests/test_pkcs10/test_pkcs10.py +++ /dev/null @@ -1,124 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `pkcs10.py` module. -""" - -import os -import sys -import nose -from tests.util import raises, PluginTester -from ipalib import pkcs10 -from ipapython import ipautil -import nss.nss as nss -from nss.error import NSPRError - -class test_update(object): - """ - Test the PKCS#10 Parser. - """ - - def setUp(self): - nss.nss_init_nodb() - if ipautil.file_exists("test0.csr"): - self.testdir="./" - elif ipautil.file_exists("tests/test_pkcs10/test0.csr"): - self.testdir= "./tests/test_pkcs10/" - else: - raise nose.SkipTest("Unable to find test update files") - - def read_file(self, filename): - fp = open(self.testdir + filename, "r") - data = fp.read() - fp.close() - return data - - def test_0(self): - """ - Test simple CSR with no attributes - """ - csr = self.read_file("test0.csr") - request = pkcs10.load_certificate_request(csr) - - subject = pkcs10.get_subject(request) - - assert(subject.common_name == 'test.example.com') - assert(subject.state_name == 'California') - assert(subject.country_name == 'US') - - def test_1(self): - """ - Test CSR with subject alt name - """ - csr = self.read_file("test1.csr") - request = pkcs10.load_certificate_request(csr) - - subject = pkcs10.get_subject(request) - - assert(subject.common_name == 'test.example.com') - assert(subject.state_name == 'California') - assert(subject.country_name == 'US') - - for extension in request.extensions: - if extension.oid_tag == nss.SEC_OID_X509_SUBJECT_ALT_NAME: - assert nss.x509_alt_name(extension.value)[0] == 'testlow.example.com' - - def test_2(self): - """ - Test CSR with subject alt name and a list of CRL distribution points - """ - csr = self.read_file("test2.csr") - request = pkcs10.load_certificate_request(csr) - - subject = pkcs10.get_subject(request) - - assert(subject.common_name == 'test.example.com') - assert(subject.state_name == 'California') - assert(subject.country_name == 'US') - - for extension in request.extensions: - if extension.oid_tag == nss.SEC_OID_X509_SUBJECT_ALT_NAME: - assert nss.x509_alt_name(extension.value)[0] == 'testlow.example.com' - if extension.oid_tag == nss.SEC_OID_X509_CRL_DIST_POINTS: - pts = nss.CRLDistributionPts(extension.value) - urls = pts[0].get_general_names() - assert('http://ca.example.com/my.crl' in urls) - assert('http://other.example.com/my.crl' in urls) - - def test_3(self): - """ - Test CSR with base64-encoded bogus data - """ - csr = self.read_file("test3.csr") - - try: - request = pkcs10.load_certificate_request(csr) - except NSPRError, nsprerr: - # (SEC_ERROR_BAD_DER) security library: improperly formatted DER-encoded message. - assert(nsprerr. errno== -8183) - - def test_4(self): - """ - Test CSR with badly formatted base64-encoded data - """ - csr = self.read_file("test4.csr") - try: - request = pkcs10.load_certificate_request(csr) - except TypeError, typeerr: - assert(str(typeerr) == 'Incorrect padding') diff --git a/tests/test_util.py b/tests/test_util.py deleted file mode 100644 index f87822a22..000000000 --- a/tests/test_util.py +++ /dev/null @@ -1,367 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `tests.util` module. -""" - -import re -import util -from util import raises, TYPE, VALUE, LEN, KEYS - - -class Prop(object): - def __init__(self, *ops): - self.__ops = frozenset(ops) - self.__prop = 'prop value' - - def __get_prop(self): - if 'get' not in self.__ops: - raise AttributeError('get prop') - return self.__prop - - def __set_prop(self, value): - if 'set' not in self.__ops: - raise AttributeError('set prop') - self.__prop = value - - def __del_prop(self): - if 'del' not in self.__ops: - raise AttributeError('del prop') - self.__prop = None - - prop = property(__get_prop, __set_prop, __del_prop) - - -class test_Fuzzy(object): - klass = util.Fuzzy - - def test_init(self): - inst = self.klass() - assert inst.regex is None - assert inst.type is None - assert inst.test is None - assert inst.re is None - - inst = self.klass('(foo|bar)') - assert inst.regex == '(foo|bar)' - assert inst.type is unicode - assert inst.test is None - assert isinstance(inst.re, re._pattern_type) - - inst = self.klass('(foo|bar)', type=str) - assert inst.regex == '(foo|bar)' - assert inst.type is str - assert inst.test is None - assert isinstance(inst.re, re._pattern_type) - - t = lambda other: other > 500 - - inst = self.klass(test=t) - assert inst.regex is None - assert inst.type is None - assert inst.test is t - assert inst.re is None - - inst = self.klass(type=(int, float), test=t) - assert inst.regex is None - assert inst.type == (int, float) - assert inst.test is t - assert inst.re is None - - def test_repr(self): - s = 'Fuzzy(%r, %r, %r)' - t = lambda other: 0.0 <= other <= 1.0 - - inst = self.klass() - assert repr(inst) == s % (None, None, None) - - inst = self.klass('foo') - assert repr(inst) == s % ('foo', unicode, None) - - inst = self.klass(type=(int, float)) - assert repr(inst) == s % (None, (int, float), None) - - inst = self.klass(type=(int, float), test=t) - assert repr(inst) == s % (None, (int, float), t) - - inst = self.klass(test=t) - assert repr(inst) == s % (None, None, t) - - def test_eq(self): - assert (self.klass('bar') == u'foobar') is True - assert (self.klass('^bar') == u'foobar') is False - assert (self.klass('bar', type=str) == u'foobar') is False - - assert ('18' == self.klass()) is True - assert ('18' == self.klass(type=int)) is False - assert (18 == self.klass(type=int)) is True - assert ('18' == self.klass(type=(int, str))) is True - - assert (self.klass() == '18') is True - assert (self.klass(type=int) == '18') is False - assert (self.klass(type=int) == 18) is True - assert (self.klass(type=(int, str)) == '18') is True - - t = lambda other: other.endswith('bar') - assert (self.klass(test=t) == 'foobar') is True - assert (self.klass(test=t, type=unicode) == 'foobar') is False - assert (self.klass(test=t) == 'barfoo') is False - - assert (False == self.klass()) is True - assert (True == self.klass()) is True - assert (None == self.klass()) is True - - -def test_assert_deepequal(): - f = util.assert_deepequal - - # Test with good scalar values: - f(u'hello', u'hello') - f(util.Fuzzy(), u'hello') - f(util.Fuzzy(type=unicode), u'hello') - f(util.Fuzzy('ell'), u'hello') - f(util.Fuzzy(test=lambda other: other.endswith('llo')), u'hello') - f(18, 18) - f(util.Fuzzy(), 18) - f(util.Fuzzy(type=int), 18) - f(util.Fuzzy(type=(int, float), test=lambda other: other > 17.9), 18) - - # Test with bad scalar values: - e = raises(AssertionError, f, u'hello', u'world', 'foo') - assert str(e) == VALUE % ( - 'foo', u'hello', u'world', tuple() - ) - - e = raises(AssertionError, f, 'hello', u'hello', 'foo') - assert str(e) == TYPE % ( - 'foo', str, unicode, 'hello', u'hello', tuple() - ) - - e = raises(AssertionError, f, 18, 18.0, 'foo') - assert str(e) == TYPE % ( - 'foo', int, float, 18, 18.0, tuple() - ) - - # Test with good compound values: - a = [ - u'hello', - dict(naughty=u'nurse'), - 18, - ] - b = [ - u'hello', - dict(naughty=u'nurse'), - 18, - ] - f(a, b) - - # Test with bad compound values: - b = [ - 'hello', - dict(naughty=u'nurse'), - 18, - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == TYPE % ( - 'foo', unicode, str, u'hello', 'hello', (2,) - ) - - b = [ - u'hello', - dict(naughty='nurse'), - 18, - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == TYPE % ( - 'foo', unicode, str, u'nurse', 'nurse', (1, 'naughty') - ) - - b = [ - u'hello', - dict(naughty=u'nurse'), - 18.0, - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == TYPE % ( - 'foo', int, float, 18, 18.0, (0,) - ) - - # List length mismatch - b = [ - u'hello', - dict(naughty=u'nurse'), - 18, - 19 - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == LEN % ( - 'foo', 3, 4, a, b, tuple() - ) - - b = [ - dict(naughty=u'nurse'), - 18, - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == LEN % ( - 'foo', 3, 2, a, b, tuple() - ) - - # Dict keys mismatch: - - # Missing - b = [ - u'hello', - dict(), - 18, - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == KEYS % ('foo', - ['naughty'], [], - dict(naughty=u'nurse'), dict(), - (1,) - ) - - # Extra - b = [ - u'hello', - dict(naughty=u'nurse', barely=u'legal'), - 18, - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == KEYS % ('foo', - [], ['barely'], - dict(naughty=u'nurse'), dict(naughty=u'nurse', barely=u'legal'), - (1,) - ) - - # Missing + Extra - b = [ - u'hello', - dict(barely=u'legal'), - 18, - ] - e = raises(AssertionError, f, a, b, 'foo') - assert str(e) == KEYS % ('foo', - ['naughty'], ['barely'], - dict(naughty=u'nurse'), dict(barely=u'legal'), - (1,) - ) - - -def test_yes_raised(): - f = util.raises - - class SomeError(Exception): - pass - - class AnotherError(Exception): - pass - - def callback1(): - 'raises correct exception' - raise SomeError() - - def callback2(): - 'raises wrong exception' - raise AnotherError() - - def callback3(): - 'raises no exception' - - f(SomeError, callback1) - - raised = False - try: - f(SomeError, callback2) - except AnotherError: - raised = True - assert raised - - raised = False - try: - f(SomeError, callback3) - except util.ExceptionNotRaised: - raised = True - assert raised - - -def test_no_set(): - # Tests that it works when prop cannot be set: - util.no_set(Prop('get', 'del'), 'prop') - - # Tests that ExceptionNotRaised is raised when prop *can* be set: - raised = False - try: - util.no_set(Prop('set'), 'prop') - except util.ExceptionNotRaised: - raised = True - assert raised - - -def test_no_del(): - # Tests that it works when prop cannot be deleted: - util.no_del(Prop('get', 'set'), 'prop') - - # Tests that ExceptionNotRaised is raised when prop *can* be set: - raised = False - try: - util.no_del(Prop('del'), 'prop') - except util.ExceptionNotRaised: - raised = True - assert raised - - -def test_read_only(): - # Test that it works when prop is read only: - assert util.read_only(Prop('get'), 'prop') == 'prop value' - - # Test that ExceptionNotRaised is raised when prop can be set: - raised = False - try: - util.read_only(Prop('get', 'set'), 'prop') - except util.ExceptionNotRaised: - raised = True - assert raised - - # Test that ExceptionNotRaised is raised when prop can be deleted: - raised = False - try: - util.read_only(Prop('get', 'del'), 'prop') - except util.ExceptionNotRaised: - raised = True - assert raised - - # Test that ExceptionNotRaised is raised when prop can be both set and - # deleted: - raised = False - try: - util.read_only(Prop('get', 'del'), 'prop') - except util.ExceptionNotRaised: - raised = True - assert raised - - # Test that AttributeError is raised when prop can't be read: - raised = False - try: - util.read_only(Prop(), 'prop') - except AttributeError: - raised = True - assert raised diff --git a/tests/test_xmlrpc/__init__.py b/tests/test_xmlrpc/__init__.py deleted file mode 100644 index 1a8ecf1c2..000000000 --- a/tests/test_xmlrpc/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Sub-package containing unit tests for `xmlrpc` package. -""" diff --git a/tests/test_xmlrpc/objectclasses.py b/tests/test_xmlrpc/objectclasses.py deleted file mode 100644 index 75ac3eb17..000000000 --- a/tests/test_xmlrpc/objectclasses.py +++ /dev/null @@ -1,163 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Defines the expected objectclass for various entries. -""" - -user_base = [ - u'top', - u'person', - u'organizationalperson', - u'inetorgperson', - u'inetuser', - u'posixaccount', - u'krbprincipalaux', - u'krbticketpolicyaux', - u'ipaobject', - u'ipasshuser', - u'ipaSshGroupOfPubKeys', -] - -user = user_base + [u'mepOriginEntry'] - -group = [ - u'top', - u'groupofnames', - u'nestedgroup', - u'ipausergroup', - u'ipaobject', -] - -externalgroup = group + [u'ipaexternalgroup'] -posixgroup = group + [u'posixgroup'] - -host = [ - u'ipasshhost', - u'ipaSshGroupOfPubKeys', - u'ieee802device', - u'ipaobject', - u'nshost', - u'ipahost', - u'pkiuser', - u'ipaservice', - u'krbprincipalaux', - u'krbprincipal', - u'top', -] - -hostgroup = [ - u'ipaobject', - u'ipahostgroup', - u'nestedGroup', - u'groupOfNames', - u'top', - u'mepOriginEntry', -] - -role = [ - u'groupofnames', - u'nestedgroup', - u'top', -] - -permission = [ - u'groupofnames', - u'ipapermission', - u'top' -] - -privilege = [ - u'nestedgroup', - u'groupofnames', - u'top' -] - -service = [ - u'krbprincipal', - u'krbprincipalaux', - u'krbticketpolicyaux', - u'ipaobject', - u'ipaservice', - u'pkiuser', - u'ipakrbprincipal', - u'top', -] - -hbacsvc = [ - u'ipaobject', - u'ipahbacservice', -] - -hbacsvcgroup = [ - u'ipaobject', - u'ipahbacservicegroup', - u'groupOfNames', - u'top', -] - -sudocmd = [ - u'ipaobject', - u'ipasudocmd', -] - -sudocmdgroup = [ - u'ipaobject', - u'ipasudocmdgrp', - u'groupOfNames', - u'top', -] - -netgroup = [ - u'ipaobject', - u'ipaassociation', - u'ipanisnetgroup', -] - -automember = [ - u'top', - u'automemberregexrule', -] - -selinuxusermap = [ - u'ipaassociation', - u'ipaselinuxusermap', -] - -hbacrule = [ - u'ipaassociation', - u'ipahbacrule', -] - -dnszone = [ - u'top', - u'idnsrecord', - u'idnszone', -] - -dnsrecord = [ - u'top', - u'idnsrecord', -] - -realmdomains = [ - u'top', - u'nsContainer', - u'domainRelatedObject', -] diff --git a/tests/test_xmlrpc/test_attr.py b/tests/test_xmlrpc/test_attr.py deleted file mode 100644 index 050ea08cc..000000000 --- a/tests/test_xmlrpc/test_attr.py +++ /dev/null @@ -1,562 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test --setattr and --addattr and other attribute-specific issues -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -user1=u'tuser1' - -class test_attr(Declarative): - - cleanup_commands = [ - ('user_del', [user1], {}), - ] - - tests = [ - - dict( - desc='Try to add user %r with single-value attribute set via ' - 'option and --addattr' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - addattr=u'sn=User2') - ), - expected=errors.OnlyOneValueAllowed(attr='sn'), - ), - - dict( - desc='Create %r' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - setattr=None) - ), - expected=dict( - value=user1, - summary=u'Added user "tuser1"', - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - dn=DN(('uid','tuser1'),('cn','users'),('cn','accounts'), - api.env.basedn), - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Change givenname, add mail %r' % user1, - command=( - 'user_mod', [user1], dict(setattr=(u'givenname=Finkle', u'mail=test@example.com')) - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com'], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Add another mail %r' % user1, - command=( - 'user_mod', [user1], dict(addattr=u'mail=test2@example.com') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Add two phone numbers at once %r' % user1, - command=( - 'user_mod', [user1], dict(setattr=u'telephoneNumber=410-555-1212', addattr=u'telephoneNumber=301-555-1212') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'410-555-1212', u'301-555-1212'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Go from two phone numbers to one %r' % user1, - command=( - 'user_mod', [user1], dict(setattr=u'telephoneNumber=301-555-1212') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'301-555-1212'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Add two more phone numbers %r' % user1, - command=( - 'user_mod', [user1], dict(addattr=(u'telephoneNumber=703-555-1212', u'telephoneNumber=202-888-9833')) - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'301-555-1212', u'202-888-9833', u'703-555-1212'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Delete one phone number for %r' % user1, - command=( - 'user_mod', [user1], dict(delattr=u'telephoneNumber=301-555-1212') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'202-888-9833', u'703-555-1212'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Try deleting the number again for %r' % user1, - command=( - 'user_mod', [user1], dict(delattr=u'telephoneNumber=301-555-1212') - ), - expected=errors.AttrValueNotFound(attr=u'telephonenumber', - value=u'301-555-1212') - ), - - - dict( - desc='Add and delete one phone number for %r' % user1, - command=( - 'user_mod', [user1], dict(addattr=u'telephoneNumber=301-555-1212', - delattr=u'telephoneNumber=202-888-9833') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'301-555-1212', u'703-555-1212'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Add and delete the same phone number for %r' % user1, - command=( - 'user_mod', [user1], dict(addattr=(u'telephoneNumber=301-555-1212', - u'telephoneNumber=202-888-9833'), - delattr=u'telephoneNumber=301-555-1212') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'703-555-1212', u'301-555-1212', u'202-888-9833'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Set and delete a phone number for %r' % user1, - command=( - 'user_mod', [user1], dict(setattr=(u'telephoneNumber=301-555-1212', - u'telephoneNumber=202-888-9833'), - delattr=u'telephoneNumber=301-555-1212') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'202-888-9833'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Try setting givenname to None with setattr in %r' % user1, - command=( - 'user_mod', [user1], dict(setattr=(u'givenname=')) - ), - expected=errors.RequirementError(name='givenname'), - ), - - - dict( - desc='Try setting givenname to None with option in %r' % user1, - command=( - 'user_mod', [user1], dict(givenname=None) - ), - expected=errors.RequirementError(name='first'), - ), - - - dict( - desc='Make sure setting givenname works with option in %r' % user1, - command=( - 'user_mod', [user1], dict(givenname=u'Fred') - ), - expected=dict( - result=dict( - givenname=[u'Fred'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'202-888-9833'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Make sure setting givenname works with setattr in %r' % user1, - command=( - 'user_mod', [user1], dict(setattr=u'givenname=Finkle') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'202-888-9833'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - dict( - desc='Lock %r using setattr' % user1, - command=( - 'user_mod', [user1], dict(setattr=u'nsaccountlock=TrUe') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'202-888-9833'], - nsaccountlock=True, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - dict( - desc='Unlock %r using addattr&delattr' % user1, - command=( - 'user_mod', [user1], dict( - addattr=u'nsaccountlock=FaLsE', - delattr=u'nsaccountlock=TRUE') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test@example.com', u'test2@example.com'], - memberof_group=[u'ipausers'], - telephonenumber=[u'202-888-9833'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - dict( - desc='Try adding a new group search fields config entry', - command=( - 'config_mod', [], dict(addattr=u'ipagroupsearchfields=newattr') - ), - expected=errors.OnlyOneValueAllowed(attr='ipagroupsearchfields'), - ), - - dict( - desc='Try adding a new cert subject base config entry', - command=( - 'config_mod', [], dict(addattr=u'ipacertificatesubjectbase=0=DOMAIN.COM') - ), - expected=errors.ValidationError(name='ipacertificatesubjectbase', - error='attribute is not configurable'), - ), - - dict( - desc='Try deleting a required config entry', - command=( - 'config_mod', [], dict(delattr=u'ipasearchrecordslimit=100') - ), - expected=errors.RequirementError(name='ipasearchrecordslimit'), - ), - - dict( - desc='Try setting nonexistent attribute', - command=('config_mod', [], dict(setattr=u'invalid_attr=false')), - expected=errors.ObjectclassViolation( - info='attribute "invalid_attr" not allowed'), - ), - - dict( - desc='Try setting out-of-range krbpwdmaxfailure', - command=('pwpolicy_mod', [], dict(setattr=u'krbpwdmaxfailure=-1')), - expected=errors.ValidationError(name='krbpwdmaxfailure', - error='must be at least 0'), - ), - - dict( - desc='Try setting out-of-range maxfail', - command=('pwpolicy_mod', [], dict(krbpwdmaxfailure=u'-1')), - expected=errors.ValidationError(name='maxfail', - error='must be at least 0'), - ), - - dict( - desc='Try setting non-numeric krbpwdmaxfailure', - command=('pwpolicy_mod', [], dict(setattr=u'krbpwdmaxfailure=abc')), - expected=errors.ConversionError(name='krbpwdmaxfailure', - error='must be an integer'), - ), - - dict( - desc='Try setting non-numeric maxfail', - command=('pwpolicy_mod', [], dict(krbpwdmaxfailure=u'abc')), - expected=errors.ConversionError(name='maxfail', - error='must be an integer'), - ), - - dict( - desc='Try deleting bogus attribute', - command=('config_mod', [], dict(delattr=u'bogusattribute=xyz')), - expected=errors.ValidationError(name='bogusattribute', - error='No such attribute on this entry'), - ), - - dict( - desc='Try deleting empty attribute', - command=('config_mod', [], - dict(delattr=u'ipaCustomFields=See Also,seealso,false')), - expected=errors.ValidationError(name='ipacustomfields', - error='No such attribute on this entry'), - ), - - dict( - desc='Set and delete one value, plus try deleting a missing one', - command=('config_mod', [], dict( - delattr=[u'ipaCustomFields=See Also,seealso,false', - u'ipaCustomFields=Country,c,false'], - addattr=u'ipaCustomFields=See Also,seealso,false')), - expected=errors.AttrValueNotFound(attr='ipacustomfields', - value='Country,c,false'), - ), - - dict( - desc='Try to delete an operational attribute with --delattr', - command=('config_mod', [], dict( - delattr=u'creatorsName=cn=directory manager')), - expected=errors.DatabaseError( - desc='Server is unwilling to perform', info=''), - ), - - ] diff --git a/tests/test_xmlrpc/test_automember_plugin.py b/tests/test_xmlrpc/test_automember_plugin.py deleted file mode 100644 index fdf3c73af..000000000 --- a/tests/test_xmlrpc/test_automember_plugin.py +++ /dev/null @@ -1,1095 +0,0 @@ -# Authors: -# Jr Aquino -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/automember.py` module. -""" - -from ipalib import api, errors -from ipapython.dn import DN -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid - - -user1=u'tuser1' -manager1=u'mscott' -fqdn1 = u'web1.%s' % api.env.domain -short1 = u'web1' -fqdn2 = u'dev1.%s' % api.env.domain -short2 = u'dev1' -fqdn3 = u'web5.%s' % api.env.domain -short3 = u'web5' -fqdn4 = u'www5.%s' % api.env.domain -short4 = u'www5' -fqdn5 = u'webserver5.%s' % api.env.domain -short5 = u'webserver5' - -group1=u'group1' -defaultgroup1=u'defaultgroup1' -hostgroup1=u'hostgroup1' -hostgroup2=u'hostgroup2' -hostgroup3=u'hostgroup3' -hostgroup4=u'hostgroup4' -defaulthostgroup1=u'defaulthostgroup1' - -group_include_regex = u'mscott' -hostgroup_include_regex = u'^web[1-9]' -hostgroup_include_regex2 = u'^www[1-9]' -hostgroup_include_regex3 = u'webserver[1-9]' -hostgroup_exclude_regex = u'^web5' -hostgroup_exclude_regex2 = u'^www5' -hostgroup_exclude_regex3 = u'^webserver5' - - -class test_automember(Declarative): - - cleanup_commands = [ - ('user_del', [user1, manager1], {}), - ('group_del', [group1, defaultgroup1], {}), - ('host_del', [fqdn1, fqdn2, fqdn3, fqdn4, fqdn5], {}), - ('hostgroup_del', [hostgroup1, hostgroup2, hostgroup3, hostgroup4, defaulthostgroup1], {}), - ('automember_del', [group1], {'type': u'group'}), - ('automember_del', [hostgroup1], {'type': u'hostgroup'}), - ('automember_del', [hostgroup2], {'type': u'hostgroup'}), - ('automember_del', [hostgroup3], {'type': u'hostgroup'}), - ('automember_del', [hostgroup4], {'type': u'hostgroup'}), - ('automember_default_group_remove', [], {'type': u'hostgroup'}), - ('automember_default_group_remove', [], {'type': u'group'}), - - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent group rule %r' % group1, - command=('automember_add', [group1], - dict(description=u'Test desc', type=u'group')), - expected=errors.NotFound(reason=u'Group: %s not found!' % group1), - ), - - dict( - desc='Try to update non-existent group rule %r' % group1, - command=('automember_add', [group1], dict(type=u'group')), - expected=errors.NotFound(reason=u'Group: %s not found!' % group1), - ), - - dict( - desc='Try to delete non-existent group rule %r' % group1, - command=('automember_del', [group1], dict(type=u'group')), - expected=errors.NotFound(reason=u': auto_member_rule not found'), - ), - - - dict( - desc='Try to retrieve non-existent hostgroup rule %r' % hostgroup1, - command=('automember_add', [hostgroup1], - dict(description=u'Test desc', type=u'hostgroup')), - expected=errors.NotFound( - reason=u'Group: %s not found!' % hostgroup1), - ), - - dict( - desc='Try to update non-existent hostgroup rule %r' % hostgroup1, - command=('automember_add', [hostgroup1], dict(type=u'hostgroup')), - expected=errors.NotFound( - reason=u'Group: %s not found!' % hostgroup1), - ), - - dict( - desc='Try to delete non-existent hostgroup rule %r' % hostgroup1, - command=('automember_del', [hostgroup1], dict(type=u'hostgroup')), - expected=errors.NotFound(reason=u': auto_member_rule not found'), - ), - - - - dict( - desc='Create %r' % group1, - command=( - 'group_add', [group1], dict(description=u'Test desc') - ), - expected=dict( - value=group1, - summary=u'Added group "%s"' % group1, - result=dict( - cn=[group1], - description=[u'Test desc'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % hostgroup1, - command=( - 'hostgroup_add', [hostgroup1], dict(description=u'Test desc') - ), - expected=dict( - value=hostgroup1, - summary=u'Added hostgroup "%s"' % hostgroup1, - result=dict( - cn=[hostgroup1], - description=[u'Test desc'], - objectclass=objectclasses.hostgroup, - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn', hostgroup1), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)], - dn=DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % hostgroup2, - command=( - 'hostgroup_add', [hostgroup2], dict(description=u'Test desc') - ), - expected=dict( - value=hostgroup2, - summary=u'Added hostgroup "%s"' % hostgroup2, - result=dict( - cn=[hostgroup2], - description=[u'Test desc'], - objectclass=objectclasses.hostgroup, - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn', hostgroup2), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)], - dn=DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % hostgroup3, - command=( - 'hostgroup_add', [hostgroup3], dict(description=u'Test desc') - ), - expected=dict( - value=hostgroup3, - summary=u'Added hostgroup "%s"' % hostgroup3, - result=dict( - cn=[hostgroup3], - description=[u'Test desc'], - objectclass=objectclasses.hostgroup, - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn', hostgroup3), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)], - dn=DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % hostgroup4, - command=( - 'hostgroup_add', [hostgroup4], dict(description=u'Test desc') - ), - expected=dict( - value=hostgroup4, - summary=u'Added hostgroup "%s"' % hostgroup4, - result=dict( - cn=[hostgroup4], - description=[u'Test desc'], - objectclass=objectclasses.hostgroup, - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn', hostgroup4), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)], - dn=DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % defaultgroup1, - command=( - 'group_add', [defaultgroup1], dict(description=u'Default test desc') - ), - expected=dict( - value=defaultgroup1, - summary=u'Added group "%s"' % defaultgroup1, - result=dict( - cn=[defaultgroup1], - description=[u'Default test desc'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn', defaultgroup1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % defaulthostgroup1, - command=( - 'hostgroup_add', [defaulthostgroup1], dict(description=u'Default test desc') - ), - expected=dict( - value=defaulthostgroup1, - summary=u'Added hostgroup "%s"' % defaulthostgroup1, - result=dict( - cn=[defaulthostgroup1], - description=[u'Default test desc'], - objectclass=objectclasses.hostgroup, - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn', defaulthostgroup1), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)], - dn=DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create automember %r' % group1, - command=( - 'automember_add', [group1], dict(description=u'Test desc', type=u'group') - ), - expected=dict( - value=group1, - summary=u'Added automember rule "%s"' % group1, - result=dict( - cn=[group1], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - objectclass=objectclasses.automember, - dn=DN(('cn', group1), ('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create automember condition %r' % group1, - command=( - 'automember_add_condition', [group1], dict( - key=u'manager', type=u'group', - automemberinclusiveregex=[group_include_regex], - ) - ), - expected=dict( - value=group1, - summary=u'Added condition(s) to "%s"' % group1, - completed=1, - failed=dict( - failed = dict( - automemberinclusiveregex=tuple(), - automemberexclusiveregex=tuple(), - ) - ), - result=dict( - cn=[group1], - description=[u'Test desc'], - automemberinclusiveregex=[u'manager=%s' % group_include_regex], - automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - ), - ), - ), - - - dict( - desc='Create automember %r' % hostgroup1, - command=( - 'automember_add', [hostgroup1], dict( - description=u'Test desc', type=u'hostgroup', - ) - ), - expected=dict( - value=hostgroup1, - summary=u'Added automember rule "%s"' % hostgroup1, - result=dict( - cn=[hostgroup1], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - objectclass=objectclasses.automember, - dn=DN(('cn', hostgroup1), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create automember condition %r' % hostgroup1, - command=( - 'automember_add_condition', [hostgroup1], dict( - key=u'fqdn', type=u'hostgroup', - automemberinclusiveregex=[hostgroup_include_regex], - ) - ), - expected=dict( - value=hostgroup1, - summary=u'Added condition(s) to "%s"' % hostgroup1, - completed=1, - failed=dict( - failed = dict( - automemberinclusiveregex=tuple(), - automemberexclusiveregex=tuple(), - ) - ), - result=dict( - cn=[hostgroup1], - description=[u'Test desc'], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex], - automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - ), - ), - ), - - - dict( - desc='Create duplicate automember condition %r' % hostgroup1, - command=( - 'automember_add_condition', [hostgroup1], dict( - key=u'fqdn', type=u'hostgroup', - automemberinclusiveregex=[hostgroup_include_regex], - ) - ), - expected=dict( - value=hostgroup1, - summary=u'Added condition(s) to "%s"' % hostgroup1, - completed=0, - failed=dict( - failed = dict( - automemberinclusiveregex=tuple(), - automemberexclusiveregex=tuple(), - ) - ), - result=dict( - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex], - ), - ), - ), - - - dict( - desc='Create additional automember conditions %r' % hostgroup1, - command=( - 'automember_add_condition', [hostgroup1], dict( - key=u'fqdn', type=u'hostgroup', - automemberinclusiveregex=[hostgroup_include_regex2, hostgroup_include_regex3], - automemberexclusiveregex=[hostgroup_exclude_regex, hostgroup_exclude_regex2, hostgroup_exclude_regex3], - ) - ), - expected=dict( - value=hostgroup1, - summary=u'Added condition(s) to "%s"' % hostgroup1, - completed=5, - failed=dict( - failed = dict( - automemberinclusiveregex=tuple(), - automemberexclusiveregex=tuple(), - ) - ), - result=dict( - cn=[hostgroup1], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex, - u'fqdn=%s' % hostgroup_include_regex3, - u'fqdn=%s' % hostgroup_include_regex2, - ], - automemberexclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex2, - u'fqdn=%s' % hostgroup_exclude_regex3, - u'fqdn=%s' % hostgroup_exclude_regex, - ], - ), - ), - ), - - - dict( - desc='Create automember %r' % hostgroup2, - command=( - 'automember_add', [hostgroup2], dict( - description=u'Test desc', type=u'hostgroup', - ) - ), - expected=dict( - value=hostgroup2, - summary=u'Added automember rule "%s"' % hostgroup2, - result=dict( - cn=[hostgroup2], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - objectclass=objectclasses.automember, - dn=DN(('cn', hostgroup2), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create automember condition %r' % hostgroup2, - command=( - 'automember_add_condition', [hostgroup2], dict( - key=u'fqdn', type=u'hostgroup', - automemberinclusiveregex=[hostgroup_exclude_regex], - ) - ), - expected=dict( - value=hostgroup2, - summary=u'Added condition(s) to "%s"' % hostgroup2, - completed=1, - failed=dict( - failed = dict( - automemberinclusiveregex=tuple(), - automemberexclusiveregex=tuple(), - ) - ), - result=dict( - cn=[hostgroup2], - description=[u'Test desc'], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex], - automembertargetgroup=[DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - ), - ), - ), - - - dict( - desc='Create automember %r' % hostgroup3, - command=( - 'automember_add', [hostgroup3], dict( - description=u'Test desc', type=u'hostgroup', - ) - ), - expected=dict( - value=hostgroup3, - summary=u'Added automember rule "%s"' % hostgroup3, - result=dict( - cn=[hostgroup3], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - objectclass=objectclasses.automember, - dn=DN(('cn', hostgroup3), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create automember condition %r' % hostgroup3, - command=( - 'automember_add_condition', [hostgroup3], dict( - key=u'fqdn', type=u'hostgroup', - automemberinclusiveregex=[hostgroup_exclude_regex2], - ) - ), - expected=dict( - value=hostgroup3, - summary=u'Added condition(s) to "%s"' % hostgroup3, - completed=1, - failed=dict( - failed = dict( - automemberinclusiveregex=tuple(), - automemberexclusiveregex=tuple(), - ) - ), - result=dict( - cn=[hostgroup3], - description=[u'Test desc'], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex2], - automembertargetgroup=[DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - ), - ), - ), - - - dict( - desc='Create automember %r' % hostgroup4, - command=( - 'automember_add', [hostgroup4], dict( - description=u'Test desc', type=u'hostgroup', - ) - ), - expected=dict( - value=hostgroup4, - summary=u'Added automember rule "%s"' % hostgroup4, - result=dict( - cn=[hostgroup4], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - objectclass=objectclasses.automember, - dn=DN(('cn', hostgroup4), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Create automember condition %r' % hostgroup4, - command=( - 'automember_add_condition', [hostgroup4], dict( - key=u'fqdn', type=u'hostgroup', - automemberinclusiveregex=[hostgroup_exclude_regex3], - ) - ), - expected=dict( - value=hostgroup4, - summary=u'Added condition(s) to "%s"' % hostgroup4, - completed=1, - failed=dict( - failed = dict( - automemberinclusiveregex=tuple(), - automemberexclusiveregex=tuple(), - ) - ), - result=dict( - cn=[hostgroup4], - description=[u'Test desc'], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex3], - automembertargetgroup=[DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - ), - ), - ), - - - dict( - desc="Retrieve automember rule for group %s" % group1, - command=('automember_show', [group1], dict( - type=u'group', - ) - ), - expected=dict( - value=group1, - result=dict( - cn=[group1], - description=[u'Test desc'], - automemberinclusiveregex=[u'manager=%s' % group_include_regex], - automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - dn=DN(('cn', group1), ('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - summary=None, - ), - ), - - - dict( - desc='Search for %r' % group1, - command=('automember_find', [group1], dict( - type=u'group' - ) - ), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - cn=[group1], - description=[u'Test desc'], - automemberinclusiveregex=[u'manager=%s' % group_include_regex], - automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - dn=DN(('cn', group1), ('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - ], - summary=u'1 rules matched', - ), - ), - - - dict( - desc='Updated automember rule %r' % group1, - command=( - 'automember_mod', [group1], dict( - type=u'group', - description=u'New desc 1', - ) - ), - expected=dict( - result=dict( - cn=[group1], - description=[u'New desc 1'], - automemberinclusiveregex=[u'manager=%s' % group_include_regex], - automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - ), - summary=u'Modified automember rule "%s"' % group1, - value=group1, - ), - ), - - - dict( - desc="Retrieve automember rule for hostgroup %s" % hostgroup1, - command=('automember_show', [hostgroup1], dict( - type=u'hostgroup', - ) - ), - expected=dict( - value=hostgroup1, - result=dict( - cn=[hostgroup1], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex, - u'fqdn=%s' % hostgroup_include_regex3, - u'fqdn=%s' % hostgroup_include_regex2, - ], - automemberexclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex2, - u'fqdn=%s' % hostgroup_exclude_regex3, - u'fqdn=%s' % hostgroup_exclude_regex, - ], - dn=DN(('cn', hostgroup1), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - summary=None, - ), - ), - - - dict( - desc='Search for %r' % hostgroup1, - command=('automember_find', [hostgroup1], dict( - type=u'hostgroup' - ) - ), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - cn=[hostgroup1], - description=[u'Test desc'], - automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex, - u'fqdn=%s' % hostgroup_include_regex3, - u'fqdn=%s' % hostgroup_include_regex2, - ], - automemberexclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex2, - u'fqdn=%s' % hostgroup_exclude_regex3, - u'fqdn=%s' % hostgroup_exclude_regex, - ], - dn=DN(('cn', hostgroup1), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - ), - ], - summary=u'1 rules matched', - ), - ), - - - dict( - desc='Updated automember rule %r' % hostgroup1, - command=( - 'automember_mod', [hostgroup1], dict( - type=u'hostgroup', - description=u'New desc 1', - ) - ), - expected=dict( - result=dict( - cn=[hostgroup1], - description=[u'New desc 1'], - automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex, - u'fqdn=%s' % hostgroup_include_regex3, - u'fqdn=%s' % hostgroup_include_regex2, - ], - automemberexclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex2, - u'fqdn=%s' % hostgroup_exclude_regex3, - u'fqdn=%s' % hostgroup_exclude_regex, - ], - ), - summary=u'Modified automember rule "%s"' % hostgroup1, - value=hostgroup1, - ), - ), - - - dict( - desc='Set default automember group for groups', - command=( - 'automember_default_group_set', [], dict( - type=u'group', - automemberdefaultgroup=defaultgroup1 - ) - ), - expected=dict( - result=dict( - cn=[u'Group'], - automemberdefaultgroup=[DN(('cn', defaultgroup1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - ), - value=u'group', - summary=u'Set default (fallback) group for automember "group"', - ), - ), - - - dict( - desc='Retrieve default automember group for groups', - command=( - 'automember_default_group_show', [], dict(type=u'group') - ), - expected=dict( - result=dict( - dn=DN(('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - cn=[u'Group'], - automemberdefaultgroup=[DN(('cn', defaultgroup1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - ), - value=u'group', - summary=None, - ), - ), - - - dict( - desc='Set default (fallback) automember group for hostgroups', - command=( - 'automember_default_group_set', [], dict( - type=u'hostgroup', - automemberdefaultgroup=defaulthostgroup1, - ) - ), - expected=dict( - result=dict( - cn=[u'Hostgroup'], - automemberdefaultgroup=[DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - ), - value=u'hostgroup', - summary=u'Set default (fallback) group for automember "hostgroup"', - ), - ), - - - dict( - desc='Retrieve default automember group for hostgroups', - command=( - 'automember_default_group_show', [], dict( - type=u'hostgroup', - ) - ), - expected=dict( - result=dict( - dn=DN(('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn), - cn=[u'Hostgroup'], - automemberdefaultgroup=[DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)], - ), - value=u'hostgroup', - summary=None, - ), - ), - - - dict( - desc='Create %r' % manager1, - command=( - 'user_add', [manager1], dict(givenname=u'Michael', sn=u'Scott') - ), - expected=dict( - value=manager1, - summary=u'Added user "mscott"', - result=dict( - gecos=[u'Michael Scott'], - givenname=[u'Michael'], - homedirectory=[u'/home/mscott'], - krbprincipalname=[u'mscott@' + api.env.realm], - has_keytab=False, - has_password=False, - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'Scott'], - uid=[manager1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (manager1, api.env.domain)], - displayname=[u'Michael Scott'], - cn=[u'Michael Scott'], - initials=[u'MS'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn', 'global_policy'), ('cn', api.env.realm), ('cn', 'kerberos'), - api.env.basedn)], - mepmanagedentry=[DN(('cn', manager1), ('cn', 'groups'), ('cn', 'accounts'), - api.env.basedn)], - memberof_group=[u'defaultgroup1', u'ipausers'], - dn=DN(('uid', 'mscott'), ('cn', 'users'), ('cn', 'accounts'), - api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', manager=manager1) - ), - expected=dict( - value=user1, - summary=u'Added user "tuser1"', - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - has_keytab=False, - has_password=False, - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - manager=[DN(('uid', 'mscott'), ('cn', 'users'), ('cn', 'accounts'), api.env.basedn)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn', 'global_policy'), ('cn', api.env.realm), ('cn', 'kerberos'), - api.env.basedn)], - mepmanagedentry=[DN(('cn', user1), ('cn', 'groups'), ('cn', 'accounts'), - api.env.basedn)], - memberof_group=[u'group1', u'ipausers'], - dn=DN(('uid', 'tuser1'), ('cn', 'users'), ('cn', 'accounts'), - api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % fqdn1, - command=('host_add', [fqdn1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn1, - summary=u'Added host "%s"' % fqdn1, - result=dict( - dn=DN(('fqdn', fqdn1), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn), - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - has_keytab=False, - has_password=False, - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn1], - memberof_hostgroup=[hostgroup1], - memberofindirect_netgroup=[hostgroup1], - ), - ), - ), - - - dict( - desc='Create %r' % fqdn2, - command=('host_add', [fqdn2], - dict( - description=u'Test host 2', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn2, - summary=u'Added host "%s"' % fqdn2, - result=dict( - dn=DN(('fqdn', fqdn2), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn), - fqdn=[fqdn2], - description=[u'Test host 2'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn2, api.env.realm)], - has_keytab=False, - has_password=False, - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn2], - memberof_hostgroup=[defaulthostgroup1], - memberofindirect_netgroup=[defaulthostgroup1], - ), - ), - ), - - - dict( - desc='Create %r' % fqdn3, - command=('host_add', [fqdn3], - dict( - description=u'Test host 3', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn3, - summary=u'Added host "%s"' % fqdn3, - result=dict( - dn=DN(('fqdn', fqdn3), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn), - fqdn=[fqdn3], - description=[u'Test host 3'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn3, api.env.realm)], - has_keytab=False, - has_password=False, - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn3], - memberof_hostgroup=[hostgroup2], - memberofindirect_netgroup=[hostgroup2], - ), - ), - ), - - - dict( - desc='Create %r' % fqdn4, - command=('host_add', [fqdn4], - dict( - description=u'Test host 4', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn4, - summary=u'Added host "%s"' % fqdn4, - result=dict( - dn=DN(('fqdn', fqdn4), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn), - fqdn=[fqdn4], - description=[u'Test host 4'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn4, api.env.realm)], - has_keytab=False, - has_password=False, - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn4], - memberof_hostgroup=[hostgroup3], - memberofindirect_netgroup=[hostgroup3], - ), - ), - ), - - - dict( - desc='Create %r' % fqdn5, - command=('host_add', [fqdn5], - dict( - description=u'Test host 5', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn5, - summary=u'Added host "%s"' % fqdn5, - result=dict( - dn=DN(('fqdn', fqdn5), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn), - fqdn=[fqdn5], - description=[u'Test host 5'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn5, api.env.realm)], - has_keytab=False, - has_password=False, - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn5], - memberof_hostgroup=[hostgroup4], - memberofindirect_netgroup=[hostgroup4], - ), - ), - ), - - - dict( - desc='Retrieve %r' % hostgroup1, - command=('hostgroup_show', [hostgroup1], {}), - expected=dict( - value=hostgroup1, - summary=None, - result={ - 'dn': DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - 'member_host': [u'%s' % fqdn1], - 'cn': [hostgroup1], - 'description': [u'Test desc'], - }, - ), - ), - - - dict( - desc='Retrieve %r' % defaulthostgroup1, - command=('hostgroup_show', [defaulthostgroup1], {}), - expected=dict( - value=defaulthostgroup1, - summary=None, - result={ - 'dn': DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - 'member_host': [u'%s' % fqdn2], - 'cn': [defaulthostgroup1], - 'description': [u'Default test desc'], - }, - ), - ), - - - dict( - desc='Retrieve %r' % hostgroup2, - command=('hostgroup_show', [hostgroup2], {}), - expected=dict( - value=hostgroup2, - summary=None, - result={ - 'dn': DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - 'member_host': [u'%s' % fqdn3], - 'cn': [hostgroup2], - 'description': [u'Test desc'], - }, - ), - ), - - - dict( - desc='Retrieve %r' % hostgroup3, - command=('hostgroup_show', [hostgroup3], {}), - expected=dict( - value=hostgroup3, - summary=None, - result={ - 'dn': DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - 'member_host': [u'%s' % fqdn4], - 'cn': [hostgroup3], - 'description': [u'Test desc'], - }, - ), - ), - - - dict( - desc='Retrieve %r' % hostgroup4, - command=('hostgroup_show', [hostgroup4], {}), - expected=dict( - value=hostgroup4, - summary=None, - result={ - 'dn': DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn), - 'member_host': [u'%s' % fqdn5], - 'cn': [hostgroup4], - 'description': [u'Test desc'], - }, - ), - ), - - ] diff --git a/tests/test_xmlrpc/test_automount_plugin.py b/tests/test_xmlrpc/test_automount_plugin.py deleted file mode 100644 index 19968a0dc..000000000 --- a/tests/test_xmlrpc/test_automount_plugin.py +++ /dev/null @@ -1,582 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/automount.py' module. -""" - -import sys -import textwrap -import tempfile -import shutil - -from ipalib import api -from ipalib import errors -from ipapython.dn import DN - -from nose.tools import raises, assert_raises # pylint: disable=E0611 -from xmlrpc_test import XMLRPC_test, assert_attr_equal -from tests.util import assert_deepequal - - -class MockTextui(list): - """Collects output lines""" - # Extend the mock object if other textui methods are called - def print_plain(self, line): - self.append(unicode(line)) - - -class AutomountTest(XMLRPC_test): - """Provides common functionality for automount tests""" - def check_tofiles(self): - """Check automountlocation_tofiles output against self.tofiles_output - """ - res = api.Command['automountlocation_tofiles'](self.locname) - - mock_ui = MockTextui() - command = api.Command['automountlocation_tofiles'] - command.output_for_cli(mock_ui, res, self.locname) - expected_output = self.tofiles_output - assert_deepequal(expected_output, u'\n'.join(mock_ui)) - - def check_import_roundtrip(self): - """Check automountlocation_tofiles/automountlocation_import roundtrip - - Loads self.tofiles_output (which should correspond to - automountlocation_tofiles output), then checks the resulting map - against tofiles_output again. - Do not use this if the test creates maps that aren't connected to - auto.master -- these can't be imported successfully. - """ - conf_directory = tempfile.mkdtemp() - - # Parse the tofiles_output into individual files, replace /etc/ by - # our temporary directory name - current_file = None - for line in self.tofiles_output.splitlines(): - line = line.replace('/etc/', '%s/' % conf_directory) - if line.startswith(conf_directory) and line.endswith(':'): - current_file = open(line.rstrip(':'), 'w') - elif '--------' in line: - current_file.close() - elif line.startswith('maps not connected to '): - break - else: - current_file.write(line + '\n') - current_file.close() - - self.failsafe_add(api.Object.automountlocation, self.locname) - - try: - # Feed the files to automountlocation_import & check - master_file = u'%s/auto.master' % conf_directory - automountlocation_import = api.Command['automountlocation_import'] - res = automountlocation_import(self.locname, master_file) - assert_deepequal(dict( - result=dict( - keys=lambda k: k, - maps=lambda m: m, - skipped=(), - duplicatemaps=(), - duplicatekeys=(), - )), res) - self.check_tofiles() - finally: - res = api.Command['automountlocation_del'](self.locname)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Success; delete the temporary directory - shutil.rmtree(conf_directory) - -class test_automount(AutomountTest): - """ - Test the `automount` plugin. - """ - locname = u'testlocation' - mapname = u'testmap' - keyname = u'testkey' - keyname_rename = u'testkey_rename' - keyname2 = u'testkey2' - description = u'description of map' - info = u'ro' - newinfo = u'rw' - map_kw = {'automountmapname': mapname, 'description': description, 'raw': True} - key_kw = {'automountkey': keyname, 'automountinformation': info, 'raw': True} - key_kw2 = {'automountkey': keyname2, 'automountinformation': info, 'raw': True} - - tofiles_output = textwrap.dedent(u""" - /etc/auto.master: - /-\t/etc/auto.direct - --------------------------- - /etc/auto.direct: - - maps not connected to /etc/auto.master: - --------------------------- - /etc/testmap: - testkey2\tro - """).strip() - - def test_0_automountlocation_add(self): - """ - Test adding a location `xmlrpc.automountlocation_add` method. - """ - ret = self.failsafe_add( - api.Object.automountlocation, self.locname - ) - entry = ret['result'] - assert_attr_equal(entry, 'cn', self.locname) - - def test_1_automountmap_add(self): - """ - Test adding a map `xmlrpc.automountmap_add` method. - """ - res = api.Command['automountmap_add'](self.locname, **self.map_kw)['result'] - assert res - assert_attr_equal(res, 'automountmapname', self.mapname) - - def test_2_automountkey_add(self): - """ - Test adding a key using `xmlrpc.automountkey_add` method. - """ - res = api.Command['automountkey_add'](self.locname, self.mapname, **self.key_kw2)['result'] - assert res - assert_attr_equal(res, 'automountkey', self.keyname2) - - def test_3_automountkey_add(self): - """ - Test adding a key using `xmlrpc.automountkey_add` method. - """ - res = api.Command['automountkey_add'](self.locname, self.mapname, **self.key_kw)['result'] - assert res - assert_attr_equal(res, 'automountkey', self.keyname) - - @raises(errors.DuplicateEntry) - def test_4_automountkey_add(self): - """ - Test adding a duplicate key using `xmlrpc.automountkey_add` method. - """ - res = api.Command['automountkey_add'](self.locname, self.mapname, **self.key_kw) - - def test_5_automountmap_show(self): - """ - Test the `xmlrpc.automountmap_show` method. - """ - res = api.Command['automountmap_show'](self.locname, self.mapname, raw=True)['result'] - assert res - assert_attr_equal(res, 'automountmapname', self.mapname) - - def test_6_automountmap_find(self): - """ - Test the `xmlrpc.automountmap_find` method. - """ - res = api.Command['automountmap_find'](self.locname, self.mapname, raw=True)['result'] - assert_attr_equal(res[0], 'automountmapname', self.mapname) - - def test_7_automountkey_show(self): - """ - Test the `xmlrpc.automountkey_show` method. - """ - showkey_kw={'automountkey': self.keyname, 'automountinformation' : self.info, 'raw': True} - res = api.Command['automountkey_show'](self.locname, self.mapname, **showkey_kw)['result'] - assert res - assert_attr_equal(res, 'automountkey', self.keyname) - assert_attr_equal(res, 'automountinformation', self.info) - - def test_8_automountkey_find(self): - """ - Test the `xmlrpc.automountkey_find` method. - """ - res = api.Command['automountkey_find'](self.locname, self.mapname, raw=True)['result'] - assert res - assert len(res) == 2 - assert_attr_equal(res[0], 'automountkey', self.keyname) - assert_attr_equal(res[0], 'automountinformation', self.info) - - def test_9_automountkey_mod(self): - """ - Test the `xmlrpc.automountkey_mod` method. - """ - self.key_kw['newautomountinformation'] = self.newinfo - self.key_kw['rename'] = self.keyname_rename - res = api.Command['automountkey_mod'](self.locname, self.mapname, **self.key_kw)['result'] - assert res - assert_attr_equal(res, 'automountinformation', self.newinfo) - assert_attr_equal(res, 'automountkey', self.keyname_rename) - - def test_a_automountmap_mod(self): - """ - Test the `xmlrpc.automountmap_mod` method. - """ - mod_kw = {'description': u'new description'} - res = api.Command['automountmap_mod'](self.locname, self.mapname, **mod_kw)['result'] - assert res - assert_attr_equal(res, 'description', 'new description') - - def test_a2_automountmap_tofiles(self): - """ - Test the `automountlocation_tofiles` command. - """ - res = api.Command['automountlocation_tofiles'](self.locname) - assert_deepequal(dict( - result=dict( - keys={'auto.direct': ()}, - orphanmaps=(dict( - dn=DN(('automountmapname', self.mapname), - ('cn', self.locname), - ('cn', 'automount'), api.env.basedn), - description=(u'description of map',), - automountmapname=(u'testmap',)),), - orphankeys=[( - dict( - dn=DN(('description', self.keyname2), - ('automountmapname', 'testmap'), - ('cn', self.locname), - ('cn', 'automount'), api.env.basedn), - automountkey=(self.keyname2,), - description=(self.keyname2,), - automountinformation=(u'ro',), - ), - dict( - dn=DN(('description', self.keyname_rename), - ('automountmapname', 'testmap'), - ('cn', self.locname), - ('cn', 'automount'), api.env.basedn), - automountkey=(self.keyname_rename,), - description=(self.keyname_rename,), - automountinformation=(u'rw',), - ))], - maps=( - dict( - dn=DN(('description', '/- auto.direct'), - ('automountmapname', 'auto.master'), - ('cn', self.locname), - ('cn', 'automount'), api.env.basedn), - automountkey=(u'/-',), - description=(u'/- auto.direct',), - automountinformation=(u'auto.direct',) - ), - ))), res) - - # Also check the CLI output - - self.check_tofiles() - - def test_b_automountkey_del(self): - """ - Test the `xmlrpc.automountkey_del` method. - """ - delkey_kw={'automountkey': self.keyname_rename, 'automountinformation' : self.newinfo} - res = api.Command['automountkey_del'](self.locname, self.mapname, **delkey_kw)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verify that it is gone - with assert_raises(errors.NotFound): - api.Command['automountkey_show'](self.locname, self.mapname, **delkey_kw) - - def test_c_automountlocation_del(self): - """ - Test the `xmlrpc.automountlocation_del` method. - """ - res = api.Command['automountlocation_del'](self.locname)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verify that it is gone - with assert_raises(errors.NotFound): - api.Command['automountlocation_show'](self.locname) - - def test_d_automountmap_del(self): - """ - Test that the `xmlrpc.automountlocation_del` method removes all maps and keys - """ - # Verify that the second key we added is gone - key_kw = {'automountkey': self.keyname2, 'automountinformation': self.info, 'raw': True} - with assert_raises(errors.NotFound): - api.Command['automountkey_show'](self.locname, self.mapname, **key_kw) - - -class test_automount_direct(AutomountTest): - """ - Test the `automount` plugin indirect map functionality. - """ - locname = u'testlocation' - mapname = u'auto.direct2' - keyname = u'/-' - direct_kw = { 'key' : keyname } - - tofiles_output = textwrap.dedent(u""" - /etc/auto.master: - /-\t/etc/auto.direct - /-\t/etc/auto.direct2 - --------------------------- - /etc/auto.direct: - --------------------------- - /etc/auto.direct2: - - maps not connected to /etc/auto.master: - """).strip() - - def test_0_automountlocation_add(self): - """ - Test adding a location. - """ - res = api.Command['automountlocation_add'](self.locname, raw=True)['result'] - assert res - assert_attr_equal(res, 'cn', self.locname) - - def test_1_automountmap_add_direct(self): - """ - Test adding a second direct map with a different info - """ - res = api.Command['automountmap_add_indirect'](self.locname, self.mapname, **self.direct_kw)['result'] - assert res - assert_attr_equal(res, 'automountmapname', self.mapname) - - @raises(errors.DuplicateEntry) - def test_2_automountmap_add_duplicate(self): - """ - Test adding a duplicate direct map. - """ - res = api.Command['automountmap_add_indirect'](self.locname, self.mapname, **self.direct_kw)['result'] - - def test_2a_automountmap_tofiles(self): - """Test the `automountmap_tofiles` command""" - self.check_tofiles() - - def test_3_automountlocation_del(self): - """ - Remove the location. - """ - res = api.Command['automountlocation_del'](self.locname)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verity that it is gone - with assert_raises(errors.NotFound): - api.Command['automountlocation_show'](self.locname) - - def test_z_import_roundtrip(self): - """Check automountlocation_tofiles/automountlocation_import roundtrip - """ - self.check_import_roundtrip() - - -class test_automount_indirect(AutomountTest): - """ - Test the `automount` plugin indirect map functionality. - """ - locname = u'testlocation' - mapname = u'auto.home' - keyname = u'/home' - parentmap = u'auto.master' - map_kw = {'key': keyname, 'parentmap': parentmap, 'raw': True} - key_kw = {'automountkey': keyname, 'automountinformation': mapname} - - tofiles_output = textwrap.dedent(u""" - /etc/auto.master: - /-\t/etc/auto.direct - /home\t/etc/auto.home - --------------------------- - /etc/auto.direct: - --------------------------- - /etc/auto.home: - - maps not connected to /etc/auto.master: - """).strip() - - def test_0_automountlocation_add(self): - """ - Test adding a location. - """ - res = api.Command['automountlocation_add'](self.locname, raw=True)['result'] - assert res - assert_attr_equal(res, 'cn', self.locname) - - def test_1_automountmap_add_indirect(self): - """ - Test adding an indirect map. - """ - res = api.Command['automountmap_add_indirect'](self.locname, self.mapname, **self.map_kw)['result'] - assert res - assert_attr_equal(res, 'automountmapname', self.mapname) - - @raises(errors.DuplicateEntry) - def test_1a_automountmap_add_indirect(self): - """ - Test adding a duplicate indirect map. - """ - api.Command['automountmap_add_indirect'](self.locname, self.mapname, **self.map_kw)['result'] - - def test_2_automountmap_show(self): - """ - Test the `xmlrpc.automountmap_show` method. - """ - res = api.Command['automountmap_show'](self.locname, self.mapname, raw=True)['result'] - assert res - assert_attr_equal(res, 'automountmapname', self.mapname) - - def test_2a_automountmap_tofiles(self): - """Test the `automountmap_tofiles` command""" - self.check_tofiles() - - def test_3_automountkey_del(self): - """ - Remove the indirect key /home. - """ - res = api.Command['automountkey_del'](self.locname, self.parentmap, **self.key_kw)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verify that it is gone - with assert_raises(errors.NotFound): - api.Command['automountkey_show'](self.locname, self.parentmap, **self.key_kw) - - def test_4_automountmap_del(self): - """ - Remove the indirect map for auto.home. - """ - res = api.Command['automountmap_del'](self.locname, self.mapname)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verify that it is gone - with assert_raises(errors.NotFound): - api.Command['automountmap_show'](self.locname, self.mapname) - - def test_5_automountlocation_del(self): - """ - Remove the location. - """ - res = api.Command['automountlocation_del'](self.locname)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verity that it is gone - with assert_raises(errors.NotFound): - api.Command['automountlocation_show'](self.locname) - - def test_z_import_roundtrip(self): - """Check automountlocation_tofiles/automountlocation_import roundtrip - """ - self.check_import_roundtrip() - -class test_automount_indirect_no_parent(AutomountTest): - """ - Test the `automount` plugin Indirect map function. - """ - locname = u'testlocation' - mapname = u'auto.home' - keyname = u'/home' - mapname2 = u'auto.direct2' - keyname2 = u'direct2' - parentmap = u'auto.master' - map_kw = {'key': keyname, 'raw': True} - map_kw2 = {'key': keyname2, 'raw': True} - - tofiles_output = textwrap.dedent(u""" - /etc/auto.master: - /-\t/etc/auto.direct - /home\t/etc/auto.home - --------------------------- - /etc/auto.direct: - --------------------------- - /etc/auto.home: - direct2\t-fstype=autofs ldap:auto.direct2 - - maps not connected to /etc/auto.master: - --------------------------- - /etc/auto.direct2: - """).strip() - - def test_0_automountlocation_add(self): - """ - Test adding a location. - """ - res = api.Command['automountlocation_add'](self.locname, raw=True)['result'] - assert res - assert_attr_equal(res, 'cn', self.locname) - - def test_1_automountmap_add_indirect(self): - """ - Test adding an indirect map with default parent. - """ - res = api.Command['automountmap_add_indirect'](self.locname, self.mapname, **self.map_kw)['result'] - assert res - assert_attr_equal(res, 'automountmapname', self.mapname) - - def test_2_automountkey_show(self): - """ - Test the `xmlrpc.automountkey_show` method with default parent. - """ - showkey_kw = {'automountkey': self.keyname, 'automountinformation': self.mapname, 'raw': True} - res = api.Command['automountkey_show'](self.locname, self.parentmap, **showkey_kw)['result'] - assert res - assert_attr_equal(res, 'automountkey', self.keyname) - - def test_2a_automountmap_add_indirect(self): - """ - Test adding an indirect map with default parent. - """ - res = api.Command['automountmap_add_indirect'](self.locname, - u'auto.direct2', parentmap=self.mapname, **self.map_kw2)['result'] - assert res - assert_attr_equal(res, 'automountmapname', self.mapname2) - - def test_2b_automountmap_tofiles(self): - """Test the `automountmap_tofiles` command""" - self.check_tofiles() - - def test_3_automountkey_del(self): - """ - Remove the indirect key /home. - """ - delkey_kw={'automountkey': self.keyname, 'automountinformation': self.mapname} - res = api.Command['automountkey_del'](self.locname, self.parentmap, **delkey_kw)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verify that it is gone - with assert_raises(errors.NotFound): - api.Command['automountkey_show'](self.locname, self.parentmap, **delkey_kw) - - def test_4_automountmap_del(self): - """ - Remove the indirect map for auto.home. - """ - res = api.Command['automountmap_del'](self.locname, self.mapname)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verify that it is gone - with assert_raises(errors.NotFound): - api.Command['automountmap_show'](self.locname, self.mapname) - - def test_5_automountlocation_del(self): - """ - Remove the location. - """ - res = api.Command['automountlocation_del'](self.locname)['result'] - assert res - assert_attr_equal(res, 'failed', '') - - # Verity that it is gone - with assert_raises(errors.NotFound): - api.Command['automountlocation_show'](self.locname) diff --git a/tests/test_xmlrpc/test_baseldap_plugin.py b/tests/test_xmlrpc/test_baseldap_plugin.py deleted file mode 100644 index 6a8501f76..000000000 --- a/tests/test_xmlrpc/test_baseldap_plugin.py +++ /dev/null @@ -1,159 +0,0 @@ -# Authors: -# Petr Viktorin -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.plugins.baseldap` module. -""" - -from ipalib import errors -from ipalib.plugins import baseldap - - -def test_exc_wrapper(): - """Test the CallbackInterface._exc_wrapper helper method""" - handled_exceptions = [] - - class test_callback(baseldap.BaseLDAPCommand): - """Fake IPA method""" - def test_fail(self): - self._exc_wrapper([], {}, self.fail)(1, 2, a=1, b=2) - - def fail(self, *args, **kwargs): - assert args == (1, 2) - assert kwargs == dict(a=1, b=2) - raise errors.ExecutionError('failure') - - instance = test_callback() - - # Test with one callback first - - @test_callback.register_exc_callback - def handle_exception(self, keys, options, e, call_func, *args, **kwargs): - assert args == (1, 2) - assert kwargs == dict(a=1, b=2) - handled_exceptions.append(type(e)) - - instance.test_fail() - assert handled_exceptions == [errors.ExecutionError] - - # Test with another callback added - - handled_exceptions = [] - - def dont_handle(self, keys, options, e, call_func, *args, **kwargs): - assert args == (1, 2) - assert kwargs == dict(a=1, b=2) - handled_exceptions.append(None) - raise e - test_callback.register_exc_callback(dont_handle, first=True) - - instance.test_fail() - assert handled_exceptions == [None, errors.ExecutionError] - - -def test_callback_registration(): - class callbacktest_base(baseldap.CallbackInterface): - _callback_registry = dict(test={}) - - def test_callback(self, param): - messages.append(('Base test_callback', param)) - - def registered_callback(self, param): - messages.append(('Base registered callback', param)) - callbacktest_base.register_callback('test', registered_callback) - - class SomeClass(object): - def registered_callback(self, command, param): - messages.append(('Registered callback from another class', param)) - callbacktest_base.register_callback('test', SomeClass().registered_callback) - - class callbacktest_subclass(callbacktest_base): - pass - - def subclass_callback(self, param): - messages.append(('Subclass registered callback', param)) - callbacktest_subclass.register_callback('test', subclass_callback) - - - messages = [] - instance = callbacktest_base() - for callback in instance.get_callbacks('test'): - callback(instance, 42) - assert messages == [ - ('Base test_callback', 42), - ('Base registered callback', 42), - ('Registered callback from another class', 42)] - - messages = [] - instance = callbacktest_subclass() - for callback in instance.get_callbacks('test'): - callback(instance, 42) - assert messages == [ - ('Base test_callback', 42), - ('Subclass registered callback', 42)] - - -def test_exc_callback_registration(): - messages = [] - class callbacktest_base(baseldap.BaseLDAPCommand): - """A method superclass with an exception callback""" - def exc_callback(self, keys, options, exc, call_func, *args, **kwargs): - """Let the world know we saw the error, but don't handle it""" - messages.append('Base exc_callback') - raise exc - - def test_fail(self): - """Raise a handled exception""" - try: - self._exc_wrapper([], {}, self.fail)(1, 2, a=1, b=2) - except Exception: - pass - - def fail(self, *args, **kwargs): - """Raise an error""" - raise errors.ExecutionError('failure') - - base_instance = callbacktest_base() - - class callbacktest_subclass(callbacktest_base): - pass - - @callbacktest_subclass.register_exc_callback - def exc_callback(self, keys, options, exc, call_func, *args, **kwargs): - """Subclass's private exception callback""" - messages.append('Subclass registered callback') - raise exc - - subclass_instance = callbacktest_subclass() - - # Make sure exception in base class is only handled by the base class - base_instance.test_fail() - assert messages == ['Base exc_callback'] - - - @callbacktest_base.register_exc_callback - def exc_callback(self, keys, options, exc, call_func, *args, **kwargs): - """Callback on super class; doesn't affect the subclass""" - messages.append('Superclass registered callback') - raise exc - - # Make sure exception in subclass is only handled by both - messages = [] - subclass_instance.test_fail() - assert messages == ['Base exc_callback', 'Subclass registered callback'] diff --git a/tests/test_xmlrpc/test_batch_plugin.py b/tests/test_xmlrpc/test_batch_plugin.py deleted file mode 100644 index 55e557050..000000000 --- a/tests/test_xmlrpc/test_batch_plugin.py +++ /dev/null @@ -1,232 +0,0 @@ -# Authors: -# Petr Viktorin -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/batch.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from tests.util import assert_equal, Fuzzy, assert_deepequal -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -group1 = u'testgroup1' - - -def deepequal_list(*expected): - """Factory for a function that checks a list - - The created function asserts items of a list are "deepequal" to the given - argument. Unlike using assert_deepequal directly, the order matters. - """ - def checker(got): - if len(expected) != len(got): - raise AssertionError('Expected %s entries, got %s\n\n%s\n%s' % - (len(expected), len(got), expected, got)) - for e, g in zip(expected, got): - assert_deepequal(e, g) - return True - return checker - - -class test_batch(Declarative): - - cleanup_commands = [ - ('group_del', [group1], {}), - ] - - tests = [ - - dict( - desc='Batch ping', - command=('batch', [dict(method='ping', params=([], {}))], {}), - expected=dict( - count=1, - results=[ - dict(summary=Fuzzy('IPA server version .*'), error=None), - ] - ), - ), - - dict( - desc='Batch two pings', - command=('batch', [dict(method='ping', params=([], {}))] * 2, {}), - expected=dict( - count=2, - results=[ - dict(summary=Fuzzy('IPA server version .*'), error=None), - dict(summary=Fuzzy('IPA server version .*'), error=None), - ] - ), - ), - - dict( - desc='Create and deleting a group', - command=('batch', [ - dict(method='group_add', - params=([group1], dict(description=u'Test desc 1'))), - dict(method='group_del', params=([group1], dict())), - ], {}), - expected=dict( - count=2, - results=deepequal_list( - dict( - value=group1, - summary=u'Added group "testgroup1"', - result=dict( - cn=[group1], - description=[u'Test desc 1'], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - gidnumber=[fuzzy_digits], - dn=DN(('cn', 'testgroup1'), - ('cn', 'groups'), - ('cn', 'accounts'), - api.env.basedn), - ), - error=None), - dict( - summary=u'Deleted group "%s"' % group1, - result=dict(failed=u''), - value=group1, - error=None), - ), - ), - ), - - dict( - desc='Try to delete nonexistent group twice', - command=('batch', [ - dict(method='group_del', params=([group1], dict())), - dict(method='group_del', params=([group1], dict())), - ], {}), - expected=dict( - count=2, - results=[ - dict( - error=u'%s: group not found' % group1, - error_name=u'NotFound', - error_code=4001, - ), - dict( - error=u'%s: group not found' % group1, - error_name=u'NotFound', - error_code=4001, - ), - ], - ), - ), - - dict( - desc='Try to delete non-existent group first, then create it', - command=('batch', [ - dict(method='group_del', params=([group1], dict())), - dict(method='group_add', - params=([group1], dict(description=u'Test desc 1'))), - ], {}), - expected=dict( - count=2, - results=deepequal_list( - dict( - error=u'%s: group not found' % group1, - error_name=u'NotFound', - error_code=4001, - ), - dict( - value=group1, - summary=u'Added group "testgroup1"', - result=dict( - cn=[group1], - description=[u'Test desc 1'], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - gidnumber=[fuzzy_digits], - dn=DN(('cn', 'testgroup1'), - ('cn', 'groups'), - ('cn', 'accounts'), - api.env.basedn), - ), - error=None), - ), - ), - ), - - dict( - desc='Try bad command invocations', - command=('batch', [ - # bad command name - dict(method='nonexistent_ipa_command', params=([], dict())), - # dash, not underscore, in command name - dict(method='user-del', params=([], dict())), - # missing command name - dict(params=([group1], dict())), - # missing params - dict(method='user_del'), - # missing required argument - dict(method='user_add', params=([], dict())), - # missing required option - dict(method='group_add', params=([group1], dict())), - # bad type - dict(method='group_add', params=([group1], dict( - description=u't', gidnumber=u'bad'))), - ], {}), - expected=dict( - count=7, - results=deepequal_list( - dict( - error=u"unknown command 'nonexistent_ipa_command'", - error_name=u'CommandError', - error_code=905, - ), - dict( - error=u"unknown command 'user-del'", - error_name=u'CommandError', - error_code=905, - ), - dict( - error=u"'method' is required", - error_name=u'RequirementError', - error_code=3007, - ), - dict( - error=u"'params' is required", - error_name=u'RequirementError', - error_code=3007, - ), - dict( - error=u"'givenname' is required", - error_name=u'RequirementError', - error_code=3007, - ), - dict( - error=u"'description' is required", - error_name=u'RequirementError', - error_code=3007, - ), - dict( - error=Fuzzy(u"invalid 'gid'.*"), - error_name=u'ConversionError', - error_code=3008, - ), - ), - ), - ), - - ] diff --git a/tests/test_xmlrpc/test_cert_plugin.py b/tests/test_xmlrpc/test_cert_plugin.py deleted file mode 100644 index 508e9141a..000000000 --- a/tests/test_xmlrpc/test_cert_plugin.py +++ /dev/null @@ -1,454 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2009,2013 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/cert.py` module against a RA. -""" - -import sys -import os -import shutil -from nose.tools import raises, assert_raises # pylint: disable=E0611 - -from xmlrpc_test import XMLRPC_test, assert_attr_equal -from ipalib import api -from ipalib import errors -from ipalib import x509 -import tempfile -from ipapython import ipautil -import nose -import base64 -from ipapython.dn import DN - -# So we can save the cert from issuance and compare it later -cert = None -newcert = None - -def is_db_configured(): - """ - Raise an exception if we are testing against lite-server and the - developer cert database is configured. - """ - aliasdir = api.env.dot_ipa + os.sep + 'alias' + os.sep + '.pwd' - - if (api.env.xmlrpc_uri == u'http://localhost:8888/ipa/xml' and - not ipautil.file_exists(aliasdir)): - raise nose.SkipTest('developer CA not configured in %s' % aliasdir) - -# Test setup -# -# This test needs a configured CA behind it in order to work properly -# -# To test against Apache directly then no changes are required. Just be -# sure the xmlrpc_uri in ~/.ipa/default.conf points to Apache. -# -# To test against Dogtag CA in the lite-server: -# -# - Copy the 3 NSS db files from /etc/httpd/alias to ~/.ipa/alias -# - Copy /etc/httpd/alias/pwdfile.txt to ~/.ipa/alias/.pwd. -# - Change ownership of these files to be readable by you. -# -# The API tested depends on the value of ~/.ipa/default/ra_plugin when -# running as the lite-server. - -class test_cert(XMLRPC_test): - - @classmethod - def setUpClass(cls): - super(test_cert, cls).setUpClass() - - if 'cert_request' not in api.Command: - raise nose.SkipTest('cert_request not registered') - - is_db_configured() - - def run_certutil(self, args, stdin=None): - new_args = ["/usr/bin/certutil", "-d", self.reqdir] - new_args = new_args + args - return ipautil.run(new_args, stdin) - - def setUp(self): - super(test_cert, self).setUp() - self.reqdir = tempfile.mkdtemp(prefix = "tmp-") - self.reqfile = self.reqdir + "/test.csr" - self.pwname = self.reqdir + "/pwd" - - # Create an empty password file - fp = open(self.pwname, "w") - fp.write("\n") - fp.close() - - # Create our temporary NSS database - self.run_certutil(["-N", "-f", self.pwname]) - - self.subject = DN(('CN', self.host_fqdn), x509.subject_base()) - - def tearDown(self): - super(test_cert, self).tearDown() - shutil.rmtree(self.reqdir, ignore_errors=True) - - def generateCSR(self, subject): - self.run_certutil(["-R", "-s", subject, - "-o", self.reqfile, - "-z", "/etc/group", - "-f", self.pwname, - "-a", - ]) - fp = open(self.reqfile, "r") - data = fp.read() - fp.close() - return data - - """ - Test the `cert` plugin. - """ - host_fqdn = u'ipatestcert.%s' % api.env.domain - service_princ = u'test/%s@%s' % (host_fqdn, api.env.realm) - - def test_0001_cert_add(self): - """ - Test the `xmlrpc.cert_request` method without --add. - - This should fail because the service principal doesn't exist - """ - # First create the host that will use this policy - res = api.Command['host_add'](self.host_fqdn, force= True)['result'] - - csr = unicode(self.generateCSR(str(self.subject))) - with assert_raises(errors.NotFound): - res = api.Command['cert_request'](csr, principal=self.service_princ) - - def test_0002_cert_add(self): - """ - Test the `xmlrpc.cert_request` method with --add. - """ - # Our host should exist from previous test - global cert - - csr = unicode(self.generateCSR(str(self.subject))) - res = api.Command['cert_request'](csr, principal=self.service_princ, add=True)['result'] - assert DN(res['subject']) == self.subject - # save the cert for the service_show/find tests - cert = res['certificate'] - - def test_0003_service_show(self): - """ - Verify that service-show has the right certificate using service-show. - """ - global cert - - res = api.Command['service_show'](self.service_princ)['result'] - assert base64.b64encode(res['usercertificate'][0]) == cert - - def test_0004_service_find(self): - """ - Verify that service-find has the right certificate using service-find. - """ - global cert - - # Assume there is only one service - res = api.Command['service_find'](self.service_princ)['result'] - assert base64.b64encode(res[0]['usercertificate'][0]) == cert - - def test_0005_cert_renew(self): - """ - Issue a new certificate for a service - """ - global newcert - - csr = unicode(self.generateCSR(str(self.subject))) - res = api.Command['cert_request'](csr, principal=self.service_princ)['result'] - assert DN(res['subject']) == self.subject - # save the cert for the service_show/find tests - newcert = res['certificate'] - - def test_0006_service_show(self): - """ - Verify the new certificate with service-show. - """ - global cert, newcert - - res = api.Command['service_show'](self.service_princ)['result'] - # It should no longer match our old cert - assert base64.b64encode(res['usercertificate'][0]) != cert - # And it should match the new one - assert base64.b64encode(res['usercertificate'][0]) == newcert - - def test_0007_cleanup(self): - """ - Clean up cert test data - """ - # Now clean things up - api.Command['host_del'](self.host_fqdn) - - # Verify that the service is gone - res = api.Command['service_find'](self.service_princ) - assert res['count'] == 0 - -class test_cert_find(XMLRPC_test): - - @classmethod - def setUpClass(cls): - super(test_cert_find, cls).setUpClass() - - if 'cert_find' not in api.Command: - raise nose.SkipTest('cert_find not registered') - - if api.env.ra_plugin != 'dogtag': - raise nose.SkipTest('cert_find for dogtag CA only') - - is_db_configured() - - """ - Test the `cert-find` command. - """ - short = api.env.host.replace('.' + api.env.domain, '') - - def test_0001_find_all(self): - """ - Search for all certificates. - - We don't know how many we'll get but there should be at least 10 - by default. - """ - res = api.Command['cert_find']() - assert 'count' in res and res['count'] >= 10 - - def test_0002_find_CA(self): - """ - Search for the CA certificate. - """ - res = api.Command['cert_find'](subject=u'Certificate Authority') - assert 'count' in res and res['count'] == 1 - - def test_0003_find_OCSP(self): - """ - Search for the OCSP certificate. - """ - res = api.Command['cert_find'](subject=u'OCSP Subsystem') - - def test_0004_find_this_host(self): - """ - Find all certificates for this IPA server - """ - res = api.Command['cert_find'](subject=api.env.host) - assert 'count' in res and res['count'] > 1 - - def test_0005_find_this_host_exact(self): - """ - Find all certificates for this IPA server (exact) - """ - res = api.Command['cert_find'](subject=api.env.host, exactly=True) - assert 'count' in res and res['count'] > 1 - - def test_0006_find_this_short_host_exact(self): - """ - Find all certificates for this IPA server short name (exact) - """ - res = api.Command['cert_find'](subject=self.short, exactly=True) - assert 'count' in res and res['count'] == 0 - - def test_0007_find_revocation_reason_0(self): - """ - Find all certificates with revocation reason 0 - """ - res = api.Command['cert_find'](revocation_reason=0) - assert 'count' in res and res['count'] == 0 - - def test_0008_find_revocation_reason_1(self): - """ - Find all certificates with revocation reason 1 - """ - res = api.Command['cert_find'](revocation_reason=1) - assert 'count' in res and res['count'] == 0 - - def test_0009_find_revocation_reason_2(self): - """ - Find all certificates with revocation reason 2 - """ - res = api.Command['cert_find'](revocation_reason=2) - assert 'count' in res and res['count'] == 0 - - def test_0010_find_revocation_reason_3(self): - """ - Find all certificates with revocation reason 3 - """ - res = api.Command['cert_find'](revocation_reason=3) - assert 'count' in res and res['count'] == 0 - - def test_0011_find_revocation_reason_4(self): - """ - Find all certificates with revocation reason 4 - - There is no way to know in advance how many revoked certificates - we'll have but in the context of make-test we'll have at least one. - """ - res = api.Command['cert_find'](revocation_reason=4) - assert 'count' in res and res['count'] >= 1 - - def test_0012_find_revocation_reason_5(self): - """ - Find all certificates with revocation reason 5 - """ - res = api.Command['cert_find'](revocation_reason=5) - assert 'count' in res and res['count'] == 0 - - def test_0013_find_revocation_reason_6(self): - """ - Find all certificates with revocation reason 6 - """ - res = api.Command['cert_find'](revocation_reason=6) - assert 'count' in res and res['count'] == 0 - - # There is no revocation reason #7 - - def test_0014_find_revocation_reason_8(self): - """ - Find all certificates with revocation reason 8 - """ - res = api.Command['cert_find'](revocation_reason=8) - assert 'count' in res and res['count'] == 0 - - def test_0015_find_revocation_reason_9(self): - """ - Find all certificates with revocation reason 9 - """ - res = api.Command['cert_find'](revocation_reason=9) - assert 'count' in res and res['count'] == 0 - - def test_0016_find_revocation_reason_10(self): - """ - Find all certificates with revocation reason 10 - """ - res = api.Command['cert_find'](revocation_reason=10) - assert 'count' in res and res['count'] == 0 - - def test_0017_find_by_issuedon(self): - """ - Find all certificates issued since 2008 - """ - res = api.Command['cert_find'](issuedon_from=u'2008-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 10 - - def test_0018_find_through_issuedon(self): - """ - Find all certificates issued through 2008 - """ - res = api.Command['cert_find'](issuedon_to=u'2008-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 0 - - def test_0019_find_notvalid_before(self): - """ - Find all certificates valid not before 2008 - """ - res = api.Command['cert_find'](validnotbefore_from=u'2008-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 10 - - def test_0020_find_notvalid_before(self): - """ - Find all certificates valid not before to 2100 - """ - res = api.Command['cert_find'](validnotbefore_to=u'2100-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 10 - - def test_0021_find_notvalid_before(self): - """ - Find all certificates valid not before 2100 - """ - res = api.Command['cert_find'](validnotbefore_from=u'2100-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 0 - - def test_0022_find_notvalid_before(self): - """ - Find all certificates valid not before to 2008 - """ - res = api.Command['cert_find'](validnotbefore_to=u'2008-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 0 - - def test_0023_find_notvalid_after(self): - """ - Find all certificates valid not after 2008 - """ - res = api.Command['cert_find'](validnotafter_from=u'2008-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 10 - - def test_0024_find_notvalid_after(self): - """ - Find all certificates valid not after to 2100 - """ - res = api.Command['cert_find'](validnotafter_to=u'2100-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 10 - - def test_0025_find_notvalid_after(self): - """ - Find all certificates valid not after 2100 - """ - res = api.Command['cert_find'](validnotafter_from=u'2100-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 0 - - def test_0026_find_notvalid_after(self): - """ - Find all certificates valid not after to 2008 - """ - res = api.Command['cert_find'](validnotafter_to=u'2008-01-01', - sizelimit=10) - assert 'count' in res and res['count'] == 0 - - def test_0027_sizelimit_zero(self): - """ - Search with a sizelimit of 0 - """ - res = api.Command['cert_find'](sizelimit=0) - assert 'count' in res and res['count'] == 0 - - @raises(errors.ValidationError) - def test_0028_find_negative_size(self): - """ - Search with a negative sizelimit - """ - res = api.Command['cert_find'](sizelimit=-100) - - def test_0029_search_for_notfound(self): - """ - Search for a host that isn't there. - """ - res = api.Command['cert_find'](subject=u'notfound') - assert 'count' in res and res['count'] == 0 - - def test_0030_search_for_testcerts(self): - """ - Search for certs created in other tests - """ - res = api.Command['cert_find'](subject=u'ipatestcert.%s' % api.env.domain) - assert 'count' in res and res['count'] >= 1 - - @raises(errors.ValidationError) - def test_0031_search_on_invalid_date(self): - """ - Search using invalid date format - """ - res = api.Command['cert_find'](issuedon_from=u'xyz') diff --git a/tests/test_xmlrpc/test_config_plugin.py b/tests/test_xmlrpc/test_config_plugin.py deleted file mode 100644 index 3d9a31daf..000000000 --- a/tests/test_xmlrpc/test_config_plugin.py +++ /dev/null @@ -1,121 +0,0 @@ -# Authors: -# Petr Viktorin -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/config.py` module. -""" - -from ipalib import errors -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid - -class test_config(Declarative): - - cleanup_commands = [ - ] - - tests = [ - - dict( - desc='Try to add an unrelated objectclass to ipauserobjectclasses', - command=('config_mod', [], - dict(addattr=u'ipauserobjectclasses=ipahost')), - expected=dict( - result=lambda d: 'ipahost' in d['ipauserobjectclasses'], - value=u'', - summary=None, - ), - ), - - dict( - desc='Remove the unrelated objectclass from ipauserobjectclasses', - command=('config_mod', [], - dict(delattr=u'ipauserobjectclasses=ipahost')), - expected=dict( - result=lambda d: 'ipahost' not in d['ipauserobjectclasses'], - value=u'', - summary=None, - ), - ), - - dict( - desc='Try to remove ipausersearchfields', - command=('config_mod', [], - dict(delattr=u'ipausersearchfields=uid,givenname,sn,telephonenumber,ou,title')), - expected=errors.RequirementError(name='ipausersearchfields'), - ), - - dict( - desc='Try to set ipaselinuxusermapdefault not in selinux order list', - command=('config_mod', [], - dict(ipaselinuxusermapdefault=u'unknown_u:s0')), - expected=errors.ValidationError(name='ipaselinuxusermapdefault', - error='SELinux user map default user not in order list'), - ), - - dict( - desc='Try to set invalid ipaselinuxusermapdefault', - command=('config_mod', [], - dict(ipaselinuxusermapdefault=u'foo')), - expected=errors.ValidationError(name='ipaselinuxusermapdefault', - error='Invalid MLS value, must match s[0-15](-s[0-15])'), - ), - - dict( - desc='Try to set invalid ipaselinuxusermapdefault with setattr', - command=('config_mod', [], - dict(setattr=u'ipaselinuxusermapdefault=unknown_u:s0')), - expected=errors.ValidationError(name='ipaselinuxusermapdefault', - error='SELinux user map default user not in order list'), - ), - - dict( - desc='Try to set ipaselinuxusermaporder without ipaselinuxusermapdefault out of it', - command=('config_mod', [], - dict(ipaselinuxusermaporder=u'notfound_u:s0')), - expected=errors.ValidationError(name='ipaselinuxusermaporder', - error='SELinux user map default user not in order list'), - ), - - dict( - desc='Try to set invalid ipaselinuxusermaporder', - command=('config_mod', [], - dict(ipaselinuxusermaporder=u'$')), - expected=errors.ValidationError(name='ipaselinuxusermaporder', - error='A list of SELinux users delimited by $ expected'), - ), - - dict( - desc='Try to set invalid selinux user in ipaselinuxusermaporder', - command=('config_mod', [], - dict(ipaselinuxusermaporder=u'unconfined_u:s0-s0:c0.c1023$baduser$guest_u:s0')), - expected=errors.ValidationError(name='ipaselinuxusermaporder', - error='SELinux user \'baduser\' is not valid: Invalid MLS ' - 'value, must match s[0-15](-s[0-15])'), - ), - - dict( - desc='Try to set new selinux order and invalid default user', - command=('config_mod', [], - dict(ipaselinuxusermaporder=u'xguest_u:s0$guest_u:s0$user_u:s0-s0:c0.c1023$staff_u:s0-s0:c0.c1023$unconfined_u:s0-s0:c0.c1023', - ipaselinuxusermapdefault=u'unknown_u:s0')), - expected=errors.ValidationError(name='ipaselinuxusermapdefault', - error='SELinux user map default user not in order list'), - ), - - ] diff --git a/tests/test_xmlrpc/test_delegation_plugin.py b/tests/test_xmlrpc/test_delegation_plugin.py deleted file mode 100644 index bc3b96a27..000000000 --- a/tests/test_xmlrpc/test_delegation_plugin.py +++ /dev/null @@ -1,300 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/delegation.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -delegation1 = u'testdelegation' -member1 = u'admins' - -class test_delegation(Declarative): - - cleanup_commands = [ - ('delegation_del', [delegation1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % delegation1, - command=('delegation_show', [delegation1], {}), - expected=errors.NotFound( - reason=u'ACI with name "%s" not found' % delegation1), - ), - - - dict( - desc='Try to update non-existent %r' % delegation1, - command=('delegation_mod', [delegation1], dict(group=u'admins')), - expected=errors.NotFound( - reason=u'ACI with name "%s" not found' % delegation1), - ), - - - dict( - desc='Try to delete non-existent %r' % delegation1, - command=('delegation_del', [delegation1], {}), - expected=errors.NotFound( - reason=u'ACI with name "%s" not found' % delegation1), - ), - - - dict( - desc='Search for non-existent %r' % delegation1, - command=('delegation_find', [delegation1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 delegations matched', - result=[], - ), - ), - - dict( - desc='Try to create %r for non-existing member group' % delegation1, - command=( - 'delegation_add', [delegation1], dict( - attrs=u'street,c,l,st,postalCode', - permissions=u'write', - group=u'editors', - memberof=u'nonexisting', - ), - ), - expected=errors.NotFound(reason=u'nonexisting: group not found'), - ), - - # Note that we add postalCode but expect postalcode. This tests - # the attrs normalizer. - dict( - desc='Create %r' % delegation1, - command=( - 'delegation_add', [delegation1], dict( - attrs=[u'street', u'c', u'l', u'st', u'postalCode'], - permissions=u'write', - group=u'editors', - memberof=u'admins', - ) - ), - expected=dict( - value=delegation1, - summary=u'Added delegation "%s"' % delegation1, - result=dict( - attrs=[u'street', u'c', u'l', u'st', u'postalcode'], - permissions=[u'write'], - aciname=delegation1, - group=u'editors', - memberof=member1, - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % delegation1, - command=( - 'delegation_add', [delegation1], dict( - attrs=[u'street', u'c', u'l', u'st', u'postalCode'], - permissions=u'write', - group=u'editors', - memberof=u'admins', - ), - ), - expected=errors.DuplicateEntry(), - ), - - - dict( - desc='Retrieve %r' % delegation1, - command=('delegation_show', [delegation1], {}), - expected=dict( - value=delegation1, - summary=None, - result={ - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'write'], - 'aciname': delegation1, - 'group': u'editors', - 'memberof': member1, - }, - ), - ), - - - dict( - desc='Retrieve %r with --raw' % delegation1, - command=('delegation_show', [delegation1], {'raw' : True}), - expected=dict( - value=delegation1, - summary=None, - result={ - 'aci': u'(targetattr = "street || c || l || st || postalcode")(targetfilter = "(memberOf=%s)")(version 3.0;acl "delegation:testdelegation";allow (write) groupdn = "ldap:///%s";)' % \ - (DN(('cn', 'admins'), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), - DN(('cn', 'editors'), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)) - }, - ), - ), - - - dict( - desc='Search for %r' % delegation1, - command=('delegation_find', [delegation1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 delegation matched', - result=[ - { - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'write'], - 'aciname': delegation1, - 'group': u'editors', - 'memberof': member1, - }, - ], - ), - ), - - - dict( - desc='Search for %r using --group filter' % delegation1, - command=('delegation_find', [delegation1], {'group': u'editors'}), - expected=dict( - count=1, - truncated=False, - summary=u'1 delegation matched', - result=[ - { - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'write'], - 'aciname': delegation1, - 'group': u'editors', - 'memberof': member1, - }, - ], - ), - ), - - - dict( - desc='Search for %r using --membergroup filter' % delegation1, - command=('delegation_find', [delegation1], {'memberof': member1}), - expected=dict( - count=1, - truncated=False, - summary=u'1 delegation matched', - result=[ - { - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'write'], - 'aciname': delegation1, - 'group': u'editors', - 'memberof': member1, - }, - ], - ), - ), - - - dict( - desc='Search for %r with --pkey-only' % delegation1, - command=('delegation_find', [delegation1], {'pkey_only' : True}), - expected=dict( - count=1, - truncated=False, - summary=u'1 delegation matched', - result=[ - { - 'aciname': delegation1, - }, - ], - ), - ), - - - dict( - desc='Search for %r with --raw' % delegation1, - command=('delegation_find', [delegation1], {'raw' : True}), - expected=dict( - count=1, - truncated=False, - summary=u'1 delegation matched', - result=[ - { - 'aci': u'(targetattr = "street || c || l || st || postalcode")(targetfilter = "(memberOf=%s)")(version 3.0;acl "delegation:testdelegation";allow (write) groupdn = "ldap:///%s";)' % \ - (DN(('cn', 'admins'), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn), - DN(('cn', 'editors'), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)), - }, - ], - ), - ), - - - dict( - desc='Update %r' % delegation1, - command=( - 'delegation_mod', [delegation1], dict(permissions=u'read') - ), - expected=dict( - value=delegation1, - summary=u'Modified delegation "%s"' % delegation1, - result=dict( - attrs=[u'street', u'c', u'l', u'st', u'postalcode'], - permissions=[u'read'], - aciname=delegation1, - group=u'editors', - memberof=member1, - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % delegation1, - command=('delegation_show', [delegation1], {}), - expected=dict( - value=delegation1, - summary=None, - result={ - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'read'], - 'aciname': delegation1, - 'group': u'editors', - 'memberof': member1, - }, - ), - ), - - - dict( - desc='Delete %r' % delegation1, - command=('delegation_del', [delegation1], {}), - expected=dict( - result=True, - value=delegation1, - summary=u'Deleted delegation "%s"' % delegation1, - ) - ), - - ] diff --git a/tests/test_xmlrpc/test_dns_plugin.py b/tests/test_xmlrpc/test_dns_plugin.py deleted file mode 100644 index 0d78f80b0..000000000 --- a/tests/test_xmlrpc/test_dns_plugin.py +++ /dev/null @@ -1,1511 +0,0 @@ -# Authors: -# Pavel Zuna -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/dns.py` module. -""" - -import nose -from ipalib import api, errors -from ipapython.dn import DN -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid - -dnszone1 = u'dnszone.test' -dnszone1_dn = DN(('idnsname',dnszone1), api.env.container_dns, api.env.basedn) -dnszone1_mname = u'ns1.%s.' % dnszone1 -dnszone1_mname_dn = DN(('idnsname','ns1'), dnszone1_dn) -dnszone1_rname = u'root.%s.' % dnszone1 -dnszone1_permission = u'Manage DNS zone %s' % dnszone1 -dnszone1_permission_dn = DN(('cn',dnszone1_permission), - api.env.container_permission,api.env.basedn) -dnszone1_txtrec_dn = DN(('idnsname', '_kerberos'), dnszone1_dn) -dnszone2 = u'dnszone2.test' -dnszone2_dn = DN(('idnsname', dnszone2), api.env.container_dns, api.env.basedn) -dnszone2_mname = u'ns1.%s.' % dnszone2 -dnszone2_rname = u'root.%s.' % dnszone2 -revdnszone1 = u'15.142.80.in-addr.arpa.' -revdnszone1_ip = u'80.142.15.0/24' -revdnszone1_dn = DN(('idnsname', revdnszone1), api.env.container_dns, api.env.basedn) -revdnszone2 = u'16.142.80.in-addr.arpa.' -revdnszone2_ip = u'80.142.16.0' -revdnszone2_dn = DN(('idnsname',revdnszone2), api.env.container_dns, api.env.basedn) -dnsres1 = u'testdnsres' -dnsres1_dn = DN(('idnsname',dnsres1), dnszone1_dn) -dnsres1_renamed = u'testdnsres-renamed' -dnsrev1 = u'80' -dnsrev1_dn = DN(('idnsname',dnsrev1), revdnszone1_dn) -dnsrev2 = u'81' -dnsrev2_dn = DN(('idnsname',dnsrev2), revdnszone1_dn) -dnsrescname = u'testcnamerec' -dnsrescname_dn = DN(('idnsname',dnsrescname), dnszone1_dn) -dnsresdname = u'testdns-dname' -dnsresdname_dn = DN(('idnsname',dnsresdname), dnszone1_dn) - -class test_dns(Declarative): - - @classmethod - def setUpClass(cls): - super(test_dns, cls).setUpClass() - - if not api.Backend.xmlclient.isconnected(): - api.Backend.xmlclient.connect(fallback=False) - try: - api.Command['dnszone_add'](dnszone1, - idnssoamname = dnszone1_mname, - idnssoarname = dnszone1_rname, - force = True, - ) - api.Command['dnszone_del'](dnszone1) - except errors.NotFound: - raise nose.SkipTest('DNS is not configured') - except errors.DuplicateEntry: - pass - - cleanup_commands = [ - ('dnszone_del', [dnszone1, dnszone2, revdnszone1, revdnszone2], - {'continue': True}), - ('dnsconfig_mod', [], {'idnsforwarders' : None, - 'idnsforwardpolicy' : None, - 'idnsallowsyncptr' : None, - 'idnszonerefresh' : None, - }), - ('permission_del', [dnszone1_permission], {'force': True}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent zone %r' % dnszone1, - command=('dnszone_show', [dnszone1], {}), - expected=errors.NotFound( - reason=u'%s: DNS zone not found' % dnszone1), - ), - - - dict( - desc='Try to update non-existent zone %r' % dnszone1, - command=('dnszone_mod', [dnszone1], {'idnssoaminimum': 3500}), - expected=errors.NotFound( - reason=u'%s: DNS zone not found' % dnszone1), - ), - - - dict( - desc='Try to delete non-existent zone %r' % dnszone1, - command=('dnszone_del', [dnszone1], {}), - expected=errors.NotFound( - reason=u'%s: DNS zone not found' % dnszone1), - ), - - - dict( - desc='Try to create zone with invalid name', - command=( - 'dnszone_add', [u'invalid zone'], { - 'idnssoamname': dnszone1_mname, - 'idnssoarname': dnszone1_rname, - 'ip_address' : u'1.2.3.4', - } - ), - expected=errors.ValidationError(name='name', - error=u'only letters, numbers, and - are allowed. ' + - u'DNS label may not start or end with -'), - ), - - - dict( - desc='Create zone %r' % dnszone1, - command=( - 'dnszone_add', [dnszone1], { - 'idnssoamname': dnszone1_mname, - 'idnssoarname': dnszone1_rname, - 'ip_address' : u'1.2.3.4', - } - ), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [dnszone1_mname], - 'nsrecord': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' - u'grant %(realm)s krb5-self * AAAA; ' - u'grant %(realm)s krb5-self * SSHFP;' - % dict(realm=api.env.realm)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - }, - }, - ), - - - dict( - desc='Try to create duplicate zone %r' % dnszone1, - command=( - 'dnszone_add', [dnszone1], { - 'idnssoamname': dnszone1_mname, - 'idnssoarname': dnszone1_rname, - 'ip_address' : u'1.2.3.4', - } - ), - expected=errors.DuplicateEntry( - message=u'DNS zone with name "%s" already exists' % dnszone1), - ), - - dict( - desc='Try to create a zone with nonexistent NS entry', - command=( - 'dnszone_add', [dnszone2], { - 'idnssoamname': dnszone2_mname, - 'idnssoarname': dnszone2_rname, - } - ), - expected=errors.NotFound(reason='Nameserver \'%s\' does not have a corresponding A/AAAA record' % (dnszone2_mname)), - ), - - dict( - desc='Create a zone with nonexistent NS entry with --force', - command=( - 'dnszone_add', [dnszone2], { - 'idnssoamname': dnszone2_mname, - 'idnssoarname': dnszone2_rname, - 'force' : True, - } - ), - expected={ - 'value': dnszone2, - 'summary': None, - 'result': { - 'dn': dnszone2_dn, - 'idnsname': [dnszone2], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [dnszone2_mname], - 'nsrecord': [dnszone2_mname], - 'idnssoarname': [dnszone2_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' - u'grant %(realm)s krb5-self * AAAA; ' - u'grant %(realm)s krb5-self * SSHFP;' - % dict(realm=api.env.realm)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - }, - }, - ), - - - dict( - desc='Retrieve zone %r' % dnszone1, - command=('dnszone_show', [dnszone1], {}), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - }, - }, - ), - - - dict( - desc='Update zone %r' % dnszone1, - command=('dnszone_mod', [dnszone1], {'idnssoarefresh': 5478}), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [u'5478'], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - }, - }, - ), - - - dict( - desc='Try to create reverse zone %r with NS record in it' % revdnszone1, - command=( - 'dnszone_add', [revdnszone1], { - 'idnssoamname': u'ns', - 'idnssoarname': dnszone1_rname, - } - ), - expected=errors.ValidationError(name='name-server', - error=u"Nameserver for reverse zone cannot be a relative DNS name"), - ), - - - dict( - desc='Create reverse zone %r' % revdnszone1, - command=( - 'dnszone_add', [revdnszone1], { - 'idnssoamname': dnszone1_mname, - 'idnssoarname': dnszone1_rname, - } - ), - expected={ - 'value': revdnszone1, - 'summary': None, - 'result': { - 'dn': revdnszone1_dn, - 'idnsname': [revdnszone1], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [dnszone1_mname], - 'nsrecord': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' - % dict(realm=api.env.realm, zone=revdnszone1)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - }, - }, - ), - - - dict( - desc='Search for zones with name server %r' % (dnszone1_mname), - command=('dnszone_find', [], {'idnssoamname': dnszone1_mname}), - expected={ - 'summary': None, - 'count': 2, - 'truncated': False, - 'result': [{ - 'dn': revdnszone1_dn, - 'idnsname': [revdnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - }, - { - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [u'5478'], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - }], - }, - ), - - - dict( - desc='Search for zones with name server %r with --forward-only' % dnszone1_mname, - command=('dnszone_find', [], {'idnssoamname': dnszone1_mname, 'forward_only' : True}), - expected={ - 'summary': None, - 'count': 1, - 'truncated': False, - 'result': [{ - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [u'5478'], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - }], - }, - ), - - - dict( - desc='Delete reverse zone %r' % revdnszone1, - command=('dnszone_del', [revdnszone1], {}), - expected={ - 'value': revdnszone1, - 'summary': u'Deleted DNS zone "%s"' % revdnszone1, - 'result': {'failed': u''}, - }, - ), - - - dict( - desc='Disable zone %r' % dnszone1, - command=('dnszone_disable', [dnszone1], {}), - expected={ - 'value': dnszone1, - 'summary': u'Disabled DNS zone "%s"' % dnszone1, - 'result': True, - }, - ), - - - dict( - desc='Check if zone %r is really disabled' % dnszone1, - command=('dnszone_show', [dnszone1], {}), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'FALSE'], - 'nsrecord': [dnszone1_mname], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - }, - }, - ), - - - dict( - desc='Enable zone %r' % dnszone1, - command=('dnszone_enable', [dnszone1], {}), - expected={ - 'value': dnszone1, - 'summary': u'Enabled DNS zone "%s"' % dnszone1, - 'result': True, - }, - ), - - - dict( - desc='Check if zone %r is really enabled' % dnszone1, - command=('dnszone_show', [dnszone1], {}), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - }, - }, - ), - - - dict( - desc='Try to retrieve non-existent record %r in zone %r' % (dnsres1, dnszone1), - command=('dnsrecord_show', [dnszone1, dnsres1], {}), - expected=errors.NotFound( - reason=u'%s: DNS resource record not found' % dnsres1), - ), - - - dict( - desc='Try to delete non-existent record %r in zone %r' % (dnsres1, dnszone1), - command=('dnsrecord_del', [dnszone1, dnsres1], {'del_all' : True}), - expected=errors.NotFound( - reason=u'%s: DNS resource record not found' % dnsres1), - ), - - - dict( - desc='Try to delete root zone record \'@\' in %r' % (dnszone1), - command=('dnsrecord_del', [dnszone1, u'@'], {'del_all' : True}), - expected=errors.ValidationError(name='del_all', - error=u"Zone record '@' cannot be deleted"), - ), - - - dict( - desc='Try to create record with invalid name in zone %r' % dnszone1, - command=('dnsrecord_add', [dnszone1, u'invalid record'], {'arecord': u'127.0.0.1'}), - expected=errors.ValidationError(name='name', - error=u'only letters, numbers, _, and - are allowed. ' + - u'DNS label may not start or end with -'), - ), - - - dict( - desc='Create record %r in zone %r' % (dnszone1, dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'127.0.0.1'}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'objectclass': objectclasses.dnsrecord, - 'arecord': [u'127.0.0.1'], - }, - }, - ), - - - dict( - desc='Search for all records in zone %r' % dnszone1, - command=('dnsrecord_find', [dnszone1], {}), - expected={ - 'summary': None, - 'count': 4, - 'truncated': False, - 'result': [ - { - 'dn': dnszone1_dn, - 'nsrecord': (dnszone1_mname,), - 'idnsname': [u'@'], - }, - { - 'dn': dnszone1_txtrec_dn, - 'txtrecord': [api.env.realm], - 'idnsname': [u'_kerberos'], - }, - { - 'dn': dnszone1_mname_dn, - 'idnsname': [u'ns1'], - 'arecord': [u'1.2.3.4'], - }, - { - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'arecord': [u'127.0.0.1'], - }, - ], - }, - ), - - - dict( - desc='Add A record to %r in zone %r' % (dnsres1, dnszone1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'10.10.0.1'}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'arecord': [u'127.0.0.1', u'10.10.0.1'], - 'objectclass': objectclasses.dnsrecord, - }, - }, - ), - - - dict( - desc='Remove A record from %r in zone %r' % (dnsres1, dnszone1), - command=('dnsrecord_del', [dnszone1, dnsres1], {'arecord': u'127.0.0.1'}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - }, - }, - ), - - - dict( - desc='Add AAAA record to %r in zone %r using dnsrecord_mod' % (dnsres1, dnszone1), - command=('dnsrecord_mod', [dnszone1, dnsres1], {'aaaarecord': u'::1'}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - 'aaaarecord': [u'::1'], - }, - }, - ), - - - dict( - desc='Try to modify nonexistent record in zone %r' % dnszone1, - command=('dnsrecord_mod', - [dnszone1, u'ghostname'], - {'aaaarecord': u'f001:baad::1'}), - expected=errors.NotFound( - reason=u'ghostname: DNS resource record not found'), - ), - - - dict( - desc='Modify AAAA record in %r in zone %r' % (dnsres1, dnszone1), - command=('dnsrecord_mod', [dnszone1, dnsres1], {'aaaarecord': u'ff02::1'}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - 'aaaarecord': [u'ff02::1'], - }, - }, - ), - - - dict( - desc='Remove AAAA record from %r in zone %r using dnsrecord_mod' % (dnsres1, dnszone1), - command=('dnsrecord_mod', [dnszone1, dnsres1], {'aaaarecord': u''}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - }, - }, - ), - - dict( - desc='Try to add invalid MX record to zone %r using dnsrecord_add' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'@'], {'mxrecord': dnszone1_mname }), - expected=errors.ValidationError(name='mx_rec', - error=u'format must be specified as "PREFERENCE EXCHANGER" ' + - u' (see RFC 1035 for details)'), - ), - - dict( - desc='Add MX record to zone %r using dnsrecord_add' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'@'], {'mxrecord': u"0 %s" % dnszone1_mname }), - expected={ - 'value': u'@', - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnszone, - 'dn': dnszone1_dn, - 'idnsname': [u'@'], - 'mxrecord': [u"0 %s" % dnszone1_mname], - 'nsrecord': [dnszone1_mname], - }, - }, - ), - - dict( - desc='Try to add invalid SRV record to zone %r using dnsrecord_add' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srvrecord': dnszone1_mname}), - expected=errors.ValidationError(name='srv_rec', - error=u'format must be specified as "PRIORITY WEIGHT PORT TARGET" ' + - u' (see RFC 2782 for details)'), - ), - - dict( - desc='Try to add invalid SRV record via parts to zone %r using dnsrecord_add' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 0, - 'srv_part_weight' : 0, - 'srv_part_port' : 123, - 'srv_part_target' : u'foo bar'}), - expected=errors.ValidationError(name='srv_target', - error=u'invalid domain-name: only letters, numbers, _, and - ' + - u'are allowed. DNS label may not start or end with -'), - ), - - dict( - desc='Try to add SRV record to zone %r both via parts and a raw value' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 0, - 'srv_part_weight' : 0, - 'srv_part_port' : 123, - 'srv_part_target' : u'foo.bar.', - 'srvrecord': [u"1 100 1234 %s" \ - % dnszone1_mname]}), - expected=errors.ValidationError(name='srv_target', - error=u'Raw value of a DNS record was already set by ' + - u'"srv_rec" option'), - ), - - dict( - desc='Add SRV record to zone %r using dnsrecord_add' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srvrecord': u"0 100 1234 %s" % dnszone1_mname}), - expected={ - 'value': u'_foo._tcp', - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': DN(('idnsname', u'_foo._tcp'), dnszone1_dn), - 'idnsname': [u'_foo._tcp'], - 'srvrecord': [u"0 100 1234 %s" % dnszone1_mname], - }, - }, - ), - - dict( - desc='Try to modify SRV record in zone %r without specifying modified value' % (dnszone1), - command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 1,}), - expected=errors.RequirementError(name='srvrecord'), - ), - - dict( - desc='Try to modify SRV record in zone %r with non-existent modified value' % (dnszone1), - command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 1, - 'srvrecord' : [u"0 100 1234 does.not.exist."] }), - expected=errors.AttrValueNotFound(attr='SRV record', - value=u'0 100 1234 does.not.exist.'), - ), - - dict( - desc='Try to modify SRV record in zone %r with invalid part value' % (dnszone1), - command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 100000, - 'srvrecord' : [u"0 100 1234 %s" % dnszone1_mname] }), - expected=errors.ValidationError(name='srv_priority', error=u'can be at most 65535'), - ), - - dict( - desc='Modify SRV record in zone %r using parts' % (dnszone1), - command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 1, - 'srvrecord' : [u"0 100 1234 %s" % dnszone1_mname] }), - expected={ - 'value': u'_foo._tcp', - 'summary': None, - 'result': { - 'idnsname': [u'_foo._tcp'], - 'srvrecord': [u"1 100 1234 %s" % dnszone1_mname], - }, - }, - ), - - dict( - desc='Try to add invalid LOC record to zone %r using dnsrecord_add' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'@'], {'locrecord': u"91 11 42.4 N 16 36 29.6 E 227.64" }), - expected=errors.ValidationError(name='lat_deg', - error=u'can be at most 90'), - ), - - dict( - desc='Add LOC record to zone %r using dnsrecord_add' % (dnszone1), - command=('dnsrecord_add', [dnszone1, u'@'], {'locrecord': u"49 11 42.4 N 16 36 29.6 E 227.64" }), - expected={ - 'value': u'@', - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnszone, - 'dn': dnszone1_dn, - 'idnsname': [u'@'], - 'mxrecord': [u"0 %s" % dnszone1_mname], - 'nsrecord': [dnszone1_mname], - 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], - }, - }, - ), - - dict( - desc='Try to add CNAME record to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'cnamerecord': u'foo-1.example.com.'}), - expected=errors.ValidationError(name='cnamerecord', - error=u'CNAME record is not allowed to coexist with any other ' - u'record (RFC 1034, section 3.6.2)'), - ), - - dict( - desc='Try to add invalid CNAME record %r using dnsrecord_add' % (dnsrescname), - command=('dnsrecord_add', [dnszone1, dnsrescname], {'cnamerecord': u'-.example.com'}), - expected=errors.ValidationError(name='hostname', - error=u'invalid domain-name: only letters, numbers, _, and - ' + - u'are allowed. DNS label may not start or end with -'), - ), - - dict( - desc='Try to add multiple CNAME record %r using dnsrecord_add' % (dnsrescname), - command=('dnsrecord_add', [dnszone1, dnsrescname], {'cnamerecord': - [u'1.example.com.', u'2.example.com.']}), - expected=errors.ValidationError(name='cnamerecord', - error=u'only one CNAME record is allowed per name (RFC 2136, section 1.1.5)'), - ), - - dict( - desc='Add CNAME record to %r using dnsrecord_add' % (dnsrescname), - command=('dnsrecord_add', [dnszone1, dnsrescname], {'cnamerecord': u'foo-1.example.com.'}), - expected={ - 'value': dnsrescname, - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': dnsrescname_dn, - 'idnsname': [dnsrescname], - 'cnamerecord': [u'foo-1.example.com.'], - }, - }, - ), - - dict( - desc='Try to add other record to CNAME record %r using dnsrecord_add' % (dnsrescname), - command=('dnsrecord_add', [dnszone1, dnsrescname], {'arecord': u'10.0.0.1'}), - expected=errors.ValidationError(name='cnamerecord', - error=u'CNAME record is not allowed to coexist with any other ' - u'record (RFC 1034, section 3.6.2)'), - ), - - dict( - desc='Try to add other record to CNAME record %r using dnsrecord_mod' % (dnsrescname), - command=('dnsrecord_mod', [dnszone1, dnsrescname], {'arecord': u'10.0.0.1'}), - expected=errors.ValidationError(name='cnamerecord', - error=u'CNAME record is not allowed to coexist with any other ' - u'record (RFC 1034, section 3.6.2)'), - ), - - dict( - desc='Add A record and delete CNAME record in %r with dnsrecord_mod' % (dnsrescname), - command=('dnsrecord_mod', [dnszone1, dnsrescname], {'arecord': u'10.0.0.1', - 'cnamerecord': None}), - expected={ - 'value': dnsrescname, - 'summary': None, - 'result': { - 'idnsname': [dnsrescname], - 'arecord': [u'10.0.0.1'], - }, - }, - ), - - dict( - desc='Try to add multiple DNAME records to %r using dnsrecord_add' % (dnsresdname), - command=('dnsrecord_add', [dnszone1, dnsres1], {'dnamerecord': - [u'foo-1.example.com.', u'foo-2.example.com.']}), - expected=errors.ValidationError(name='dnamerecord', - error=u'only one DNAME record is allowed per name (RFC 6672, section 2.4)'), - ), - - dict( - desc='Try to add invalid DNAME record %r using dnsrecord_add' % (dnsresdname), - command=('dnsrecord_add', [dnszone1, dnsresdname], {'dnamerecord': u'-.example.com.'}), - expected=errors.ValidationError(name='target', - error=u'invalid domain-name: only letters, numbers, _, and - ' + - u'are allowed. DNS label may not start or end with -'), - ), - - dict( - desc='Add DNAME record to %r using dnsrecord_add' % (dnsresdname), - command=('dnsrecord_add', [dnszone1, dnsresdname], - {'dnamerecord': u'd.example.com.', 'arecord': u'10.0.0.1'}), - expected={ - 'value': dnsresdname, - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': dnsresdname_dn, - 'idnsname': [dnsresdname], - 'dnamerecord': [u'd.example.com.'], - 'arecord': [u'10.0.0.1'], - }, - }, - ), - - dict( - desc='Try to add CNAME record to %r using dnsrecord_add' % (dnsresdname), - command=('dnsrecord_add', [dnszone1, dnsresdname], {'cnamerecord': u'foo-1.example.com.'}), - expected=errors.ValidationError(name='cnamerecord', - error=u'CNAME record is not allowed to coexist with any other ' - u'record (RFC 1034, section 3.6.2)'), - ), - - dict( - desc='Try to add NS record to %r using dnsrecord_add' % (dnsresdname), - command=('dnsrecord_add', [dnszone1, dnsresdname], - {'nsrecord': u'%s.%s.' % (dnsres1, dnszone1)}), - expected=errors.ValidationError(name='dnamerecord', - error=u'DNAME record is not allowed to coexist with an NS ' - u'record except when located in a zone root record (RFC 6672, section 2.3)'), - ), - - dict( - desc='Add NS+DNAME record to %r zone record using dnsrecord_add' % (dnszone2), - command=('dnsrecord_add', [dnszone2, u'@'], - {'dnamerecord': u'd.example.com.', - 'nsrecord': dnszone1_mname}), - expected = { - 'value': u'@', - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnszone, - 'dnamerecord': [u'd.example.com.'], - 'dn': dnszone2_dn, - 'nsrecord': [dnszone2_mname, dnszone1_mname], - 'idnsname': [u'@'] - } - }, - ), - - - dict( - desc='Delete zone %r' % dnszone2, - command=('dnszone_del', [dnszone2], {}), - expected={ - 'value': dnszone2, - 'summary': u'Deleted DNS zone "%s"' % dnszone2, - 'result': {'failed': u''}, - }, - ), - - dict( - desc='Try to add invalid KX record %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'kxrecord': u'foo-1.example.com' }), - expected=errors.ValidationError(name='kx_rec', - error=u'format must be specified as "PREFERENCE EXCHANGER" ' + - u' (see RFC 2230 for details)'), - ), - - dict( - desc='Add KX record to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'kxrecord': u'1 foo-1' }), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - 'kxrecord': [u'1 foo-1'], - }, - }, - ), - - dict( - desc='Add TXT record to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'txtrecord': u'foo bar' }), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - 'kxrecord': [u'1 foo-1'], - 'txtrecord': [u'foo bar'], - }, - }, - ), - - dict( - desc='Add NSEC record to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], { - 'nsec_part_next': dnszone1, - 'nsec_part_types' : [u'TXT', u'A']}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - 'kxrecord': [u'1 foo-1'], - 'txtrecord': [u'foo bar'], - 'nsecrecord': [dnszone1 + u' TXT A'], - }, - }, - ), - - dict( - desc='Try to add unresolvable absolute NS record to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist.'}), - expected=errors.NotFound(reason=u"Nameserver 'does.not.exist.' does not have a corresponding A/AAAA record"), - ), - - dict( - desc='Try to add unresolvable relative NS record to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist'}), - expected=errors.NotFound(reason=u"Nameserver 'does.not.exist.%s.' does not have a corresponding A/AAAA record" % dnszone1), - ), - - dict( - desc='Add unresolvable NS record with --force to %r using dnsrecord_add' % (dnsres1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist.', - 'force' : True}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'arecord': [u'10.10.0.1'], - 'kxrecord': [u'1 foo-1'], - 'txtrecord': [u'foo bar'], - 'nsecrecord': [dnszone1 + u' TXT A'], - 'nsrecord': [u'does.not.exist.'], - }, - }, - ), - - dict( - desc='Try to to rename DNS zone %r root record' % (dnszone1), - command=('dnsrecord_mod', [dnszone1, u'@'], {'rename': dnsres1_renamed,}), - expected=errors.ValidationError(name='rename', - error=u'DNS zone root record cannot be renamed') - ), - - dict( - desc='Rename DNS record %r to %r' % (dnsres1, dnsres1_renamed), - command=('dnsrecord_mod', [dnszone1, dnsres1], {'rename': dnsres1_renamed,}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'idnsname': [dnsres1_renamed], - 'arecord': [u'10.10.0.1'], - 'kxrecord': [u'1 foo-1'], - 'txtrecord': [u'foo bar'], - 'nsecrecord': [dnszone1 + u' TXT A'], - 'nsrecord': [u'does.not.exist.'], - }, - }, - ), - - - dict( - desc='Delete record %r in zone %r' % (dnsres1_renamed, dnszone1), - command=('dnsrecord_del', [dnszone1, dnsres1_renamed], {'del_all': True }), - expected={ - 'value': dnsres1_renamed, - 'summary': u'Deleted record "%s"' % dnsres1_renamed, - 'result': {'failed': u''}, - }, - ), - - - dict( - desc='Try to create a reverse zone from invalid IP', - command=( - 'dnszone_add', [], { - 'name_from_ip': u'foo', - 'idnssoamname': dnszone1_mname, - 'idnssoarname': dnszone1_rname, - } - ), - expected=errors.ValidationError(name='name_from_ip', - error=u'invalid IP network format'), - ), - - dict( - desc='Create reverse zone from IP/netmask %r using name_from_ip option' % revdnszone1_ip, - command=( - 'dnszone_add', [], { - 'name_from_ip': revdnszone1_ip, - 'idnssoamname': dnszone1_mname, - 'idnssoarname': dnszone1_rname, - } - ), - expected={ - 'value': revdnszone1, - 'summary': None, - 'result': { - 'dn': revdnszone1_dn, - 'idnsname': [revdnszone1], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [dnszone1_mname], - 'nsrecord': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' - % dict(realm=api.env.realm, zone=revdnszone1)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - }, - }, - ), - - - dict( - desc='Create reverse zone from IP %r using name_from_ip option' % revdnszone2_ip, - command=( - 'dnszone_add', [], { - 'name_from_ip': revdnszone2_ip, - 'idnssoamname': dnszone1_mname, - 'idnssoarname': dnszone1_rname, - } - ), - expected={ - 'value': revdnszone2, - 'summary': None, - 'result': { - 'dn': revdnszone2_dn, - 'idnsname': [revdnszone2], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [dnszone1_mname], - 'nsrecord': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' - % dict(realm=api.env.realm, zone=revdnszone2)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - }, - }, - ), - - - dict( - desc='Try to add invalid PTR %r to %r using dnsrecord_add' % (dnsrev1, revdnszone1), - command=('dnsrecord_add', [revdnszone1, dnsrev1], {'ptrrecord': u'-.example.com' }), - expected=errors.ValidationError(name='hostname', - error=u'invalid domain-name: only letters, numbers, and - ' + - u'are allowed. DNS label may not start or end with -'), - ), - - dict( - desc='Add PTR record %r to %r using dnsrecord_add' % (dnsrev1, revdnszone1), - command=('dnsrecord_add', [revdnszone1, dnsrev1], {'ptrrecord': u'foo-1.example.com' }), - expected={ - 'value': dnsrev1, - 'summary': None, - 'result': { - 'objectclass': objectclasses.dnsrecord, - 'dn': dnsrev1_dn, - 'idnsname': [dnsrev1], - 'ptrrecord': [u'foo-1.example.com.'], - }, - }, - ), - - dict( - desc='Show record %r in zone %r with --structured and --all options'\ - % (dnsrev1, revdnszone1), - command=('dnsrecord_show', [revdnszone1, dnsrev1], - {'structured': True, 'all': True}), - expected={ - 'value': dnsrev1, - 'summary': None, - 'result': { - 'dn': dnsrev1_dn, - 'idnsname': [dnsrev1], - 'objectclass': objectclasses.dnsrecord, - 'dnsrecords': [ - { - 'dnstype': u'PTR', - 'dnsdata': u'foo-1.example.com.', - 'ptr_part_hostname': u'foo-1.example.com.' - }, - ], - }, - }, - ), - - dict( - desc='Update global DNS settings', - command=('dnsconfig_mod', [], {'idnsforwarders' : [u'80.142.15.80'],}), - expected={ - 'value': u'', - 'summary': None, - 'result': { - 'idnsforwarders': [u'80.142.15.80'], - }, - }, - ), - - - dict( - desc='Try to add invalid allow-query to zone %r' % dnszone1, - command=('dnszone_mod', [dnszone1], {'idnsallowquery': u'foo'}), - expected=errors.ValidationError(name='allow_query', - error=u"failed to detect a valid IP address from 'foo'"), - ), - - dict( - desc='Add allow-query ACL to zone %r' % dnszone1, - command=('dnszone_mod', [dnszone1], {'idnsallowquery': u'!10/8;any'}), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'mxrecord': [u'0 ns1.dnszone.test.'], - 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [u'5478'], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowquery': [u'!10.0.0.0/8;any;'], - 'idnsallowtransfer': [u'none;'], - }, - }, - ), - - - dict( - desc='Try to add invalid allow-transfer to zone %r' % dnszone1, - command=('dnszone_mod', [dnszone1], {'idnsallowtransfer': u'10.'}), - expected=errors.ValidationError(name='allow_transfer', - error=u"failed to detect a valid IP address from '10.'"), - ), - - dict( - desc='Add allow-transer ACL to zone %r' % dnszone1, - command=('dnszone_mod', [dnszone1], {'idnsallowtransfer': u'80.142.15.80'}), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'mxrecord': [u'0 ns1.dnszone.test.'], - 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [u'5478'], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowquery': [u'!10.0.0.0/8;any;'], - 'idnsallowtransfer': [u'80.142.15.80;'], - }, - }, - ), - - - dict( - desc='Set SOA serial of zone %r to high number' % dnszone1, - command=('dnszone_mod', [dnszone1], {'idnssoaserial': 4294967295}), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'nsrecord': [dnszone1_mname], - 'mxrecord': [u'0 ns1.dnszone.test.'], - 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], - 'idnssoamname': [dnszone1_mname], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [u'4294967295'], - 'idnssoarefresh': [u'5478'], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowquery': [u'!10.0.0.0/8;any;'], - 'idnsallowtransfer': [u'80.142.15.80;'], - }, - }, - ), - - - dict( - desc='Try to create duplicate PTR record for %r with --a-create-reverse' % dnsres1, - command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'80.142.15.80', - 'a_extra_create_reverse' : True}), - expected=errors.DuplicateEntry(message=u'Reverse record for IP ' + - u'address 80.142.15.80 already exists in reverse zone ' + - u'15.142.80.in-addr.arpa..'), - ), - - - dict( - desc='Create A record %r in zone %r with --a-create-reverse' % (dnsres1, dnszone1), - command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'80.142.15.81', - 'a_extra_create_reverse' : True}), - expected={ - 'value': dnsres1, - 'summary': None, - 'result': { - 'dn': dnsres1_dn, - 'idnsname': [dnsres1], - 'objectclass': objectclasses.dnsrecord, - 'arecord': [u'80.142.15.81'], - }, - }, - ), - - - dict( - desc='Check reverse record for %r created via --a-create-reverse' % dnsres1, - command=('dnsrecord_show', [revdnszone1, dnsrev2], {}), - expected={ - 'value': dnsrev2, - 'summary': None, - 'result': { - 'dn': dnsrev2_dn, - 'idnsname': [dnsrev2], - 'ptrrecord': [dnsres1 + '.' + dnszone1 + '.'], - }, - }, - ), - - - dict( - desc='Try to add per-zone permission for unknown zone', - command=('dnszone_add_permission', [u'does.not.exist'], {}), - expected=errors.NotFound(reason=u'does.not.exist: DNS zone not found') - ), - - - dict( - desc='Add per-zone permission for zone %r' % dnszone1, - command=( - 'dnszone_add_permission', [dnszone1], {} - ), - expected=dict( - result=True, - value=dnszone1_permission, - summary=u'Added system permission "%s"' % dnszone1_permission, - ), - ), - - - dict( - desc='Try to add duplicate per-zone permission for zone %r' % dnszone1, - command=( - 'dnszone_add_permission', [dnszone1], {} - ), - expected=errors.DuplicateEntry(message=u'permission with name ' - '"%s" already exists' % dnszone1_permission) - ), - - - dict( - desc='Make sure the permission was created %r' % dnszone1, - command=( - 'permission_show', [dnszone1_permission], {} - ), - expected=dict( - value=dnszone1_permission, - summary=None, - result={ - 'dn': dnszone1_permission_dn, - 'cn': [dnszone1_permission], - 'ipapermissiontype': [u'SYSTEM'], - }, - ), - ), - - - dict( - desc='Try to remove per-zone permission for unknown zone', - command=('dnszone_remove_permission', [u'does.not.exist'], {}), - expected=errors.NotFound(reason=u'does.not.exist: DNS zone not found') - ), - - - dict( - desc='Remove per-zone permission for zone %r' % dnszone1, - command=( - 'dnszone_remove_permission', [dnszone1], {} - ), - expected=dict( - result=True, - value=dnszone1_permission, - summary=u'Removed system permission "%s"' % dnszone1_permission, - ), - ), - - - dict( - desc='Make sure the permission for zone %r was deleted' % dnszone1, - command=( - 'permission_show', [dnszone1_permission], {} - ), - expected=errors.NotFound(reason=u'%s: permission not found' - % dnszone1_permission) - ), - - - dict( - desc='Delete zone %r' % dnszone1, - command=('dnszone_del', [dnszone1], {}), - expected={ - 'value': dnszone1, - 'summary': u'Deleted DNS zone "%s"' % dnszone1, - 'result': {'failed': u''}, - }, - ), - - - dict( - desc='Try to create zone %r nameserver not in it' % dnszone1, - command=( - 'dnszone_add', [dnszone1], { - 'idnssoamname': u'not.in.this.zone.', - 'idnssoarname': dnszone1_rname, - 'ip_address' : u'1.2.3.4', - } - ), - expected=errors.ValidationError(name='ip_address', - error=u"Nameserver DNS record is created only for nameservers" - u" in current zone"), - ), - - - dict( - desc='Create zone %r with relative nameserver' % dnszone1, - command=( - 'dnszone_add', [dnszone1], { - 'idnssoamname': u'ns', - 'idnssoarname': dnszone1_rname, - 'ip_address' : u'1.2.3.4', - } - ), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [u'ns'], - 'nsrecord': [u'ns'], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' - u'grant %(realm)s krb5-self * AAAA; ' - u'grant %(realm)s krb5-self * SSHFP;' - % dict(realm=api.env.realm)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - }, - }, - ), - - - dict( - desc='Delete zone %r' % dnszone1, - command=('dnszone_del', [dnszone1], {}), - expected={ - 'value': dnszone1, - 'summary': u'Deleted DNS zone "%s"' % dnszone1, - 'result': {'failed': u''}, - }, - ), - - - dict( - desc='Create zone %r with nameserver in the zone itself' % dnszone1, - command=( - 'dnszone_add', [dnszone1], { - 'idnssoamname': dnszone1 + u'.', - 'idnssoarname': dnszone1_rname, - 'ip_address' : u'1.2.3.4', - } - ), - expected={ - 'value': dnszone1, - 'summary': None, - 'result': { - 'dn': dnszone1_dn, - 'idnsname': [dnszone1], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [dnszone1 + u'.'], - 'nsrecord': [dnszone1 + u'.'], - 'idnssoarname': [dnszone1_rname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' - u'grant %(realm)s krb5-self * AAAA; ' - u'grant %(realm)s krb5-self * SSHFP;' - % dict(realm=api.env.realm)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - }, - }, - ), - - ] diff --git a/tests/test_xmlrpc/test_dns_realmdomains_integration.py b/tests/test_xmlrpc/test_dns_realmdomains_integration.py deleted file mode 100644 index c4660a577..000000000 --- a/tests/test_xmlrpc/test_dns_realmdomains_integration.py +++ /dev/null @@ -1,168 +0,0 @@ -# Authors: -# Ana Krivokapic -# -# Copyright (C) 2013 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test integration of DNS and realmdomains. -1. dnszone_{add,del} should create/delete appropriate entry in realmdomains. -2. realmdomains_mod should add a _kerberos TXT record in the DNS zone. -""" - -from ipalib import api, errors -from ipapython.dn import DN -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits - - -cn = u'Realm Domains' -dn = DN(('cn', cn), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) -our_domain = api.env.domain -dnszone_1 = u'dnszone.test' -dnszone_1_dn = DN(('idnsname', dnszone_1), api.env.container_dns, - api.env.basedn) -idnssoamname = u'ns1.%s.' % dnszone_1 -idnssoarname = u'root.%s.' % dnszone_1 -dnszone_2 = u'dnszone2.test' -dnszone_2_dn = DN(('idnsname', dnszone_2), api.env.container_dns, - api.env.basedn) - - -def assert_realmdomain_and_txt_record_present(response): - zone = response['value'] - - r = api.Command['realmdomains_show']() - assert zone in r['result']['associateddomain'] - - r = api.Command['dnsrecord_show'](zone, u'_kerberos') - assert api.env.realm in r['result']['txtrecord'] - - return True - - -def assert_realmdomain_and_txt_record_not_present(response): - zone = response['value'] - - r = api.Command['realmdomains_show']() - assert zone not in r['result']['associateddomain'] - - try: - api.Command['dnsrecord_show'](zone, u'_kerberos') - except errors.NotFound: - return True - - -class test_dns_realmdomains_integration(Declarative): - cleanup_commands = [ - ('realmdomains_mod', [], {'associateddomain': [our_domain]}), - ('dnszone_del', [dnszone_1, dnszone_2], {'continue': True}), - ] - - tests = [ - dict( - desc='Check realmdomain and TXT record get created ' - 'during dnszone_add', - command=( - 'dnszone_add', [dnszone_1], { - 'idnssoamname': idnssoamname, - 'idnssoarname': idnssoarname, - 'ip_address': u'1.2.3.4', - } - ), - expected={ - 'value': dnszone_1, - 'summary': None, - 'result': { - 'dn': dnszone_1_dn, - 'idnsname': [dnszone_1], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [idnssoamname], - 'nsrecord': [idnssoamname], - 'idnssoarname': [idnssoarname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' - u'grant %(realm)s krb5-self * AAAA; ' - u'grant %(realm)s krb5-self * SSHFP;' - % dict(realm=api.env.realm)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - - }, - }, - extra_check=assert_realmdomain_and_txt_record_present, - ), - - dict( - desc='Check realmdomain and TXT record do not get created ' - 'during dnszone_add for forwarded zone', - command=( - 'dnszone_add', [dnszone_2], { - 'idnssoamname': idnssoamname, - 'idnssoarname': idnssoarname, - 'idnsforwarders': u'1.2.3.4', - 'idnsforwardpolicy': u'only', - 'force': True, - } - ), - expected={ - 'value': dnszone_2, - 'summary': None, - 'result': { - 'dn': dnszone_2_dn, - 'idnsname': [dnszone_2], - 'idnszoneactive': [u'TRUE'], - 'idnssoamname': [idnssoamname], - 'idnsforwarders': [u'1.2.3.4'], - 'idnsforwardpolicy': [u'only'], - 'nsrecord': [idnssoamname], - 'idnssoarname': [idnssoarname], - 'idnssoaserial': [fuzzy_digits], - 'idnssoarefresh': [fuzzy_digits], - 'idnssoaretry': [fuzzy_digits], - 'idnssoaexpire': [fuzzy_digits], - 'idnssoaminimum': [fuzzy_digits], - 'idnsallowdynupdate': [u'FALSE'], - 'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; ' - u'grant %(realm)s krb5-self * AAAA; ' - u'grant %(realm)s krb5-self * SSHFP;' - % dict(realm=api.env.realm)], - 'idnsallowtransfer': [u'none;'], - 'idnsallowquery': [u'any;'], - 'objectclass': objectclasses.dnszone, - - }, - }, - extra_check=assert_realmdomain_and_txt_record_not_present, - ), - - dict( - desc='Check realmdomain and TXT record get deleted ' - 'during dnszone_del', - command=('dnszone_del', [dnszone_1], {}), - expected={ - 'value': dnszone_1, - 'summary': u'Deleted DNS zone "%s"' % dnszone_1, - 'result': {'failed': u''}, - }, - extra_check=assert_realmdomain_and_txt_record_not_present, - ), - ] diff --git a/tests/test_xmlrpc/test_external_members.py b/tests/test_xmlrpc/test_external_members.py deleted file mode 100644 index 6f9949f45..000000000 --- a/tests/test_xmlrpc/test_external_members.py +++ /dev/null @@ -1,160 +0,0 @@ -# Authors: -# Ana Krivokapic -# -# Copyright (C) 2013 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test adding/removing external members (trusted domain objects) to IPA groups. -These tests are skipped if trust is not established. -""" - -import nose -from ipalib import api -from ipapython.dn import DN -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_user_or_group_sid - -group_name = u'external_group' -group_desc = u'Test external group' -group_dn = DN(('cn', group_name), api.env.container_group, api.env.basedn) - - -def get_trusted_group_name(): - trusts = api.Command['trust_find']() - if trusts['count'] == 0: - return None - - ad_netbios = trusts['result'][0]['ipantflatname'] - return u'%s\Domain Admins' % ad_netbios - - -class test_external_members(Declarative): - @classmethod - def setUpClass(cls): - super(test_external_members, cls).setUpClass() - if not api.Backend.xmlclient.isconnected(): - api.Backend.xmlclient.connect(fallback=False) - - trusts = api.Command['trust_find']() - if trusts['count'] == 0: - raise nose.SkipTest('Trust is not established') - - cleanup_commands = [ - ('group_del', [group_name], {}), - ] - - tests = [ - dict( - desc='Create external group "%s"' % group_name, - command=( - 'group_add', [group_name], dict(description=group_desc, external=True) - ), - expected=dict( - value=group_name, - summary=u'Added group "%s"' % group_name, - result=dict( - cn=[group_name], - description=[group_desc], - objectclass=objectclasses.externalgroup, - ipauniqueid=[fuzzy_uuid], - dn=group_dn, - ), - ), - ), - dict( - desc='Add external member "%s" to group "%s"' % (get_trusted_group_name(), group_name), - command=( - 'group_add_member', [group_name], dict(ipaexternalmember=get_trusted_group_name()) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result=dict( - dn=group_dn, - ipaexternalmember=[fuzzy_user_or_group_sid], - cn=[group_name], - description=[group_desc], - ), - ), - ), - dict( - desc='Try to add duplicate external member "%s" to group "%s"' % (get_trusted_group_name(), group_name), - command=( - 'group_add_member', [group_name], dict(ipaexternalmember=get_trusted_group_name()) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - group=[(fuzzy_user_or_group_sid, u'This entry is already a member')], - user=tuple(), - ), - ), - result=dict( - dn=group_dn, - ipaexternalmember=[fuzzy_user_or_group_sid], - cn=[group_name], - description=[group_desc], - ), - ), - ), - dict( - desc='Remove external member "%s" from group "%s"' % (get_trusted_group_name(), group_name), - command=( - 'group_remove_member', [group_name], dict(ipaexternalmember=get_trusted_group_name()) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result=dict( - dn=group_dn, - cn=[group_name], - ipaexternalmember=[], - description=[group_desc], - ), - ), - ), - dict( - desc='Try to remove external entry "%s" which is not a member of group "%s" from group "%s"' % (get_trusted_group_name(), group_name, group_name), - command=( - 'group_remove_member', [group_name], dict(ipaexternalmember=get_trusted_group_name()) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - group=[(fuzzy_user_or_group_sid, u'This entry is not a member')], - user=tuple(), - ), - ), - result=dict( - dn=group_dn, - cn=[group_name], - description=[group_desc], - ), - ), - ), - ] diff --git a/tests/test_xmlrpc/test_group_plugin.py b/tests/test_xmlrpc/test_group_plugin.py deleted file mode 100644 index 7a9b8b6d1..000000000 --- a/tests/test_xmlrpc/test_group_plugin.py +++ /dev/null @@ -1,1046 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/group.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from tests.util import Fuzzy -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid, fuzzy_set_ci -from ipapython.dn import DN - -group1 = u'testgroup1' -group2 = u'testgroup2' -group3 = u'testgroup3' -renamedgroup1 = u'testgroup' -user1 = u'tuser1' - -invalidgroup1=u'+tgroup1' - -# When adding external SID member to a group we can't test -# it fully due to possibly missing Samba 4 python bindings -# and/or not configured AD trusts. Thus, we'll use incorrect -# SID value to merely test that proper exceptions are raised -external_sid1=u'S-1-1-123456-789-1' - -def get_group_dn(cn): - return DN(('cn', cn), api.env.container_group, api.env.basedn) - -class test_group(Declarative): - cleanup_commands = [ - ('group_del', [group1], {}), - ('group_del', [group2], {}), - ('group_del', [group3], {}), - ('group_del', [renamedgroup1], {}), - ('user_del', [user1], {}), - ] - - tests = [ - - ################ - # create group1: - dict( - desc='Try to retrieve non-existent %r' % group1, - command=('group_show', [group1], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group1), - ), - - - dict( - desc='Try to update non-existent %r' % group1, - command=('group_mod', [group1], dict(description=u'Foo')), - expected=errors.NotFound(reason=u'%s: group not found' % group1), - ), - - - dict( - desc='Try to delete non-existent %r' % group1, - command=('group_del', [group1], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group1), - ), - - - dict( - desc='Try to rename non-existent %r' % group1, - command=('group_mod', [group1], dict(setattr=u'cn=%s' % renamedgroup1)), - expected=errors.NotFound(reason=u'%s: group not found' % group1), - ), - - - dict( - desc='Create non-POSIX %r' % group1, - command=( - 'group_add', [group1], dict(description=u'Test desc 1',nonposix=True) - ), - expected=dict( - value=group1, - summary=u'Added group "testgroup1"', - result=dict( - cn=[group1], - description=[u'Test desc 1'], - objectclass=objectclasses.group, - ipauniqueid=[fuzzy_uuid], - dn=get_group_dn('testgroup1'), - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % group1, - command=( - 'group_add', [group1], dict(description=u'Test desc 1') - ), - expected=errors.DuplicateEntry( - message=u'group with name "%s" already exists' % group1), - ), - - - dict( - desc='Retrieve non-POSIX %r' % group1, - command=('group_show', [group1], {}), - expected=dict( - value=group1, - summary=None, - result=dict( - cn=[group1], - description=[u'Test desc 1'], - dn=get_group_dn('testgroup1'), - ), - ), - ), - - - dict( - desc='Updated non-POSIX %r' % group1, - command=( - 'group_mod', [group1], dict(description=u'New desc 1') - ), - expected=dict( - result=dict( - cn=[group1], - description=[u'New desc 1'], - ), - summary=u'Modified group "testgroup1"', - value=group1, - ), - ), - - - dict( - desc='Retrieve %r to verify update' % group1, - command=('group_show', [group1], {}), - expected=dict( - value=group1, - result=dict( - cn=[group1], - description=[u'New desc 1'], - dn=get_group_dn('testgroup1'), - ), - summary=None, - ), - ), - - - # FIXME: The return value is totally different here than from the above - # group_mod() test. I think that for all *_mod() commands we should - # just return the entry exactly as *_show() does. - dict( - desc='Updated %r to promote it to a POSIX group' % group1, - command=('group_mod', [group1], dict(posix=True)), - expected=dict( - result=dict( - cn=[group1], - description=[u'New desc 1'], - gidnumber=[fuzzy_digits], - ), - value=group1, - summary=u'Modified group "testgroup1"', - ), - ), - - - dict( - desc="Retrieve %r to verify it's a POSIX group" % group1, - command=('group_show', [group1], {}), - expected=dict( - value=group1, - result=dict( - cn=[group1], - description=(u'New desc 1',), - dn=get_group_dn('testgroup1'), - gidnumber=[fuzzy_digits], - ), - summary=None, - ), - ), - - - dict( - desc='Search for %r' % group1, - command=('group_find', [], dict(cn=group1)), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - dn=get_group_dn(group1), - cn=[group1], - description=[u'New desc 1'], - gidnumber=[fuzzy_digits], - ), - ], - summary=u'1 group matched', - ), - ), - - - - ################ - # create group2: - dict( - desc='Try to retrieve non-existent %r' % group2, - command=('group_show', [group2], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group2), - ), - - - dict( - desc='Try to update non-existent %r' % group2, - command=('group_mod', [group2], dict(description=u'Foo')), - expected=errors.NotFound(reason=u'%s: group not found' % group2), - ), - - - dict( - desc='Try to delete non-existent %r' % group2, - command=('group_del', [group2], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group2), - ), - - - dict( - desc='Create %r' % group2, - command=( - 'group_add', [group2], dict(description=u'Test desc 2') - ), - expected=dict( - value=group2, - summary=u'Added group "testgroup2"', - result=dict( - cn=[group2], - description=[u'Test desc 2'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.posixgroup, - ipauniqueid=[fuzzy_uuid], - dn=get_group_dn('testgroup2'), - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % group2, - command=( - 'group_add', [group2], dict(description=u'Test desc 2') - ), - expected=errors.DuplicateEntry( - message=u'group with name "%s" already exists' % group2), - ), - - - dict( - desc='Retrieve %r' % group2, - command=('group_show', [group2], {}), - expected=dict( - value=group2, - summary=None, - result=dict( - cn=[group2], - description=[u'Test desc 2'], - gidnumber=[fuzzy_digits], - dn=get_group_dn('testgroup2'), - ), - ), - ), - - - dict( - desc='Updated %r' % group2, - command=( - 'group_mod', [group2], dict(description=u'New desc 2') - ), - expected=dict( - result=dict( - cn=[group2], - gidnumber=[fuzzy_digits], - description=[u'New desc 2'], - ), - summary=u'Modified group "testgroup2"', - value=group2, - ), - ), - - - dict( - desc='Retrieve %r to verify update' % group2, - command=('group_show', [group2], {}), - expected=dict( - value=group2, - result=dict( - cn=[group2], - description=[u'New desc 2'], - gidnumber=[fuzzy_digits], - dn=get_group_dn('testgroup2'), - ), - summary=None, - ), - ), - - - dict( - desc='Search for %r' % group2, - command=('group_find', [], dict(cn=group2)), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - dn=get_group_dn('testgroup2'), - cn=[group2], - description=[u'New desc 2'], - gidnumber=[fuzzy_digits], - ), - ], - summary=u'1 group matched', - ), - ), - - - dict( - desc='Search for all groups', - command=('group_find', [], {}), - expected=dict( - summary=u'6 groups matched', - count=6, - truncated=False, - result=[ - { - 'dn': get_group_dn('admins'), - 'member_user': [u'admin'], - 'gidnumber': [fuzzy_digits], - 'cn': [u'admins'], - 'description': [u'Account administrators group'], - }, - { - 'dn': get_group_dn('editors'), - 'gidnumber': [fuzzy_digits], - 'cn': [u'editors'], - 'description': [u'Limited admins who can edit other users'], - }, - { - 'dn': get_group_dn('ipausers'), - 'cn': [u'ipausers'], - 'description': [u'Default group for all users'], - }, - dict( - dn=get_group_dn(group1), - cn=[group1], - description=[u'New desc 1'], - gidnumber=[fuzzy_digits], - ), - dict( - dn=get_group_dn(group2), - cn=[group2], - description=[u'New desc 2'], - gidnumber=[fuzzy_digits], - ), - { - 'dn': get_group_dn('trust admins'), - 'member_user': [u'admin'], - 'cn': [u'trust admins'], - 'description': [u'Trusts administrators group'], - }, - ], - ), - ), - - dict( - desc='Search for non-POSIX groups', - command=('group_find', [], dict(nonposix=True, all=True)), - expected=dict( - summary=u'2 groups matched', - count=2, - truncated=False, - result=[ - { - 'dn': get_group_dn('ipausers'), - 'cn': [u'ipausers'], - 'description': [u'Default group for all users'], - 'objectclass': fuzzy_set_ci(objectclasses.group), - 'ipauniqueid': [fuzzy_uuid], - }, - { - 'dn': get_group_dn('trust admins'), - 'member_user': [u'admin'], - 'cn': [u'trust admins'], - 'description': [u'Trusts administrators group'], - 'objectclass': fuzzy_set_ci(objectclasses.group), - 'ipauniqueid': [fuzzy_uuid], - }, - ], - ), - ), - - dict( - desc='Search for non-POSIX groups with criteria filter', - command=('group_find', [u'users'], dict(nonposix=True, all=True)), - expected=dict( - summary=u'1 group matched', - count=1, - truncated=False, - result=[ - { - 'dn': get_group_dn('ipausers'), - 'cn': [u'ipausers'], - 'description': [u'Default group for all users'], - 'objectclass': fuzzy_set_ci(objectclasses.group), - 'ipauniqueid': [fuzzy_uuid], - }, - ], - ), - ), - - dict( - desc='Search for POSIX groups', - command=('group_find', [], dict(posix=True, all=True)), - expected=dict( - summary=u'4 groups matched', - count=4, - truncated=False, - result=[ - { - 'dn': get_group_dn('admins'), - 'member_user': [u'admin'], - 'gidnumber': [fuzzy_digits], - 'cn': [u'admins'], - 'description': [u'Account administrators group'], - 'objectclass': fuzzy_set_ci(objectclasses.posixgroup), - 'ipauniqueid': [fuzzy_uuid], - }, - { - 'dn': get_group_dn('editors'), - 'gidnumber': [fuzzy_digits], - 'cn': [u'editors'], - 'description': [u'Limited admins who can edit other users'], - 'objectclass': fuzzy_set_ci(objectclasses.posixgroup), - 'ipauniqueid': [fuzzy_uuid], - }, - dict( - dn=get_group_dn(group1), - cn=[group1], - description=[u'New desc 1'], - gidnumber=[fuzzy_digits], - objectclass=fuzzy_set_ci(objectclasses.posixgroup), - ipauniqueid=[fuzzy_uuid], - ), - dict( - dn=get_group_dn(group2), - cn=[group2], - description=[u'New desc 2'], - gidnumber=[fuzzy_digits], - objectclass=fuzzy_set_ci(objectclasses.posixgroup), - ipauniqueid=[fuzzy_uuid], - ), - ], - ), - ), - - - ############### - # test external SID members for group3: - dict( - desc='Create external %r' % group3, - command=( - 'group_add', [group3], dict(description=u'Test desc 3',external=True) - ), - expected=dict( - value=group3, - summary=u'Added group "testgroup3"', - result=dict( - cn=[group3], - description=[u'Test desc 3'], - objectclass=objectclasses.externalgroup, - ipauniqueid=[fuzzy_uuid], - dn=get_group_dn(group3), - ), - ), - ), - - dict( - desc='Search for external groups', - command=('group_find', [], dict(external=True, all=True)), - expected=dict( - summary=u'1 group matched', - count=1, - truncated=False, - result=[ - dict( - cn=[group3], - description=[u'Test desc 3'], - objectclass=fuzzy_set_ci(objectclasses.externalgroup), - ipauniqueid=[fuzzy_uuid], - dn=get_group_dn(group3), - ), - ], - ), - ), - - - dict( - desc='Convert posix group %r to support external membership' % (group2), - command=( - 'group_mod', [group2], dict(external=True) - ), - expected=errors.PosixGroupViolation(), - ), - - - dict( - desc='Convert external members group %r to posix' % (group3), - command=( - 'group_mod', [group3], dict(posix=True) - ), - expected=errors.ExternalGroupViolation(), - ), - - - dict( - desc='Add external member %r to %r' % (external_sid1, group3), - command=( - 'group_add_member', [group3], dict(ipaexternalmember=external_sid1) - ), - expected=lambda x, output: type(x) == errors.ValidationError or type(x) == errors.NotFound, - ), - - - dict( - desc='Remove group %r with external membership' % (group3), - command=('group_del', [group3], {}), - expected=dict( - result=dict(failed=u''), - value=group3, - summary=u'Deleted group "testgroup3"', - ), - ), - - - ############### - # member stuff: - dict( - desc='Add member %r to %r' % (group2, group1), - command=( - 'group_add_member', [group1], dict(group=group2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': get_group_dn(group1), - 'member_group': (group2,), - 'gidnumber': [fuzzy_digits], - 'cn': [group1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - # FIXME: Shouldn't this raise a NotFound instead? - desc='Try to add non-existent member to %r' % group1, - command=( - 'group_add_member', [group1], dict(group=u'notfound') - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - group=[(u'notfound', u'no such entry')], - user=tuple(), - ), - ), - result={ - 'dn': get_group_dn(group1), - 'member_group': (group2,), - 'gidnumber': [fuzzy_digits], - 'cn': [group1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - desc='Remove member %r from %r' % (group2, group1), - command=('group_remove_member', - [group1], dict(group=group2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': get_group_dn(group1), - 'cn': [group1], - 'gidnumber': [fuzzy_digits], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - # FIXME: Shouldn't this raise a NotFound instead? - desc='Try to remove non-existent member from %r' % group1, - command=('group_remove_member', - [group1], dict(group=u'notfound') - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - group=[(u'notfound', u'This entry is not a member')], - user=tuple(), - ), - ), - result={ - 'dn': get_group_dn(group1), - 'cn': [group1], - 'gidnumber': [fuzzy_digits], - 'description': [u'New desc 1'], - }, - ), - ), - - - dict( - desc='Rename %r' % group1, - command=('group_mod', [group1], dict(setattr=u'cn=%s' % renamedgroup1)), - expected=dict( - value=group1, - result=dict( - cn=[renamedgroup1], - description=[u'New desc 1'], - gidnumber=[fuzzy_digits], - ), - summary=u'Modified group "%s"' % group1 - ) - ), - - - dict( - desc='Rename %r back' % renamedgroup1, - command=('group_mod', [renamedgroup1], dict(setattr=u'cn=%s' % group1)), - expected=dict( - value=renamedgroup1, - result=dict( - cn=[group1], - description=[u'New desc 1'], - gidnumber=[fuzzy_digits], - ), - summary=u'Modified group "%s"' % renamedgroup1 - ) - ), - - - - ################ - # delete group1: - dict( - desc='Delete %r' % group1, - command=('group_del', [group1], {}), - expected=dict( - result=dict(failed=u''), - value=group1, - summary=u'Deleted group "testgroup1"', - ) - ), - - - dict( - desc='Try to delete non-existent %r' % group1, - command=('group_del', [group1], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group1), - ), - - - dict( - desc='Try to retrieve non-existent %r' % group1, - command=('group_show', [group1], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group1), - ), - - - dict( - desc='Try to update non-existent %r' % group1, - command=('group_mod', [group1], dict(description=u'Foo')), - expected=errors.NotFound(reason=u'%s: group not found' % group1), - ), - - - - ################ - # delete group2: - dict( - desc='Delete %r' % group2, - command=('group_del', [group2], {}), - expected=dict( - result=dict(failed=u''), - value=group2, - summary=u'Deleted group "testgroup2"', - ) - ), - - - dict( - desc='Try to delete non-existent %r' % group2, - command=('group_del', [group2], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group2), - ), - - - dict( - desc='Try to retrieve non-existent %r' % group2, - command=('group_show', [group2], {}), - expected=errors.NotFound(reason=u'%s: group not found' % group2), - ), - - - dict( - desc='Try to update non-existent %r' % group2, - command=('group_mod', [group2], dict(description=u'Foo')), - expected=errors.NotFound(reason=u'%s: group not found' % group2), - ), - - dict( - desc='Test an invalid group name %r' % invalidgroup1, - command=('group_add', [invalidgroup1], dict(description=u'Test')), - expected=errors.ValidationError(name='group_name', - error=u'may only include letters, numbers, _, -, . and $'), - ), - - # The assumption on these next 4 tests is that if we don't get a - # validation error then the request was processed normally. - dict( - desc='Test that validation is disabled on mods', - command=('group_mod', [invalidgroup1], {}), - expected=errors.NotFound( - reason=u'%s: group not found' % invalidgroup1), - ), - - - dict( - desc='Test that validation is disabled on deletes', - command=('group_del', [invalidgroup1], {}), - expected=errors.NotFound( - reason=u'%s: group not found' % invalidgroup1), - ), - - - dict( - desc='Test that validation is disabled on show', - command=('group_show', [invalidgroup1], {}), - expected=errors.NotFound( - reason=u'%s: group not found' % invalidgroup1), - ), - - - ##### managed entry tests - dict( - desc='Create %r' % user1, - command=( - 'user_add', [], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/%s' % user1], - krbprincipalname=[u'%s@%s' % (user1, api.env.realm)], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - dn=DN(('uid',user1),('cn','users'),('cn','accounts'), - api.env.basedn), - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Verify the managed group %r was created' % user1, - command=('group_show', [user1], {}), - expected=dict( - value=user1, - summary=None, - result=dict( - cn=[user1], - description=[u'User private group for %s' % user1], - gidnumber=[fuzzy_digits], - dn=get_group_dn(user1), - ), - ), - ), - - - dict( - desc='Verify that managed group %r can be found' % user1, - command=('group_find', [], {'cn': user1, 'private': True}), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - dn=get_group_dn(user1), - cn=[user1], - description=[u'User private group for %s' % user1], - gidnumber=[fuzzy_digits], - ), - ], - summary=u'1 group matched', - ), - ), - - - dict( - desc='Try to delete a managed group %r' % user1, - command=('group_del', [user1], {}), - expected=errors.ManagedGroupError(), - ), - - - dict( - desc='Detach managed group %r' % user1, - command=('group_detach', [user1], {}), - expected=dict( - result=True, - value=user1, - summary=u'Detached group "%s" from user "%s"' % (user1, user1), - ), - ), - - - dict( - desc='Now delete the unmanaged group %r' % user1, - command=('group_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - value=user1, - summary=u'Deleted group "%s"' % user1, - ) - ), - - dict( - desc='Verify that %r is really gone' % user1, - command=('group_show', [user1], {}), - expected=errors.NotFound(reason=u'%s: group not found' % user1), - ), - - dict( - desc='Delete %r' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "tuser1"', - value=user1, - ), - ), - - dict( - desc='Create %r without User Private Group' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', noprivate=True, gidnumber=1000) - ), - expected=dict( - value=user1, - summary=u'Added user "tuser1"', - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - description=[], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user_base, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[u'1000'], - mail=[u'%s@%s' % (user1, api.env.domain)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('uid','tuser1'),('cn','users'),('cn','accounts'), - api.env.basedn), - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - ), - ), - ), - - dict( - desc='Verify the managed group %r was not created' % user1, - command=('group_show', [user1], {}), - expected=errors.NotFound(reason=u'%s: group not found' % user1), - ), - - dict( - desc='Try to remove the admin user from the admins group', - command=('group_remove_member', [u'admins'], dict(user=[u'admin'])), - expected=errors.LastMemberError(key=u'admin', label=u'group', - container='admins'), - ), - - dict( - desc='Add %r to the admins group' % user1, - command=('group_add_member', [u'admins'], dict(user=user1)), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': get_group_dn('admins'), - 'member_user': [u'admin', user1], - 'gidnumber': [fuzzy_digits], - 'cn': [u'admins'], - 'description': [u'Account administrators group'], - }, - ), - ), - - dict( - desc='Try to remove admin and %r from the admins group' % user1, - command=('group_remove_member', [u'admins'], - dict(user=[u'admin', user1])), - expected=errors.LastMemberError(key=u'admin', label=u'group', - container='admins'), - ), - - dict( - desc='Try to delete the admins group', - command=('group_del', [u'admins'], {}), - expected=errors.ProtectedEntryError(label=u'group', - key='admins', reason='privileged group'), - ), - - - dict( - desc='Try to rename the admins group', - command=('group_mod', [u'admins'], dict(rename=u'loosers')), - expected=errors.ProtectedEntryError(label=u'group', - key='admins', reason='Cannot be renamed'), - ), - - dict( - desc='Try to rename the admins group via setattr', - command=('group_mod', [u'admins'], {'setattr': u'cn=loosers'}), - expected=errors.ProtectedEntryError(label=u'group', - key='admins', reason='Cannot be renamed'), - ), - - dict( - desc='Try to modify the admins group to support external membership', - command=('group_mod', [u'admins'], dict(external=True)), - expected=errors.ProtectedEntryError(label=u'group', - key='admins', reason='Cannot support external non-IPA members'), - ), - - dict( - desc='Try to delete the trust admins group', - command=('group_del', [u'trust admins'], {}), - expected=errors.ProtectedEntryError(label=u'group', - key='trust admins', reason='privileged group'), - ), - - dict( - desc='Try to rename the trust admins group', - command=('group_mod', [u'trust admins'], dict(rename=u'loosers')), - expected=errors.ProtectedEntryError(label=u'group', - key='trust admins', reason='Cannot be renamed'), - ), - - dict( - desc='Try to rename the trust admins group via setattr', - command=('group_mod', [u'trust admins'], {'setattr': u'cn=loosers'}), - expected=errors.ProtectedEntryError(label=u'group', - key='trust admins', reason='Cannot be renamed'), - ), - - - dict( - desc='Try to modify the trust admins group to support external membership', - command=('group_mod', [u'trust admins'], dict(external=True)), - expected=errors.ProtectedEntryError(label=u'group', - key='trust admins', reason='Cannot support external non-IPA members'), - ), - - dict( - desc='Delete %r' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - ] diff --git a/tests/test_xmlrpc/test_hbac_plugin.py b/tests/test_xmlrpc/test_hbac_plugin.py deleted file mode 100644 index c0f8b5307..000000000 --- a/tests/test_xmlrpc/test_hbac_plugin.py +++ /dev/null @@ -1,497 +0,0 @@ -# Authors: -# Pavel Zuna -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/hbacrule.py` module. -""" - -from nose.tools import raises, assert_raises # pylint: disable=E0611 - -from xmlrpc_test import XMLRPC_test, assert_attr_equal -from ipalib import api -from ipalib import errors - -class test_hbac(XMLRPC_test): - """ - Test the `hbacrule` plugin. - """ - rule_name = u'testing_rule1234' - rule_type = u'allow' - rule_type_fail = u'value not allowed' - rule_service = u'ssh' - rule_time = u'absolute 20081010000000 ~ 20081015120000' - rule_time2 = u'absolute 20081010000000 ~ 20081016120000' - # wrong time, has 30th day in February in first date - rule_time_fail = u'absolute 20080230000000 ~ 20081015120000' - rule_desc = u'description' - rule_desc_mod = u'description modified' - - test_user = u'hbacrule_test_user' - test_group = u'hbacrule_test_group' - test_host = u'hbacrule.testnetgroup' - test_hostgroup = u'hbacrule_test_hostgroup' - test_service = u'sshd' - test_host_external = u'notfound.example.com' - - test_invalid_sourcehost = u'inv+alid#srchost.nonexist.com' - - def test_0_hbacrule_add(self): - """ - Test adding a new HBAC rule using `xmlrpc.hbacrule_add`. - """ - ret = self.failsafe_add(api.Object.hbacrule, - self.rule_name, - accessruletype=self.rule_type, - description=self.rule_desc, - ) - entry = ret['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert_attr_equal(entry, 'accessruletype', self.rule_type) - assert_attr_equal(entry, 'ipaenabledflag', 'TRUE') - assert_attr_equal(entry, 'description', self.rule_desc) - - @raises(errors.DuplicateEntry) - def test_1_hbacrule_add(self): - """ - Test adding an existing HBAC rule using `xmlrpc.hbacrule_add'. - """ - api.Command['hbacrule_add']( - self.rule_name, accessruletype=self.rule_type - ) - - def test_2_hbacrule_show(self): - """ - Test displaying a HBAC rule using `xmlrpc.hbacrule_show`. - """ - entry = api.Command['hbacrule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert_attr_equal(entry, 'ipaenabledflag', 'TRUE') - assert_attr_equal(entry, 'description', self.rule_desc) - - def test_3_hbacrule_mod(self): - """ - Test modifying a HBAC rule using `xmlrpc.hbacrule_mod`. - """ - ret = api.Command['hbacrule_mod']( - self.rule_name, description=self.rule_desc_mod - ) - entry = ret['result'] - assert_attr_equal(entry, 'description', self.rule_desc_mod) - -# def test_4_hbacrule_add_accesstime(self): -# """ -# Test adding access time to HBAC rule using `xmlrpc.hbacrule_add_accesstime`. -# """ -# return -# ret = api.Command['hbacrule_add_accesstime']( -# self.rule_name, accesstime=self.rule_time2 -# ) -# entry = ret['result'] -# assert_attr_equal(entry, 'accesstime', self.rule_time); -# assert_attr_equal(entry, 'accesstime', self.rule_time2); - -# def test_5_hbacrule_add_accesstime(self): -# """ -# Test adding invalid access time to HBAC rule using `xmlrpc.hbacrule_add_accesstime`. -# """ -# try: -# api.Command['hbacrule_add_accesstime']( -# self.rule_name, accesstime=self.rule_time_fail -# ) -# except errors.ValidationError: -# pass -# else: -# assert False - - def test_6_hbacrule_find(self): - """ - Test searching for HBAC rules using `xmlrpc.hbacrule_find`. - """ - ret = api.Command['hbacrule_find']( - cn=self.rule_name, accessruletype=self.rule_type, - description=self.rule_desc_mod - ) - assert ret['truncated'] is False - entries = ret['result'] - assert_attr_equal(entries[0], 'cn', self.rule_name) - assert_attr_equal(entries[0], 'accessruletype', self.rule_type) - assert_attr_equal(entries[0], 'description', self.rule_desc_mod) - - def test_7_hbacrule_init_testing_data(self): - """ - Initialize data for more HBAC plugin testing. - """ - self.failsafe_add(api.Object.user, - self.test_user, givenname=u'first', sn=u'last' - ) - self.failsafe_add(api.Object.group, - self.test_group, description=u'description' - ) - self.failsafe_add(api.Object.host, - self.test_host, force=True - ) - self.failsafe_add(api.Object.hostgroup, - self.test_hostgroup, description=u'description' - ) - self.failsafe_add(api.Object.hbacsvc, - self.test_service, description=u'desc', - ) - - def test_8_hbacrule_add_user(self): - """ - Test adding user and group to HBAC rule using `xmlrpc.hbacrule_add_user`. - """ - ret = api.Command['hbacrule_add_user']( - self.rule_name, user=self.test_user, group=self.test_group - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberuser' in failed - assert 'user' in failed['memberuser'] - assert not failed['memberuser']['user'] - assert 'group' in failed['memberuser'] - assert not failed['memberuser']['group'] - entry = ret['result'] - assert_attr_equal(entry, 'memberuser_user', self.test_user) - assert_attr_equal(entry, 'memberuser_group', self.test_group) - - def test_9_a_show_user(self): - """ - Test showing a user to verify HBAC rule membership - `xmlrpc.user_show`. - """ - ret = api.Command['user_show'](self.test_user, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_hbacrule', self.rule_name) - - def test_9_b_show_group(self): - """ - Test showing a group to verify HBAC rule membership - `xmlrpc.group_show`. - """ - ret = api.Command['group_show'](self.test_group, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_hbacrule', self.rule_name) - - def test_9_hbacrule_remove_user(self): - """ - Test removing user and group from HBAC rule using `xmlrpc.hbacrule_remove_user'. - """ - ret = api.Command['hbacrule_remove_user']( - self.rule_name, user=self.test_user, group=self.test_group - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberuser' in failed - assert 'user' in failed['memberuser'] - assert not failed['memberuser']['user'] - assert 'group' in failed['memberuser'] - assert not failed['memberuser']['group'] - entry = ret['result'] - assert 'memberuser_user' not in entry - assert 'memberuser_group' not in entry - - def test_a_hbacrule_add_host(self): - """ - Test adding host and hostgroup to HBAC rule using `xmlrpc.hbacrule_add_host`. - """ - ret = api.Command['hbacrule_add_host']( - self.rule_name, host=self.test_host, hostgroup=self.test_hostgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberhost' in failed - assert 'host' in failed['memberhost'] - assert not failed['memberhost']['host'] - assert 'hostgroup' in failed['memberhost'] - assert not failed['memberhost']['hostgroup'] - entry = ret['result'] - assert_attr_equal(entry, 'memberhost_host', self.test_host) - assert_attr_equal(entry, 'memberhost_hostgroup', self.test_hostgroup) - - def test_a_hbacrule_show_host(self): - """ - Test showing host to verify HBAC rule membership - `xmlrpc.host_show`. - """ - ret = api.Command['host_show'](self.test_host, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_hbacrule', self.rule_name) - - def test_a_hbacrule_show_hostgroup(self): - """ - Test showing hostgroup to verify HBAC rule membership - `xmlrpc.hostgroup_show`. - """ - ret = api.Command['hostgroup_show'](self.test_hostgroup, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_hbacrule', self.rule_name) - - def test_b_hbacrule_remove_host(self): - """ - Test removing host and hostgroup from HBAC rule using `xmlrpc.hbacrule_remove_host`. - """ - ret = api.Command['hbacrule_remove_host']( - self.rule_name, host=self.test_host, hostgroup=self.test_hostgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberhost' in failed - assert 'host' in failed['memberhost'] - assert not failed['memberhost']['host'] - assert 'hostgroup' in failed['memberhost'] - assert not failed['memberhost']['hostgroup'] - entry = ret['result'] - assert 'memberhost_host' not in entry - assert 'memberhost_hostgroup' not in entry - - @raises(errors.DeprecationError) - def test_a_hbacrule_add_sourcehost_deprecated(self): - """ - Test deprecated command hbacrule_add_sourcehost. - """ - ret = api.Command['hbacrule_add_sourcehost']( - self.rule_name, host=self.test_host, hostgroup=self.test_hostgroup - ) - - def test_a_hbacrule_add_service(self): - """ - Test adding service to HBAC rule using `xmlrpc.hbacrule_add_service`. - """ - ret = api.Command['hbacrule_add_service']( - self.rule_name, hbacsvc=self.test_service - ) - assert ret['completed'] == 1 - failed = ret['failed'] - assert 'memberservice' in failed - assert 'hbacsvc' in failed['memberservice'] - assert not failed['memberservice']['hbacsvc'] - entry = ret['result'] - assert_attr_equal(entry, 'memberservice_hbacsvc', self.test_service) - - def test_a_hbacrule_remove_service(self): - """ - Test removing service to HBAC rule using `xmlrpc.hbacrule_remove_service`. - """ - ret = api.Command['hbacrule_remove_service']( - self.rule_name, hbacsvc=self.test_service - ) - assert ret['completed'] == 1 - failed = ret['failed'] - assert 'memberservice' in failed - assert 'hbacsvc' in failed['memberservice'] - assert not failed['memberservice']['hbacsvc'] - entry = ret['result'] - assert 'memberservice service' not in entry - - @raises(errors.DeprecationError) - def test_b_hbacrule_remove_sourcehost_deprecated(self): - """ - Test deprecated command hbacrule_remove_sourcehost. - """ - ret = api.Command['hbacrule_remove_sourcehost']( - self.rule_name, host=self.test_host, hostgroup=self.test_hostgroup - ) - - @raises(errors.ValidationError) - def test_c_hbacrule_mod_invalid_external_setattr(self): - """ - Test adding the same external host using `xmlrpc.hbacrule_add_host`. - """ - ret = api.Command['hbacrule_mod']( - self.rule_name, setattr=self.test_invalid_sourcehost - ) - - def test_d_hbacrule_disable(self): - """ - Test disabling HBAC rule using `xmlrpc.hbacrule_disable`. - """ - assert api.Command['hbacrule_disable'](self.rule_name)['result'] is True - entry = api.Command['hbacrule_show'](self.rule_name)['result'] - # FIXME: Should this be 'disabled' or 'FALSE'? - assert_attr_equal(entry, 'ipaenabledflag', 'FALSE') - - def test_e_hbacrule_enabled(self): - """ - Test enabling HBAC rule using `xmlrpc.hbacrule_enable`. - """ - assert api.Command['hbacrule_enable'](self.rule_name)['result'] is True - # check it's really enabled - entry = api.Command['hbacrule_show'](self.rule_name)['result'] - # FIXME: Should this be 'enabled' or 'TRUE'? - assert_attr_equal(entry, 'ipaenabledflag', 'TRUE') - - def test_ea_hbacrule_disable_setattr(self): - """ - Test disabling HBAC rule using setattr - """ - command_result = api.Command['hbacrule_mod']( - self.rule_name, setattr=u'ipaenabledflag=false') - assert command_result['result']['ipaenabledflag'] == (u'FALSE',) - entry = api.Command['hbacrule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'ipaenabledflag', 'FALSE') - - def test_eb_hbacrule_enable_setattr(self): - """ - Test enabling HBAC rule using setattr - """ - command_result = api.Command['hbacrule_mod']( - self.rule_name, setattr=u'ipaenabledflag=1') - assert command_result['result']['ipaenabledflag'] == (u'TRUE',) - # check it's really enabled - entry = api.Command['hbacrule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'ipaenabledflag', 'TRUE') - - @raises(errors.MutuallyExclusiveError) - def test_f_hbacrule_exclusiveuser(self): - """ - Test adding a user to an HBAC rule when usercat='all' - """ - api.Command['hbacrule_mod'](self.rule_name, usercategory=u'all') - try: - api.Command['hbacrule_add_user'](self.rule_name, user=u'admin') - finally: - api.Command['hbacrule_mod'](self.rule_name, usercategory=u'') - - @raises(errors.MutuallyExclusiveError) - def test_g_hbacrule_exclusiveuser(self): - """ - Test setting usercat='all' in an HBAC rule when there are users - """ - api.Command['hbacrule_add_user'](self.rule_name, user=u'admin') - try: - api.Command['hbacrule_mod'](self.rule_name, usercategory=u'all') - finally: - api.Command['hbacrule_remove_user'](self.rule_name, user=u'admin') - - @raises(errors.MutuallyExclusiveError) - def test_h_hbacrule_exclusivehost(self): - """ - Test adding a host to an HBAC rule when hostcat='all' - """ - api.Command['hbacrule_mod'](self.rule_name, hostcategory=u'all') - try: - api.Command['hbacrule_add_host'](self.rule_name, host=self.test_host) - finally: - api.Command['hbacrule_mod'](self.rule_name, hostcategory=u'') - - @raises(errors.MutuallyExclusiveError) - def test_i_hbacrule_exclusivehost(self): - """ - Test setting hostcat='all' in an HBAC rule when there are hosts - """ - api.Command['hbacrule_add_host'](self.rule_name, host=self.test_host) - try: - api.Command['hbacrule_mod'](self.rule_name, hostcategory=u'all') - finally: - api.Command['hbacrule_remove_host'](self.rule_name, host=self.test_host) - - @raises(errors.MutuallyExclusiveError) - def test_j_hbacrule_exclusiveservice(self): - """ - Test adding a service to an HBAC rule when servicecat='all' - """ - api.Command['hbacrule_mod'](self.rule_name, servicecategory=u'all') - try: - api.Command['hbacrule_add_service'](self.rule_name, hbacsvc=self.test_service) - finally: - api.Command['hbacrule_mod'](self.rule_name, servicecategory=u'') - - @raises(errors.MutuallyExclusiveError) - def test_k_hbacrule_exclusiveservice(self): - """ - Test setting servicecat='all' in an HBAC rule when there are services - """ - api.Command['hbacrule_add_service'](self.rule_name, hbacsvc=self.test_service) - try: - api.Command['hbacrule_mod'](self.rule_name, servicecategory=u'all') - finally: - api.Command['hbacrule_remove_service'](self.rule_name, hbacsvc=self.test_service) - - @raises(errors.ValidationError) - def test_l_hbacrule_add(self): - """ - Test adding a new HBAC rule with a deny type. - """ - api.Command['hbacrule_add']( - u'denyrule', - accessruletype=u'deny', - description=self.rule_desc, - ) - - @raises(errors.ValidationError) - def test_m_hbacrule_add(self): - """ - Test changing an HBAC rule to the deny type - """ - api.Command['hbacrule_mod']( - self.rule_name, - accessruletype=u'deny', - ) - - def test_n_hbacrule_links(self): - """ - Test adding various links to HBAC rule - """ - api.Command['hbacrule_add_service']( - self.rule_name, hbacsvc=self.test_service - ) - - entry = api.Command['hbacrule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert_attr_equal(entry, 'memberservice_hbacsvc', self.test_service) - - def test_y_hbacrule_zap_testing_data(self): - """ - Clear data for HBAC plugin testing. - """ - api.Command['hbacrule_remove_host'](self.rule_name, host=self.test_host) - api.Command['hbacrule_remove_host'](self.rule_name, hostgroup=self.test_hostgroup) - api.Command['user_del'](self.test_user) - api.Command['group_del'](self.test_group) - api.Command['host_del'](self.test_host) - api.Command['hostgroup_del'](self.test_hostgroup) - api.Command['hbacsvc_del'](self.test_service) - - def test_k_2_sudorule_referential_integrity(self): - """ - Test that links in HBAC rule were removed by referential integrity plugin - """ - entry = api.Command['hbacrule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert 'sourcehost_host' not in entry - assert 'sourcehost_hostgroup' not in entry - assert 'memberservice_hbacsvc' not in entry - - def test_z_hbacrule_del(self): - """ - Test deleting a HBAC rule using `xmlrpc.hbacrule_del`. - """ - api.Command['hbacrule_del'](self.rule_name) - # verify that it's gone - with assert_raises(errors.NotFound): - api.Command['hbacrule_show'](self.rule_name) - - @raises(errors.ValidationError) - def test_zz_hbacrule_add_with_deprecated_option(self): - """ - Test using a deprecated command option 'sourcehostcategory' with 'hbacrule_add'. - """ - api.Command['hbacrule_add']( - self.rule_name, sourcehostcategory=u'all' - ) diff --git a/tests/test_xmlrpc/test_hbacsvcgroup_plugin.py b/tests/test_xmlrpc/test_hbacsvcgroup_plugin.py deleted file mode 100644 index 591c8a966..000000000 --- a/tests/test_xmlrpc/test_hbacsvcgroup_plugin.py +++ /dev/null @@ -1,256 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.plugins.hbacsvcgroup` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid -from tests.test_xmlrpc import objectclasses -from ipapython.dn import DN - -hbacsvcgroup1 = u'testhbacsvcgroup1' -dn1 = DN(('cn',hbacsvcgroup1),('cn','hbacservicegroups'),('cn','hbac'), - api.env.basedn) - -hbacsvc1 = u'sshd' -hbacsvc_dn1 = DN(('cn',hbacsvc1),('cn','hbacservices'),('cn','hbac'), - api.env.basedn) - - -class test_hbacsvcgroup(Declarative): - - cleanup_commands = [ - ('hbacsvcgroup_del', [hbacsvcgroup1], {}), - ('hbacsvc_del', [hbacsvc1], {}), - ] - - tests=[ - - dict( - desc='Try to retrieve non-existent %r' % hbacsvcgroup1, - command=('hbacsvcgroup_show', [hbacsvcgroup1], {}), - expected=errors.NotFound( - reason=u'%s: HBAC service group not found' % hbacsvcgroup1), - ), - - - dict( - desc='Try to update non-existent %r' % hbacsvcgroup1, - command=('hbacsvcgroup_mod', [hbacsvcgroup1], - dict(description=u'Updated hbacsvcgroup 1') - ), - expected=errors.NotFound( - reason=u'%s: HBAC service group not found' % hbacsvcgroup1), - ), - - - dict( - desc='Try to delete non-existent %r' % hbacsvcgroup1, - command=('hbacsvcgroup_del', [hbacsvcgroup1], {}), - expected=errors.NotFound( - reason=u'%s: HBAC service group not found' % hbacsvcgroup1), - ), - - - dict( - desc='Create %r' % hbacsvcgroup1, - command=('hbacsvcgroup_add', [hbacsvcgroup1], - dict(description=u'Test hbacsvcgroup 1') - ), - expected=dict( - value=hbacsvcgroup1, - summary=u'Added HBAC service group "testhbacsvcgroup1"', - result=dict( - dn=dn1, - cn=[hbacsvcgroup1], - objectclass=objectclasses.hbacsvcgroup, - description=[u'Test hbacsvcgroup 1'], - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % hbacsvcgroup1, - command=('hbacsvcgroup_add', [hbacsvcgroup1], - dict(description=u'Test hbacsvcgroup 1') - ), - expected=errors.DuplicateEntry( - message=u'HBAC service group with name "%s" already exists' % - hbacsvcgroup1), - ), - - - dict( - desc='Create service %r' % hbacsvc1, - command=('hbacsvc_add', [hbacsvc1], - dict( - description=u'Test service 1', - ), - ), - expected=dict( - value=hbacsvc1, - summary=u'Added HBAC service "%s"' % hbacsvc1, - result=dict( - dn=hbacsvc_dn1, - cn=[hbacsvc1], - description=[u'Test service 1'], - objectclass=objectclasses.hbacsvc, - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc=u'Add service %r to %r' % (hbacsvc1, hbacsvcgroup1), - command=( - 'hbacsvcgroup_add_member', [hbacsvcgroup1], dict(hbacsvc=hbacsvc1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - hbacsvc=tuple(), - ), - ), - result={ - 'dn': dn1, - 'cn': [hbacsvcgroup1], - 'description': [u'Test hbacsvcgroup 1'], - 'member_hbacsvc': [hbacsvc1], - }, - ), - ), - - - dict( - desc='Retrieve %r' % hbacsvcgroup1, - command=('hbacsvcgroup_show', [hbacsvcgroup1], {}), - expected=dict( - value=hbacsvcgroup1, - summary=None, - result={ - 'dn': dn1, - 'member_hbacsvc': [hbacsvc1], - 'cn': [hbacsvcgroup1], - 'description': [u'Test hbacsvcgroup 1'], - }, - ), - ), - - - dict( - desc='Search for %r' % hbacsvcgroup1, - command=('hbacsvcgroup_find', [], dict(cn=hbacsvcgroup1)), - expected=dict( - count=1, - truncated=False, - summary=u'1 HBAC service group matched', - result=[ - { - 'dn': dn1, - 'member_hbacsvc': [hbacsvc1], - 'cn': [hbacsvcgroup1], - 'description': [u'Test hbacsvcgroup 1'], - }, - ], - ), - ), - - - dict( - desc='Update %r' % hbacsvcgroup1, - command=('hbacsvcgroup_mod', [hbacsvcgroup1], - dict(description=u'Updated hbacsvcgroup 1') - ), - expected=dict( - value=hbacsvcgroup1, - summary=u'Modified HBAC service group "testhbacsvcgroup1"', - result=dict( - cn=[hbacsvcgroup1], - description=[u'Updated hbacsvcgroup 1'], - member_hbacsvc=[hbacsvc1], - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % hbacsvcgroup1, - command=('hbacsvcgroup_show', [hbacsvcgroup1], {}), - expected=dict( - value=hbacsvcgroup1, - summary=None, - result={ - 'dn': dn1, - 'member_hbacsvc': [hbacsvc1], - 'cn': [hbacsvcgroup1], - 'description': [u'Updated hbacsvcgroup 1'], - }, - ), - ), - - - dict( - desc='Remove service %r from %r' % (hbacsvc1, hbacsvcgroup1), - command=('hbacsvcgroup_remove_member', [hbacsvcgroup1], - dict(hbacsvc=hbacsvc1) - ), - expected=dict( - failed=dict( - member=dict( - hbacsvc=tuple(), - ), - ), - completed=1, - result={ - 'dn': dn1, - 'cn': [hbacsvcgroup1], - 'description': [u'Updated hbacsvcgroup 1'], - }, - ), - ), - - - dict( - desc='Delete %r' % hbacsvcgroup1, - command=('hbacsvcgroup_del', [hbacsvcgroup1], {}), - expected=dict( - value=hbacsvcgroup1, - summary=u'Deleted HBAC service group "testhbacsvcgroup1"', - result=dict(failed=u''), - ), - ), - - - dict( - desc='Delete service %r' % hbacsvc1, - command=('hbacsvc_del', [hbacsvc1], {}), - expected=dict( - value=hbacsvc1, - summary=u'Deleted HBAC service "%s"' % hbacsvc1, - result=dict(failed=u''), - ), - ) - - ] diff --git a/tests/test_xmlrpc/test_hbactest_plugin.py b/tests/test_xmlrpc/test_hbactest_plugin.py deleted file mode 100644 index 520f20247..000000000 --- a/tests/test_xmlrpc/test_hbactest_plugin.py +++ /dev/null @@ -1,217 +0,0 @@ -# Authors: -# Pavel Zuna -# Alexander Bokovoy -# -# Copyright (C) 2009-2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/hbactest.py` module. -""" - -from xmlrpc_test import XMLRPC_test, assert_attr_equal -from ipalib import api -from ipalib import errors -from types import NoneType -from nose.tools import raises - -# Test strategy: -# 1. Create few allow rules: with user categories, with explicit users, with user groups, with groups, with services -# 2. Create users for test -# 3. Run detailed and non-detailed tests for explicitly specified rules, check expected result -# -class test_hbactest(XMLRPC_test): - """ - Test the `hbactest` plugin. - """ - rule_names = [u'testing_rule1234_%d' % (d) for d in [1,2,3,4]] - rule_type = u'allow' - rule_service = u'ssh' - rule_descs = [u'description %d' % (d) for d in [1,2,3,4]] - - test_user = u'hbacrule_test_user' - test_group = u'hbacrule_test_group' - test_host = u'hbacrule.testhost' - test_hostgroup = u'hbacrule_test_hostgroup' - test_sourcehost = u'hbacrule.testsrchost' - test_sourcehostgroup = u'hbacrule_test_src_hostgroup' - test_service = u'ssh' - - # Auxiliary funcion for checking existence of warning for specified rule - def check_rule_presence(self,rule_name,warnings): - for warning in warnings: - if rule_name in warning: - return True - return False - - def test_0_hbactest_addrules(self): - """ - Prepare data by adding test HBAC rules using `xmlrpc.hbacrule_add'. - """ - - self.failsafe_add(api.Object.user, - self.test_user, givenname=u'first', sn=u'last' - ) - self.failsafe_add(api.Object.group, - self.test_group, description=u'description' - ) - self.failsafe_add(api.Object.host, - self.test_host, force=True - ) - self.failsafe_add(api.Object.hostgroup, - self.test_hostgroup, description=u'description' - ) - self.failsafe_add(api.Object.host, - self.test_sourcehost, force=True - ) - self.failsafe_add(api.Object.hostgroup, - self.test_sourcehostgroup, description=u'desc' - ) - self.failsafe_add(api.Object.hbacsvc, - self.test_service, description=u'desc' - ) - - for i in [0,1,2,3]: - api.Command['hbacrule_add']( - self.rule_names[i], accessruletype=self.rule_type, description=self.rule_descs[i], - ) - - ret = api.Command['hbacrule_add_user']( - self.rule_names[i], user=self.test_user, group=self.test_group - ) - - ret = api.Command['hbacrule_add_host']( - self.rule_names[i], host=self.test_host, hostgroup=self.test_hostgroup - ) - - ret = api.Command['hbacrule_add_service']( - self.rule_names[i], hbacsvc=self.test_service - ) - - if i & 1: - ret = api.Command['hbacrule_disable'](self.rule_names[i]) - - def test_a_hbactest_check_rules_detail(self): - """ - Test 'ipa hbactest --rules' (explicit IPA rules, detailed output) - """ - ret = api.Command['hbactest']( - user=self.test_user, - targethost=self.test_host, - service=self.test_service, - rules=self.rule_names - ) - assert ret['value'] == True - assert type(ret['error']) == NoneType - for i in [0,1,2,3]: - assert self.rule_names[i] in ret['matched'] - - def test_b_hbactest_check_rules_nodetail(self): - """ - Test 'ipa hbactest --rules --nodetail' (explicit IPA rules, no detailed output) - """ - ret = api.Command['hbactest']( - user=self.test_user, - targethost=self.test_host, - service=self.test_service, - rules=self.rule_names, - nodetail=True - ) - assert ret['value'] == True - assert ret['error'] == None - assert ret['matched'] == None - assert ret['notmatched'] == None - - def test_c_hbactest_check_rules_enabled_detail(self): - """ - Test 'ipa hbactest --enabled' (all enabled IPA rules, detailed output) - """ - ret = api.Command['hbactest']( - user=self.test_user, - targethost=self.test_host, - service=self.test_service, - enabled=True - ) - # --enabled will try to work with _all_ enabled rules in IPA database - # It means we could have matched something else (unlikely but possible) - # Thus, check that our two enabled rules are in matched, nothing more - for i in [0,2]: - assert self.rule_names[i] in ret['matched'] - - def test_d_hbactest_check_rules_disabled_detail(self): - """ - Test 'ipa hbactest --disabled' (all disabled IPA rules, detailed output) - """ - ret = api.Command['hbactest']( - user=self.test_user, - targethost=self.test_host, - service=self.test_service, - disabled=True - ) - # --disabled will try to work with _all_ disabled rules in IPA database - # It means we could have matched something else (unlikely but possible) - # Thus, check that our two disabled rules are in matched, nothing more - for i in [1,3]: - assert self.rule_names[i] in ret['matched'] - - def test_e_hbactest_check_non_existing_rule_detail(self): - """ - Test running 'ipa hbactest' with non-existing rule in --rules - """ - ret = api.Command['hbactest']( - user=self.test_user, - targethost=self.test_host, - service=self.test_service, - rules=[u'%s_1x1' % (rule) for rule in self.rule_names], - nodetail=True - ) - - assert ret['value'] == False - assert ret['matched'] == None - assert ret['notmatched'] == None - for rule in self.rule_names: - assert u'%s_1x1' % (rule) in ret['error'] - - @raises(errors.ValidationError) - def test_f_hbactest_check_sourcehost_option_is_deprecated(self): - """ - Test running 'ipa hbactest' with --srchost option raises ValidationError - """ - api.Command['hbactest']( - user=self.test_user, - targethost=self.test_host, - sourcehost=self.test_sourcehost, - service=self.test_service, - rules=[u'%s_1x1' % rule for rule in self.rule_names], - nodetail=True - ) - - def test_g_hbactest_clear_testing_data(self): - """ - Clear data for HBAC test plugin testing. - """ - for i in [0,1,2,3]: - api.Command['hbacrule_remove_host'](self.rule_names[i], host=self.test_host) - api.Command['hbacrule_remove_host'](self.rule_names[i], hostgroup=self.test_hostgroup) - api.Command['hbacrule_del'](self.rule_names[i]) - - api.Command['user_del'](self.test_user) - api.Command['group_del'](self.test_group) - api.Command['host_del'](self.test_host) - api.Command['hostgroup_del'](self.test_hostgroup) - api.Command['host_del'](self.test_sourcehost) - api.Command['hostgroup_del'](self.test_sourcehostgroup) - api.Command['hbacsvc_del'](self.test_service) - diff --git a/tests/test_xmlrpc/test_host_plugin.py b/tests/test_xmlrpc/test_host_plugin.py deleted file mode 100644 index 07faf7760..000000000 --- a/tests/test_xmlrpc/test_host_plugin.py +++ /dev/null @@ -1,939 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2008, 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.plugins.host` module. -""" - -import os -import tempfile -from ipapython import ipautil -from ipalib import api, errors, x509 -from ipapython.dn import DN -from nose.tools import raises, assert_raises -from nose.plugins.skip import Skip, SkipTest -from tests.test_xmlrpc.xmlrpc_test import (Declarative, XMLRPC_test, - fuzzy_uuid, fuzzy_digits, fuzzy_hash, fuzzy_date, fuzzy_issuer, - fuzzy_hex) -from tests.test_xmlrpc import objectclasses -import base64 - - -fqdn1 = u'testhost1.%s' % api.env.domain -short1 = u'testhost1' -dn1 = DN(('fqdn',fqdn1),('cn','computers'),('cn','accounts'), - api.env.basedn) -service1 = u'dns/%s@%s' % (fqdn1, api.env.realm) -service1dn = DN(('krbprincipalname',service1.lower()),('cn','services'), - ('cn','accounts'),api.env.basedn) -fqdn2 = u'shouldnotexist.%s' % api.env.domain -dn2 = DN(('fqdn',fqdn2),('cn','computers'),('cn','accounts'), - api.env.basedn) -fqdn3 = u'testhost2.%s' % api.env.domain -short3 = u'testhost2' -dn3 = DN(('fqdn',fqdn3),('cn','computers'),('cn','accounts'), - api.env.basedn) -fqdn4 = u'testhost2.lab.%s' % api.env.domain -dn4 = DN(('fqdn',fqdn4),('cn','computers'),('cn','accounts'), - api.env.basedn) -invalidfqdn1 = u'foo_bar.lab.%s' % api.env.domain - -# We can use the same cert we generated for the service tests -fd = open('tests/test_xmlrpc/service.crt', 'r') -servercert = fd.readlines() -servercert = ''.join(servercert) -servercert = x509.strip_header(servercert) -fd.close() - -sshpubkey = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGAX3xAeLeaJggwTqMjxNwa6XHBUAikXPGMzEpVrlLDCZtv00djsFTBi38PkgxBJVkgRWMrcBsr/35lq7P6w8KGIwA8GI48Z0qBS2NBMJ2u9WQ2hjLN6GdMlo77O0uJY3251p12pCVIS/bHRSq8kHO2No8g7KA9fGGcagPfQH+ee3t7HUkpbQkFTmbPPN++r3V8oVUk5LxbryB3UIIVzNmcSIn3JrXynlvui4MixvrtX6zx+O/bBo68o8/eZD26QrahVbA09fivrn/4h3TM019Eu/c2jOdckfU3cHUV/3Tno5d6JicibyaoDDK7S/yjdn5jhaz8MSEayQvFkZkiF0L public key test' -sshpubkeyfp = u'13:67:6B:BF:4E:A2:05:8E:AE:25:8B:A1:31:DE:6F:1B public key test (ssh-rsa)' - -class test_host(Declarative): - - cleanup_commands = [ - ('host_del', [fqdn1], {}), - ('host_del', [fqdn2], {}), - ('host_del', [fqdn3], {}), - ('host_del', [fqdn4], {}), - ('service_del', [service1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % fqdn1, - command=('host_show', [fqdn1], {}), - expected=errors.NotFound( - reason=u'%s: host not found' % fqdn1), - ), - - - dict( - desc='Try to update non-existent %r' % fqdn1, - command=('host_mod', [fqdn1], dict(description=u'Nope')), - expected=errors.NotFound( - reason=u'%s: host not found' % fqdn1), - ), - - - dict( - desc='Try to delete non-existent %r' % fqdn1, - command=('host_del', [fqdn1], {}), - expected=errors.NotFound( - reason=u'%s: host not found' % fqdn1), - ), - - - dict( - desc='Create %r' % fqdn1, - command=('host_add', [fqdn1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn1, - summary=u'Added host "%s"' % fqdn1, - result=dict( - dn=dn1, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn1], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % fqdn1, - command=('host_add', [fqdn1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=errors.DuplicateEntry(message=u'host with name ' + - u'"%s" already exists' % fqdn1), - ), - - - dict( - desc='Retrieve %r' % fqdn1, - command=('host_show', [fqdn1], {}), - expected=dict( - value=fqdn1, - summary=None, - result=dict( - dn=dn1, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - has_keytab=False, - has_password=False, - managedby_host=[fqdn1], - ), - ), - ), - - - dict( - desc='Retrieve %r with all=True' % fqdn1, - command=('host_show', [fqdn1], dict(all=True)), - expected=dict( - value=fqdn1, - summary=None, - result=dict( - dn=dn1, - cn=[fqdn1], - fqdn=[fqdn1], - description=[u'Test host 1'], - # FIXME: Why is 'localalityname' returned as 'l' with --all? - # It is intuitive for --all to return additional attributes, - # but not to return existing attributes under different - # names. - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - serverhostname=[u'testhost1'], - objectclass=objectclasses.host, - managedby_host=[fqdn1], - managing_host=[fqdn1], - ipauniqueid=[fuzzy_uuid], - has_keytab=False, - has_password=False, - ipakrbokasdelegate=False, - ipakrbrequirespreauth=True, - ), - ), - ), - - - dict( - desc='Search for %r' % fqdn1, - command=('host_find', [fqdn1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 host matched', - result=[ - dict( - dn=dn1, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - managedby_host=[u'%s' % fqdn1], - has_keytab=False, - has_password=False, - ), - ], - ), - ), - - - dict( - desc='Search for %r with all=True' % fqdn1, - command=('host_find', [fqdn1], dict(all=True)), - expected=dict( - count=1, - truncated=False, - summary=u'1 host matched', - result=[ - dict( - dn=dn1, - cn=[fqdn1], - fqdn=[fqdn1], - description=[u'Test host 1'], - # FIXME: Why is 'localalityname' returned as 'l' with --all? - # It is intuitive for --all to return additional attributes, - # but not to return existing attributes under different - # names. - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - serverhostname=[u'testhost1'], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[u'%s' % fqdn1], - managing_host=[u'%s' % fqdn1], - has_keytab=False, - has_password=False, - ipakrbokasdelegate=False, - ipakrbrequirespreauth=True, - ), - ], - ), - ), - - - dict( - desc='Update %r' % fqdn1, - command=('host_mod', [fqdn1], dict(description=u'Updated host 1', - usercertificate=servercert)), - expected=dict( - value=fqdn1, - summary=u'Modified host "%s"' % fqdn1, - result=dict( - description=[u'Updated host 1'], - fqdn=[fqdn1], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % fqdn1, - command=('host_show', [fqdn1], {}), - expected=dict( - value=fqdn1, - summary=None, - result=dict( - dn=dn1, - fqdn=[fqdn1], - description=[u'Updated host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - has_keytab=False, - has_password=False, - managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - ), - ), - ), - - dict( - desc='Create %r' % fqdn3, - command=('host_add', [fqdn3], - dict( - description=u'Test host 2', - l=u'Undisclosed location 2', - force=True, - ), - ), - expected=dict( - value=fqdn3, - summary=u'Added host "%s"' % fqdn3, - result=dict( - dn=dn3, - fqdn=[fqdn3], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn3, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[u'%s' % fqdn3], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Create %r' % fqdn4, - command=('host_add', [fqdn4], - dict( - description=u'Test host 4', - l=u'Undisclosed location 4', - force=True, - ), - ), - expected=dict( - value=fqdn4, - summary=u'Added host "%s"' % fqdn4, - result=dict( - dn=dn4, - fqdn=[fqdn4], - description=[u'Test host 4'], - l=[u'Undisclosed location 4'], - krbprincipalname=[u'host/%s@%s' % (fqdn4, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[u'%s' % fqdn4], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Add managedby_host %r to %r' % (fqdn1, fqdn3), - command=('host_add_managedby', [fqdn3], - dict( - host=u'%s' % fqdn1, - ), - ), - expected=dict( - completed=1, - failed=dict( - managedby = dict( - host=tuple(), - ), - ), - result=dict( - dn=dn3, - fqdn=[fqdn3], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn3, api.env.realm)], - managedby_host=[u'%s' % fqdn3, u'%s' % fqdn1], - ), - ), - ), - - dict( - desc='Retrieve %r' % fqdn3, - command=('host_show', [fqdn3], {}), - expected=dict( - value=fqdn3, - summary=None, - result=dict( - dn=dn3, - fqdn=[fqdn3], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn3, api.env.realm)], - has_keytab=False, - has_password=False, - managedby_host=[u'%s' % fqdn3, u'%s' % fqdn1], - ), - ), - ), - - dict( - desc='Search for hosts with --man-hosts and --not-man-hosts', - command=('host_find', [], {'man_host' : fqdn3, 'not_man_host' : fqdn1}), - expected=dict( - count=1, - truncated=False, - summary=u'1 host matched', - result=[ - dict( - dn=dn3, - fqdn=[fqdn3], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn3, api.env.realm)], - has_keytab=False, - has_password=False, - managedby_host=[u'%s' % fqdn3, u'%s' % fqdn1], - ), - ], - ), - ), - - dict( - desc='Try to search for hosts with --man-hosts', - command=('host_find', [], {'man_host' : [fqdn3,fqdn4]}), - expected=dict( - count=0, - truncated=False, - summary=u'0 hosts matched', - result=[], - ), - ), - - dict( - desc='Remove managedby_host %r from %r' % (fqdn1, fqdn3), - command=('host_remove_managedby', [fqdn3], - dict( - host=u'%s' % fqdn1, - ), - ), - expected=dict( - completed=1, - failed=dict( - managedby = dict( - host=tuple(), - ), - ), - result=dict( - dn=dn3, - fqdn=[fqdn3], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn3, api.env.realm)], - managedby_host=[u'%s' % fqdn3], - ), - ), - ), - - - dict( - desc='Show a host with multiple matches %s' % short3, - command=('host_show', [short3], {}), - expected=errors.SingleMatchExpected(found=2), - ), - - - dict( - desc='Try to rename %r' % fqdn1, - command=('host_mod', [fqdn1], dict(setattr=u'fqdn=changed.example.com')), - expected=errors.NotAllowedOnRDN() - ), - - - dict( - desc='Add MAC address to %r' % fqdn1, - command=('host_mod', [fqdn1], dict(macaddress=u'00:50:56:30:F6:5F')), - expected=dict( - value=fqdn1, - summary=u'Modified host "%s"' % fqdn1, - result=dict( - description=[u'Updated host 1'], - fqdn=[fqdn1], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - macaddress=[u'00:50:56:30:F6:5F'], - issuer=fuzzy_issuer, - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Add another MAC address to %r' % fqdn1, - command=('host_mod', [fqdn1], dict(macaddress=[u'00:50:56:30:F6:5F', u'00:50:56:2C:8D:82'])), - expected=dict( - value=fqdn1, - summary=u'Modified host "%s"' % fqdn1, - result=dict( - description=[u'Updated host 1'], - fqdn=[fqdn1], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - macaddress=[u'00:50:56:30:F6:5F', u'00:50:56:2C:8D:82'], - issuer=fuzzy_issuer, - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Add an illegal MAC address to %r' % fqdn1, - command=('host_mod', [fqdn1], dict(macaddress=[u'xx'])), - expected=errors.ValidationError(name='macaddress', - error=u'Must be of the form HH:HH:HH:HH:HH:HH, where ' + - u'each H is a hexadecimal character.'), - ), - - - dict( - desc='Add SSH public key to %r' % fqdn1, - command=('host_mod', [fqdn1], dict(ipasshpubkey=[sshpubkey])), - expected=dict( - value=fqdn1, - summary=u'Modified host "%s"' % fqdn1, - result=dict( - description=[u'Updated host 1'], - fqdn=[fqdn1], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - macaddress=[u'00:50:56:30:F6:5F', u'00:50:56:2C:8D:82'], - ipasshpubkey=[sshpubkey], - sshpubkeyfp=[sshpubkeyfp], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Add an illegal SSH public key to %r' % fqdn1, - command=('host_mod', [fqdn1], dict(ipasshpubkey=[u'no-pty %s' % sshpubkey])), - expected=errors.ValidationError(name='sshpubkey', - error=u'options are not allowed'), - ), - - - dict( - desc='Delete %r' % fqdn1, - command=('host_del', [fqdn1], {}), - expected=dict( - value=fqdn1, - summary=u'Deleted host "%s"' % fqdn1, - result=dict(failed=u''), - ), - ), - - - dict( - desc='Try to retrieve non-existent %r' % fqdn1, - command=('host_show', [fqdn1], {}), - expected=errors.NotFound(reason=u'%s: host not found' % fqdn1), - ), - - - dict( - desc='Try to update non-existent %r' % fqdn1, - command=('host_mod', [fqdn1], dict(description=u'Nope')), - expected=errors.NotFound(reason=u'%s: host not found' % fqdn1), - ), - - - dict( - desc='Try to delete non-existent %r' % fqdn1, - command=('host_del', [fqdn1], {}), - expected=errors.NotFound(reason=u'%s: host not found' % fqdn1), - ), - - # Test deletion using a non-fully-qualified hostname. Services - # associated with this host should also be removed. - dict( - desc='Re-create %r' % fqdn1, - command=('host_add', [fqdn1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn1, - summary=u'Added host "%s"' % fqdn1, - result=dict( - dn=dn1, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[u'%s' % fqdn1], - has_keytab=False, - has_password=False, - ), - ), - ), - - dict( - desc='Add a service to host %r' % fqdn1, - command=('service_add', [service1], {'force': True}), - expected=dict( - value=service1, - summary=u'Added service "%s"' % service1, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - objectclass=objectclasses.service, - managedby_host=[fqdn1], - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - dict( - desc='Delete using host name %r' % short1, - command=('host_del', [short1], {}), - expected=dict( - value=short1, - summary=u'Deleted host "%s"' % short1, - result=dict(failed=u''), - ), - ), - - dict( - desc='Search for services for %r' % fqdn1, - command=('service_find', [fqdn1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 services matched', - result=[ - ], - ), - ), - - - dict( - desc='Try to add host not in DNS %r without force' % fqdn2, - command=('host_add', [fqdn2], {}), - expected=errors.DNSNotARecordError( - reason=u'Host does not have corresponding DNS A record'), - ), - - - dict( - desc='Try to add host not in DNS %r with force' % fqdn2, - command=('host_add', [fqdn2], - dict( - description=u'Test host 2', - l=u'Undisclosed location 2', - userclass=[u'webserver', u'mailserver'], - force=True, - ), - ), - expected=dict( - value=fqdn2, - summary=u'Added host "%s"' % fqdn2, - result=dict( - dn=dn2, - fqdn=[fqdn2], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn2, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn2], - userclass=[u'webserver', u'mailserver'], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Retrieve %r' % fqdn2, - command=('host_show', [fqdn2], {}), - expected=dict( - value=fqdn2, - summary=None, - result=dict( - dn=dn2, - fqdn=[fqdn2], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn2, api.env.realm)], - has_keytab=False, - has_password=False, - managedby_host=[fqdn2], - userclass=[u'webserver', u'mailserver'], - ), - ), - ), - - - # This test will only succeed when running against lite-server.py - # on same box as IPA install. - dict( - desc='Delete the current host (master?) %s should be caught' % api.env.host, - command=('host_del', [api.env.host], {}), - expected=errors.ValidationError(name='hostname', - error=u'An IPA master host cannot be deleted or disabled'), - ), - - - dict( - desc='Disable the current host (master?) %s should be caught' % api.env.host, - command=('host_disable', [api.env.host], {}), - expected=errors.ValidationError(name='hostname', - error=u'An IPA master host cannot be deleted or disabled'), - ), - - - dict( - desc='Test that validation is enabled on adds', - command=('host_add', [invalidfqdn1], {}), - expected=errors.ValidationError(name='hostname', - error=u'invalid domain-name: only letters, numbers, and - ' + - u'are allowed. DNS label may not start or end with -'), - ), - - - # The assumption on these next 4 tests is that if we don't get a - # validation error then the request was processed normally. - dict( - desc='Test that validation is disabled on mods', - command=('host_mod', [invalidfqdn1], {}), - expected=errors.NotFound( - reason=u'%s: host not found' % invalidfqdn1), - ), - - - dict( - desc='Test that validation is disabled on deletes', - command=('host_del', [invalidfqdn1], {}), - expected=errors.NotFound( - reason=u'%s: host not found' % invalidfqdn1), - ), - - - dict( - desc='Test that validation is disabled on show', - command=('host_show', [invalidfqdn1], {}), - expected=errors.NotFound( - reason=u'%s: host not found' % invalidfqdn1), - ), - - - dict( - desc='Test that validation is disabled on find', - command=('host_find', [invalidfqdn1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 hosts matched', - result=[], - ), - ), - - - dict( - desc='Add managedby_host %r to %r' % (fqdn3, fqdn4), - command=('host_add_managedby', [fqdn4], dict(host=fqdn3,), - ), - expected=dict( - completed=1, - failed=dict( - managedby = dict( - host=tuple(), - ), - ), - result=dict( - dn=dn4, - fqdn=[fqdn4], - description=[u'Test host 4'], - l=[u'Undisclosed location 4'], - krbprincipalname=[u'host/%s@%s' % (fqdn4, api.env.realm)], - managedby_host=[fqdn4, fqdn3], - ), - ), - ), - - - dict( - desc='Delete %r' % fqdn3, - command=('host_del', [fqdn3], {}), - expected=dict( - value=fqdn3, - summary=u'Deleted host "%s"' % fqdn3, - result=dict(failed=u''), - ), - ), - - - dict( - desc='Retrieve %r to verify that %r is gone from managedBy' % (fqdn4, fqdn3), - command=('host_show', [fqdn4], {}), - expected=dict( - value=fqdn4, - summary=None, - result=dict( - dn=dn4, - fqdn=[fqdn4], - description=[u'Test host 4'], - l=[u'Undisclosed location 4'], - krbprincipalname=[u'host/%s@%s' % (fqdn4, api.env.realm)], - has_keytab=False, - has_password=False, - managedby_host=[fqdn4], - ), - ), - ), - - ] - -class test_host_false_pwd_change(XMLRPC_test): - - fqdn1 = u'testhost1.%s' % api.env.domain - short1 = u'testhost1' - new_pass = u'pass_123' - command = "ipa-client/ipa-join" - - @classmethod - def setUpClass(cls): - [cls.keytabfd,cls.keytabname] = tempfile.mkstemp() - os.close(cls.keytabfd) - - does_command_exist = os.path.isfile(cls.command) - - if not does_command_exist: - raise SkipTest("Command '%s' not found" % cls.command) - - # auxiliary function for checking whether the join operation has set - # correct attributes - def host_joined(self): - ret = api.Command['host_show'](self.fqdn1, all=True) - assert (ret['result']['has_keytab'] == True) - assert (ret['result']['has_password'] == False) - - def test_a_join_host(self): - """ - Create a test host and join him into IPA. - """ - - # create a test host with bulk enrollment password - random_pass = api.Command['host_add'](self.fqdn1, random=True, force=True)['result']['randompassword'] - - # joint the host with the bulk password - new_args = [self.command, - "-s", api.env.host, - "-h", self.fqdn1, - "-k", self.keytabname, - "-w", random_pass, - "-q", - ] - try: - # join operation may fail on 'adding key into keytab', but - # the keytab is not necessary for further tests - (out, err, rc) = ipautil.run(new_args, None) - except ipautil.CalledProcessError, e: - pass - finally: - self.host_joined() - - @raises(errors.ValidationError) - def test_b_try_password(self): - """ - Try to change the password of enrolled host with specified password - """ - api.Command['host_mod'](self.fqdn1, userpassword=self.new_pass) - - @raises(errors.ValidationError) - def test_c_try_random(self): - """ - Try to change the password of enrolled host with random password - """ - api.Command['host_mod'](self.fqdn1, random=True) - - def test_d_cleanup(self): - """ - Clean up test data - """ - os.unlink(self.keytabname) - api.Command['host_del'](self.fqdn1) - # verify that it's gone - with assert_raises(errors.NotFound): - api.Command['host_show'](self.fqdn1) diff --git a/tests/test_xmlrpc/test_hostgroup_plugin.py b/tests/test_xmlrpc/test_hostgroup_plugin.py deleted file mode 100644 index 36c497ba8..000000000 --- a/tests/test_xmlrpc/test_hostgroup_plugin.py +++ /dev/null @@ -1,313 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2008, 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib.plugins.hostgroup` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid -from tests.test_xmlrpc import objectclasses -from ipapython.dn import DN - -hostgroup1 = u'testhostgroup1' -dn1 = DN(('cn',hostgroup1),('cn','hostgroups'),('cn','accounts'), - api.env.basedn) - -hostgroup_single = u'a' -dn_single = DN(('cn',hostgroup_single),('cn','hostgroups'),('cn','accounts'), - api.env.basedn) - -fqdn1 = u'testhost1.%s' % api.env.domain -host_dn1 = DN(('fqdn',fqdn1),('cn','computers'),('cn','accounts'), - api.env.basedn) - -invalidhostgroup1 = u'@invalid' - - -class test_hostgroup(Declarative): - - cleanup_commands = [ - ('hostgroup_del', [hostgroup1], {}), - ('host_del', [fqdn1], {}), - ] - - tests=[ - - dict( - desc='Try to retrieve non-existent %r' % hostgroup1, - command=('hostgroup_show', [hostgroup1], {}), - expected=errors.NotFound( - reason=u'%s: host group not found' % hostgroup1), - ), - - - dict( - desc='Try to update non-existent %r' % hostgroup1, - command=('hostgroup_mod', [hostgroup1], - dict(description=u'Updated hostgroup 1') - ), - expected=errors.NotFound( - reason=u'%s: host group not found' % hostgroup1), - ), - - - dict( - desc='Try to delete non-existent %r' % hostgroup1, - command=('hostgroup_del', [hostgroup1], {}), - expected=errors.NotFound( - reason=u'%s: host group not found' % hostgroup1), - ), - - - dict( - desc='Test an invalid hostgroup name %r' % invalidhostgroup1, - command=('hostgroup_add', [invalidhostgroup1], dict(description=u'Test')), - expected=errors.ValidationError(name='hostgroup_name', - error=u'may only include letters, numbers, _, -, and .'), - ), - - - dict( - desc='Create %r' % hostgroup1, - command=('hostgroup_add', [hostgroup1], - dict(description=u'Test hostgroup 1') - ), - expected=dict( - value=hostgroup1, - summary=u'Added hostgroup "testhostgroup1"', - result=dict( - dn=dn1, - cn=[hostgroup1], - objectclass=objectclasses.hostgroup, - description=[u'Test hostgroup 1'], - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn',hostgroup1),('cn','ng'),('cn','alt'), - api.env.basedn)], - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % hostgroup1, - command=('hostgroup_add', [hostgroup1], - dict(description=u'Test hostgroup 1') - ), - expected=errors.DuplicateEntry(message= - u'host group with name "%s" already exists' % hostgroup1), - ), - - - dict( - desc='Create host %r' % fqdn1, - command=('host_add', [fqdn1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn1, - summary=u'Added host "%s"' % fqdn1, - result=dict( - dn=host_dn1, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn1], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc=u'Add host %r to %r' % (fqdn1, hostgroup1), - command=( - 'hostgroup_add_member', [hostgroup1], dict(host=fqdn1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - host=tuple(), - hostgroup=tuple(), - ), - ), - result={ - 'dn': dn1, - 'cn': [hostgroup1], - 'description': [u'Test hostgroup 1'], - 'member_host': [fqdn1], - }, - ), - ), - - - dict( - desc='Retrieve %r' % hostgroup1, - command=('hostgroup_show', [hostgroup1], {}), - expected=dict( - value=hostgroup1, - summary=None, - result={ - 'dn': dn1, - 'member_host': [u'testhost1.%s' % api.env.domain], - 'cn': [hostgroup1], - 'description': [u'Test hostgroup 1'], - }, - ), - ), - - - dict( - desc='Search for %r' % hostgroup1, - command=('hostgroup_find', [], dict(cn=hostgroup1)), - expected=dict( - count=1, - truncated=False, - summary=u'1 hostgroup matched', - result=[ - { - 'dn': dn1, - 'member_host': [u'testhost1.%s' % api.env.domain], - 'cn': [hostgroup1], - 'description': [u'Test hostgroup 1'], - }, - ], - ), - ), - - - dict( - desc='Update %r' % hostgroup1, - command=('hostgroup_mod', [hostgroup1], - dict(description=u'Updated hostgroup 1') - ), - expected=dict( - value=hostgroup1, - summary=u'Modified hostgroup "testhostgroup1"', - result=dict( - cn=[hostgroup1], - description=[u'Updated hostgroup 1'], - member_host=[u'testhost1.%s' % api.env.domain], - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % hostgroup1, - command=('hostgroup_show', [hostgroup1], {}), - expected=dict( - value=hostgroup1, - summary=None, - result={ - 'dn': dn1, - 'member_host': [u'testhost1.%s' % api.env.domain], - 'cn': [hostgroup1], - 'description': [u'Updated hostgroup 1'], - }, - ), - ), - - - dict( - desc='Remove host %r from %r' % (fqdn1, hostgroup1), - command=('hostgroup_remove_member', [hostgroup1], - dict(host=fqdn1) - ), - expected=dict( - failed=dict( - member=dict( - host=tuple(), - hostgroup=tuple(), - ), - ), - completed=1, - result={ - 'dn': dn1, - 'cn': [hostgroup1], - 'description': [u'Updated hostgroup 1'], - }, - ), - ), - - - dict( - desc='Delete %r' % hostgroup1, - command=('hostgroup_del', [hostgroup1], {}), - expected=dict( - value=hostgroup1, - summary=u'Deleted hostgroup "testhostgroup1"', - result=dict(failed=u''), - ), - ), - - - dict( - desc='Create hostgroup with name containing only one letter: %r' % hostgroup_single, - command=('hostgroup_add', [hostgroup_single], - dict(description=u'Test hostgroup with single letter in name') - ), - expected=dict( - value=hostgroup_single, - summary=u'Added hostgroup "a"', - result=dict( - dn=dn_single, - cn=[hostgroup_single], - objectclass=objectclasses.hostgroup, - description=[u'Test hostgroup with single letter in name'], - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn',hostgroup_single),('cn','ng'),('cn','alt'), - api.env.basedn)], - ), - ), - ), - - - dict( - desc='Delete %r' % hostgroup_single, - command=('hostgroup_del', [hostgroup_single], {}), - expected=dict( - value=hostgroup_single, - summary=u'Deleted hostgroup "a"', - result=dict(failed=u''), - ), - ), - - - dict( - desc='Delete host %r' % fqdn1, - command=('host_del', [fqdn1], {}), - expected=dict( - value=fqdn1, - summary=u'Deleted host "%s"' % fqdn1, - result=dict(failed=u''), - ), - ) - - ] diff --git a/tests/test_xmlrpc/test_krbtpolicy.py b/tests/test_xmlrpc/test_krbtpolicy.py deleted file mode 100644 index c61e754d2..000000000 --- a/tests/test_xmlrpc/test_krbtpolicy.py +++ /dev/null @@ -1,150 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test kerberos ticket policy -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -user1 = u'tuser1' - -class test_krbtpolicy(Declarative): - cleanup_commands = [ - ('user_del', [user1], {}), - ('krbtpolicy_reset', [], {}), - ] - - tests = [ - - - dict( - desc='Reset global policy', - command=( - 'krbtpolicy_reset', [], {} - ), - expected=dict( - value=u'', - summary=None, - result=dict( - krbmaxticketlife=[u'86400'], - krbmaxrenewableage=[u'604800'], - ), - ), - ), - - - dict( - desc='Show global policy', - command=( - 'krbtpolicy_show', [], {} - ), - expected=dict( - value=u'', - summary=None, - result=dict( - dn=DN(('cn',api.env.domain),('cn','kerberos'), - api.env.basedn), - krbmaxticketlife=[u'86400'], - krbmaxrenewableage=[u'604800'], - ), - ), - ), - - - dict( - desc='Update global policy', - command=( - 'krbtpolicy_mod', [], dict(krbmaxticketlife=3600) - ), - expected=dict( - value=u'', - summary=None, - result=dict( - krbmaxticketlife=[u'3600'], - krbmaxrenewableage=[u'604800'], - ), - ), - ), - - - dict( - desc='Create %r' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user1),('cn','users'),('cn','accounts'), api.env.basedn) - ), - ), - ), - - - dict( - desc='Update user ticket policy', - command=( - 'krbtpolicy_mod', [user1], dict(krbmaxticketlife=3600) - ), - expected=dict( - value=user1, - summary=None, - result=dict( - krbmaxticketlife=[u'3600'], - ), - ), - ), - - - dict( - desc='Try updating other user attribute', - command=( - 'krbtpolicy_mod', [user1], dict(setattr=u'givenname=Pete') - ), - expected=errors.ObjectclassViolation(info='attribute "givenname" not allowed'), - ), - - - ] diff --git a/tests/test_xmlrpc/test_nesting.py b/tests/test_xmlrpc/test_nesting.py deleted file mode 100644 index e1b41b284..000000000 --- a/tests/test_xmlrpc/test_nesting.py +++ /dev/null @@ -1,797 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test group nexting an indirect members -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -group1 = u'testgroup1' -group2 = u'testgroup2' -group3 = u'testgroup3' -group4 = u'testgroup4' -user1 = u'tuser1' -user2 = u'tuser2' -user3 = u'tuser3' -user4 = u'tuser4' - -hostgroup1 = u'testhostgroup1' -hgdn1 = DN(('cn',hostgroup1),('cn','hostgroups'),('cn','accounts'), - api.env.basedn) -hostgroup2 = u'testhostgroup2' -hgdn2 = DN(('cn',hostgroup2),('cn','hostgroups'),('cn','accounts'), - api.env.basedn) - -fqdn1 = u'testhost1.%s' % api.env.domain -host_dn1 = DN(('fqdn',fqdn1),('cn','computers'),('cn','accounts'), - api.env.basedn) - - -class test_nesting(Declarative): - cleanup_commands = [ - ('group_del', [group1], {}), - ('group_del', [group2], {}), - ('group_del', [group3], {}), - ('group_del', [group4], {}), - ('user_del', [user1], {}), - ('user_del', [user2], {}), - ('user_del', [user3], {}), - ('user_del', [user4], {}), - ('host_del', [fqdn1], {}), - ('hostgroup_del', [hostgroup1], {}), - ('hostgroup_del', [hostgroup2], {}), - ] - - tests = [ - - ################ - # create group1: - - dict( - desc='Create %r' % group1, - command=( - 'group_add', [group1], dict(description=u'Test desc 1') - ), - expected=dict( - value=group1, - summary=u'Added group "testgroup1"', - result=dict( - cn=[group1], - description=[u'Test desc 1'], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - gidnumber=[fuzzy_digits], - dn=DN(('cn','testgroup1'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - ################ - # create group2: - dict( - desc='Create %r' % group2, - command=( - 'group_add', [group2], dict(description=u'Test desc 2') - ), - expected=dict( - value=group2, - summary=u'Added group "testgroup2"', - result=dict( - cn=[group2], - description=[u'Test desc 2'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn','testgroup2'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % group3, - command=( - 'group_add', [group3], dict(description=u'Test desc 3') - ), - expected=dict( - value=group3, - summary=u'Added group "testgroup3"', - result=dict( - cn=[group3], - description=[u'Test desc 3'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn','testgroup3'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % group4, - command=( - 'group_add', [group4], dict(description=u'Test desc 4') - ), - expected=dict( - value=group4, - summary=u'Added group "testgroup4"', - result=dict( - cn=[group4], - description=[u'Test desc 4'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn','testgroup4'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user1),('cn','users'),('cn','accounts'), - api.env.basedn) - ), - ), - ), - - - dict( - desc='Create %r' % user2, - command=( - 'user_add', [user2], dict(givenname=u'Test', sn=u'User2') - ), - expected=dict( - value=user2, - summary=u'Added user "%s"' % user2, - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user2, api.env.domain)], - displayname=[u'Test User2'], - cn=[u'Test User2'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user2),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user2),('cn','users'),('cn','accounts'), - api.env.basedn) - ), - ), - ), - - - dict( - desc='Create %r' % user3, - command=( - 'user_add', [user3], dict(givenname=u'Test', sn=u'User3') - ), - expected=dict( - value=user3, - summary=u'Added user "%s"' % user3, - result=dict( - gecos=[u'Test User3'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser3'], - krbprincipalname=[u'tuser3@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User3'], - uid=[user3], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user3, api.env.domain)], - displayname=[u'Test User3'], - cn=[u'Test User3'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user3),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user3),('cn','users'),('cn','accounts'), - api.env.basedn) - ), - ), - ), - - - dict( - desc='Create %r' % user4, - command=( - 'user_add', [user4], dict(givenname=u'Test', sn=u'User4') - ), - expected=dict( - value=user4, - summary=u'Added user "%s"' % user4, - result=dict( - gecos=[u'Test User4'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser4'], - krbprincipalname=[u'tuser4@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User4'], - uid=[user4], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user4, api.env.domain)], - displayname=[u'Test User4'], - cn=[u'Test User4'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user4),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user4),('cn','users'),('cn','accounts'), - api.env.basedn) - ), - ), - ), - - - ############### - # member stuff - # - # Create 4 groups and 4 users and set the following membership: - # - # g1: - # no direct memberships - # - # g2: - # memberof: g1 - # member: user1, user2 - # - # g3: - # memberof: g1 - # member: user3, g4 - # - # g4: - # memberof: g3 - # member: user1, user4 - # - # So when we do a show it looks like: - # - # g1: - # member groups: g2, g3 - # indirect member group: g4 - # indirect member users: user1, user2, tuser3, tuser4 - # - # g2: - # member of group: g1 - # member users: tuser1, tuser2 - # - # g3: - # member users: tuser3 - # member groups: g4 - # member of groups: g1 - # indirect member users: tuser4 - # - # g4: - # member users: tuser1, tuser4 - # member of groups: g3 - # indirect member of groups: g1 - # - # Note that tuser1 is an indirect member of g1 both through - # g2 and g4. It should appear just once in the list. - - dict( - desc='Add a group member %r to %r' % (group2, group1), - command=( - 'group_add_member', [group1], dict(group=group2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group1),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_group': (group2,), - 'gidnumber': [fuzzy_digits], - 'cn': [group1], - 'description': [u'Test desc 1'], - }, - ), - ), - - - dict( - desc='Add a group member %r to %r' % (group3, group1), - command=( - 'group_add_member', [group1], dict(group=group3) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group1),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_group': [group2, group3,], - 'gidnumber': [fuzzy_digits], - 'cn': [group1], - 'description': [u'Test desc 1'], - }, - ), - ), - - - dict( - desc='Add a user member %r to %r' % (user1, group2), - command=( - 'group_add_member', [group2], dict(user=user1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group2),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_user': (u'tuser1',), - 'memberof_group': (u'testgroup1',), - 'gidnumber': [fuzzy_digits], - 'cn': [group2], - 'description': [u'Test desc 2'], - }, - ), - ), - - - dict( - desc='Add a user member %r to %r' % (user2, group2), - command=( - 'group_add_member', [group2], dict(user=user2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group2),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_user': [user1, user2], - 'memberof_group': [group1], - 'gidnumber': [fuzzy_digits], - 'cn': [group2], - 'description': [u'Test desc 2'], - }, - ), - ), - - - dict( - desc='Add a user member %r to %r' % (user3, group3), - command=( - 'group_add_member', [group3], dict(user=user3) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group3),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_user': [user3], - 'memberof_group': [group1], - 'gidnumber': [fuzzy_digits], - 'cn': [group3], - 'description': [u'Test desc 3'], - }, - ), - ), - - - dict( - desc='Add a group member %r to %r' % (group4, group3), - command=( - 'group_add_member', [group3], dict(group=group4) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group3),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_user': [user3], - 'memberof_group': [group1], - 'member_group': [group4], - 'gidnumber': [fuzzy_digits], - 'cn': [group3], - 'description': [u'Test desc 3'], - }, - ), - ), - - - dict( - desc='Add a user member %r to %r' % (user1, group4), - command=( - 'group_add_member', [group4], dict(user=user1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group4),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_user': [user1], - 'memberof_group': [group3], - 'memberofindirect_group': [group1], - 'gidnumber': [fuzzy_digits], - 'cn': [group4], - 'description': [u'Test desc 4'], - }, - ), - ), - - - dict( - desc='Add a user member %r to %r' % (user4, group4), - command=( - 'group_add_member', [group4], dict(user=user4) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group4),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_user': [user1, user4], - 'memberof_group': [group3], - 'memberofindirect_group': [group1], - 'gidnumber': [fuzzy_digits], - 'cn': [group4], - 'description': [u'Test desc 4'], - }, - ), - ), - - - dict( - desc='Retrieve group %r' % group1, - command=('group_show', [group1], {}), - expected=dict( - value=group1, - summary=None, - result=dict( - cn=[group1], - description=[u'Test desc 1'], - gidnumber= [fuzzy_digits], - memberindirect_group = [group4], - member_group = [group2, group3], - memberindirect_user = [user1, user2, user3, user4], - dn=DN(('cn','testgroup1'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Retrieve group %r' % group2, - command=('group_show', [group2], {}), - expected=dict( - value=group2, - summary=None, - result=dict( - cn=[group2], - description=[u'Test desc 2'], - gidnumber= [fuzzy_digits], - memberof_group = [group1], - member_user = [user1, user2], - dn=DN(('cn','testgroup2'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Retrieve group %r' % group3, - command=('group_show', [group3], {}), - expected=dict( - value=group3, - summary=None, - result=dict( - cn=[group3], - description=[u'Test desc 3'], - gidnumber= [fuzzy_digits], - memberof_group = [group1], - member_user = [user3], - member_group = [group4], - memberindirect_user = [user1, user4], - dn=DN(('cn','testgroup3'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Retrieve group %r' % group4, - command=('group_show', [group4], {}), - expected=dict( - value=group4, - summary=None, - result=dict( - cn=[group4], - description=[u'Test desc 4'], - gidnumber= [fuzzy_digits], - memberof_group = [group3], - member_user = [user1, user4], - memberofindirect_group = [group1], - dn=DN(('cn','testgroup4'),('cn','groups'), - ('cn','accounts'),api.env.basedn), - ), - ), - ), - - - # Now do something similar with hosts and hostgroups - dict( - desc='Create host %r' % fqdn1, - command=('host_add', [fqdn1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn1, - summary=u'Added host "%s"' % fqdn1, - result=dict( - dn=host_dn1, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn1], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Create %r' % hostgroup1, - command=('hostgroup_add', [hostgroup1], - dict(description=u'Test hostgroup 1') - ), - expected=dict( - value=hostgroup1, - summary=u'Added hostgroup "testhostgroup1"', - result=dict( - dn=hgdn1, - cn=[hostgroup1], - objectclass=objectclasses.hostgroup, - description=[u'Test hostgroup 1'], - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn',hostgroup1),('cn','ng'),('cn','alt'), - api.env.basedn)], - ), - ), - ), - - - dict( - desc='Create %r' % hostgroup2, - command=('hostgroup_add', [hostgroup2], - dict(description=u'Test hostgroup 2') - ), - expected=dict( - value=hostgroup2, - summary=u'Added hostgroup "testhostgroup2"', - result=dict( - dn=hgdn2, - cn=[hostgroup2], - objectclass=objectclasses.hostgroup, - description=[u'Test hostgroup 2'], - ipauniqueid=[fuzzy_uuid], - mepmanagedentry=[DN(('cn',hostgroup2),('cn','ng'),('cn','alt'), - api.env.basedn)], - ), - ), - ), - - - dict( - desc=u'Add host %r to %r' % (fqdn1, hostgroup2), - command=( - 'hostgroup_add_member', [hostgroup2], dict(host=fqdn1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - host=tuple(), - hostgroup=tuple(), - ), - ), - result={ - 'dn': hgdn2, - 'cn': [hostgroup2], - 'description': [u'Test hostgroup 2'], - 'member_host': [fqdn1], - }, - ), - ), - - - dict( - desc=u'Add hostgroup %r to %r' % (hostgroup2, hostgroup1), - command=( - 'hostgroup_add_member', [hostgroup1], dict(hostgroup=hostgroup2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - host=tuple(), - hostgroup=tuple(), - ), - ), - result={ - 'dn': hgdn1, - 'cn': [hostgroup1], - 'description': [u'Test hostgroup 1'], - 'member_hostgroup': [hostgroup2], - 'memberindirect_host': [fqdn1], - }, - ), - ), - - - dict( - desc='Retrieve %r' % hostgroup1, - command=('hostgroup_show', [hostgroup1], {}), - expected=dict( - value=hostgroup1, - summary=None, - result={ - 'dn': hgdn1, - 'memberindirect_host': [u'testhost1.%s' % api.env.domain], - 'member_hostgroup': [hostgroup2], - 'cn': [hostgroup1], - 'description': [u'Test hostgroup 1'], - }, - ), - ), - - - dict( - desc='Retrieve %r' % fqdn1, - command=('host_show', [fqdn1], {}), - expected=dict( - value=fqdn1, - summary=None, - result=dict( - dn=host_dn1, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - has_keytab=False, - has_password=False, - managedby_host=[fqdn1], - memberof_hostgroup = [u'testhostgroup2'], - memberofindirect_hostgroup = [u'testhostgroup1'], - ), - ), - ), - - ] diff --git a/tests/test_xmlrpc/test_netgroup_plugin.py b/tests/test_xmlrpc/test_netgroup_plugin.py deleted file mode 100644 index ee826b752..000000000 --- a/tests/test_xmlrpc/test_netgroup_plugin.py +++ /dev/null @@ -1,1361 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/netgroup.py` module. -""" - -import nose -import krbV -from ipalib import api -from ipalib import errors -from ipaserver.plugins.ldap2 import ldap2 -from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid, fuzzy_netgroupdn -from tests.test_xmlrpc import objectclasses -from ipapython.dn import DN - -# Global so we can save the value between tests -netgroup_dn = None - -# See if our LDAP server is up and we can talk to it over GSSAPI -ccache = krbV.default_context().default_ccache().name - -netgroup1 = u'netgroup1' -netgroup2 = u'netgroup2' -netgroup_single = u'a' - -host1 = u'ipatesthost.%s' % api.env.domain -host_dn1 = DN(('fqdn',host1),('cn','computers'),('cn','accounts'), - api.env.basedn) - -unknown_host = u'unknown' - -unknown_host2 = u'unknown2' - -hostgroup1 = u'hg1' -hostgroup_dn1 = DN(('cn',hostgroup1),('cn','hostgroups'),('cn','accounts'), - api.env.basedn) - -user1 = u'jexample' - -# user2 is a member of testgroup -user2 = u'pexample' - -group1 = u'testgroup' - -invalidnetgroup1=u'+badnetgroup' -invalidnisdomain1=u'domain1,domain2' -invalidnisdomain2=u'+invalidnisdomain' -invalidhost=u'+invalid&host' - -class test_netgroup(Declarative): - """ - Test the `netgroup` plugin. - """ - - cleanup_commands = [ - ('netgroup_del', [netgroup1], {}), - ('netgroup_del', [netgroup2], {}), - ('host_del', [host1], {}), - ('hostgroup_del', [hostgroup1], {}), - ('user_del', [user1], {}), - ('user_del', [user2], {}), - ('group_del', [group1], {}), - ] - - tests=[ - - dict( - desc='Try to retrieve non-existent %r' % netgroup1, - command=('netgroup_show', [netgroup1], {}), - expected=errors.NotFound( - reason=u'%s: netgroup not found' % netgroup1), - ), - - - dict( - desc='Try to update non-existent %r' % netgroup1, - command=('netgroup_mod', [netgroup1], - dict(description=u'Updated hostgroup 1') - ), - expected=errors.NotFound( - reason=u'%s: netgroup not found' % netgroup1), - ), - - - dict( - desc='Try to delete non-existent %r' % netgroup1, - command=('netgroup_del', [netgroup1], {}), - expected=errors.NotFound( - reason=u'%s: netgroup not found' % netgroup1), - ), - - - dict( - desc='Test an invalid netgroup name %r' % invalidnetgroup1, - command=('netgroup_add', [invalidnetgroup1], dict(description=u'Test')), - expected=errors.ValidationError(name='name', - error=u'may only include letters, numbers, _, -, and .'), - ), - - - dict( - desc='Test an invalid nisdomain1 name %r' % invalidnisdomain1, - command=('netgroup_add', [netgroup1], - dict(description=u'Test',nisdomainname=invalidnisdomain1)), - expected=errors.ValidationError(name='nisdomain', - error='may only include letters, numbers, _, -, and .'), - ), - - - dict( - desc='Test an invalid nisdomain2 name %r' % invalidnisdomain2, - command=('netgroup_add', [netgroup1], - dict(description=u'Test',nisdomainname=invalidnisdomain2)), - expected=errors.ValidationError(name='nisdomain', - error='may only include letters, numbers, _, -, and .'), - ), - - - dict( - desc='Create %r' % netgroup1, - command=('netgroup_add', [netgroup1], - dict(description=u'Test netgroup 1') - ), - expected=dict( - value=netgroup1, - summary=u'Added netgroup "%s"' % netgroup1, - result=dict( - dn=fuzzy_netgroupdn, - cn=[netgroup1], - objectclass=objectclasses.netgroup, - description=[u'Test netgroup 1'], - nisdomainname=['%s' % api.env.domain], - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Create %r' % netgroup2, - command=('netgroup_add', [netgroup2], - dict(description=u'Test netgroup 2') - ), - expected=dict( - value=netgroup2, - summary=u'Added netgroup "%s"' % netgroup2, - result=dict( - dn=fuzzy_netgroupdn, - cn=[netgroup2], - objectclass=objectclasses.netgroup, - description=[u'Test netgroup 2'], - nisdomainname=['%s' % api.env.domain], - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Create netgroup with name containing only one letter: %r' % netgroup_single, - command=('netgroup_add', [netgroup_single], - dict(description=u'Test netgroup_single') - ), - expected=dict( - value=netgroup_single, - summary=u'Added netgroup "%s"' % netgroup_single, - result=dict( - dn=fuzzy_netgroupdn, - cn=[netgroup_single], - objectclass=objectclasses.netgroup, - description=[u'Test netgroup_single'], - nisdomainname=['%s' % api.env.domain], - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Delete %r' % netgroup_single, - command=('netgroup_del', [netgroup_single], {}), - expected=dict( - value=netgroup_single, - summary=u'Deleted netgroup "%s"' % netgroup_single, - result=dict(failed=u''), - ), - ), - - - dict( - desc='Try to create duplicate %r' % netgroup1, - command=('netgroup_add', [netgroup1], - dict(description=u'Test netgroup 1') - ), - expected=errors.DuplicateEntry( - message=u'netgroup with name "%s" already exists' % netgroup1), - ), - - - dict( - desc='Create host %r' % host1, - command=('host_add', [host1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=host1, - summary=u'Added host "%s"' % host1, - result=dict( - dn=host_dn1, - fqdn=[host1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (host1, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[host1], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Create %r' % hostgroup1, - command=('hostgroup_add', [hostgroup1], - dict(description=u'Test hostgroup 1') - ), - expected=dict( - value=hostgroup1, - summary=u'Added hostgroup "%s"' % hostgroup1, - result=dict( - dn=hostgroup_dn1, - cn=[hostgroup1], - objectclass=objectclasses.hostgroup, - description=[u'Test hostgroup 1'], - mepmanagedentry=[DN(('cn',hostgroup1),('cn','ng'),('cn','alt'), - api.env.basedn)], - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Create %r' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/%s' % user1], - krbprincipalname=[u'%s@%s' % (user1, api.env.realm)], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user1),('cn','users'),('cn','accounts'), - api.env.basedn), - ), - ), - ), - - dict( - desc='Create %r' % user2, - command=( - 'user_add', [user2], dict(givenname=u'Test', sn=u'User2') - ), - expected=dict( - value=user2, - summary=u'Added user "%s"' % user2, - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - homedirectory=[u'/home/%s' % user2], - krbprincipalname=[u'%s@%s' % (user2, api.env.realm)], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user2, api.env.domain)], - displayname=[u'Test User2'], - cn=[u'Test User2'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user2),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user2),('cn','users'),('cn','accounts'), - api.env.basedn), - ), - ), - ), - - - dict( - desc='Create %r' % group1, - command=( - 'group_add', [group1], dict(description=u'Test desc 1') - ), - expected=dict( - value=group1, - summary=u'Added group "%s"' % group1, - result=dict( - cn=[group1], - description=[u'Test desc 1'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn',group1),('cn','groups'),('cn','accounts'), - api.env.basedn), - ), - ), - ), - - - dict( - desc='Add user %r to group %r' % (user2, group1), - command=( - 'group_add_member', [group1], dict(user=user2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn',group1),('cn','groups'),('cn','accounts'), - api.env.basedn), - 'member_user': (user2,), - 'gidnumber': [fuzzy_digits], - 'cn': [group1], - 'description': [u'Test desc 1'], - }, - ), - ), - - - dict( - desc='Add invalid host %r to netgroup %r' % (invalidhost, netgroup1), - command=('netgroup_add_member', [netgroup1], dict(host=invalidhost)), - expected=errors.ValidationError(name='host', - error='only letters, numbers, _, and - are allowed. ' + - u'DNS label may not start or end with -'), - ), - - - dict( - desc='Add host %r to netgroup %r' % (host1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(host=host1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Add hostgroup %r to netgroup %r' % (hostgroup1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(hostgroup=hostgroup1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Search for netgroups using no_user', - command=('netgroup_find', [], dict(no_user=user1)), - expected=dict( - count=2, - truncated=False, - summary=u'2 netgroups matched', - result=[ - { - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - { - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup2], - 'description': [u'Test netgroup 2'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ], - ), - ), - - dict( - desc="Check %r doesn't match when searching for %s" % (netgroup1, user1), - command=('netgroup_find', [], dict(user=user1)), - expected=dict( - count=0, - truncated=False, - summary=u'0 netgroups matched', - result=[], - ), - ), - - dict( - desc='Add user %r to netgroup %r' % (user1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(user=user1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - dict( - desc="Check %r doesn't match when searching for no %s" % (netgroup1, user1), - command=('netgroup_find', [], dict(no_user=user1)), - expected=dict( - count=1, - truncated=False, - summary=u'1 netgroup matched', - result=[ - { - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup2], - 'description': [u'Test netgroup 2'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ], - ), - ), - - dict( - desc='Add group %r to netgroup %r' % (group1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(group=group1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Add netgroup %r to netgroup %r' % (netgroup2, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(netgroup=netgroup2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Add non-existent netgroup to netgroup %r' % (netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(netgroup=u'notfound') - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=[(u'notfound', u'no such entry')], - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Add duplicate user %r to netgroup %r' % (user1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(user=user1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=[('%s' % user1, u'This entry is already a member')], - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - dict( - desc='Add duplicate group %r to netgroup %r' % (group1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(group=group1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=[('%s' % group1, u'This entry is already a member')], - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Add duplicate host %r to netgroup %r' % (host1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(host=host1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=[('%s' % host1, u'This entry is already a member')], - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Add duplicate hostgroup %r to netgroup %r' % (hostgroup1, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(hostgroup=hostgroup1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=[('%s' % hostgroup1, u'This entry is already a member')], - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ), - ), - - - dict( - desc='Add unknown host %r to netgroup %r' % (unknown_host, netgroup1), - command=( - 'netgroup_add_member', [netgroup1], dict(host=unknown_host) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - dict( - desc='Add invalid host %r to netgroup %r using setattr' % - (invalidhost, netgroup1), - command=( - 'netgroup_mod', [netgroup1], - dict(setattr='externalhost=%s' % invalidhost) - ), - expected=errors.ValidationError(name='externalhost', - error='only letters, numbers, _, and - are allowed. ' + - 'DNS label may not start or end with -'), - ), - - dict( - desc='Add unknown host %r to netgroup %r using addattr' % - (unknown_host2, netgroup1), - command=( - 'netgroup_mod', [netgroup1], - dict(addattr='externalhost=%s' % unknown_host2) - ), - expected=dict( - value=u'netgroup1', - summary=u'Modified netgroup "netgroup1"', - result={ - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host, unknown_host2], - }, - ) - ), - - dict( - desc='Remove unknown host %r from netgroup %r using delattr' % - (unknown_host2, netgroup1), - command=( - 'netgroup_mod', [netgroup1], - dict(delattr='externalhost=%s' % unknown_host2) - ), - expected=dict( - value=u'netgroup1', - summary=u'Modified netgroup "netgroup1"', - result={ - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ) - ), - - dict( - desc='Retrieve %r' % netgroup1, - command=('netgroup_show', [netgroup1], {}), - expected=dict( - value=netgroup1, - summary=None, - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - dict( - desc='Search for %r' % netgroup1, - command=('netgroup_find', [], dict(cn=netgroup1)), - expected=dict( - count=1, - truncated=False, - summary=u'1 netgroup matched', - result=[ - { - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ], - ), - ), - - dict( - desc='Search for %r using user' % netgroup1, - command=('netgroup_find', [], dict(user=user1)), - expected=dict( - count=1, - truncated=False, - summary=u'1 netgroup matched', - result=[ - { - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ], - ), - ), - - dict( - desc='Search for all netgroups using empty member user', - command=('netgroup_find', [], dict(user=None)), - expected=dict( - count=2, - truncated=False, - summary=u'2 netgroups matched', - result=[ - { - 'dn': fuzzy_netgroupdn, - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Test netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - { - 'dn': fuzzy_netgroupdn, - 'memberof_netgroup': (netgroup1,), - 'cn': [netgroup2], - 'description': [u'Test netgroup 2'], - 'nisdomainname': [u'%s' % api.env.domain], - }, - ], - ), - ), - - dict( - desc='Update %r' % netgroup1, - command=('netgroup_mod', [netgroup1], - dict(description=u'Updated netgroup 1') - ), - expected=dict( - value=netgroup1, - summary=u'Modified netgroup "%s"' % netgroup1, - result={ - 'memberhost_host': (host1,), - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove host %r from netgroup %r' % (host1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(host=host1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberhost_hostgroup': (hostgroup1,), - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove hostgroup %r from netgroup %r' % (hostgroup1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(hostgroup=hostgroup1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberuser_user': (user1,), - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove user %r from netgroup %r' % (user1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(user=user1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'memberuser_group': (group1,), - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove group %r from netgroup %r' % (group1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(group=group1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'member_netgroup': (netgroup2,), - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove netgroup %r from netgroup %r' % (netgroup2, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(netgroup=netgroup2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove host %r from netgroup %r again' % (host1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(host=host1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=[('%s' % host1, u'This entry is not a member')] - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove hostgroup %r from netgroup %r again' % (hostgroup1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(hostgroup=hostgroup1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=[('%s' % hostgroup1, u'This entry is not a member')], - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove user %r from netgroup %r again' % (user1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(user=user1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group=tuple(), - user=[('%s' % user1, u'This entry is not a member')], - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove group %r from netgroup %r again' % (group1, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(group=group1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=tuple(), - ), - memberuser=dict( - group= [('%s' % group1, u'This entry is not a member')], - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Remove netgroup %r from netgroup %r again' % (netgroup2, netgroup1), - command=( - 'netgroup_remove_member', [netgroup1], dict(netgroup=netgroup2) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - netgroup=[('%s' % netgroup2, u'This entry is not a member')], - ), - memberuser=dict( - group=tuple(), - user=tuple(), - ), - memberhost=dict( - hostgroup=tuple(), - host=tuple(), - ), - ), - result={ - 'dn': fuzzy_netgroupdn, - 'cn': [netgroup1], - 'description': [u'Updated netgroup 1'], - 'nisdomainname': [u'%s' % api.env.domain], - 'externalhost': [unknown_host], - }, - ), - ), - - - dict( - desc='Delete %r' % netgroup1, - command=('netgroup_del', [netgroup1], {}), - expected=dict( - value=netgroup1, - summary=u'Deleted netgroup "%s"' % netgroup1, - result=dict(failed=u''), - ), - ), - - ] - -# No way to convert this test just yet. - -# def test_6b_netgroup_show(self): -# """ -# Confirm the underlying triples -# """ -# # Do an LDAP query to the compat area and verify that the entry -# # is correct -# conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri, base_dn=api.env.basedn) -# conn.connect(ccache=ccache) -# try: -# entries = conn.find_entries('cn=%s' % self.ng_cn, -# base_dn='cn=ng,cn=compat,%s' % api.env.basedn) -# except errors.NotFound: -# raise nose.SkipTest('compat and nis are not enabled, skipping test') -# finally: -# conn.disconnect() -# triples = entries[0][0][1]['nisnetgrouptriple'] -# -# # This may not prove to be reliable since order is not guaranteed -# # and even which user gets into which triple can be random. -# assert '(nosuchhost,jexample,example.com)' in triples -# assert '(ipatesthost.%s,pexample,example.com)' % api.env.domain in triples diff --git a/tests/test_xmlrpc/test_passwd_plugin.py b/tests/test_xmlrpc/test_passwd_plugin.py deleted file mode 100644 index 2a44da711..000000000 --- a/tests/test_xmlrpc/test_passwd_plugin.py +++ /dev/null @@ -1,69 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/passwd.py` module. -""" - -import sys - -from nose.tools import assert_raises # pylint: disable=E0611 - -from xmlrpc_test import XMLRPC_test, assert_attr_equal -from ipalib import api -from ipalib import errors - - -class test_passwd(XMLRPC_test): - """ - Test the `passwd` plugin. - """ - uid = u'pwexample' - givenname = u'Jim' - sn = u'Example' - home = u'/home/%s' % uid - principalname = u'%s@%s' % (uid, api.env.realm) - kw = {'givenname': givenname, 'sn': sn, 'uid': uid, 'homedirectory': home} - - def test_1_user_add(self): - """ - Create a test user - """ - entry = api.Command['user_add'](**self.kw)['result'] - assert_attr_equal(entry, 'givenname', self.givenname) - assert_attr_equal(entry, 'sn', self.sn) - assert_attr_equal(entry, 'uid', self.uid) - assert_attr_equal(entry, 'homedirectory', self.home) - assert_attr_equal(entry, 'objectclass', 'ipaobject') - - def test_2_set_passwd(self): - """ - Test the `xmlrpc.passwd` method. - """ - out = api.Command['passwd'](self.uid, password=u'password1') - assert out['result'] is True - - def test_3_user_del(self): - """ - Remove the test user - """ - api.Command['user_del'](self.uid) - - # Verify that it is gone - with assert_raises(errors.NotFound): - api.Command['user_show'](self.uid) diff --git a/tests/test_xmlrpc/test_permission_plugin.py b/tests/test_xmlrpc/test_permission_plugin.py deleted file mode 100644 index 4a81f9746..000000000 --- a/tests/test_xmlrpc/test_permission_plugin.py +++ /dev/null @@ -1,972 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/permission.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -permission1 = u'testperm' -permission1_dn = DN(('cn',permission1), - api.env.container_permission,api.env.basedn) - - -permission1_renamed = u'testperm1_rn' -permission1_renamed_dn = DN(('cn',permission1_renamed), - api.env.container_permission,api.env.basedn) - -permission1_renamed_ucase = u'Testperm_RN' -permission1_renamed_ucase_dn = DN(('cn',permission1_renamed_ucase), - api.env.container_permission,api.env.basedn) - - -permission2 = u'testperm2' -permission2_dn = DN(('cn',permission2), - api.env.container_permission,api.env.basedn) - -permission3 = u'testperm3' -permission3_dn = DN(('cn',permission3), - api.env.container_permission,api.env.basedn) -permission3_attributelevelrights = { - 'member': u'rscwo', - 'seealso': u'rscwo', - 'ipapermissiontype': u'rscwo', - 'cn': u'rscwo', - 'businesscategory': u'rscwo', - 'objectclass': u'rscwo', - 'memberof': u'rscwo', - 'aci': u'rscwo', - 'subtree': u'rscwo', - 'o': u'rscwo', - 'filter': u'rscwo', - 'attrs': u'rscwo', - 'owner': u'rscwo', - 'group': u'rscwo', - 'ou': u'rscwo', - 'targetgroup': u'rscwo', - 'type': u'rscwo', - 'permissions': u'rscwo', - 'nsaccountlock': u'rscwo', - 'description': u'rscwo', - } - -privilege1 = u'testpriv1' -privilege1_dn = DN(('cn',privilege1), - api.env.container_privilege,api.env.basedn) - -invalid_permission1 = u'bad;perm' - - -class test_permission(Declarative): - - cleanup_commands = [ - ('permission_del', [permission1], {}), - ('permission_del', [permission2], {}), - ('permission_del', [permission3], {}), - ('privilege_del', [privilege1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % permission1, - command=('permission_show', [permission1], {}), - expected=errors.NotFound( - reason=u'%s: permission not found' % permission1), - ), - - - dict( - desc='Try to update non-existent %r' % permission1, - command=('permission_mod', [permission1], dict(permissions=u'all')), - expected=errors.NotFound( - reason=u'%s: permission not found' % permission1), - ), - - - dict( - desc='Try to delete non-existent %r' % permission1, - command=('permission_del', [permission1], {}), - expected=errors.NotFound( - reason=u'%s: permission not found' % permission1), - ), - - - dict( - desc='Search for non-existent %r' % permission1, - command=('permission_find', [permission1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 permissions matched', - result=[], - ), - ), - - - dict( - desc='Create %r' % permission1, - command=( - 'permission_add', [permission1], dict( - type=u'user', - permissions=u'write', - ) - ), - expected=dict( - value=permission1, - summary=u'Added permission "%s"' % permission1, - result=dict( - dn=permission1_dn, - cn=[permission1], - objectclass=objectclasses.permission, - type=u'user', - permissions=[u'write'], - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % permission1, - command=( - 'permission_add', [permission1], dict( - type=u'user', - permissions=u'write', - ), - ), - expected=errors.DuplicateEntry(), - ), - - - dict( - desc='Create %r' % privilege1, - command=('privilege_add', [privilege1], - dict(description=u'privilege desc. 1') - ), - expected=dict( - value=privilege1, - summary=u'Added privilege "%s"' % privilege1, - result=dict( - dn=privilege1_dn, - cn=[privilege1], - description=[u'privilege desc. 1'], - objectclass=objectclasses.privilege, - ), - ), - ), - - - dict( - desc='Add permission %r to privilege %r' % (permission1, privilege1), - command=('privilege_add_permission', [privilege1], - dict(permission=permission1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - permission=[], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Retrieve %r' % permission1, - command=('permission_show', [permission1], {}), - expected=dict( - value=permission1, - summary=None, - result={ - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - }, - ), - ), - - - dict( - desc='Retrieve %r with --raw' % permission1, - command=('permission_show', [permission1], {'raw' : True}), - expected=dict( - value=permission1, - summary=None, - result={ - 'dn': permission1_dn, - 'cn': [permission1], - 'member': [privilege1_dn], - 'aci': u'(target = "ldap:///%s")(version 3.0;acl "permission:testperm";allow (write) groupdn = "ldap:///%s";)' % \ - (DN(('uid', '*'), ('cn', 'users'), ('cn', 'accounts'), api.env.basedn), - DN(('cn', 'testperm'), ('cn', 'permissions'), ('cn', 'pbac'), api.env.basedn)) - }, - ), - ), - - - dict( - desc='Search for %r' % permission1, - command=('permission_find', [permission1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 permission matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - }, - ], - ), - ), - - - dict( - desc='Search for %r using --name' % permission1, - command=('permission_find', [], {'cn': permission1}), - expected=dict( - count=1, - truncated=False, - summary=u'1 permission matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - }, - ], - ), - ), - - - dict( - desc='Search for non-existence permission using --name', - command=('permission_find', [], {'cn': u'notfound'}), - expected=dict( - count=0, - truncated=False, - summary=u'0 permissions matched', - result=[], - ), - ), - - - dict( - desc='Search for %r' % privilege1, - command=('permission_find', [privilege1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 permission matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - }, - ], - ), - ), - - - dict( - desc='Search for %r with --raw' % permission1, - command=('permission_find', [permission1], {'raw' : True}), - expected=dict( - count=1, - truncated=False, - summary=u'1 permission matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - 'member': [privilege1_dn], - 'aci': u'(target = "ldap:///%s")(version 3.0;acl "permission:testperm";allow (write) groupdn = "ldap:///%s";)' % \ - (DN(('uid', '*'), ('cn', 'users'), ('cn', 'accounts'), api.env.basedn), - DN(('cn', 'testperm'), ('cn', 'permissions'), ('cn', 'pbac'), api.env.basedn)), - }, - ], - ), - ), - - - dict( - desc='Create %r' % permission2, - command=( - 'permission_add', [permission2], dict( - type=u'user', - permissions=u'write', - setattr=u'owner=cn=test', - addattr=u'owner=cn=test2', - ) - ), - expected=dict( - value=permission2, - summary=u'Added permission "%s"' % permission2, - result=dict( - dn=permission2_dn, - cn=[permission2], - objectclass=objectclasses.permission, - type=u'user', - permissions=[u'write'], - owner=[u'cn=test', u'cn=test2'], - ), - ), - ), - - - dict( - desc='Search for %r' % permission1, - command=('permission_find', [permission1], {}), - expected=dict( - count=2, - truncated=False, - summary=u'2 permissions matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - }, - { - 'dn': permission2_dn, - 'cn': [permission2], - 'type': u'user', - 'permissions': [u'write'], - }, - ], - ), - ), - - - dict( - desc='Search for %r with --pkey-only' % permission1, - command=('permission_find', [permission1], {'pkey_only' : True}), - expected=dict( - count=2, - truncated=False, - summary=u'2 permissions matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - }, - { - 'dn': permission2_dn, - 'cn': [permission2], - }, - ], - ), - ), - - - dict( - desc='Search by ACI attribute with --pkey-only', - command=('permission_find', [], {'pkey_only': True, - 'attrs': [u'krbminpwdlife']}), - expected=dict( - count=1, - truncated=False, - summary=u'1 permission matched', - result=[ - { - 'dn': DN(('cn','Modify Group Password Policy'), - api.env.container_permission, api.env.basedn), - 'cn': [u'Modify Group Password Policy'], - }, - ], - ), - ), - - - dict( - desc='Search for %r' % privilege1, - command=('privilege_find', [privilege1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 privilege matched', - result=[ - { - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1], - }, - ], - ), - ), - - - dict( - desc='Search for %r with a limit of 1 (truncated)' % permission1, - command=('permission_find', [permission1], dict(sizelimit=1)), - expected=dict( - count=1, - truncated=True, - summary=u'1 permission matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - }, - ], - ), - ), - - - dict( - desc='Search for %r with a limit of 2' % permission1, - command=('permission_find', [permission1], dict(sizelimit=2)), - expected=dict( - count=2, - truncated=False, - summary=u'2 permissions matched', - result=[ - { - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - }, - { - 'dn': permission2_dn, - 'cn': [permission2], - 'type': u'user', - 'permissions': [u'write'], - }, - ], - ), - ), - - - # This tests setting truncated to True in the post_callback of - # permission_find(). The return order in LDAP is not guaranteed - # but in practice this is the first entry it finds. This is subject - # to change. - dict( - desc='Search for permissions by attr with a limit of 1 (truncated)', - command=('permission_find', [], dict(attrs=u'ipaenabledflag', - sizelimit=1)), - expected=dict( - count=1, - truncated=True, - summary=u'1 permission matched', - result=[ - { - 'dn': DN(('cn', 'Modify HBAC rule'), - api.env.container_permission, api.env.basedn), - 'cn': [u'Modify HBAC rule'], - 'member_privilege': [u'HBAC Administrator'], - 'memberindirect_role': [u'IT Security Specialist'], - 'permissions' : [u'write'], - 'attrs': [u'servicecategory', u'sourcehostcategory', u'cn', u'description', u'ipaenabledflag', u'accesstime', u'usercategory', u'hostcategory', u'accessruletype', u'sourcehost'], - 'subtree' : u'ldap:///%s' % DN(('ipauniqueid', '*'), ('cn', 'hbac'), api.env.basedn), - }, - ], - ), - ), - - - dict( - desc='Update %r' % permission1, - command=( - 'permission_mod', [permission1], dict( - permissions=u'read', - memberof=u'ipausers', - setattr=u'owner=cn=other-test', - addattr=u'owner=cn=other-test2', - ) - ), - expected=dict( - value=permission1, - summary=u'Modified permission "%s"' % permission1, - result=dict( - dn=permission1_dn, - cn=[permission1], - member_privilege=[privilege1], - type=u'user', - permissions=[u'read'], - memberof=u'ipausers', - owner=[u'cn=other-test', u'cn=other-test2'], - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % permission1, - command=('permission_show', [permission1], {}), - expected=dict( - value=permission1, - summary=None, - result={ - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'read'], - 'memberof': u'ipausers', - }, - ), - ), - - - - dict( - desc='Try to rename %r to existing permission %r' % (permission1, - permission2), - command=( - 'permission_mod', [permission1], dict(rename=permission2, - permissions=u'all',) - ), - expected=errors.DuplicateEntry(), - ), - - - dict( - desc='Try to rename %r to empty name' % (permission1), - command=( - 'permission_mod', [permission1], dict(rename=u'', - permissions=u'all',) - ), - expected=errors.ValidationError(name='rename', - error=u'New name can not be empty'), - ), - - - dict( - desc='Check integrity of original permission %r' % permission1, - command=('permission_show', [permission1], {}), - expected=dict( - value=permission1, - summary=None, - result={ - 'dn': permission1_dn, - 'cn': [permission1], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'read'], - 'memberof': u'ipausers', - }, - ), - ), - - - dict( - desc='Rename %r to permission %r' % (permission1, - permission1_renamed), - command=( - 'permission_mod', [permission1], dict(rename=permission1_renamed, - permissions= u'all',) - ), - expected=dict( - value=permission1, - summary=u'Modified permission "%s"' % permission1, - result={ - 'dn': permission1_renamed_dn, - 'cn': [permission1_renamed], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'all'], - 'memberof': u'ipausers', - }, - ), - ), - - - dict( - desc='Rename %r to permission %r' % (permission1_renamed, - permission1_renamed_ucase), - command=( - 'permission_mod', [permission1_renamed], dict(rename=permission1_renamed_ucase, - permissions= u'write',) - ), - expected=dict( - value=permission1_renamed, - summary=u'Modified permission "%s"' % permission1_renamed, - result={ - 'dn': permission1_renamed_ucase_dn, - 'cn': [permission1_renamed_ucase], - 'member_privilege': [privilege1], - 'type': u'user', - 'permissions': [u'write'], - 'memberof': u'ipausers', - }, - ), - ), - - - dict( - desc='Change %r to a subtree type' % permission1_renamed_ucase, - command=( - 'permission_mod', [permission1_renamed_ucase], - dict(subtree=u'ldap:///%s' % DN(('cn', '*'), ('cn', 'test'), ('cn', 'accounts'), api.env.basedn), - type=None) - ), - expected=dict( - value=permission1_renamed_ucase, - summary=u'Modified permission "%s"' % permission1_renamed_ucase, - result=dict( - dn=permission1_renamed_ucase_dn, - cn=[permission1_renamed_ucase], - member_privilege=[privilege1], - subtree=u'ldap:///%s' % DN(('cn', '*'), ('cn', 'test'), ('cn', 'accounts'), api.env.basedn), - permissions=[u'write'], - memberof=u'ipausers', - ), - ), - ), - - - dict( - desc='Search for %r using --subtree' % permission1, - command=('permission_find', [], - {'subtree': u'ldap:///%s' % DN(('cn', '*'), ('cn', 'test'), ('cn', 'accounts'), api.env.basedn)}), - expected=dict( - count=1, - truncated=False, - summary=u'1 permission matched', - result=[ - { - 'dn':permission1_renamed_ucase_dn, - 'cn':[permission1_renamed_ucase], - 'member_privilege':[privilege1], - 'subtree':u'ldap:///%s' % DN(('cn', '*'), ('cn', 'test'), ('cn', 'accounts'), api.env.basedn), - 'permissions':[u'write'], - 'memberof':u'ipausers', - }, - ], - ), - ), - - - dict( - desc='Search using nonexistent --subtree', - command=('permission_find', [], {'subtree': u'foo'}), - expected=dict( - count=0, - truncated=False, - summary=u'0 permissions matched', - result=[], - ), - ), - - - dict( - desc='Search using --targetgroup', - command=('permission_find', [], {'targetgroup': u'ipausers'}), - expected=dict( - count=1, - truncated=False, - summary=u'1 permission matched', - result=[ - { - 'dn': DN(('cn','Add user to default group'), - api.env.container_permission, api.env.basedn), - 'cn': [u'Add user to default group'], - 'member_privilege': [u'User Administrators'], - 'attrs': [u'member'], - 'targetgroup': u'ipausers', - 'memberindirect_role': [u'User Administrator'], - 'permissions': [u'write'] - } - ], - ), - ), - - - dict( - desc='Delete %r' % permission1_renamed_ucase, - command=('permission_del', [permission1_renamed_ucase], {}), - expected=dict( - result=dict(failed=u''), - value=permission1_renamed_ucase, - summary=u'Deleted permission "%s"' % permission1_renamed_ucase, - ) - ), - - - dict( - desc='Try to delete non-existent %r' % permission1, - command=('permission_del', [permission1], {}), - expected=errors.NotFound( - reason=u'%s: permission not found' % permission1), - ), - - - dict( - desc='Try to retrieve non-existent %r' % permission1, - command=('permission_show', [permission1], {}), - expected=errors.NotFound( - reason=u'%s: permission not found' % permission1), - ), - - - dict( - desc='Try to update non-existent %r' % permission1, - command=('permission_mod', [permission1], dict(rename=u'Foo')), - expected=errors.NotFound( - reason=u'%s: permission not found' % permission1), - ), - - - dict( - desc='Delete %r' % permission2, - command=('permission_del', [permission2], {}), - expected=dict( - result=dict(failed=u''), - value=permission2, - summary=u'Deleted permission "%s"' % permission2, - ) - ), - - - dict( - desc='Search for %r' % permission1, - command=('permission_find', [permission1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 permissions matched', - result=[], - ), - ), - - - dict( - desc='Delete %r' % privilege1, - command=('privilege_del', [privilege1], {}), - expected=dict( - result=dict(failed=u''), - value=privilege1, - summary=u'Deleted privilege "%s"' % privilege1, - ) - ), - - dict( - desc='Try to create permission %r with non-existing memberof' % permission1, - command=( - 'permission_add', [permission1], dict( - memberof=u'nonexisting', - permissions=u'write', - ) - ), - expected=errors.NotFound(reason=u'nonexisting: group not found'), - ), - - dict( - desc='Create memberof permission %r' % permission1, - command=( - 'permission_add', [permission1], dict( - memberof=u'editors', - permissions=u'write', - type=u'user', - ) - ), - expected=dict( - value=permission1, - summary=u'Added permission "%s"' % permission1, - result=dict( - dn=permission1_dn, - cn=[permission1], - objectclass=objectclasses.permission, - memberof=u'editors', - permissions=[u'write'], - type=u'user', - ), - ), - ), - - dict( - desc='Try to update non-existent memberof of %r' % permission1, - command=('permission_mod', [permission1], dict( - memberof=u'nonexisting')), - expected=errors.NotFound(reason=u'nonexisting: group not found'), - ), - - dict( - desc='Update memberof permission %r' % permission1, - command=( - 'permission_mod', [permission1], dict( - memberof=u'admins', - ) - ), - expected=dict( - value=permission1, - summary=u'Modified permission "%s"' % permission1, - result=dict( - dn=permission1_dn, - cn=[permission1], - memberof=u'admins', - permissions=[u'write'], - type=u'user', - ), - ), - ), - - dict( - desc='Unset memberof of permission %r' % permission1, - command=( - 'permission_mod', [permission1], dict( - memberof=None, - ) - ), - expected=dict( - summary=u'Modified permission "%s"' % permission1, - value=permission1, - result=dict( - dn=permission1_dn, - cn=[permission1], - permissions=[u'write'], - type=u'user', - ), - ), - ), - - - dict( - desc='Delete %r' % permission1, - command=('permission_del', [permission1], {}), - expected=dict( - result=dict(failed=u''), - value=permission1, - summary=u'Deleted permission "%s"' % permission1, - ) - ), - - - dict( - desc='Create targetgroup permission %r' % permission1, - command=( - 'permission_add', [permission1], dict( - targetgroup=u'editors', - permissions=u'write', - ) - ), - expected=dict( - value=permission1, - summary=u'Added permission "%s"' % permission1, - result=dict( - dn=permission1_dn, - cn=[permission1], - objectclass=objectclasses.permission, - targetgroup=u'editors', - permissions=[u'write'], - ), - ), - ), - - dict( - desc='Try to create invalid %r' % invalid_permission1, - command=('permission_add', [invalid_permission1], dict( - type=u'user', - permissions=u'write', - )), - expected=errors.ValidationError(name='name', - error='May only contain letters, numbers, -, _, and space'), - ), - - dict( - desc='Create %r' % permission3, - command=( - 'permission_add', [permission3], dict( - type=u'user', - permissions=u'write', - attrs=[u'cn'] - ) - ), - expected=dict( - value=permission3, - summary=u'Added permission "%s"' % permission3, - result=dict( - dn=permission3_dn, - cn=[permission3], - objectclass=objectclasses.permission, - type=u'user', - permissions=[u'write'], - attrs=(u'cn',), - ), - ), - ), - - dict( - desc='Retrieve %r with --all --rights' % permission3, - command=('permission_show', [permission3], {'all' : True, 'rights' : True}), - expected=dict( - value=permission3, - summary=None, - result=dict( - dn=permission3_dn, - cn=[permission3], - objectclass=objectclasses.permission, - type=u'user', - attrs=(u'cn',), - permissions=[u'write'], - attributelevelrights=permission3_attributelevelrights - ), - ), - ), - - dict( - desc='Modify %r with --all -rights' % permission3, - command=('permission_mod', [permission3], {'all' : True, 'rights': True, 'attrs':[u'cn',u'uid']}), - expected=dict( - value=permission3, - summary=u'Modified permission "%s"' % permission3, - result=dict( - dn=permission3_dn, - cn=[permission3], - objectclass=objectclasses.permission, - type=u'user', - attrs=(u'cn',u'uid'), - permissions=[u'write'], - attributelevelrights=permission3_attributelevelrights, - ), - ), - ), - ] diff --git a/tests/test_xmlrpc/test_ping_plugin.py b/tests/test_xmlrpc/test_ping_plugin.py deleted file mode 100644 index 3673b436f..000000000 --- a/tests/test_xmlrpc/test_ping_plugin.py +++ /dev/null @@ -1,53 +0,0 @@ -# Authors: -# Petr Viktorin -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/ping.py` module, and XML-RPC in general. -""" - -from ipalib import api, errors, messages, _ -from tests.util import Fuzzy -from xmlrpc_test import Declarative -from ipapython.version import API_VERSION - - -class test_ping(Declarative): - - tests = [ - dict( - desc='Ping the server', - command=('ping', [], {}), - expected=dict( - summary=Fuzzy('IPA server version .*. API version .*')), - ), - - dict( - desc='Try to ping with an argument', - command=('ping', ['bad_arg'], {}), - expected=errors.ZeroArgumentError(name='ping'), - ), - - dict( - desc='Try to ping with an option', - command=('ping', [], dict(bad_arg=True)), - expected=errors.OptionError(_('Unknown option: %(option)s'), - option='bad_arg'), - ), - - ] diff --git a/tests/test_xmlrpc/test_privilege_plugin.py b/tests/test_xmlrpc/test_privilege_plugin.py deleted file mode 100644 index 81e51d5e1..000000000 --- a/tests/test_xmlrpc/test_privilege_plugin.py +++ /dev/null @@ -1,412 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/privilege.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -permission1 = u'testperm' -permission1_dn = DN(('cn',permission1), - api.env.container_permission,api.env.basedn) - -permission2 = u'testperm2' -permission2_dn = DN(('cn',permission2), - api.env.container_permission,api.env.basedn) - -privilege1 = u'testpriv1' -privilege1_dn = DN(('cn',privilege1), - api.env.container_privilege,api.env.basedn) - - -class test_privilege(Declarative): - - cleanup_commands = [ - ('permission_del', [permission1], {}), - ('permission_del', [permission2], {}), - ('privilege_del', [privilege1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % privilege1, - command=('privilege_show', [privilege1], {}), - expected=errors.NotFound( - reason=u'%s: privilege not found' % privilege1), - ), - - - dict( - desc='Try to update non-existent %r' % privilege1, - command=('privilege_mod', [privilege1], dict(description=u'Foo')), - expected=errors.NotFound( - reason=u'%s: privilege not found' % privilege1), - ), - - - dict( - desc='Try to delete non-existent %r' % privilege1, - command=('privilege_del', [privilege1], {}), - expected=errors.NotFound( - reason=u'%s: privilege not found' % privilege1), - ), - - - dict( - desc='Search for non-existent %r' % privilege1, - command=('privilege_find', [privilege1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 privileges matched', - result=[], - ), - ), - - - dict( - desc='Create %r' % permission1, - command=( - 'permission_add', [permission1], dict( - type=u'user', - permissions=[u'add', u'delete'], - ) - ), - expected=dict( - value=permission1, - summary=u'Added permission "%s"' % permission1, - result=dict( - dn=permission1_dn, - cn=[permission1], - objectclass=objectclasses.permission, - type=u'user', - permissions=[u'add', u'delete'], - ), - ), - ), - - - dict( - desc='Create %r' % privilege1, - command=('privilege_add', [privilege1], - dict(description=u'privilege desc. 1') - ), - expected=dict( - value=privilege1, - summary=u'Added privilege "%s"' % privilege1, - result=dict( - dn=privilege1_dn, - cn=[privilege1], - description=[u'privilege desc. 1'], - objectclass=objectclasses.privilege, - ), - ), - ), - - - dict( - desc='Add permission %r to privilege %r' % (permission1, privilege1), - command=('privilege_add_permission', [privilege1], - dict(permission=permission1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - permission=[], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Retrieve %r' % privilege1, - command=('privilege_show', [privilege1], {}), - expected=dict( - value=privilege1, - summary=None, - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1], - }, - ), - ), - - - dict( - desc='Search for %r' % privilege1, - command=('privilege_find', [privilege1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 privilege matched', - result=[ - { - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1], - }, - ], - ), - ), - - - dict( - desc='Search for %r' % privilege1, - command=('privilege_find', [privilege1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 privilege matched', - result=[ - { - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1], - }, - ], - ), - ), - - - dict( - desc='Create %r' % permission2, - command=( - 'permission_add', [permission2], dict( - type=u'user', - permissions=u'write', - ) - ), - expected=dict( - value=permission2, - summary=u'Added permission "%s"' % permission2, - result=dict( - dn=permission2_dn, - cn=[permission2], - objectclass=objectclasses.permission, - type=u'user', - permissions=[u'write'], - ), - ), - ), - - - dict( - desc='Add permission %r to privilege %r' % (permission2, privilege1), - command=('privilege_add_permission', [privilege1], - dict(permission=permission2) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - permission=[], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1, permission2], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Add permission %r to privilege %r again' % (permission2, privilege1), - command=('privilege_add_permission', [privilege1], - dict(permission=permission2) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - permission=[(u'testperm2', u'This entry is already a member'),], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1, permission2], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Search for %r' % privilege1, - command=('privilege_find', [privilege1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 privilege matched', - result=[ - { - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'privilege desc. 1'], - 'memberof_permission': [permission1, permission2], - }, - ], - ), - ), - - - dict( - desc='Update %r' % privilege1, - command=( - 'privilege_mod', [privilege1], dict(description=u'New desc 1') - ), - expected=dict( - value=privilege1, - summary=u'Modified privilege "%s"' % privilege1, - result=dict( - cn=[privilege1], - description=[u'New desc 1'], - memberof_permission=[permission1, permission2], - ), - ), - ), - - - dict( - desc='Remove permission from %r' % privilege1, - command=('privilege_remove_permission', [privilege1], - dict(permission=permission1), - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - permission=[], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'New desc 1'], - 'memberof_permission': [permission2], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Remove permission from %r again' % privilege1, - command=('privilege_remove_permission', [privilege1], - dict(permission=permission1), - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - permission=[(u'testperm', u'This entry is not a member'),], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'New desc 1'], - 'memberof_permission': [permission2], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Add zero permissions to %r' % privilege1, - command=('privilege_add_permission', [privilege1], - dict(permission=None), - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - permission=[], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'New desc 1'], - 'memberof_permission': [permission2], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Remove zero permissions from %r' % privilege1, - command=('privilege_remove_permission', [privilege1], - dict(permission=None), - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - permission=[], - ), - ), - result={ - 'dn': privilege1_dn, - 'cn': [privilege1], - 'description': [u'New desc 1'], - 'memberof_permission': [permission2], - 'objectclass': objectclasses.privilege, - } - ), - ), - - - dict( - desc='Delete %r' % privilege1, - command=('privilege_del', [privilege1], {}), - expected=dict( - result=dict(failed=u''), - value=privilege1, - summary=u'Deleted privilege "%s"' % privilege1, - ) - ), - - - ] diff --git a/tests/test_xmlrpc/test_pwpolicy_plugin.py b/tests/test_xmlrpc/test_pwpolicy_plugin.py deleted file mode 100644 index 3b482ce2d..000000000 --- a/tests/test_xmlrpc/test_pwpolicy_plugin.py +++ /dev/null @@ -1,244 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/pwpolicy.py` module. -""" - -import sys -from nose.tools import assert_raises # pylint: disable=E0611 - -from xmlrpc_test import XMLRPC_test, assert_attr_equal -from ipalib import api -from ipalib import errors - - -class test_pwpolicy(XMLRPC_test): - """ - Test the `pwpolicy` plugin. - """ - group = u'testgroup12' - group2 = u'testgroup22' - group3 = u'testgroup32' - user = u'testuser12' - kw = {'cospriority': 1, 'krbminpwdlife': 30, 'krbmaxpwdlife': 40, 'krbpwdhistorylength': 5, 'krbpwdminlength': 6 } - kw2 = {'cospriority': 2, 'krbminpwdlife': 40, 'krbmaxpwdlife': 60, 'krbpwdhistorylength': 8, 'krbpwdminlength': 9 } - kw3 = {'cospriority': 10, 'krbminpwdlife': 50, 'krbmaxpwdlife': 30, 'krbpwdhistorylength': 3, 'krbpwdminlength': 4 } - global_policy = u'global_policy' - - def test_1_pwpolicy_add(self): - """ - Test adding a per-group policy using the `xmlrpc.pwpolicy_add` method. - """ - # First set up a group and user that will use this policy - self.failsafe_add( - api.Object.group, self.group, description=u'pwpolicy test group', - ) - self.failsafe_add( - api.Object.user, self.user, givenname=u'Test', sn=u'User' - ) - api.Command.group_add_member(self.group, user=self.user) - - entry = api.Command['pwpolicy_add'](self.group, **self.kw)['result'] - assert_attr_equal(entry, 'krbminpwdlife', '30') - assert_attr_equal(entry, 'krbmaxpwdlife', '40') - assert_attr_equal(entry, 'krbpwdhistorylength', '5') - assert_attr_equal(entry, 'krbpwdminlength', '6') - assert_attr_equal(entry, 'cospriority', '1') - - def test_2_pwpolicy_add(self): - """ - Add a policy with a already used priority. - - The priority validation is done first, so it's OK that the group - is the same here. - """ - try: - api.Command['pwpolicy_add'](self.group, **self.kw) - except errors.ValidationError: - pass - else: - assert False - - def test_3_pwpolicy_add(self): - """ - Add a policy that already exists. - """ - try: - # cospriority needs to be unique - self.kw['cospriority'] = 3 - api.Command['pwpolicy_add'](self.group, **self.kw) - except errors.DuplicateEntry: - pass - else: - assert False - - def test_4_pwpolicy_add(self): - """ - Test adding another per-group policy using the `xmlrpc.pwpolicy_add` method. - """ - self.failsafe_add( - api.Object.group, self.group2, description=u'pwpolicy test group 2' - ) - entry = api.Command['pwpolicy_add'](self.group2, **self.kw2)['result'] - assert_attr_equal(entry, 'krbminpwdlife', '40') - assert_attr_equal(entry, 'krbmaxpwdlife', '60') - assert_attr_equal(entry, 'krbpwdhistorylength', '8') - assert_attr_equal(entry, 'krbpwdminlength', '9') - assert_attr_equal(entry, 'cospriority', '2') - - def test_5_pwpolicy_add(self): - """ - Add a pwpolicy for a non-existent group - """ - try: - api.Command['pwpolicy_add'](u'nopwpolicy', cospriority=1, krbminpwdlife=1) - except errors.NotFound: - pass - else: - assert False - - def test_6_pwpolicy_show(self): - """ - Test the `xmlrpc.pwpolicy_show` method with global policy. - """ - entry = api.Command['pwpolicy_show']()['result'] - # Note that this assumes an unchanged global policy - assert_attr_equal(entry, 'krbminpwdlife', '1') - assert_attr_equal(entry, 'krbmaxpwdlife', '90') - assert_attr_equal(entry, 'krbpwdhistorylength', '0') - assert_attr_equal(entry, 'krbpwdminlength', '8') - - def test_7_pwpolicy_show(self): - """ - Test the `xmlrpc.pwpolicy_show` method. - """ - entry = api.Command['pwpolicy_show'](self.group)['result'] - assert_attr_equal(entry, 'krbminpwdlife', '30') - assert_attr_equal(entry, 'krbmaxpwdlife', '40') - assert_attr_equal(entry, 'krbpwdhistorylength', '5') - assert_attr_equal(entry, 'krbpwdminlength', '6') - assert_attr_equal(entry, 'cospriority', '1') - - def test_8_pwpolicy_mod(self): - """ - Test the `xmlrpc.pwpolicy_mod` method for global policy. - """ - entry = api.Command['pwpolicy_mod'](krbminpwdlife=50)['result'] - assert_attr_equal(entry, 'krbminpwdlife', '50') - - # Great, now change it back - entry = api.Command['pwpolicy_mod'](krbminpwdlife=1)['result'] - assert_attr_equal(entry, 'krbminpwdlife', '1') - - def test_9_pwpolicy_mod(self): - """ - Test the `xmlrpc.pwpolicy_mod` method. - """ - entry = api.Command['pwpolicy_mod'](self.group, krbminpwdlife=50)['result'] - assert_attr_equal(entry, 'krbminpwdlife', '50') - - def test_a_pwpolicy_managed(self): - """ - Test adding password policy to a managed group. - """ - try: - entry = api.Command['pwpolicy_add'](self.user, krbminpwdlife=50, cospriority=2)['result'] - except errors.ManagedPolicyError: - pass - else: - assert False - - def test_b_pwpolicy_add(self): - """ - Test adding a third per-group policy using the `xmlrpc.pwpolicy_add` method. - """ - self.failsafe_add( - api.Object.group, self.group3, description=u'pwpolicy test group 3' - ) - entry = api.Command['pwpolicy_add'](self.group3, **self.kw3)['result'] - assert_attr_equal(entry, 'krbminpwdlife', '50') - assert_attr_equal(entry, 'krbmaxpwdlife', '30') - assert_attr_equal(entry, 'krbpwdhistorylength', '3') - assert_attr_equal(entry, 'krbpwdminlength', '4') - assert_attr_equal(entry, 'cospriority', '10') - - def test_c_pwpolicy_find(self): - """Test that password policies are sorted and reported properly""" - result = api.Command['pwpolicy_find']()['result'] - assert len(result) == 4 - - # Test that policies are sorted in numerical order - assert result[0]['cn'] == (self.group,) - assert result[1]['cn'] == (self.group2,) - assert result[2]['cn'] == (self.group3,) - assert result[3]['cn'] == ('global_policy',) - - # Test that returned values match the arguments - # Only test the second and third results; the first one was modified - for entry, expected in (result[1], self.kw2), (result[2], self.kw3): - for name, value in expected.iteritems(): - assert_attr_equal(entry, name, str(value)) - - def test_c_pwpolicy_find_pkey_only(self): - """Test that password policies are sorted properly with --pkey-only""" - result = api.Command['pwpolicy_find'](pkey_only=True)['result'] - assert len(result) == 4 - assert result[0]['cn'] == (self.group,) - assert result[1]['cn'] == (self.group2,) - assert result[2]['cn'] == (self.group3,) - assert result[3]['cn'] == ('global_policy',) - - def test_d_pwpolicy_show(self): - """Test that deleting a group removes its pwpolicy""" - api.Command['group_del'](self.group3) - with assert_raises(errors.NotFound): - api.Command['pwpolicy_show'](self.group3) - - def test_e_pwpolicy_del(self): - """ - Test the `xmlrpc.pwpolicy_del` method. - """ - api.Command['pwpolicy_del'](self.group) - # Verify that it is gone - try: - api.Command['pwpolicy_show'](self.group) - except errors.NotFound: - pass - else: - assert False - - # Verify that global policy cannot be deleted - try: - api.Command['pwpolicy_del'](self.global_policy) - except errors.ValidationError: - pass - else: - assert False - try: - api.Command['pwpolicy_show'](self.global_policy) - except errors.NotFound: - assert False - - # Remove the groups we created - api.Command['group_del'](self.group) - api.Command['group_del'](self.group2) - - # Remove the user we created - api.Command['user_del'](self.user) diff --git a/tests/test_xmlrpc/test_range_plugin.py b/tests/test_xmlrpc/test_range_plugin.py deleted file mode 100644 index ce7043311..000000000 --- a/tests/test_xmlrpc/test_range_plugin.py +++ /dev/null @@ -1,536 +0,0 @@ -# Authors: -# Alexander Bokovoy -# -# Copyright (C) 2012 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/idrange.py` module, and XML-RPC in general. -""" - -from ipalib import api, errors, _ -from tests.util import assert_equal, Fuzzy -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from tests.test_xmlrpc import objectclasses -from ipapython.dn import * - -import ldap, ldap.sasl, ldap.modlist - -testrange1 = u'testrange1' -testrange1_base_id = 900000 -testrange1_size = 99999 -testrange1_base_rid = 10000 -testrange1_secondary_base_rid = 200000 - -testrange2 = u'testrange2' -testrange2_base_id = 100 -testrange2_size = 50 -testrange2_base_rid = 100 -testrange2_secondary_base_rid = 1000 - -testrange3 = u'testrange3' -testrange3_base_id = 200 -testrange3_size = 50 -testrange3_base_rid = 70 -testrange3_secondary_base_rid = 1100 - -testrange4 = u'testrange4' -testrange4_base_id = 300 -testrange4_size = 50 -testrange4_base_rid = 200 -testrange4_secondary_base_rid = 1030 - -testrange5 = u'testrange5' -testrange5_base_id = 400 -testrange5_size = 50 -testrange5_base_rid = 1020 -testrange5_secondary_base_rid = 1200 - -testrange6 = u'testrange6' -testrange6_base_id = 130 -testrange6_size = 50 -testrange6_base_rid = 500 -testrange6_secondary_base_rid = 1300 - -testrange7 = u'testrange7' -testrange7_base_id = 600 -testrange7_size = 50 -testrange7_base_rid = 600 -testrange7_secondary_base_rid = 649 - -testrange8 = u'testrange8' -testrange8_base_id = 700 -testrange8_size = 50 -testrange8_base_rid = 700 - -testrange9 = u'testrange9' -testrange9_base_id = 800 -testrange9_size = 50 -testrange9_base_rid = 800 - -testrange10 = u'testrange10' -testrange10_base_id = 900 -testrange10_size = 50 -testrange10_base_rid = 900 - -testrange9_dn = "cn={name},cn=ranges,cn=etc,{basedn}".format(name=testrange9, - basedn=api.env.basedn) - -testrange9_add = dict( - objectClass=["ipaIDrange", "ipatrustedaddomainrange"], - ipaBaseID="{base_id}".format(base_id=testrange9_base_id), - ipaBaseRID="{base_rid}".format(base_rid=testrange9_base_rid), - ipaIDRangeSize="{size}".format(size=testrange9_size), - ipaNTTrustedDomainSID="S-1-5-21-259319770-2312917334-591429603", - ) - -testrange10_dn = "cn={name},cn=ranges,cn=etc,{basedn}".format(name=testrange10, - basedn=api.env.basedn) - -testrange10_add = dict( - objectClass=["ipaIDrange", "ipatrustedaddomainrange"], - ipaBaseID="{base_id}".format(base_id=testrange10_base_id), - ipaBaseRID="{base_rid}".format(base_rid=testrange10_base_rid), - ipaIDRangeSize="{size}".format(size=testrange10_size), - ipaNTTrustedDomainSID="S-1-5-21-2997650941-1802118864-3094776726", - ) - -testtrust = u'testtrust' -testtrust_dn = "cn=testtrust,cn=trusts,{basedn}".format(basedn=api.env.basedn) - -testtrust_add = dict( - objectClass=["ipaNTTrustedDomain", "ipaIDobject", "top"], - ipaNTFlatName='TESTTRUST', - ipaNTTrustedDomainSID='S-1-5-21-2997650941-1802118864-3094776726', - ipaNTSIDBlacklistIncoming='S-1-0', - ipaNTTrustPartner='testtrust.mock', - ipaNTTrustType='2', - ipaNTTrustDirection='3', - ipaNTTrustAttributes='8', - ) - -user1 = u'tuser1' -user1_uid = 900000 -group1 = u'group1' -group1_gid = 900100 - - -class test_range(Declarative): - - def __init__(self): - super(test_range, self).__init__() - self.connection = None - - @classmethod - def connect_ldap(self): - self.connection = ldap.initialize('ldap://{host}' - .format(host=api.env.host)) - - auth = ldap.sasl.gssapi("") - self.connection.sasl_interactive_bind_s('', auth) - - @classmethod - def add_entry(self, dn, mods): - ldif = ldap.modlist.addModlist(mods) - self.connection.add_s(dn, ldif) - - @classmethod - def setUpClass(self): - super(test_range, self).setUpClass() - - self.tearDownClass() - - try: - self.connect_ldap() - - self.add_entry(testrange9_dn, testrange9_add) - self.add_entry(testrange10_dn, testrange10_add) - self.add_entry(testtrust_dn, testtrust_add) - - except ldap.ALREADY_EXISTS: - pass - - finally: - if self.connection is not None: - self.connection.unbind_s() - - @classmethod - def tearDownClass(self): - - try: - self.connect_ldap() - self.connection.delete_s(testrange9_dn) - self.connection.delete_s(testrange10_dn) - self.connection.delete_s(testtrust_dn) - - except ldap.NO_SUCH_OBJECT: - pass - - finally: - if self.connection is not None: - self.connection.unbind_s() - - cleanup_commands = [ - ('idrange_del', [testrange1, testrange2, testrange3, testrange4, - testrange5, testrange6, testrange7, testrange8], - {'continue': True}), - ('user_del', [user1], {}), - ('group_del', [group1], {}), - ] - - tests = [ - dict( - desc='Create ID range %r' % (testrange1), - command=('idrange_add', [testrange1], - dict(ipabaseid=testrange1_base_id, ipaidrangesize=testrange1_size, - ipabaserid=testrange1_base_rid, ipasecondarybaserid=testrange1_secondary_base_rid)), - expected=dict( - result=dict( - dn=DN(('cn',testrange1),('cn','ranges'),('cn','etc'), - api.env.basedn), - cn=[testrange1], - objectclass=[u'ipaIDrange', u'ipadomainidrange'], - ipabaseid=[unicode(testrange1_base_id)], - ipabaserid=[unicode(testrange1_base_rid)], - ipasecondarybaserid=[unicode(testrange1_secondary_base_rid)], - ipaidrangesize=[unicode(testrange1_size)], - iparangetype=[u'local domain range'], - ), - value=testrange1, - summary=u'Added ID range "%s"' % (testrange1), - ), - ), - - dict( - desc='Retrieve ID range %r' % (testrange1), - command=('idrange_show', [testrange1], dict()), - expected=dict( - result=dict( - dn=DN(('cn',testrange1),('cn','ranges'),('cn','etc'), - api.env.basedn), - cn=[testrange1], - ipabaseid=[unicode(testrange1_base_id)], - ipabaserid=[unicode(testrange1_base_rid)], - ipasecondarybaserid=[unicode(testrange1_secondary_base_rid)], - ipaidrangesize=[unicode(testrange1_size)], - iparangetype=[u'local domain range'], - ), - value=testrange1, - summary=None, - ), - ), - - - dict( - desc='Create user %r in ID range %r' % (user1, testrange1), - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - uidnumber=user1_uid) - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[unicode(user1_uid)], - gidnumber=[unicode(user1_uid)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - mail=[u'%s@%s' % (user1, api.env.domain)], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid',user1),('cn','users'),('cn','accounts'), api.env.basedn) - ), - ), - ), - - - dict( - desc='Create group %r in ID range %r' % (group1, testrange1), - command=( - 'group_add', [group1], dict(description=u'Test desc 1', - gidnumber=group1_gid) - ), - expected=dict( - value=group1, - summary=u'Added group "%s"' % group1, - result=dict( - cn=[group1], - description=[u'Test desc 1'], - gidnumber=[unicode(group1_gid)], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn',group1),('cn','groups'),('cn','accounts'), api.env.basedn), - ), - ), - ), - - - dict( - desc='Try to modify ID range %r to get out bounds object #1' % (testrange1), - command=('idrange_mod', [testrange1], dict(ipabaseid=90001)), - expected=errors.ValidationError(name='ipabaseid,ipaidrangesize', - error=u'range modification leaving objects with ID out of the' - u' defined range is not allowed'), - ), - - - dict( - desc='Try to modify ID range %r to get out bounds object #2' % (testrange1), - command=('idrange_mod', [testrange1], dict(ipaidrangesize=100)), - expected=errors.ValidationError(name='ipabaseid,ipaidrangesize', - error=u'range modification leaving objects with ID out of the' - u' defined range is not allowed'), - ), - - - dict( - desc='Try to modify ID range %r to get out bounds object #3' % (testrange1), - command=('idrange_mod', [testrange1], dict(ipabaseid=100, ipaidrangesize=100)), - expected=errors.ValidationError(name='ipabaseid,ipaidrangesize', - error=u'range modification leaving objects with ID out of the' - u' defined range is not allowed'), - ), - - - dict( - desc='Modify ID range %r' % (testrange1), - command=('idrange_mod', [testrange1], dict(ipaidrangesize=90000)), - expected=dict( - result=dict( - cn=[testrange1], - ipabaseid=[unicode(testrange1_base_id)], - ipabaserid=[unicode(testrange1_base_rid)], - ipasecondarybaserid=[unicode(testrange1_secondary_base_rid)], - ipaidrangesize=[u'90000'], - iparangetype=[u'local domain range'], - ), - value=testrange1, - summary=u'Modified ID range "%s"' % (testrange1), - ), - ), - - - dict( - desc='Try to delete ID range %r with active IDs inside it' % testrange1, - command=('idrange_del', [testrange1], {}), - expected=errors.ValidationError(name='ipabaseid,ipaidrangesize', - error=u'range modification leaving objects with ID out of the' - u' defined range is not allowed'), - ), - - - dict( - desc='Delete user %r' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - value=user1, - summary=u'Deleted user "%s"' % user1, - ), - ), - - - dict( - desc='Delete group %r' % group1, - command=('group_del', [group1], {}), - expected=dict( - result=dict(failed=u''), - value=group1, - summary=u'Deleted group "%s"' % group1, - ), - ), - - - dict( - desc='Delete ID range %r' % testrange1, - command=('idrange_del', [testrange1], {}), - expected=dict( - result=dict(failed=u''), - value=testrange1, - summary=u'Deleted ID range "%s"' % testrange1, - ), - ), - - dict( - desc='Create ID range %r' % (testrange2), - command=('idrange_add', [testrange2], - dict(ipabaseid=testrange2_base_id, - ipaidrangesize=testrange2_size, - ipabaserid=testrange2_base_rid, - ipasecondarybaserid=testrange2_secondary_base_rid)), - expected=dict( - result=dict( - dn=DN(('cn',testrange2),('cn','ranges'),('cn','etc'), - api.env.basedn), - cn=[testrange2], - objectclass=[u'ipaIDrange', u'ipadomainidrange'], - ipabaseid=[unicode(testrange2_base_id)], - ipabaserid=[unicode(testrange2_base_rid)], - ipasecondarybaserid=[unicode(testrange2_secondary_base_rid)], - ipaidrangesize=[unicode(testrange2_size)], - iparangetype=[u'local domain range'], - ), - value=testrange2, - summary=u'Added ID range "%s"' % (testrange2), - ), - ), - - dict( - desc='Try to modify ID range %r so that its rid ranges are overlapping themselves' % (testrange2), - command=('idrange_mod', [testrange2], - dict(ipabaserid=(testrange2_base_rid*10))), - expected=errors.ValidationError( - name='ID Range setup', error='Primary RID range and secondary RID range cannot overlap'), - ), - - dict( - desc='Try to create ID range %r with overlapping rid range' % (testrange3), - command=('idrange_add', [testrange3], - dict(ipabaseid=testrange3_base_id, - ipaidrangesize=testrange3_size, - ipabaserid=testrange3_base_rid, - ipasecondarybaserid=testrange3_secondary_base_rid)), - expected=errors.DatabaseError( - desc='Constraint violation', info='New primary rid range overlaps with existing primary rid range.'), - ), - - dict( - desc='Try to create ID range %r with overlapping secondary rid range' % (testrange4), - command=('idrange_add', [testrange4], - dict(ipabaseid=testrange4_base_id, - ipaidrangesize=testrange4_size, - ipabaserid=testrange4_base_rid, - ipasecondarybaserid=testrange4_secondary_base_rid)), - expected=errors.DatabaseError( - desc='Constraint violation', info='New secondary rid range overlaps with existing secondary rid range.'), - ), - - dict( - desc='Try to create ID range %r with primary range overlapping secondary rid range' % (testrange5), - command=('idrange_add', [testrange5], - dict(ipabaseid=testrange5_base_id, - ipaidrangesize=testrange5_size, - ipabaserid=testrange5_base_rid, - ipasecondarybaserid=testrange5_secondary_base_rid)), - expected=errors.DatabaseError( - desc='Constraint violation', info='New primary rid range overlaps with existing secondary rid range.'), - ), - - dict( - desc='Try to create ID range %r with overlapping id range' % (testrange6), - command=('idrange_add', [testrange6], - dict(ipabaseid=testrange6_base_id, - ipaidrangesize=testrange6_size, - ipabaserid=testrange6_base_rid, - ipasecondarybaserid=testrange6_secondary_base_rid)), - expected=errors.DatabaseError( - desc='Constraint violation', info='New base range overlaps with existing base range.'), - ), - - dict( - desc='Try to create ID range %r with rid ranges overlapping themselves' % (testrange7), - command=('idrange_add', [testrange7], - dict(ipabaseid=testrange7_base_id, - ipaidrangesize=testrange7_size, - ipabaserid=testrange7_base_rid, - ipasecondarybaserid=testrange7_secondary_base_rid)), - expected=errors.ValidationError( - name='ID Range setup', error='Primary RID range and secondary RID range cannot overlap'), - ), - - dict( - desc='Delete ID range %r' % testrange2, - command=('idrange_del', [testrange2], {}), - expected=dict( - result=dict(failed=u''), - value=testrange2, - summary=u'Deleted ID range "%s"' % testrange2, - ), - ), - - dict( - desc='Create ID range %r' % (testrange8), - command=('idrange_add', [testrange8], - dict(ipabaseid=testrange8_base_id, - ipaidrangesize=testrange8_size)), - expected=dict( - result=dict( - dn=DN(('cn',testrange8),('cn','ranges'),('cn','etc'), - api.env.basedn), - cn=[testrange8], - objectclass=[u'ipaIDrange', u'ipadomainidrange'], - ipabaseid=[unicode(testrange8_base_id)], - ipaidrangesize=[unicode(testrange8_size)], - iparangetype=[u'local domain range'], - ), - value=testrange8, - summary=u'Added ID range "%s"' % (testrange8), - ), - ), - - dict( - desc='Try to modify ID range %r so it has only primary rid range set' % (testrange8), - command=('idrange_mod', [testrange8], - dict(ipabaserid=testrange8_base_rid)), - expected=errors.ValidationError( - name='ID Range setup', error='Options secondary-rid-base and rid-base must be used together'), - ), - - dict( - desc='Delete ID range %r' % testrange8, - command=('idrange_del', [testrange8], {}), - expected=dict( - result=dict(failed=u''), - value=testrange8, - summary=u'Deleted ID range "%s"' % testrange8, - ), - ), - - dict( - desc='Delete non-active AD trusted range %r' % testrange9, - command=('idrange_del', [testrange9], {}), - expected=dict( - result=dict(failed=u''), - value=testrange9, - summary=u'Deleted ID range "%s"' % testrange9, - ), - ), - - dict( - desc='Try to delete active AD trusted range %r' % testrange10, - command=('idrange_del', [testrange10], {}), - expected=errors.DependentEntry( - label='Active Trust', - key=testrange10, - dependent=testtrust), - ), - - ] diff --git a/tests/test_xmlrpc/test_realmdomains_plugin.py b/tests/test_xmlrpc/test_realmdomains_plugin.py deleted file mode 100644 index 22cac2286..000000000 --- a/tests/test_xmlrpc/test_realmdomains_plugin.py +++ /dev/null @@ -1,164 +0,0 @@ -# Authors: -# Ana Krivokapic -# -# Copyright (C) 2013 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/realmdomains.py` module. -""" - -from ipalib import api, errors -from ipapython.dn import DN -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative - - -cn = u'Realm Domains' -dn = DN(('cn', cn), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) -our_domain = api.env.domain -new_domain_1 = u'example1.com' -new_domain_2 = u'example2.com' -bad_domain = u'doesnotexist.test' - - -class test_realmdomains(Declarative): - - cleanup_commands = [ - ('realmdomains_mod', [], {'associateddomain': [our_domain]}), - ] - - tests = [ - dict( - desc='Retrieve realm domains', - command=('realmdomains_show', [], {}), - expected=dict( - value=u'', - summary=None, - result=dict( - dn=dn, - associateddomain=[our_domain], - ), - ), - ), - dict( - desc='Retrieve realm domains - print all attributes', - command=('realmdomains_show', [], {'all': True}), - expected=dict( - value=u'', - summary=None, - result=dict( - dn=dn, - associateddomain=[our_domain], - cn=[cn], - objectclass=objectclasses.realmdomains, - ), - ), - ), - dict( - desc='Replace list of realm domains with "%s"' % [our_domain, new_domain_1], - command=('realmdomains_mod', [], {'associateddomain': [our_domain, new_domain_1]}), - expected=dict( - value=u'', - summary=None, - result=dict( - associateddomain=[our_domain, new_domain_1], - ), - ), - ), - dict( - desc='Add domain "%s" to list' % new_domain_2, - command=('realmdomains_mod', [], {'add_domain': new_domain_2}), - expected=dict( - value=u'', - summary=None, - result=dict( - associateddomain=[our_domain, new_domain_1, new_domain_2], - ), - ), - ), - dict( - desc='Delete domain "%s" from list' % new_domain_2, - command=('realmdomains_mod', [], {'del_domain': new_domain_2}), - expected=dict( - value=u'', - summary=None, - result=dict( - associateddomain=[our_domain, new_domain_1], - ), - ), - ), - dict( - desc='Add domain "%s" and delete domain "%s"' % (new_domain_2, new_domain_1), - command=('realmdomains_mod', [], {'add_domain': new_domain_2, 'del_domain': new_domain_1}), - expected=dict( - value=u'', - summary=None, - result=dict( - associateddomain=[our_domain, new_domain_2], - ), - ), - ), - dict( - desc='Try to specify --domain and --add-domain options together', - command=('realmdomains_mod', [], { - 'associateddomain': [our_domain, new_domain_1], - 'add_domain': new_domain_1, - }), - expected=errors.MutuallyExclusiveError( - reason='you cannot specify the --domain option together with --add-domain or --del-domain'), - ), - dict( - desc='Try to replace list of realm domains with a list without our domain', - command=('realmdomains_mod', [], {'associateddomain': [new_domain_1]}), - expected=errors.ValidationError( - name='domain', error='cannot delete domain of IPA server'), - ), - dict( - desc='Try to replace list of realm domains with a list with an invalid domain "%s"' % bad_domain, - command=('realmdomains_mod', [], {'associateddomain': [our_domain, bad_domain]}), - expected=errors.ValidationError( - name='domain', error='no SOA or NS records found for domains: %s' % bad_domain), - ), - dict( - desc='Try to add an invalid domain "%s"' % bad_domain, - command=('realmdomains_mod', [], {'add_domain': bad_domain}), - expected=errors.ValidationError( - name='add_domain', error='no SOA or NS records found for domain %s' % bad_domain), - ), - dict( - desc='Try to delete our domain', - command=('realmdomains_mod', [], {'del_domain': our_domain}), - expected=errors.ValidationError( - name='del_domain', error='cannot delete domain of IPA server'), - ), - dict( - desc='Try to delete domain which is not in list', - command=('realmdomains_mod', [], {'del_domain': new_domain_1}), - expected=errors.AttrValueNotFound( - attr='associateddomain', value=new_domain_1), - ), - dict( - desc='Add an invalid domain "%s" with --force option' % bad_domain, - command=('realmdomains_mod', [], {'add_domain': bad_domain, 'force': True}), - expected=dict( - value=u'', - summary=None, - result=dict( - associateddomain=[our_domain, new_domain_2, bad_domain], - ), - ), - ), - ] diff --git a/tests/test_xmlrpc/test_replace.py b/tests/test_xmlrpc/test_replace.py deleted file mode 100644 index 434f71d70..000000000 --- a/tests/test_xmlrpc/test_replace.py +++ /dev/null @@ -1,236 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the modlist replace logic. Some attributes require a MOD_REPLACE -while others are fine using ADD/DELETE. - -Note that member management in other tests also exercises the -gen_modlist code. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -user1=u'tuser1' - - -class test_replace(Declarative): - - cleanup_commands = [ - ('user_del', [user1], {}), - ] - - tests = [ - - dict( - desc='Create %r with 2 e-mail accounts' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - mail=[u'test1@example.com', u'test2@example.com']) - ), - expected=dict( - value=user1, - summary=u'Added user "tuser1"', - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - mail=[u'test1@example.com', u'test2@example.com'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm),('cn','kerberos'), - api.env.basedn)], - mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=DN(('uid','tuser1'),('cn','users'),('cn','accounts'), - api.env.basedn), - ), - ), - ), - - - dict( - desc='Drop one e-mail account, add another to %r' % user1, - command=( - 'user_mod', [user1], dict(mail=[u'test1@example.com', u'test3@example.com']) - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test1@example.com', u'test3@example.com'], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Set mail to a new single value %r' % user1, - command=( - 'user_mod', [user1], dict(mail=u'test4@example.com') - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test4@example.com'], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Set mail to three new values %r' % user1, - command=( - 'user_mod', [user1], dict(mail=[u'test5@example.com', u'test6@example.com', u'test7@example.com']) - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'test6@example.com', u'test7@example.com', u'test5@example.com'], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Remove all mail values %r' % user1, - command=( - 'user_mod', [user1], dict(mail=u'') - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Ensure single-value mods work too, replace initials %r' % user1, - command=( - 'user_mod', [user1], dict(initials=u'ABC') - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - initials=[u'ABC'], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - - dict( - desc='Drop a single-value attribute %r' % user1, - command=( - 'user_mod', [user1], dict(initials=u'') - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "tuser1"', - value=user1, - ), - ), - - ] diff --git a/tests/test_xmlrpc/test_role_plugin.py b/tests/test_xmlrpc/test_role_plugin.py deleted file mode 100644 index be3fecebc..000000000 --- a/tests/test_xmlrpc/test_role_plugin.py +++ /dev/null @@ -1,625 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# John Dennis -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/role.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN - -search = u'test-role' - -role1 = u'test-role-1' -role1_dn = DN(('cn',role1),api.env.container_rolegroup, - api.env.basedn) -renamedrole1 = u'test-role' -invalidrole1 = u' whitespace ' - -role2 = u'test-role-2' -role2_dn = DN(('cn',role2),api.env.container_rolegroup, - api.env.basedn) - -group1 = u'testgroup1' -group1_dn = DN(('cn',group1),api.env.container_group, - api.env.basedn) - -privilege1 = u'r,w privilege 1' -privilege1_dn = DN(('cn', privilege1), DN(api.env.container_privilege), - api.env.basedn) - -class test_role(Declarative): - - cleanup_commands = [ - ('role_del', [role1], {}), - ('role_del', [role2], {}), - ('group_del', [group1], {}), - ('privilege_del', [privilege1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % role1, - command=('role_show', [role1], {}), - expected=errors.NotFound(reason=u'%s: role not found' % role1), - ), - - - dict( - desc='Try to update non-existent %r' % role1, - command=('role_mod', [role1], dict(description=u'Foo')), - expected=errors.NotFound(reason=u'%s: role not found' % role1), - ), - - - dict( - desc='Try to delete non-existent %r' % role1, - command=('role_del', [role1], {}), - expected=errors.NotFound(reason=u'%s: role not found' % role1), - ), - - - dict( - desc='Try to rename non-existent %r' % role1, - command=('role_mod', [role1], dict(setattr=u'cn=%s' % renamedrole1)), - expected=errors.NotFound(reason=u'%s: role not found' % role1), - ), - - - dict( - desc='Search for non-existent %r' % role1, - command=('role_find', [role1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 roles matched', - result=[], - ), - ), - - - dict( - desc='Create invalid %r' % invalidrole1, - command=('role_add', [invalidrole1], - dict(description=u'role desc 1') - ), - expected=errors.ValidationError(name='name', - error=u'Leading and trailing spaces are not allowed'), - ), - - - dict( - desc='Create %r' % role1, - command=('role_add', [role1], - dict(description=u'role desc 1') - ), - expected=dict( - value=role1, - summary=u'Added role "%s"' % role1, - result=dict( - dn=role1_dn, - cn=[role1], - description=[u'role desc 1'], - objectclass=objectclasses.role, - ), - ), - ), - - - dict( - desc='Retrieve %r' % role1, - command=('role_show', [role1], {}), - expected=dict( - value=role1, - summary=None, - result=dict( - dn=role1_dn, - cn=[role1], - description=[u'role desc 1'], - ), - ), - ), - - - dict( - desc='Create %r' % group1, - command=( - 'group_add', [group1], dict(description=u'group desc 1', - nonposix=True,) - ), - expected=dict( - value=group1, - summary=u'Added group "testgroup1"', - result=dict( - dn=group1_dn, - cn=[group1], - description=[u'group desc 1'], - objectclass=objectclasses.group, - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Create %r' % privilege1, - command=('privilege_add', [privilege1], - dict(description=u'privilege desc. 1') - ), - expected=dict( - value=privilege1, - summary=u'Added privilege "%s"' % privilege1, - result=dict( - dn=privilege1_dn, - cn=[privilege1], - description=[u'privilege desc. 1'], - objectclass=objectclasses.privilege, - ), - ), - ), - - - dict( - desc='Add privilege %r to role %r' % (privilege1, role1), - command=('role_add_privilege', [role1], - dict(privilege=privilege1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - privilege=[], - ), - ), - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'memberof_privilege': [privilege1], - 'objectclass': objectclasses.role, - } - ), - ), - - - dict( - desc='Add zero privileges to role %r' % role1, - command=('role_add_privilege', [role1], dict(privilege=None) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - privilege=[], - ), - ), - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'memberof_privilege': [privilege1], - 'objectclass': objectclasses.role, - } - ), - ), - - - dict( - desc='Remove zero privileges from role %r' % role1, - command=('role_remove_privilege', [role1], dict(privilege=None) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - privilege=[], - ), - ), - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'memberof_privilege': [privilege1], - 'objectclass': objectclasses.role, - } - ), - ), - - - dict( - desc='Add member %r to %r' % (group1, role1), - command=('role_add_member', [role1], dict(group=group1)), - expected=dict( - completed=1, - failed=dict( - member=dict( - user=[], - group=[], - host=[], - hostgroup=[], - ), - ), - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'member_group': [group1], - 'memberof_privilege': [privilege1], - } - ), - ), - - - dict( - desc='Retrieve %r to verify member-add' % role1, - command=('role_show', [role1], {}), - expected=dict( - value=role1, - summary=None, - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'member_group': [group1], - 'memberof_privilege': [privilege1], - }, - ), - ), - - - dict( - desc='Search for %r' % role1, - command=('role_find', [role1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 role matched', - result=[ - { - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'member_group': [group1], - 'memberof_privilege': [privilege1], - }, - ], - ), - ), - - - dict( - desc='Search for %r' % search, - command=('role_find', [search], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 role matched', - result=[ - { - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'member_group': [group1], - 'memberof_privilege': [privilege1], - }, - ], - ), - ), - - - dict( - desc='Create %r' % role2, - command=('role_add', [role2], - dict(description=u'role desc 2') - ), - expected=dict( - value=role2, - summary=u'Added role "%s"' % role2, - result=dict( - dn=role2_dn, - cn=[role2], - description=[u'role desc 2'], - objectclass=objectclasses.role, - ), - ), - ), - - - dict( - desc='Search for %r' % role1, - command=('role_find', [role1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 role matched', - result=[ - { - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'member_group': [group1], - 'memberof_privilege': [privilege1], - }, - ], - ), - ), - - - dict( - desc='Search for %r' % search, - command=('role_find', [search], {}), - expected=dict( - count=2, - truncated=False, - summary=u'2 roles matched', - result=[ - { - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'role desc 1'], - 'member_group': [group1], - 'memberof_privilege': [privilege1], - }, - { - 'dn': role2_dn, - 'cn': [role2], - 'description': [u'role desc 2'], - }, - ], - ), - ), - - - dict( - desc='Update %r' % role1, - command=( - 'role_mod', [role1], dict(description=u'New desc 1') - ), - expected=dict( - value=role1, - summary=u'Modified role "%s"' % role1, - result=dict( - cn=[role1], - description=[u'New desc 1'], - member_group=[group1], - memberof_privilege=[privilege1], - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % role1, - command=('role_show', [role1], {}), - expected=dict( - value=role1, - summary=None, - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'New desc 1'], - 'member_group': [group1], - 'memberof_privilege': [privilege1], - }, - ), - ), - - - dict( - desc='Remove member %r from %r' % (group1, role1), - command=('role_remove_member', [role1], dict(group=group1)), - expected=dict( - completed=1, - failed=dict( - member=dict( - user=[], - group=[], - host=[], - hostgroup=[], - ), - ), - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'New desc 1'], - 'memberof_privilege': [privilege1], - }, - ), - ), - - - dict( - desc='Retrieve %r to verify member-del' % role1, - command=('role_show', [role1], {}), - expected=dict( - value=role1, - summary=None, - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'New desc 1'], - 'memberof_privilege': [privilege1], - }, - ), - ), - - - dict( - desc='Delete %r' % group1, - command=('group_del', [group1], {}), - expected=dict( - result=dict(failed=u''), - value=group1, - summary=u'Deleted group "testgroup1"', - ) - ), - - - dict( - desc='Rename %r' % role1, - command=('role_mod', [role1], dict(setattr=u'cn=%s' % renamedrole1)), - expected=dict( - value=role1, - result=dict( - cn=[renamedrole1], - description=[u'New desc 1'], - memberof_privilege=[privilege1], - ), - summary=u'Modified role "%s"' % role1 - ) - ), - - - dict( - desc='Rename %r back' % renamedrole1, - command=('role_mod', [renamedrole1], dict(setattr=u'cn=%s' % role1)), - expected=dict( - value=renamedrole1, - result=dict( - cn=[role1], - description=[u'New desc 1'], - memberof_privilege=[privilege1], - ), - summary=u'Modified role "%s"' % renamedrole1 - ) - ), - - - dict( - desc='Remove privilege %r from role %r' % (privilege1, role1), - command=('role_remove_privilege', [role1], - dict(privilege=privilege1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - privilege=[], - ), - ), - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'New desc 1'], - 'objectclass': objectclasses.role, - } - ), - ), - - - dict( - desc='Remove privilege %r from role %r again' % (privilege1, role1), - command=('role_remove_privilege', [role1], - dict(privilege=privilege1) - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - privilege=[(u'%s' % privilege1, u'This entry is not a member'),], - ), - ), - result={ - 'dn': role1_dn, - 'cn': [role1], - 'description': [u'New desc 1'], - 'objectclass': objectclasses.role, - } - ), - ), - - - - dict( - desc='Delete %r' % role1, - command=('role_del', [role1], {}), - expected=dict( - result=dict(failed=u''), - value=role1, - summary=u'Deleted role "%s"' % role1, - ) - ), - - - dict( - desc='Try to delete non-existent %r' % role1, - command=('role_del', [role1], {}), - expected=errors.NotFound(reason=u'%s: role not found' % role1), - ), - - - dict( - desc='Try to show non-existent %r' % role1, - command=('role_show', [role1], {}), - expected=errors.NotFound(reason=u'%s: role not found' % role1), - ), - - - dict( - desc='Try to update non-existent %r' % role1, - command=('role_mod', [role1], dict(description=u'Foo')), - expected=errors.NotFound(reason=u'%s: role not found' % role1), - ), - - - dict( - desc='Search for %r' % search, - command=('role_find', [search], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 role matched', - result=[ - { - 'dn': role2_dn, - 'cn': [role2], - 'description': [u'role desc 2'], - }, - ], - ), - ), - - - dict( - desc='Delete %r' % role2, - command=('role_del', [role2], {}), - expected=dict( - result=dict(failed=u''), - value=role2, - summary=u'Deleted role "%s"' % role2, - ) - ), - - - dict( - desc='Search for %r' % search, - command=('role_find', [search], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 roles matched', - result=[], - ), - ), - - ] diff --git a/tests/test_xmlrpc/test_selfservice_plugin.py b/tests/test_xmlrpc/test_selfservice_plugin.py deleted file mode 100644 index fa67cbc2d..000000000 --- a/tests/test_xmlrpc/test_selfservice_plugin.py +++ /dev/null @@ -1,290 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/selfservice.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid - -selfservice1 = u'testself' -invalid_selfservice1 = u'bad+name' - -class test_selfservice(Declarative): - - cleanup_commands = [ - ('selfservice_del', [selfservice1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % selfservice1, - command=('selfservice_show', [selfservice1], {}), - expected=errors.NotFound( - reason=u'ACI with name "%s" not found' % selfservice1), - ), - - - dict( - desc='Try to update non-existent %r' % selfservice1, - command=('selfservice_mod', [selfservice1], - dict(permissions=u'write')), - expected=errors.NotFound( - reason=u'ACI with name "%s" not found' % selfservice1), - ), - - - dict( - desc='Try to delete non-existent %r' % selfservice1, - command=('selfservice_del', [selfservice1], {}), - expected=errors.NotFound( - reason=u'ACI with name "%s" not found' % selfservice1), - ), - - - dict( - desc='Search for non-existent %r' % selfservice1, - command=('selfservice_find', [selfservice1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 selfservices matched', - result=[], - ), - ), - - - # Note that we add postalCode but expect postalcode. This tests - # the attrs normalizer. - dict( - desc='Create %r' % selfservice1, - command=( - 'selfservice_add', [selfservice1], dict( - attrs=[u'street', u'c', u'l', u'st', u'postalcode'], - permissions=u'write', - ) - ), - expected=dict( - value=selfservice1, - summary=u'Added selfservice "%s"' % selfservice1, - result=dict( - attrs=[u'street', u'c', u'l', u'st', u'postalcode'], - permissions=[u'write'], - selfaci=True, - aciname=selfservice1, - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % selfservice1, - command=( - 'selfservice_add', [selfservice1], dict( - attrs=[u'street', u'c', u'l', u'st', u'postalcode'], - permissions=u'write', - ), - ), - expected=errors.DuplicateEntry(), - ), - - - dict( - desc='Retrieve %r' % selfservice1, - command=('selfservice_show', [selfservice1], {}), - expected=dict( - value=selfservice1, - summary=None, - result={ - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'write'], - 'selfaci': True, - 'aciname': selfservice1, - }, - ), - ), - - - dict( - desc='Retrieve %r with --raw' % selfservice1, - command=('selfservice_show', [selfservice1], {'raw':True}), - expected=dict( - value=selfservice1, - summary=None, - result={ - 'aci': u'(targetattr = "street || c || l || st || postalcode")(version 3.0;acl "selfservice:testself";allow (write) userdn = "ldap:///self";)', - }, - ), - ), - - - dict( - desc='Search for %r' % selfservice1, - command=('selfservice_find', [selfservice1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 selfservice matched', - result=[ - { - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'write'], - 'selfaci': True, - 'aciname': selfservice1, - }, - ], - ), - ), - - dict( - desc='Search for %r with --pkey-only' % selfservice1, - command=('selfservice_find', [selfservice1], {'pkey_only' : True}), - expected=dict( - count=1, - truncated=False, - summary=u'1 selfservice matched', - result=[ - { - 'aciname': selfservice1, - }, - ], - ), - ), - - - dict( - desc='Search for %r with empty attrs and permissions' % selfservice1, - command=('selfservice_find', [selfservice1], {'attrs' : None, 'permissions' : None}), - expected=dict( - count=1, - truncated=False, - summary=u'1 selfservice matched', - result=[ - { - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'write'], - 'selfaci': True, - 'aciname': selfservice1, - }, - ], - ), - ), - - - dict( - desc='Search for %r with --raw' % selfservice1, - command=('selfservice_find', [selfservice1], {'raw':True}), - expected=dict( - count=1, - truncated=False, - summary=u'1 selfservice matched', - result=[ - { - 'aci': u'(targetattr = "street || c || l || st || postalcode")(version 3.0;acl "selfservice:testself";allow (write) userdn = "ldap:///self";)' - }, - ], - ), - ), - - - dict( - desc='Update %r' % selfservice1, - command=( - 'selfservice_mod', [selfservice1], dict(permissions=u'read') - ), - expected=dict( - value=selfservice1, - summary=u'Modified selfservice "%s"' % selfservice1, - result=dict( - attrs=[u'street', u'c', u'l', u'st', u'postalcode'], - permissions=[u'read'], - selfaci=True, - aciname=selfservice1, - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % selfservice1, - command=('selfservice_show', [selfservice1], {}), - expected=dict( - value=selfservice1, - summary=None, - result={ - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'read'], - 'selfaci': True, - 'aciname': selfservice1, - }, - ), - ), - - - dict( - desc='Try to update %r with empty permissions' % selfservice1, - command=( - 'selfservice_mod', [selfservice1], dict(permissions=None) - ), - expected=errors.RequirementError(name='permissions'), - ), - - - dict( - desc='Retrieve %r to verify invalid update' % selfservice1, - command=('selfservice_show', [selfservice1], {}), - expected=dict( - value=selfservice1, - summary=None, - result={ - 'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], - 'permissions': [u'read'], - 'selfaci': True, - 'aciname': selfservice1, - }, - ), - ), - - - dict( - desc='Delete %r' % selfservice1, - command=('selfservice_del', [selfservice1], {}), - expected=dict( - result=True, - value=selfservice1, - summary=u'Deleted selfservice "%s"' % selfservice1, - ) - ), - - dict( - desc='Create invalid %r' % invalid_selfservice1, - command=( - 'selfservice_add', [invalid_selfservice1], dict( - attrs=[u'street', u'c', u'l', u'st', u'postalcode'], - permissions=u'write', - ) - ), - expected=errors.ValidationError(name='name', - error='May only contain letters, numbers, -, _, and space'), - ), - - ] diff --git a/tests/test_xmlrpc/test_selinuxusermap_plugin.py b/tests/test_xmlrpc/test_selinuxusermap_plugin.py deleted file mode 100644 index ad3cb3465..000000000 --- a/tests/test_xmlrpc/test_selinuxusermap_plugin.py +++ /dev/null @@ -1,934 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2011 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/selinuxusermap.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid -from ipapython.dn import DN -from tests.util import Fuzzy - -rule1 = u'selinuxrule1' -selinuxuser1 = u'guest_u:s0' -selinuxuser2 = u'xguest_u:s0' - -user1 = u'tuser1' -group1 = u'testgroup1' -host1 = u'testhost1.%s' % api.env.domain -hostdn1 = DN(('fqdn', host1), ('cn', 'computers'), ('cn', 'accounts'), - api.env.basedn) -hbacrule1 = u'testhbacrule1' -hbacrule2 = u'testhbacrule12' - -# Note (?i) at the beginning of the regexp is the ingnore case flag -fuzzy_selinuxusermapdn = Fuzzy( - '(?i)ipauniqueid=[0-9a-f]{8}-[0-9a-f]{4}' - '-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12},%s,%s' - % (api.env.container_selinux, api.env.basedn) -) -fuzzy_hbacruledn = Fuzzy( - '(?i)ipauniqueid=[0-9a-f]{8}-[0-9a-f]{4}' - '-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12},%s,%s' - % (api.env.container_hbac, api.env.basedn) -) - -allow_all_rule_dn = api.Command['hbacrule_show'](u'allow_all')['result']['dn'] - - -class test_selinuxusermap(Declarative): - cleanup_commands = [ - ('selinuxusermap_del', [rule1], {}), - ('group_del', [group1], {}), - ('user_del', [user1], {}), - ('host_del', [host1], {}), - ('hbacrule_del', [hbacrule1], {}), - ('hbacrule_del', [hbacrule2], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % rule1, - command=('selinuxusermap_show', [rule1], {}), - expected=errors.NotFound( - reason=u'%s: SELinux User Map rule not found' % rule1), - ), - - - dict( - desc='Try to update non-existent %r' % rule1, - command=('selinuxusermap_mod', [rule1], dict(description=u'Foo')), - expected=errors.NotFound( - reason=u'%s: SELinux User Map rule not found' % rule1), - ), - - - dict( - desc='Try to delete non-existent %r' % rule1, - command=('selinuxusermap_del', [rule1], {}), - expected=errors.NotFound( - reason=u'%s: SELinux User Map rule not found' % rule1), - ), - - - dict( - desc='Create rule %r' % rule1, - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1) - ), - expected=dict( - value=rule1, - summary=u'Added SELinux User Map "%s"' % rule1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser1], - objectclass=objectclasses.selinuxusermap, - ipauniqueid=[fuzzy_uuid], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % rule1, - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1) - ), - expected=errors.DuplicateEntry(message=u'SELinux User Map rule ' + - u'with name "%s" already exists' % rule1), - ), - - - dict( - desc='Retrieve rule %r' % rule1, - command=('selinuxusermap_show', [rule1], {}), - expected=dict( - value=rule1, - summary=None, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser1], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - ), - ), - - - dict( - desc='Update rule %r' % rule1, - command=( - 'selinuxusermap_mod', [rule1], - dict(ipaselinuxuser=selinuxuser2) - ), - expected=dict( - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - ), - summary=u'Modified SELinux User Map "%s"' % rule1, - value=rule1, - ), - ), - - - dict( - desc='Retrieve %r to verify update' % rule1, - command=('selinuxusermap_show', [rule1], {}), - expected=dict( - value=rule1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - summary=None, - ), - ), - - - dict( - desc='Search for rule %r' % rule1, - command=('selinuxusermap_find', [], dict(cn=rule1)), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - ], - summary=u'1 SELinux User Map matched', - ), - ), - - - ############### - # Create additional entries needed for testing - dict( - desc='Create %r' % user1, - command=( - 'user_add', [], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/%s' % user1], - krbprincipalname=[u'%s@%s' % (user1, api.env.realm)], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn', 'global_policy'), - ('cn', api.env.realm), - ('cn', 'kerberos'), - api.env.basedn) - ], - mepmanagedentry=[DN(('cn', user1), ('cn', 'groups'), - ('cn', 'accounts'), api.env.basedn)], - memberof_group=[u'ipausers'], - dn=DN(('uid', user1), ('cn', 'users'), ('cn', 'accounts'), - api.env.basedn), - has_keytab=False, - has_password=False, - ), - ), - ), - - dict( - desc='Create group %r' % group1, - command=( - 'group_add', [group1], dict(description=u'Test desc 1') - ), - expected=dict( - value=group1, - summary=u'Added group "%s"' % group1, - result=dict( - cn=[group1], - description=[u'Test desc 1'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), - api.env.basedn), - ), - ), - ), - - - dict( - desc='Add member %r to %r' % (user1, group1), - command=( - 'group_add_member', [group1], dict(user=user1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': DN(('cn', group1), ('cn', 'groups'), - ('cn', 'accounts'), api.env.basedn), - 'member_user': (user1,), - 'gidnumber': [fuzzy_digits], - 'cn': [group1], - 'description': [u'Test desc 1'], - }, - ), - ), - - - dict( - desc='Create host %r' % host1, - command=('host_add', [host1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=host1, - summary=u'Added host "%s"' % host1, - result=dict( - dn=hostdn1, - fqdn=[host1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (host1, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[host1], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Create HBAC rule %r' % hbacrule1, - command=( - 'hbacrule_add', [hbacrule1], {} - ), - expected=dict( - value=hbacrule1, - summary=u'Added HBAC rule "%s"' % hbacrule1, - result=dict( - cn=[hbacrule1], - objectclass=objectclasses.hbacrule, - ipauniqueid=[fuzzy_uuid], - accessruletype=[u'allow'], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_hbacruledn, - ), - ), - ), - - - dict( - desc='Create HBAC rule %r' % hbacrule2, - command=( - 'hbacrule_add', [hbacrule2], {} - ), - expected=dict( - value=hbacrule2, - summary=u'Added HBAC rule "%s"' % hbacrule2, - result=dict( - cn=[hbacrule2], - objectclass=objectclasses.hbacrule, - ipauniqueid=[fuzzy_uuid], - accessruletype=[u'allow'], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_hbacruledn, - ), - ), - ), - - - ############### - # Fill out rule with members and/or pointers to HBAC rules - dict( - desc='Add user to %r' % rule1, - command=('selinuxusermap_add_user', [rule1], dict(user=user1)), - expected=dict( - failed=dict(memberuser=dict(group=[], user=[])), - completed=1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - memberuser_user=[user1], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - dict( - desc='Add non-existent user to %r' % rule1, - command=('selinuxusermap_add_user', [rule1], - dict(user=u'notfound')), - expected=dict( - failed=dict( - memberuser=dict(group=[], - user=[(u'notfound', u'no such entry')]) - ), - completed=0, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - memberuser_user=[user1], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - dict( - desc='Remove user from %r' % rule1, - command=('selinuxusermap_remove_user', [rule1], dict(user=user1)), - expected=dict( - failed=dict(memberuser=dict(group=[], user=[])), - completed=1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - dict( - desc='Remove non-existent user to %r' % rule1, - command=('selinuxusermap_remove_user', [rule1], - dict(user=u'notfound')), - expected=dict( - failed=dict( - memberuser=dict(group=[], - user=[(u'notfound', u'This entry is not a member')] - ) - ), - completed=0, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - dict( - desc='Add group to %r' % rule1, - command=('selinuxusermap_add_user', [rule1], dict(group=group1)), - expected=dict( - failed=dict(memberuser=dict(group=[], user=[])), - completed=1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - memberuser_group=[group1], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - dict( - desc='Add host to %r' % rule1, - command=('selinuxusermap_add_host', [rule1], dict(host=host1)), - expected=dict( - failed=dict(memberhost=dict(hostgroup=[], host=[])), - completed=1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - memberhost_host=[host1], - memberuser_group=[group1], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - ############### - # Test enabling and disabling - dict( - desc='Disable %r' % rule1, - command=('selinuxusermap_disable', [rule1], {}), - expected=dict( - result=True, - value=rule1, - summary=u'Disabled SELinux User Map "%s"' % rule1, - ) - ), - - - dict( - desc='Disable %r again' % rule1, - command=('selinuxusermap_disable', [rule1], {}), - expected=errors.AlreadyInactive(), - ), - - - dict( - desc='Enable %r' % rule1, - command=('selinuxusermap_enable', [rule1], {}), - expected=dict( - result=True, - value=rule1, - summary=u'Enabled SELinux User Map "%s"' % rule1, - ) - ), - - - dict( - desc='Re-enable %r again' % rule1, - command=('selinuxusermap_enable', [rule1], {}), - expected=errors.AlreadyActive(), - ), - - - # Point to an HBAC Rule - dict( - desc='Add an HBAC rule to %r that has other members' % rule1, - command=( - 'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1) - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - - dict( - desc='Remove host from %r' % rule1, - command=('selinuxusermap_remove_host', [rule1], dict(host=host1)), - expected=dict( - failed=dict(memberhost=dict(hostgroup=[], host=[])), - completed=1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - memberuser_group=[group1], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - dict( - desc='Remove group from %r' % rule1, - command=('selinuxusermap_remove_user', [rule1], - dict(group=group1)), - expected=dict( - failed=dict(memberuser=dict(group=[], user=[])), - completed=1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - ) - ), - - - dict( - desc='Add non-existent HBAC rule to %r' % rule1, - command=( - 'selinuxusermap_mod', [rule1], dict(seealso=u'notfound') - ), - expected=errors.NotFound( - reason=u'HBAC rule notfound not found'), - ), - - - dict( - desc='Add an HBAC rule to %r' % rule1, - command=( - 'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1) - ), - expected=dict( - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser2], - ipaenabledflag=[u'TRUE'], - seealso=hbacrule1, - ), - summary=u'Modified SELinux User Map "%s"' % rule1, - value=rule1, - ), - ), - - - dict( - desc='Add user to %r that has HBAC' % rule1, - command=('selinuxusermap_add_user', [rule1], dict(user=user1)), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - - dict( - desc='Add host to %r that has HBAC' % rule1, - command=('selinuxusermap_add_host', [rule1], dict(host=host1)), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - - dict( - desc='Try to delete HBAC rule pointed to by %r' % rule1, - command=('hbacrule_del', [hbacrule1], {}), - expected=errors.DependentEntry(key=hbacrule1, - label=u'SELinux User Map', dependent=rule1) - ), - - - # This tests selinuxusermap-find --hbacrule= returns an - # exact match - dict( - desc='Try to delete similarly named HBAC rule %r' % hbacrule2, - command=('hbacrule_del', [hbacrule2], {}), - expected=dict( - result=dict(failed=u''), - value=hbacrule2, - summary=u'Deleted HBAC rule "%s"' % hbacrule2, - ) - ), - - - # Test clean up - dict( - desc='Delete %r' % rule1, - command=('selinuxusermap_del', [rule1], {}), - expected=dict( - result=dict(failed=u''), - value=rule1, - summary=u'Deleted SELinux User Map "%s"' % rule1, - ) - ), - - - dict( - desc='Try to delete non-existent %r' % rule1, - command=('selinuxusermap_del', [rule1], {}), - expected=errors.NotFound( - reason=u'%s: SELinux User Map rule not found' % rule1), - ), - - - # Some negative tests - dict( - desc='Create rule with unknown user %r' % rule1, - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=u'notfound:s0:c0') - ), - expected=errors.NotFound(reason=u'SELinux user notfound:s0:c0 ' + - u'not found in ordering list (in config)'), - ), - - - dict( - desc='Create rule with invalid user bad+user', - command=( - 'selinuxusermap_add', [rule1], dict(ipaselinuxuser=u'bad+user') - ), - expected=errors.ValidationError(name='selinuxuser', - error=u'Invalid SELinux user name, only a-Z and _ are allowed' - ), - ), - - - dict( - desc='Create rule with invalid MCS xguest_u:s999', - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=u'xguest_u:s999') - ), - expected=errors.ValidationError(name='selinuxuser', - error=u'Invalid MLS value, must match s[0-15](-s[0-15])'), - ), - - - dict( - desc='Create rule with invalid MLS xguest_u:s0:p88', - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=u'xguest_u:s0:p88') - ), - expected=errors.ValidationError(name='selinuxuser', - error=u'Invalid MCS value, must match c[0-1023].c[0-1023] ' + - u'and/or c[0-1023]-c[0-c0123]'), - ), - - - dict( - desc='Create rule with invalid MLS xguest_u:s0:c0.c1028', - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=u'xguest_u:s0-s0:c0.c1028') - ), - expected=errors.ValidationError(name='selinuxuser', - error=u'Invalid MCS value, must match c[0-1023].c[0-1023] ' + - u'and/or c[0-1023]-c[0-c0123]'), - ), - - - dict( - desc='Create rule with invalid user via setattr', - command=( - 'selinuxusermap_mod', [rule1], - dict(setattr=u'ipaselinuxuser=deny') - ), - expected=errors.ValidationError(name='ipaselinuxuser', - error=u'Invalid MLS value, must match s[0-15](-s[0-15])'), - ), - - dict( - desc='Create rule with both --hbacrule and --usercat set', - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1, - seealso=hbacrule1, - usercategory=u'all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Create rule with both --hbacrule and --hostcat set', - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1, - seealso=hbacrule1, - hostcategory=u'all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Create rule with both --hbacrule ' - 'and --usercat set via setattr', - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1, - seealso=hbacrule1, - setattr=u'usercategory=all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Create rule with both --hbacrule ' - 'and --hostcat set via setattr', - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1, - seealso=hbacrule1, - setattr=u'hostcategory=all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Create rule %r with --hbacrule' % rule1, - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1, seealso=hbacrule1) - ), - expected=dict( - value=rule1, - summary=u'Added SELinux User Map "%s"' % rule1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser1], - objectclass=objectclasses.selinuxusermap, - ipauniqueid=[fuzzy_uuid], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - seealso=hbacrule1 - ), - ), - ), - - dict( - desc='Add an --usercat to %r that has HBAC set' % rule1, - command=( - 'selinuxusermap_mod', [rule1], dict(usercategory=u'all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Add an --hostcat to %r that has HBAC set' % rule1, - command=( - 'selinuxusermap_mod', [rule1], dict(hostcategory=u'all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Add an usercat via setattr to %r that has HBAC set' % rule1, - command=( - 'selinuxusermap_mod', [rule1], - dict(setattr=u'usercategory=all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Add an hostcat via setattr to %r that has HBAC set' % rule1, - command=( - 'selinuxusermap_mod', [rule1], - dict(setattr=u'hostcategory=all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Delete %r' % rule1, - command=('selinuxusermap_del', [rule1], {}), - expected=dict( - result=dict(failed=u''), - value=rule1, - summary=u'Deleted SELinux User Map "%s"' % rule1, - ) - ), - - dict( - desc='Create rule %r with usercat and hostcat set' % rule1, - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1, - usercategory=u'all', - hostcategory=u'all') - ), - expected=dict( - value=rule1, - summary=u'Added SELinux User Map "%s"' % rule1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser1], - objectclass=objectclasses.selinuxusermap, - ipauniqueid=[fuzzy_uuid], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - usercategory=[u'all'], - hostcategory=[u'all'] - ), - ), - ), - - dict( - desc='Add HBAC rule to %r that has usercat and hostcat' % rule1, - command=( - 'selinuxusermap_mod', [rule1], dict(seealso=hbacrule1) - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Delete %r' % rule1, - command=('selinuxusermap_del', [rule1], {}), - expected=dict( - result=dict(failed=u''), - value=rule1, - summary=u'Deleted SELinux User Map "%s"' % rule1, - ) - ), - - dict( - desc='Create rule %r' % rule1, - command=( - 'selinuxusermap_add', [rule1], - dict(ipaselinuxuser=selinuxuser1) - ), - expected=dict( - value=rule1, - summary=u'Added SELinux User Map "%s"' % rule1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser1], - objectclass=objectclasses.selinuxusermap, - ipauniqueid=[fuzzy_uuid], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - ), - ), - ), - - dict( - desc='Add HBAC rule, hostcat and usercat to %r' % rule1, - command=( - 'selinuxusermap_mod', [rule1], - dict(seealso=hbacrule1, - usercategory=u'all', - hostcategory=u'all') - ), - expected=errors.MutuallyExclusiveError( - reason=u'HBAC rule and local members cannot both be set'), - ), - - dict( - desc='Delete %r' % rule1, - command=('selinuxusermap_del', [rule1], {}), - expected=dict( - result=dict(failed=u''), - value=rule1, - summary=u'Deleted SELinux User Map "%s"' % rule1, - ) - ), - - dict( - desc='Create rule %r with ' - '--setattr=seealso=' % rule1, - command=( - 'selinuxusermap_add', - [rule1], - dict(ipaselinuxuser=selinuxuser1, - setattr=u'seealso=%s' % allow_all_rule_dn) - ), - expected=dict( - value=rule1, - summary=u'Added SELinux User Map "%s"' % rule1, - result=dict( - cn=[rule1], - ipaselinuxuser=[selinuxuser1], - objectclass=objectclasses.selinuxusermap, - ipauniqueid=[fuzzy_uuid], - ipaenabledflag=[u'TRUE'], - dn=fuzzy_selinuxusermapdn, - seealso=u'allow_all', - ), - ), - ), - - dict( - desc='Delete %r' % rule1, - command=('selinuxusermap_del', [rule1], {}), - expected=dict( - result=dict(failed=u''), - value=rule1, - summary=u'Deleted SELinux User Map "%s"' % rule1, - ) - ), - ] diff --git a/tests/test_xmlrpc/test_service_plugin.py b/tests/test_xmlrpc/test_service_plugin.py deleted file mode 100644 index 6f8dbbee7..000000000 --- a/tests/test_xmlrpc/test_service_plugin.py +++ /dev/null @@ -1,632 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/service.py` module. -""" - -from ipalib import api, errors, x509 -from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_hash -from tests.test_xmlrpc.xmlrpc_test import fuzzy_digits, fuzzy_date, fuzzy_issuer -from tests.test_xmlrpc.xmlrpc_test import fuzzy_hex -from tests.test_xmlrpc import objectclasses -import base64 -from ipapython.dn import DN - -fqdn1 = u'testhost1.%s' % api.env.domain -fqdn2 = u'testhost2.%s' % api.env.domain -fqdn3 = u'TestHost3.%s' % api.env.domain -service1 = u'HTTP/%s@%s' % (fqdn1, api.env.realm) -hostprincipal1 = u'host/%s@%s' % (fqdn1, api.env.realm) -service1dn = DN(('krbprincipalname',service1),('cn','services'),('cn','accounts'),api.env.basedn) -host1dn = DN(('fqdn',fqdn1),('cn','computers'),('cn','accounts'),api.env.basedn) -host2dn = DN(('fqdn',fqdn2),('cn','computers'),('cn','accounts'),api.env.basedn) -host3dn = DN(('fqdn',fqdn3),('cn','computers'),('cn','accounts'),api.env.basedn) - -fd = open('tests/test_xmlrpc/service.crt', 'r') -servercert = fd.readlines() -servercert = ''.join(servercert) -servercert = x509.strip_header(servercert) -fd.close() - -badservercert = 'MIICbzCCAdigAwIBAgICA/4wDQYJKoZIhvcNAQEFBQAwKTEnMCUGA1UEAxMeSVBBIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDgwOTE1MDIyN1oXDTIwMDgwOTE1MDIyN1owKTEMMAoGA1UEChMDSVBBMRkwFwYDVQQDExBwdW1hLmdyZXlvYWsuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwYbfEOQPgGenPn9vt1JFKvWm/Je3y2tawGWA3LXDuqfFJyYtZ8ib3TcBUOnLk9WK5g2qCwHaNlei7bj8ggIfr5hegAVe10cun+wYErjnYo7hsHYd+57VZezeipWrXu+7NoNd4+c4A5lk4A/xJay9j3bYx2oOM8BEox4xWYoWge1ljPrc5JK46f0X7AGW4F2VhnKPnf8rwSuzI1U8VGjutyM9TWNy3m9KMWeScjyG/ggIpOjUDMV7HkJL0Di61lznR9jXubpiEC7gWGbTp84eGl/Nn9bgK1AwHfJ2lHwfoY4uiL7ge1gyP6EvuUlHoBzdb7pekiX28iePjW3iEG9IawIDAQABoyIwIDARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4GBACRESLemRV9BPxfEgbALuxH5oE8jQm8WZ3pm2pALbpDlAd9wQc3yVf6RtkfVthyDnM18bg7IhxKpd77/p3H8eCnS8w5MLVRda6ktUC6tGhFTS4QKAf0WyDGTcIgkXbeDw0OPAoNHivoXbIXIIRxlw/XgaSaMzJQDBG8iROsN4kCv' - - -class test_service(Declarative): - - cleanup_commands = [ - ('host_del', [fqdn1], {}), - ('host_del', [fqdn2], {}), - ('host_del', [fqdn3], {}), - ('service_del', [service1], {}), - ] - - tests = [ - dict( - desc='Try to retrieve non-existent %r' % service1, - command=('service_show', [service1], {}), - expected=errors.NotFound( - reason=u'%s: service not found' % service1), - ), - - - dict( - desc='Try to update non-existent %r' % service1, - command=('service_mod', [service1], dict(usercertificate=servercert)), - expected=errors.NotFound( - reason=u'%s: service not found' % service1), - ), - - - dict( - desc='Try to delete non-existent %r' % service1, - command=('service_del', [service1], {}), - expected=errors.NotFound( - reason=u'%s: service not found' % service1), - ), - - - dict( - desc='Create %r' % fqdn1, - command=('host_add', [fqdn1], - dict( - description=u'Test host 1', - l=u'Undisclosed location 1', - force=True, - ), - ), - expected=dict( - value=fqdn1, - summary=u'Added host "%s"' % fqdn1, - result=dict( - dn=host1dn, - fqdn=[fqdn1], - description=[u'Test host 1'], - l=[u'Undisclosed location 1'], - krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[u'%s' % fqdn1], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Create %r' % fqdn2, - command=('host_add', [fqdn2], - dict( - description=u'Test host 2', - l=u'Undisclosed location 2', - force=True, - ), - ), - expected=dict( - value=fqdn2, - summary=u'Added host "%s"' % fqdn2, - result=dict( - dn=host2dn, - fqdn=[fqdn2], - description=[u'Test host 2'], - l=[u'Undisclosed location 2'], - krbprincipalname=[u'host/%s@%s' % (fqdn2, api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[u'%s' % fqdn2], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Create %r' % fqdn3, - command=('host_add', [fqdn3], - dict( - description=u'Test host 3', - l=u'Undisclosed location 3', - force=True, - ), - ), - expected=dict( - value=fqdn3.lower(), - summary=u'Added host "%s"' % fqdn3.lower(), - result=dict( - dn=host3dn, - fqdn=[fqdn3.lower()], - description=[u'Test host 3'], - l=[u'Undisclosed location 3'], - krbprincipalname=[u'host/%s@%s' % (fqdn3.lower(), api.env.realm)], - objectclass=objectclasses.host, - ipauniqueid=[fuzzy_uuid], - managedby_host=[u'%s' % fqdn3.lower()], - has_keytab=False, - has_password=False, - ), - ), - ), - - - dict( - desc='Create %r' % service1, - command=('service_add', [service1], - dict( - force=True, - ), - ), - expected=dict( - value=service1, - summary=u'Added service "%s"' % service1, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - objectclass=objectclasses.service, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn1], - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % service1, - command=('service_add', [service1], - dict( - force=True, - ), - ), - expected=errors.DuplicateEntry( - message=u'service with name "%s" already exists' % service1), - ), - - - dict( - desc='Retrieve %r' % service1, - command=('service_show', [service1], {}), - expected=dict( - value=service1, - summary=None, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - has_keytab=False, - managedby_host=[fqdn1], - ), - ), - ), - - - dict( - desc='Retrieve %r with all=True' % service1, - command=('service_show', [service1], dict(all=True)), - expected=dict( - value=service1, - summary=None, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - ipakrbprincipalalias=[service1], - objectclass=objectclasses.service, - ipauniqueid=[fuzzy_uuid], - managedby_host=[fqdn1], - has_keytab=False, - ipakrbrequirespreauth=True, - ipakrbokasdelegate=False, - ), - ), - ), - - - dict( - desc='Search for %r' % service1, - command=('service_find', [service1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 service matched', - result=[ - dict( - dn=service1dn, - krbprincipalname=[service1], - managedby_host=[fqdn1], - has_keytab=False, - ), - ], - ), - ), - - - dict( - desc='Search for %r with all=True' % service1, - command=('service_find', [service1], dict(all=True)), - expected=dict( - count=1, - truncated=False, - summary=u'1 service matched', - result=[ - dict( - dn=service1dn, - krbprincipalname=[service1], - ipakrbprincipalalias=[service1], - objectclass=objectclasses.service, - ipauniqueid=[fuzzy_uuid], - has_keytab=False, - managedby_host=[fqdn1], - ipakrbrequirespreauth=True, - ipakrbokasdelegate=False, - ), - ], - ), - ), - - - dict( - desc='Add non-existent host to %r' % service1, - command=('service_add_host', [service1], dict(host=u'notfound')), - expected=dict( - failed=dict(managedby=dict(host=[(u'notfound', u'no such entry')])), - completed=0, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - managedby_host=[fqdn1], - ), - ), - ), - - - dict( - desc='Remove non-existent host from %r' % service1, - command=('service_remove_host', [service1], dict(host=u'notfound')), - expected=dict( - failed=dict(managedby=dict(host=[(u'notfound', u'This entry is not a member')])), - completed=0, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - managedby_host=[fqdn1], - ), - ), - ), - - - dict( - desc='Add host to %r' % service1, - command=('service_add_host', [service1], dict(host=fqdn2)), - expected=dict( - failed=dict(managedby=dict(host=[])), - completed=1, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - managedby_host=[fqdn1, fqdn2], - ), - ), - ), - - - dict( - desc='Remove host from %r' % service1, - command=('service_remove_host', [service1], dict(host=fqdn2)), - expected=dict( - failed=dict(managedby=dict(host=[])), - completed=1, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - managedby_host=[fqdn1], - ), - ), - ), - - - dict( - desc='Add mixed-case host to %r' % service1, - command=('service_add_host', [service1], dict(host=fqdn3)), - expected=dict( - failed=dict(managedby=dict(host=[])), - completed=1, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - managedby_host=[fqdn1, fqdn3.lower()], - ), - ), - ), - - - dict( - desc='Remove mixed-case host from %r' % service1, - command=('service_remove_host', [service1], dict(host=fqdn3)), - expected=dict( - failed=dict(managedby=dict(host=[])), - completed=1, - result=dict( - dn=service1dn, - krbprincipalname=[service1], - managedby_host=[fqdn1], - ), - ), - ), - - - dict( - desc='Update %r with a bad certificate' % service1, - command=('service_mod', [service1], dict(usercertificate=badservercert)), - expected=errors.CertificateOperationError( - error=u'Issuer "CN=IPA Test Certificate Authority" does not ' + - u'match the expected issuer'), - ), - - - dict( - desc='Update %r' % service1, - command=('service_mod', [service1], dict(usercertificate=servercert)), - expected=dict( - value=service1, - summary=u'Modified service "%s"' % service1, - result=dict( - usercertificate=[base64.b64decode(servercert)], - krbprincipalname=[service1], - managedby_host=[fqdn1], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - ), - ), - ), - - - dict( - desc='Try to update %r with invalid ipakrbauthz data ' - 'combination' % service1, - command=('service_mod', [service1], - dict(ipakrbauthzdata=[u'MS-PAC', u'NONE'])), - expected=errors.ValidationError(name='ipakrbauthzdata', - error=u'NONE value cannot be combined with other PAC types') - ), - - - dict( - desc='Update %r with valid ipakrbauthz data ' - 'combination' % service1, - command=('service_mod', [service1], - dict(ipakrbauthzdata=[u'MS-PAC'])), - expected=dict( - value=service1, - summary=u'Modified service "%s"' % service1, - result=dict( - usercertificate=[base64.b64decode(servercert)], - krbprincipalname=[service1], - managedby_host=[fqdn1], - ipakrbauthzdata=[u'MS-PAC'], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % service1, - command=('service_show', [service1], {}), - expected=dict( - value=service1, - summary=None, - result=dict( - dn=service1dn, - usercertificate=[base64.b64decode(servercert)], - krbprincipalname=[service1], - has_keytab=False, - managedby_host=[fqdn1], - ipakrbauthzdata=[u'MS-PAC'], - # These values come from the servercert that is in this - # test case. - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - ), - ), - ), - - - dict( - desc='Enable %r OK_AS_DELEGATE Kerberos ticket flag' % service1, - command=('service_mod', [service1], dict(ipakrbokasdelegate=True)), - expected=dict( - value=service1, - summary=u'Modified service "%s"' % service1, - result=dict( - usercertificate=[base64.b64decode(servercert)], - krbprincipalname=[service1], - managedby_host=[fqdn1], - ipakrbauthzdata=[u'MS-PAC'], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - krbticketflags=[u'1048704'], - ipakrbokasdelegate=True, - ), - ), - ), - - - dict( - desc='Update %r Kerberos ticket flags with setattr' % service1, - command=('service_mod', [service1], - dict(setattr=[u'krbTicketFlags=1048577'])), - expected=dict( - value=service1, - summary=u'Modified service "%s"' % service1, - result=dict( - usercertificate=[base64.b64decode(servercert)], - krbprincipalname=[service1], - managedby_host=[fqdn1], - ipakrbauthzdata=[u'MS-PAC'], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - krbticketflags=[u'1048577'], - ), - ), - ), - - - dict( - desc='Disable %r OK_AS_DELEGATE Kerberos ticket flag' % service1, - command=('service_mod', [service1], dict(ipakrbokasdelegate=False)), - expected=dict( - value=service1, - summary=u'Modified service "%s"' % service1, - result=dict( - usercertificate=[base64.b64decode(servercert)], - krbprincipalname=[service1], - managedby_host=[fqdn1], - ipakrbauthzdata=[u'MS-PAC'], - valid_not_before=fuzzy_date, - valid_not_after=fuzzy_date, - subject=DN(('CN',api.env.host),x509.subject_base()), - serial_number=fuzzy_digits, - serial_number_hex=fuzzy_hex, - md5_fingerprint=fuzzy_hash, - sha1_fingerprint=fuzzy_hash, - issuer=fuzzy_issuer, - krbticketflags=[u'1'], - ipakrbokasdelegate=False, - ), - ), - ), - - - dict( - desc='Delete %r' % service1, - command=('service_del', [service1], {}), - expected=dict( - value=service1, - summary=u'Deleted service "%s"' % service1, - result=dict(failed=u''), - ), - ), - - - dict( - desc='Try to retrieve non-existent %r' % service1, - command=('service_show', [service1], {}), - expected=errors.NotFound( - reason=u'%s: service not found' % service1), - ), - - - dict( - desc='Try to update non-existent %r' % service1, - command=('service_mod', [service1], dict(usercertificate=servercert)), - expected=errors.NotFound( - reason=u'%s: service not found' % service1), - ), - - - dict( - desc='Try to delete non-existent %r' % service1, - command=('service_del', [service1], {}), - expected=errors.NotFound( - reason=u'%s: service not found' % service1), - ), - - - dict( - desc='Create service with malformed principal "foo"', - command=('service_add', [u'foo'], {}), - expected=errors.MalformedServicePrincipal(reason='missing service') - ), - - - dict( - desc='Create service with bad realm "HTTP/foo@FOO.NET"', - command=('service_add', [u'HTTP/foo@FOO.NET'], {}), - expected=errors.RealmMismatch(), - ), - - - dict( - desc='Create a host service %r' % hostprincipal1, - command=('service_add', [hostprincipal1], {}), - expected=errors.HostService() - ), - - - # These tests will only succeed when running against lite-server.py - # on same box as IPA install. - dict( - desc='Delete the current host (master?) %s HTTP service, should be caught' % api.env.host, - command=('service_del', ['HTTP/%s' % api.env.host], {}), - expected=errors.ValidationError(name='principal', error='This principal is required by the IPA master'), - ), - - - dict( - desc='Delete the current host (master?) %s ldap service, should be caught' % api.env.host, - command=('service_del', ['ldap/%s' % api.env.host], {}), - expected=errors.ValidationError(name='principal', error='This principal is required by the IPA master'), - ), - - - dict( - desc='Disable the current host (master?) %s HTTP service, should be caught' % api.env.host, - command=('service_disable', ['HTTP/%s' % api.env.host], {}), - expected=errors.ValidationError(name='principal', error='This principal is required by the IPA master'), - ), - - - dict( - desc='Disable the current host (master?) %s ldap service, should be caught' % api.env.host, - command=('service_disable', ['ldap/%s' % api.env.host], {}), - expected=errors.ValidationError(name='principal', error='This principal is required by the IPA master'), - ), - - - ] diff --git a/tests/test_xmlrpc/test_sudocmd_plugin.py b/tests/test_xmlrpc/test_sudocmd_plugin.py deleted file mode 100644 index 7b355072b..000000000 --- a/tests/test_xmlrpc/test_sudocmd_plugin.py +++ /dev/null @@ -1,327 +0,0 @@ -# Authors: -# Jr Aquino -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/sudocmd.py` module. -""" - -from ipalib import errors -from tests.test_xmlrpc.xmlrpc_test import (Declarative, fuzzy_sudocmddn, - fuzzy_uuid) -from tests.test_xmlrpc import objectclasses - -sudocmd1 = u'/usr/bin/sudotestcmd1' -sudocmd1_camelcase = u'/usr/bin/sudoTestCmd1' - -sudorule1 = u'test_sudorule1' - - -class test_sudocmd(Declarative): - - cleanup_commands = [ - ('sudocmd_del', [sudocmd1], {}), - ('sudocmd_del', [sudocmd1_camelcase], {}), - ('sudorule_del', [sudorule1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Try to update non-existent %r' % sudocmd1, - command=('sudocmd_mod', [sudocmd1], dict(description=u'Nope')), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Try to delete non-existent %r' % sudocmd1, - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Create %r' % sudocmd1, - command=('sudocmd_add', [sudocmd1], - dict( - description=u'Test sudo command 1', - ), - ), - expected=dict( - value=sudocmd1, - summary=u'Added Sudo Command "%s"' % sudocmd1, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - objectclass=objectclasses.sudocmd, - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - dict( - desc='Create %r' % sudocmd1_camelcase, - command=('sudocmd_add', [sudocmd1_camelcase], - dict( - description=u'Test sudo command 2', - ), - ), - expected=dict( - value=sudocmd1_camelcase, - summary=u'Added Sudo Command "%s"' % sudocmd1_camelcase, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1_camelcase], - description=[u'Test sudo command 2'], - objectclass=objectclasses.sudocmd, - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % sudocmd1, - command=('sudocmd_add', [sudocmd1], - dict( - description=u'Test sudo command 1', - ), - ), - expected=errors.DuplicateEntry(message=u'sudo command with ' + - u'name "%s" already exists' % sudocmd1), - ), - - dict( - desc='Try to create duplicate %r' % sudocmd1_camelcase, - command=('sudocmd_add', [sudocmd1_camelcase], - dict( - description=u'Test sudo command 2', - ), - ), - expected=errors.DuplicateEntry(message=u'sudo command with ' + - u'name "%s" already exists' % sudocmd1_camelcase), - ), - - - dict( - desc='Retrieve %r' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=dict( - value=sudocmd1, - summary=None, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - ), - ), - ), - - - dict( - desc='Search for %r' % sudocmd1, - command=('sudocmd_find', [sudocmd1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 Sudo Command matched', - result=[ - dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - ), - ], - ), - ), - - dict( - desc='Search for %r' % sudocmd1_camelcase, - command=('sudocmd_find', [sudocmd1_camelcase], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 Sudo Command matched', - result=[ - dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1_camelcase], - description=[u'Test sudo command 2'], - ), - ], - ), - ), - - - dict( - desc='Update %r' % sudocmd1, - command=('sudocmd_mod', [sudocmd1], dict( - description=u'Updated sudo command 1')), - expected=dict( - value=sudocmd1, - summary=u'Modified Sudo Command "%s"' % sudocmd1, - result=dict( - sudocmd=[sudocmd1], - description=[u'Updated sudo command 1'], - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=dict( - value=sudocmd1, - summary=None, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Updated sudo command 1'], - ), - ), - ), - - dict( - desc='Create %r' % sudorule1, - command=('sudorule_add', [sudorule1], {}), - expected=lambda e, result: True, - ), - - dict( - desc='Add %r to %r allow list' % (sudocmd1, sudorule1), - command=('sudorule_add_allow_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1), - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.DependentEntry(key=sudocmd1, label='sudorule', - dependent=sudorule1), - ), - - dict( - desc='Remove %r from %r' % (sudocmd1, sudorule1), - command=('sudorule_remove_allow_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc='Add %r to %r deny list' % (sudocmd1, sudorule1), - command=('sudorule_add_deny_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1), - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.DependentEntry(key=sudocmd1, label='sudorule', - dependent=sudorule1), - ), - - dict( - desc='Remove %r from %r' % (sudocmd1, sudorule1), - command=('sudorule_remove_deny_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc='Delete %r' % sudocmd1, - command=('sudocmd_del', [sudocmd1], {}), - expected=dict( - value=sudocmd1, - summary=u'Deleted Sudo Command "%s"' % sudocmd1, - result=dict(failed=u''), - ), - ), - - - dict( - desc='Try to retrieve non-existent %r' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Try to update non-existent %r' % sudocmd1, - command=('sudocmd_mod', [sudocmd1], dict(description=u'Nope')), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Try to delete non-existent %r' % sudocmd1, - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - dict( - desc='Retrieve %r' % sudocmd1_camelcase, - command=('sudocmd_show', [sudocmd1_camelcase], {}), - expected=dict( - value=sudocmd1_camelcase, - summary=None, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1_camelcase], - description=[u'Test sudo command 2'], - ), - ), - ), - ] diff --git a/tests/test_xmlrpc/test_sudocmdgroup_plugin.py b/tests/test_xmlrpc/test_sudocmdgroup_plugin.py deleted file mode 100644 index 7d688dc32..000000000 --- a/tests/test_xmlrpc/test_sudocmdgroup_plugin.py +++ /dev/null @@ -1,693 +0,0 @@ -# Authors: -# Jr Aquino -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/sudocmdgroup.py` module. -""" - -from ipalib import api, errors -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_sudocmddn -from ipapython.dn import DN - -sudocmdgroup1 = u'testsudocmdgroup1' -sudocmdgroup2 = u'testsudocmdgroup2' -sudocmd1 = u'/usr/bin/sudotestcmd1' -sudocmd1_camelcase = u'/usr/bin/sudoTestCmd1' -sudocmd_plus = u'/bin/ls -l /lost+found/*' - -def create_command(sudocmd): - return dict( - desc='Create %r' % sudocmd, - command=( - 'sudocmd_add', [], dict(sudocmd=sudocmd, - description=u'Test sudo command') - ), - expected=dict( - value=sudocmd, - summary=u'Added Sudo Command "%s"' % sudocmd, - result=dict( - objectclass=objectclasses.sudocmd, - sudocmd=[sudocmd], - ipauniqueid=[fuzzy_uuid], description=[u'Test sudo command'], - dn=fuzzy_sudocmddn, - ), - ), - ) - -class test_sudocmdgroup(Declarative): - cleanup_commands = [ - ('sudocmdgroup_del', [sudocmdgroup1], {}), - ('sudocmdgroup_del', [sudocmdgroup2], {}), - ('sudocmd_del', [sudocmd1], {}), - ('sudocmd_del', [sudocmd1_camelcase], {}), - ('sudocmd_del', [sudocmd_plus], {}), - ] - - tests = [ - - ################ - # create sudo command - dict( - desc='Create %r' % sudocmd1, - command=( - 'sudocmd_add', [], dict(sudocmd=sudocmd1, description=u'Test sudo command 1') - ), - expected=dict( - value=sudocmd1, - summary=u'Added Sudo Command "%s"' % sudocmd1, - result=dict( - objectclass=objectclasses.sudocmd, - sudocmd=[u'/usr/bin/sudotestcmd1'], - ipauniqueid=[fuzzy_uuid], - description=[u'Test sudo command 1'], - dn=fuzzy_sudocmddn, - ), - ), - ), - - dict( - desc='Create %r' % sudocmd1_camelcase, - command=( - 'sudocmd_add', [], dict(sudocmd=sudocmd1_camelcase, description=u'Test sudo command 2') - ), - expected=dict( - value=sudocmd1_camelcase, - summary=u'Added Sudo Command "%s"' % sudocmd1_camelcase, - result=dict( - objectclass=objectclasses.sudocmd, - sudocmd=[u'/usr/bin/sudoTestCmd1'], - ipauniqueid=[fuzzy_uuid], - description=[u'Test sudo command 2'], - dn=fuzzy_sudocmddn, - ), - ), - ), - - dict( - desc='Verify the managed sudo command %r was created' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=dict( - value=sudocmd1, - summary=None, - result=dict( - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - dn=fuzzy_sudocmddn, - ), - ), - ), - - - ################ - # create sudo command group1: - dict( - desc='Try to retrieve non-existent %r' % sudocmdgroup1, - command=('sudocmdgroup_show', [sudocmdgroup1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup1), - ), - - - dict( - desc='Try to update non-existent %r' % sudocmdgroup1, - command=('sudocmdgroup_mod', [sudocmdgroup1], - dict(description=u'Foo')), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup1), - ), - - - dict( - desc='Try to delete non-existent %r' % sudocmdgroup1, - command=('sudocmdgroup_del', [sudocmdgroup1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup1), - ), - - - dict( - desc='Create %r' % sudocmdgroup1, - command=( - 'sudocmdgroup_add', [sudocmdgroup1], - dict(description=u'Test desc 1') - ), - expected=dict( - value=sudocmdgroup1, - summary=u'Added Sudo Command Group "testsudocmdgroup1"', - result=dict( - cn=[sudocmdgroup1], - description=[u'Test desc 1'], - objectclass=objectclasses.sudocmdgroup, - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn','testsudocmdgroup1'),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % sudocmdgroup1, - command=( - 'sudocmdgroup_add', [sudocmdgroup1], - dict(description=u'Test desc 1') - ), - expected=errors.DuplicateEntry(message=u'sudo command group ' + - u'with name "%s" already exists' % sudocmdgroup1), - ), - - - dict( - desc='Retrieve %r' % sudocmdgroup1, - command=('sudocmdgroup_show', [sudocmdgroup1], {}), - expected=dict( - value=sudocmdgroup1, - summary=None, - result=dict( - cn=[sudocmdgroup1], - description=[u'Test desc 1'], - dn=DN(('cn','testsudocmdgroup1'),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Updated %r' % sudocmdgroup1, - command=( - 'sudocmdgroup_mod', [sudocmdgroup1], - dict(description=u'New desc 1') - ), - expected=dict( - result=dict( - cn=[sudocmdgroup1], - description=[u'New desc 1'], - ), - summary=u'Modified Sudo Command Group "testsudocmdgroup1"', - value=sudocmdgroup1, - ), - ), - - - dict( - desc='Retrieve %r to verify update' % sudocmdgroup1, - command=('sudocmdgroup_show', [sudocmdgroup1], {}), - expected=dict( - value=sudocmdgroup1, - result=dict( - cn=[sudocmdgroup1], - description=[u'New desc 1'], - dn=DN(('cn','testsudocmdgroup1'),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - ), - summary=None, - ), - ), - - - dict( - desc='Search for %r' % sudocmdgroup1, - command=('sudocmdgroup_find', [], dict(cn=sudocmdgroup1)), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - dn=DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - cn=[sudocmdgroup1], - description=[u'New desc 1'], - ), - ], - summary=u'1 Sudo Command Group matched', - ), - ), - - - - ################ - # create sudocmdgroup2: - dict( - desc='Try to retrieve non-existent %r' % sudocmdgroup2, - command=('sudocmdgroup_show', [sudocmdgroup2], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup2), - ), - - - dict( - desc='Try to update non-existent %r' % sudocmdgroup2, - command=('sudocmdgroup_mod', [sudocmdgroup2], - dict(description=u'Foo')), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup2), - ), - - - dict( - desc='Try to delete non-existent %r' % sudocmdgroup2, - command=('sudocmdgroup_del', [sudocmdgroup2], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup2), - ), - - - dict( - desc='Create %r' % sudocmdgroup2, - command=( - 'sudocmdgroup_add', [sudocmdgroup2], - dict(description=u'Test desc 2') - ), - expected=dict( - value=sudocmdgroup2, - summary=u'Added Sudo Command Group "testsudocmdgroup2"', - result=dict( - cn=[sudocmdgroup2], - description=[u'Test desc 2'], - objectclass=objectclasses.sudocmdgroup, - ipauniqueid=[fuzzy_uuid], - dn=DN(('cn','testsudocmdgroup2'),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % sudocmdgroup2, - command=( - 'sudocmdgroup_add', [sudocmdgroup2], - dict(description=u'Test desc 2') - ), - expected=errors.DuplicateEntry( - message=u'sudo command group with name "%s" already exists' % - sudocmdgroup2), - ), - - - dict( - desc='Retrieve %r' % sudocmdgroup2, - command=('sudocmdgroup_show', [sudocmdgroup2], {}), - expected=dict( - value=sudocmdgroup2, - summary=None, - result=dict( - cn=[sudocmdgroup2], - description=[u'Test desc 2'], - dn=DN(('cn','testsudocmdgroup2'),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - ), - ), - ), - - - dict( - desc='Updated %r' % sudocmdgroup2, - command=( - 'sudocmdgroup_mod', [sudocmdgroup2], - dict(description=u'New desc 2') - ), - expected=dict( - result=dict( - cn=[sudocmdgroup2], - description=[u'New desc 2'], - ), - summary=u'Modified Sudo Command Group "testsudocmdgroup2"', - value=sudocmdgroup2, - ), - ), - - - dict( - desc='Retrieve %r to verify update' % sudocmdgroup2, - command=('sudocmdgroup_show', [sudocmdgroup2], {}), - expected=dict( - value=sudocmdgroup2, - result=dict( - cn=[sudocmdgroup2], - description=[u'New desc 2'], - dn=DN(('cn','testsudocmdgroup2'),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - ), - summary=None, - ), - ), - - - dict( - desc='Search for %r' % sudocmdgroup2, - command=('sudocmdgroup_find', [], dict(cn=sudocmdgroup2)), - expected=dict( - count=1, - truncated=False, - result=[ - dict( - dn=DN(('cn',sudocmdgroup2),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - cn=[sudocmdgroup2], - description=[u'New desc 2'], - ), - ], - summary=u'1 Sudo Command Group matched', - ), - ), - - - dict( - desc='Search for all sudocmdgroups', - command=('sudocmdgroup_find', [], {}), - expected=dict( - summary=u'2 Sudo Command Groups matched', - count=2, - truncated=False, - result=[ - dict( - dn=DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - cn=[sudocmdgroup1], - description=[u'New desc 1'], - ), - dict( - dn=DN(('cn',sudocmdgroup2),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - cn=[sudocmdgroup2], - description=[u'New desc 2'], - ), - ], - ), - ), - - - - ############### - # member stuff: - dict( - desc='Add member %r to %r' % (sudocmd1, sudocmdgroup1), - command=( - 'sudocmdgroup_add_member', [sudocmdgroup1], - dict(sudocmd=sudocmd1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - sudocmd=tuple(), - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'member_sudocmd': (sudocmd1,), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - desc='Retrieve %r to show membership' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=dict( - value=sudocmd1, - summary=None, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - memberof_sudocmdgroup=[u'testsudocmdgroup1'], - ), - ), - ), - - dict( - desc='Try to add non-existent member to %r' % sudocmdgroup1, - command=( - 'sudocmdgroup_add_member', [sudocmdgroup1], - dict(sudocmd=u'notfound') - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - sudocmd=[(u'notfound', u'no such entry')], - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'member_sudocmd': (u'/usr/bin/sudotestcmd1',), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - desc='Add member %r to %r' % (sudocmd1_camelcase, sudocmdgroup1), - command=( - 'sudocmdgroup_add_member', [sudocmdgroup1], - dict(sudocmd=sudocmd1_camelcase) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - sudocmd=tuple(), - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'member_sudocmd': (sudocmd1, sudocmd1_camelcase), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - desc='Remove member %r from %r' % (sudocmd1, sudocmdgroup1), - command=('sudocmdgroup_remove_member', - [sudocmdgroup1], dict(sudocmd=sudocmd1) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - sudocmd=tuple(), - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'member_sudocmd': (sudocmd1_camelcase,), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - desc='Remove member %r from %r' % (sudocmd1_camelcase, sudocmdgroup1), - command=('sudocmdgroup_remove_member', - [sudocmdgroup1], dict(sudocmd=sudocmd1_camelcase) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - sudocmd=tuple(), - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - # FIXME: Shouldn't this raise a NotFound instead? - desc='Try to remove non-existent member from %r' % sudocmdgroup1, - command=('sudocmdgroup_remove_member', - [sudocmdgroup1], dict(sudocmd=u'notfound') - ), - expected=dict( - completed=0, - failed=dict( - member=dict( - sudocmd=[(u'notfound', u'This entry is not a member')], - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - ################ - # test a command that needs DN escaping: - create_command(sudocmd_plus), - - dict( - desc='Add %r to %r' % (sudocmd_plus, sudocmdgroup1), - command=('sudocmdgroup_add_member', [sudocmdgroup1], - dict(sudocmd=sudocmd_plus) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - sudocmd=tuple(), - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'member_sudocmd': (sudocmd_plus,), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - dict( - desc='Remove %r from %r' % (sudocmd_plus, sudocmdgroup1), - command=('sudocmdgroup_remove_member', [sudocmdgroup1], - dict(sudocmd=sudocmd_plus) - ), - expected=dict( - completed=1, - failed=dict( - member=dict( - sudocmd=tuple(), - ), - ), - result={ - 'dn': DN(('cn',sudocmdgroup1),('cn','sudocmdgroups'), - ('cn','sudo'),api.env.basedn), - 'cn': [sudocmdgroup1], - 'description': [u'New desc 1'], - }, - ), - ), - - ################ - # delete sudocmdgroup1: - dict( - desc='Delete %r' % sudocmdgroup1, - command=('sudocmdgroup_del', [sudocmdgroup1], {}), - expected=dict( - result=dict(failed=u''), - value=sudocmdgroup1, - summary=u'Deleted Sudo Command Group "testsudocmdgroup1"', - ) - ), - - - dict( - desc='Try to delete non-existent %r' % sudocmdgroup1, - command=('sudocmdgroup_del', [sudocmdgroup1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup1), - ), - - - dict( - desc='Try to retrieve non-existent %r' % sudocmdgroup1, - command=('sudocmdgroup_show', [sudocmdgroup1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup1), - ), - - - dict( - desc='Try to update non-existent %r' % sudocmdgroup1, - command=('sudocmdgroup_mod', [sudocmdgroup1], - dict(description=u'Foo')), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup1), - ), - - - ################ - # delete sudocmdgroup2: - dict( - desc='Delete %r' % sudocmdgroup2, - command=('sudocmdgroup_del', [sudocmdgroup2], {}), - expected=dict( - result=dict(failed=u''), - value=sudocmdgroup2, - summary=u'Deleted Sudo Command Group "testsudocmdgroup2"', - ) - ), - - - dict( - desc='Try to delete non-existent %r' % sudocmdgroup2, - command=('sudocmdgroup_del', [sudocmdgroup2], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup2), - ), - - - dict( - desc='Try to retrieve non-existent %r' % sudocmdgroup2, - command=('sudocmdgroup_show', [sudocmdgroup2], {}), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup2), - ), - - - dict( - desc='Try to update non-existent %r' % sudocmdgroup2, - command=('sudocmdgroup_mod', [sudocmdgroup2], - dict(description=u'Foo')), - expected=errors.NotFound( - reason=u'%s: sudo command group not found' % sudocmdgroup2), - ), - - - ##### clean up test Command - - dict( - desc='Now delete the sudo command %r' % sudocmd1, - command=('sudocmd_del', [sudocmd1], {}), - expected=dict( - result=dict(failed=u''), - value=sudocmd1, - summary=u'Deleted Sudo Command "%s"' % sudocmd1, - ) - ), - - - dict( - desc='Verify that %r is really gone' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - ] diff --git a/tests/test_xmlrpc/test_sudorule_plugin.py b/tests/test_xmlrpc/test_sudorule_plugin.py deleted file mode 100644 index ec5d16d62..000000000 --- a/tests/test_xmlrpc/test_sudorule_plugin.py +++ /dev/null @@ -1,781 +0,0 @@ -# Authors: -# Jr Aquino -# Pavel Zuna -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/sudorule.py` module. -""" - -from nose.tools import raises, assert_raises # pylint: disable=E0611 - -from xmlrpc_test import XMLRPC_test, assert_attr_equal -from ipalib import api -from ipalib import errors - -class test_sudorule(XMLRPC_test): - """ - Test the `sudorule` plugin. - """ - rule_name = u'testing_sudorule1' - rule_name2 = u'testing_sudorule2' - rule_command = u'/usr/bin/testsudocmd1' - rule_desc = u'description' - rule_desc_mod = u'description modified' - - test_user = u'sudorule_test_user' - test_external_user = u'external_test_user' - test_group = u'sudorule_test_group' - test_external_group = u'external_test_group' - test_host = u'sudorule.testhost' - test_external_host = u'external.testhost' - test_hostgroup = u'sudorule_test_hostgroup' - test_sudoallowcmdgroup = u'sudorule_test_allowcmdgroup' - test_sudodenycmdgroup = u'sudorule_test_denycmdgroup' - test_command = u'/usr/bin/testsudocmd1' - test_denycommand = u'/usr/bin/testdenysudocmd1' - test_runasuser = u'manager' - test_runasgroup = u'manager' - test_category = u'all' - test_option = u'authenticate' - - test_invalid_user = u'+invalid#user' - test_invalid_host = u'+invalid&host.nonexist.com' - test_invalid_group = u'+invalid#group' - - def test_0_sudorule_add(self): - """ - Test adding a new Sudo rule using `xmlrpc.sudorule_add`. - """ - ret = self.failsafe_add(api.Object.sudorule, - self.rule_name, - description=self.rule_desc, - ) - entry = ret['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert_attr_equal(entry, 'description', self.rule_desc) - - @raises(errors.DuplicateEntry) - def test_1_sudorule_add(self): - """ - Test adding an duplicate Sudo rule using `xmlrpc.sudorule_add'. - """ - api.Command['sudorule_add']( - self.rule_name - ) - - def test_2_sudorule_show(self): - """ - Test displaying a Sudo rule using `xmlrpc.sudorule_show`. - """ - entry = api.Command['sudorule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert_attr_equal(entry, 'description', self.rule_desc) - - def test_3_sudorule_mod(self): - """ - Test modifying a Sudo rule using `xmlrpc.sudorule_mod`. - """ - ret = api.Command['sudorule_mod']( - self.rule_name, description=self.rule_desc_mod - ) - entry = ret['result'] - assert_attr_equal(entry, 'description', self.rule_desc_mod) - - def test_6_sudorule_find(self): - """ - Test searching for Sudo rules using `xmlrpc.sudorule_find`. - """ - ret = api.Command['sudorule_find']( - cn=self.rule_name, - description=self.rule_desc_mod - ) - assert ret['truncated'] is False - entries = ret['result'] - assert_attr_equal(entries[0], 'cn', self.rule_name) - assert_attr_equal(entries[0], 'description', self.rule_desc_mod) - - def test_7_sudorule_init_testing_data(self): - """ - Initialize data for more Sudo rule plugin testing. - """ - self.failsafe_add(api.Object.user, - self.test_user, givenname=u'first', sn=u'last' - ) - self.failsafe_add(api.Object.user, - self.test_runasuser, givenname=u'first', sn=u'last' - ) - self.failsafe_add(api.Object.group, - self.test_group, description=u'description' - ) - self.failsafe_add(api.Object.host, - self.test_host, force=True - ) - self.failsafe_add(api.Object.hostgroup, - self.test_hostgroup, description=u'description' - ) - self.failsafe_add(api.Object.sudocmdgroup, - self.test_sudoallowcmdgroup, description=u'desc' - ) - self.failsafe_add(api.Object.sudocmdgroup, - self.test_sudodenycmdgroup, description=u'desc' - ) - self.failsafe_add(api.Object.sudocmd, - self.test_command, description=u'desc' - ) - - def test_8_sudorule_add_user(self): - """ - Test adding user and group to Sudo rule using - `xmlrpc.sudorule_add_user`. - """ - ret = api.Command['sudorule_add_user']( - self.rule_name, user=self.test_user, group=self.test_group - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberuser' in failed - assert 'user' in failed['memberuser'] - assert not failed['memberuser']['user'] - assert 'group' in failed['memberuser'] - assert not failed['memberuser']['group'] - entry = ret['result'] - assert_attr_equal(entry, 'memberuser_user', self.test_user) - assert_attr_equal(entry, 'memberuser_group', self.test_group) - - def test_9_a_show_user(self): - """ - Test showing a user to verify Sudo rule membership - `xmlrpc.user_show`. - """ - ret = api.Command['user_show'](self.test_user, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_sudorule', self.rule_name) - - def test_9_b_show_group(self): - """ - Test showing a group to verify Sudo rule membership - `xmlrpc.group_show`. - """ - ret = api.Command['group_show'](self.test_group, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_sudorule', self.rule_name) - - def test_9_sudorule_remove_user(self): - """ - Test removing user and group from Sudo rule using - `xmlrpc.sudorule_remove_user'. - """ - ret = api.Command['sudorule_remove_user']( - self.rule_name, user=self.test_user, group=self.test_group - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberuser' in failed - assert 'user' in failed['memberuser'] - assert not failed['memberuser']['user'] - assert 'group' in failed['memberuser'] - assert not failed['memberuser']['group'] - entry = ret['result'] - assert 'memberuser_user' not in entry - assert 'memberuser_group' not in entry - - def test_a_sudorule_add_runasuser(self): - """ - Test adding run as user to Sudo rule using - `xmlrpc.sudorule_add_runasuser`. - """ - ret = api.Command['sudorule_add_runasuser']( - self.rule_name, user=self.test_runasuser - ) - assert ret['completed'] == 1 - failed = ret['failed'] - assert 'ipasudorunas' in failed - assert 'user' in failed['ipasudorunas'] - assert not failed['ipasudorunas']['user'] - entry = ret['result'] - assert_attr_equal(entry, 'ipasudorunas_user', self.test_runasuser) - - def test_a_sudorule_add_runasuser_invalid(self): - """ - Test adding run as invalid user to Sudo rule using - `xmlrpc.sudorule_add_runasuser`. - """ - try: - api.Command['sudorule_add_runasuser']( - self.rule_name, user=self.test_invalid_user - ) - except errors.ValidationError: - pass - else: - assert False - - def test_b_sudorule_remove_runasuser(self): - """ - Test removing run as user to Sudo rule using - `xmlrpc.sudorule_remove_runasuser'. - """ - ret = api.Command['sudorule_remove_runasuser']( - self.rule_name, user=self.test_runasuser - ) - assert ret['completed'] == 1 - failed = ret['failed'] - assert 'ipasudorunas' in failed - assert 'user' in failed['ipasudorunas'] - assert not failed['ipasudorunas']['user'] - entry = ret['result'] - assert 'ipasudorunas_user' not in entry - - def test_a_sudorule_add_runasgroup(self): - """ - Test adding run as group to Sudo rule using - `xmlrpc.sudorule_add_runasgroup`. - """ - ret = api.Command['sudorule_add_runasgroup']( - self.rule_name, group=self.test_runasgroup - ) - assert ret['completed'] == 1 - failed = ret['failed'] - assert 'ipasudorunasgroup' in failed - assert 'group' in failed['ipasudorunasgroup'] - assert not failed['ipasudorunasgroup']['group'] - entry = ret['result'] - assert_attr_equal(entry, 'ipasudorunasgroup_group', - self.test_runasgroup) - - def test_a_sudorule_add_runasgroup_invalid(self): - """ - Test adding run as invalid user to Sudo rule using - `xmlrpc.sudorule_add_runasuser`. - """ - try: - api.Command['sudorule_add_runasgroup']( - self.rule_name, group=self.test_invalid_group - ) - except errors.ValidationError: - pass - else: - assert False - - def test_b_sudorule_remove_runasgroup(self): - """ - Test removing run as group to Sudo rule using - `xmlrpc.sudorule_remove_runasgroup'. - """ - ret = api.Command['sudorule_remove_runasgroup']( - self.rule_name, group=self.test_runasgroup - ) - assert ret['completed'] == 1 - failed = ret['failed'] - assert 'ipasudorunasgroup' in failed - assert 'group' in failed['ipasudorunasgroup'] - assert not failed['ipasudorunasgroup']['group'] - entry = ret['result'] - assert 'ipasudorunasgroup_group' not in entry - - def test_a_sudorule_add_externaluser(self): - """ - Test adding an external user to Sudo rule using - `xmlrpc.sudorule_add_user`. - """ - ret = api.Command['sudorule_add_user']( - self.rule_name, user=self.test_external_user - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert_attr_equal(entry, 'externaluser', self.test_external_user) - - def test_a_sudorule_add_externaluser_invalid(self): - """ - Test adding an invalid external user to Sudo rule using - `xmlrpc.sudorule_add_user`. - """ - try: - api.Command['sudorule_add_user']( - self.rule_name, user=self.test_invalid_user - ) - except errors.ValidationError: - pass - else: - assert False - - def test_b_sudorule_remove_externaluser(self): - """ - Test removing an external user from Sudo rule using - `xmlrpc.sudorule_remove_user'. - """ - ret = api.Command['sudorule_remove_user']( - self.rule_name, user=self.test_external_user - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert entry['externaluser'] == () - - def test_a_sudorule_add_runasexternaluser(self): - """ - Test adding an external runasuser to Sudo rule using - `xmlrpc.sudorule_add_runasuser`. - """ - ret = api.Command['sudorule_add_runasuser']( - self.rule_name, user=self.test_external_user - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert_attr_equal(entry, 'ipasudorunasextuser', self.test_external_user) - - def test_b_sudorule_remove_runasexternaluser(self): - """ - Test removing an external runasuser from Sudo rule using - `xmlrpc.sudorule_remove_runasuser'. - """ - ret = api.Command['sudorule_remove_runasuser']( - self.rule_name, user=self.test_external_user - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert entry['ipasudorunasextuser'] == () - - def test_a_sudorule_add_runasexternalgroup(self): - """ - Test adding an external runasgroup to Sudo rule using - `xmlrpc.sudorule_add_runasgroup`. - """ - ret = api.Command['sudorule_add_runasgroup']( - self.rule_name, group=self.test_external_group - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert_attr_equal(entry, 'ipasudorunasextgroup', self.test_external_group) - - def test_b_sudorule_remove_runasexternalgroup(self): - """ - Test removing an external runasgroup from Sudo rule using - `xmlrpc.sudorule_remove_runasgroup'. - """ - ret = api.Command['sudorule_remove_runasgroup']( - self.rule_name, group=self.test_external_group - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert entry['ipasudorunasextgroup'] == () - - def test_a_sudorule_add_option(self): - """ - Test adding an option to Sudo rule using - `xmlrpc.sudorule_add_option`. - """ - ret = api.Command['sudorule_add_option']( - self.rule_name, ipasudoopt=self.test_option - ) - entry = ret['result'] - assert_attr_equal(entry, 'ipasudoopt', self.test_option) - - def test_b_sudorule_remove_option(self): - """ - Test removing an option from Sudo rule using - `xmlrpc.sudorule_remove_option'. - """ - ret = api.Command['sudorule_remove_option']( - self.rule_name, ipasudoopt=self.test_option - ) - entry = ret['result'] - assert 'ipasudoopt' not in entry - - def test_a_sudorule_add_host(self): - """ - Test adding host and hostgroup to Sudo rule using - `xmlrpc.sudorule_add_host`. - """ - ret = api.Command['sudorule_add_host']( - self.rule_name, host=self.test_host, hostgroup=self.test_hostgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberhost' in failed - assert 'host' in failed['memberhost'] - assert not failed['memberhost']['host'] - assert 'hostgroup' in failed['memberhost'] - assert not failed['memberhost']['hostgroup'] - entry = ret['result'] - assert_attr_equal(entry, 'memberhost_host', self.test_host) - assert_attr_equal(entry, 'memberhost_hostgroup', self.test_hostgroup) - - def test_a_sudorule_show_host(self): - """ - Test showing host to verify Sudo rule membership - `xmlrpc.host_show`. - """ - ret = api.Command['host_show'](self.test_host, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_sudorule', self.rule_name) - - def test_a_sudorule_show_hostgroup(self): - """ - Test showing hostgroup to verify Sudo rule membership - `xmlrpc.hostgroup_show`. - """ - ret = api.Command['hostgroup_show'](self.test_hostgroup, all=True) - entry = ret['result'] - assert_attr_equal(entry, 'memberof_sudorule', self.rule_name) - - def test_b_sudorule_remove_host(self): - """ - Test removing host and hostgroup from Sudo rule using - `xmlrpc.sudorule_remove_host`. - """ - ret = api.Command['sudorule_remove_host']( - self.rule_name, host=self.test_host, hostgroup=self.test_hostgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberhost' in failed - assert 'host' in failed['memberhost'] - assert not failed['memberhost']['host'] - assert 'hostgroup' in failed['memberhost'] - assert not failed['memberhost']['hostgroup'] - entry = ret['result'] - assert 'memberhost_host' not in entry - assert 'memberhost_hostgroup' not in entry - - def test_a_sudorule_add_externalhost(self): - """ - Test adding an external host to Sudo rule using - `xmlrpc.sudorule_add_host`. - """ - ret = api.Command['sudorule_add_host']( - self.rule_name, host=self.test_external_host - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert_attr_equal(entry, 'externalhost', self.test_external_host) - - def test_a_sudorule_add_externalhost_invalid(self): - """ - Test adding an invalid external host to Sudo rule using - `xmlrpc.sudorule_add_host`. - """ - try: - api.Command['sudorule_add_host']( - self.rule_name, host=self.test_invalid_host - ) - except errors.ValidationError: - pass - else: - assert False - - def test_a_sudorule_mod_externalhost_invalid_addattr(self): - """ - Test adding an invalid external host to Sudo rule using - `xmlrpc.sudorule_mod --addattr`. - """ - try: - api.Command['sudorule_mod']( - self.rule_name, - addattr='externalhost=%s' % self.test_invalid_host - ) - except errors.ValidationError, e: - assert unicode(e) == ("invalid 'externalhost': only letters, " + - "numbers, _, and - are allowed. " + - "DNS label may not start or end with -") - else: - assert False - - def test_b_sudorule_remove_externalhost(self): - """ - Test removing an external host from Sudo rule using - `xmlrpc.sudorule_remove_host`. - """ - ret = api.Command['sudorule_remove_host']( - self.rule_name, host=self.test_external_host - ) - assert ret['completed'] == 1 - failed = ret['failed'] - entry = ret['result'] - assert len(entry['externalhost']) == 0 - - def test_a_sudorule_add_allow_command(self): - """ - Test adding allow command and cmdgroup to Sudo rule using - `xmlrpc.sudorule_add_allow_command`. - """ - ret = api.Command['sudorule_add_allow_command']( - self.rule_name, sudocmd=self.test_command, - sudocmdgroup=self.test_sudoallowcmdgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberallowcmd' in failed - assert 'sudocmd' in failed['memberallowcmd'] - assert not failed['memberallowcmd']['sudocmd'] - assert 'sudocmdgroup' in failed['memberallowcmd'] - assert not failed['memberallowcmd']['sudocmdgroup'] - entry = ret['result'] - assert_attr_equal(entry, 'memberallowcmd_sudocmd', self.test_command) - assert_attr_equal(entry, 'memberallowcmd_sudocmdgroup', - self.test_sudoallowcmdgroup) - - def test_a_sudorule_remove_allow_command(self): - """ - Test removing allow command and sudocmdgroup from Sudo rule using - `xmlrpc.sudorule_remove_command`. - """ - ret = api.Command['sudorule_remove_allow_command']( - self.rule_name, sudocmd=self.test_command, - sudocmdgroup=self.test_sudoallowcmdgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberallowcmd' in failed - assert 'sudocmd' in failed['memberallowcmd'] - assert not failed['memberallowcmd']['sudocmd'] - assert 'sudocmdgroup' in failed['memberallowcmd'] - assert not failed['memberallowcmd']['sudocmdgroup'] - entry = ret['result'] - assert 'memberallowcmd_sudocmd' not in entry - assert 'memberallowcmd_sudocmdgroup' not in entry - - def test_b_sudorule_add_deny_command(self): - """ - Test adding deny command and cmdgroup to Sudo rule using - `xmlrpc.sudorule_add_deny_command`. - """ - ret = api.Command['sudorule_add_deny_command']( - self.rule_name, sudocmd=self.test_command, - sudocmdgroup=self.test_sudodenycmdgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberdenycmd' in failed - assert 'sudocmd' in failed['memberdenycmd'] - assert not failed['memberdenycmd']['sudocmd'] - assert 'sudocmdgroup' in failed['memberdenycmd'] - assert not failed['memberdenycmd']['sudocmdgroup'] - entry = ret['result'] - assert_attr_equal(entry, 'memberdenycmd_sudocmd', self.test_command) - assert_attr_equal(entry, 'memberdenycmd_sudocmdgroup', - self.test_sudodenycmdgroup) - - def test_b_sudorule_remove_deny_command(self): - """ - Test removing deny command and sudocmdgroup from Sudo rule using - `xmlrpc.sudorule_remove_deny_command`. - """ - ret = api.Command['sudorule_remove_deny_command']( - self.rule_name, sudocmd=self.test_command, - sudocmdgroup=self.test_sudodenycmdgroup - ) - assert ret['completed'] == 2 - failed = ret['failed'] - assert 'memberdenycmd' in failed - assert 'sudocmd' in failed['memberdenycmd'] - assert not failed['memberdenycmd']['sudocmd'] - assert 'sudocmdgroup' in failed['memberdenycmd'] - assert not failed['memberdenycmd']['sudocmdgroup'] - entry = ret['result'] - assert 'memberdenycmd_sudocmd' not in entry - assert 'memberdenycmd_sudocmdgroup' not in entry - - @raises(errors.MutuallyExclusiveError) - def test_c_sudorule_exclusiveuser(self): - """ - Test adding a user to an Sudo rule when usercat='all' - """ - api.Command['sudorule_mod'](self.rule_name, usercategory=u'all') - try: - api.Command['sudorule_add_user'](self.rule_name, user=u'admin') - finally: - api.Command['sudorule_mod'](self.rule_name, usercategory=u'') - - @raises(errors.MutuallyExclusiveError) - def test_d_sudorule_exclusiveuser(self): - """ - Test setting usercat='all' in an Sudo rule when there are users - """ - api.Command['sudorule_add_user'](self.rule_name, user=u'admin') - try: - api.Command['sudorule_mod'](self.rule_name, usercategory=u'all') - finally: - api.Command['sudorule_remove_user'](self.rule_name, user=u'admin') - - @raises(errors.MutuallyExclusiveError) - def test_e_sudorule_exclusivehost(self): - """ - Test adding a host to an Sudo rule when hostcat='all' - """ - api.Command['sudorule_mod'](self.rule_name, hostcategory=u'all') - try: - api.Command['sudorule_add_host'](self.rule_name, host=self.test_host) - finally: - api.Command['sudorule_mod'](self.rule_name, hostcategory=u'') - - @raises(errors.MutuallyExclusiveError) - def test_f_sudorule_exclusivehost(self): - """ - Test setting hostcat='all' in an Sudo rule when there are hosts - """ - api.Command['sudorule_add_host'](self.rule_name, host=self.test_host) - try: - api.Command['sudorule_mod'](self.rule_name, hostcategory=u'all') - finally: - api.Command['sudorule_remove_host'](self.rule_name, host=self.test_host) - - @raises(errors.MutuallyExclusiveError) - def test_g_sudorule_exclusivecommand(self): - """ - Test adding a command to an Sudo rule when cmdcategory='all' - """ - api.Command['sudorule_mod'](self.rule_name, cmdcategory=u'all') - try: - api.Command['sudorule_add_allow_command'](self.rule_name, sudocmd=self.test_command) - finally: - api.Command['sudorule_mod'](self.rule_name, cmdcategory=u'') - - @raises(errors.MutuallyExclusiveError) - def test_h_sudorule_exclusivecommand(self): - """ - Test setting cmdcategory='all' in an Sudo rule when there are commands - """ - api.Command['sudorule_add_allow_command'](self.rule_name, sudocmd=self.test_command) - try: - api.Command['sudorule_mod'](self.rule_name, cmdcategory=u'all') - finally: - api.Command['sudorule_remove_allow_command'](self.rule_name, sudocmd=self.test_command) - - @raises(errors.MutuallyExclusiveError) - def test_i_sudorule_exclusiverunas(self): - """ - Test adding a runasuser to an Sudo rule when ipasudorunasusercategory='all' - """ - api.Command['sudorule_mod'](self.rule_name, ipasudorunasusercategory=u'all') - try: - api.Command['sudorule_add_runasuser'](self.rule_name, user=self.test_user) - finally: - api.Command['sudorule_mod'](self.rule_name, ipasudorunasusercategory=u'') - - @raises(errors.MutuallyExclusiveError) - def test_j_1_sudorule_exclusiverunas(self): - """ - Test setting ipasudorunasusercategory='all' in an Sudo rule when there are runas users - """ - api.Command['sudorule_add_runasuser'](self.rule_name, user=self.test_user) - try: - api.Command['sudorule_mod'](self.rule_name, ipasudorunasusercategory=u'all') - finally: - api.Command['sudorule_remove_runasuser'](self.rule_name, user=self.test_command) - - def test_j_2_sudorule_referential_integrity(self): - """ - Test adding various links to Sudo rule - """ - api.Command['sudorule_add_user'](self.rule_name, user=self.test_user) - api.Command['sudorule_add_runasuser'](self.rule_name, user=self.test_runasuser, - group=self.test_group) - api.Command['sudorule_add_runasgroup'](self.rule_name, group=self.test_group) - api.Command['sudorule_add_host'](self.rule_name, host=self.test_host) - api.Command['sudorule_add_allow_command'](self.rule_name, - sudocmd=self.test_command) - api.Command['sudorule_add_deny_command'](self.rule_name, - sudocmdgroup=self.test_sudodenycmdgroup) - entry = api.Command['sudorule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert_attr_equal(entry, 'memberuser_user', self.test_user) - assert_attr_equal(entry, 'memberallowcmd_sudocmd', self.test_command) - assert_attr_equal(entry, 'memberdenycmd_sudocmdgroup', - self.test_sudodenycmdgroup) - assert_attr_equal(entry, 'memberhost_host', self.test_host) - assert_attr_equal(entry, 'ipasudorunas_user', self.test_runasuser) - assert_attr_equal(entry, 'ipasudorunas_group', self.test_group) - assert_attr_equal(entry, 'ipasudorunasgroup_group', self.test_group) - - - def test_k_1_sudorule_clear_testing_data(self): - """ - Clear data for Sudo rule plugin testing. - """ - api.Command['user_del'](self.test_user) - api.Command['user_del'](self.test_runasuser) - api.Command['group_del'](self.test_group) - api.Command['host_del'](self.test_host) - api.Command['hostgroup_del'](self.test_hostgroup) - api.Command['sudorule_remove_allow_command'](self.rule_name, - sudocmd=self.test_command) - api.Command['sudocmd_del'](self.test_command) - api.Command['sudocmdgroup_del'](self.test_sudoallowcmdgroup) - api.Command['sudocmdgroup_del'](self.test_sudodenycmdgroup) - - def test_k_2_sudorule_referential_integrity(self): - """ - Test that links in Sudo rule were removed by referential integrity plugin - """ - entry = api.Command['sudorule_show'](self.rule_name)['result'] - assert_attr_equal(entry, 'cn', self.rule_name) - assert 'memberuser_user' not in entry - assert 'memberallowcmd_sudocmd' not in entry - assert 'memberdenycmd_sudocmdgroup' not in entry - assert 'memberhost_host' not in entry - assert 'ipasudorunas_user' not in entry - assert 'ipasudorunas_group' not in entry - assert 'ipasudorunasgroup_group' not in entry - - def test_l_sudorule_order(self): - """ - Test that order uniqueness is maintained - """ - api.Command['sudorule_mod'](self.rule_name, sudoorder=1) - - api.Command['sudorule_add'](self.rule_name2) - - # mod of rule that has no order and set a duplicate - try: - api.Command['sudorule_mod'](self.rule_name2, sudoorder=1) - except errors.ValidationError: - pass - - # Remove the rule so we can re-add it - api.Command['sudorule_del'](self.rule_name2) - - # add a new rule with a duplicate order - with assert_raises(errors.ValidationError): - api.Command['sudorule_add'](self.rule_name2, sudoorder=1) - - # add a new rule with a unique order - api.Command['sudorule_add'](self.rule_name2, sudoorder=2) - with assert_raises(errors.ValidationError): - api.Command['sudorule_mod'](self.rule_name2, sudoorder=1) - - # Try setting both to 0 - api.Command['sudorule_mod'](self.rule_name2, sudoorder=0) - with assert_raises(errors.ValidationError): - api.Command['sudorule_mod'](self.rule_name, sudoorder=0) - - - def test_m_sudorule_del(self): - """ - Test deleting a Sudo rule using `xmlrpc.sudorule_del`. - """ - api.Command['sudorule_del'](self.rule_name) - # verify that it's gone - with assert_raises(errors.NotFound): - api.Command['sudorule_show'](self.rule_name) - api.Command['sudorule_del'](self.rule_name2) diff --git a/tests/test_xmlrpc/test_trust_plugin.py b/tests/test_xmlrpc/test_trust_plugin.py deleted file mode 100644 index 7627be748..000000000 --- a/tests/test_xmlrpc/test_trust_plugin.py +++ /dev/null @@ -1,159 +0,0 @@ -# Authors: -# Martin Kosek -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Test the `ipalib/plugins/trust.py` module. -""" - -import nose -from ipalib import api, errors -from ipapython.dn import DN -from tests.test_xmlrpc import objectclasses -from xmlrpc_test import (Declarative, fuzzy_guid, fuzzy_domain_sid, fuzzy_string, - fuzzy_uuid, fuzzy_digits) - - -trustconfig_ad_config = DN(('cn', api.env.domain), - api.env.container_cifsdomains, api.env.basedn) -testgroup = u'adtestgroup' -testgroup_dn = DN(('cn', testgroup), api.env.container_group, api.env.basedn) - -default_group = u'Default SMB Group' -default_group_dn = DN(('cn', default_group), api.env.container_group, api.env.basedn) - -class test_trustconfig(Declarative): - - @classmethod - def setUpClass(cls): - super(test_trustconfig, cls).setUpClass() - if not api.Backend.xmlclient.isconnected(): - api.Backend.xmlclient.connect(fallback=False) - try: - api.Command['trustconfig_show'](trust_type=u'ad') - except errors.NotFound: - raise nose.SkipTest('Trusts are not configured') - - cleanup_commands = [ - ('group_del', [testgroup], {}), - ('trustconfig_mod', [], {'trust_type': u'ad', - 'ipantfallbackprimarygroup': default_group}), - ] - - tests = [ - - dict( - desc='Retrieve trust configuration for AD domains', - command=('trustconfig_show', [], {'trust_type': u'ad'}), - expected={ - 'value': u'ad', - 'summary': None, - 'result': { - 'dn': trustconfig_ad_config, - 'cn': [api.env.domain], - 'ipantdomainguid': [fuzzy_guid], - 'ipantfallbackprimarygroup': [default_group], - 'ipantflatname': [fuzzy_string], - 'ipantsecurityidentifier': [fuzzy_domain_sid] - }, - }, - ), - - dict( - desc='Retrieve trust configuration for AD domains with --raw', - command=('trustconfig_show', [], {'trust_type': u'ad', 'raw': True}), - expected={ - 'value': u'ad', - 'summary': None, - 'result': { - 'dn': trustconfig_ad_config, - 'cn': [api.env.domain], - 'ipantdomainguid': [fuzzy_guid], - 'ipantfallbackprimarygroup': [default_group_dn], - 'ipantflatname': [fuzzy_string], - 'ipantsecurityidentifier': [fuzzy_domain_sid] - }, - }, - ), - - dict( - desc='Create auxiliary group %r' % testgroup, - command=( - 'group_add', [testgroup], dict(description=u'Test group') - ), - expected=dict( - value=testgroup, - summary=u'Added group "%s"' % testgroup, - result=dict( - cn=[testgroup], - description=[u'Test group'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=testgroup_dn, - ), - ), - ), - - dict( - desc='Try to change primary fallback group to nonexistent group', - command=('trustconfig_mod', [], - {'trust_type': u'ad', 'ipantfallbackprimarygroup': u'doesnotexist'}), - expected=errors.NotFound(reason=u'%s: group not found' % 'doesnotexist') - ), - - dict( - desc='Try to change primary fallback group to nonexistent group DN', - command=('trustconfig_mod', [], {'trust_type': u'ad', - 'ipantfallbackprimarygroup': u'cn=doesnotexist,dc=test'}), - expected=errors.NotFound(reason=u'%s: group not found' % 'cn=doesnotexist,dc=test') - ), - - dict( - desc='Change primary fallback group to "%s"' % testgroup, - command=('trustconfig_mod', [], {'trust_type': u'ad', - 'ipantfallbackprimarygroup': testgroup}), - expected={ - 'value': u'ad', - 'summary': u'Modified "ad" trust configuration', - 'result': { - 'cn': [api.env.domain], - 'ipantdomainguid': [fuzzy_guid], - 'ipantfallbackprimarygroup': [testgroup], - 'ipantflatname': [fuzzy_string], - 'ipantsecurityidentifier': [fuzzy_domain_sid] - }, - }, - ), - - dict( - desc='Change primary fallback group back to "%s" using DN' % default_group, - command=('trustconfig_mod', [], {'trust_type': u'ad', - 'ipantfallbackprimarygroup': unicode(default_group_dn)}), - expected={ - 'value': u'ad', - 'summary': u'Modified "ad" trust configuration', - 'result': { - 'cn': [api.env.domain], - 'ipantdomainguid': [fuzzy_guid], - 'ipantfallbackprimarygroup': [default_group], - 'ipantflatname': [fuzzy_string], - 'ipantsecurityidentifier': [fuzzy_domain_sid] - }, - }, - ), - ] diff --git a/tests/test_xmlrpc/test_user_plugin.py b/tests/test_xmlrpc/test_user_plugin.py deleted file mode 100644 index 7e992224c..000000000 --- a/tests/test_xmlrpc/test_user_plugin.py +++ /dev/null @@ -1,1837 +0,0 @@ -# Authors: -# Rob Crittenden -# Pavel Zuna -# Jason Gerard DeRose -# -# Copyright (C) 2008, 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Test the `ipalib/plugins/user.py` module. -""" - -from ipalib import api, errors, messages -from tests.test_xmlrpc import objectclasses -from tests.util import assert_equal, assert_not_equal -from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid, fuzzy_password, fuzzy_string, fuzzy_dergeneralizedtime -from ipapython.dn import DN -from ipapython.version import API_VERSION - -user1=u'tuser1' -user2=u'tuser2' -admin1=u'admin' -admin2=u'admin2' -renameduser1=u'tuser' -group1=u'group1' -admins_group=u'admins' - -invaliduser1=u'+tuser1' -invaliduser2=u'tuser1234567890123456789012345678901234567890' - -sshpubkey = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGAX3xAeLeaJggwTqMjxNwa6XHBUAikXPGMzEpVrlLDCZtv00djsFTBi38PkgxBJVkgRWMrcBsr/35lq7P6w8KGIwA8GI48Z0qBS2NBMJ2u9WQ2hjLN6GdMlo77O0uJY3251p12pCVIS/bHRSq8kHO2No8g7KA9fGGcagPfQH+ee3t7HUkpbQkFTmbPPN++r3V8oVUk5LxbryB3UIIVzNmcSIn3JrXynlvui4MixvrtX6zx+O/bBo68o8/eZD26QrahVbA09fivrn/4h3TM019Eu/c2jOdckfU3cHUV/3Tno5d6JicibyaoDDK7S/yjdn5jhaz8MSEayQvFkZkiF0L public key test' -sshpubkeyfp = u'13:67:6B:BF:4E:A2:05:8E:AE:25:8B:A1:31:DE:6F:1B public key test (ssh-rsa)' - -def get_user_dn(uid): - return DN(('uid', uid), api.env.container_user, api.env.basedn) - -def get_group_dn(cn): - return DN(('cn', cn), api.env.container_group, api.env.basedn) - -def upg_check(response): - """Check that the user was assigned to the corresponding private group.""" - assert_equal(response['result']['uidnumber'], - response['result']['gidnumber']) - return True - -def not_upg_check(response): - """Check that the user was not assigned to the corresponding private group.""" - assert_not_equal(response['result']['uidnumber'], - response['result']['gidnumber']) - return True - -class test_user(Declarative): - - cleanup_commands = [ - ('user_del', [user1, user2, renameduser1, admin2], {'continue': True}), - ('group_del', [group1], {}), - ('automember_default_group_remove', [], {'type': u'group'}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent "%s"' % user1, - command=('user_show', [user1], {}), - expected=errors.NotFound(reason=u'%s: user not found' % user1), - ), - - - dict( - desc='Try to update non-existent "%s"' % user1, - command=('user_mod', [user1], dict(givenname=u'Foo')), - expected=errors.NotFound(reason=u'%s: user not found' % user1), - ), - - - dict( - desc='Try to delete non-existent "%s"' % user1, - command=('user_del', [user1], {}), - expected=errors.NotFound(reason=u'%s: user not found' % user1), - ), - - - dict( - desc='Try to rename non-existent "%s"' % user1, - command=('user_mod', [user1], dict(setattr=u'uid=%s' % renameduser1)), - expected=errors.NotFound(reason=u'%s: user not found' % user1), - ), - - - dict( - desc='Create "%s"' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - extra_check = upg_check, - ), - - - dict( - desc='Try to create duplicate "%s"' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=errors.DuplicateEntry( - message=u'user with name "%s" already exists' % user1), - ), - - - dict( - desc='Retrieve "%s"' % user1, - command=( - 'user_show', [user1], {} - ), - expected=dict( - result=dict( - dn=get_user_dn(user1), - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - value=user1, - summary=None, - ), - ), - - - dict( - desc='Search for "%s" with all=True' % user1, - command=( - 'user_find', [user1], {'all': True} - ), - expected=dict( - result=[ - { - 'dn': get_user_dn(user1), - 'cn': [u'Test User1'], - 'gecos': [u'Test User1'], - 'givenname': [u'Test'], - 'homedirectory': [u'/home/tuser1'], - 'krbprincipalname': [u'tuser1@' + api.env.realm], - 'loginshell': [u'/bin/sh'], - 'memberof_group': [u'ipausers'], - 'objectclass': objectclasses.user, - 'sn': [u'User1'], - 'uid': [user1], - 'uidnumber': [fuzzy_digits], - 'gidnumber': [fuzzy_digits], - 'ipauniqueid': [fuzzy_uuid], - 'mepmanagedentry': [get_group_dn(user1)], - 'krbpwdpolicyreference': [DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - 'nsaccountlock': False, - 'has_keytab': False, - 'has_password': False, - 'displayname': [u'Test User1'], - 'cn': [u'Test User1'], - 'initials': [u'TU'], - 'mail': [u'%s@%s' % (user1, api.env.domain)], - }, - ], - summary=u'1 user matched', - count=1, truncated=False, - ), - ), - - - dict( - desc='Search for "%s" with pkey-only=True' % user1, - command=( - 'user_find', [user1], {'pkey_only': True} - ), - expected=dict( - result=[ - { - 'dn': get_user_dn(user1), - 'uid': [user1], - }, - ], - summary=u'1 user matched', - count=1, truncated=False, - ), - ), - - - dict( - desc='Search for "%s" with minimal attributes' % user1, - command=( - 'user_find', [user1], {} - ), - expected=dict( - result=[ - dict( - dn=get_user_dn(user1), - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - nsaccountlock=False, - has_keytab=False, - has_password=False, - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - ), - ], - summary=u'1 user matched', - count=1, - truncated=False, - ), - ), - - - dict( - desc='Search for all users', - command=( - 'user_find', [], {} - ), - expected=dict( - result=[ - dict( - dn=get_user_dn(admin1), - homedirectory=[u'/home/admin'], - loginshell=[u'/bin/bash'], - sn=[u'Administrator'], - uid=[admin1], - nsaccountlock=False, - has_keytab=True, - has_password=True, - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - ), - dict( - dn=get_user_dn(user1), - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - nsaccountlock=False, - has_keytab=False, - has_password=False, - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - ), - ], - summary=u'2 users matched', - count=2, - truncated=False, - ), - ), - - - dict( - desc='Search for all users with a limit of 1', - command=( - 'user_find', [], dict(sizelimit=1,), - ), - expected=dict( - result=[ - dict( - dn=get_user_dn(admin1), - homedirectory=[u'/home/admin'], - loginshell=[u'/bin/bash'], - sn=[u'Administrator'], - uid=[admin1], - nsaccountlock=False, - has_keytab=True, - has_password=True, - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - ), - ], - summary=u'1 user matched', - count=1, - truncated=True, - ), - ), - - - dict( - desc='Disable "%s"' % user1, - command=( - 'user_disable', [user1], {} - ), - expected=dict( - result=True, - value=user1, - summary=u'Disabled user account "%s"' % user1, - ), - ), - - dict( - desc='Assert user is disabled', - command=('user_find', [user1], {}), - expected=dict( - result=[lambda d: d['nsaccountlock'] == True], - summary=u'1 user matched', - count=1, - truncated=False, - ), - ), - - dict( - desc='Enable "%s"' % user1, - command=( - 'user_enable', [user1], {} - ), - expected=dict( - result=True, - value=user1, - summary=u'Enabled user account "%s"' % user1, - ), - ), - - dict( - desc='Assert user "%s" is enabled' % user1, - command=('user_find', [user1], {}), - expected=dict( - result=[lambda d: d['nsaccountlock'] == False], - summary=u'1 user matched', - count=1, - truncated=False, - ), - ), - - dict( - desc='Disable "%s" using setattr' % user1, - command=('user_mod', [user1], dict(setattr=u'nsaccountlock=True')), - expected=dict( - result=lambda d: d['nsaccountlock'] == True, - value=user1, - summary=u'Modified user "%s"' % user1, - ), - ), - - dict( - desc='Enable "%s" using setattr' % user1, - command=('user_mod', [user1], dict(setattr=u'nsaccountlock=False')), - expected=dict( - result=lambda d: d['nsaccountlock'] == False, - value=user1, - summary=u'Modified user "%s"' % user1, - ), - ), - - dict( - desc='Disable "%s" using user_mod' % user1, - command=('user_mod', [user1], dict(nsaccountlock=True)), - expected=dict( - result=lambda d: d['nsaccountlock'] == True, - value=user1, - summary=u'Modified user "%s"' % user1, - ), - ), - - dict( - desc='Enable "%s" using user_mod' % user1, - command=('user_mod', [user1], dict(nsaccountlock=False)), - expected=dict( - result=lambda d: d['nsaccountlock'] == False, - value=user1, - summary=u'Modified user "%s"' % user1, - ), - ), - - dict( - desc='Try setting virtual attribute on "%s" using setattr' % user1, - command=('user_mod', [user1], dict(setattr=u'random=xyz123')), - expected=errors.ObjectclassViolation( - info='attribute "random" not allowed'), - ), - - dict( - desc='Update "%s"' % user1, - command=( - 'user_mod', [user1], dict(givenname=u'Finkle') - ), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "%s"' % user1, - value=user1, - ), - ), - - - dict( - desc='Try updating the krb ticket policy of "%s"' % user1, - command=( - 'user_mod', [user1], dict(setattr=u'krbmaxticketlife=88000') - ), - expected=errors.ObjectclassViolation( - info=u'attribute "krbmaxticketlife" not allowed'), - ), - - - dict( - desc='Retrieve "%s" to verify update' % user1, - command=('user_show', [user1], {}), - expected=dict( - result=dict( - dn=get_user_dn(user1), - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=None, - value=user1, - ), - - ), - - - dict( - desc='Rename "%s"' % user1, - command=('user_mod', [user1], dict(setattr=u'uid=%s' % renameduser1)), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[renameduser1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "%s"' % user1, - value=user1, - ), - ), - - - dict( - desc='Rename "%s" to same value' % renameduser1, - command=('user_mod', [renameduser1], dict(setattr=u'uid=%s' % renameduser1)), - expected=errors.EmptyModlist(), - ), - - - dict( - desc='Rename back "%s"' % renameduser1, - command=('user_mod', [renameduser1], dict(setattr=u'uid=%s' % user1)), - expected=dict( - result=dict( - givenname=[u'Finkle'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - memberof_group=[u'ipausers'], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "%s"' % renameduser1, - value=renameduser1, - ), - ), - - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - - dict( - desc='Try to delete non-existent "%s"' % user1, - command=('user_del', [user1], {}), - expected=errors.NotFound(reason=u'tuser1: user not found'), - ), - - - dict( - desc='Create user "%s" with krb ticket policy' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - setattr=u'krbmaxticketlife=88000') - ), - expected=errors.ObjectclassViolation(info='attribute "krbmaxticketlife" not allowed'), - ), - - - dict( - desc='Create "%s" with SSH public key' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', ipasshpubkey=[sshpubkey]) - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - mail=[u'%s@%s' % (user1, api.env.domain)], - ipasshpubkey=[sshpubkey], - sshpubkeyfp=[sshpubkeyfp], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - extra_check = upg_check, - ), - - - dict( - desc='Add an illegal SSH public key to "%r"' % user1, - command=('user_mod', [user1], dict(ipasshpubkey=[u"anal nathrach orth' bhais's bethad do che'l de'nmha"])), - expected=errors.ValidationError(name='sshpubkey', - error=u'invalid SSH public key'), - ), - - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - - dict( - desc='Create "%s"' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - extra_check = upg_check, - ), - - - dict( - desc='Create "%s"' % user2, - command=( - 'user_add', [user2], dict(givenname=u'Test', sn=u'User2') - ), - expected=dict( - value=user2, - summary=u'Added user "%s"' % user2, - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User2'], - cn=[u'Test User2'], - mail=[u'%s@%s' % (user2, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user2)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user2), - ), - ), - extra_check = upg_check, - ), - - - dict( - desc='Make non-existent "%s" the manager of "%s"' % (renameduser1, user2), - command=('user_mod', [user2], dict(manager=renameduser1)), - expected=errors.NotFound( - reason=u'manager %s not found' % renameduser1), - ), - - - dict( - desc='Make "%s" the manager of "%s"' % (user1, user2), - command=('user_mod', [user2], dict(manager=user1)), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - loginshell=[u'/bin/sh'], - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - memberof_group=[u'ipausers'], - mail=[u'%s@%s' % (user2, api.env.domain)], - nsaccountlock=False, - has_keytab=False, - has_password=False, - manager=[user1], - ), - summary=u'Modified user "%s"' % user2, - value=user2, - ), - ), - - dict( - desc='Search for "%s" with manager "%s"' % (user2, user1), - command=( - 'user_find', [user2], {'manager': user1} - ), - expected=dict( - result=[ - dict( - dn=get_user_dn(user2), - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - loginshell=[u'/bin/sh'], - sn=[u'User2'], - uid=[user2], - nsaccountlock=False, - has_keytab=False, - has_password=False, - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user2, api.env.domain)], - manager=[user1], - ), - ], - summary=u'1 user matched', - count=1, - truncated=False, - ), - ), - - dict( - desc='Delete "%s" and "%s" at the same time' % (user1, user2), - command=('user_del', [user1, user2], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "tuser1,tuser2"', - value=u','.join((user1, user2)), - ), - ), - - dict( - desc='Try to retrieve non-existent "%s"' % user1, - command=('user_show', [user1], {}), - expected=errors.NotFound(reason=u'%s: user not found' % user1), - ), - - - dict( - desc='Try to update non-existent "%s"' % user1, - command=('user_mod', [user1], dict(givenname=u'Foo')), - expected=errors.NotFound(reason=u'%s: user not found' % user1), - ), - - - dict( - desc='Test an invalid login name "%s"' % invaliduser1, - command=('user_add', [invaliduser1], dict(givenname=u'Test', sn=u'User1')), - expected=errors.ValidationError(name='login', - error=u'may only include letters, numbers, _, -, . and $'), - ), - - - dict( - desc='Test a login name that is too long "%s"' % invaliduser2, - command=('user_add', [invaliduser2], - dict(givenname=u'Test', sn=u'User1')), - expected=errors.ValidationError(name='login', - error='can be at most 32 characters'), - ), - - - # The assumption on these next 4 tests is that if we don't get a - # validation error then the request was processed normally. - dict( - desc='Test that validation is disabled on deletes', - command=('user_del', [invaliduser1], {}), - expected=errors.NotFound( - reason=u'%s: user not found' % invaliduser1), - ), - - - dict( - desc='Test that validation is disabled on show', - command=('user_show', [invaliduser1], {}), - expected=errors.NotFound( - reason=u'%s: user not found' % invaliduser1), - ), - - - dict( - desc='Test that validation is disabled on find', - command=('user_find', [invaliduser1], {}), - expected=dict( - count=0, - truncated=False, - summary=u'0 users matched', - result=[], - ), - ), - - - dict( - desc='Try to rename to invalid username "%s"' % user1, - command=('user_mod', [user1], dict(rename=invaliduser1)), - expected=errors.ValidationError(name='rename', - error=u'may only include letters, numbers, _, -, . and $'), - ), - - - dict( - desc='Try to rename to a username that is too long "%s"' % user1, - command=('user_mod', [user1], dict(rename=invaliduser2)), - expected=errors.ValidationError(name='login', - error='can be at most 32 characters'), - ), - - - dict( - desc='Create "%s"' % group1, - command=( - 'group_add', [group1], dict(description=u'Test desc') - ), - expected=dict( - value=group1, - summary=u'Added group "%s"' % group1, - result=dict( - cn=[group1], - description=[u'Test desc'], - gidnumber=[fuzzy_digits], - objectclass=objectclasses.group + [u'posixgroup'], - ipauniqueid=[fuzzy_uuid], - dn=get_group_dn(group1), - ), - ), - ), - - - dict( - desc='Try to user "%s" where the managed group exists' % group1, - command=( - 'user_add', [group1], dict(givenname=u'Test', sn=u'User1') - ), - expected=errors.ManagedGroupExistsError(group=group1) - ), - - - dict( - desc='Create "%s" with a full address' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - street=u'123 Maple Rd', l=u'Anytown', st=u'MD', - telephonenumber=u'410-555-1212', postalcode=u'01234-5678') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - mail=[u'%s@%s' % (user1, api.env.domain)], - street=[u'123 Maple Rd'], - l=[u'Anytown'], - st=[u'MD'], - postalcode=[u'01234-5678'], - telephonenumber=[u'410-555-1212'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - ), - - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - dict( - desc='Create "%s" with random password' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', random=True) - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=True, - has_password=True, - randompassword=fuzzy_password, - krbextradata=[fuzzy_string], - krbpasswordexpiration=[fuzzy_dergeneralizedtime], - krblastpwdchange=[fuzzy_dergeneralizedtime], - dn=get_user_dn(user1), - ), - ), - ), - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - dict( - desc='Create "%s"' % user2, - command=( - 'user_add', [user2], dict(givenname=u'Test', sn=u'User2') - ), - expected=dict( - value=user2, - summary=u'Added user "%s"' % user2, - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User2'], - cn=[u'Test User2'], - mail=[u'%s@%s' % (user2, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user2)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user2), - ), - ), - ), - - dict( - desc='Modify "%s" with random password' % user2, - command=( - 'user_mod', [user2], dict(random=True) - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - loginshell=[u'/bin/sh'], - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - memberof_group=[u'ipausers'], - mail=[u'%s@%s' % (user2, api.env.domain)], - nsaccountlock=False, - has_keytab=True, - has_password=True, - randompassword=fuzzy_password, - ), - summary=u'Modified user "%s"' % user2, - value=user2, - ), - ), - - dict( - desc='Delete "%s"' % user2, - command=('user_del', [user2], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user2, - value=user2, - ), - ), - - dict( - desc='Create user "%s" with upper-case principal' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - krbprincipalname=user1.upper()) - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - ), - - - dict( - desc='Create user "%s" with bad realm in principal' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - krbprincipalname='%s@NOTFOUND.ORG' % user1) - ), - expected=errors.RealmMismatch() - ), - - - dict( - desc='Create user "%s" with malformed principal' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', - krbprincipalname='%s@BAD@NOTFOUND.ORG' % user1) - ), - expected=errors.MalformedUserPrincipal(principal='%s@BAD@NOTFOUND.ORG' % user1), - ), - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - dict( - desc='Change default home directory', - command=( - 'config_mod', [], dict(ipahomesrootdir=u'/other-home'), - ), - expected=lambda x, output: x is None, - ), - - dict( - desc='Create user "%s" with different default home directory' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/other-home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - ), - - - dict( - desc='Reset default home directory', - command=( - 'config_mod', [], dict(ipahomesrootdir=u'/home'), - ), - expected=lambda x, output: x is None, - ), - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - dict( - desc='Change default login shell', - command=( - 'config_mod', [], dict(ipadefaultloginshell=u'/usr/bin/ipython'), - ), - expected=lambda x, output: x is None, - ), - - dict( - desc='Create user "%s" with different default login shell' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/usr/bin/ipython'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - initials=[u'TU'], - mail=[u'%s@%s' % (user1, api.env.domain)], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - ), - - dict( - desc='Reset default login shell', - command=( - 'config_mod', [], dict(ipadefaultloginshell=u'/bin/sh'), - ), - expected=lambda x, output: x is None, - ), - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - dict( - desc='Create "%s" without UPG' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', noprivate=True) - ), - expected=errors.NotFound(reason='Default group for new users is not POSIX'), - ), - - dict( - desc='Create "%s" without UPG with GID explicitly set' % user2, - command=( - 'user_add', [user2], dict(givenname=u'Test', sn=u'User2', noprivate=True, gidnumber=1000) - ), - expected=dict( - value=user2, - summary=u'Added user "%s"' % user2, - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - description=[], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user_base, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[u'1000'], - displayname=[u'Test User2'], - cn=[u'Test User2'], - mail=[u'%s@%s' % (user2, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user2), - ), - ), - ), - - dict( - desc='Delete "%s"' % user2, - command=('user_del', [user2], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user2, - value=user2, - ), - ), - - dict( - desc='Change default user group', - command=( - 'config_mod', [], dict(ipadefaultprimarygroup=group1), - ), - expected=lambda x, output: x is None, - ), - - dict( - desc='Create "%s" without UPG' % user1, - command=( - 'user_add', [user1], dict(givenname=u'Test', sn=u'User1', noprivate=True) - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - description=[], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user_base, - sn=[u'User1'], - uid=[user1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - memberof_group=[group1], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - extra_check = not_upg_check, - ), - - dict( - desc='Create "%s" without UPG with GID explicitly set' % user2, - command=( - 'user_add', [user2], dict(givenname=u'Test', sn=u'User2', noprivate=True, gidnumber=1000) - ), - expected=dict( - value=user2, - summary=u'Added user "%s"' % user2, - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - description=[], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user_base, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[u'1000'], - displayname=[u'Test User2'], - cn=[u'Test User2'], - mail=[u'%s@%s' % (user2, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - memberof_group=[group1], - has_keytab=False, - has_password=False, - dn=get_user_dn(user2), - ), - ), - ), - - dict( - desc='Set %r as manager of %r' % (user1, user2), - command=( - 'user_mod', [user2], dict(manager=user1) - ), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - loginshell=[u'/bin/sh'], - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - memberof_group=[group1], - mail=[u'%s@%s' % (user2, api.env.domain)], - nsaccountlock=False, - has_keytab=False, - has_password=False, - manager=[user1], - ), - summary=u'Modified user "%s"' % user2, - value=user2, - ), - ), - - dict( - desc='Rename "%s"' % user1, - command=('user_mod', [user1], dict(rename=renameduser1)), - expected=dict( - result=dict( - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - loginshell=[u'/bin/sh'], - sn=[u'User1'], - uid=[renameduser1], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user1, api.env.domain)], - memberof_group=[group1], - nsaccountlock=False, - has_keytab=False, - has_password=False, - ), - summary=u'Modified user "%s"' % user1, - value=user1, - ), - ), - - dict( - desc='Retrieve %r and check that manager is renamed' % user2, - command=( - 'user_show', [user2], {'all': True} - ), - expected=dict( - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user_base, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[u'1000'], - displayname=[u'Test User2'], - cn=[u'Test User2'], - mail=[u'%s@%s' % (user2, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - memberof_group=[group1], - nsaccountlock=False, - has_keytab=False, - has_password=False, - dn=get_user_dn(user2), - manager=[renameduser1], - ), - value=user2, - summary=None, - ), - ), - - dict( - desc='Delete %r' % renameduser1, - command=('user_del', [renameduser1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % renameduser1, - value=renameduser1, - ), - ), - - dict( - desc='Retrieve %r and check that manager is gone' % user2, - command=( - 'user_show', [user2], {'all': True} - ), - expected=dict( - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user_base, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[u'1000'], - displayname=[u'Test User2'], - cn=[u'Test User2'], - mail=[u'%s@%s' % (user2, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - memberof_group=[group1], - nsaccountlock=False, - has_keytab=False, - has_password=False, - dn=get_user_dn(user2), - ), - value=user2, - summary=None, - ), - ), - - dict( - desc='Reset default user group', - command=( - 'config_mod', [], dict(ipadefaultprimarygroup=u'ipausers'), - ), - expected=lambda x, output: x is None, - ), - - dict( - desc='Try to remove the original admin user "%s"' % admin1, - command=('user_del', [admin1], {}), - expected=errors.LastMemberError(key=admin1, label=u'group', - container=admins_group), - ), - - dict( - desc='Try to disable the original admin user "%s"' % admin1, - command=('user_disable', [admin1], {}), - expected=errors.LastMemberError(key=admin1, label=u'group', - container=admins_group), - ), - - - dict( - desc='Create 2nd admin user "%s"' % admin2, - command=( - 'user_add', [admin2], dict(givenname=u'Second', sn=u'Admin') - ), - expected=dict( - value=admin2, - summary=u'Added user "%s"' % admin2, - result=dict( - gecos=[u'Second Admin'], - givenname=[u'Second'], - homedirectory=[u'/home/admin2'], - krbprincipalname=[u'admin2@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'Admin'], - uid=[admin2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - displayname=[u'Second Admin'], - cn=[u'Second Admin'], - initials=[u'SA'], - mail=[u'%s@%s' % (admin2, api.env.domain)], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(admin2)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(admin2), - ), - ), - ), - - dict( - desc='Add "%s" to the admins group "%s"' % (admin2, admins_group), - command=('group_add_member', [admins_group], dict(user=admin2)), - expected=dict( - completed=1, - failed=dict( - member=dict( - group=tuple(), - user=tuple(), - ), - ), - result={ - 'dn': get_group_dn(admins_group), - 'member_user': [admin1, admin2], - 'gidnumber': [fuzzy_digits], - 'cn': [admins_group], - 'description': [u'Account administrators group'], - }, - ), - ), - - - dict( - desc='Retrieve admins group "%s" to verify membership is "%s","%s"' % (admins_group, admin1, admin2), - command=('group_show', [admins_group], {}), - expected=dict( - value=admins_group, - result=dict( - cn=[admins_group], - gidnumber=[fuzzy_digits], - description=[u'Account administrators group'], - dn=get_group_dn(admins_group), - member_user=[admin1, admin2], - ), - summary=None, - ), - ), - - dict( - desc='Disable 2nd admin user "%s", admins group "%s" should also contain enabled "%s"' % (admin2, admins_group, admin1), - command=( - 'user_disable', [admin2], {} - ), - expected=dict( - result=True, - value=admin2, - summary=u'Disabled user account "%s"' % admin2, - ), - ), - - dict( - desc='Assert 2nd admin user "%s" is disabled' % admin2, - command=('user_find', [admin2], {}), - expected=dict( - result=[lambda d: d['nsaccountlock'] == True], - summary=u'1 user matched', - count=1, - truncated=False, - ), - ), - - dict( - desc='Try to disable the origin admin user "%s"' % admin1, - command=('user_disable', [admin1], {}), - expected=errors.LastMemberError(key=admin1, label=u'group', - container=admins_group), - ), - - dict( - desc='Try to remove the original admin user "%s"' % admin1, - command=('user_del', [admin1], {}), - expected=errors.LastMemberError(key=admin1, label=u'group', - container=admins_group), - ), - - dict( - desc='Delete 2nd admin "%s"' % admin2, - command=('user_del', [admin2], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % admin2, - value=admin2, - ), - ), - - dict( - desc='Retrieve admins group "%s" to verify membership is "%s"' % (admins_group, admin1), - command=('group_show', [admins_group], {}), - expected=dict( - value=admins_group, - result=dict( - cn=[admins_group], - gidnumber=[fuzzy_digits], - description=[u'Account administrators group'], - dn=get_group_dn(admins_group), - member_user=[admin1], - ), - summary=None, - ), - ), - - dict( - desc='Assert original admin user "%s" is enabled' % admin1, - command=('user_find', [admin1], {}), - expected=dict( - result=[lambda d: d['nsaccountlock'] == False], - summary=u'1 user matched', - count=1, - truncated=False, - ), - ), - - dict( - desc='Try to remove the original admin user "%s"' % admin1, - command=('user_del', [admin1], {}), - expected=errors.LastMemberError(key=admin1, label=u'group', - container=admins_group), - ), - - dict( - desc='Try to disable the original admin user "%s"' % admin1, - command=('user_disable', [admin1], {}), - expected=errors.LastMemberError(key=admin1, label=u'group', - container=admins_group), - ), - - dict( - desc='Set default automember group for groups as ipausers', - command=( - 'automember_default_group_set', [], dict( - type=u'group', - automemberdefaultgroup=u'ipausers' - ) - ), - expected=dict( - result=dict( - cn=[u'Group'], - automemberdefaultgroup=[DN(('cn', 'ipausers'), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)], - ), - value=u'group', - summary=u'Set default (fallback) group for automember "group"', - ), - ), - - dict( - desc='Delete "%s"' % user2, - command=('user_del', [user2], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user2, - value=user2, - ), - ), - - dict( - desc='Create %r' % user2, - command=( - 'user_add', [user2], dict(givenname=u'Test', sn=u'User2') - ), - expected=dict( - value=user2, - summary=u'Added user "tuser2"', - result=dict( - gecos=[u'Test User2'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser2'], - krbprincipalname=[u'tuser2@' + api.env.realm], - has_keytab=False, - has_password=False, - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User2'], - uid=[user2], - uidnumber=[fuzzy_digits], - gidnumber=[fuzzy_digits], - mail=[u'%s@%s' % (user2, api.env.domain)], - displayname=[u'Test User2'], - cn=[u'Test User2'], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn', 'global_policy'), ('cn', api.env.realm), ('cn', 'kerberos'), - api.env.basedn)], - mepmanagedentry=[DN(('cn', user2), ('cn', 'groups'), ('cn', 'accounts'), - api.env.basedn)], - memberof_group=[u'ipausers'], - dn=DN(('uid', 'tuser2'), ('cn', 'users'), ('cn', 'accounts'), - api.env.basedn), - ), - ), - ), - - dict( - desc='Create "%s" with UID 999' % user1, - command=( - 'user_add', [user1], dict( - givenname=u'Test', sn=u'User1', uidnumber=999) - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[u'999'], - gidnumber=[u'999'], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - extra_check = upg_check, - ), - - dict( - desc='Delete "%s"' % user1, - command=('user_del', [user1], {}), - expected=dict( - result=dict(failed=u''), - summary=u'Deleted user "%s"' % user1, - value=user1, - ), - ), - - dict( - desc='Create "%s" with old DNA_MAGIC uid 999' % user1, - command=( - 'user_add', [user1], dict( - givenname=u'Test', sn=u'User1', uidnumber=999, - version=u'2.49') - ), - expected=dict( - value=user1, - summary=u'Added user "%s"' % user1, - result=dict( - gecos=[u'Test User1'], - givenname=[u'Test'], - homedirectory=[u'/home/tuser1'], - krbprincipalname=[u'tuser1@' + api.env.realm], - loginshell=[u'/bin/sh'], - objectclass=objectclasses.user, - sn=[u'User1'], - uid=[user1], - uidnumber=[lambda v: int(v) != 999], - gidnumber=[lambda v: int(v) != 999], - displayname=[u'Test User1'], - cn=[u'Test User1'], - mail=[u'%s@%s' % (user1, api.env.domain)], - initials=[u'TU'], - ipauniqueid=[fuzzy_uuid], - krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm), - ('cn','kerberos'),api.env.basedn)], - mepmanagedentry=[get_group_dn(user1)], - memberof_group=[u'ipausers'], - has_keytab=False, - has_password=False, - dn=get_user_dn(user1), - ), - ), - extra_check = upg_check, - ), - - ] diff --git a/tests/test_xmlrpc/xmlrpc_test.py b/tests/test_xmlrpc/xmlrpc_test.py deleted file mode 100644 index 89f1adc38..000000000 --- a/tests/test_xmlrpc/xmlrpc_test.py +++ /dev/null @@ -1,329 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Base class for all XML-RPC tests -""" - -import sys -import socket -import nose -from tests.util import assert_deepequal, Fuzzy -from ipalib import api, request, errors -from ipalib.x509 import valid_issuer -from ipapython.version import API_VERSION - - -# Matches a gidnumber like '1391016742' -# FIXME: Does it make more sense to return gidnumber, uidnumber, etc. as `int` -# or `long`? If not, we still need to return them as `unicode` instead of `str`. -fuzzy_digits = Fuzzy('^\d+$', type=basestring) - -uuid_re = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' - -# Matches an ipauniqueid like u'784d85fd-eae7-11de-9d01-54520012478b' -fuzzy_uuid = Fuzzy('^%s$' % uuid_re) - -# Matches trusted domain GUID, like u'463bf2be-3456-4a57-979e-120304f2a0eb' -fuzzy_guid = fuzzy_uuid - -# Matches SID of a trusted domain -# SID syntax: http://msdn.microsoft.com/en-us/library/ff632068.aspx -_sid_identifier_authority = '(0x[0-9a-f]{1,12}|[0-9]{1,10})' -fuzzy_domain_sid = Fuzzy( - '^S-1-5-21-%(idauth)s-%(idauth)s-%(idauth)s$' % dict(idauth=_sid_identifier_authority) -) -fuzzy_user_or_group_sid = Fuzzy( - '^S-1-5-21-%(idauth)s-%(idauth)s-%(idauth)s-%(idauth)s$' % dict(idauth=_sid_identifier_authority) -) - -# Matches netgroup dn. Note (?i) at the beginning of the regexp is the ingnore case flag -fuzzy_netgroupdn = Fuzzy( - '(?i)ipauniqueid=%s,cn=ng,cn=alt,%s' % (uuid_re, api.env.basedn) -) - -# Matches sudocmd dn -fuzzy_sudocmddn = Fuzzy( - '(?i)ipauniqueid=%s,cn=sudocmds,cn=sudo,%s' % (uuid_re, api.env.basedn) -) - -# Matches a hash signature, not enforcing length -fuzzy_hash = Fuzzy('^([a-f0-9][a-f0-9]:)+[a-f0-9][a-f0-9]$', type=basestring) - -# Matches a date, like Tue Apr 26 17:45:35 2016 UTC -fuzzy_date = Fuzzy('^[a-zA-Z]{3} [a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} \d{4} UTC$') - -fuzzy_issuer = Fuzzy(type=basestring, test=lambda issuer: valid_issuer(issuer)) - -fuzzy_hex = Fuzzy('^0x[0-9a-fA-F]+$', type=basestring) - -# Matches password - password consists of all printable characters without whitespaces -# The only exception is space, but space cannot be at the beggingin or end of the pwd -fuzzy_password = Fuzzy('^\S([\S ]*\S)*$') - -# Matches generalized time value. Time format is: %Y%m%d%H%M%SZ -fuzzy_dergeneralizedtime = Fuzzy('^[0-9]{14}Z$') - -# match any string -fuzzy_string = Fuzzy(type=basestring) - -# case insensitive match of sets -def fuzzy_set_ci(s): - return Fuzzy(test=lambda other: set(x.lower() for x in other) == set(y.lower() for y in s)) - -try: - if not api.Backend.xmlclient.isconnected(): - api.Backend.xmlclient.connect(fallback=False) - res = api.Command['user_show'](u'notfound') -except errors.NetworkError: - server_available = False -except IOError: - server_available = False -except errors.NotFound: - server_available = True - - - -def assert_attr_equal(entry, key, value): - if type(entry) is not dict: - raise AssertionError( - 'assert_attr_equal: entry must be a %r; got a %r: %r' % ( - dict, type(entry), entry) - ) - if key not in entry: - raise AssertionError( - 'assert_attr_equal: entry has no key %r: %r' % (key, entry) - ) - if value not in entry[key]: - raise AssertionError( - 'assert_attr_equal: %r: %r not in %r' % (key, value, entry[key]) - ) - - -def assert_is_member(entry, value, key='member'): - if type(entry) is not dict: - raise AssertionError( - 'assert_is_member: entry must be a %r; got a %r: %r' % ( - dict, type(entry), entry) - ) - if key not in entry: - raise AssertionError( - 'assert_is_member: entry has no key %r: %r' % (key, entry) - ) - for member in entry[key]: - if member.startswith(value): - return - raise AssertionError( - 'assert_is_member: %r: %r not in %r' % (key, value, entry[key]) - ) - - -# Initialize the API. We do this here so that one can run the tests -# individually instead of at the top-level. If API.bootstrap() -# has already been called we continue gracefully. Other errors will be -# raised. - -class XMLRPC_test(object): - """ - Base class for all XML-RPC plugin tests - """ - - @classmethod - def setUpClass(cls): - if not server_available: - raise nose.SkipTest('%r: Server not available: %r' % - (cls.__module__, api.env.xmlrpc_uri)) - - def setUp(self): - if not api.Backend.xmlclient.isconnected(): - api.Backend.xmlclient.connect(fallback=False) - - def tearDown(self): - """ - nose tear-down fixture. - """ - request.destroy_context() - - def failsafe_add(self, obj, pk, **options): - """ - Delete possible leftover entry first, then add. - - This helps speed us up when a partial test failure has left LDAP in a - dirty state. - - :param obj: An Object like api.Object.user - :param pk: The primary key of the entry to be created - :param options: Kwargs to be passed to obj.add() - """ - try: - obj.methods['del'](pk) - except errors.NotFound: - pass - return obj.methods['add'](pk, **options) - - -IGNORE = """Command %r is missing attribute %r in output entry. - args = %r - options = %r - entry = %r""" - - -EXPECTED = """Expected %r to raise %s. - args = %r - options = %r - output = %r""" - - -UNEXPECTED = """Expected %r to raise %s, but caught different. - args = %r - options = %r - %s: %s""" - - -KWARGS = """Command %r raised %s with wrong kwargs. - args = %r - options = %r - kw_expected = %r - kw_got = %r""" - - -class Declarative(XMLRPC_test): - """A declarative-style test suite - - A Declarative test suite is controlled by the ``tests`` and - ``cleanup_commands`` class variables. - - The ``tests`` is a list of dictionaries with the following keys: - - ``desc`` - A name/description of the test - ``command`` - A (command, args, kwargs) triple specifying the command to run - ``expected`` - Can be either an ``errors.PublicError`` instance, in which case - the command must fail with the given error; or the - expected result. - The result is checked with ``tests.util.assert_deepequal``. - ``extra_check`` (optional) - A checking function that is called with the response. It must - return true for the test to pass. - - The ``cleanup_commands`` is a list of (command, args, kwargs) - triples. These are commands get run both before and after tests, - and must not fail. - """ - - cleanup_commands = tuple() - tests = tuple() - - def cleanup_generate(self, stage): - for (i, command) in enumerate(self.cleanup_commands): - func = lambda: self.cleanup(command) - func.description = '%s %s-cleanup[%d]: %r' % ( - self.__class__.__name__, stage, i, command - ) - yield (func,) - - def cleanup(self, command): - (cmd, args, options) = command - if cmd not in api.Command: - raise nose.SkipTest( - 'cleanup command %r not in api.Command' % cmd - ) - try: - api.Command[cmd](*args, **options) - except (errors.NotFound, errors.EmptyModlist): - pass - - def test_generator(self): - """ - Iterate through tests. - - nose reports each one as a seperate test. - """ - - # Iterate through pre-cleanup: - for tup in self.cleanup_generate('pre'): - yield tup - - # Iterate through the tests: - name = self.__class__.__name__ - for (i, test) in enumerate(self.tests): - nice = '%s[%d]: %s: %s' % ( - name, i, test['command'][0], test.get('desc', '') - ) - func = lambda: self.check(nice, **test) - func.description = nice - yield (func,) - - # Iterate through post-cleanup: - for tup in self.cleanup_generate('post'): - yield tup - - def check(self, nice, desc, command, expected, extra_check=None): - (cmd, args, options) = command - options.setdefault('version', API_VERSION) - if cmd not in api.Command: - raise nose.SkipTest('%r not in api.Command' % cmd) - if isinstance(expected, errors.PublicError): - self.check_exception(nice, cmd, args, options, expected) - elif hasattr(expected, '__call__'): - self.check_callable(nice, cmd, args, options, expected) - else: - self.check_output(nice, cmd, args, options, expected, extra_check) - - def check_exception(self, nice, cmd, args, options, expected): - klass = expected.__class__ - name = klass.__name__ - try: - output = api.Command[cmd](*args, **options) - except StandardError, e: - pass - else: - raise AssertionError( - EXPECTED % (cmd, name, args, options, output) - ) - if not isinstance(e, klass): - raise AssertionError( - UNEXPECTED % (cmd, name, args, options, e.__class__.__name__, e) - ) - # FIXME: the XML-RPC transport doesn't allow us to return structured - # information through the exception, so we can't test the kw on the - # client side. However, if we switch to using JSON-RPC for the default - # transport, the exception is a free-form data structure (dict). - # For now just compare the strings - assert_deepequal(expected.strerror, e.strerror) - - def check_callable(self, nice, cmd, args, options, expected): - output = dict() - e = None - try: - output = api.Command[cmd](*args, **options) - except StandardError, e: - pass - if not expected(e, output): - raise AssertionError( - UNEXPECTED % (cmd, args, options, e.__class__.__name__, e) - ) - - def check_output(self, nice, cmd, args, options, expected, extra_check): - got = api.Command[cmd](*args, **options) - assert_deepequal(expected, got, nice) - if extra_check and not extra_check(got): - raise AssertionError('Extra check %s failed' % extra_check) diff --git a/tests/util.py b/tests/util.py deleted file mode 100644 index 117d2c834..000000000 --- a/tests/util.py +++ /dev/null @@ -1,637 +0,0 @@ -# Authors: -# Jason Gerard DeRose -# -# Copyright (C) 2008 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Common utility functions and classes for unit tests. -""" - -import inspect -import os -from os import path -import tempfile -import shutil -import re -import ipalib -from ipalib.plugable import Plugin -from ipalib.request import context -from ipapython.dn import DN - -class TempDir(object): - def __init__(self): - self.__path = tempfile.mkdtemp(prefix='ipa.tests.') - assert self.path == self.__path - - def __get_path(self): - assert path.abspath(self.__path) == self.__path - assert self.__path.startswith('/tmp/ipa.tests.') - assert path.isdir(self.__path) and not path.islink(self.__path) - return self.__path - path = property(__get_path) - - def rmtree(self): - if self.__path is not None: - shutil.rmtree(self.path) - self.__path = None - - def makedirs(self, *parts): - d = self.join(*parts) - if not path.exists(d): - os.makedirs(d) - assert path.isdir(d) and not path.islink(d) - return d - - def touch(self, *parts): - d = self.makedirs(*parts[:-1]) - f = path.join(d, parts[-1]) - assert not path.exists(f) - open(f, 'w').close() - assert path.isfile(f) and not path.islink(f) - return f - - def write(self, content, *parts): - d = self.makedirs(*parts[:-1]) - f = path.join(d, parts[-1]) - assert not path.exists(f) - open(f, 'w').write(content) - assert path.isfile(f) and not path.islink(f) - return f - - def join(self, *parts): - return path.join(self.path, *parts) - - def __del__(self): - self.rmtree() - - -class TempHome(TempDir): - def __init__(self): - super(TempHome, self).__init__() - self.__home = os.environ['HOME'] - os.environ['HOME'] = self.path - - -class ExceptionNotRaised(Exception): - """ - Exception raised when an *expected* exception is *not* raised during a - unit test. - """ - msg = 'expected %s' - - def __init__(self, expected): - self.expected = expected - - def __str__(self): - return self.msg % self.expected.__name__ - - -def assert_equal(val1, val2): - """ - Assert ``val1`` and ``val2`` are the same type and of equal value. - """ - assert type(val1) is type(val2), '%r != %r' % (val1, val2) - assert val1 == val2, '%r != %r' % (val1, val2) - - -def assert_not_equal(val1, val2): - """ - Assert ``val1`` and ``val2`` are the same type and of non-equal value. - """ - assert type(val1) is type(val2), '%r != %r' % (val1, val2) - assert val1 != val2, '%r == %r' % (val1, val2) - - -class Fuzzy(object): - """ - Perform a fuzzy (non-strict) equality tests. - - `Fuzzy` instances will likely be used when comparing nesting data-structures - using `assert_deepequal()`. - - By default a `Fuzzy` instance is equal to everything. For example, all of - these evaluate to ``True``: - - >>> Fuzzy() == False - True - >>> 7 == Fuzzy() # Order doesn't matter - True - >>> Fuzzy() == u'Hello False, Lucky 7!' - True - - The first optional argument *regex* is a regular expression pattern to - match. For example, you could match a phone number like this: - - >>> phone = Fuzzy('^\d{3}-\d{3}-\d{4}$') - >>> u'123-456-7890' == phone - True - - Use of a regular expression by default implies the ``unicode`` type, so - comparing with an ``str`` instance will evaluate to ``False``: - - >>> phone.type - - >>> '123-456-7890' == phone - False - - The *type* kwarg allows you to specify a type constraint, so you can force - the above to work on ``str`` instances instead: - - >>> '123-456-7890' == Fuzzy('^\d{3}-\d{3}-\d{4}$', type=str) - True - - You can also use the *type* constraint on its own without the *regex*, for - example: - - >>> 42 == Fuzzy(type=int) - True - >>> 42.0 == Fuzzy(type=int) - False - >>> 42.0 == Fuzzy(type=(int, float)) - True - - Finally the *test* kwarg is an optional callable that will be called to - perform the loose equality test. For example: - - >>> 42 == Fuzzy(test=lambda other: other > 42) - False - >>> 43 == Fuzzy(test=lambda other: other > 42) - True - - You can use *type* and *test* together. For example: - - >>> 43 == Fuzzy(type=float, test=lambda other: other > 42) - False - >>> 42.5 == Fuzzy(type=float, test=lambda other: other > 42) - True - - The *regex*, *type*, and *test* kwargs are all availabel via attributes on - the `Fuzzy` instance: - - >>> fuzzy = Fuzzy('.+', type=str, test=lambda other: True) - >>> fuzzy.regex - '.+' - >>> fuzzy.type - - >>> fuzzy.test # doctest:+ELLIPSIS - at 0x...> - - To aid debugging, `Fuzzy.__repr__()` revealse these kwargs as well: - - >>> fuzzy # doctest:+ELLIPSIS - Fuzzy('.+', , at 0x...>) - """ - - def __init__(self, regex=None, type=None, test=None): - """ - Initialize. - - :param regex: A regular expression pattern to match, e.g. - ``u'^\d+foo'`` - - :param type: A type or tuple of types to test using ``isinstance()``, - e.g. ``(int, float)`` - - :param test: A callable used to perform equality test, e.g. - ``lambda other: other >= 18`` - """ - assert regex is None or isinstance(regex, basestring) - assert test is None or callable(test) - if regex is None: - self.re = None - else: - self.re = re.compile(regex) - if type is None: - type = unicode - assert type in (unicode, str, basestring) - self.regex = regex - self.type = type - self.test = test - - def __repr__(self): - return '%s(%r, %r, %r)' % ( - self.__class__.__name__, self.regex, self.type, self.test - ) - - def __eq__(self, other): - if not (self.type is None or isinstance(other, self.type)): - return False - if not (self.re is None or self.re.search(other)): - return False - if not (self.test is None or self.test(other)): - return False - return True - - def __ne__(self, other): - return not self.__eq__(other) - - -VALUE = """assert_deepequal: expected != got. - %s - expected = %r - got = %r - path = %r""" - -TYPE = """assert_deepequal: type(expected) is not type(got). - %s - type(expected) = %r - type(got) = %r - expected = %r - got = %r - path = %r""" - -LEN = """assert_deepequal: list length mismatch. - %s - len(expected) = %r - len(got) = %r - expected = %r - got = %r - path = %r""" - -KEYS = """assert_deepequal: dict keys mismatch. - %s - missing keys = %r - extra keys = %r - expected = %r - got = %r - path = %r""" - - -def assert_deepequal(expected, got, doc='', stack=tuple()): - """ - Recursively check for type and equality. - - If a value in expected is callable then it will used as a callback to - test for equality on the got value. The callback is passed the got - value and returns True if equal, False otherwise. - - If the tests fails, it will raise an ``AssertionError`` with detailed - information, including the path to the offending value. For example: - - >>> expected = [u'Hello', dict(world=u'how are you?')] - >>> got = [u'Hello', dict(world='how are you?')] - >>> expected == got - True - >>> assert_deepequal(expected, got, doc='Testing my nested data') - Traceback (most recent call last): - ... - AssertionError: assert_deepequal: type(expected) is not type(got). - Testing my nested data - type(expected) = - type(got) = - expected = u'how are you?' - got = 'how are you?' - path = (0, 'world') - - Note that lists and tuples are considered equivalent, and the order of - their elements does not matter. - """ - if isinstance(expected, tuple): - expected = list(expected) - if isinstance(got, tuple): - got = list(got) - if isinstance(expected, DN): - if isinstance(got, basestring): - got = DN(got) - if not (isinstance(expected, Fuzzy) or callable(expected) or type(expected) is type(got)): - raise AssertionError( - TYPE % (doc, type(expected), type(got), expected, got, stack) - ) - if isinstance(expected, (list, tuple)): - if len(expected) != len(got): - raise AssertionError( - LEN % (doc, len(expected), len(got), expected, got, stack) - ) - # Sort list elements, unless they are dictionaries - if expected and isinstance(expected[0], dict): - s_got = got - s_expected = expected - else: - s_got = sorted(got) - s_expected = sorted(expected) - for (i, e_sub) in enumerate(s_expected): - g_sub = s_got[i] - assert_deepequal(e_sub, g_sub, doc, stack + (i,)) - elif isinstance(expected, dict): - missing = set(expected).difference(got) - extra = set(got).difference(expected) - if missing or extra: - raise AssertionError(KEYS % ( - doc, sorted(missing), sorted(extra), expected, got, stack - ) - ) - for key in sorted(expected): - e_sub = expected[key] - g_sub = got[key] - assert_deepequal(e_sub, g_sub, doc, stack + (key,)) - elif callable(expected): - if not expected(got): - raise AssertionError( - VALUE % (doc, expected, got, stack) - ) - elif expected != got: - raise AssertionError( - VALUE % (doc, expected, got, stack) - ) - - -def raises(exception, callback, *args, **kw): - """ - Tests that the expected exception is raised; raises ExceptionNotRaised - if test fails. - """ - raised = False - try: - callback(*args, **kw) - except exception, e: - raised = True - if not raised: - raise ExceptionNotRaised(exception) - return e - - -def getitem(obj, key): - """ - Works like getattr but for dictionary interface. Use this in combination - with raises() to test that, for example, KeyError is raised. - """ - return obj[key] - - -def setitem(obj, key, value): - """ - Works like setattr but for dictionary interface. Use this in combination - with raises() to test that, for example, TypeError is raised. - """ - obj[key] = value - - -def delitem(obj, key): - """ - Works like delattr but for dictionary interface. Use this in combination - with raises() to test that, for example, TypeError is raised. - """ - del obj[key] - - -def no_set(obj, name, value='some_new_obj'): - """ - Tests that attribute cannot be set. - """ - raises(AttributeError, setattr, obj, name, value) - - -def no_del(obj, name): - """ - Tests that attribute cannot be deleted. - """ - raises(AttributeError, delattr, obj, name) - - -def read_only(obj, name, value='some_new_obj'): - """ - Tests that attribute is read-only. Returns attribute. - """ - # Test that it cannot be set: - no_set(obj, name, value) - - # Test that it cannot be deleted: - no_del(obj, name) - - # Return the attribute - return getattr(obj, name) - - -def is_prop(prop): - return type(prop) is property - - -class ClassChecker(object): - __cls = None - __subcls = None - - def __get_cls(self): - if self.__cls is None: - self.__cls = self._cls - assert inspect.isclass(self.__cls) - return self.__cls - cls = property(__get_cls) - - def __get_subcls(self): - if self.__subcls is None: - self.__subcls = self.get_subcls() - assert inspect.isclass(self.__subcls) - return self.__subcls - subcls = property(__get_subcls) - - def get_subcls(self): - raise NotImplementedError( - self.__class__.__name__, - 'get_subcls()' - ) - - def tearDown(self): - """ - nose tear-down fixture. - """ - context.__dict__.clear() - - - - - - - - -def check_TypeError(value, type_, name, callback, *args, **kw): - """ - Tests a standard TypeError raised with `errors.raise_TypeError`. - """ - e = raises(TypeError, callback, *args, **kw) - assert e.value is value - assert e.type is type_ - assert e.name == name - assert type(e.name) is str - assert str(e) == ipalib.errors.TYPE_ERROR % (name, type_, value) - return e - - -def get_api(**kw): - """ - Returns (api, home) tuple. - - This function returns a tuple containing an `ipalib.plugable.API` - instance and a `TempHome` instance. - """ - home = TempHome() - api = ipalib.create_api(mode='unit_test') - api.env.in_tree = True - for (key, value) in kw.iteritems(): - api.env[key] = value - return (api, home) - - -def create_test_api(**kw): - """ - Returns (api, home) tuple. - - This function returns a tuple containing an `ipalib.plugable.API` - instance and a `TempHome` instance. - """ - home = TempHome() - api = ipalib.create_api(mode='unit_test') - api.env.in_tree = True - for (key, value) in kw.iteritems(): - api.env[key] = value - return (api, home) - - -class PluginTester(object): - __plugin = None - - def __get_plugin(self): - if self.__plugin is None: - self.__plugin = self._plugin - assert issubclass(self.__plugin, Plugin) - return self.__plugin - plugin = property(__get_plugin) - - def register(self, *plugins, **kw): - """ - Create a testing api and register ``self.plugin``. - - This method returns an (api, home) tuple. - - :param plugins: Additional \*plugins to register. - :param kw: Additional \**kw args to pass to `create_test_api`. - """ - (api, home) = create_test_api(**kw) - api.register(self.plugin) - for p in plugins: - api.register(p) - return (api, home) - - def finalize(self, *plugins, **kw): - (api, home) = self.register(*plugins, **kw) - api.finalize() - return (api, home) - - def instance(self, namespace, *plugins, **kw): - (api, home) = self.finalize(*plugins, **kw) - o = api[namespace][self.plugin.__name__] - return (o, api, home) - - def tearDown(self): - """ - nose tear-down fixture. - """ - context.__dict__.clear() - - -class dummy_ugettext(object): - __called = False - - def __init__(self, translation=None): - if translation is None: - translation = u'The translation' - self.translation = translation - assert type(self.translation) is unicode - - def __call__(self, message): - assert self.__called is False - self.__called = True - assert type(message) is str - assert not hasattr(self, 'message') - self.message = message - assert type(self.translation) is unicode - return self.translation - - def called(self): - return self.__called - - def reset(self): - assert type(self.translation) is unicode - assert type(self.message) is str - del self.message - assert self.__called is True - self.__called = False - - -class dummy_ungettext(object): - __called = False - - def __init__(self): - self.translation_singular = u'The singular translation' - self.translation_plural = u'The plural translation' - - def __call__(self, singular, plural, n): - assert type(singular) is str - assert type(plural) is str - assert type(n) is int - assert self.__called is False - self.__called = True - self.singular = singular - self.plural = plural - self.n = n - if n == 1: - return self.translation_singular - return self.translation_plural - - -class DummyMethod(object): - def __init__(self, callback, name): - self.__callback = callback - self.__name = name - - def __call__(self, *args, **kw): - return self.__callback(self.__name, args, kw) - - -class DummyClass(object): - def __init__(self, *calls): - self.__calls = calls - self.__i = 0 - for (name, args, kw, result) in calls: - method = DummyMethod(self.__process, name) - setattr(self, name, method) - - def __process(self, name_, args_, kw_): - if self.__i >= len(self.__calls): - raise AssertionError( - 'extra call: %s, %r, %r' % (name_, args_, kw_) - ) - (name, args, kw, result) = self.__calls[self.__i] - self.__i += 1 - i = self.__i - if name_ != name: - raise AssertionError( - 'call %d should be to method %r; got %r' % (i, name, name_) - ) - if args_ != args: - raise AssertionError( - 'call %d to %r should have args %r; got %r' % (i, name, args, args_) - ) - if kw_ != kw: - raise AssertionError( - 'call %d to %r should have kw %r, got %r' % (i, name, kw, kw_) - ) - if isinstance(result, Exception): - raise result - return result - - def _calledall(self): - return self.__i == len(self.__calls) -- cgit