提交 3b1616b0 编写于 作者: L Lukáš Doktor

avocado.core.loader: Use only correct test_types

The usage usage of incorrect test-types (types which can't be executed
like missing file, broken symlink ...) was not found useful. This
patch only allows "good" test types to be listed and possible to use.

Additionally the test type now requires to specify loader and type to
avoid possible clashes (and to emphasize the relation between loader
and test type).
Signed-off-by: NLukáš Doktor <ldoktor@redhat.com>
上级 2e7ec402
......@@ -83,20 +83,11 @@ class TestLoaderProxy(object):
self._initialized_plugins = []
self.registered_plugins = []
self.url_plugin_mapping = {}
self._test_types = {}
def register_plugin(self, plugin):
try:
if issubclass(plugin, TestLoader):
self.registered_plugins.append(plugin)
for test_type in plugin.get_type_label_mapping().itervalues():
if (test_type in self._test_types and
self._test_types[test_type] != plugin):
msg = ("Multiple plugins using the same test_type not "
"yet supported (%s, %s)"
% (test_type, self._test_types))
raise NotImplementedError(msg)
self._test_types[test_type] = plugin
else:
raise ValueError
except ValueError:
......@@ -104,44 +95,59 @@ class TestLoaderProxy(object):
"TestLoader" % plugin)
def load_plugins(self, args):
def _err_list_loaders():
return ("Loaders: %s\nTypes: %s" % (names,
self._test_types.keys()))
def _good_test_types(plugin):
"""
List all supported test types (excluding incorrect ones)
"""
name = plugin.name
mapping = plugin.get_type_label_mapping()
# Using __func__ to avoid problem with different term_supp instances
healthy_func = getattr(output.term_support.healthy_str, '__func__')
types = [mapping[_[0]]
for _ in plugin.get_decorator_mapping().iteritems()
if _[1].__func__ is healthy_func]
return [name + '.' + _ for _ in types]
def _str_loaders():
"""
:return: string of sorted loaders and types
"""
return ", ".join(sorted(supported_types + supported_loaders))
self._initialized_plugins = []
# Add (default) file loader if not already registered
if FileLoader not in self.registered_plugins:
self.register_plugin(FileLoader)
supported_loaders = [_.name for _ in self.registered_plugins]
supported_types = []
for plugin in self.registered_plugins:
supported_types.extend(_good_test_types(plugin))
# Load plugin by the priority from settings
names = ["@" + _.name for _ in self.registered_plugins]
loaders = getattr(args, 'loaders', None)
if not loaders:
loaders = settings.get_value("plugins", "loaders", list, [])
if '?' in loaders:
raise LoaderError("Loaders: %s\nTypes: %s"
% (names, self._test_types.keys()))
if "DEFAULT" in loaders: # Replace DEFAULT with unused loaders
idx = loaders.index("DEFAULT")
loaders = (loaders[:idx] + [_ for _ in names if _ not in loaders] +
raise LoaderError("Available loader plugins: %s" % _str_loaders())
if "@DEFAULT" in loaders: # Replace @DEFAULT with unused loaders
idx = loaders.index("@DEFAULT")
loaders = (loaders[:idx] + [plugin for plugin in supported_loaders
if plugin not in loaders] +
loaders[idx+1:])
while "DEFAULT" in loaders: # Remove duplicite DEFAULT entries
loaders.remove("DEFAULT")
while "@DEFAULT" in loaders: # Remove duplicite @DEFAULT entries
loaders.remove("@DEFAULT")
loaders = [_.split(':', 1) for _ in loaders]
priority = [_[0] for _ in loaders]
for i, name in enumerate(priority):
extra_params = {}
if name in names:
plugin = self.registered_plugins[names.index(name)]
elif name in self._test_types:
plugin = self._test_types[name]
extra_params['allowed_test_types'] = name
else:
raise InvalidLoaderPlugin("Loader '%s' not available:\n"
"Loaders: %s\nTypes: %s"
% (name, names,
self._test_types.keys()))
if name in supported_types:
name, extra_params['allowed_test_types'] = name.split('.', 1)
elif name not in supported_loaders:
raise InvalidLoaderPlugin("Loader '%s' not available (%s)"
% (name, _str_loaders()))
if len(loaders[i]) == 2:
extra_params['loader_options'] = loaders[i][1]
plugin = self.registered_plugins[supported_loaders.index(name)]
self._initialized_plugins.append(plugin(args, extra_params))
def get_extra_listing(self):
......
......@@ -12,7 +12,7 @@ The order of test loaders
Avocado supports different types of test starting with `SIMPLE` tests, which
are simply executable files, then unittest-like tests called `INSTRUMENTED`
up to some tests like the `avocado-vt` ones, which uses complex
matrix of tests from config files that don't directl map to existing files.
matrix of tests from config files that don't directly map to existing files.
Given the number of loaders, the mapping from test names on the command line
to executed tests might not always be unique. Additionally some people might
always (or for given run) want to execute only tests of a single type.
......@@ -22,16 +22,15 @@ settings (``/etc/avocado/``), or temporarily using ``--loaders``
(option of ``avocado run``) option.
This option allows you to specify order and some params of the available test
loaders. You can specify either ``@`` + loader_name (``@file``),
TEST_TYPE (``SIMPLE``) and for some loaders even additional params passed
after ``:`` (``@file:/bin/echo -e`` or ``INNER_RUNNER:/bin/echo -e``). You can
also supply ``DEFAULT``, which injects into that position all the remaining
unused loaders.
loaders. You can specify either loader_name (``file``), loader_name +
TEST_TYPE (``file.SIMPLE``) and for some loaders even additional params
passed after ``:`` (``@file:/bin/echo -e``. You can also supply ``@DEFAULT``,
which injects into that position all the remaining unused loaders.
To get help about ``--loaders``::
$ avocado run --loaders ?
$ avocado run --loaders @file:?
$ avocado run --loaders file:?
Example of how ``--loaders`` affects the produced tests (manually gathered
as some of them result in error)::
......@@ -41,12 +40,12 @@ as some of them result in error)::
> VT io-github-autotest-qemu.boot
> MISSING this_does_not_exist
> SIMPLE /bin/echo
$ avocado run passtest boot this_does_not_exist /bin/echo --loaders DEFAULT "@file:/bin/echo -e"
$ avocado run passtest boot this_does_not_exist /bin/echo --loaders @DEFAULT "file:/bin/echo -e"
> INSTRUMENTED passtest.py:PassTest.test
> VT io-github-autotest-qemu.boot
> INNER_RUNNER this_does_not_exist
> SIMPLE /bin/echo
$ avocado run passtest boot this_does_not_exist /bin/echo --loaders SIMPLE INSTRUMENTED DEFAULT INNER_RUNNER:/bin/echo
$ avocado run passtest boot this_does_not_exist /bin/echo --loaders file.SIMPLE file.INSTRUMENTED @DEFAULT file.INNER_RUNNER:/bin/echo
> INSTRUMENTED passtest.py:PassTest.test
> VT io-github-autotest-qemu.boot
> INNER_RUNNER this_does_not_exist
......
......@@ -56,10 +56,10 @@ password =
# avocado.core.plugins.htmlresult ImportError No module named pystache
# add 'avocado.core.plugins.htmlresult' as an element of the list below.
skip_broken_plugin_notification = []
# Optionally you can specify the priority of test loaders (@file) or test
# types (SIMPLE). Some of the plugins even support extra params
# (INNER_RUNNER:/bin/echo -e). Plugins will be used accordingly to the plugin
# Optionally you can specify the priority of test loaders (file) or test
# types (file.SIMPLE). Some of the plugins even support extra params
# (file:/bin/echo -e). Plugins will be used accordingly to the plugin
# priorities. It's possible to list plugins multiple times (with different
# options or just types).
# The type "DEFAULT" will be replaced with all available unused loaders.
loaders = ['@file', 'DEFAULT']
# options or test types).
# The keyword "@DEFAULT" will be replaced with all available unused loaders.
loaders = ['file', '@DEFAULT']
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册