tests: make PEP8 happier
This commit is contained in:
		
							parent
							
								
									40156c3e78
								
							
						
					
					
						commit
						d8f80c9687
					
				| @ -71,13 +71,11 @@ TEMPLATE = 'fedora-23' | |||||||
| VMPREFIX = 'test-inst-' | VMPREFIX = 'test-inst-' | ||||||
| CLSVMPREFIX = 'test-cls-' | CLSVMPREFIX = 'test-cls-' | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| if 'DEFAULT_LVM_POOL' in os.environ.keys(): | if 'DEFAULT_LVM_POOL' in os.environ.keys(): | ||||||
|     DEFAULT_LVM_POOL = os.environ['DEFAULT_LVM_POOL'] |     DEFAULT_LVM_POOL = os.environ['DEFAULT_LVM_POOL'] | ||||||
| else: | else: | ||||||
|     DEFAULT_LVM_POOL = 'qubes_dom0/pool00' |     DEFAULT_LVM_POOL = 'qubes_dom0/pool00' | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| POOL_CONF = {'name': 'test-lvm', | POOL_CONF = {'name': 'test-lvm', | ||||||
|              'driver': 'lvm_thin', |              'driver': 'lvm_thin', | ||||||
|              'volume_group': DEFAULT_LVM_POOL.split('/')[0], |              'volume_group': DEFAULT_LVM_POOL.split('/')[0], | ||||||
| @ -92,6 +90,7 @@ in_git = False | |||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     import libvirt |     import libvirt | ||||||
|  | 
 | ||||||
|     libvirt.openReadOnly(qubes.config.defaults['libvirt_uri']).close() |     libvirt.openReadOnly(qubes.config.defaults['libvirt_uri']).close() | ||||||
|     in_dom0 = True |     in_dom0 = True | ||||||
| except libvirt.libvirtError: | except libvirt.libvirtError: | ||||||
| @ -116,37 +115,40 @@ except OSError: | |||||||
| 
 | 
 | ||||||
| ha_syslog = None | ha_syslog = None | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def skipUnlessDom0(test_item): | def skipUnlessDom0(test_item): | ||||||
|     '''Decorator that skips test outside dom0. |     """Decorator that skips test outside dom0. | ||||||
| 
 | 
 | ||||||
|     Some tests (especially integration tests) have to be run in more or less |     Some tests (especially integration tests) have to be run in more or less | ||||||
|     working dom0. This is checked by connecting to libvirt. |     working dom0. This is checked by connecting to libvirt. | ||||||
|     ''' |     """ | ||||||
| 
 | 
 | ||||||
|     return unittest.skipUnless(in_dom0, 'outside dom0')(test_item) |     return unittest.skipUnless(in_dom0, 'outside dom0')(test_item) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def skipUnlessGit(test_item): | def skipUnlessGit(test_item): | ||||||
|     '''Decorator that skips test outside git repo. |     """Decorator that skips test outside git repo. | ||||||
| 
 | 
 | ||||||
|     There are very few tests that an be run only in git. One example is |     There are very few tests that an be run only in git. One example is | ||||||
|     correctness of example code that won't get included in RPM. |     correctness of example code that won't get included in RPM. | ||||||
|     ''' |     """ | ||||||
| 
 | 
 | ||||||
|     return unittest.skipUnless(in_git, 'outside git tree')(test_item) |     return unittest.skipUnless(in_git, 'outside git tree')(test_item) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def skipUnlessEnv(varname): | def skipUnlessEnv(varname): | ||||||
|     '''Decorator generator for skipping tests without environment variable set. |     """Decorator generator for skipping tests without environment variable set. | ||||||
| 
 | 
 | ||||||
|     Some tests require working X11 display, like those using GTK library, which |     Some tests require working X11 display, like those using GTK library, which | ||||||
|     segfaults without connection to X. |     segfaults without connection to X. | ||||||
|     Other require their own, custom variables. |     Other require their own, custom variables. | ||||||
|     ''' |     """ | ||||||
| 
 | 
 | ||||||
|     return unittest.skipUnless(os.getenv(varname), 'no {} set'.format(varname)) |     return unittest.skipUnless(os.getenv(varname), 'no {} set'.format(varname)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestEmitter(qubes.events.Emitter): | class TestEmitter(qubes.events.Emitter): | ||||||
|     '''Dummy event emitter which records events fired on it. |     """Dummy event emitter which records events fired on it. | ||||||
| 
 | 
 | ||||||
|     Events are counted in :py:attr:`fired_events` attribute, which is |     Events are counted in :py:attr:`fired_events` attribute, which is | ||||||
|     :py:class:`collections.Counter` instance. For each event, ``(event, args, |     :py:class:`collections.Counter` instance. For each event, ``(event, args, | ||||||
| @ -160,7 +162,7 @@ class TestEmitter(qubes.events.Emitter): | |||||||
|     >>> emitter.fire_event('event', spam='eggs', foo='bar') |     >>> emitter.fire_event('event', spam='eggs', foo='bar') | ||||||
|     >>> emitter.fired_events |     >>> emitter.fired_events | ||||||
|     Counter({('event', (1, 2, 3), (('foo', 'bar'), ('spam', 'eggs'))): 1}) |     Counter({('event', (1, 2, 3), (('foo', 'bar'), ('spam', 'eggs'))): 1}) | ||||||
|     ''' |     """ | ||||||
| 
 | 
 | ||||||
|     def __init__(self, *args, **kwargs): |     def __init__(self, *args, **kwargs): | ||||||
|         super(TestEmitter, self).__init__(*args, **kwargs) |         super(TestEmitter, self).__init__(*args, **kwargs) | ||||||
| @ -200,6 +202,7 @@ def expectedFailureIfTemplate(templates): | |||||||
|     handle both 'whonix-ws' and 'whonix-gw'. |     handle both 'whonix-ws' and 'whonix-gw'. | ||||||
|     templates can be either a single string, or an iterable |     templates can be either a single string, or an iterable | ||||||
|     """ |     """ | ||||||
|  | 
 | ||||||
|     def decorator(func): |     def decorator(func): | ||||||
|         @functools.wraps(func) |         @functools.wraps(func) | ||||||
|         def wrapper(self, *args, **kwargs): |         def wrapper(self, *args, **kwargs): | ||||||
| @ -217,7 +220,9 @@ def expectedFailureIfTemplate(templates): | |||||||
|             else: |             else: | ||||||
|                 # Call directly: |                 # Call directly: | ||||||
|                 func(self, *args, **kwargs) |                 func(self, *args, **kwargs) | ||||||
|  | 
 | ||||||
|         return wrapper |         return wrapper | ||||||
|  | 
 | ||||||
|     return decorator |     return decorator | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -241,10 +246,12 @@ def wait_on_fail(func): | |||||||
|             sys.stdout.flush() |             sys.stdout.flush() | ||||||
|             reader = asyncio.StreamReader(loop=self.loop) |             reader = asyncio.StreamReader(loop=self.loop) | ||||||
|             transport, protocol = self.loop.run_until_complete( |             transport, protocol = self.loop.run_until_complete( | ||||||
|                 self.loop.connect_read_pipe(lambda: asyncio.StreamReaderProtocol(reader), |                 self.loop.connect_read_pipe( | ||||||
|  |                     lambda: asyncio.StreamReaderProtocol(reader), | ||||||
|                     sys.stdin)) |                     sys.stdin)) | ||||||
|             self.loop.run_until_complete(reader.readline()) |             self.loop.run_until_complete(reader.readline()) | ||||||
|             raise |             raise | ||||||
|  | 
 | ||||||
|     return wrapper |     return wrapper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -263,11 +270,9 @@ class _AssertNotRaisesContext(object): | |||||||
| 
 | 
 | ||||||
|         self.failureException = test_case.failureException |         self.failureException = test_case.failureException | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     def __enter__(self): |     def __enter__(self): | ||||||
|         return self |         return self | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     def __exit__(self, exc_type, exc_value, tb): |     def __exit__(self, exc_type, exc_value, tb): | ||||||
|         if exc_type is None: |         if exc_type is None: | ||||||
|             return True |             return True | ||||||
| @ -282,8 +287,9 @@ class _AssertNotRaisesContext(object): | |||||||
| 
 | 
 | ||||||
|         self.exception = exc_value  # store for later retrieval |         self.exception = exc_value  # store for later retrieval | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| class _QrexecPolicyContext(object): | class _QrexecPolicyContext(object): | ||||||
|     '''Context manager for SystemTestCase.qrexec_policy''' |     """Context manager for SystemTestCase.qrexec_policy""" | ||||||
| 
 | 
 | ||||||
|     def __init__(self, service, source, destination, allow=True, action=None): |     def __init__(self, service, source, destination, allow=True, action=None): | ||||||
|         try: |         try: | ||||||
| @ -343,8 +349,9 @@ class _QrexecPolicyContext(object): | |||||||
|             self.close() |             self.close() | ||||||
|             self._filename.unlink() |             self._filename.unlink() | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| class substitute_entry_points(object): | class substitute_entry_points(object): | ||||||
|     '''Monkey-patch pkg_resources to substitute one group in iter_entry_points |     """Monkey-patch pkg_resources to substitute one group in iter_entry_points | ||||||
| 
 | 
 | ||||||
|     This is for testing plugins, like device classes. |     This is for testing plugins, like device classes. | ||||||
| 
 | 
 | ||||||
| @ -356,7 +363,7 @@ class substitute_entry_points(object): | |||||||
| 
 | 
 | ||||||
|     This context manager is stackable. To substitute more than one entry point |     This context manager is stackable. To substitute more than one entry point | ||||||
|     group, just nest two contexts. |     group, just nest two contexts. | ||||||
|     ''' # pylint: disable=invalid-name |     """  # pylint: disable=invalid-name | ||||||
| 
 | 
 | ||||||
|     def __init__(self, group, tempgroup): |     def __init__(self, group, tempgroup): | ||||||
|         self.group = group |         self.group = group | ||||||
| @ -379,8 +386,8 @@ class substitute_entry_points(object): | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class QubesTestCase(unittest.TestCase): | class QubesTestCase(unittest.TestCase): | ||||||
|     '''Base class for Qubes unit tests. |     """Base class for Qubes unit tests. | ||||||
|     ''' |     """ | ||||||
| 
 | 
 | ||||||
|     def __init__(self, *args, **kwargs): |     def __init__(self, *args, **kwargs): | ||||||
|         super(QubesTestCase, self).__init__(*args, **kwargs) |         super(QubesTestCase, self).__init__(*args, **kwargs) | ||||||
| @ -405,7 +412,6 @@ class QubesTestCase(unittest.TestCase): | |||||||
|             self.__class__.__name__, |             self.__class__.__name__, | ||||||
|             self._testMethodName) |             self._testMethodName) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     def setUp(self): |     def setUp(self): | ||||||
|         super().setUp() |         super().setUp() | ||||||
|         self.addCleanup(self.cleanup_gc) |         self.addCleanup(self.cleanup_gc) | ||||||
| @ -415,9 +421,9 @@ class QubesTestCase(unittest.TestCase): | |||||||
|         self.addCleanup(self.cleanup_traceback) |         self.addCleanup(self.cleanup_traceback) | ||||||
| 
 | 
 | ||||||
|     def cleanup_traceback(self): |     def cleanup_traceback(self): | ||||||
|         '''Remove local variables reference from tracebacks to allow garbage |         """Remove local variables reference from tracebacks to allow garbage | ||||||
|         collector to clean all Qubes*() objects, otherwise file descriptors |         collector to clean all Qubes*() objects, otherwise file descriptors | ||||||
|         held by them will leak''' |         held by them will leak""" | ||||||
|         exc_infos = [e for test_case, e in self._outcome.errors |         exc_infos = [e for test_case, e in self._outcome.errors | ||||||
|                      if test_case is self] |                      if test_case is self] | ||||||
|         if self._outcome.expectedFailure: |         if self._outcome.expectedFailure: | ||||||
| @ -444,7 +450,8 @@ class QubesTestCase(unittest.TestCase): | |||||||
|                 import objgraph |                 import objgraph | ||||||
|                 objgraph.show_backrefs(leaked, |                 objgraph.show_backrefs(leaked, | ||||||
|                                        max_depth=15, extra_info=extra_info, |                                        max_depth=15, extra_info=extra_info, | ||||||
|                     filename='/tmp/objgraph-{}.png'.format(self.id())) |                                        filename='/tmp/objgraph-{}.png'.format( | ||||||
|  |                                            self.id())) | ||||||
|             except ImportError: |             except ImportError: | ||||||
|                 pass |                 pass | ||||||
| 
 | 
 | ||||||
| @ -453,7 +460,7 @@ class QubesTestCase(unittest.TestCase): | |||||||
|         assert not leaked |         assert not leaked | ||||||
| 
 | 
 | ||||||
|     def cleanup_loop(self): |     def cleanup_loop(self): | ||||||
|         '''Check if the loop is empty''' |         """Check if the loop is empty""" | ||||||
|         # XXX BEWARE this is touching undocumented, implementation-specific |         # XXX BEWARE this is touching undocumented, implementation-specific | ||||||
|         # attributes of the loop. This is most certainly unsupported and likely |         # attributes of the loop. This is most certainly unsupported and likely | ||||||
|         # will break when messing with: Python version, kernel family, loop |         # will break when messing with: Python version, kernel family, loop | ||||||
| @ -523,15 +530,14 @@ class QubesTestCase(unittest.TestCase): | |||||||
|         with context: |         with context: | ||||||
|             callableObj(*args, **kwargs) |             callableObj(*args, **kwargs) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     def assertXMLEqual(self, xml1, xml2, msg=''): |     def assertXMLEqual(self, xml1, xml2, msg=''): | ||||||
|         '''Check for equality of two XML objects. |         """Check for equality of two XML objects. | ||||||
| 
 | 
 | ||||||
|         :param xml1: first element |         :param xml1: first element | ||||||
|         :param xml2: second element |         :param xml2: second element | ||||||
|         :type xml1: :py:class:`lxml.etree._Element` |         :type xml1: :py:class:`lxml.etree._Element` | ||||||
|         :type xml2: :py:class:`lxml.etree._Element` |         :type xml2: :py:class:`lxml.etree._Element` | ||||||
|         ''' |         """ | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(xml1.tag, xml2.tag) |         self.assertEqual(xml1.tag, xml2.tag) | ||||||
|         msg += '/' + str(xml1.tag) |         msg += '/' + str(xml1.tag) | ||||||
| @ -559,7 +565,7 @@ class QubesTestCase(unittest.TestCase): | |||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|     def assertEventFired(self, subject, event, kwargs=None): |     def assertEventFired(self, subject, event, kwargs=None): | ||||||
|         '''Check whether event was fired on given emitter and fail if it did |         """Check whether event was fired on given emitter and fail if it did | ||||||
|         not. |         not. | ||||||
| 
 | 
 | ||||||
|         :param subject: emitter which is being checked |         :param subject: emitter which is being checked | ||||||
| @ -567,7 +573,7 @@ class QubesTestCase(unittest.TestCase): | |||||||
|         :param str event: event identifier |         :param str event: event identifier | ||||||
|         :param dict kwargs: when given, all items must appear in kwargs passed \ |         :param dict kwargs: when given, all items must appear in kwargs passed \ | ||||||
|             to an event |             to an event | ||||||
|         ''' |         """ | ||||||
| 
 | 
 | ||||||
|         will_not_match = object() |         will_not_match = object() | ||||||
|         for ev, ev_kwargs in subject.fired_events: |         for ev, ev_kwargs in subject.fired_events: | ||||||
| @ -584,16 +590,15 @@ class QubesTestCase(unittest.TestCase): | |||||||
|         self.fail('event {!r} {}did not fire on {!r}'.format( |         self.fail('event {!r} {}did not fire on {!r}'.format( | ||||||
|             event, ('' if kwargs is None else '{!r} '.format(kwargs)), subject)) |             event, ('' if kwargs is None else '{!r} '.format(kwargs)), subject)) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     def assertEventNotFired(self, subject, event, kwargs=None): |     def assertEventNotFired(self, subject, event, kwargs=None): | ||||||
|         '''Check whether event was fired on given emitter. Fail if it did. |         """Check whether event was fired on given emitter. Fail if it did. | ||||||
| 
 | 
 | ||||||
|         :param subject: emitter which is being checked |         :param subject: emitter which is being checked | ||||||
|         :type emitter: :py:class:`TestEmitter` |         :type emitter: :py:class:`TestEmitter` | ||||||
|         :param str event: event identifier |         :param str event: event identifier | ||||||
|         :param list kwargs: when given, all items must appear in kwargs passed \ |         :param list kwargs: when given, all items must appear in kwargs passed \ | ||||||
|             to an event |             to an event | ||||||
|         ''' |         """ | ||||||
| 
 | 
 | ||||||
|         will_not_match = object() |         will_not_match = object() | ||||||
|         for ev, ev_kwargs in subject.fired_events: |         for ev, ev_kwargs in subject.fired_events: | ||||||
| @ -612,9 +617,8 @@ class QubesTestCase(unittest.TestCase): | |||||||
| 
 | 
 | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     def assertXMLIsValid(self, xml, file=None, schema=None): |     def assertXMLIsValid(self, xml, file=None, schema=None): | ||||||
|         '''Check whether given XML fulfills Relax NG schema. |         """Check whether given XML fulfills Relax NG schema. | ||||||
| 
 | 
 | ||||||
|         Schema can be given in a couple of ways: |         Schema can be given in a couple of ways: | ||||||
| 
 | 
 | ||||||
| @ -627,7 +631,7 @@ class QubesTestCase(unittest.TestCase): | |||||||
|         :param lxml.etree._Element xml: XML element instance to check |         :param lxml.etree._Element xml: XML element instance to check | ||||||
|         :param str file: filename of Relax NG schema |         :param str file: filename of Relax NG schema | ||||||
|         :param str schema: optional explicit schema string |         :param str schema: optional explicit schema string | ||||||
|         ''' # pylint: disable=redefined-builtin |         """  # pylint: disable=redefined-builtin | ||||||
| 
 | 
 | ||||||
|         if schema is not None and file is None: |         if schema is not None and file is None: | ||||||
|             relaxng = schema |             relaxng = schema | ||||||
| @ -693,6 +697,7 @@ class SystemTestCase(QubesTestCase): | |||||||
|     Such (group of) test need to take care about |     Such (group of) test need to take care about | ||||||
|     :py:meth:`TestCase.tearDownClass` implementation itself. |     :py:meth:`TestCase.tearDownClass` implementation itself. | ||||||
|     """ |     """ | ||||||
|  | 
 | ||||||
|     # noinspection PyAttributeOutsideInit |     # noinspection PyAttributeOutsideInit | ||||||
|     def setUp(self): |     def setUp(self): | ||||||
|         if not in_dom0: |         if not in_dom0: | ||||||
| @ -805,11 +810,10 @@ class SystemTestCase(QubesTestCase): | |||||||
| 
 | 
 | ||||||
|         self.app.default_netvm = str(default_netvm) |         self.app.default_netvm = str(default_netvm) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     def _find_pool(self, volume_group, thin_pool): |     def _find_pool(self, volume_group, thin_pool): | ||||||
|         ''' Returns the pool matching the specified ``volume_group`` & |         """ Returns the pool matching the specified ``volume_group`` & | ||||||
|             ``thin_pool``, or None. |             ``thin_pool``, or None. | ||||||
|         ''' |         """ | ||||||
|         pools = [p for p in self.app.pools |         pools = [p for p in self.app.pools | ||||||
|                  if issubclass(p.__class__, qubes.storage.lvm.ThinPool)] |                  if issubclass(p.__class__, qubes.storage.lvm.ThinPool)] | ||||||
|         for pool in pools: |         for pool in pools: | ||||||
| @ -867,7 +871,6 @@ class SystemTestCase(QubesTestCase): | |||||||
| 
 | 
 | ||||||
|         self._remove_vm_disk(vmname) |         self._remove_vm_disk(vmname) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def _remove_vm_libvirt(dom): |     def _remove_vm_libvirt(dom): | ||||||
|         try: |         try: | ||||||
| @ -876,7 +879,6 @@ class SystemTestCase(QubesTestCase): | |||||||
|             pass |             pass | ||||||
|         dom.undefine() |         dom.undefine() | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def _remove_vm_disk(vmname): |     def _remove_vm_disk(vmname): | ||||||
|         for dirspec in ( |         for dirspec in ( | ||||||
| @ -892,11 +894,11 @@ class SystemTestCase(QubesTestCase): | |||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def _remove_vm_disk_lvm(prefix=VMPREFIX): |     def _remove_vm_disk_lvm(prefix=VMPREFIX): | ||||||
|         ''' Remove LVM volumes with given prefix |         """ Remove LVM volumes with given prefix | ||||||
| 
 | 
 | ||||||
|         This is "a bit" drastic, as it removes volumes regardless of volume |         This is "a bit" drastic, as it removes volumes regardless of volume | ||||||
|         group, thin pool etc. But we assume no important data on test system. |         group, thin pool etc. But we assume no important data on test system. | ||||||
|         ''' |         """ | ||||||
|         try: |         try: | ||||||
|             volumes = subprocess.check_output( |             volumes = subprocess.check_output( | ||||||
|                 ['lvs', '--noheadings', '-o', 'vg_name,name', |                 ['lvs', '--noheadings', '-o', 'vg_name,name', | ||||||
| @ -974,10 +976,10 @@ class SystemTestCase(QubesTestCase): | |||||||
|             vm.startup_lock.release() |             vm.startup_lock.release() | ||||||
| 
 | 
 | ||||||
|     def remove_test_vms(self, xmlpath=XMLPATH, prefix=VMPREFIX): |     def remove_test_vms(self, xmlpath=XMLPATH, prefix=VMPREFIX): | ||||||
|         '''Aggressively remove any domain that has name in testing namespace. |         """Aggressively remove any domain that has name in testing namespace. | ||||||
| 
 | 
 | ||||||
|         :param prefix: name prefix of VMs to remove, can be a list of prefixes |         :param prefix: name prefix of VMs to remove, can be a list of prefixes | ||||||
|         ''' |         """ | ||||||
| 
 | 
 | ||||||
|         if isinstance(prefix, str): |         if isinstance(prefix, str): | ||||||
|             prefixes = [prefix] |             prefixes = [prefix] | ||||||
| @ -996,8 +998,10 @@ class SystemTestCase(QubesTestCase): | |||||||
|                 except AttributeError: |                 except AttributeError: | ||||||
|                     host_app = qubes.Qubes() |                     host_app = qubes.Qubes() | ||||||
|                 self.remove_vms([vm for vm in app.domains |                 self.remove_vms([vm for vm in app.domains | ||||||
|                     if any(vm.name.startswith(prefix) for prefix in prefixes) or |                                  if any( | ||||||
|                        (isinstance(vm, qubes.vm.dispvm.DispVM) and vm.name |                         vm.name.startswith(prefix) for prefix in prefixes) or | ||||||
|  |                                  (isinstance(vm, | ||||||
|  |                                              qubes.vm.dispvm.DispVM) and vm.name | ||||||
|                                   not in host_app.domains)]) |                                   not in host_app.domains)]) | ||||||
|                 if not hasattr(self, 'host_app'): |                 if not hasattr(self, 'host_app'): | ||||||
|                     host_app.close() |                     host_app.close() | ||||||
| @ -1057,7 +1061,8 @@ class SystemTestCase(QubesTestCase): | |||||||
|         """ |         """ | ||||||
|         wait_count = 0 |         wait_count = 0 | ||||||
|         while subprocess.call(['xdotool', 'getwindowname', str(winid)], |         while subprocess.call(['xdotool', 'getwindowname', str(winid)], | ||||||
|                 stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) == 0: |                               stdout=subprocess.DEVNULL, | ||||||
|  |                               stderr=subprocess.STDOUT) == 0: | ||||||
|             wait_count += 1 |             wait_count += 1 | ||||||
|             if wait_count > timeout * 10: |             if wait_count > timeout * 10: | ||||||
|                 self.fail("Timeout while waiting for {}({}) window to " |                 self.fail("Timeout while waiting for {}({}) window to " | ||||||
| @ -1149,7 +1154,8 @@ class SystemTestCase(QubesTestCase): | |||||||
| 
 | 
 | ||||||
|     def shutdown_and_wait(self, vm, timeout=60): |     def shutdown_and_wait(self, vm, timeout=60): | ||||||
|         try: |         try: | ||||||
|             self.loop.run_until_complete(vm.shutdown(wait=True, timeout=timeout)) |             self.loop.run_until_complete( | ||||||
|  |                 vm.shutdown(wait=True, timeout=timeout)) | ||||||
|         except qubes.exc.QubesException: |         except qubes.exc.QubesException: | ||||||
|             name = vm.name |             name = vm.name | ||||||
|             del vm |             del vm | ||||||
| @ -1227,9 +1233,9 @@ class SystemTestCase(QubesTestCase): | |||||||
|             subprocess.check_call(['sudo', 'losetup', '-d', loopdev]) |             subprocess.check_call(['sudo', 'losetup', '-d', loopdev]) | ||||||
| 
 | 
 | ||||||
|     def create_bootable_iso(self): |     def create_bootable_iso(self): | ||||||
|         '''Create simple bootable ISO image. |         """Create simple bootable ISO image. | ||||||
|         Type 'poweroff' to it to terminate that VM. |         Type 'poweroff' to it to terminate that VM. | ||||||
|         ''' |         """ | ||||||
|         isolinux_cfg = ( |         isolinux_cfg = ( | ||||||
|             'prompt 1\n' |             'prompt 1\n' | ||||||
|             'label poweroff\n' |             'label poweroff\n' | ||||||
| @ -1281,8 +1287,10 @@ class SystemTestCase(QubesTestCase): | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| _templates = None | _templates = None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def list_templates(): | def list_templates(): | ||||||
|     '''Returns tuple of template names available in the system.''' |     """Returns tuple of template names available in the system.""" | ||||||
|     global _templates |     global _templates | ||||||
|     if _templates is None: |     if _templates is None: | ||||||
|         if 'QUBES_TEST_TEMPLATES' in os.environ: |         if 'QUBES_TEST_TEMPLATES' in os.environ: | ||||||
| @ -1291,7 +1299,8 @@ def list_templates(): | |||||||
|         try: |         try: | ||||||
|             app = qubes.Qubes() |             app = qubes.Qubes() | ||||||
|             _templates = tuple(vm.name for vm in app.domains |             _templates = tuple(vm.name for vm in app.domains | ||||||
|                 if isinstance(vm, qubes.vm.templatevm.TemplateVM) and |                                if isinstance(vm, | ||||||
|  |                                              qubes.vm.templatevm.TemplateVM) and | ||||||
|                                vm.features.get('os', None) != 'Windows') |                                vm.features.get('os', None) != 'Windows') | ||||||
|             app.close() |             app.close() | ||||||
|             del app |             del app | ||||||
| @ -1299,8 +1308,9 @@ def list_templates(): | |||||||
|             _templates = () |             _templates = () | ||||||
|     return _templates |     return _templates | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def create_testcases_for_templates(name, *bases, module, **kwds): | def create_testcases_for_templates(name, *bases, module, **kwds): | ||||||
|     '''Do-it-all helper for generating per-template tests via load_tests proto |     """Do-it-all helper for generating per-template tests via load_tests proto | ||||||
| 
 | 
 | ||||||
|     This does several things: |     This does several things: | ||||||
|         - creates per-template classes |         - creates per-template classes | ||||||
| @ -1326,7 +1336,7 @@ def create_testcases_for_templates(name, *bases, module, **kwds): | |||||||
|     *NOTE* adding ``module=sys.modules[__name__]`` is *mandatory*, and to allow |     *NOTE* adding ``module=sys.modules[__name__]`` is *mandatory*, and to allow | ||||||
|     enforcing this, it uses keyword-only argument syntax, which is only in |     enforcing this, it uses keyword-only argument syntax, which is only in | ||||||
|     Python 3. |     Python 3. | ||||||
|     ''' |     """ | ||||||
|     # Do not attempt to grab the module from traceback, since we are actually |     # Do not attempt to grab the module from traceback, since we are actually | ||||||
|     # a generator and loadTestsFromNames may also be a generator, so it's not |     # a generator and loadTestsFromNames may also be a generator, so it's not | ||||||
|     # possible to correctly guess frame from stack. Explicit is better than |     # possible to correctly guess frame from stack. Explicit is better than | ||||||
| @ -1342,8 +1352,9 @@ def create_testcases_for_templates(name, *bases, module, **kwds): | |||||||
|         setattr(module, clsname, cls) |         setattr(module, clsname, cls) | ||||||
|         yield '.'.join((module.__name__, clsname)) |         yield '.'.join((module.__name__, clsname)) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def maybe_create_testcases_on_import(create_testcases_gen): | def maybe_create_testcases_on_import(create_testcases_gen): | ||||||
|     '''If certain conditions are met, call *create_testcases_gen* to create |     """If certain conditions are met, call *create_testcases_gen* to create | ||||||
|     testcases for templates tests. The purpose is to use it on integration |     testcases for templates tests. The purpose is to use it on integration | ||||||
|     tests module(s) import, so the test runner could discover tests without |     tests module(s) import, so the test runner could discover tests without | ||||||
|     using load tests protocol. |     using load tests protocol. | ||||||
| @ -1352,17 +1363,18 @@ def maybe_create_testcases_on_import(create_testcases_gen): | |||||||
|      - QUBES_TEST_TEMPLATES present in the environment (it's possible to |      - QUBES_TEST_TEMPLATES present in the environment (it's possible to | ||||||
|      create test cases without opening qubes.xml) |      create test cases without opening qubes.xml) | ||||||
|      - QUBES_TEST_LOAD_ALL present in the environment |      - QUBES_TEST_LOAD_ALL present in the environment | ||||||
|     ''' |     """ | ||||||
|     if 'QUBES_TEST_TEMPLATES' in os.environ or \ |     if 'QUBES_TEST_TEMPLATES' in os.environ or \ | ||||||
|             'QUBES_TEST_LOAD_ALL' in os.environ: |             'QUBES_TEST_LOAD_ALL' in os.environ: | ||||||
|         list(create_testcases_gen()) |         list(create_testcases_gen()) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def extra_info(obj): | def extra_info(obj): | ||||||
|     '''Return short info identifying object. |     """Return short info identifying object. | ||||||
| 
 | 
 | ||||||
|     For example, if obj is a qube, return its name. This is for use with |     For example, if obj is a qube, return its name. This is for use with | ||||||
|     :py:mod:`objgraph` package. |     :py:mod:`objgraph` package. | ||||||
|     ''' |     """ | ||||||
|     # Feel free to extend to other cases. |     # Feel free to extend to other cases. | ||||||
| 
 | 
 | ||||||
|     if isinstance(obj, qubes.vm.qubesvm.QubesVM): |     if isinstance(obj, qubes.vm.qubesvm.QubesVM): | ||||||
| @ -1375,6 +1387,7 @@ def extra_info(obj): | |||||||
| 
 | 
 | ||||||
|     return '' |     return '' | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def load_tests(loader, tests, pattern):  # pylint: disable=unused-argument | def load_tests(loader, tests, pattern):  # pylint: disable=unused-argument | ||||||
|     # discard any tests from this module, because it hosts base classes |     # discard any tests from this module, because it hosts base classes | ||||||
|     tests = unittest.TestSuite() |     tests = unittest.TestSuite() | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Frédéric Pierret (fepitre)
						Frédéric Pierret (fepitre)