freeipa/tests/test_ipalib/test_base.py

353 lines
10 KiB
Python

# 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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipalib.base` module.
"""
from tests.util import ClassChecker, raises
from ipalib.constants import NAME_REGEX, NAME_ERROR
from ipalib.constants import TYPE_ERROR, SET_ERROR, DEL_ERROR, OVERRIDE_ERROR
from ipalib import base
class test_ReadOnly(ClassChecker):
"""
Test the `ipalib.base.ReadOnly` class
"""
_cls = base.ReadOnly
def test_lock(self):
"""
Test the `ipalib.base.ReadOnly.__lock__` method.
"""
o = self.cls()
assert o._ReadOnly__locked is False
o.__lock__()
assert o._ReadOnly__locked is True
e = raises(AssertionError, o.__lock__) # Can only be locked once
assert str(e) == '__lock__() can only be called once'
assert o._ReadOnly__locked is True # This should still be True
def test_islocked(self):
"""
Test the `ipalib.base.ReadOnly.__islocked__` method.
"""
o = self.cls()
assert o.__islocked__() is False
o.__lock__()
assert o.__islocked__() is True
def test_setattr(self):
"""
Test the `ipalib.base.ReadOnly.__setattr__` method.
"""
o = self.cls()
o.attr1 = 'Hello, world!'
assert o.attr1 == 'Hello, world!'
o.__lock__()
for name in ('attr1', 'attr2'):
e = raises(AttributeError, setattr, o, name, 'whatever')
assert str(e) == SET_ERROR % ('ReadOnly', name, 'whatever')
assert o.attr1 == 'Hello, world!'
def test_delattr(self):
"""
Test the `ipalib.base.ReadOnly.__delattr__` method.
"""
o = self.cls()
o.attr1 = 'Hello, world!'
o.attr2 = 'How are you?'
assert o.attr1 == 'Hello, world!'
assert o.attr2 == 'How are you?'
del o.attr1
assert not hasattr(o, 'attr1')
o.__lock__()
e = raises(AttributeError, delattr, o, 'attr2')
assert str(e) == DEL_ERROR % ('ReadOnly', 'attr2')
assert o.attr2 == 'How are you?'
def test_lock():
"""
Test the `ipalib.base.lock` function
"""
f = base.lock
# Test with ReadOnly instance:
o = base.ReadOnly()
assert o.__islocked__() is False
assert f(o) is o
assert o.__islocked__() is True
e = raises(AssertionError, f, o)
assert str(e) == 'already locked: %r' % o
# Test with another class implemented locking protocol:
class Lockable(object):
__locked = False
def __lock__(self):
self.__locked = True
def __islocked__(self):
return self.__locked
o = Lockable()
assert o.__islocked__() is False
assert f(o) is o
assert o.__islocked__() is True
e = raises(AssertionError, f, o)
assert str(e) == 'already locked: %r' % o
# Test with a class incorrectly implementing the locking protocol:
class Broken(object):
def __lock__(self):
pass
def __islocked__(self):
return False
o = Broken()
e = raises(AssertionError, f, o)
assert str(e) == 'failed to lock: %r' % o
def test_islocked():
"""
Test the `ipalib.base.islocked` function.
"""
f = base.islocked
# Test with ReadOnly instance:
o = base.ReadOnly()
assert f(o) is False
o.__lock__()
assert f(o) is True
# Test with another class implemented locking protocol:
class Lockable(object):
__locked = False
def __lock__(self):
self.__locked = True
def __islocked__(self):
return self.__locked
o = Lockable()
assert f(o) is False
o.__lock__()
assert f(o) is True
# Test with a class incorrectly implementing the locking protocol:
class Broken(object):
__lock__ = False
def __islocked__(self):
return False
o = Broken()
e = raises(AssertionError, f, o)
assert str(e) == 'no __lock__() method: %r' % o
def test_check_name():
"""
Test the `ipalib.base.check_name` function.
"""
f = base.check_name
okay = [
'user_add',
'stuff2junk',
'sixty9',
]
nope = [
'_user_add',
'__user_add',
'user_add_',
'user_add__',
'_user_add_',
'__user_add__',
'60nine',
]
for name in okay:
assert name is f(name)
e = raises(TypeError, f, unicode(name))
assert str(e) == TYPE_ERROR % ('name', str, unicode(name), unicode)
for name in nope:
e = raises(ValueError, f, name)
assert str(e) == NAME_ERROR % (NAME_REGEX, name)
for name in okay:
e = raises(ValueError, f, name.upper())
assert str(e) == NAME_ERROR % (NAME_REGEX, name.upper())
def membername(i):
return 'member%03d' % i
class DummyMember(object):
def __init__(self, i):
self.i = i
self.name = membername(i)
def gen_members(*indexes):
return tuple(DummyMember(i) for i in indexes)
class test_NameSpace(ClassChecker):
"""
Test the `ipalib.base.NameSpace` class.
"""
_cls = base.NameSpace
def new(self, count, sort=True):
members = tuple(DummyMember(i) for i in xrange(count, 0, -1))
assert len(members) == count
o = self.cls(members, sort=sort)
return (o, members)
def test_init(self):
"""
Test the `ipalib.base.NameSpace.__init__` method.
"""
o = self.cls([])
assert len(o) == 0
assert list(o) == []
assert list(o()) == []
# Test members as attribute and item:
for cnt in (3, 42):
for sort in (True, False):
(o, members) = self.new(cnt, sort=sort)
assert len(members) == cnt
for m in members:
assert getattr(o, m.name) is m
assert o[m.name] is m
# Test that TypeError is raised if sort is not a bool:
e = raises(TypeError, self.cls, [], sort=None)
assert str(e) == TYPE_ERROR % ('sort', bool, None, type(None))
# Test that AttributeError is raised with duplicate member name:
members = gen_members(0, 1, 2, 1, 3)
e = raises(AttributeError, self.cls, members)
assert str(e) == OVERRIDE_ERROR % (
'NameSpace', membername(1), members[1], members[3]
)
def test_len(self):
"""
Test the `ipalib.base.NameSpace.__len__` method.
"""
for count in (5, 18, 127):
(o, members) = self.new(count)
assert len(o) == count
(o, members) = self.new(count, sort=False)
assert len(o) == count
def test_iter(self):
"""
Test the `ipalib.base.NameSpace.__iter__` method.
"""
(o, members) = self.new(25)
assert list(o) == sorted(m.name for m in members)
(o, members) = self.new(25, sort=False)
assert list(o) == list(m.name for m in members)
def test_call(self):
"""
Test the `ipalib.base.NameSpace.__call__` method.
"""
(o, members) = self.new(25)
assert list(o()) == sorted(members, key=lambda m: m.name)
(o, members) = self.new(25, sort=False)
assert tuple(o()) == members
def test_contains(self):
"""
Test the `ipalib.base.NameSpace.__contains__` method.
"""
yes = (99, 3, 777)
no = (9, 333, 77)
for sort in (True, False):
members = gen_members(*yes)
o = self.cls(members, sort=sort)
for i in yes:
assert membername(i) in o
assert membername(i).upper() not in o
for i in no:
assert membername(i) not in o
def test_getitem(self):
"""
Test the `ipalib.base.NameSpace.__getitem__` method.
"""
cnt = 17
for sort in (True, False):
(o, members) = self.new(cnt, sort=sort)
assert len(members) == cnt
if sort is True:
members = tuple(sorted(members, key=lambda m: m.name))
# Test str keys:
for m in members:
assert o[m.name] is m
e = raises(KeyError, o.__getitem__, 'nope')
# Test int indexes:
for i in xrange(cnt):
assert o[i] is members[i]
e = raises(IndexError, o.__getitem__, cnt)
# Test negative int indexes:
for i in xrange(1, cnt + 1):
assert o[-i] is members[-i]
e = raises(IndexError, o.__getitem__, -(cnt + 1))
# Test slicing:
assert o[3:] == members[3:]
assert o[:10] == members[:10]
assert o[3:10] == members[3:10]
assert o[-9:] == members[-9:]
assert o[:-4] == members[:-4]
assert o[-9:-4] == members[-9:-4]
# Test that TypeError is raised with wrong type
e = raises(TypeError, o.__getitem__, 3.0)
assert str(e) == TYPE_ERROR % ('key', (str, int, slice), 3.0, float)
def test_repr(self):
"""
Test the `ipalib.base.NameSpace.__repr__` method.
"""
for cnt in (0, 1, 2):
for sort in (True, False):
(o, members) = self.new(cnt, sort=sort)
if cnt == 1:
assert repr(o) == \
'NameSpace(<%d member>, sort=%r)' % (cnt, sort)
else:
assert repr(o) == \
'NameSpace(<%d members>, sort=%r)' % (cnt, sort)
def test_todict(self):
"""
Test the `ipalib.base.NameSpace.__todict__` method.
"""
for cnt in (3, 101):
for sort in (True, False):
(o, members) = self.new(cnt, sort=sort)
d = o.__todict__()
assert d == dict((m.name, m) for m in members)
# Test that a copy is returned:
assert o.__todict__() is not d