This is an automated email from the git hooks/post-receive script.
spichugi pushed a commit to branch master
in repository 389-ds-base.
commit 1e28c75c6507df8eeb881cc771a555b658f11ef0
Author: Simon Pichugin <spichugi(a)redhat.com>
Date: Wed Sep 20 12:01:23 2017 +0200
Issue 49381 - Refactor numerous suite docstrings - Part 2
Description: We need to have properly formatted and detailed
docstrings in all existing test suites.
Suites that were changed in this commit:
sasl allowed_mechs, basic, password, replication.
Also, fix create test.py tool, create password policy fixture in
syntax test, in replication move get_repl_entries to __init__.py,
move test_double_delete, test_password_repl_error, test_invalid_agmt
from acceptance_test.py to regression_test.py.
Rename plain.py to plain_test.py
and allowed_mechs.py to allowed_mechs_test.py.
https://pagure.io/389-ds-base/issue/49381
Reviewed by: amsharma, vashirov, wibrown (Thanks!)
---
dirsrvtests/create_test.py | 8 +-
dirsrvtests/tests/suites/basic/basic_test.py | 2 +-
dirsrvtests/tests/suites/password/password_test.py | 17 +-
dirsrvtests/tests/suites/password/pwdAdmin_test.py | 117 ++++++---
.../suites/password/pwdPolicy_attribute_test.py | 61 +++--
.../password/pwdPolicy_inherit_global_test.py | 66 ++---
.../tests/suites/password/pwdPolicy_syntax_test.py | 101 ++++++--
.../suites/password/pwdPolicy_warning_test.py | 238 +++++++++---------
.../suites/password/pwd_lockout_bypass_test.py | 25 ++
.../tests/suites/password/pwp_history_test.py | 38 ++-
.../tests/suites/password/regression_test.py | 32 +--
dirsrvtests/tests/suites/replication/__init__.py | 18 ++
.../tests/suites/replication/acceptance_test.py | 271 +++++++--------------
.../tests/suites/replication/cleanallruv_test.py | 227 ++++++++++-------
.../tests/suites/replication/regression_test.py | 174 +++++++++++++
.../tests/suites/replication/single_master_test.py | 41 ++--
.../tests/suites/replication/tombstone_test.py | 17 +-
.../replication/wait_for_async_feature_test.py | 57 ++++-
.../{allowed_mechs.py => allowed_mechs_test.py} | 78 ++++--
.../tests/suites/sasl/{plain.py => plain_test.py} | 2 +-
20 files changed, 1019 insertions(+), 571 deletions(-)
diff --git a/dirsrvtests/create_test.py b/dirsrvtests/create_test.py
index 4902f7b..f5f988c 100755
--- a/dirsrvtests/create_test.py
+++ b/dirsrvtests/create_test.py
@@ -210,9 +210,10 @@ if len(sys.argv) > 0:
if my_topology[0]:
topology_import = 'from lib389.topologies import {} as
topo\n'.format(my_topology[1])
else:
- topology_import = ''
+ topology_import = 'from lib389.topologies import create_topology\n'
TEST.write('import logging\nimport pytest\nimport os\n')
+ TEST.write('from lib389._constants import *\n')
TEST.write('{}\n'.format(topology_import))
TEST.write('DEBUGGING = os.getenv("DEBUGGING", default=False)\n')
@@ -220,7 +221,7 @@ if len(sys.argv) > 0:
TEST.write(' logging.getLogger(__name__).setLevel(logging.DEBUG)\n')
TEST.write('else:\n')
TEST.write(' logging.getLogger(__name__).setLevel(logging.INFO)\n')
- TEST.write('log = logging.getLogger(__name__)\n\n\n')
+ TEST.write('log = logging.getLogger(__name__)\n\n')
# Add topology function for non existing (in lib389/topologies.py) topologies only
if not my_topology[0]:
@@ -236,7 +237,7 @@ if len(sys.argv) > 0:
topologies_str += " {} standalone instances".format(instances)
# Write the 'topology function'
- TEST.write('(a)pytest.fixture(scope="module")\n')
+ TEST.write('\n(a)pytest.fixture(scope="module")\n')
TEST.write('def topo(request):\n')
TEST.write(' """Create a topology
with{}"""\n\n'.format(topologies_str))
TEST.write(' topology = create_topology({\n')
@@ -255,6 +256,7 @@ if len(sys.argv) > 0:
TEST.write(' # replicas.test(DEFAULT_SUFFIX,
topology.cs["consumer1"])\n')
writeFinalizer()
+ TEST.write(' return topology\n\n')
tc_id = '0'
while not check_id_uniqueness(tc_id): tc_id = uuid.uuid4()
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py
b/dirsrvtests/tests/suites/basic/basic_test.py
index 45988dc..40ffde8 100644
--- a/dirsrvtests/tests/suites/basic/basic_test.py
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
@@ -580,7 +580,7 @@ def test_basic_referrals(topology_st, import_example_ldif):
:setup: Standalone instance
:steps:
- 1. Set the referral and the backenidealyd state
+ 1. Set the referral and the backend state
2. Set backend state to referral mode.
3. Set server to not follow referral.
4. Search using referral.
diff --git a/dirsrvtests/tests/suites/password/password_test.py
b/dirsrvtests/tests/suites/password/password_test.py
index 860192f..b08c6b0 100644
--- a/dirsrvtests/tests/suites/password/password_test.py
+++ b/dirsrvtests/tests/suites/password/password_test.py
@@ -18,9 +18,22 @@ log = logging.getLogger(__name__)
def test_password_delete_specific_password(topology_st):
- """ Delete a specific userpassword, and make sure
+ """Delete a specific userPassword, and make sure
it is actually deleted from the entry
- """
+
+ :id: 800f432a-52ab-4661-ac66-a2bdd9b984d6
+ :setup: Standalone instance
+ :steps:
+ 1. Add a user with userPassword attribute in cleartext
+ 2. Delete the added value of userPassword attribute
+ 3. Check if the userPassword attribute is deleted
+ 4. Delete the user
+ :expectedresults:
+ 1. The user with userPassword in cleartext should be added successfully
+ 2. Operation should be successful
+ 3. UserPassword should be deleted
+ 4. The user should be successfully deleted
+ """
log.info('Running test_password_delete_specific_password...')
diff --git a/dirsrvtests/tests/suites/password/pwdAdmin_test.py
b/dirsrvtests/tests/suites/password/pwdAdmin_test.py
index b49e10d..0d13936 100644
--- a/dirsrvtests/tests/suites/password/pwdAdmin_test.py
+++ b/dirsrvtests/tests/suites/password/pwdAdmin_test.py
@@ -28,13 +28,16 @@ ENTRY_DN = 'cn=%s,%s' % (ENTRY_NAME, SUFFIX)
INVALID_PWDS = ('2_Short', 'No_Number', 'N0Special',
'{SSHA}bBy8UdtPZwu8uZna9QOYG3Pr41RpIRVDl8wddw==')
-def test_pwdAdmin_init(topology_st):
- '''
- Create our future Password Admin entry, set the password policy, and test
- that its working
- '''
+(a)pytest.fixture(scope="module")
+def password_policy(topology_st):
+ """Set up password policy
+ Create a Password Admin entry;
+ Set up password policy attributes in config;
+ Add an aci to give everyone full access;
+ Test that the setup works
+ """
- log.info('test_pwdAdmin_init: Creating Password Administator entries...')
+ log.info('test_pwdAdmin_init: Creating Password Administrator entries...')
# Add Password Admin 1
try:
@@ -100,7 +103,7 @@ def test_pwdAdmin_init(topology_st):
#
# Bind as the future Password Admin
#
- log.info('test_pwdAdmin_init: Bind as the Password Administator (before
activating)...')
+ log.info('test_pwdAdmin_init: Bind as the Password Administrator (before
activating)...')
try:
topology_st.standalone.simple_bind_s(ADMIN_DN, ADMIN_PWD)
except ldap.LDAPError as e:
@@ -139,19 +142,61 @@ def test_pwdAdmin_init(topology_st):
assert False
-def test_pwdAdmin(topology_st):
- '''
- Test that password administrators/root DN can
- bypass password syntax/policy.
-
- We need to test how passwords are modified in
- existing entries, and when adding new entries.
-
- Create the Password Admin entry, but do not set
- it as an admin yet. Use the entry to verify invalid
- passwords are caught. Then activate the password
- admin and make sure it can bypass password policy.
- '''
+def test_pwdAdmin(topology_st, password_policy):
+ """Test that password administrators/root DN can
+ bypass password syntax/policy
+
+ :id: 5ce316d8-88ef-4248-8b63-90736985dad5
+ :setup: Standalone instance, Password Admin entry,
+ Password policy configured as below:
+ nsslapd-pwpolicy-local: on
+ passwordCheckSyntax: on
+ passwordMinCategories: 1
+ passwordMinTokenLength: 1
+ passwordExp: on
+ passwordMinDigits: 1
+ passwordMinSpecials: 1
+ :steps:
+ 1. Bind as Root DN
+ 2. Set passwordAdminDn to our admin entry DN
+ 3. Bind as Password Admin
+ 4. Add entries with invalid passwords
+ 5. Delete the entries after each pass
+ 6. Add the entry for the next round of testing
+ 7. Bind as root DN
+ 8. Remove passwordAdminDN attribute
+ 9. Bind as Password Admin (admin rights are revoked)
+ 10. Make invalid password updates
+ 11. Bind as root DN to make the update
+ 12. Set passwordAdminDn to our admin entry DN
+ 13. Bind as Password Admin
+ 14. Make the same password updates
+ 15. Bind as root DN to make the update
+ 16. Set passwordAdminDn to admin group entry
+ 17. Bind as admin2
+ 18. Make some invalid password updates
+ 19. Bind back as Root DN
+ :expectedresults:
+ 1. Bind should be successful
+ 2. passwordAdminDn should be set successful
+ 3. Bind should be successful
+ 4. The entries should be successfully added
+ 5. The entries should be successfully deleted
+ 6. The entry should be successfully added
+ 7. Bind should be successful
+ 8. passwordAdminDn should be removed successful
+ 9. Bind should be successful
+ 10. Invalid password updates should fail
+ 11. Bind should be successful
+ 12. passwordAdminDn should be set successful
+ 13. Bind should be successful
+ 14. The same password updates should pass now
+ 15. Bind should be successful
+ 16. passwordAdminDn should be set successful
+ 17. Bind should be successful
+ 18. The same password updates should pass now
+ 19. Bind should be successful
+ """
#
# Now activate a password administator, bind as root dn to do the config
@@ -160,7 +205,7 @@ def test_pwdAdmin(topology_st):
log.info('test_pwdAdmin: Activate the Password Administator...')
#
- # Setup our test entry, and test password policy is working
+ # Get our test entry
#
entry = Entry(ENTRY_DN)
entry.setValues('objectclass', 'top', 'person')
@@ -361,14 +406,28 @@ def test_pwdAdmin(topology_st):
assert False
-def test_pwdAdmin_config_validation(topology_st):
- '''
- Test config validation:
-
- - Test adding multiple passwordAdminDN attributes
- - Test adding invalid values(non-DN's)
- '''
- # Add mulitple attributes - one already eists so just try and add as second one
+def test_pwdAdmin_config_validation(topology_st, password_policy):
+ """Check passwordAdminDN for valid and invalid values
+
+ :id: f7049482-41e8-438b-ae18-cdd2612c783a
+ :setup: Standalone instance, Password Admin entry,
+ Password policy configured as below:
+ nsslapd-pwpolicy-local: on
+ passwordCheckSyntax: on
+ passwordMinCategories: 1
+ passwordMinTokenLength: 1
+ passwordExp: on
+ passwordMinDigits: 1
+ passwordMinSpecials: 1
+ :steps:
+ 1. Add multiple attributes - one already exists so just try and add the second
one
+ 2. Set passwordAdminDN attribute to an invalid value (ZZZZZ)
+ :expectedresults:
+ 1. The operation should fail
+ 2. The operation should fail
+ """
+
+ # Add multiple attributes - one already exists so just try and add the second one
try:
topology_st.standalone.modify_s(CONFIG_DN, [(ldap.MOD_ADD,
'passwordAdminDN', ENTRY_DN)])
log.fatal('test_pwdAdmin_config_validation: Incorrectly was able to add two
config attributes')
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py
b/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py
index 9d77c7b..b3ef61d 100644
--- a/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py
@@ -127,19 +127,22 @@ def test_change_pwd(topology_st, test_user, password_policy,
"""Verify that 'passwordChange' attr works as expected
User should have a priority over a subtree.
- :feature: Password policy
-
- :setup: Standalone instance, test user,
+ :id: 2c884432-2ba1-4662-8e5d-2cd49f77e5fa
+ :setup: Standalone instance, a test user,
password policy entries for a user and a subtree
-
- :steps: 1. Set passwordChange on the user and the subtree
- to various combinations
- 2. Bind as test user
- 3. Try to change password
-
- :expectedresults: Subtree/User passwordChange - result
- off/on, on/on - success
- on/off, off/off - UNWILLING_TO_PERFORM
+ :steps:
+ 1. Set passwordChange on the user and the subtree
+ to various combinations
+ 2. Bind as test user
+ 3. Try to change password
+ 4. Clean up - change the password to default while bound as DM
+ :expectedresults:
+ 1. passwordChange should be successfully set
+ 2. Bind should be successful
+ 3. Subtree/User passwordChange - result, accordingly:
+ off/on, on/on - success;
+ on/off, off/off - UNWILLING_TO_PERFORM
+ 4. Operation should be successful
"""
log.info('Set passwordChange to "{}" -
{}'.format(subtree_pwchange,
@@ -196,21 +199,27 @@ def test_pwd_min_age(topology_st, test_user, password_policy):
should not allow the user to change the password within 10 seconds after
his previous change.
- :ID: 85b98516-8c82-45bd-b9ec-90bd1245e09c
- :feature: Password policy
- :setup: Standalone instance, test user,
+ :id: 85b98516-8c82-45bd-b9ec-90bd1245e09c
+ :setup: Standalone instance, a test user,
password policy entries for a user and a subtree
- :steps: 1. Set passwordMinAge to 10 on the user pwpolicy entry
- 2. Set passwordMinAge to 10 on the subtree pwpolicy entry
- 3. Set passwordMinAge to 10 on the cn=config entry
- 4. Bind as test user
- 5. Try to change password two times in a row
- 6. Wait 12 seconds
- 7. Try to change password
- :expectedresults: User should be not allowed to change the password
- right after previous change - CONSTRAINT_VIOLATION
- User should be not allowed to change the password
- after 12 seconds passed
+ :steps:
+ 1. Set passwordMinAge to 10 on the user pwpolicy entry
+ 2. Set passwordMinAge to 10 on the subtree pwpolicy entry
+ 3. Set passwordMinAge to 10 on the cn=config entry
+ 4. Bind as test user
+ 5. Try to change the password two times in a row
+ 6. Wait 12 seconds
+ 7. Try to change the password
+ 8. Clean up - change the password to default while bound as DM
+ :expectedresults:
+ 1. passwordMinAge should be successfully set on the user pwpolicy entry
+ 2. passwordMinAge should be successfully set on the subtree pwpolicy entry
+ 3. passwordMinAge should be successfully set on the cn=config entry
+ 4. Bind should be successful
+ 5. The password should be successfully changed
+ 6. 12 seconds have passed
+ 7. Constraint Violation error should be raised
+ 8. Operation should be successful
"""
num_seconds = '10'
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_inherit_global_test.py
b/dirsrvtests/tests/suites/password/pwdPolicy_inherit_global_test.py
index 828a2d3..823cfda 100644
--- a/dirsrvtests/tests/suites/password/pwdPolicy_inherit_global_test.py
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_inherit_global_test.py
@@ -139,25 +139,23 @@ def check_attr_val(topology_st, dn, attr, expected):
[('off', 'off'), ('on', 'off'),
('off', 'on')])
def test_entry_has_no_restrictions(topology_st, password_policy, test_user,
inherit_value, checksyntax_value):
- """Make sure an entry added to ou=people
- has no password syntax restrictions when:
- - 'passwordCheckSyntax' is 'off' for
'nsslapd-pwpolicy-inherit-global'
- equaled 'off' and 'on'
- - 'passwordCheckSyntax' is 'on' for
'nsslapd-pwpolicy-inherit-global'
- equaled 'off'
-
- :ID: 2f07ff40-76ca-45a9-a556-331c94084945
- :feature: Password policy
+ """Make sure an entry added to ou=people has no password syntax
restrictions
+
+ :id: 2f07ff40-76ca-45a9-a556-331c94084945
:setup: Standalone instance, test user,
password policy entries for a subtree
- :steps: 1. Bind as test user
- 2. Set 'nsslapd-pwpolicy-inherit-global' and
- 'passwordCheckSyntax' accordingly:
- a) 'off' and 'off'
- b) 'on' and 'off'
- c) 'off' and 'on'
- 3. Try to add user with a short password
- :expectedresults: No exception should occure
+ :steps:
+ 1. Bind as test user
+ 2. Set 'nsslapd-pwpolicy-inherit-global' and
+ 'passwordCheckSyntax' accordingly:
+ 'off' and 'off'; 'on' and 'off'; 'off'
and 'on'
+ 3. Try to add user with a short password
+ 4. Cleanup - remove temp user bound as DM
+ :expectedresults:
+ 1. Bind should be successful
+ 2. Attributes should be successfully set
+ 3. No exceptions should occur
+ 4. Operation should be successful
"""
log.info('Set {} to {}'.format(ATTR_INHERIT_GLOBAL, inherit_value))
@@ -203,24 +201,30 @@ def test_entry_has_no_restrictions(topology_st, password_policy,
test_user,
@pytest.mark.parametrize('container', [DN_CONFIG, PWP_CONTAINER_PEOPLE])
def test_entry_has_restrictions(topology_st, password_policy, test_user, container):
- """Set 'nsslapd-pwpolicy-inherit-global: on'
- and 'passwordCheckSyntax: on'. Make sure that
- syntax rules work, if set them at both: cn=config and
+ """Set 'nsslapd-pwpolicy-inherit-global: on' and
'passwordCheckSyntax: on'.
+ Make sure that syntax rules work, if set them at both: cn=config and
ou=people policy container.
- :ID: 4bb0f474-17c1-40f7-aab4-4ddc17d019e8
- :feature: Password policy
+ :id: 4bb0f474-17c1-40f7-aab4-4ddc17d019e8
:setup: Standalone instance, test user,
password policy entries for a subtree
- :steps: 1. Bind as test user
- 2. Switch 'nsslapd-pwpolicy-inherit-global: on'
- 3. Switch 'passwordCheckSyntax: on'
- 4. Set 'passwordMinLength: 9' to:
- a) cn=config
- b) ou=people policy container
- 5. Try to add user with a short password (<9)
- 6. Try to add user with a long password (>9)
- :expectedresults: User should be rejected
+ :steps:
+ 1. Bind as test user
+ 2. Switch 'nsslapd-pwpolicy-inherit-global: on'
+ 3. Switch 'passwordCheckSyntax: on'
+ 4. Set 'passwordMinLength: 9' to:
+ cn=config and ou=people policy container
+ 5. Try to add user with a short password (<9)
+ 6. Try to add user with a long password (>9)
+ 7. Cleanup - remove temp users bound as DM
+ :expectedresults:
+ 1. Bind should be successful
+ 2. nsslapd-pwpolicy-inherit-global should be successfully set
+ 3. passwordCheckSyntax should be successfully set
+ 4. passwordMinLength should be successfully set
+ 5. User should be rejected
+ 6. User should be rejected
+ 7. Operation should be successful
"""
log.info('Set {} to {}'.format(ATTR_INHERIT_GLOBAL, 'on'))
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
b/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
index 1464233..5737303 100644
--- a/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
@@ -22,9 +22,21 @@ logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)
-def _create_user(inst):
+(a)pytest.fixture(scope="module")
+def password_policy(topology_st):
+ """Set global password policy"""
+
+ log.info('Enable global password policy. Check for syntax.')
+ topology_st.standalone.config.set('passwordCheckSyntax', 'on')
+ topology_st.standalone.config.set('nsslapd-pwpolicy-local', 'off')
+ topology_st.standalone.config.set('passwordMinCategories', '1')
+
+
+(a)pytest.fixture(scope="module")
+def test_user(topology_st):
"""Create the test user."""
- inst.add_s(Entry((
+
+ topology_st.standalone.add_s(Entry((
USER_DN, {
'objectClass': 'top account simplesecurityobject'.split(),
'uid': 'user',
@@ -34,6 +46,7 @@ def _create_user(inst):
def setPolicy(inst, attr, value):
"""Bind as ROot DN, set polcy, and then bind as
user"""
+
try:
inst.simple_bind_s(DN_DM, PASSWORD)
except ldap.LDAPError as e:
@@ -117,22 +130,82 @@ def tryPassword(inst, policy_attr, value, reset_value, pw_bad,
pw_good, msg):
setPolicy(inst, policy_attr, reset_value)
-def test_pwdPolicy_syntax(topology_st):
- '''
- Password policy test: Ensure that on a password change, the policy syntax
+def test_basic(topology_st, test_user, password_policy):
+ """Ensure that on a password change, the policy syntax
is enforced correctly.
- '''
-
- # Create a user
- _create_user(topology_st.standalone)
- # Set the password policy globally
- topology_st.standalone.config.set('passwordCheckSyntax', 'on')
- topology_st.standalone.config.set('nsslapd-pwpolicy-local', 'off')
- topology_st.standalone.config.set('passwordMinCategories', '1')
+ :id: e8de7029-7fa6-4e96-9eb6-4a121f4c8fb3
+ :setup: Standalone instance, a test user,
+ global password policy with:
+ passwordCheckSyntax - on; nsslapd-pwpolicy-local - off;
+ passwordMinCategories - 1
+ :steps:
+ 1. Set passwordMinLength to 10 in cn=config
+ 2. Set userPassword to 'passwd' in cn=config
+ 3. Set userPassword to 'password123' in cn=config
+ 4. Set passwordMinLength to 2 in cn=config
+ 5. Set passwordMinDigits to 2 in cn=config
+ 6. Set userPassword to 'passwd' in cn=config
+ 7. Set userPassword to 'password123' in cn=config
+ 8. Set passwordMinDigits to 0 in cn=config
+ 9. Set passwordMinAlphas to 2 in cn=config
+ 10. Set userPassword to 'p123456789' in cn=config
+ 11. Set userPassword to 'password123' in cn=config
+ 12. Set passwordMinAlphas to 0 in cn=config
+ 13. Set passwordMaxRepeats to 2 in cn=config
+ 14. Set userPassword to 'password' in cn=config
+ 15. Set userPassword to 'password123' in cn=config
+ 16. Set passwordMaxRepeats to 0 in cn=config
+ 17. Set passwordMinSpecials to 2 in cn=config
+ 18. Set userPassword to 'passwd' in cn=config
+ 19. Set userPassword to 'password_#$' in cn=config
+ 20. Set passwordMinSpecials to 0 in cn=config
+ 21. Set passwordMinLowers to 2 in cn=config
+ 22. Set userPassword to 'PASSWORD123' in cn=config
+ 23. Set userPassword to 'password123' in cn=config
+ 24. Set passwordMinLowers to 0 in cn=config
+ 25. Set passwordMinUppers to 2 in cn=config
+ 26. Set userPassword to 'password' in cn=config
+ 27. Set userPassword to 'PASSWORD' in cn=config
+ 28. Set passwordMinUppers to 0 in cn=config
+ :expectedresults:
+ 1. passwordMinLength should be successfully set
+ 2. Password should be rejected because length too short
+ 3. Password should be accepted
+ 4. passwordMinLength should be successfully set
+ 5. passwordMinDigits should be successfully set
+ 6. Password should be rejected because
+ it does not contain minimum number of digits
+ 7. Password should be accepted
+ 8. passwordMinDigits should be successfully set
+ 9. passwordMinAlphas should be successfully set
+ 10. Password should be rejected because
+ it does not contain minimum number of alphas
+ 11. Password should be accepted
+ 12. passwordMinAlphas should be successfully set
+ 13. passwordMaxRepeats should be successfully set
+ 14. Password should be rejected because too many repeating characters
+ 15. Password should be accepted
+ 16. passwordMaxRepeats should be successfully set
+ 17. passwordMinSpecials should be successfully set
+ 18. Password should be rejected because
+ it does not contain minimum number of special characters
+ 19. Password should be accepted
+ 20. passwordMinSpecials should be successfully set
+ 21. passwordMinLowers should be successfully set
+ 22. Password should be rejected because
+ it does not contain minimum number of lowercase characters
+ 23. Password should be accepted
+ 24. passwordMinLowers should be successfully set
+ 25. passwordMinUppers should be successfully set
+ 26. Password should be rejected because
+ it does not contain minimum number of lowercase characters
+ 27. Password should be accepted
+ 28. passwordMinUppers should be successfully set
+ """
#
- # Test each syntax catagory
+ # Test each syntax category
#
# Min Length
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_warning_test.py
b/dirsrvtests/tests/suites/password/pwdPolicy_warning_test.py
index 1b955c6..10775ff 100644
--- a/dirsrvtests/tests/suites/password/pwdPolicy_warning_test.py
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_warning_test.py
@@ -238,17 +238,20 @@ def test_different_values(topology_st, value):
"""Try to set passwordSendExpiringTime attribute
to various values both valid and invalid
- :ID: 3e6d79fb-b4c8-4860-897e-5b207815a75d
- :feature: Password Expiry Warning Time
- :setup: Standalone DS instance
- :steps: 1. Try to set valid and invalid values
- for passwordSendExpiringTime attribute
- under cn=config entry
- 2. Run the search command to check the
- value of passwordSendExpiringTime attribute
- :expectedresults: 1. Invalid values should be rejected with
- an OPERATIONS_ERROR
- 2. Valid values should be accepted and saved
+ :id: 3e6d79fb-b4c8-4860-897e-5b207815a75d
+ :setup: Standalone instance
+ :steps:
+ 1. Try to set passwordSendExpiringTime to 'on' and 'off'
+ under cn=config entry
+ 2. Try to set passwordSendExpiringTime to ' ' and 'junk123'
+ under cn=config entry
+ 3. Run the search command to check the
+ value of passwordSendExpiringTime attribute
+ :expectedresults:
+ 1. Valid values should be accepted and saved
+ 2. Should be rejected with an OPERATIONS_ERROR
+ 3. The attribute should be changed for valid values
+ and unchanged for invalid
"""
log.info('Get the default value')
@@ -280,19 +283,21 @@ def test_expiry_time(topology_st, global_policy, add_user):
"""Test whether the password expiry warning
time for a user is returned appropriately
- :ID: 7adfd395-9b25-4cc0-9b71-14710dc1a28c
- :feature: Pasword Expiry Warning Time
- :setup: Standalone DS instance with,
- 1. Global password policy configured as below:
- passwordExp: on
- passwordMaxAge: 172800
- passwordWarning: 86400
- passwordSendExpiringTime: on
- 2. User entry for binding
- :steps: 1. Bind as the user
- 2. Request the control for the user
- :expectedresults: The password expiry warning time for the user should be
- returned
+ :id: 7adfd395-9b25-4cc0-9b71-14710dc1a28c
+ :setup: Standalone instance, a user entry,
+ Global password policy configured as below:
+ passwordExp: on
+ passwordMaxAge: 172800
+ passwordWarning: 86400
+ passwordSendExpiringTime: on
+ :steps:
+ 1. Bind as the normal user
+ 2. Request password policy control for the user
+ 3. Bind as DM
+ :expectedresults:
+ 1. Bind should be successful
+ 2. The password expiry warning time for the user should be returned
+ 3. Bind should be successful
"""
res_ctrls = None
@@ -315,27 +320,28 @@ def test_expiry_time(topology_st, global_policy, add_user):
@pytest.mark.parametrize("attr,val", [(CONFIG_ATTR, 'off'),
('passwordWarning', '3600')])
def test_password_warning(topology_st, global_policy, add_user, attr, val):
- """Test password expiry warning time by
- setting passwordSendExpiringTime to off
+ """Test password expiry warning time by setting
passwordSendExpiringTime to off
and setting passwordWarning to a short value
- :ID: 39f54b3c-8c80-43ca-856a-174d81c56ce8
- :feature: Password Expiry Warning Time
- :setup: Standalone DS instance with,
- 1. Global password policy configures as below:
- passwordExp: on
- passwordMaxAge: 172800
- passwordWarning: 86400
- passwordSendExpiringTime: on
- 2. User entry for binding
- :steps: 1a. Set passwordSendExpiringTime attribute to off.
- 1b. In the another attempt, try to set passwordWarning
- to a small value (for eg: 3600 seconds)
- 2. Bind as the user
- 3a. Request the control for the user
- 3b. Request the password expiry warning time
- :expectedresults: a. Password expiry warning time should not be returned
- b. Password expiry warning time should be returned
+ :id: 39f54b3c-8c80-43ca-856a-174d81c56ce8
+ :setup: Standalone instance, a test user,
+ Global password policy configured as below:
+ passwordExp: on
+ passwordMaxAge: 172800
+ passwordWarning: 86400
+ passwordSendExpiringTime: on
+ :steps:
+ 1. Set passwordSendExpiringTime attribute to off or
+ to on and passwordWarning to a small value (3600)
+ 2. Bind as the normal user
+ 3. Request the password expiry warning time
+ 4. Bind as DM
+ :expectedresults:
+ 1. passwordSendExpiringTime and passwordWarning are set successfully
+ 2. Bind should be successful
+ 3. Password expiry warning time should be returned for the small value
+ and should not be returned when passwordSendExpiringTime is off
+ 4. Bind should be successful
"""
try:
@@ -361,32 +367,33 @@ def test_password_warning(topology_st, global_policy, add_user,
attr, val):
def test_with_different_password_states(topology_st, global_policy, add_user):
"""Test the control with different password states
- :ID: d297fb1a-661f-4d52-bb43-2a2a340b8b0e
- :feature: Password Expiry Warning Time
- :setup: Standalone DS instance with,
- 1. Global password policy configured as below:
- passwordExp: on
- passwordMaxAge: 172800
- passwordWarning: 86400
- passwordSendExpiringTime: on
- 2. User entry for binding to the server
- :steps: 1. Expire user's password by setting the system
- date past the valid period for the password
- 2. Try to bind to the server with the user entry
- 3. Set the system date to the current day
- 4. Try to bind with the user entry and request
- the control
+ :id: d297fb1a-661f-4d52-bb43-2a2a340b8b0e
+ :setup: Standalone instance, a user entry,
+ Global password policy configured as below:
+ passwordExp: on
+ passwordMaxAge: 172800
+ passwordWarning: 86400
+ passwordSendExpiringTime: on
+ :steps:
+ 1. Expire user's password by changing
+ passwordExpirationTime timestamp
+ 2. Try to bind to the server with the user entry
+ 3. Revert back user's passwordExpirationTime
+ 4. Try to bind with the user entry and request
+ the control
+ 5. Bind as DM
:expectedresults:
- 1. In the first try, the bind should fail with an
- INVALID_CREDENTIALS error
- 2. In the second try, the bind should be successful
- and the password expiry warning time should be
- returned
+ 1. Operation should be successful
+ 2. Operation should fail because of Invalid Credentials
+ 3. passwordExpirationTime is successfully changed
+ 4. Bind should be successful and the password expiry
+ warning time should be returned
+ 5. Bind should be successful
"""
res_ctrls = None
- log.info("Expiring user's password by changing" \
+ log.info("Expire user's password by changing" \
"passwordExpirationTime timestamp")
old_ts = topology_st.standalone.search_s(USER_DN, ldap.SCOPE_SUBTREE,
'(objectClass=*)',
['passwordExpirationTime'])[0].getValue('passwordExpirationTime')
@@ -426,23 +433,23 @@ def test_with_different_password_states(topology_st, global_policy,
add_user):
def test_default_behavior(topology_st, global_policy_default, add_user):
- """Test the default behavior of password
- expiry warning time
-
- :ID: c47fa824-ee08-4b78-885f-bca4c42bb655
- :feature: Password Expiry Warning Time
- :setup: Standalone DS instance with,
- 1. Global password policy configured as follows,
- passwordExp: on
- passwordMaxAge: 8640000
- passwordWarning: 86400
- passwordSendExpiringTime: off
- 2. User entry for binding to the server
- :steps: 1. Bind as the user
- 2. Request the control for the user
+ """Test the default behavior of password expiry warning time
+
+ :id: c47fa824-ee08-4b78-885f-bca4c42bb655
+ :setup: Standalone instance, a user entry,
+ Global password policy configured as below:
+ passwordExp: on
+ passwordMaxAge: 8640000
+ passwordWarning: 86400
+ passwordSendExpiringTime: off
+ :steps:
+ 1. Bind as the normal user
+ 2. Request the control for the user
+ 3. Bind as DM
:expectedresults:
- 1. Bind should be successful
- 2. No control should be returned
+ 1. Bind should be successful
+ 2. No control should be returned
+ 3. Bind should be successful
"""
res_ctrls = None
@@ -464,23 +471,24 @@ def test_when_maxage_and_warning_are_the_same(topology_st,
global_policy_default
passwordWarning are set to the same value.
:id: e57a1b1c-96fc-11e7-a91b-28d244694824
- :feature: Password Expiry Warning Time
- :setup: Standalone DS instance with,
- 1. Global password policy configured as follows,
- passwordExp: on
- passwordMaxAge: 86400
- passwordWarning: 86400
- passwordSendExpiringTime: off
- 2. User entry for binding to the server
- :steps: 1. Bind as the user
- 2. Change user's password to reset its password expiration time
- 3. Request the control for the user
+ :setup: Standalone instance, a user entry,
+ Global password policy configured as below:
+ passwordExp: on
+ passwordMaxAge: 86400
+ passwordWarning: 86400
+ passwordSendExpiringTime: off
+ :steps:
+ 1. Bind as the normal user
+ 2. Change user's password to reset its password expiration time
+ 3. Request the control for the user
+ 4. Bind as DM
:expectedresults:
- 1. Bind should be successful
- 2. Password should be changed and password's expiration time reset
- 3. Password expiry warning time should be returned by the
- server since passwordMaxAge and passwordWarning are set
- to the same value
+ 1. Bind should be successful
+ 2. Password should be changed and password's expiration time reset
+ 3. Password expiry warning time should be returned by the
+ server since passwordMaxAge and passwordWarning are set
+ to the same value
+ 4. Bind should be successful
"""
log.info('Set the new values')
@@ -509,26 +517,24 @@ def test_when_maxage_and_warning_are_the_same(topology_st,
global_policy_default
def test_with_local_policy(topology_st, global_policy, local_policy):
- """Test the attribute with fine grained policy
- set for the user
-
- :ID: ab7d9f86-8cfe-48c3-8baa-739e599f006a
- :feature: Password Expiry Warning Time
- :setup: Standalone DS instance with,
- 1. Global password policy configured as below,
- passwordExp: on
- passwordMaxAge: 172800
- passwordWarning: 86400
- passwordSendExpiringTime: on
- 2. User entry for binding to the server
- 3. Configure fine grained password policy for the user
- as below:
- ns-newpwpolicy.pl -D 'cn=Directory Manager' -w secret123
- -h localhost -p 389 -U 'uid=tuser,dc=example,dc=com'
- :steps: 1. Bind as the user
- 2. Request the control for the user
- :expectedresults: Password expiry warning time should not be returned for the
- user
+ """Test the attribute with fine grained policy set for the user
+
+ :id: ab7d9f86-8cfe-48c3-8baa-739e599f006a
+ :setup: Standalone instance, a user entry,
+ Global password policy configured as below:
+ passwordExp: on
+ passwordMaxAge: 172800
+ passwordWarning: 86400
+ passwordSendExpiringTime: on
+ Fine grained password policy for the user using ns-newpwpolicy.pl
+ :steps:
+ 1. Bind as the normal user
+ 2. Request the control for the user
+ 3. Bind as DM
+ :expectedresults:
+ 1. Bind should be successful
+ 2. Password expiry warning time should not be returned for the user
+ 3. Bind should be successful
"""
res_ctrls = None
diff --git a/dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py
b/dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py
index e4add72..1a0aef1 100644
--- a/dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py
+++ b/dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py
@@ -20,7 +20,32 @@ BAD_PASSWORD = 'aontseunao'
logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)
+
def test_lockout_bypass(topology_st):
+ """Check basic password lockout functionality
+
+ :id: 2482a992-1719-495c-b75b-78fe5c48c873
+ :setup: Standalone instance
+ :steps:
+ 1. Set passwordMaxFailure to 1
+ 2. Set passwordLockDuration to 7
+ 3. Set passwordLockout to 'on'
+ 4. Create a user
+ 5. Set a userPassword attribute
+ 6. Bind as the user with a bad credentials
+ 7. Bind as the user with a bad credentials
+ 8. Bind as the user with a good credentials
+ :expectedresults:
+ 1. passwordMaxFailure should be successfully set
+ 2. passwordLockDuration should be successfully set
+ 3. passwordLockout should be successfully set
+ 4. User should be created
+ 5. userPassword should be successfully set
+ 6. Should throw an invalid credentials error
+ 7. Should throw a constraint violation error
+ 8. Should throw a constraint violation error
+ """
+
inst = topology_st.standalone
# Configure the lock policy
diff --git a/dirsrvtests/tests/suites/password/pwp_history_test.py
b/dirsrvtests/tests/suites/password/pwp_history_test.py
index 1ec1fa0..f391646 100644
--- a/dirsrvtests/tests/suites/password/pwp_history_test.py
+++ b/dirsrvtests/tests/suites/password/pwp_history_test.py
@@ -17,12 +17,36 @@ logging.getLogger(__name__).setLevel(logging.DEBUG)
log = logging.getLogger(__name__)
-def test_pwp_history_test(topology_st):
- """
- Test password policy history feature:
- - Test password history is enforced
- - Test password history works after an Admin resets the password
- - Test that the correct number of passwords are stored in history
+def test_basic(topology_st):
+ """Test basic password policy history feature functionality
+
+ :id: 83d74f7d-3036-4944-8839-1b40bbf265ff
+ :setup: Standalone instance
+ :steps:
+ 1. Configure password history policy as bellow:
+ passwordHistory: on
+ passwordInHistory: 3
+ passwordChange: on
+ passwordStorageScheme: CLEAR
+ 2. Add a test user
+ 3. Attempt to change password to the same password
+ 4. Change password four times
+ 5. Check that we only have 3 passwords stored in history
+ 6. Attempt to change the password to previous passwords
+ 7. Reset password by Directory Manager (admin reset)
+ 8. Try and change the password to the previous password before the reset
+ :expectedresults:
+ 1. Password history policy should be configured successfully
+ 2. User should be added successfully
+ 3. Password change should be correctly rejected
+ with Constrant Violation error
+ 4. Password should be successfully changed
+ 5. Only 3 passwords should be stored in history
+ 6. Password changes should be correctly rejected
+ with Constrant Violation error
+ 7. Password should be successfully reset
+ 8. Password change should be correctly rejected
+ with Constrant Violation error
"""
USER_DN = 'uid=testuser,' + DEFAULT_SUFFIX
@@ -139,7 +163,7 @@ def test_pwp_history_test(topology_st):
time.sleep(1)
#
- # Check that we only have 3 passwords stored in history\
+ # Check that we only have 3 passwords stored in history
#
try:
entry = topology_st.standalone.search_s(USER_DN, ldap.SCOPE_BASE,
diff --git a/dirsrvtests/tests/suites/password/regression_test.py
b/dirsrvtests/tests/suites/password/regression_test.py
index f6ee167..409a4f0 100644
--- a/dirsrvtests/tests/suites/password/regression_test.py
+++ b/dirsrvtests/tests/suites/password/regression_test.py
@@ -82,17 +82,17 @@ def test_trivial_passw_check(topo, passw_policy, test_user,
user_pasw):
"""PasswordCheckSyntax attribute fails to validate cn, sn, uid,
givenname, ou and mail attributes
:id: bf9fe1ef-56cb-46a3-a6f8-5530398a06dc
- :feature: Password policy
:setup: Standalone instance.
- :steps: 1. Configure local password policy with PasswordCheckSyntax set to on.
- 2. Add users with cn, sn, uid, givenname, mail and userPassword attributes.
- 3. Configure subtree password policy for ou=people subtree.
- 4. Reset userPassword with trivial values like cn, sn, uid, givenname, ou and
mail attributes.
+ :steps:
+ 1. Configure local password policy with PasswordCheckSyntax set to on.
+ 2. Add users with cn, sn, uid, givenname, mail and userPassword attributes.
+ 3. Configure subtree password policy for ou=people subtree.
+ 4. Reset userPassword with trivial values like cn, sn, uid, givenname, ou and
mail attributes.
:expectedresults:
- 1. Enabling PasswordCheckSyntax should PASS.
- 2. Add users should PASS.
- 3. Configure subtree password policy should PASS.
- 4. Resetting userPassword to cn, sn, uid and mail should be rejected.
+ 1. Enabling PasswordCheckSyntax should PASS.
+ 2. Add users should PASS.
+ 3. Configure subtree password policy should PASS.
+ 4. Resetting userPassword to cn, sn, uid and mail should be rejected.
"""
conn = test_user.bind(PASSWORD)
@@ -112,15 +112,15 @@ def test_global_vs_local(topo, passw_policy, test_user, user_pasw):
"""Passwords rejected if its similar to uid, cn, sn, givenname, ou and
mail attributes
:id: dfd6cf5d-8bcd-4895-a691-a43ad9ec1be8
- :feature: Password policy
:setup: Standalone instance
- :steps: 1. Configure global password policy with PasswordCheckSyntax set to off
- 2. Add users with cn, sn, uid, mail, givenname and userPassword attributes
- 3. Replace userPassword similar to cn, sn, uid, givenname, ou and mail
attributes
+ :steps:
+ 1. Configure global password policy with PasswordCheckSyntax set to off
+ 2. Add users with cn, sn, uid, mail, givenname and userPassword attributes
+ 3. Replace userPassword similar to cn, sn, uid, givenname, ou and mail
attributes
:expectedresults:
- 1. Disabling the local policy should PASS.
- 2. Add users should PASS.
- 3. Resetting userPasswords similar to cn, sn, uid, givenname, ou and mail
attributes should PASS.
+ 1. Disabling the local policy should PASS.
+ 2. Add users should PASS.
+ 3. Resetting userPasswords similar to cn, sn, uid, givenname, ou and mail
attributes should PASS.
"""
log.info('Configure Pwpolicy with PasswordCheckSyntax and nsslapd-pwpolicy-local
set to off')
diff --git a/dirsrvtests/tests/suites/replication/__init__.py
b/dirsrvtests/tests/suites/replication/__init__.py
index e69de29..c5117a9 100644
--- a/dirsrvtests/tests/suites/replication/__init__.py
+++ b/dirsrvtests/tests/suites/replication/__init__.py
@@ -0,0 +1,18 @@
+import time
+import ldap
+from lib389._constants import DEFAULT_SUFFIX
+
+
+def get_repl_entries(topo, entry_name, attr_list):
+ """Get a list of test entries from all masters"""
+
+ entries_list = []
+
+ time.sleep(10)
+
+ for inst in topo.all_insts.values():
+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,
"uid={}".format(entry_name), attr_list)
+ entries_list += entries
+
+ return entries_list
+
diff --git a/dirsrvtests/tests/suites/replication/acceptance_test.py
b/dirsrvtests/tests/suites/replication/acceptance_test.py
index 2897726..d7c1dfc 100644
--- a/dirsrvtests/tests/suites/replication/acceptance_test.py
+++ b/dirsrvtests/tests/suites/replication/acceptance_test.py
@@ -10,12 +10,8 @@ import pytest
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_m4 as topo_m4
-
-from lib389._constants import (BACKEND_NAME, DEFAULT_SUFFIX, LOG_REPLICA,
REPLICA_RUV_FILTER,
- ReplicaRole, REPLICATION_BIND_DN, REPLICATION_BIND_PW,
- REPLICATION_BIND_METHOD, REPLICATION_TRANSPORT,
defaultProperties,
- RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD,
RA_TRANSPORT_PROT,
- DN_DM, PASSWORD, LOG_DEFAULT, RA_ENABLED, RA_SCHEDULE)
+from lib389._constants import *
+from . import get_repl_entries
TEST_ENTRY_NAME = 'mmrepl_test'
TEST_ENTRY_DN = 'uid={},{}'.format(TEST_ENTRY_NAME, DEFAULT_SUFFIX)
@@ -90,33 +86,15 @@ def new_suffix(topo_m4, request):
request.addfinalizer(fin)
-def get_repl_entries(topo, entry_name, attr_list):
- """Get a list of test entries from all masters"""
-
- entries_list = []
- num_of_masters = len({name: inst for name, inst in topo.ms.items() if not
name.endswith('agmts')})
-
- log.info('Wait for replication to happen')
- time.sleep(10)
-
- for num in range(1, num_of_masters + 1):
- entries = topo.ms['master{}'.format(num)].search_s(DEFAULT_SUFFIX,
ldap.SCOPE_SUBTREE,
-
"uid={}".format(entry_name), attr_list)
- entries_list += entries
-
- return entries_list
-
-
def test_add_entry(topo_m4, test_entry):
"""Check that entries are replicated after add operation
- :ID: 024250f1-5f7e-4f3b-a9f5-27741e6fd405
- :feature: Multi master replication
- :setup: Four masters replication setup
- :steps: 1. Add entry to master1
- 2. Wait for replication to happen
- 3. Check entry on all other masters
- :expectedresults: Entry should be replicated
+ :id: 024250f1-5f7e-4f3b-a9f5-27741e6fd405
+ :setup: Four masters replication setup, an entry
+ :steps:
+ 1. Check entry on all other masters
+ :expectedresults:
+ 1. The entry should be replicated to all masters
"""
entries = get_repl_entries(topo_m4, TEST_ENTRY_NAME, ["uid"])
@@ -126,13 +104,28 @@ def test_add_entry(topo_m4, test_entry):
def test_modify_entry(topo_m4, test_entry):
"""Check that entries are replicated after modify operation
- :ID: 36764053-622c-43c2-a132-d7a3ab7d9aaa
- :feature: Multi master replication
+ :id: 36764053-622c-43c2-a132-d7a3ab7d9aaa
:setup: Four masters replication setup, an entry
- :steps: 1. Modify the entry on master1 (try add, modify and delete operations)
- 2. Wait for replication to happen
- 3. Check entry on all other masters
- :expectedresults: Entry attr should be replicated
+ :steps:
+ 1. Modify the entry on master1 - add attribute
+ 2. Wait for replication to happen
+ 3. Check entry on all other masters
+ 4. Modify the entry on master1 - replace attribute
+ 5. Wait for replication to happen
+ 6. Check entry on all other masters
+ 7. Modify the entry on master1 - delete attribute
+ 8. Wait for replication to happen
+ 9. Check entry on all other masters
+ :expectedresults:
+ 1. Attribute should be successfully added
+ 2. Some time should pass
+ 3. The change should be present on all masters
+ 4. Attribute should be successfully replaced
+ 5. Some time should pass
+ 6. The change should be present on all masters
+ 4. Attribute should be successfully deleted
+ 8. Some time should pass
+ 9. The change should be present on all masters
"""
log.info('Modifying entry {} - add operation'.format(TEST_ENTRY_DN))
@@ -181,13 +174,14 @@ def test_modify_entry(topo_m4, test_entry):
def test_delete_entry(topo_m4, test_entry):
"""Check that entry deletion is replicated after delete operation
- :ID: 18437262-9d6a-4b98-a47a-6182501ab9bc
- :feature: Multi master replication
+ :id: 18437262-9d6a-4b98-a47a-6182501ab9bc
:setup: Four masters replication setup, an entry
- :steps: 1. Delete the entry from master1
- 2. Wait for replication to happen
- 3. Check entry on all other masters
- :expectedresults: Entry deletion should be replicated
+ :steps:
+ 1. Delete the entry from master1
+ 2. Check entry on all other masters
+ :expectedresults:
+ 1. The entry should be deleted
+ 2. The change should be present on all masters
"""
log.info('Deleting entry {} during the test'.format(TEST_ENTRY_DN))
@@ -201,14 +195,14 @@ def test_delete_entry(topo_m4, test_entry):
def test_modrdn_entry(topo_m4, test_entry, delold):
"""Check that entries are replicated after modrdn operation
- :ID: 02558e6d-a745-45ae-8d88-34fe9b16adc9
- :feature: Multi master replication
+ :id: 02558e6d-a745-45ae-8d88-34fe9b16adc9
:setup: Four masters replication setup, an entry
- :steps: 1. Make modrdn operation on entry on master1 with both delold 1 and 0
- 2. Wait for replication to happen
- 3. Check entry on all other masters
- :expectedresults: Entry with new RDN should be replicated.
- If delold was specified, entry with old RDN shouldn't exist
+ :steps:
+ 1. Make modrdn operation on entry on master1 with both delold 1 and 0
+ 2. Check entry on all other masters
+ :expectedresults:
+ 1. Modrdn operation should be successful
+ 2. The change should be present on all masters
"""
newrdn_name = 'newrdn'
@@ -239,15 +233,20 @@ def test_modrdn_entry(topo_m4, test_entry, delold):
def test_modrdn_after_pause(topo_m4):
"""Check that changes are properly replicated after replica pause
- :ID: 6271dc9c-a993-4a9e-9c6d-05650cdab282
- :feature: Multi master replication
+ :id: 6271dc9c-a993-4a9e-9c6d-05650cdab282
:setup: Four masters replication setup, an entry
- :steps: 1. Pause all replicas
- 2. Make modrdn operation on entry on master1
- 3. Resume all replicas
- 4. Wait for replication to happen
- 5. Check entry on all other masters
- :expectedresults: Entry with new RDN should be replicated.
+ :steps:
+ 1. Pause all replicas
+ 2. Make modrdn operation on entry on master1
+ 3. Resume all replicas
+ 4. Wait for replication to happen
+ 5. Check entry on all other masters
+ :expectedresults:
+ 1. Replicas should be paused
+ 2. Modrdn operation should be successful
+ 3. Replicas should be resumed
+ 4. Some time should pass
+ 5. The change should be present on all masters
"""
newrdn_name = 'newrdn'
@@ -293,16 +292,18 @@ def test_modrdn_after_pause(topo_m4):
topo_m4.ms["master1"].delete_s(newrdn_dn)
-# Bugzilla 842441
+(a)pytest.mark.bz842441
def test_modify_stripattrs(topo_m4):
"""Check that we can modify nsds5replicastripattrs
- :ID: f36abed8-e262-4f35-98aa-71ae55611aaa
- :feature: Multi master replication
+ :id: f36abed8-e262-4f35-98aa-71ae55611aaa
:setup: Four masters replication setup
- :steps: 1. Modify nsds5replicastripattrs attribute on any agreement
- 2. Search for the modified attribute
+ :steps:
+ 1. Modify nsds5replicastripattrs attribute on any agreement
+ 2. Search for the modified attribute
:expectedresults: It should be contain the value
+ 1. nsds5replicastripattrs should be successfully set
+ 2. The modified attribute should be the one we set
"""
m1 = topo_m4.ms["master1"]
@@ -320,13 +321,16 @@ def test_modify_stripattrs(topo_m4):
def test_new_suffix(topo_m4, new_suffix):
"""Check that we can enable replication on a new suffix
- :ID: d44a9ed4-26b0-4189-b0d0-b2b336ddccbd
- :feature: Multi master replication
- :setup: Four masters replication setup, new suffix
- :steps: 1. Enable replication on the new suffix
- 2. Check if it works
- 3. Disable replication on the new suffix
- :expectedresults: Replication works on the new suffix
+ :id: d44a9ed4-26b0-4189-b0d0-b2b336ddccbd
+ :setup: Four masters replication setup, a new suffix
+ :steps:
+ 1. Enable replication on the new suffix
+ 2. Check if replication works
+ 3. Disable replication on the new suffix
+ :expectedresults:
+ 1. Replication on the new suffix should be enabled
+ 2. Replication should work
+ 3. Replication on the new suffix should be disabled
"""
m1 = topo_m4.ms["master1"]
@@ -369,14 +373,17 @@ def test_new_suffix(topo_m4, new_suffix):
def test_many_attrs(topo_m4, test_entry):
"""Check a replication with many attributes (add and delete)
- :ID: d540b358-f67a-43c6-8df5-7c74b3cb7523
- :feature: Multi master replication
+ :id: d540b358-f67a-43c6-8df5-7c74b3cb7523
:setup: Four masters replication setup, a test entry
- :steps: 1. Add 10 new attributes to the entry
- 2. Delete one from the beginning, two from the middle
- and one from the end
- 3. Check that the changes were replicated in the right order
- :expectedresults: All changes are successfully replicated in the right order
+ :steps:
+ 1. Add 10 new attributes to the entry
+ 2. Delete few attributes: one from the beginning,
+ two from the middle and one from the end
+ 3. Check that the changes were replicated in the right order
+ :expectedresults:
+ 1. The attributes should be successfully added
+ 2. Delete operations should be successful
+ 3. The changes should be replicated in the right order
"""
m1 = topo_m4.ms["master1"]
@@ -412,118 +419,6 @@ def test_many_attrs(topo_m4, test_entry):
assert value not in delete_list
-def test_double_delete(topo_m4, test_entry):
- """Check that double delete of the entry doesn't crash server
-
- :ID: 3496c82d-636a-48c9-973c-2455b12164cc
- :feature: Multi master replication
- :setup: Four masters replication setup, a test entry
- :steps: 1. Delete the entry
- 2. Delete the entry on the second master
- 3. Check that server is alive
- :expectedresults: Server hasn't crash
- """
-
- log.info('Deleting entry {} from master1'.format(TEST_ENTRY_DN))
- topo_m4.ms["master1"].delete_s(TEST_ENTRY_DN)
-
- log.info('Deleting entry {} from master2'.format(TEST_ENTRY_DN))
- try:
- topo_m4.ms["master2"].delete_s(TEST_ENTRY_DN)
- except ldap.NO_SUCH_OBJECT:
- log.info("Entry {} wasn't found master2. It is
expected.".format(TEST_ENTRY_DN))
-
- log.info('Make searches to check if server is alive')
- entries = get_repl_entries(topo_m4, TEST_ENTRY_NAME, ["uid"])
- assert not entries, "Entry deletion {} wasn't replicated
successfully".format(TEST_ENTRY_DN)
-
-
-def test_password_repl_error(topo_m4, test_entry):
- """Check that error about userpassword replication is properly logged
-
- :ID: 714130ff-e4f0-4633-9def-c1f4b24abfef
- :feature: Multi master replication
- :setup: Four masters replication setup, a test entry
- :steps: 1. Change userpassword on master 1
- 2. Restart the servers to flush the logs
- 3. Check the error log for an replication error
- :expectedresults: We don't have a replication error in the error log
- """
-
- m1 = topo_m4.ms["master1"]
- m2 = topo_m4.ms["master2"]
- TEST_ENTRY_NEW_PASS = 'new_{}'.format(TEST_ENTRY_NAME)
-
- log.info('Clean the error log')
- m2.deleteErrorLogs()
-
- log.info('Set replication loglevel')
- m2.setLogLevel(LOG_REPLICA)
-
- log.info('Modifying entry {} - change userpassword on master
2'.format(TEST_ENTRY_DN))
- try:
- m1.modify_s(TEST_ENTRY_DN, [(ldap.MOD_REPLACE, 'userpassword',
'new_{}'.format(TEST_ENTRY_NAME))])
- except ldap.LDAPError as e:
- log.error('Failed to modify entry (%s): error (%s)' % (TEST_ENTRY_DN,
-
e.message['desc']))
- raise e
-
- log.info('Restart the servers to flush the logs')
- for num in range(1, 5):
- topo_m4.ms["master{}".format(num)].restart(timeout=10)
-
- try:
- log.info('Check that password works on master 2')
- m2.simple_bind_s(TEST_ENTRY_DN, TEST_ENTRY_NEW_PASS)
- m2.simple_bind_s(DN_DM, PASSWORD)
-
- log.info('Check the error log for the error with
{}'.format(TEST_ENTRY_DN))
- assert not m2.ds_error_log.match('.*can.t add a change for
uid={}.*'.format(TEST_ENTRY_NAME))
- finally:
- log.info('Reset bind DN to Directory manager')
- for num in range(1, 5):
- topo_m4.ms["master{}".format(num)].simple_bind_s(DN_DM, PASSWORD)
- log.info('Set the default loglevel')
- m2.setLogLevel(LOG_DEFAULT)
-
-
-def test_invalid_agmt(topo_m4):
- """Test adding that an invalid agreement is properly rejected and does
not crash the server
-
- :id: 6c3b2a7e-edcd-4327-a003-6bd878ff722b
- :setup: MMR with four masters
- :steps:
- 1. Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
- 2. Verify the server is still running
- :expectedresults:
- 1. Invalid repl agreement should be rejected
- 2. Server should be still running
- """
- m1 = topo_m4.ms["master1"]
-
- # Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
- AGMT_DN = 'cn=whatever,cn=replica,cn="dc=example,dc=com",cn=mapping
tree,cn=config'
- try:
- invalid_props = {RA_ENABLED: 'True', # Invalid value
- RA_SCHEDULE: '0001-2359 0123456'}
- m1.agreement.create(suffix=DEFAULT_SUFFIX, host='localhost', port=389,
properties=invalid_props)
- except ldap.UNWILLING_TO_PERFORM:
- m1.log.info('Invalid repl agreement correctly rejected')
- except ldap.LDAPError as e:
- m1.log.fatal('Got unexpected error adding invalid agreement: ' + str(e))
- assert False
- else:
- m1.log.fatal('Invalid agreement was incorrectly accepted by the server')
- assert False
-
- # Verify the server is still running
- try:
- m1.simple_bind_s(DN_DM, PASSWORD)
- except ldap.LDAPError as e:
- m1.log.fatal('Failed to bind: ' + str(e))
- assert False
-
-
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/dirsrvtests/tests/suites/replication/cleanallruv_test.py
b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
index 620a53e..a042fbd 100644
--- a/dirsrvtests/tests/suites/replication/cleanallruv_test.py
+++ b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
@@ -9,18 +9,11 @@
import threading
import pytest
+from lib389 import DirSrv
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_m4
-
-from lib389._constants import (DEFAULT_SUFFIX, REPLICA_RUV_FILTER, ReplicaRole,
- REPLICAID_MASTER_4, REPLICAID_MASTER_3,
REPLICAID_MASTER_2,
- REPLICAID_MASTER_1, REPLICATION_BIND_DN,
REPLICATION_BIND_PW,
- REPLICATION_BIND_METHOD, REPLICATION_TRANSPORT, SUFFIX,
- RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD,
RA_TRANSPORT_PROT,
- defaultProperties, args_instance)
-
-from lib389 import DirSrv
+from lib389._constants import *
logging.getLogger(__name__).setLevel(logging.DEBUG)
log = logging.getLogger(__name__)
@@ -224,15 +217,20 @@ def restore_master4(topology_m4):
def test_clean(topology_m4):
"""Check that cleanallruv task works properly
- :ID: e9b3ce5c-e17c-409e-aafc-e97d630f2878
- :feature: CleanAllRUV
+ :id: e9b3ce5c-e17c-409e-aafc-e97d630f2878
:setup: Replication setup with four masters
- :steps: 1. Check that replication works on all masters
- 2. Disable replication on master 4
- 3. Remove agreements to master 4 from other masters
- 4. Run a cleanallruv task on master 1 with a 'force' option
'on'
- 5. Check that everything was cleaned and no hanging tasks left
- :expectedresults: Everything was cleaned and no hanging tasks left
+ :steps:
+ 1. Check that replication works on all masters
+ 2. Disable replication on master 4
+ 3. Remove agreements to master 4 from other masters
+ 4. Run a cleanallruv task on master 1 with a 'force' option 'on'
+ 5. Check that everything was cleaned
+ :expectedresults:
+ 1. Replication should work properly on all masters
+ 2. Operation should be successful
+ 3. Agreements to master 4 should be removed
+ 4. Cleanallruv task should be successfully executed
+ 5. Everything should be cleaned
"""
log.info('Running test_clean...')
@@ -285,18 +283,30 @@ def test_clean(topology_m4):
def test_clean_restart(topology_m4):
"""Check that cleanallruv task works properly after a restart
- :ID: c6233bb3-092c-4919-9ac9-80dd02cc6e02
- :feature: CleanAllRUV
+ :id: c6233bb3-092c-4919-9ac9-80dd02cc6e02
:setup: Replication setup with four masters
- :steps: 1. Disable replication on master 4
- 2. Remove agreements to master 4 from other masters
- 3. Stop master 3
- 4. Run a cleanallruv task on master 1
- 5. Stop master 1
- 6. Start master 3 and make sure that no crash happened
- 7. Start master 1 and make sure that no crash happened
- 8. Check that everything was cleaned and no hanging tasks left
- :expectedresults: Everything was cleaned and no hanging tasks left
+ :steps:
+ 1. Disable replication on master 4
+ 2. Remove agreements to master 4 from other masters
+ 3. Stop master 3
+ 4. Run a cleanallruv task on master 1
+ 5. Stop master 1
+ 6. Start master 3
+ 7. Make sure that no crash happened
+ 8. Start master 1
+ 9. Make sure that no crash happened
+ 10. Check that everything was cleaned
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Agreements to master 4 should be removed
+ 3. Master 3 should be stopped
+ 4. Cleanallruv task should be successfully executed
+ 5. Master 1 should be stopped
+ 6. Master 3 should be started
+ 7. No crash should happened
+ 8. Master 1 should be started
+ 9. No crash should happened
+ 10. Everything should be cleaned
"""
log.info('Running test_clean_restart...')
@@ -358,17 +368,24 @@ def test_clean_restart(topology_m4):
def test_clean_force(topology_m4):
"""Check that multiple tasks with a 'force' option work
properly
- :ID: eb76a93d-8d1c-405e-9f25-6e8d5a781098
- :feature: CleanAllRUV
+ :id: eb76a93d-8d1c-405e-9f25-6e8d5a781098
:setup: Replication setup with four masters
- :steps: 1. Stop master 3
- 2. Add a bunch of updates to master 4
- 3. Disable replication on master 4
- 4. Start master 3
- 5. Remove agreements to master 4 from other masters
- 6. Run a cleanallruv task on master 1 with a 'force' option
'on'
- 7. Check that everything was cleaned and no hanging tasks left
- :expectedresults: Everything was cleaned and no hanging tasks left
+ :steps:
+ 1. Stop master 3
+ 2. Add a bunch of updates to master 4
+ 3. Disable replication on master 4
+ 4. Start master 3
+ 5. Remove agreements to master 4 from other masters
+ 6. Run a cleanallruv task on master 1 with a 'force' option 'on'
+ 7. Check that everything was cleaned
+ :expectedresults:
+ 1. Master 3 should be stopped
+ 2. Operation should be successful
+ 3. Replication on master 4 should be disabled
+ 4. Master 3 should be started
+ 5. Agreements to master 4 should be removed
+ 6. Operation should be successful
+ 7. Everything should be cleaned
"""
log.info('Running test_clean_force...')
@@ -418,17 +435,20 @@ def test_clean_force(topology_m4):
def test_abort(topology_m4):
"""Test the abort task basic functionality
- :ID: b09a6887-8de0-4fac-8e41-73ccbaaf7a08
- :feature: CleanAllRUV
+ :id: b09a6887-8de0-4fac-8e41-73ccbaaf7a08
:setup: Replication setup with four masters
- :steps: 1. Disable replication on master 4
- 2. Remove agreements to master 4 from other masters
- 3. Stop master 2
- 4. Run a cleanallruv task on master 1
- 5. Run a cleanallruv abort task on master 1
- 6. Wait for the task to be done
- 7. Check that no hanging tasks left
+ :steps:
+ 1. Disable replication on master 4
+ 2. Remove agreements to master 4 from other masters
+ 3. Stop master 2
+ 4. Run a cleanallruv task on master 1
+ 5. Run a cleanallruv abort task on master 1
:expectedresults: No hanging tasks left
+ 1. Replication on master 4 should be disabled
+ 2. Agreements to master 4 should be removed
+ 3. Master 2 should be stopped
+ 4. Operation should be successful
+ 5. Operation should be successful
"""
log.info('Running test_abort...')
@@ -497,20 +517,30 @@ def test_abort(topology_m4):
def test_abort_restart(topology_m4):
"""Test the abort task can handle a restart, and then resume
- :ID: b66e33d4-fe85-4e1c-b882-75da80f70ab3
- :feature: CleanAllRUV
+ :id: b66e33d4-fe85-4e1c-b882-75da80f70ab3
:setup: Replication setup with four masters
- :steps: 1. Disable replication on master 4
- 2. Remove agreements to master 4 from other masters
- 3. Stop master 3
- 4. Run a cleanallruv task on master 1
- 5. Run a cleanallruv abort task on master 1
- 6. Restart master 1 and make sure that no crash happened
- 7. Start master 3
- 8. Check that abort task was resumed on master 1
- and errors log doesn't have 'Aborting abort task' message
- :expectedresults: Abort task was resumed on master 1
- and errors log doesn't have 'Aborting abort task'
message
+ :steps:
+ 1. Disable replication on master 4
+ 2. Remove agreements to master 4 from other masters
+ 3. Stop master 3
+ 4. Run a cleanallruv task on master 1
+ 5. Run a cleanallruv abort task on master 1
+ 6. Restart master 1
+ 7. Make sure that no crash happened
+ 8. Start master 3
+ 9. Check master 1 does not have the clean task running
+ 10. Check that errors log doesn't have 'Aborting abort task' message
+ :expectedresults:
+ 1. Replication on master 4 should be disabled
+ 2. Agreements to master 4 should be removed
+ 3. Master 3 should be stopped
+ 4. Operation should be successful
+ 5. Operation should be successful
+ 6. Master 1 should be restarted
+ 7. No crash should happened
+ 8. Master 3 should be started
+ 9. Check master 1 shouldn't have the clean task running
+ 10. Errors log shouldn't have 'Aborting abort task' message
"""
log.info('Running test_abort_restart...')
@@ -593,17 +623,20 @@ def test_abort_restart(topology_m4):
def test_abort_certify(topology_m4):
"""Test the abort task with a replica-certify-all option
- :ID: 78959966-d644-44a8-b98c-1fcf21b45eb0
- :feature: CleanAllRUV
+ :id: 78959966-d644-44a8-b98c-1fcf21b45eb0
:setup: Replication setup with four masters
- :steps: 1. Disable replication on master 4
- 2. Remove agreements to master 4 from other masters
- 3. Stop master 2
- 4. Run a cleanallruv task on master 1
- 5. Run a cleanallruv abort task on master 1 with a replica-certify-all
option
- 6. Wait for the task to be done
- 7. Check that no hanging tasks left
+ :steps:
+ 1. Disable replication on master 4
+ 2. Remove agreements to master 4 from other masters
+ 3. Stop master 2
+ 4. Run a cleanallruv task on master 1
+ 5. Run a cleanallruv abort task on master 1 with a replica-certify-all option
:expectedresults: No hanging tasks left
+ 1. Replication on master 4 should be disabled
+ 2. Agreements to master 4 should be removed
+ 3. Master 2 should be stopped
+ 4. Operation should be successful
+ 5. Operation should be successful
"""
log.info('Running test_abort_certify...')
@@ -689,17 +722,23 @@ def test_abort_certify(topology_m4):
def test_stress_clean(topology_m4):
"""Put each server(m1 - m4) under a stress, and perform the entire
clean process
- :ID: a8263cd6-f068-4357-86e0-e7c34504c8c5
- :feature: CleanAllRUV
+ :id: a8263cd6-f068-4357-86e0-e7c34504c8c5
:setup: Replication setup with four masters
- :steps: 1. Add a bunch of updates to all masters
- 2. Put master 4 to read-only mode
- 3. Disable replication on master 4 and wait for the changes
- 4. Start master 3
- 5. Remove agreements to master 4 from other masters
- 6. Run a cleanallruv task on master 1
- 7. Check that everything was cleaned and no hanging tasks left
- :expectedresults: Everything was cleaned and no hanging tasks left
+ :steps:
+ 1. Add a bunch of updates to all masters
+ 2. Put master 4 to read-only mode
+ 3. Disable replication on master 4
+ 5. Remove agreements to master 4 from other masters
+ 6. Run a cleanallruv task on master 1
+ 7. Check that everything was cleaned
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Master 4 should be put to read-only mode
+ 3. Replication on master 4 should be disabled
+ 2. Agreements to master 4 should be removed
+ 5. Agreements to master 4 should be removed
+ 6. Operation should be successful
+ 7. Everything should be cleaned
"""
log.info('Running test_stress_clean...')
@@ -788,18 +827,26 @@ def test_stress_clean(topology_m4):
def test_multiple_tasks_with_force(topology_m4):
"""Check that multiple tasks with a 'force' option work
properly
- :ID: eb76a93d-8d1c-405e-9f25-6e8d5a781098
- :feature: CleanAllRUV
+ :id: eb76a93d-8d1c-405e-9f25-6e8d5a781098
:setup: Replication setup with four masters
- :steps: 1. Stop master 3
- 2. Add a bunch of updates to master 4
- 3. Disable replication on master 4
- 4. Start master 3
- 5. Remove agreements to master 4 from other masters
- 6. Run a cleanallruv task on master 1 with a 'force' option
'on'
- 7. Run one more cleanallruv task on master 1 with a 'force' option
'off'
- 8. Check that everything was cleaned and no hanging tasks left
- :expectedresults: Everything was cleaned and no hanging tasks left
+ :steps:
+ 1. Stop master 3
+ 2. Add a bunch of updates to master 4
+ 3. Disable replication on master 4
+ 4. Start master 3
+ 5. Remove agreements to master 4 from other masters
+ 6. Run a cleanallruv task on master 1 with a 'force' option 'on'
+ 7. Run one more cleanallruv task on master 1 with a 'force' option
'off'
+ 8. Check that everything was cleaned
+ :expectedresults:
+ 1. Master 3 should be stopped
+ 2. Operation should be successful
+ 3. Replication on master 4 should be disabled
+ 4. Master 3 should be started
+ 5. Agreements to master 4 should be removed
+ 6. Operation should be successful
+ 7. Operation should be successful
+ 8. Everything should be cleaned
"""
log.info('Running test_multiple_tasks_with_force...')
diff --git a/dirsrvtests/tests/suites/replication/regression_test.py
b/dirsrvtests/tests/suites/replication/regression_test.py
new file mode 100644
index 0000000..3cb2093
--- /dev/null
+++ b/dirsrvtests/tests/suites/replication/regression_test.py
@@ -0,0 +1,174 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2017 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import pytest
+from lib389.idm.user import TEST_USER_PROPERTIES, UserAccounts
+from lib389.utils import *
+from lib389.topologies import topology_m2 as topo_m2
+from lib389._constants import *
+from . import get_repl_entries
+
+NEW_SUFFIX_NAME = 'test_repl'
+NEW_SUFFIX = 'o={}'.format(NEW_SUFFIX_NAME)
+NEW_BACKEND = 'repl_base'
+
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+if DEBUGGING:
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+ logging.getLogger(__name__).setLevel(logging.INFO)
+log = logging.getLogger(__name__)
+
+
+(a)pytest.fixture(scope="function")
+def test_entry(topo_m2, request):
+ """Add test entry using UserAccounts"""
+
+ log.info('Adding a test entry user')
+ users = UserAccounts(topo_m2.ms["master1"], DEFAULT_SUFFIX)
+ tuser = users.create(properties=TEST_USER_PROPERTIES)
+
+ def fin():
+ if users.list():
+ log.info('Deleting user-{}'.format(tuser.dn))
+ tuser.delete()
+ else:
+ log.info('There is no user to delete')
+
+ request.addfinalizer(fin)
+ return tuser
+
+
+def test_double_delete(topo_m2, test_entry):
+ """Check that double delete of the entry doesn't crash server
+
+ :id: 3496c82d-636a-48c9-973c-2455b12164cc
+ :setup: Four masters replication setup, a test entry
+ :steps:
+ 1. Delete the entry on the first master
+ 2. Delete the entry on the second master
+ 3. Check that server is alive
+ :expectedresults:
+ 1. Entry should be successfully deleted from first master
+ 2. Entry should be successfully deleted from second aster
+ 3. Server should me alive
+ """
+
+ test_entry_rdn = test_entry.rdn
+
+ log.info('Deleting entry {} from master1'.format(test_entry.dn))
+ topo_m2.ms["master1"].delete_s(test_entry.dn)
+
+ log.info('Deleting entry {} from master2'.format(test_entry.dn))
+ try:
+ topo_m2.ms["master2"].delete_s(test_entry.dn)
+ except ldap.NO_SUCH_OBJECT:
+ log.info("Entry {} wasn't found master2. It is
expected.".format(test_entry.dn))
+
+ log.info('Make searches to check if server is alive')
+ entries = get_repl_entries(topo_m2, test_entry_rdn, ["uid"])
+ assert not entries, "Entry deletion {} wasn't replicated
successfully".format(test_entry.dn)
+
+
+def test_password_repl_error(topo_m2, test_entry):
+ """Check that error about userpassword replication is properly logged
+
+ :id: 714130ff-e4f0-4633-9def-c1f4b24abfef
+ :setup: Four masters replication setup, a test entry
+ :steps:
+ 1. Change userpassword on the first master
+ 2. Restart the servers to flush the logs
+ 3. Check the error log for an replication error
+ :expectedresults:
+ 1. Password should be successfully changed
+ 2. Server should be successfully restarted
+ 3. There should be no replication errors in the error log
+ """
+
+ m1 = topo_m2.ms["master1"]
+ m2 = topo_m2.ms["master2"]
+ TEST_ENTRY_NEW_PASS = 'new_pass'
+
+ log.info('Clean the error log')
+ m2.deleteErrorLogs()
+
+ log.info('Set replication loglevel')
+ m2.setLogLevel(LOG_REPLICA)
+
+ log.info('Modifying entry {} - change userpassword on master
1'.format(test_entry.dn))
+ try:
+ m1.modify_s(test_entry.dn, [(ldap.MOD_REPLACE, 'userpassword',
TEST_ENTRY_NEW_PASS)])
+ except ldap.LDAPError as e:
+ log.error('Failed to modify entry (%s): error (%s)' % (test_entry.dn,
+
e.message['desc']))
+ raise e
+
+ log.info('Restart the servers to flush the logs')
+ for num in range(1, 3):
+ topo_m2.ms["master{}".format(num)].restart(timeout=10)
+
+ time.sleep(5)
+
+ try:
+ log.info('Check that password works on master 2')
+ m2.simple_bind_s(test_entry.dn, TEST_ENTRY_NEW_PASS)
+ m2.simple_bind_s(DN_DM, PASSWORD)
+
+ log.info('Check the error log for the error with
{}'.format(test_entry.dn))
+ assert not m2.ds_error_log.match('.*can.t add a change for
{}.*'.format(test_entry.dn))
+ finally:
+ log.info('Reset bind DN to Directory manager')
+ for num in range(1, 3):
+ topo_m2.ms["master{}".format(num)].simple_bind_s(DN_DM, PASSWORD)
+ log.info('Set the default loglevel')
+ m2.setLogLevel(LOG_DEFAULT)
+
+
+def test_invalid_agmt(topo_m2):
+ """Test adding that an invalid agreement is properly rejected and does
not crash the server
+
+ :id: 6c3b2a7e-edcd-4327-a003-6bd878ff722b
+ :setup: Four masters replication setup
+ :steps:
+ 1. Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
+ 2. Verify the server is still running
+ :expectedresults:
+ 1. Invalid repl agreement should be rejected
+ 2. Server should be still running
+ """
+
+ m1 = topo_m2.ms["master1"]
+
+ # Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
+ AGMT_DN = 'cn=whatever,cn=replica,cn="dc=example,dc=com",cn=mapping
tree,cn=config'
+ try:
+ invalid_props = {RA_ENABLED: 'True', # Invalid value
+ RA_SCHEDULE: '0001-2359 0123456'}
+ m1.agreement.create(suffix=DEFAULT_SUFFIX, host='localhost', port=389,
properties=invalid_props)
+ except ldap.UNWILLING_TO_PERFORM:
+ m1.log.info('Invalid repl agreement correctly rejected')
+ except ldap.LDAPError as e:
+ m1.log.fatal('Got unexpected error adding invalid agreement: ' + str(e))
+ assert False
+ else:
+ m1.log.fatal('Invalid agreement was incorrectly accepted by the server')
+ assert False
+
+ # Verify the server is still running
+ try:
+ m1.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError as e:
+ m1.log.fatal('Failed to bind: ' + str(e))
+ assert False
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
diff --git a/dirsrvtests/tests/suites/replication/single_master_test.py
b/dirsrvtests/tests/suites/replication/single_master_test.py
index 95ad1f5..44cd5cf 100644
--- a/dirsrvtests/tests/suites/replication/single_master_test.py
+++ b/dirsrvtests/tests/suites/replication/single_master_test.py
@@ -81,17 +81,23 @@ def replica_without_init(topo_nr):
def test_mail_attr_repl(topo_r, test_user):
"""Check that no crash happens during mail attribute replication
- :ID: 959edc84-05be-4bf9-a541-53afae482052
- :feature: Single master replication
+ :id: 959edc84-05be-4bf9-a541-53afae482052
:setup: Replication setup with master and consumer instances,
test user on master
- :steps: 1. Check that user was replicated to consumer
- 2. Back up mail database file
- 3. Remove mail attribute from the user entry
- 4. Restore mail database
- 5. Search for the entry with a substring 'mail=user*'
- 6. Search for the entry once again to make sure that server is alive
- :expectedresults: No crash happens
+ :steps:
+ 1. Check that user was replicated to consumer
+ 2. Back up mail database file
+ 3. Remove mail attribute from the user entry
+ 4. Restore mail database
+ 5. Search for the entry with a substring 'mail=user*'
+ 6. Search for the entry once again to make sure that server is alive
+ :expectedresults:
+ 1. The user should be replicated to consumer
+ 2. Operation should be successful
+ 3. The mail attribute should be removed
+ 4. Operation should be successful
+ 5. Search should be successful
+ 6. No crash should happen
"""
master = topo_r.ms["master1"]
@@ -144,15 +150,18 @@ def test_mail_attr_repl(topo_r, test_user):
def test_lastupdate_attr_before_init(topo_nr, replica_without_init):
"""Check that LastUpdate replica attributes show right values
- :ID: bc8ce431-ff65-41f5-9331-605cbcaaa887
- :feature: Single master replication
+ :id: bc8ce431-ff65-41f5-9331-605cbcaaa887
:setup: Replication setup with master and consumer instances
without initialization
- :steps: 1. Check nsds5replicaLastUpdateStart, nsds5replicaLastUpdateEnd,
- nsds5replicaLastUpdateStatus attrs
- :expectedresults: nsds5replicaLastUpdateStart: 0, nsds5replicaLastUpdateEnd: 0 and
- nsds5replicaLastUpdateStatus is not equal to
- "0 Replica acquired successfully: Incremental update started"
+ :steps:
+ 1. Check nsds5replicaLastUpdateStart value
+ 2. Check nsds5replicaLastUpdateEnd value
+ 3. Check nsds5replicaLastUpdateStatus value
+ :expectedresults:
+ 1. nsds5replicaLastUpdateStart should be equal to 0
+ 2. nsds5replicaLastUpdateEnd should be equal to 0
+ 3. nsds5replicaLastUpdateStatus should not be equal
+ to "0 Replica acquired successfully: Incremental update started"
"""
master = topo_nr.ins["standalone1"]
diff --git a/dirsrvtests/tests/suites/replication/tombstone_test.py
b/dirsrvtests/tests/suites/replication/tombstone_test.py
index d1a8178..a701148 100644
--- a/dirsrvtests/tests/suites/replication/tombstone_test.py
+++ b/dirsrvtests/tests/suites/replication/tombstone_test.py
@@ -13,17 +13,22 @@ from lib389.topologies import topology_st
from lib389._constants import DEFAULT_SUFFIX, ReplicaRole, REPLICAID_MASTER_1
+
def test_purge_success(topology_st):
"""Verify that tombstones are created successfully
- :ID: adb86f50-ae76-4ed6-82b4-3cdc30ccab78
- :feature: nsTombstone
+ :id: adb86f50-ae76-4ed6-82b4-3cdc30ccab78
:setup: Standalone instance
- :steps: 1. Enable replication to unexisting instance
- 2. Add an entry to the replicated suffix
- 3. Delete the entry
- 4. Check that tombstone entry exists (objectclass=nsTombstone)
+ :steps:
+ 1. Enable replication to unexisting instance
+ 2. Add an entry to the replicated suffix
+ 3. Delete the entry
+ 4. Check that tombstone entry exists (objectclass=nsTombstone)
:expectedresults: Tombstone entry exist
+ 1. Operation should be successful
+ 2. The entry should be successfully added
+ 3. The entry should be successfully deleted
+ 4. Tombstone entry should exist
"""
log.info('Setting up replication...')
diff --git a/dirsrvtests/tests/suites/replication/wait_for_async_feature_test.py
b/dirsrvtests/tests/suites/replication/wait_for_async_feature_test.py
index cac25f8..21edbee 100644
--- a/dirsrvtests/tests/suites/replication/wait_for_async_feature_test.py
+++ b/dirsrvtests/tests/suites/replication/wait_for_async_feature_test.py
@@ -96,7 +96,18 @@ def entries(topology_m2, request):
def test_not_int_value(topology_m2):
- """Tests not integer value"""
+ """Tests not integer value
+
+ :id: 67c9994f-9251-425a-8197-8d12ad9beafc
+ :setup: Replication with two masters
+ :steps:
+ 1. Try to set some string value
+ to nsDS5ReplicaWaitForAsyncResults
+ :expectedresults:
+ 1. Invalid syntax error should be raised
+ """
+
+
master1 = topology_m2.ms["master1"]
agmt = master1.agreement.list(suffix=DEFAULT_SUFFIX)[0].dn
@@ -109,7 +120,19 @@ def test_not_int_value(topology_m2):
def test_multi_value(topology_m2):
- """Tests multi value"""
+ """Tests multi value
+
+ :id: 1932301a-db29-407e-b27e-4466a876d1d3
+ :setup: Replication with two masters
+ :steps:
+ 1. Set nsDS5ReplicaWaitForAsyncResults to some int
+ 2. Try to add one more int value
+ to nsDS5ReplicaWaitForAsyncResults
+ :expectedresults:
+ 1. nsDS5ReplicaWaitForAsyncResults should be set
+ 2. Object class violation error should be raised
+ """
+
master1 = topology_m2.ms["master1"]
agmt = master1.agreement.list(suffix=DEFAULT_SUFFIX)[0].dn
@@ -127,7 +150,19 @@ def test_multi_value(topology_m2):
def test_value_check(topology_m2, waitfor_async_attr):
- """Checks that value has been set correctly"""
+ """Checks that value has been set correctly
+
+ :id: 3e81afe9-5130-410d-a1bb-d798d8ab8519
+ :setup: Replication with two masters,
+ wait for async set on all masters, try:
+ None, '2000', '0', '-5'
+ :steps:
+ 1. Search for nsDS5ReplicaWaitForAsyncResults on master 1
+ 2. Search for nsDS5ReplicaWaitForAsyncResults on master 2
+ :expectedresults:
+ 1. nsDS5ReplicaWaitForAsyncResults should be set correctly
+ 2. nsDS5ReplicaWaitForAsyncResults should be set correctly
+ """
attr_value = waitfor_async_attr[0]
@@ -152,6 +187,22 @@ def test_value_check(topology_m2, waitfor_async_attr):
def test_behavior_with_value(topology_m2, waitfor_async_attr, entries):
"""Tests replication behavior with valid
nsDS5ReplicaWaitForAsyncResults attribute values
+
+ :id: 117b6be2-cdab-422e-b0c7-3b88bbeec036
+ :setup: Replication with two masters,
+ wait for async set on all masters, try:
+ None, '2000', '0', '-5'
+ :steps:
+ 1. Set Replication Debugging loglevel for the errorlog
+ 2. Set nsslapd-logging-hr-timestamps-enabled to 'off' on both masters
+ 3. Gather all sync attempts, group by timestamp
+ 4. Take the most common timestamp and assert it has appeared
+ in the set range
+ :expectedresults:
+ 1. Replication Debugging loglevel should be set
+ 2. nsslapd-logging-hr-timestamps-enabled should be set
+ 3. Operation should be successful
+ 4. Errors log should have all timestamp appear
"""
master1 = topology_m2.ms["master1"]
diff --git a/dirsrvtests/tests/suites/sasl/allowed_mechs.py
b/dirsrvtests/tests/suites/sasl/allowed_mechs_test.py
similarity index 64%
rename from dirsrvtests/tests/suites/sasl/allowed_mechs.py
rename to dirsrvtests/tests/suites/sasl/allowed_mechs_test.py
index 5b1b92c..81b1c04 100644
--- a/dirsrvtests/tests/suites/sasl/allowed_mechs.py
+++ b/dirsrvtests/tests/suites/sasl/allowed_mechs_test.py
@@ -12,30 +12,64 @@ import os
from lib389.topologies import topology_st
-def test_sasl_allowed_mechs(topology_st):
+def test_basic_feature(topology_st):
"""Test the alloweed sasl mechanism feature
- :ID: ab7d9f86-8cfe-48c3-8baa-739e599f006a
- :feature: Allowed sasl mechanisms
- :steps: 1. Get the default list of mechanisms
- 2. Set allowed mechanism PLAIN, and verify it's correctly listed
- 3. Restart server, and verify list is still correct
- 4. Test EXTERNAL is properly listed
- 5. Add GSSAPI to the existing list, and verify it's correctly listed
- 6. Restart server and verify list is still correct
- 7. Add ANONYMOUS to the existing list, and veirfy it's correctly listed
- 8. Restart server and verify list is still correct
- 9. Remove GSSAPI and verify it's correctly listed
- 10. Restart server and verify list is still correct
- 11. Reset allowed list to nothing, verify "all" the mechanisms are
returned
- 12. Restart server and verify list is still correct
-
- :expectedresults: The supported mechanisms supported what is set for the allowed
- mechanisms
+ :id: ab7d9f86-8cfe-48c3-8baa-739e599f006a
+ :setup: Standalone instance
+ :steps:
+ 1. Get the default list of mechanisms
+ 2. Set allowed mechanism PLAIN
+ 3. Verify the list
+ 4. Restart the server
+ 5. Verify that list is still correct
+ 6. Edit mechanisms to allow just PLAIN and EXTERNAL
+ 7. Verify the list
+ 8. Edit mechanisms to allow just PLAIN and GSSAPI
+ 9. Verify the list
+ 10. Restart the server
+ 11. Verify that list is still correct
+ 12. Edit mechanisms to allow just PLAIN, GSSAPI, and ANONYMOUS
+ 13. Verify the list
+ 14. Restart the server
+ 15. Verify that list is still correct
+ 16. Edit mechanisms to allow just PLAIN and ANONYMOUS
+ 17. Verify the list
+ 18. Restart the server
+ 19. Verify that list is still correct
+ 20. Reset the allowed list to nothing,
+ 21. Verify that the returned mechanisms are the default ones
+ 22. Restart the server
+ 23. Verify that list is still correct
+ :expectedresults:
+ 1. GSSAPI, PLAIN and EXTERNAL mechanisms should be acquired
+ 2. Operation should be successful
+ 3. List should have - PLAIN, EXTERNAL; shouldn't have - GSSAPI
+ 4. Server should be restarted
+ 5. List should have - PLAIN, EXTERNAL; shouldn't have - GSSAPI
+ 6. Operation should be successful
+ 7. List should have - PLAIN, EXTERNAL; shouldn't have - GSSAPI
+ 8. Operation should be successful
+ 9. List should have - PLAIN, EXTERNAL, GSSAPI
+ 10. Server should be restarted
+ 11. List should have - PLAIN, EXTERNAL, GSSAPI
+ 12. Operation should be successful
+ 13. List should have - PLAIN, EXTERNAL, GSSAPI, ANONYMOUS
+ 14. Server should be restarted
+ 15. List should have - PLAIN, EXTERNAL, GSSAPI, ANONYMOUS
+ 16. Operation should be successful
+ 17. List should have - PLAIN, EXTERNAL, ANONYMOUS; shouldn't have - GSSAPI
+ 18. Server should be restarted
+ 19. List should have - PLAIN, EXTERNAL, ANONYMOUS; shouldn't have - GSSAPI
+ 20. Operation should be successful
+ 21. List should have - PLAIN, EXTERNAL, GSSAPI
+ 22. Server should be restarted
+ 23. List should have - PLAIN, EXTERNAL, GSSAPI
"""
+
standalone = topology_st.standalone
- # Get the supported mechs. This should contain PLAIN, GSSAPI, EXTERNAL at least
+ # Get the supported mechanisms. This should contain PLAIN, GSSAPI, EXTERNAL at least
standalone.log.info("Test we have some of the default mechanisms")
orig_mechs = standalone.rootdse.supported_sasl()
print(orig_mechs)
@@ -43,7 +77,7 @@ def test_sasl_allowed_mechs(topology_st):
assert('PLAIN' in orig_mechs)
assert('EXTERNAL' in orig_mechs)
- # Now edit the supported mechs. Check them again.
+ # Now edit the supported mechanisms. Check them again.
standalone.log.info("Edit mechanisms to allow just PLAIN")
standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN')
limit_mechs = standalone.rootdse.supported_sasl()
@@ -68,7 +102,7 @@ def test_sasl_allowed_mechs(topology_st):
assert('EXTERNAL' in limit_mechs)
assert('GSSAPI' not in limit_mechs)
- # Now edit the supported mechs. Check them again.
+ # Now edit the supported mechanisms. Check them again.
standalone.log.info("Edit mechanisms to allow just PLAIN and GSSAPI")
standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN,
GSSAPI')
limit_mechs = standalone.rootdse.supported_sasl()
@@ -86,7 +120,7 @@ def test_sasl_allowed_mechs(topology_st):
assert('GSSAPI' in limit_mechs)
assert(len(limit_mechs) == 3)
- # Add ANONYMOUS to the supported mechs and test again.
+ # Add ANONYMOUS to the supported mechanisms and test again.
standalone.log.info("Edit mechanisms to allow just PLAIN, GSSAPI, and
ANONYMOUS")
standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, GSSAPI,
ANONYMOUS')
limit_mechs = standalone.rootdse.supported_sasl()
diff --git a/dirsrvtests/tests/suites/sasl/plain.py
b/dirsrvtests/tests/suites/sasl/plain_test.py
similarity index 99%
rename from dirsrvtests/tests/suites/sasl/plain.py
rename to dirsrvtests/tests/suites/sasl/plain_test.py
index a48e340..cff2507 100644
--- a/dirsrvtests/tests/suites/sasl/plain.py
+++ b/dirsrvtests/tests/suites/sasl/plain_test.py
@@ -20,7 +20,7 @@ from lib389.idm.services import ServiceAccounts
log = logging.getLogger(__name__)
-def test_sasl_plain(topology_st):
+def test_basic_feature(topology_st):
"""Check basic SASL functionality for PLAIN mechanism
:id: 75ddc6fa-aa5a-4025-9c71-1abad20c91fc
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.