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
