Francesco Romani has uploaded a new change for review.

Change subject: utils: add weakmethod helper
......................................................................

utils: add weakmethod helper

TODO: write proper commit message.

Change-Id: I9f26aa314e26142122e9f594275406cf7fbade98
Bug-Url: https://bugzilla.redhat.com/??????
Signed-off-by: Francesco Romani <from...@redhat.com>
---
M lib/vdsm/utils.py
M tests/utilsTests.py
2 files changed, 72 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/65/51865/1

diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 670c73f..e958a8a 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -1,5 +1,5 @@
 #
-# Copyright 2008-2013 Red Hat, Inc.
+# Copyright 2008-2016 Red Hat, Inc.
 #
 # 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
@@ -49,6 +49,8 @@
 import string
 import threading
 import time
+import weakref
+
 import vdsm.infra.zombiereaper as zombiereaper
 
 
@@ -897,3 +899,14 @@
     original order.
     """
     return OrderedDict.fromkeys(iterable).keys()
+
+
+def weakmethod(meth):
+    func = meth.__func__
+    ref = weakref.ref(meth.__self__)
+
+    def wrapper(*args, **kwargs):
+        # TODO: if ref() is None?
+        return func(ref(), *args, **kwargs)
+
+    return wrapper
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index 94705fd..e2fb30c 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -1,5 +1,5 @@
 #
-# Copyright 2012-2013 Red Hat, Inc.
+# Copyright 2012-2016 Red Hat, Inc.
 #
 # 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
@@ -24,6 +24,7 @@
 import cpopen
 import errno
 import fcntl
+import gc
 import logging
 import operator
 import os
@@ -993,6 +994,62 @@
         self.assertEqual(log.messages, [])
 
 
+class FakeVirDomain(object):
+
+    def public(self, *args, **kw):
+        return 'public', args, kw
+
+    def _private(self, *args, **kw):
+        return '_private', args, kw
+
+    def __del__(self):
+        print('__del__', self.__class__.__name__)
+
+
+@contextlib.contextmanager
+def _debug_gc():
+    flags = gc.get_debug()
+    try:
+        gc.set_debug(gc.DEBUG_LEAK)
+        yield
+    finally:
+        gc.set_debug(flags)
+
+
+def _wrap(obj):
+    for name in dir(obj):
+        if name.startswith('_'):
+            continue
+        attr = getattr(obj, name)
+        if not callable(attr):
+            continue
+        setattr(obj, name, utils.weakmethod(attr))
+        del name, attr
+    return obj
+
+
+class WeakmethodTests(TestCaseBase):
+
+    def test_avoid_reference_cycles(self):
+
+        # test environment is too noisy
+        gc.collect()
+        before = set(gc.garbage)
+
+        with _debug_gc():
+            obj = _wrap(FakeVirDomain())
+
+            self.assertEquals(obj.public(), ("public", (), {}))
+            self.assertEquals(obj._private(), ("_private", (), {}))
+
+            del obj
+
+        gc.collect()
+        after = set(gc.garbage)
+
+        self.assertNotIn(FakeVirDomain, after - before)
+
+
 class NoIntrPollTests(TestCaseBase):
     RETRIES = 3
     SLEEP_INTERVAL = 0.1


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9f26aa314e26142122e9f594275406cf7fbade98
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <from...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to