#50777 Issue 49761 - Fix CI test suite issues
Closed 3 years ago by spichugi. Opened 4 years ago by bsmejkal.
bsmejkal/389-ds-base ou_ticket48755  into  master

@@ -10,6 +10,7 @@ 

  import pytest

  import subprocess

  from lib389.idm.user import TEST_USER_PROPERTIES, UserAccounts

+ from lib389.pwpolicy import PwPolicyManager

  from lib389.utils import *

  from lib389.topologies import topology_m2 as topo_m2, TopologyMain, topology_m3 as topo_m3, create_topology, _remove_ssca_db

  from lib389._constants import *
@@ -132,6 +133,54 @@ 

      return tuser

  

  

+ def add_ou_entry(server, idx, parent):

+     ous = OrganizationalUnits(server, parent)

+     name = 'OU%d' % idx

+     ous.create(properties={'ou': '%s' % name})

+ 

+ 

+ def add_user_entry(server, idx, parent):

+     users = UserAccounts(server, DEFAULT_SUFFIX, rdn=parent)

+     user_properties = {

+         'uid': 'tuser%d' % idx,

+         'givenname': 'test',

+         'cn': 'Test User%d' % idx,

+         'sn': 'user%d' % idx,

+         'userpassword': PW_DM,

+         'uidNumber' : '1000%d' % idx,

+         'gidNumber': '2000%d' % idx,

+         'homeDirectory': '/home/{}'.format('tuser%d' % idx)

+     }

+     users.create(properties=user_properties)

+ 

+ 

+ def del_user_entry(server, idx, parent):

+     users = UserAccounts(server, DEFAULT_SUFFIX, rdn=parent)

+     test_user = users.get('tuser%d' % idx)

+     test_user.delete()

+ 

+ 

+ def rename_entry(server, idx, ou_name, new_parent):

+     users = UserAccounts(server, DEFAULT_SUFFIX, rdn=ou_name)

+     name = 'tuser%d' % idx

+     rdn = 'uid=%s' % name

+     test_user = users.get(name)

+     test_user.rename(new_rdn=rdn, newsuperior=new_parent)

+ 

+ 

+ def add_ldapsubentry(server, parent):

+     pwp = PwPolicyManager(server)

+     policy_props = {'passwordStorageScheme': 'ssha',

+                                 'passwordCheckSyntax': 'on',

+                                 'passwordInHistory': '6',

+                                 'passwordChange': 'on',

+                                 'passwordMinAge': '0',

+                                 'passwordExp': 'off',

+                                 'passwordMustChange': 'off',}

+     log.info('Create password policy for subtree {}'.format(parent))

+     pwp.create_subtree_policy(parent, policy_props)

+ 

+ 

  def test_double_delete(topo_m2, create_entry):

      """Check that double delete of the entry doesn't crash server

  
@@ -696,6 +745,107 @@ 

          pass

  

  

+ @pytest.mark.bz1314956

+ @pytest.mark.ds48755

+ def test_moving_entry_make_online_init_fail(topology_m2):

+     """

+     Moving an entry could make the online init fail

+ 

+     :id: e3895be7-884a-4e9f-80e3-24e9a5167c9e

+     :setup: Two masters replication setup

+     :steps:

+          1. Generate DIT_0

+          2. Generate password policy for DIT_0

+          3. Create users for DIT_0

+          4. Turn idx % 2 == 0 users into tombstones

+          5. Generate DIT_1

+          6. Move 'ou=OU0,ou=OU0,dc=example,dc=com' to DIT_1

+          7. Move 'ou=OU0,dc=example,dc=com' to DIT_1

+          8. Move idx % 2 == 1 users to 'ou=OU0,ou=OU0,ou=OU1,dc=example,dc=com'

+          9. Init replicas

+          10. Number of entries should match on both masters

+ 

+     :expectedresults:

+          1. Success

+          2. Success

+          3. Success

+          4. Success

+          5. Success

+          6. Success

+          7. Success

+          8. Success

+          9. Success

+          10. Success

+     """

+ 

+     M1 = topology_m2.ms["master1"]

+     M2 = topology_m2.ms["master2"]

+ 

+     log.info("Generating DIT_0")

+     idx = 0

+     add_ou_entry(M1, idx, DEFAULT_SUFFIX)

+     log.info("Created entry: ou=OU0, dc=example, dc=com")

+ 

+     ou0 = 'ou=OU%d' % idx

+     first_parent = '%s,%s' % (ou0, DEFAULT_SUFFIX)

+     add_ou_entry(M1, idx, first_parent)

+     log.info("Created entry: ou=OU0, ou=OU0, dc=example, dc=com")

+ 

+     add_ldapsubentry(M1, first_parent)

+ 

+     ou_name = 'ou=OU%d,ou=OU%d' % (idx, idx)

+     second_parent = 'ou=OU%d,%s' % (idx, first_parent)

+     for idx in range(0, 9):

+         add_user_entry(M1, idx, ou_name)

+         if idx % 2 == 0:

+             log.info("Turning tuser%d into a tombstone entry" % idx)

+             del_user_entry(M1, idx, ou_name)

+ 

+     log.info('%s => %s => %s => 10 USERS' % (DEFAULT_SUFFIX, first_parent, second_parent))

+ 

+     log.info("Generating DIT_1")

+     idx = 1

+     add_ou_entry(M1, idx, DEFAULT_SUFFIX)

+     log.info("Created entry: ou=OU1,dc=example,dc=com")

+ 

+     third_parent = 'ou=OU%d,%s' % (idx, DEFAULT_SUFFIX)

+     add_ou_entry(M1, idx, third_parent)

+     log.info("Created entry: ou=OU1, ou=OU1, dc=example, dc=com")

+ 

+     add_ldapsubentry(M1, third_parent)

+ 

+     log.info("Moving %s to DIT_1" % second_parent)

+     OrganizationalUnits(M1, second_parent).get('OU0').rename(ou0, newsuperior=third_parent)

+ 

+     log.info("Moving %s to DIT_1" % first_parent)

+     fourth_parent = '%s,%s' % (ou0, third_parent)

+     OrganizationalUnits(M1, first_parent).get('OU0').rename(ou0, newsuperior=fourth_parent)

+ 

+     fifth_parent = '%s,%s' % (ou0, fourth_parent)

+ 

+     ou_name = 'ou=OU0,ou=OU1'

+     log.info("Moving USERS to %s" % fifth_parent)

+     for idx in range(0, 9):

+         if idx % 2 == 1:

+             rename_entry(M1, idx, ou_name, fifth_parent)

+ 

+     log.info('%s => %s => %s => %s => 10 USERS' % (DEFAULT_SUFFIX, third_parent, fourth_parent, fifth_parent))

+ 

+     log.info("Run Initialization.")

+     repl = ReplicationManager(DEFAULT_SUFFIX)

+     repl.wait_for_replication(M1, M2, timeout=5)

+ 

+     m1entries = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,

+                             '(|(objectclass=ldapsubentry)(objectclass=nstombstone)(nsuniqueid=*))')

+     m2entries = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,

+                             '(|(objectclass=ldapsubentry)(objectclass=nstombstone)(nsuniqueid=*))')

+ 

+     log.info("m1entry count - %d", len(m1entries))

+     log.info("m2entry count - %d", len(m2entries))

+ 

+     assert len(m1entries) == len(m2entries)

+ 

+ 

  if __name__ == '__main__':

      # Run isolated

      # -s for DEBUG mode

@@ -1,160 +0,0 @@ 

- # --- BEGIN COPYRIGHT BLOCK ---

- # Copyright (C) 2016 Red Hat, Inc.

- # All rights reserved.

- #

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

- # See LICENSE for details.

- # --- END COPYRIGHT BLOCK ---

- #

- import time

- import pytest

- from lib389.tasks import *

- from lib389.utils import *

- from lib389.topologies import topology_m2

- 

- pytestmark = pytest.mark.tier2

- 

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

- log = logging.getLogger(__name__)

- 

- 

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

- def add_ou_entry(server, idx, myparent):

-     name = 'OU%d' % idx

-     dn = 'ou=%s,%s' % (name, myparent)

-     server.add_s(Entry((dn, {'objectclass': ['top', 'organizationalunit'],

-                              'ou': name})))

-     time.sleep(1)

- 

- 

- def add_user_entry(server, idx, myparent):

-     name = 'tuser%d' % idx

-     dn = 'uid=%s,%s' % (name, myparent)

-     server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'organizationalPerson', 'inetorgperson'],

-                              'givenname': 'test',

-                              'sn': 'user%d' % idx,

-                              'cn': 'Test User%d' % idx,

-                              'userpassword': 'password'})))

-     time.sleep(1)

- 

- 

- def del_user_entry(server, idx, myparent):

-     name = 'tuser%d' % idx

-     dn = 'uid=%s,%s' % (name, myparent)

-     server.delete_s(dn)

-     time.sleep(1)

- 

- 

- def add_ldapsubentry(server, myparent):

-     name = 'nsPwPolicyContainer'

-     container = 'cn=%s,%s' % (name, myparent)

-     server.add_s(Entry((container, {'objectclass': ['top', 'nsContainer'],

-                                     'cn': '%s' % name})))

- 

-     name = 'nsPwPolicyEntry'

-     pwpentry = 'cn=%s,%s' % (name, myparent)

-     pwpdn = 'cn="%s",%s' % (pwpentry, container)

-     server.add_s(Entry((pwpdn, {'objectclass': ['top', 'ldapsubentry', 'passwordpolicy'],

-                                 'passwordStorageScheme': 'ssha',

-                                 'passwordCheckSyntax': 'on',

-                                 'passwordInHistory': '6',

-                                 'passwordChange': 'on',

-                                 'passwordMinAge': '0',

-                                 'passwordExp': 'off',

-                                 'passwordMustChange': 'off',

-                                 'cn': '%s' % pwpentry})))

- 

-     name = 'nsPwTemplateEntry'

-     tmplentry = 'cn=%s,%s' % (name, myparent)

-     tmpldn = 'cn="%s",%s' % (tmplentry, container)

-     server.add_s(Entry((tmpldn, {'objectclass': ['top', 'ldapsubentry', 'costemplate', 'extensibleObject'],

-                                  'cosPriority': '1',

-                                  'cn': '%s' % tmplentry})))

- 

-     name = 'nsPwPolicy_CoS'

-     cos = 'cn=%s,%s' % (name, myparent)

-     server.add_s(Entry((cos, {'objectclass': ['top', 'ldapsubentry', 'cosPointerDefinition', 'cosSuperDefinition'],

-                               'costemplatedn': '%s' % tmpldn,

-                               'cosAttribute': 'pwdpolicysubentry default operational-default',

-                               'cn': '%s' % name})))

-     time.sleep(1)

- 

- 

- def test_ticket48755(topology_m2):

-     log.info("Ticket 48755 - moving an entry could make the online init fail")

- 

-     M1 = topology_m2.ms["master1"]

-     M2 = topology_m2.ms["master2"]

- 

-     log.info("Generating DIT_0")

-     idx = 0

-     add_ou_entry(M1, idx, DEFAULT_SUFFIX)

- 

-     ou0 = 'ou=OU%d' % idx

-     parent0 = '%s,%s' % (ou0, DEFAULT_SUFFIX)

-     add_ou_entry(M1, idx, parent0)

- 

-     add_ldapsubentry(M1, parent0)

- 

-     parent00 = 'ou=OU%d,%s' % (idx, parent0)

-     for idx in range(0, 9):

-         add_user_entry(M1, idx, parent00)

-         if idx % 2 == 0:

-             log.info("Turning tuser%d into a tombstone entry" % idx)

-             del_user_entry(M1, idx, parent00)

- 

-     log.info('%s => %s => %s => 10 USERS' % (DEFAULT_SUFFIX, parent0, parent00))

- 

-     log.info("Generating DIT_1")

-     idx = 1

-     add_ou_entry(M1, idx, DEFAULT_SUFFIX)

- 

-     parent1 = 'ou=OU%d,%s' % (idx, DEFAULT_SUFFIX)

-     add_ou_entry(M1, idx, parent1)

- 

-     add_ldapsubentry(M1, parent1)

- 

-     log.info("Moving %s to DIT_1" % parent00)

-     M1.rename_s(parent00, ou0, newsuperior=parent1, delold=1)

-     time.sleep(1)

- 

-     log.info("Moving %s to DIT_1" % parent0)

-     parent01 = '%s,%s' % (ou0, parent1)

-     M1.rename_s(parent0, ou0, newsuperior=parent01, delold=1)

-     time.sleep(1)

- 

-     parent001 = '%s,%s' % (ou0, parent01)

-     log.info("Moving USERS to %s" % parent0)

-     for idx in range(0, 9):

-         if idx % 2 == 1:

-             name = 'tuser%d' % idx

-             rdn = 'uid=%s' % name

-             dn = 'uid=%s,%s' % (name, parent01)

-             M1.rename_s(dn, rdn, newsuperior=parent001, delold=1)

-             time.sleep(1)

- 

-     log.info('%s => %s => %s => %s => 10 USERS' % (DEFAULT_SUFFIX, parent1, parent01, parent001))

- 

-     log.info("Run Consumer Initialization.")

-     m1_m2_agmt = M1.agreement.list(suffix=DEFAULT_SUFFIX)[0].dn

-     M1.startReplication_async(m1_m2_agmt)

-     M1.waitForReplInit(m1_m2_agmt)

-     time.sleep(2)

- 

-     m1entries = M1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,

-                             '(|(objectclass=ldapsubentry)(objectclass=nstombstone)(nsuniqueid=*))')

-     m2entries = M2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE,

-                             '(|(objectclass=ldapsubentry)(objectclass=nstombstone)(nsuniqueid=*))')

- 

-     log.info("m1entry count - %d", len(m1entries))

-     log.info("m2entry count - %d", len(m2entries))

- 

-     assert len(m1entries) == len(m2entries)

-     log.info('PASSED')

- 

- 

- if __name__ == '__main__':

-     # Run isolated

-     # -s for DEBUG mode

-     CURRENT_FILE = os.path.realpath(__file__)

-     pytest.main("-s %s" % CURRENT_FILE)

Description:
Fixing failing ticket48755_test.py, so it would pass nightly tests.
Also moved the test from tickets to suites/replication/regressions_test.py

This code is NOT IN MERGEABLE state.
The test passes on Fedora, RHEL7 and RHEL8
but I could use an advice with how to replace "search_s"
so the test wouldn't use deprecated features, please.
Thanks.

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

Reviewed by: vashirov (Thanks!)

search_s won't be deprecated itself. We just want to get rid of the Entry API.
https://pagure.io/389-ds-base/issue/50600
So we are free to use it in special cases. This one is special, I think. The case when we want to get all server entries including hidden and tombstones.

The code LGTM! Ack

rebased onto b8a922e

4 years ago

Pull-Request has been merged by spichugi

4 years ago

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

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

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

Thank you for understanding. We apologize for all inconvenience.

Pull-Request has been closed by spichugi

3 years ago