FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > 64 Studio > 64 Studio Developer

 
 
LinkBack Thread Tools
 
Old 05-14-2010, 08:36 AM
Martin Sivak
 
Default Add Mock classes

---
anaconda | 4 +-
tests/__init__.py | 14 ++-
tests/mock/__init__.py | 45 ++++++++
tests/mock/disk.py | 89 ++++++++++++++++
tests/mock/mock.py | 271 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 415 insertions(+), 8 deletions(-)
create mode 100644 tests/mock/__init__.py
create mode 100644 tests/mock/disk.py
create mode 100644 tests/mock/mock.py

diff --git a/anaconda b/anaconda
index 191dab0..b5532b0 100755
--- a/anaconda
+++ b/anaconda
@@ -151,7 +151,7 @@ def setupPythonUpdates():
target = "/etc/udev/rules.d/" + rule.split('/')[-1]
shutil.copyfile(rule, target)

-def parseOptions():
+def parseOptions(argv = None):
def resolution_cb (option, opt_str, value, parser):
parser.values.runres = value

@@ -229,7 +229,7 @@ def parseOptions():
op.add_option("-t", "--test", dest="unsupportedMode",
action="store_const", const="test")

- return op.parse_args()
+ return op.parse_args(argv)

def setupPythonPath():
haveUpdates = False
diff --git a/tests/__init__.py b/tests/__init__.py
index d5b53a8..784c932 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,15 +1,12 @@
import os

-# this has to be imported before running anything
-import anaconda_log
-import upgrade
-
-
def getAvailableSuites():
- root, tests_dir = os.path.split(os.path.dirname(__file__))
+ root_dir, tests_dir = os.path.split(os.path.dirname(__file__))
modules = []

for root, dirs, files in os.walk(tests_dir):
+ if os.path.exists(os.path.join(root, ".disabled")):
+ continue
for filename in files:
if filename.endswith(".py") and filename != "__init__.py":
basename, extension = os.path.splitext(filename)
@@ -27,3 +24,8 @@ def getAvailableSuites():
available_suites[module] = suite()

return available_suites
+
+if __name__ == '__main__':
+ s = getAvailableSuites()
+ unittest.TextTestRunner(verbosity=2).run(s)
+
diff --git a/tests/mock/__init__.py b/tests/mock/__init__.py
new file mode 100644
index 0000000..416105c
--- /dev/null
+++ b/tests/mock/__init__.py
@@ -0,0 +1,45 @@
+# Mocking library for module and code injection, replay tests and other
+# unit testing purposes
+#
+# Copyright (C) 2010
+# Red Hat, Inc. All rights reserved.
+#
+# 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 2 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/>.
+#
+# Author(s): Martin Sivak <msivak@redhat.com>
+
+
+from disk import *
+from mock import *
+import unittest
+
+class TestCase(unittest.TestCase):
+ def __init__(self, *args, **kwargs):
+ unittest.TestCase.__init__(self, *args, **kwargs)
+ self.injectedModules = {}
+
+ def setupModules(self, a):
+ """Mock specified list of modules and store the list so it can be
+ properly unloaded during tearDown"""
+ import sys
+ for m in a:
+ sys.modules[m] = Mock()
+ self.injectedModules[m] = sys.modules[m]
+
+ def tearDownModules(self):
+ """Unload previously Mocked modules"""
+ import sys
+ for k in self.injectedModules.keys():
+ del sys.modules[k]
+
diff --git a/tests/mock/disk.py b/tests/mock/disk.py
new file mode 100644
index 0000000..b87a3a2
--- /dev/null
+++ b/tests/mock/disk.py
@@ -0,0 +1,89 @@
+# Copyright (C) 2010
+# Red Hat, Inc. All rights reserved.
+#
+# 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 2 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/>.
+#
+# Author(s): Martin Sivak <msivak@redhat.com>
+
+from StringIO import StringIO
+
+class DiskIO(object):
+ """Simple object to simplify mocking of file operations in Mock
+ based testing"""
+
+ class TestFile(StringIO):
+ def __init__(self, store, path, content = ""):
+ StringIO.__init__(self, content)
+ self._store = store
+ self._path = path
+ self._ro = False
+
+ def flush(self):
+ self._store[self._path] = self.getvalue()
+
+ def close(self):
+ self.flush()
+ return StringIO.close(self)
+
+ class Dir(object):
+ pass
+
+ class Link(object):
+ pass
+
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ self.fs = {
+ "/proc": self.Dir,
+ "/proc/cmdline": "linux",
+ }
+ self._pwd = "/"
+
+ #Emulate file objects
+ def open(self, filename, mode = "r"):
+ path = os.path.join(self._pwd, filename)
+ content = self.fs.get(path, None)
+ if content == self.Dir:
+ raise IOError("[Errno 21] Is a directory: '%s'" % (path))
+ elif not content and mode.startswith("w"):
+ self.fs[path] = ""
+ f = self.IO(self.fs, path, self.fs[path])
+ elif not content:
+ raise IOError("[Errno 2] No such file or directory: '%s'" % (path,))
+ elif mode.endswith("+") or mode.endswith("a"):
+ f = self.IO(self.fs, path, content)
+ f.seek(0, os.SEEK_END)
+ else:
+ f = self.IO(self.fs, path, content)
+
+ return f
+
+ #Emulate os.path calls
+ def os_path_exists(self, path):
+ path = os.path.join(self._pwd, path)
+ return self.fs.has_key(path)
+
+ #Emulate os calls
+ def os_remove(self, path):
+ path = os.path.join(self._pwd, path)
+ try:
+ del self.fs[path]
+ except KeyError:
+ raise OSError("[Errno 2] No such file or directory: '%s'" % (path,))
+
+ def os_access(self, path, mode):
+ return self.path_exists(path)
+
diff --git a/tests/mock/mock.py b/tests/mock/mock.py
new file mode 100644
index 0000000..03871d6
--- /dev/null
+++ b/tests/mock/mock.py
@@ -0,0 +1,271 @@
+# mock.py
+# Test tools for mocking and patching.
+# Copyright (C) 2007-2009 Michael Foord
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+
+# mock 0.6.0
+# http://www.voidspace.org.uk/python/mock/
+
+# Released subject to the BSD License
+# Please see http://www.voidspace.org.uk/python/license.shtml
+
+# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
+# Comments, suggestions and bug reports welcome.
+
+
+__all__ = (
+ 'Mock',
+ 'patch',
+ 'patch_object',
+ 'sentinel',
+ 'DEFAULT'
+)
+
+__version__ = '0.6.0'
+
+class SentinelObject(object):
+ def __init__(self, name):
+ self.name = name
+
+ def __repr__(self):
+ return '<SentinelObject "%s">' % self.name
+
+
+class Sentinel(object):
+ def __init__(self):
+ self._sentinels = {}
+
+ def __getattr__(self, name):
+ return self._sentinels.setdefault(name, SentinelObject(name))
+
+
+sentinel = Sentinel()
+
+DEFAULT = sentinel.DEFAULT
+
+class OldStyleClass:
+ pass
+ClassType = type(OldStyleClass)
+
+def _is_magic(name):
+ return '__%s__' % name[2:-2] == name
+
+def _copy(value):
+ if type(value) in (dict, list, tuple, set):
+ return type(value)(value)
+ return value
+
+
+class Mock(object):
+
+ def __init__(self, spec=None, side_effect=None, return_value=DEFAULT,
+ name=None, parent=None, wraps=None):
+ self._parent = parent
+ self._name = name
+ if spec is not None and not isinstance(spec, list):
+ spec = [member for member in dir(spec) if not _is_magic(member)]
+
+ self._methods = spec
+ self._children = {}
+ self._return_value = return_value
+ self.side_effect = side_effect
+ self._wraps = wraps
+
+ self.reset_mock()
+
+
+ def reset_mock(self):
+ self.called = False
+ self.call_args = None
+ self.call_count = 0
+ self.call_args_list = []
+ self.method_calls = []
+ for child in self._children.itervalues():
+ child.reset_mock()
+ if isinstance(self._return_value, Mock):
+ self._return_value.reset_mock()
+
+
+ def __get_return_value(self):
+ if self._return_value is DEFAULT:
+ self._return_value = Mock()
+ return self._return_value
+
+ def __set_return_value(self, value):
+ self._return_value = value
+
+ return_value = property(__get_return_value, __set_return_value)
+
+
+ def __call__(self, *args, **kwargs):
+ self.called = True
+ self.call_count += 1
+ self.call_args = (args, kwargs)
+ self.call_args_list.append((args, kwargs))
+
+ parent = self._parent
+ name = self._name
+ while parent is not None:
+ parent.method_calls.append((name, args, kwargs))
+ if parent._parent is None:
+ break
+ name = parent._name + '.' + name
+ parent = parent._parent
+
+ ret_val = DEFAULT
+ if self.side_effect is not None:
+ if (isinstance(self.side_effect, Exception) or
+ isinstance(self.side_effect, (type, ClassType)) and
+ issubclass(self.side_effect, Exception)):
+ raise self.side_effect
+
+ ret_val = self.side_effect(*args, **kwargs)
+ if ret_val is DEFAULT:
+ ret_val = self.return_value
+
+ if self._wraps is not None and self._return_value is DEFAULT:
+ return self._wraps(*args, **kwargs)
+ if ret_val is DEFAULT:
+ ret_val = self.return_value
+ return ret_val
+
+
+ def __getattr__(self, name):
+ if self._methods is not None:
+ if name not in self._methods:
+ raise AttributeError("Mock object has no attribute '%s'" % name)
+ elif _is_magic(name):
+ raise AttributeError(name)
+
+ if name not in self._children:
+ wraps = None
+ if self._wraps is not None:
+ wraps = getattr(self._wraps, name)
+ self._children[name] = Mock(parent=self, name=name, wraps=wraps)
+
+ return self._children[name]
+
+
+ def assert_called_with(self, *args, **kwargs):
+ assert self.call_args == (args, kwargs), 'Expected: %s
Called with: %s' % ((args, kwargs), self.call_args)
+
+
+def _dot_lookup(thing, comp, import_path):
+ try:
+ return getattr(thing, comp)
+ except AttributeError:
+ __import__(import_path)
+ return getattr(thing, comp)
+
+
+def _importer(target):
+ components = target.split('.')
+ import_path = components.pop(0)
+ thing = __import__(import_path)
+
+ for comp in components:
+ import_path += ".%s" % comp
+ thing = _dot_lookup(thing, comp, import_path)
+ return thing
+
+
+class _patch(object):
+ def __init__(self, target, attribute, new, spec, create):
+ self.target = target
+ self.attribute = attribute
+ self.new = new
+ self.spec = spec
+ self.create = create
+ self.has_local = False
+
+
+ def __call__(self, func):
+ if hasattr(func, 'patchings'):
+ func.patchings.append(self)
+ return func
+
+ def patched(*args, **keywargs):
+ # don't use a with here (backwards compatability with 2.5)
+ extra_args = []
+ for patching in patched.patchings:
+ arg = patching.__enter__()
+ if patching.new is DEFAULT:
+ extra_args.append(arg)
+ args += tuple(extra_args)
+ try:
+ return func(*args, **keywargs)
+ finally:
+ for patching in getattr(patched, 'patchings', []):
+ patching.__exit__()
+
+ patched.patchings = [self]
+ patched.__name__ = func.__name__
+ patched.compat_co_firstlineno = getattr(func, "compat_co_firstlineno",
+ func.func_code.co_firstlineno)
+ return patched
+
+
+ def get_original(self):
+ target = self.target
+ name = self.attribute
+ create = self.create
+
+ original = DEFAULT
+ if _has_local_attr(target, name):
+ try:
+ original = target.__dict__[name]
+ except AttributeError:
+ # for instances of classes with slots, they have no __dict__
+ original = getattr(target, name)
+ elif not create and not hasattr(target, name):
+ raise AttributeError("%s does not have the attribute %r" % (target, name))
+ return original
+
+
+ def __enter__(self):
+ new, spec, = self.new, self.spec
+ original = self.get_original()
+ if new is DEFAULT:
+ # XXXX what if original is DEFAULT - shouldn't use it as a spec
+ inherit = False
+ if spec == True:
+ # set spec to the object we are replacing
+ spec = original
+ if isinstance(spec, (type, ClassType)):
+ inherit = True
+ new = Mock(spec=spec)
+ if inherit:
+ new.return_value = Mock(spec=spec)
+ self.temp_original = original
+ setattr(self.target, self.attribute, new)
+ return new
+
+
+ def __exit__(self, *_):
+ if self.temp_original is not DEFAULT:
+ setattr(self.target, self.attribute, self.temp_original)
+ else:
+ delattr(self.target, self.attribute)
+ del self.temp_original
+
+
+def patch_object(target, attribute, new=DEFAULT, spec=None, create=False):
+ return _patch(target, attribute, new, spec, create)
+
+
+def patch(target, new=DEFAULT, spec=None, create=False):
+ try:
+ target, attribute = target.rsplit('.', 1)
+ except (TypeError, ValueError):
+ raise TypeError("Need a valid target to patch. You supplied: %r" % (target,))
+ target = _importer(target)
+ return _patch(target, attribute, new, spec, create)
+
+
+
+def _has_local_attr(obj, name):
+ try:
+ return name in vars(obj)
+ except TypeError:
+ # objects without a __dict__
+ return hasattr(obj, name)
--
1.6.6.1

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 05-14-2010, 08:46 AM
Ales Kozumplik
 
Default Add Mock classes

On 05/14/2010 10:36 AM, Martin Sivak wrote:

---
anaconda | 4 +-
tests/__init__.py | 14 ++-
tests/mock/__init__.py | 45 ++++++++
tests/mock/disk.py | 89 ++++++++++++++++
tests/mock/mock.py | 271 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 415 insertions(+), 8 deletions(-)
create mode 100644 tests/mock/__init__.py
create mode 100644 tests/mock/disk.py
create mode 100644 tests/mock/mock.py


Ack to both.

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 

Thread Tools




All times are GMT. The time now is 12:55 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org