From 2b077f7b0d68a758ae15a73eeef74591bac84360 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 12 Mar 2012 05:58:44 -0400 Subject: [PATCH] Test the batch plugin This adds tests for the batch plugin, and changes its output declaration to allow results as tuples (this tripped validation). The assert_deepequal function ignores the order of items in lists. Document this in its docstring, and use a custom checker for the batch plugin results. --- ipalib/plugins/batch.py | 11 +- tests/test_xmlrpc/test_batch_plugin.py | 194 +++++++++++++++++++++++++ tests/util.py | 3 + 3 files changed, 201 insertions(+), 7 deletions(-) create mode 100644 tests/test_xmlrpc/test_batch_plugin.py diff --git a/ipalib/plugins/batch.py b/ipalib/plugins/batch.py index 4c5a6bd1e..8abad5e1e 100644 --- a/ipalib/plugins/batch.py +++ b/ipalib/plugins/batch.py @@ -76,11 +76,11 @@ class batch(Command): has_output = ( Output('count', int, doc=''), - Output('results', list, doc='') + Output('results', (list, tuple), doc='') ) def execute(self, *args, **options): - results=[] + results = [] for arg in args[0]: params = dict() name = None @@ -92,11 +92,8 @@ class batch(Command): name = arg['method'] if name not in self.Command: raise errors.CommandError(name=name) - a = arg['params'][0] - kw = arg['params'][1] - newkw = {} - for k in kw: - newkw[str(k)] = kw[k] + a, kw = arg['params'] + newkw = dict((str(k), v) for k, v in kw.iteritems()) params = api.Command[name].args_options_2_params(*a, **newkw) result = api.Command[name](*a, **newkw) diff --git a/tests/test_xmlrpc/test_batch_plugin.py b/tests/test_xmlrpc/test_batch_plugin.py new file mode 100644 index 000000000..d69bfd9c4 --- /dev/null +++ b/tests/test_xmlrpc/test_batch_plugin.py @@ -0,0 +1,194 @@ +# Authors: +# Petr Viktorin +# +# Copyright (C) 2012 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Test the `ipalib/plugins/batch.py` module. +""" + +from ipalib import api, errors +from tests.test_xmlrpc import objectclasses +from tests.util import assert_equal, Fuzzy, assert_deepequal +from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid +from ipalib.dn import DN + +group1 = u'testgroup1' + + +def deepequal_list(*expected): + """Factory for a function that checks a list + + The created function asserts items of a list are "deepequal" to the given + argument. Unlike using assert_deepequal directly, the order matters. + """ + def checker(got): + if len(expected) != len(got): + raise AssertionError('Expected %s entries, got %s\n\n%s\n%s' % + (len(expected), len(got), expected, got)) + for e, g in zip(expected, got): + assert_deepequal(e, g) + return True + return checker + + +class test_batch(Declarative): + + cleanup_commands = [ + ('group_del', [group1], {}), + ] + + tests = [ + + dict( + desc='Batch ping', + command=('batch', [dict(method='ping', params=([], {}))], {}), + expected=dict( + count=1, + results=[ + dict(summary=Fuzzy('IPA server version .*'), error=None), + ] + ), + ), + + dict( + desc='Batch two pings', + command=('batch', [dict(method='ping', params=([], {}))] * 2, {}), + expected=dict( + count=2, + results=[ + dict(summary=Fuzzy('IPA server version .*'), error=None), + dict(summary=Fuzzy('IPA server version .*'), error=None), + ] + ), + ), + + dict( + desc='Create and deleting a group', + command=('batch', [ + dict(method='group_add', + params=([group1], dict(description=u'Test desc 1'))), + dict(method='group_del', params=([group1], dict())), + ], {}), + expected=dict( + count=2, + results=deepequal_list( + dict( + value=group1, + summary=u'Added group "testgroup1"', + result=dict( + cn=[group1], + description=[u'Test desc 1'], + objectclass=objectclasses.group + [u'posixgroup'], + ipauniqueid=[fuzzy_uuid], + gidnumber=[fuzzy_digits], + dn=lambda x: DN(x) == \ + DN(('cn', 'testgroup1'), + ('cn', 'groups'), + ('cn', 'accounts'), + api.env.basedn), + ), + error=None), + dict( + summary=u'Deleted group "%s"' % group1, + result=dict(failed=u''), + value=group1, + error=None), + ), + ), + ), + + dict( + desc='Try to delete nonexistent group twice', + command=('batch', [ + dict(method='group_del', params=([group1], dict())), + dict(method='group_del', params=([group1], dict())), + ], {}), + expected=dict( + count=2, + results=[ + dict(error=u'%s: group not found' % group1), + dict(error=u'%s: group not found' % group1), + ], + ), + ), + + dict( + desc='Try to delete non-existent group first, then create it', + command=('batch', [ + dict(method='group_del', params=([group1], dict())), + dict(method='group_add', + params=([group1], dict(description=u'Test desc 1'))), + ], {}), + expected=dict( + count=2, + results=deepequal_list( + dict(error=u'%s: group not found' % group1), + dict( + value=group1, + summary=u'Added group "testgroup1"', + result=dict( + cn=[group1], + description=[u'Test desc 1'], + objectclass=objectclasses.group + [u'posixgroup'], + ipauniqueid=[fuzzy_uuid], + gidnumber=[fuzzy_digits], + dn=lambda x: DN(x) == \ + DN(('cn', 'testgroup1'), + ('cn', 'groups'), + ('cn', 'accounts'), + api.env.basedn), + ), + error=None), + ), + ), + ), + + dict( + desc='Try bad command invocations', + command=('batch', [ + # bad command name + dict(method='nonexistent_ipa_command', params=([], dict())), + # dash, not underscore, in command name + dict(method='user-del', params=([], dict())), + # missing command name + dict(params=([group1], dict())), + # missing params + dict(method='user_del'), + # missing required argument + dict(method='user_add', params=([], dict())), + # missing required option + dict(method='group_add', params=([group1], dict())), + # bad type + dict(method='group_add', params=([group1], dict( + description=u't', gidnumber=u'bad'))), + ], {}), + expected=dict( + count=7, + results=deepequal_list( + dict(error=u"unknown command 'nonexistent_ipa_command'"), + dict(error=u"unknown command 'user-del'"), + dict(error=u"'method' is required"), + dict(error=u"'params' is required"), + dict(error=u"'givenname' is required"), + dict(error=u"'description' is required"), + dict(error=Fuzzy(u"invalid 'gid'.*")), + ), + ), + ), + + ] diff --git a/tests/util.py b/tests/util.py index 9bce7c08c..7929321a1 100644 --- a/tests/util.py +++ b/tests/util.py @@ -287,6 +287,9 @@ def assert_deepequal(expected, got, doc='', stack=tuple()): expected = u'how are you?' got = 'how are you?' path = (0, 'world') + + Note that lists and tuples are considered equivalent, and the order of + their elements does not matter. """ if isinstance(expected, tuple): expected = list(expected)