Nir Soffer has uploaded a new change for review.

Change subject: testlib: Allow recording class methods
......................................................................

testlib: Allow recording class methods

The @recorded decorator could not be applied to class methods, and we
are using lot of boilerplate code to record class methods.

This patch modify the decorator so it can be used to decorate both
instance and class methods.

Change-Id: Idf33cba4ab41dc4cc7cc09d4afa70d33b75cde9f
Signed-off-by: Nir Soffer <[email protected]>
---
M tests/testlib.py
M tests/testlibTests.py
2 files changed, 59 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/60/49960/1

diff --git a/tests/testlib.py b/tests/testlib.py
index 378c1ed..37409a7 100644
--- a/tests/testlib.py
+++ b/tests/testlib.py
@@ -412,13 +412,34 @@
 
 def recorded(meth):
     """
-    Method decorator recording calls to instance's __recording__ list.
+    Method decorator recording calls to receiver __recording__ list.
+
+    Can decorate an instance method or class method. Instance methods are
+    stored in the instance __recording__ list, and class methods in the class
+    __recording__ list.
+
+    You are responsible for clearing the class __recording__ list.
+
+    Note: when decorating a class method, this decorator must be after the
+    @classmethod property:
+
+    class Foo(objet):
+
+        @classmethod
+        @recorded
+        def foo(cls):
+            pass
+
     """
     @wraps(meth)
-    def wrapper(self, *args, **kwargs):
-        recording = self.__dict__.setdefault("__recording__", [])
+    def wrapper(obj, *args, **kwargs):
+        try:
+            recording = getattr(obj, "__recording__")
+        except AttributeError:
+            recording = []
+            setattr(obj, "__recording__", recording)
         recording.append((meth.func_name, args, kwargs))
-        return meth(self, *args, **kwargs)
+        return meth(obj, *args, **kwargs)
     return wrapper
 
 
diff --git a/tests/testlibTests.py b/tests/testlibTests.py
index 0e6f604..9c7ddb4 100644
--- a/tests/testlibTests.py
+++ b/tests/testlibTests.py
@@ -64,6 +64,10 @@
 
 class RecordedTests(VdsmTestCase):
 
+    def setUp(self):
+        if hasattr(Recorded, '__recording__'):
+            del Recorded.__recording__
+
     def test_no_args(self):
         obj = Recorded()
         obj.no_args()
@@ -110,9 +114,39 @@
             ("kwargs", (), {"a": 1}),
         ])
 
+    def test_class_method_via_class(self):
+        Recorded.class_method('a', b=2)
+        self.assertEqual(Recorded.__recording__,
+                         [('class_method', ('a',), {'b': 2})])
+
+    def test_class_method_via_obj(self):
+        obj = Recorded()
+        obj.class_method('a', b=2)
+        self.assertEqual(Recorded.__recording__,
+                         [('class_method', ('a',), {'b': 2})])
+
+    def test_class_method_flow(self):
+        obj = Recorded()
+        obj.class_method('a', b=2)
+        obj.class_method_noargs()
+        self.assertEqual(Recorded.__recording__, [
+            ('class_method', ('a',), {'b': 2}),
+            ('class_method_noargs', (), {}),
+        ])
+
 
 class Recorded(object):
 
+    @classmethod
+    @recorded
+    def class_method(cls, *a, **kw):
+        pass
+
+    @classmethod
+    @recorded
+    def class_method_noargs(cls):
+        pass
+
     @recorded
     def args_and_kwargs(self, a, b, c=3, d=4):
         pass


-- 
To view, visit https://gerrit.ovirt.org/49960
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idf33cba4ab41dc4cc7cc09d4afa70d33b75cde9f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to