summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/config.py87
-rw-r--r--tests/test_ipalib/test_config.py122
2 files changed, 207 insertions, 2 deletions
diff --git a/ipalib/config.py b/ipalib/config.py
index b3155490c..4f7a008d3 100644
--- a/ipalib/config.py
+++ b/ipalib/config.py
@@ -28,6 +28,7 @@ methods, such as DNS.
from ConfigParser import SafeConfigParser, ParsingError
import types
import os
+import sys
from errors import check_isinstance, raise_TypeError
@@ -126,6 +127,92 @@ class Environment(object):
return default
+class Env(object):
+ """
+ A mapping object used to store the environment variables.
+ """
+
+ __locked = False
+
+ def __init__(self):
+ object.__setattr__(self, '_Env__d', {})
+
+ def __lock__(self):
+ """
+ Prevent further changes to environment.
+ """
+ if self.__locked is True:
+ raise StandardError(
+ '%s.__lock__() already called' % self.__class__.__name__
+ )
+ object.__setattr__(self, '_Env__locked', True)
+
+ def __getattr__(self, name):
+ """
+ Return the attribute named ``name``.
+ """
+ if name in self.__d:
+ return self[name]
+ raise AttributeError('%s.%s' %
+ (self.__class__.__name__, name)
+ )
+
+ def __setattr__(self, name, value):
+ """
+ Set the attribute named ``name`` to ``value``.
+ """
+ self[name] = value
+
+ def __delattr__(self, name):
+ """
+ Raise AttributeError (deletion is not allowed).
+ """
+ raise AttributeError('cannot del %s.%s' %
+ (self.__class__.__name__, name)
+ )
+
+ def __getitem__(self, key):
+ """
+ Return the value corresponding to ``key``.
+ """
+ if key not in self.__d:
+ raise KeyError(key)
+ value = self.__d[key]
+ if callable(value):
+ return value()
+ return value
+
+ def __setitem__(self, key, value):
+ """
+ Set ``key`` to ``value``.
+ """
+ if self.__locked:
+ raise AttributeError('locked: cannot set %s.%s to %r' %
+ (self.__class__.__name__, key, value)
+ )
+ if key in self.__d or hasattr(self, key):
+ raise AttributeError('cannot overwrite %s.%s with %r' %
+ (self.__class__.__name__, key, value)
+ )
+ self.__d[key] = value
+ if not callable(value):
+ assert type(value) in (str, int, bool)
+ object.__setattr__(self, key, value)
+
+ def __contains__(self, key):
+ """
+ Return True if instance contains ``key``; otherwise return False.
+ """
+ return key in self.__d
+
+ def __iter__(self): # Fix
+ """
+ Iterate through keys in ascending order.
+ """
+ for key in sorted(self.__d):
+ yield key
+
+
def set_default_env(env):
"""
Set default values for ``env``.
diff --git a/tests/test_ipalib/test_config.py b/tests/test_ipalib/test_config.py
index ed982a731..fa497206c 100644
--- a/tests/test_ipalib/test_config.py
+++ b/tests/test_ipalib/test_config.py
@@ -23,8 +23,8 @@ Test the `ipalib.config` module.
import types
-from tests.util import raises, setitem, delitem
-#from tests.util import getitem, setitem, delitem
+from tests.util import raises, setitem, delitem, ClassChecker
+from tests.util import getitem, setitem, delitem
from ipalib import config
@@ -112,6 +112,124 @@ def test_Environment():
assert env.a != 1000
+class test_Env(ClassChecker):
+ """
+ Test the `ipalib.config.Env` class.
+ """
+
+ _cls = config.Env
+
+ def test_init(self):
+ """
+ Test the `ipalib.config.Env.__init__` method.
+ """
+ o = self.cls()
+
+ def test_lock(self):
+ """
+ Test the `ipalib.config.Env.__lock__` method.
+ """
+ o = self.cls()
+ assert o._Env__locked is False
+ o.__lock__()
+ assert o._Env__locked is True
+ e = raises(StandardError, o.__lock__)
+ assert str(e) == 'Env.__lock__() already called'
+
+ def test_getattr(self):
+ """
+ Test the `ipalib.config.Env.__getattr__` method.
+
+ Also tests the `ipalib.config.Env.__getitem__` method.
+ """
+ o = self.cls()
+ value = 'some value'
+ o.key = value
+ assert o.key is value
+ assert o['key'] is value
+ o.call = lambda: 'whatever'
+ assert o.call == 'whatever'
+ assert o['call'] == 'whatever'
+ for name in ('one', 'two'):
+ e = raises(AttributeError, getattr, o, name)
+ assert str(e) == 'Env.%s' % name
+ e = raises(KeyError, getitem, o, name)
+ assert str(e) == repr(name)
+
+ def test_setattr(self):
+ """
+ Test the `ipalib.config.Env.__setattr__` method.
+
+ Also tests the `ipalib.config.Env.__setitem__` method.
+ """
+ items = [
+ ('one', 1),
+ ('two', lambda: 2),
+ ('three', 3),
+ ('four', lambda: 4),
+ ]
+ for setvar in (setattr, setitem):
+ o = self.cls()
+ for (i, (name, value)) in enumerate(items):
+ setvar(o, name, value)
+ assert getattr(o, name) == i + 1
+ assert o[name] == i + 1
+ if callable(value):
+ assert name not in dir(o)
+ else:
+ assert name in dir(o)
+ e = raises(AttributeError, setvar, o, name, 42)
+ assert str(e) == 'cannot overwrite Env.%s with 42' % name
+ o = self.cls()
+ o.__lock__()
+ for (name, value) in items:
+ e = raises(AttributeError, setvar, o, name, value)
+ assert str(e) == \
+ 'locked: cannot set Env.%s to %r' % (name, value)
+
+ def test_delattr(self):
+ """
+ Test the `ipalib.config.Env.__delattr__` method.
+
+ This also tests that ``__delitem__`` is not implemented.
+ """
+ o = self.cls()
+ o.one = 1
+ assert o.one == 1
+ for key in ('one', 'two'):
+ e = raises(AttributeError, delattr, o, key)
+ assert str(e) == 'cannot del Env.%s' % key
+ e = raises(AttributeError, delitem, o, key)
+ assert str(e) == '__delitem__'
+
+ def test_contains(self):
+ """
+ Test the `ipalib.config.Env.__contains__` method.
+ """
+ o = self.cls()
+ items = [
+ ('one', 1),
+ ('two', lambda: 2),
+ ('three', 3),
+ ('four', lambda: 4),
+ ]
+ for (key, value) in items:
+ assert key not in o
+ o[key] = value
+ assert key in o
+
+ def test_iter(self):
+ """
+ Test the `ipalib.config.Env.__iter__` method.
+ """
+ o = self.cls()
+ assert list(o) == []
+ keys = ('one', 'two', 'three', 'four', 'five')
+ for key in keys:
+ o[key] = 'the value'
+ assert list(o) == sorted(keys)
+
+
def test_set_default_env():
"""
Test the `ipalib.config.set_default_env` function.