URL: https://github.com/freeipa/freeipa/pull/3251 Author: rcritten Title: #3251: [Backport][ipa-4-7] Work around autoremember-build timing issue test failures Action: opened
PR body: """ This PR was opened automatically because PR #3242 was pushed to master and backport to ipa-4-7 is required. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/3251/head:pr3251 git checkout pr3251
From 8559064f2bf3f8450d80b4e1b70bcaf24c48dddc Mon Sep 17 00:00:00 2001 From: Rob Crittenden <rcrit...@redhat.com> Date: Mon, 10 Jun 2019 13:52:08 -0400 Subject: [PATCH] tests: Wait for automember rebuild --no-wait tasks to finish The behavior of automember changed with the design https://www.port389.org/docs/389ds/design/automember-postop-modify-design.html such that members are "cleaned up" first then re-added. This has the effect of removing members that no longer apply to a rule. This was breaking the automember rebuild tests because sometimes the tests were faster than 389-ds causing memberships to be missed. This does a client-side wait for the task to finish up so still exercises the rebuild code. https://pagure.io/freeipa/issue/7972 Signed-off-by: Rob Crittenden <rcrit...@redhat.com> --- .../test_xmlrpc/test_automember_plugin.py | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/ipatests/test_xmlrpc/test_automember_plugin.py b/ipatests/test_xmlrpc/test_automember_plugin.py index 7f61929b56..344d682c24 100644 --- a/ipatests/test_xmlrpc/test_automember_plugin.py +++ b/ipatests/test_xmlrpc/test_automember_plugin.py @@ -31,7 +31,9 @@ from ipapython.ipautil import run from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test, raises_exact from ipatests.util import assert_deepequal +from ipaserver.plugins.automember import REBUILD_TASK_CONTAINER +import time import pytest import unittest @@ -275,6 +277,52 @@ def set_automember_process_modify_ops(value): run(cmd) +def wait_automember_rebuild(): + """Wait for an asynchronous automember rebuild to finish + + Lookup the rebuild taskid and then loop until it is finished. + + If no task is found assume that the task is already finished. + """ + if not have_ldap2: + raise unittest.SkipTest('server plugin not available') + ldap = ldap2(api) + ldap.connect() + + # give the task a chance to start + time.sleep(1) + + try: + task_entries, unused = ldap.find_entries( + base_dn=REBUILD_TASK_CONTAINER, + filter='(&(!(nstaskexitcode=0))(scope=*))') + except errors.NotFound: + # either it's done already or it never started + return + + # we run these serially so there should be only one at a time + assert len(task_entries) == 1 + + task_dn = task_entries[0].dn + + start_time = time.time() + while True: + try: + task = ldap.get_entry(task_dn) + except errors.NotFound: + # not likely but let's hope the task disappered because it's + # finished + break + + if 'nstaskexitcode' in task: + # a non-zero exit code means something broke + assert task.single_value['nstaskexitcode'] == '0' + break + time.sleep(1) + # same arbitrary wait time as hardcoded in automember plugin + assert time.time() < (start_time + 60) + + @pytest.mark.tier1 class TestAutomemberRebuildHostMembership(XMLRPC_test): def test_create_deps_for_rebuilding_hostgroups(self, hostgroup1, host1, @@ -302,6 +350,7 @@ def test_rebuild_membership_hostgroups(self, automember_hostgroup, set_automember_process_modify_ops(value=b'off') automember_hostgroup.rebuild() automember_hostgroup.rebuild(no_wait=True) + wait_automember_rebuild() # After rebuild, the member is added, and we need to update # the tracker obj hostgroup1.attrs.update(member_host=[host1.fqdn]) @@ -315,6 +364,7 @@ def test_rebuild_membership_hostgroups(self, automember_hostgroup, # Rebuild membership to re-add the member automember_hostgroup.rebuild() automember_hostgroup.rebuild(no_wait=True) + wait_automember_rebuild() # After rebuild, the member is added, and we need to update # the tracker obj hostgroup1.attrs.update(member_host=[host1.fqdn]) @@ -342,6 +392,7 @@ def test_rebuild_membership_for_host(self, host1, automember_hostgroup, no_wait=True) result = command() automember_hostgroup.check_rebuild(result, no_wait=True) + wait_automember_rebuild() hostgroup1.attrs.update(member_host=[host1.fqdn]) hostgroup1.retrieve() @@ -380,6 +431,7 @@ def test_rebuild_membership_groups(self, automember_group, group1, user1): set_automember_process_modify_ops(value=b'off') automember_group.rebuild() automember_group.rebuild(no_wait=True) + wait_automember_rebuild() # After rebuild, the member is added, and we need to update # the tracker obj group1.attrs.update(member_user=[user1.name]) @@ -393,6 +445,7 @@ def test_rebuild_membership_groups(self, automember_group, group1, user1): # Rebuild membership to re-add the member automember_group.rebuild() automember_group.rebuild(no_wait=True) + wait_automember_rebuild() # After rebuild, the member is added, and we need to update # the tracker obj group1.attrs.update(member_user=[user1.name]) @@ -419,6 +472,7 @@ def test_rebuild_membership_for_user(self, user1, automember_group, no_wait=True) result = command() automember_group.check_rebuild(result, no_wait=True) + wait_automember_rebuild() group1.attrs.update(member_user=[user1.name]) group1.retrieve()
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org