Change in vdsm[master]: tests: Add monkey patching class decorator
nsoffer at redhat.com
nsoffer at redhat.com
Mon Oct 14 22:16:44 UTC 2013
Nir Soffer has uploaded a new change for review.
Change subject: tests: Add monkey patching class decorator
......................................................................
tests: Add monkey patching class decorator
Using the new MonkeyClass decorator, you can do monkey patching during
all test methods in a test case class, without implementing setUp() or
tearDown().
Change-Id: Ice429b01afaf00730ff59dcdf866ab5eeae6b926
Signed-off-by: Nir Soffer <nsoffer at redhat.com>
---
M tests/monkeypatch.py
M tests/monkeypatchTests.py
2 files changed, 89 insertions(+), 15 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/20175/1
diff --git a/tests/monkeypatch.py b/tests/monkeypatch.py
index f851f82..b51f097 100644
--- a/tests/monkeypatch.py
+++ b/tests/monkeypatch.py
@@ -21,8 +21,9 @@
from contextlib import contextmanager
from functools import wraps
+
#
-# Monkey patch
+# Monkey patch.
#
# Usage:
# ---
@@ -49,8 +50,6 @@
# # using patched functions
# ---
#
-
-
class Patch(object):
def __init__(self, what):
@@ -75,7 +74,7 @@
#
# Usage:
# ---
-# from monkeypatch import MonkeyPatch
+# from monkeypatch import MonkeyPatchScope
#
# def test():
# with MonkeyPatchScope([
@@ -96,7 +95,7 @@
#
-# Monkey patch decoration.
+# Monkey patch function decorator.
#
# Usage:
# ---
@@ -116,3 +115,50 @@
return f(*args, **kw)
return wrapper
return decorator
+
+
+#
+# Monkey patch class decorator.
+#
+# Usage:
+# ---
+# from monkeypatch import MonkeyClass
+#
+# @MonkeyClass(subprocess, 'Popen', lambda x: None)
+# @MonkeyClass(os, 'chown', lambda *x: 0)
+# class TestSomething():
+#
+# def testThis(self):
+# # using patched functions
+#
+# def testThat(self):
+# # using patched functions
+# ---
+#
+def MonkeyClass(module, name, that):
+
+ def setup_decorator(func):
+ @wraps(func)
+ def setup(self, *a, **kw):
+ if not hasattr(self, '__monkeystack__'):
+ self.__monkeystack__ = []
+ patch = Patch([(module, name, that)])
+ self.__monkeystack__.append(patch)
+ patch.apply()
+ return func(self, *a, **kw)
+ return setup
+
+ def teardown_decorator(func):
+ @wraps(func)
+ def teardown(self, *a, **kw):
+ patch = self.__monkeystack__.pop()
+ patch.revert()
+ return func(self, *a, **kw)
+ return teardown
+
+ def wrapper(cls):
+ cls.setUp = setup_decorator(cls.setUp)
+ cls.tearDown = teardown_decorator(cls.tearDown)
+ return cls
+
+ return wrapper
diff --git a/tests/monkeypatchTests.py b/tests/monkeypatchTests.py
index b1b9359..2c52b4f 100644
--- a/tests/monkeypatchTests.py
+++ b/tests/monkeypatchTests.py
@@ -20,7 +20,7 @@
from testrunner import VdsmTestCase
-import monkeypatch
+from monkeypatch import Patch, MonkeyPatch, MonkeyClass
class FakeModule:
@@ -49,7 +49,7 @@
pass
-class TestMonkeyPatchDecorator(VdsmTestCase):
+class TestMonkeyPatch(VdsmTestCase):
module = FakeModule()
@@ -66,18 +66,46 @@
# This method patches module in one way
- @monkeypatch.MonkeyPatch(module, 'a', patched)
+ @MonkeyPatch(module, 'a', patched)
def testPatchOne(self):
self.assertEqual(self.module.a, patched)
self.assertNotEqual(self.module.b, patched)
# This method patches module in another way
- @monkeypatch.MonkeyPatch(module, 'a', patched)
- @monkeypatch.MonkeyPatch(module, 'b', patched)
+ @MonkeyPatch(module, 'a', patched)
+ @MonkeyPatch(module, 'b', patched)
def testPatchBoth(self):
self.assertEqual(self.module.a, patched)
self.assertEqual(self.module.b, patched)
+
+
+module = FakeModule()
+
+
+ at MonkeyClass(module, 'a', patched)
+class TestMonkeyClass(VdsmTestCase):
+
+ def tearDown(self):
+ self.assertTrue(module.isClean())
+
+ def testPatched(self):
+ self.assertEqual(module.a, patched)
+ self.assertNotEqual(module.b, patched)
+ self.assertNotEqual(module.c, patched)
+
+
+ at MonkeyClass(module, 'a', patched)
+ at MonkeyClass(module, 'b', patched)
+class TestMonkeyClassChain(VdsmTestCase):
+
+ def tearDown(self):
+ self.assertTrue(module.isClean())
+
+ def testPatched(self):
+ self.assertEqual(module.a, patched)
+ self.assertEqual(module.b, patched)
+ self.assertNotEqual(module.c, patched)
class TestMonkeyPatchFixture(VdsmTestCase):
@@ -85,7 +113,7 @@
def __init__(self, *a, **kw):
super(VdsmTestCase, self).__init__(*a, **kw)
self.module = FakeModule()
- self.patch = monkeypatch.Patch([
+ self.patch = Patch([
(self.module, 'a', patched),
(self.module, 'b', patched),
])
@@ -106,19 +134,19 @@
self.assertNotEqual(self.module.c, patched)
-class TestMonkeyPatchAssertions(VdsmTestCase):
+class TestMonkeyPatchFixtureAssertions(VdsmTestCase):
def testAlreadyApplied(self):
- patch = monkeypatch.Patch([(FakeModule(), 'a', patched)])
+ patch = Patch([(FakeModule(), 'a', patched)])
patch.apply()
self.assertRaises(AssertionError, patch.apply)
def testNotApplied(self):
- patch = monkeypatch.Patch([(FakeModule(), 'a', patched)])
+ patch = Patch([(FakeModule(), 'a', patched)])
self.assertRaises(AssertionError, patch.revert)
def testAlreadyReverted(self):
- patch = monkeypatch.Patch([(FakeModule(), 'a', patched)])
+ patch = Patch([(FakeModule(), 'a', patched)])
patch.apply()
patch.revert()
self.assertRaises(AssertionError, patch.revert)
--
To view, visit http://gerrit.ovirt.org/20175
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ice429b01afaf00730ff59dcdf866ab5eeae6b926
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer at redhat.com>
More information about the vdsm-patches
mailing list