qubes/tests: use loadTestsFromNames for nose2 compat

This commit is contained in:
Wojtek Porczyk 2018-03-30 03:04:15 +02:00
parent 3c2ac0fd41
commit dfe7688158
10 changed files with 95 additions and 79 deletions

View File

@ -1127,6 +1127,50 @@ def list_templates():
_templates = ()
return _templates
def create_testcases_for_templates(name, *bases, globals, **kwds):
'''Do-it-all helper for generating per-template tests via load_tests proto
This does several things:
- creates per-template classes
- adds them to module's :py:func:`globals`
- returns an iterable suitable for passing to loader.loadTestsFromNames
TestCase classes created by this function have implicit `.template`
attribute, which contains name of the respective template. They are also
named with given prefix, underscore and template name. If template name
contains characters not valid as part of Python identifier, they are
impossible to get via standard ``.`` operator, though :py:func:`getattr` is
still usable.
>>> class MyTestsMixIn:
... def test_000_my_test(self):
... assert self.template.startswith('debian')
>>> def load_tests(loader, tests, pattern):
... tests.addTests(loader.loadTestsFromNames(
... qubes.tests.create_testcases_for_templates(
... 'TC_00_MyTests', MyTestsMixIn, qubes.tests.SystemTestCase,
... globals=globals())))
*NOTE* adding ``globals=globals()`` is *mandatory*, and to allow enforcing
this, it uses keyword-only argument syntax, which is Python 3 only.
'''
# NOTE globals is passed from calling function, and has slightly different
# semantics (no ``()``).
#
# Do not attempt to grab from traceback, since we are actually a generator
# and loadTestsFromNames may also be a generator, so it's not possible to
# correctly guess frame from stack. Explicit is better than implicit!
module = globals['__name__']
for template in list_templates():
clsname = name + '_' + template
cls = type(clsname, bases, {'template': template, **kwds})
cls.__module__ = module
# XXX I wonder what other __dunder__ attrs did I miss
globals[clsname] = cls
yield '.'.join((module, clsname))
def extra_info(obj):
'''Return short info identifying object.

View File

@ -18,11 +18,12 @@
# License along with this library; if not, see <https://www.gnu.org/licenses/>.
#
import sys
import asyncio
import subprocess
import sys
import pkg_resources
import qubes.tests
import qubes.vm.appvm
@ -206,15 +207,10 @@ def load_tests(loader, tests, pattern):
'qubes.tests.extra.for_template'):
try:
for test_case in entry.load()():
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'{}_{}_{}'.format(
entry.name, test_case.__name__, template),
(test_case,),
{'template': template}
)
))
test.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates(
test_case.__name__, test_case,
globals=sys.modules[test_case.__module__].__dict__)))
except Exception as err: # pylint: disable=broad-except
def runTest(self):
raise err

View File

@ -651,11 +651,8 @@ class TC_10_BackupVMMixin(BackupTestsMixin):
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_10_BackupVM_' + template,
(TC_10_BackupVMMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_10_BackupVM',
TC_10_BackupVMMixin, qubes.tests.SystemTestCase,
globals=globals())))
return tests

View File

@ -793,17 +793,14 @@ class TC_06_AppVMMixin(object):
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_05_StandaloneVM_' + template,
(TC_05_StandaloneVMMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_06_AppVM_' + template,
(TC_06_AppVMMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_05_StandaloneVM',
TC_05_StandaloneVMMixin, qubes.tests.SystemTestCase,
globals=globals())))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_06_AppVM',
TC_06_AppVMMixin, qubes.tests.SystemTestCase,
globals=globals())))
return tests

View File

@ -282,11 +282,8 @@ class TC_20_DispVMMixin(object):
self.assertEqual(test_txt_content, b"Test test 2\ntest1\n")
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_20_DispVM_' + template,
(TC_20_DispVMMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_20_DispVM',
TC_20_DispVMMixin, qubes.tests.SystemTestCase,
globals=globals())))
return tests

View File

@ -386,11 +386,8 @@ Test package
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_00_Dom0Upgrade_' + template,
(TC_00_Dom0UpgradeMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_00_Dom0Upgrade',
TC_00_Dom0UpgradeMixin, qubes.tests.SystemTestCase
globals=globals())))
return tests

View File

@ -1323,20 +1323,16 @@ SHA256:
'{}: {}\n{}'.format(self.update_cmd, stdout, stderr))
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'VmNetworking_' + template,
(VmNetworkingMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromTestCase(
type(
'VmIPv6Networking_' + template,
(VmIPv6NetworkingMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromTestCase(
type(
'VmUpdates_' + template,
(VmUpdatesMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('VmNetworking',
VmNetworkingMixin, qubes.tests.SystemTestCase
globals=globals())))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('VmIPv6Networking',
VmIPv6NetworkingMixin, qubes.tests.SystemTestCase
globals=globals())))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('VmUpdates',
VmUpdates, qubes.tests.SystemTestCase
globals=globals())))
return tests

View File

@ -136,11 +136,8 @@ class TC_40_PVGrub(object):
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_40_PVGrub_' + template,
(TC_40_PVGrub, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_40_PVGrub',
TC_40_PVGrub, qubes.tests.SystemTestCase
globals=globals())))
return tests

View File

@ -392,10 +392,8 @@ class SaltVMTestMixin(SaltTestMixin):
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_10_VMSalt_' + template,
(SaltVMTestMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_10_VMSalt',
SaltVMTestMixin, qubes.tests.SystemTestCase
globals=globals())))
return tests

View File

@ -1012,11 +1012,8 @@ class TC_10_Generic(qubes.tests.SystemTestCase):
def load_tests(loader, tests, pattern):
for template in qubes.tests.list_templates():
tests.addTests(loader.loadTestsFromTestCase(
type(
'TC_00_AppVM_' + template,
(TC_00_AppVMMixin, qubes.tests.SystemTestCase),
{'template': template})))
tests.addTests(loader.loadTestsFromNames(
qubes.tests.create_testcases_for_templates('TC_00_AppVM',
TC_00_AppVMMixin, qubes.tests.SystemTestCase
globals=globals())))
return tests