Merge branch 'tests-leaks'

* tests-leaks:
  ext/pci: handle 'qubes-close' event
  tests: allow extensions to cleanup objects references
This commit is contained in:
Marek Marczykowski-Górecki 2020-01-16 04:00:59 +01:00
commit e6aa35fcdf
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
4 changed files with 26 additions and 1 deletions

View File

@ -724,6 +724,17 @@ class Qubes(qubes.PropertyHolder):
:param event: Event name (``'pool-delete'``)
:param pool: Pool object
.. event:: qubes-close (subject, event)
Fired when this Qubes() object instance is going to be closed
and destroyed. In practice it is called only during tests, to
cleanup objects from one test, before another.
It is _not_ called when qubesd daemon is stopped.
:param subject: Event emitter
:param event: Event name (``'qubes-close'``)
Methods and attributes:
"""
default_guivm = qubes.VMProperty(
@ -1085,6 +1096,9 @@ class Qubes(qubes.PropertyHolder):
for frame in traceback.extract_stack():
self.log.debug('%s', frame)
# let all the extension cleanup things
self.fire_event('qubes-close')
super().close()
if self._domain_event_callback_id is not None:
@ -1094,6 +1108,9 @@ class Qubes(qubes.PropertyHolder):
# Only our Lord, The God Almighty, knows what references
# are kept in extensions.
# NOTE: this doesn't really delete extension objects - Extension class
# saves reference to instance, and also various registered (class level)
# event handlers do that too
del self._extensions
for vm in self.domains:

View File

@ -313,6 +313,12 @@ class PCIDeviceExtension(qubes.ext.Extension):
else:
raise
@qubes.ext.handler('qubes-close', system=True)
def on_app_close(self, app, event):
# pylint: disable=unused-argument,no-self-use
_cache_get.cache_clear()
@functools.lru_cache(maxsize=None)
def _cache_get(vm, ident):
''' Caching wrapper around `PCIDevice(vm, ident)`. '''

View File

@ -410,7 +410,6 @@ class QubesTestCase(unittest.TestCase):
self.loop = asyncio.get_event_loop()
self.addCleanup(self.cleanup_loop)
self.addCleanup(self.cleanup_traceback)
self.addCleanup(qubes.ext.pci._cache_get.cache_clear)
def cleanup_traceback(self):
'''Remove local variables reference from tracebacks to allow garbage

View File

@ -273,6 +273,9 @@ class QubesVMTestsMixin(object):
def tearDown(self):
try:
# self.app is not a real events emiter, so make the call manually
for handler in qubes.Qubes.__handlers__.get('qubes-close'):
handler(self.app, 'qubes-close')
self.app.domains.close()
except AttributeError:
pass