diff options
Diffstat (limited to 'tests/test_ipalib/test_frontend.py')
-rw-r--r-- | tests/test_ipalib/test_frontend.py | 1188 |
1 files changed, 0 insertions, 1188 deletions
diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py deleted file mode 100644 index 3a540608d..000000000 --- a/tests/test_ipalib/test_frontend.py +++ /dev/null @@ -1,1188 +0,0 @@ -# Authors: -# Jason Gerard DeRose <jderose@redhat.com> -# -# Copyright (C) 2008 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 <http://www.gnu.org/licenses/>. - -""" -Test the `ipalib.frontend` module. -""" - -from tests.util import raises, getitem, no_set, no_del, read_only -from tests.util import check_TypeError, ClassChecker, create_test_api -from tests.util import assert_equal -from ipalib.constants import TYPE_ERROR -from ipalib.base import NameSpace -from ipalib import frontend, backend, plugable, errors, parameters, config -from ipalib import output, messages -from ipalib.parameters import Str -from ipapython.version import API_VERSION - -def test_RULE_FLAG(): - assert frontend.RULE_FLAG == 'validation_rule' - - -def test_rule(): - """ - Test the `ipalib.frontend.rule` function. - """ - flag = frontend.RULE_FLAG - rule = frontend.rule - def my_func(): - pass - assert not hasattr(my_func, flag) - rule(my_func) - assert getattr(my_func, flag) is True - @rule - def my_func2(): - pass - assert getattr(my_func2, flag) is True - - -def test_is_rule(): - """ - Test the `ipalib.frontend.is_rule` function. - """ - is_rule = frontend.is_rule - flag = frontend.RULE_FLAG - - class no_call(object): - def __init__(self, value): - if value is not None: - assert value in (True, False) - setattr(self, flag, value) - - class call(no_call): - def __call__(self): - pass - - assert is_rule(call(True)) - assert not is_rule(no_call(True)) - assert not is_rule(call(False)) - assert not is_rule(call(None)) - - -class test_HasParam(ClassChecker): - """ - Test the `ipalib.frontend.Command` class. - """ - - _cls = frontend.HasParam - - def test_get_param_iterable(self): - """ - Test the `ipalib.frontend.HasParam._get_param_iterable` method. - """ - class WithTuple(self.cls): - takes_stuff = ('one', 'two') - o = WithTuple() - assert o._get_param_iterable('stuff') is WithTuple.takes_stuff - - junk = ('three', 'four') - class WithCallable(self.cls): - def takes_stuff(self): - return junk - o = WithCallable() - assert o._get_param_iterable('stuff') is junk - - class WithParam(self.cls): - takes_stuff = parameters.Str('five') - o = WithParam() - assert o._get_param_iterable('stuff') == (WithParam.takes_stuff,) - - class WithStr(self.cls): - takes_stuff = 'six' - o = WithStr() - assert o._get_param_iterable('stuff') == ('six',) - - class Wrong(self.cls): - takes_stuff = ['seven', 'eight'] - o = Wrong() - e = raises(TypeError, o._get_param_iterable, 'stuff') - assert str(e) == '%s.%s must be a tuple, callable, or spec; got %r' % ( - 'Wrong', 'takes_stuff', Wrong.takes_stuff - ) - - def test_filter_param_by_context(self): - """ - Test the `ipalib.frontend.HasParam._filter_param_by_context` method. - """ - class Example(self.cls): - def get_stuff(self): - return ( - 'one', # Make sure create_param() is called for each spec - 'two', - parameters.Str('three', include='cli'), - parameters.Str('four', exclude='server'), - parameters.Str('five', exclude=['whatever', 'cli']), - ) - o = Example() - - # Test when env is None: - params = list(o._filter_param_by_context('stuff')) - assert list(p.name for p in params) == [ - 'one', 'two', 'three', 'four', 'five' - ] - for p in params: - assert type(p) is parameters.Str - - # Test when env.context == 'cli': - cli = config.Env(context='cli') - assert cli.context == 'cli' - params = list(o._filter_param_by_context('stuff', cli)) - assert list(p.name for p in params) == ['one', 'two', 'three', 'four'] - for p in params: - assert type(p) is parameters.Str - - # Test when env.context == 'server' - server = config.Env(context='server') - assert server.context == 'server' - params = list(o._filter_param_by_context('stuff', server)) - assert list(p.name for p in params) == ['one', 'two', 'five'] - for p in params: - assert type(p) is parameters.Str - - # Test with no get_stuff: - class Missing(self.cls): - pass - o = Missing() - gen = o._filter_param_by_context('stuff') - e = raises(NotImplementedError, list, gen) - assert str(e) == 'Missing.get_stuff()' - - # Test when get_stuff is not callable: - class NotCallable(self.cls): - get_stuff = ('one', 'two') - o = NotCallable() - gen = o._filter_param_by_context('stuff') - e = raises(TypeError, list, gen) - assert str(e) == '%s.%s must be a callable; got %r' % ( - 'NotCallable', 'get_stuff', NotCallable.get_stuff - ) - - -class test_Command(ClassChecker): - """ - Test the `ipalib.frontend.Command` class. - """ - - _cls = frontend.Command - - def get_subcls(self): - """ - Return a standard subclass of `ipalib.frontend.Command`. - """ - class Rule(object): - def __init__(self, name): - self.name = name - - def __call__(self, _, value): - if value != self.name: - return _('must equal %r') % self.name - - default_from = parameters.DefaultFrom( - lambda arg: arg, - 'default_from' - ) - normalizer = lambda value: value.lower() - - class example(self.cls): - takes_options = ( - parameters.Str('option0', Rule('option0'), - normalizer=normalizer, - default_from=default_from, - ), - parameters.Str('option1', Rule('option1'), - normalizer=normalizer, - default_from=default_from, - ), - ) - return example - - def get_instance(self, args=tuple(), options=tuple()): - """ - Helper method used to test args and options. - """ - class example(self.cls): - takes_args = args - takes_options = options - o = example() - o.finalize() - return o - - def test_class(self): - """ - Test the `ipalib.frontend.Command` class. - """ - assert self.cls.takes_options == tuple() - assert self.cls.takes_args == tuple() - - def test_get_args(self): - """ - Test the `ipalib.frontend.Command.get_args` method. - """ - assert list(self.cls().get_args()) == [] - args = ('login', 'stuff') - o = self.get_instance(args=args) - assert tuple(o.get_args()) == args - - def test_get_options(self): - """ - Test the `ipalib.frontend.Command.get_options` method. - """ - options = list(self.cls().get_options()) - assert len(options) == 1 - assert options[0].name == 'version' - options = ('verbose', 'debug') - o = self.get_instance(options=options) - assert len(tuple(o.get_options())) == 3 - assert 'verbose' in tuple(o.get_options()) - assert 'debug' in tuple(o.get_options()) - - def test_args(self): - """ - Test the ``ipalib.frontend.Command.args`` instance attribute. - """ - assert self.cls().args is None - o = self.cls() - o.finalize() - assert type(o.args) is plugable.NameSpace - assert len(o.args) == 0 - args = ('destination', 'source?') - ns = self.get_instance(args=args).args - assert type(ns) is plugable.NameSpace - assert len(ns) == len(args) - assert list(ns) == ['destination', 'source'] - assert type(ns.destination) is parameters.Str - assert type(ns.source) is parameters.Str - assert ns.destination.required is True - assert ns.destination.multivalue is False - assert ns.source.required is False - assert ns.source.multivalue is False - - # Test TypeError: - e = raises(TypeError, self.get_instance, args=(u'whatever',)) - assert str(e) == TYPE_ERROR % ( - 'spec', (str, parameters.Param), u'whatever', unicode) - - # Test ValueError, required after optional: - e = raises(ValueError, self.get_instance, args=('arg1?', 'arg2')) - assert str(e) == 'arg2: required argument after optional' - - # Test ValueError, scalar after multivalue: - e = raises(ValueError, self.get_instance, args=('arg1+', 'arg2')) - assert str(e) == 'arg2: only final argument can be multivalue' - - def test_max_args(self): - """ - Test the ``ipalib.frontend.Command.max_args`` instance attribute. - """ - o = self.get_instance() - assert o.max_args == 0 - o = self.get_instance(args=('one?',)) - assert o.max_args == 1 - o = self.get_instance(args=('one', 'two?')) - assert o.max_args == 2 - o = self.get_instance(args=('one', 'multi+',)) - assert o.max_args is None - o = self.get_instance(args=('one', 'multi*',)) - assert o.max_args is None - - def test_options(self): - """ - Test the ``ipalib.frontend.Command.options`` instance attribute. - """ - assert self.cls().options is None - o = self.cls() - o.finalize() - assert type(o.options) is plugable.NameSpace - assert len(o.options) == 1 - options = ('target', 'files*') - ns = self.get_instance(options=options).options - assert type(ns) is plugable.NameSpace - assert len(ns) == len(options) + 1 - assert list(ns) == ['target', 'files', 'version'] - assert type(ns.target) is parameters.Str - assert type(ns.files) is parameters.Str - assert ns.target.required is True - assert ns.target.multivalue is False - assert ns.files.required is False - assert ns.files.multivalue is True - - def test_output(self): - """ - Test the ``ipalib.frontend.Command.output`` instance attribute. - """ - inst = self.cls() - assert inst.output is None - inst.finalize() - assert type(inst.output) is plugable.NameSpace - assert list(inst.output) == ['result'] - assert type(inst.output.result) is output.Output - - def test_iter_output(self): - """ - Test the ``ipalib.frontend.Command._iter_output`` instance attribute. - """ - class Example(self.cls): - pass - inst = Example() - - inst.has_output = tuple() - assert list(inst._iter_output()) == [] - - wrong = ['hello', 'world'] - inst.has_output = wrong - e = raises(TypeError, list, inst._iter_output()) - assert str(e) == 'Example.has_output: need a %r; got a %r: %r' % ( - tuple, list, wrong - ) - - wrong = ('hello', 17) - inst.has_output = wrong - e = raises(TypeError, list, inst._iter_output()) - assert str(e) == 'Example.has_output[1]: need a %r; got a %r: %r' % ( - (str, output.Output), int, 17 - ) - - okay = ('foo', output.Output('bar'), 'baz') - inst.has_output = okay - items = list(inst._iter_output()) - assert len(items) == 3 - assert list(o.name for o in items) == ['foo', 'bar', 'baz'] - for o in items: - assert type(o) is output.Output - - def test_soft_validate(self): - """ - Test the `ipalib.frontend.Command.soft_validate` method. - """ - class user_add(frontend.Command): - takes_args = parameters.Str('uid', - normalizer=lambda value: value.lower(), - default_from=lambda givenname, sn: givenname[0] + sn, - ) - - takes_options = ('givenname', 'sn') - - cmd = user_add() - cmd.env = config.Env(context='cli') - cmd.finalize() - assert list(cmd.params) == ['givenname', 'sn', 'uid', 'version'] - ret = cmd.soft_validate({}) - assert sorted(ret['values']) == ['version'] - assert sorted(ret['errors']) == ['givenname', 'sn', 'uid'] - assert cmd.soft_validate(dict(givenname=u'First', sn=u'Last')) == dict( - values=dict(givenname=u'First', sn=u'Last', uid=u'flast', - version=None), - errors=dict(), - ) - - def test_convert(self): - """ - Test the `ipalib.frontend.Command.convert` method. - """ - kw = dict( - option0=u'1.5', - option1=u'7', - ) - o = self.subcls() - o.finalize() - for (key, value) in o.convert(**kw).iteritems(): - assert_equal(unicode(kw[key]), value) - - def test_normalize(self): - """ - Test the `ipalib.frontend.Command.normalize` method. - """ - kw = dict( - option0=u'OPTION0', - option1=u'OPTION1', - ) - norm = dict((k, v.lower()) for (k, v) in kw.items()) - sub = self.subcls() - sub.finalize() - assert sub.normalize(**kw) == norm - - def test_get_default(self): - """ - Test the `ipalib.frontend.Command.get_default` method. - """ - # FIXME: Add an updated unit tests for get_default() - - def test_default_from_chaining(self): - """ - Test chaining of parameters through default_from. - """ - class my_cmd(self.cls): - takes_options = ( - Str('option0'), - Str('option1', default_from=lambda option0: option0), - Str('option2', default_from=lambda option1: option1), - ) - - def run(self, *args, **options): - return dict(result=options) - - kw = dict(option0=u'some value') - - (api, home) = create_test_api() - api.finalize() - o = my_cmd() - o.set_api(api) - o.finalize() - e = o(**kw) - assert type(e) is dict - assert 'result' in e - assert 'option2' in e['result'] - assert e['result']['option2'] == u'some value' - - def test_validate(self): - """ - Test the `ipalib.frontend.Command.validate` method. - """ - - sub = self.subcls() - sub.env = config.Env(context='cli') - sub.finalize() - - # Check with valid values - okay = dict( - option0=u'option0', - option1=u'option1', - another_option='some value', - version=API_VERSION, - ) - sub.validate(**okay) - - # Check with an invalid value - fail = dict(okay) - fail['option0'] = u'whatever' - e = raises(errors.ValidationError, sub.validate, **fail) - assert_equal(e.name, 'option0') - assert_equal(e.value, u'whatever') - assert_equal(e.error, u"must equal 'option0'") - assert e.rule.__class__.__name__ == 'Rule' - assert e.index is None - - # Check with a missing required arg - fail = dict(okay) - fail.pop('option1') - e = raises(errors.RequirementError, sub.validate, **fail) - assert e.name == 'option1' - - def test_execute(self): - """ - Test the `ipalib.frontend.Command.execute` method. - """ - o = self.cls() - e = raises(NotImplementedError, o.execute) - assert str(e) == 'Command.execute()' - - def test_args_options_2_params(self): - """ - Test the `ipalib.frontend.Command.args_options_2_params` method. - """ - - # Test that ZeroArgumentError is raised: - o = self.get_instance() - e = raises(errors.ZeroArgumentError, o.args_options_2_params, 1) - assert e.name == 'example' - - # Test that MaxArgumentError is raised (count=1) - o = self.get_instance(args=('one?',)) - e = raises(errors.MaxArgumentError, o.args_options_2_params, 1, 2) - assert e.name == 'example' - assert e.count == 1 - assert str(e) == "command 'example' takes at most 1 argument" - - # Test that MaxArgumentError is raised (count=2) - o = self.get_instance(args=('one', 'two?')) - e = raises(errors.MaxArgumentError, o.args_options_2_params, 1, 2, 3) - assert e.name == 'example' - assert e.count == 2 - assert str(e) == "command 'example' takes at most 2 arguments" - - # Test that OptionError is raised when an extra option is given: - o = self.get_instance() - e = raises(errors.OptionError, o.args_options_2_params, bad_option=True) - assert e.option == 'bad_option' - - # Test that OverlapError is raised: - o = self.get_instance(args=('one', 'two'), options=('three', 'four')) - e = raises(errors.OverlapError, o.args_options_2_params, - 1, 2, three=3, two=2, four=4, one=1) - assert e.names == ['one', 'two'] - - # Test the permutations: - o = self.get_instance(args=('one', 'two*'), options=('three', 'four')) - mthd = o.args_options_2_params - assert mthd() == dict() - assert mthd(1) == dict(one=1) - assert mthd(1, 2) == dict(one=1, two=(2,)) - assert mthd(1, 21, 22, 23) == dict(one=1, two=(21, 22, 23)) - assert mthd(1, (21, 22, 23)) == dict(one=1, two=(21, 22, 23)) - assert mthd(three=3, four=4) == dict(three=3, four=4) - assert mthd(three=3, four=4, one=1, two=2) == \ - dict(one=1, two=2, three=3, four=4) - assert mthd(1, 21, 22, 23, three=3, four=4) == \ - dict(one=1, two=(21, 22, 23), three=3, four=4) - assert mthd(1, (21, 22, 23), three=3, four=4) == \ - dict(one=1, two=(21, 22, 23), three=3, four=4) - - def test_args_options_2_entry(self): - """ - Test `ipalib.frontend.Command.args_options_2_entry` method. - """ - class my_cmd(self.cls): - takes_args = ( - parameters.Str('one', attribute=True), - parameters.Str('two', attribute=False), - ) - takes_options = ( - parameters.Str('three', attribute=True, multivalue=True), - parameters.Str('four', attribute=True, multivalue=False), - ) - - def run(self, *args, **kw): - return self.args_options_2_entry(*args, **kw) - - args = ('one', 'two') - kw = dict(three=('three1', 'three2'), four='four') - - (api, home) = create_test_api() - api.finalize() - o = my_cmd() - o.set_api(api) - o.finalize() - e = o.run(*args, **kw) - assert type(e) is dict - assert 'one' in e - assert 'two' not in e - assert 'three' in e - assert 'four' in e - assert e['one'] == 'one' - assert e['three'] == ['three1', 'three2'] - assert e['four'] == 'four' - - def test_params_2_args_options(self): - """ - Test the `ipalib.frontend.Command.params_2_args_options` method. - """ - o = self.get_instance(args='one', options='two') - assert o.params_2_args_options() == ((None,), {}) - assert o.params_2_args_options(one=1) == ((1,), {}) - assert o.params_2_args_options(two=2) == ((None,), dict(two=2)) - assert o.params_2_args_options(two=2, one=1) == ((1,), dict(two=2)) - - def test_run(self): - """ - Test the `ipalib.frontend.Command.run` method. - """ - class my_cmd(self.cls): - def execute(self, *args, **kw): - return ('execute', args, kw) - - def forward(self, *args, **kw): - return ('forward', args, kw) - - args = ('Hello,', 'world,') - kw = dict(how_are='you', on_this='fine day?', version=API_VERSION) - - # Test in server context: - (api, home) = create_test_api(in_server=True) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - out = o.run(*args, **kw) - assert ('execute', args, kw) == out - - # Test in non-server context - (api, home) = create_test_api(in_server=False) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - assert ('forward', args, kw) == o.run(*args, **kw) - - def test_messages(self): - """ - Test correct handling of messages - """ - class TestMessage(messages.PublicMessage): - type = 'info' - format = 'This is a message.' - errno = 1234 - - class my_cmd(self.cls): - def execute(self, *args, **kw): - result = {'name': 'execute'} - messages.add_message(kw['version'], result, TestMessage()) - return result - - def forward(self, *args, **kw): - result = {'name': 'forward'} - messages.add_message(kw['version'], result, TestMessage()) - return result - - args = ('Hello,', 'world,') - kw = dict(how_are='you', on_this='fine day?', version=API_VERSION) - - expected = [TestMessage().to_dict()] - - # Test in server context: - (api, home) = create_test_api(in_server=True) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - assert {'name': 'execute', 'messages': expected} == o.run(*args, **kw) - - # Test in non-server context - (api, home) = create_test_api(in_server=False) - api.finalize() - o = my_cmd() - o.set_api(api) - assert o.run.im_func is self.cls.run.im_func - assert {'name': 'forward', 'messages': expected} == o.run(*args, **kw) - - def test_validate_output_basic(self): - """ - Test the `ipalib.frontend.Command.validate_output` method. - """ - class Example(self.cls): - has_output = ('foo', 'bar', 'baz') - - inst = Example() - inst.finalize() - - # Test with wrong type: - wrong = ('foo', 'bar', 'baz') - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): need a %r; got a %r: %r' % ( - 'Example', dict, tuple, wrong - ) - - # Test with a missing keys: - wrong = dict(bar='hello') - e = raises(ValueError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): missing keys %r in %r' % ( - 'Example', ['baz', 'foo'], wrong - ) - - # Test with extra keys: - wrong = dict(foo=1, bar=2, baz=3, fee=4, azz=5) - e = raises(ValueError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): unexpected keys %r in %r' % ( - 'Example', ['azz', 'fee'], wrong - ) - - # Test with different keys: - wrong = dict(baz=1, xyzzy=2, quux=3) - e = raises(ValueError, inst.validate_output, wrong) - assert str(e) == '%s.validate_output(): missing keys %r in %r' % ( - 'Example', ['bar', 'foo'], wrong - ), str(e) - - def test_validate_output_per_type(self): - """ - Test `ipalib.frontend.Command.validate_output` per-type validation. - """ - - class Complex(self.cls): - has_output = ( - output.Output('foo', int), - output.Output('bar', list), - ) - inst = Complex() - inst.finalize() - - wrong = dict(foo=17.9, bar=[18]) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == '%s:\n output[%r]: need %r; got %r: %r' % ( - 'Complex.validate_output()', 'foo', int, float, 17.9 - ) - - wrong = dict(foo=18, bar=17) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == '%s:\n output[%r]: need %r; got %r: %r' % ( - 'Complex.validate_output()', 'bar', list, int, 17 - ) - - def test_validate_output_nested(self): - """ - Test `ipalib.frontend.Command.validate_output` nested validation. - """ - - class Subclass(output.ListOfEntries): - pass - - # Test nested validation: - class nested(self.cls): - has_output = ( - output.Output('hello', int), - Subclass('world'), - ) - inst = nested() - inst.finalize() - okay = dict(foo='bar') - nope = ('aye', 'bee') - - wrong = dict(hello=18, world=[okay, nope, okay]) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == output.emsg % ( - 'nested', 'Subclass', 'world', 1, dict, tuple, nope - ) - - wrong = dict(hello=18, world=[okay, okay, okay, okay, nope]) - e = raises(TypeError, inst.validate_output, wrong) - assert str(e) == output.emsg % ( - 'nested', 'Subclass', 'world', 4, dict, tuple, nope - ) - - def test_get_output_params(self): - """ - Test the `ipalib.frontend.Command.get_output_params` method. - """ - class example(self.cls): - has_output_params = ( - 'one', - 'two', - 'three', - ) - takes_args = ( - 'foo', - ) - takes_options = ( - Str('bar', flags='no_output'), - 'baz', - ) - - inst = example() - assert list(inst.get_output_params()) == ['one', 'two', 'three'] - inst.finalize() - assert list(inst.get_output_params()) == [ - 'one', 'two', 'three', inst.params.foo, inst.params.baz - ] - assert list(inst.output_params) == ['one', 'two', 'three', 'foo', 'baz'] - - -class test_LocalOrRemote(ClassChecker): - """ - Test the `ipalib.frontend.LocalOrRemote` class. - """ - _cls = frontend.LocalOrRemote - - def test_init(self): - """ - Test the `ipalib.frontend.LocalOrRemote.__init__` method. - """ - o = self.cls() - o.finalize() - assert list(o.args) == [] - assert list(o.options) == ['server', 'version'] - op = o.options.server - assert op.required is False - assert op.default is False - - def test_run(self): - """ - Test the `ipalib.frontend.LocalOrRemote.run` method. - """ - class example(self.cls): - takes_args = 'key?' - - def forward(self, *args, **options): - return dict(result=('forward', args, options)) - - def execute(self, *args, **options): - return dict(result=('execute', args, options)) - - # Test when in_server=False: - (api, home) = create_test_api(in_server=False) - api.register(example) - api.finalize() - cmd = api.Command.example - assert cmd(version=u'2.47') == dict( - result=('execute', (None,), dict(version=u'2.47', server=False)) - ) - assert cmd(u'var', version=u'2.47') == dict( - result=('execute', (u'var',), dict(version=u'2.47', server=False)) - ) - assert cmd(server=True, version=u'2.47') == dict( - result=('forward', (None,), dict(version=u'2.47', server=True)) - ) - assert cmd(u'var', server=True, version=u'2.47') == dict( - result=('forward', (u'var',), dict(version=u'2.47', server=True)) - ) - - # Test when in_server=True (should always call execute): - (api, home) = create_test_api(in_server=True) - api.register(example) - api.finalize() - cmd = api.Command.example - assert cmd(version=u'2.47') == dict( - result=('execute', (None,), dict(version=u'2.47', server=False)) - ) - assert cmd(u'var', version=u'2.47') == dict( - result=('execute', (u'var',), dict(version=u'2.47', server=False)) - ) - assert cmd(server=True, version=u'2.47') == dict( - result=('execute', (None,), dict(version=u'2.47', server=True)) - ) - assert cmd(u'var', server=True, version=u'2.47') == dict( - result=('execute', (u'var',), dict(version=u'2.47', server=True)) - ) - - -class test_Object(ClassChecker): - """ - Test the `ipalib.frontend.Object` class. - """ - _cls = frontend.Object - - def test_class(self): - """ - Test the `ipalib.frontend.Object` class. - """ - assert self.cls.backend is None - assert self.cls.methods is None - assert self.cls.properties is None - assert self.cls.params is None - assert self.cls.params_minus_pk is None - assert self.cls.takes_params == tuple() - - def test_init(self): - """ - Test the `ipalib.frontend.Object.__init__` method. - """ - o = self.cls() - assert o.backend is None - assert o.methods is None - assert o.properties is None - assert o.params is None - assert o.params_minus_pk is None - assert o.properties is None - - def test_set_api(self): - """ - Test the `ipalib.frontend.Object.set_api` method. - """ - # Setup for test: - class DummyAttribute(object): - def __init__(self, obj_name, attr_name, name=None): - self.obj_name = obj_name - self.attr_name = attr_name - if name is None: - self.name = '%s_%s' % (obj_name, attr_name) - else: - self.name = name - self.param = frontend.create_param(attr_name) - - def __clone__(self, attr_name): - return self.__class__( - self.obj_name, - self.attr_name, - getattr(self, attr_name) - ) - - def get_attributes(cnt, format): - for name in ['other', 'user', 'another']: - for i in xrange(cnt): - yield DummyAttribute(name, format % i) - - cnt = 10 - formats = dict( - methods='method_%d', - properties='property_%d', - ) - - - _d = dict( - Method=plugable.NameSpace( - get_attributes(cnt, formats['methods']) - ), - Property=plugable.NameSpace( - get_attributes(cnt, formats['properties']) - ), - ) - api = plugable.MagicDict(_d) - assert len(api.Method) == cnt * 3 - assert len(api.Property) == cnt * 3 - - class user(self.cls): - pass - - # Actually perform test: - o = user() - o.set_api(api) - assert read_only(o, 'api') is api - for name in ['methods', 'properties']: - namespace = getattr(o, name) - assert isinstance(namespace, plugable.NameSpace) - assert len(namespace) == cnt - f = formats[name] - for i in xrange(cnt): - attr_name = f % i - attr = namespace[attr_name] - assert isinstance(attr, DummyAttribute) - assert attr is getattr(namespace, attr_name) - assert attr.obj_name == 'user' - assert attr.attr_name == attr_name - assert attr.name == '%s_%s' % ('user', attr_name) - - # Test params instance attribute - o = self.cls() - o.set_api(api) - ns = o.params - assert type(ns) is plugable.NameSpace - assert len(ns) == 0 - class example(self.cls): - takes_params = ('banana', 'apple') - o = example() - o.set_api(api) - ns = o.params - assert type(ns) is plugable.NameSpace - assert len(ns) == 2, repr(ns) - assert list(ns) == ['banana', 'apple'] - for p in ns(): - assert type(p) is parameters.Str - assert p.required is True - assert p.multivalue is False - - def test_primary_key(self): - """ - Test the `ipalib.frontend.Object.primary_key` attribute. - """ - (api, home) = create_test_api() - api.finalize() - - # Test with no primary keys: - class example1(self.cls): - takes_params = ( - 'one', - 'two', - ) - o = example1() - o.set_api(api) - assert o.primary_key is None - - # Test with 1 primary key: - class example2(self.cls): - takes_params = ( - 'one', - 'two', - parameters.Str('three', primary_key=True), - 'four', - ) - o = example2() - o.set_api(api) - pk = o.primary_key - assert type(pk) is parameters.Str - assert pk.name == 'three' - assert pk.primary_key is True - assert o.params[2] is o.primary_key - assert isinstance(o.params_minus_pk, plugable.NameSpace) - assert list(o.params_minus_pk) == ['one', 'two', 'four'] - - # Test with multiple primary_key: - class example3(self.cls): - takes_params = ( - parameters.Str('one', primary_key=True), - parameters.Str('two', primary_key=True), - 'three', - parameters.Str('four', primary_key=True), - ) - o = example3() - o.set_api(api) - e = raises(ValueError, o.finalize) - assert str(e) == \ - 'example3 (Object) has multiple primary keys: one, two, four' - - def test_backend(self): - """ - Test the `ipalib.frontend.Object.backend` attribute. - """ - (api, home) = create_test_api() - class ldap(backend.Backend): - whatever = 'It worked!' - api.register(ldap) - class user(frontend.Object): - backend_name = 'ldap' - api.register(user) - api.finalize() - b = api.Object.user.backend - assert isinstance(b, ldap) - assert b.whatever == 'It worked!' - - def test_get_dn(self): - """ - Test the `ipalib.frontend.Object.get_dn` method. - """ - o = self.cls() - e = raises(NotImplementedError, o.get_dn, 'primary key') - assert str(e) == 'Object.get_dn()' - class user(self.cls): - pass - o = user() - e = raises(NotImplementedError, o.get_dn, 'primary key') - assert str(e) == 'user.get_dn()' - - def test_params_minus(self): - """ - Test the `ipalib.frontend.Object.params_minus` method. - """ - class example(self.cls): - takes_params = ('one', 'two', 'three', 'four') - o = example() - (api, home) = create_test_api() - o.set_api(api) - p = o.params - assert tuple(o.params_minus()) == tuple(p()) - assert tuple(o.params_minus([])) == tuple(p()) - assert tuple(o.params_minus('two', 'three')) == (p.one, p.four) - assert tuple(o.params_minus(['two', 'three'])) == (p.one, p.four) - assert tuple(o.params_minus(p.two, p.three)) == (p.one, p.four) - assert tuple(o.params_minus([p.two, p.three])) == (p.one, p.four) - ns = NameSpace([p.two, p.three]) - assert tuple(o.params_minus(ns)) == (p.one, p.four) - - -class test_Attribute(ClassChecker): - """ - Test the `ipalib.frontend.Attribute` class. - """ - _cls = frontend.Attribute - - def test_class(self): - """ - Test the `ipalib.frontend.Attribute` class. - """ - assert self.cls.__bases__ == (plugable.Plugin,) - assert type(self.cls.obj) is property - assert type(self.cls.obj_name) is property - assert type(self.cls.attr_name) is property - - def test_init(self): - """ - Test the `ipalib.frontend.Attribute.__init__` method. - """ - class user_add(self.cls): - pass - o = user_add() - assert read_only(o, 'obj') is None - assert read_only(o, 'obj_name') == 'user' - assert read_only(o, 'attr_name') == 'add' - - def test_set_api(self): - """ - Test the `ipalib.frontend.Attribute.set_api` method. - """ - user_obj = 'The user frontend.Object instance' - class api(object): - Object = dict(user=user_obj) - class user_add(self.cls): - pass - o = user_add() - assert read_only(o, 'api') is None - assert read_only(o, 'obj') is None - o.set_api(api) - assert read_only(o, 'api') is api - assert read_only(o, 'obj') is user_obj - - -class test_Method(ClassChecker): - """ - Test the `ipalib.frontend.Method` class. - """ - _cls = frontend.Method - - def get_api(self, args=tuple(), options=tuple()): - """ - Return a finalized `ipalib.plugable.API` instance. - """ - (api, home) = create_test_api() - class user(frontend.Object): - takes_params = ( - 'givenname', - 'sn', - frontend.Param('uid', primary_key=True), - 'initials', - ) - class user_verb(self.cls): - takes_args = args - takes_options = options - api.register(user) - api.register(user_verb) - api.finalize() - return api - - def test_class(self): - """ - Test the `ipalib.frontend.Method` class. - """ - assert self.cls.__bases__ == (frontend.Attribute, frontend.Command) - - def test_init(self): - """ - Test the `ipalib.frontend.Method.__init__` method. - """ - class user_add(self.cls): - pass - o = user_add() - assert o.name == 'user_add' - assert o.obj_name == 'user' - assert o.attr_name == 'add' - - -class test_Property(ClassChecker): - """ - Test the `ipalib.frontend.Property` class. - """ - _cls = frontend.Property - - def get_subcls(self): - """ - Return a standard subclass of `ipalib.frontend.Property`. - """ - class user_givenname(self.cls): - 'User first name' - - @frontend.rule - def rule0_lowercase(self, value): - if not value.islower(): - return 'Must be lowercase' - return user_givenname - - def test_class(self): - """ - Test the `ipalib.frontend.Property` class. - """ - assert self.cls.__bases__ == (frontend.Attribute,) - assert self.cls.klass is parameters.Str - - def test_init(self): - """ - Test the `ipalib.frontend.Property.__init__` method. - """ - o = self.subcls() - assert len(o.rules) == 1 - assert o.rules[0].__name__ == 'rule0_lowercase' - param = o.param - assert isinstance(param, parameters.Str) - assert param.name == 'givenname' - assert unicode(param.doc) == u'User first name' |