From 007c360f85151caab7d608cc0a4eb1916b18eba9 Mon Sep 17 00:00:00 2001 From: Filip Skola Date: Mon, 18 Jan 2016 13:56:44 +0100 Subject: Refactor test_sudocmd_plugin Reviewed-By: Ales 'alich' Marecek --- ipatests/test_xmlrpc/test_sudocmd_plugin.py | 448 +++++++++---------------- ipatests/test_xmlrpc/tracker/sudocmd_plugin.py | 113 +++++++ 2 files changed, 269 insertions(+), 292 deletions(-) create mode 100644 ipatests/test_xmlrpc/tracker/sudocmd_plugin.py (limited to 'ipatests/test_xmlrpc') diff --git a/ipatests/test_xmlrpc/test_sudocmd_plugin.py b/ipatests/test_xmlrpc/test_sudocmd_plugin.py index 2056118ba..7ffe7a1d0 100644 --- a/ipatests/test_xmlrpc/test_sudocmd_plugin.py +++ b/ipatests/test_xmlrpc/test_sudocmd_plugin.py @@ -21,309 +21,173 @@ Test the `ipalib/plugins/sudocmd.py` module. """ -from ipalib import errors -from ipatests.test_xmlrpc.xmlrpc_test import (Declarative, fuzzy_sudocmddn, - fuzzy_uuid) -from ipatests.test_xmlrpc import objectclasses +from ipalib import api, errors +from ipatests.util import assert_deepequal +from ipatests.test_xmlrpc.xmlrpc_test import (XMLRPC_test, raises_exact) +from ipatests.test_xmlrpc.tracker.sudocmd_plugin import SudoCmdTracker import pytest -sudocmd1 = u'/usr/bin/sudotestcmd1' -sudocmd1_camelcase = u'/usr/bin/sudoTestCmd1' -sudorule1 = u'test_sudorule1' +@pytest.fixture(scope='class') +def sudocmd1(request): + tracker = SudoCmdTracker(command=u'/usr/bin/sudotestcmd1', + description=u'Test sudo command 1') + return tracker.make_fixture(request) -@pytest.mark.tier1 -class test_sudocmd(Declarative): - - cleanup_commands = [ - ('sudocmd_del', [sudocmd1], {}), - ('sudocmd_del', [sudocmd1_camelcase], {}), - ('sudorule_del', [sudorule1], {}), - ] - - tests = [ - - dict( - desc='Try to retrieve non-existent %r' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Try to update non-existent %r' % sudocmd1, - command=('sudocmd_mod', [sudocmd1], dict(description=u'Nope')), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Try to delete non-existent %r' % sudocmd1, - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - - - dict( - desc='Create %r' % sudocmd1, - command=('sudocmd_add', [sudocmd1], - dict( - description=u'Test sudo command 1', - ), - ), - expected=dict( - value=sudocmd1, - summary=u'Added Sudo Command "%s"' % sudocmd1, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - objectclass=objectclasses.sudocmd, - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - dict( - desc='Create %r' % sudocmd1_camelcase, - command=('sudocmd_add', [sudocmd1_camelcase], - dict( - description=u'Test sudo command 2', - ), - ), - expected=dict( - value=sudocmd1_camelcase, - summary=u'Added Sudo Command "%s"' % sudocmd1_camelcase, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1_camelcase], - description=[u'Test sudo command 2'], - objectclass=objectclasses.sudocmd, - ipauniqueid=[fuzzy_uuid], - ), - ), - ), - - - dict( - desc='Try to create duplicate %r' % sudocmd1, - command=('sudocmd_add', [sudocmd1], - dict( - description=u'Test sudo command 1', - ), - ), - expected=errors.DuplicateEntry(message=u'sudo command with ' + - u'name "%s" already exists' % sudocmd1), - ), - - dict( - desc='Try to create duplicate %r' % sudocmd1_camelcase, - command=('sudocmd_add', [sudocmd1_camelcase], - dict( - description=u'Test sudo command 2', - ), - ), - expected=errors.DuplicateEntry(message=u'sudo command with ' + - u'name "%s" already exists' % sudocmd1_camelcase), - ), - - - dict( - desc='Retrieve %r' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=dict( - value=sudocmd1, - summary=None, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - ), - ), - ), +@pytest.fixture(scope='class') +def sudocmd2(request): + tracker = SudoCmdTracker(command=u'/usr/bin/sudoTestCmd1', + description=u'Test sudo command 2') + return tracker.make_fixture(request) - dict( - desc='Search for %r' % sudocmd1, - command=('sudocmd_find', [sudocmd1], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 Sudo Command matched', - result=[ - dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Test sudo command 1'], - ), - ], - ), - ), +@pytest.fixture(scope='class') +def sudorule1(request): + name = u'test_sudorule1' - dict( - desc='Search for %r' % sudocmd1_camelcase, - command=('sudocmd_find', [sudocmd1_camelcase], {}), - expected=dict( - count=1, - truncated=False, - summary=u'1 Sudo Command matched', - result=[ - dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1_camelcase], - description=[u'Test sudo command 2'], - ), - ], - ), - ), + def fin(): + api.Command['sudorule_del'](name) + request.addfinalizer(fin) + return name - dict( - desc='Update %r' % sudocmd1, - command=('sudocmd_mod', [sudocmd1], dict( - description=u'Updated sudo command 1')), - expected=dict( - value=sudocmd1, - summary=u'Modified Sudo Command "%s"' % sudocmd1, - result=dict( - sudocmd=[sudocmd1], - description=[u'Updated sudo command 1'], - ), - ), - ), - - - dict( - desc='Retrieve %r to verify update' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=dict( - value=sudocmd1, - summary=None, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1], - description=[u'Updated sudo command 1'], - ), - ), - ), - - dict( - desc='Create %r' % sudorule1, - command=('sudorule_add', [sudorule1], {}), - expected=lambda e, result: True, - ), - - dict( - desc='Add %r to %r allow list' % (sudocmd1, sudorule1), - command=('sudorule_add_allow_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1), - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.DependentEntry(key=sudocmd1, label='sudorule', - dependent=sudorule1), - ), - - dict( - desc='Remove %r from %r' % (sudocmd1, sudorule1), - command=('sudorule_remove_allow_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc='Add %r to %r deny list' % (sudocmd1, sudorule1), - command=('sudorule_add_deny_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc="Test %r can't be deleted when in %r" % (sudocmd1, sudorule1), - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.DependentEntry(key=sudocmd1, label='sudorule', - dependent=sudorule1), - ), - - dict( - desc='Remove %r from %r' % (sudocmd1, sudorule1), - command=('sudorule_remove_deny_command', [sudorule1], - dict(sudocmd=sudocmd1)), - expected=dict( - completed=1, - failed=dict( - memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), - result=lambda result: True, - ), - ), - - dict( - desc='Delete %r' % sudocmd1, - command=('sudocmd_del', [sudocmd1], {}), - expected=dict( - value=[sudocmd1], - summary=u'Deleted Sudo Command "%s"' % sudocmd1, - result=dict(failed=[]), - ), - ), - - - dict( - desc='Try to retrieve non-existent %r' % sudocmd1, - command=('sudocmd_show', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - +@pytest.mark.tier1 +class TestNonexistentSudoCmd(XMLRPC_test): + def test_retrieve_nonexistent(self, sudocmd1): + """ Try to retrieve non-existent sudocmd """ + command = sudocmd1.make_retrieve_command() + with raises_exact(errors.NotFound( + reason=u'%s: sudo command not found' % sudocmd1.cmd)): + command() + + def test_update_nonexistent(self, sudocmd1): + """ Try to update non-existent sudocmd """ + command = sudocmd1.make_update_command(dict(description=u'Nope')) + with raises_exact(errors.NotFound( + reason=u'%s: sudo command not found' % sudocmd1.cmd)): + command() + + def test_delete_nonexistent(self, sudocmd1): + """ Try to delete non-existent sudocmd """ + command = sudocmd1.make_delete_command() + with raises_exact(errors.NotFound( + reason=u'%s: sudo command not found' % sudocmd1.cmd)): + command() - dict( - desc='Try to update non-existent %r' % sudocmd1, - command=('sudocmd_mod', [sudocmd1], dict(description=u'Nope')), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), +@pytest.mark.tier1 +class TestSudoCmd(XMLRPC_test): + def test_create(self, sudocmd1, sudocmd2): + """ Create sudocmd and sudocmd with camelcase'd command """ + sudocmd1.ensure_exists() + sudocmd2.ensure_exists() + + def test_create_duplicates(self, sudocmd1, sudocmd2): + """ Try to create duplicate sudocmds """ + sudocmd1.ensure_exists() + sudocmd2.ensure_exists() + command1 = sudocmd1.make_create_command() + command2 = sudocmd2.make_create_command() + + with raises_exact(errors.DuplicateEntry( + message=u'sudo command with name "%s" already exists' % + sudocmd1.cmd)): + command1() + with raises_exact(errors.DuplicateEntry( + message=u'sudo command with name "%s" already exists' % + sudocmd2.cmd)): + command2() + + def test_retrieve(self, sudocmd1): + """ Retrieve sudocmd """ + sudocmd1.ensure_exists() + sudocmd1.retrieve() + + def test_search(self, sudocmd1, sudocmd2): + """ Search for sudocmd """ + sudocmd1.find() + sudocmd2.find() + + def test_update_and_verify(self, sudocmd1): + """ Update sudocmd description and verify by retrieve """ + sudocmd1_desc_new = u'Updated sudo command 1' + sudocmd1.update(dict(description=sudocmd1_desc_new), + dict(description=[sudocmd1_desc_new])) + sudocmd1.retrieve() - dict( - desc='Try to delete non-existent %r' % sudocmd1, - command=('sudocmd_del', [sudocmd1], {}), - expected=errors.NotFound( - reason=u'%s: sudo command not found' % sudocmd1), - ), - dict( - desc='Retrieve %r' % sudocmd1_camelcase, - command=('sudocmd_show', [sudocmd1_camelcase], {}), - expected=dict( - value=sudocmd1_camelcase, - summary=None, - result=dict( - dn=fuzzy_sudocmddn, - sudocmd=[sudocmd1_camelcase], - description=[u'Test sudo command 2'], - ), - ), - ), - ] +@pytest.mark.tier1 +class TestSudoCmdInSudoRuleLists(XMLRPC_test): + def test_add_sudocmd_to_sudorule_allow_list(self, sudocmd1, sudorule1): + """ Add sudocmd to sudorule allow list """ + sudocmd1.ensure_exists() + api.Command['sudorule_add'](sudorule1) + result = api.Command['sudorule_add_allow_command']( + sudorule1, sudocmd=sudocmd1.cmd + ) + assert_deepequal(dict( + completed=1, + failed=dict( + memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), + result=lambda result: True, + ), result) + + def test_del_dependent_sudocmd_sudorule_allow(self, sudocmd1, sudorule1): + """ Try to delete sudocmd that is in sudorule allow list """ + sudocmd1.ensure_exists() + command = sudocmd1.make_delete_command() + with raises_exact(errors.DependentEntry( + key=sudocmd1.cmd, + label='sudorule', + dependent=sudorule1)): + command() + + def test_remove_sudocmd_from_sudorule_allow(self, sudocmd1, sudorule1): + """ Remove sudocmd from sudorule allow list """ + sudocmd1.ensure_exists() + result = api.Command['sudorule_remove_allow_command']( + sudorule1, sudocmd=sudocmd1.cmd + ) + assert_deepequal(dict( + completed=1, + failed=dict( + memberallowcmd=dict(sudocmdgroup=(), sudocmd=())), + result=lambda result: True), + result) + + def test_add_sudocmd_to_sudorule_deny_list(self, sudocmd1, sudorule1): + """ Add sudocmd to sudorule deny list """ + sudocmd1.ensure_exists() + result = api.Command['sudorule_add_deny_command']( + sudorule1, sudocmd=sudocmd1.cmd + ) + assert_deepequal(dict( + completed=1, + failed=dict( + memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), + result=lambda result: True), + result) + + def test_del_dependent_sudocmd_sudorule_deny(self, sudocmd1, sudorule1): + """ Try to delete sudocmd that is in sudorule deny list """ + sudocmd1.ensure_exists() + command = sudocmd1.make_delete_command() + with raises_exact(errors.DependentEntry( + key=sudocmd1.cmd, + label='sudorule', + dependent=sudorule1)): + command() + + def test_remove_sudocmd_from_sudorule_deny(self, sudocmd1, sudorule1): + """ Remove sudocmd from sudorule deny list """ + sudocmd1.ensure_exists() + result = api.Command['sudorule_remove_deny_command']( + sudorule1, sudocmd=sudocmd1.cmd + ) + assert_deepequal(dict( + completed=1, + failed=dict( + memberdenycmd=dict(sudocmdgroup=(), sudocmd=())), + result=lambda result: True), + result) diff --git a/ipatests/test_xmlrpc/tracker/sudocmd_plugin.py b/ipatests/test_xmlrpc/tracker/sudocmd_plugin.py new file mode 100644 index 000000000..eb72e4ba2 --- /dev/null +++ b/ipatests/test_xmlrpc/tracker/sudocmd_plugin.py @@ -0,0 +1,113 @@ +# +# Copyright (C) 2015 FreeIPA Contributors see COPYING for license +# + +from ipatests.test_xmlrpc import objectclasses +from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_uuid, fuzzy_sudocmddn + +from ipatests.test_xmlrpc.tracker.base import Tracker +from ipatests.util import assert_deepequal + + +class SudoCmdTracker(Tracker): + """ Class for tracking sudo commands """ + retrieve_keys = {u'dn', u'sudocmd', u'description', + u'memberof_sudocmdgroup'} + retrieve_all_keys = retrieve_keys | {u'ipauniqueid', u'objectclass'} + + create_keys = retrieve_all_keys + update_keys = retrieve_keys - {u'dn'} + + def __init__(self, command, description="Test sudo command"): + super(SudoCmdTracker, self).__init__(default_version=None) + self.cmd = command + self.dn = fuzzy_sudocmddn + self.description = description + + @property + def name(self): + """ Property holding the name of the entry in LDAP """ + return self.cmd + + def make_create_command(self, force=True): + """ Make function that creates a sudocmd using 'sudocmd-add' """ + return self.make_command('sudocmd_add', self.cmd, + description=self.description) + + def make_delete_command(self): + """ Make function that deletes a sudocmd using 'sudocmd-del' """ + return self.make_command('sudocmd_del', self.cmd) + + def make_retrieve_command(self, all=False, raw=False): + """ Make function that retrieves a sudocmd using 'sudocmd-show' """ + return self.make_command('sudocmd_show', self.cmd, all=all) + + def make_find_command(self, *args, **kwargs): + """ Make function that searches for a sudocmd using 'sudocmd-find' """ + return self.make_command('sudocmd_find', *args, **kwargs) + + def make_update_command(self, updates): + """ Make function that updates a sudocmd using 'sudocmd-mod' """ + return self.make_command('sudocmd_mod', self.cmd, **updates) + + def track_create(self): + """ Updates expected state for sudocmd creation""" + self.attrs = dict( + dn=self.dn, + sudocmd=[self.cmd], + description=[self.description], + ipauniqueid=[fuzzy_uuid], + objectclass=objectclasses.sudocmd, + ) + self.exists = True + + def check_create(self, result): + """ Checks 'sudocmd_add' command result """ + assert_deepequal(dict( + value=self.cmd, + summary=u'Added Sudo Command "%s"' % self.cmd, + result=self.filter_attrs(self.create_keys) + ), result) + + def check_delete(self, result): + """ Checks 'sudocmd_del' command result """ + assert_deepequal(dict( + value=[self.cmd], + summary=u'Deleted Sudo Command "%s"' % self.cmd, + result=dict(failed=[]), + ), result) + + def check_retrieve(self, result, all=False, raw=False): + """ Checks 'sudocmd_show' command result """ + if all: + expected = self.filter_attrs(self.retrieve_all_keys) + else: + expected = self.filter_attrs(self.retrieve_keys) + + assert_deepequal(dict( + value=self.cmd, + summary=None, + result=expected + ), result) + + def check_find(self, result, all=False, raw=False): + """ Checks 'sudocmd_find' command result """ + if all: + expected = self.filter_attrs(self.retrieve_all_keys) + else: + expected = self.filter_attrs(self.retrieve_keys) + + assert_deepequal(dict( + count=1, + truncated=False, + summary=u'1 Sudo Command matched', + result=[expected], + ), result) + + def check_update(self, result, extra_keys={}): + """ Checks 'sudocmd_mod' command result """ + assert_deepequal(dict( + value=self.cmd, + summary=u'Modified Sudo Command "%s"' % self.cmd, + result=self.filter_attrs(self.update_keys | set(extra_keys)) + ), result) -- cgit