From 074447cad28873e8c925e89934967acf6d8acda4 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Tue, 20 Dec 2022 14:38:02 -0500 Subject: [PATCH] Add conditional support for loader based plugins The "loader" architecture has been removed in the latest Avocado commits (and will be reflected on Avocado version 100.0 and later). This adds a conditional support for the loader based plugins, so that the latest Avocado-VT can still be used (hopefully for a short time) with Avocado versions having loader support. Fixes: https://github.com/avocado-framework/avocado-vt/issues/3591 Signed-off-by: Cleber Rosa --- avocado_vt/loader.py | 202 +++++++++++++++++----------------- avocado_vt/plugins/vt.py | 12 +- avocado_vt/plugins/vt_init.py | 15 ++- avocado_vt/plugins/vt_list.py | 12 +- 4 files changed, 133 insertions(+), 108 deletions(-) diff --git a/avocado_vt/loader.py b/avocado_vt/loader.py index d0860b5d21..47761547bb 100644 --- a/avocado_vt/loader.py +++ b/avocado_vt/loader.py @@ -20,7 +20,6 @@ import logging import os -from avocado.core import loader from avocado.core import output from virttest import cartesian_config @@ -32,6 +31,12 @@ from .discovery import DiscoveryMixIn from .test import VirtTest +try: + from avocado.core import loader + AVOCADO_LOADER_AVAILABLE = True +except ImportError: + AVOCADO_LOADER_AVAILABLE = False + LOG = logging.getLogger("avocado.app") @@ -86,107 +91,108 @@ class NotAvocadoVTTest(object): """ -class VirtTestLoader(loader.TestLoader, DiscoveryMixIn): - - """ - Avocado loader plugin to load avocado-vt tests - """ - - name = 'vt' +if AVOCADO_LOADER_AVAILABLE: + class VirtTestLoader(loader.TestLoader, DiscoveryMixIn): - def __init__(self, config, extra_params): - """ - Following extra_params are supported: - * avocado_vt_extra_params: Will override the "vt_extra_params" - of this plugins "self.config" (extends the --vt-extra-params) """ - vt_extra_params = extra_params.pop("avocado_vt_extra_params", None) - super(VirtTestLoader, self).__init__(config, extra_params) - # Avocado has renamed "args" to "config" in 84ae9a5d61, lets - # keep making the old name available for compatibility with - # new and old releases - if hasattr(self, 'config'): - self.args = self.config # pylint: disable=E0203 - # And in case an older Avocado is used, the Loader class will - # contain an "args" attribute instead - else: - self.config = self.args # pylint: disable=E0203 - if vt_extra_params: - # We don't want to override the original config - self.config = copy.deepcopy(self.config) - extra = get_opt(self.config, 'vt.extra_params') - if extra is not None: - extra += vt_extra_params - else: - extra = vt_extra_params - set_opt(self.config, 'vt.extra_params', extra) - - def get_extra_listing(self): - if get_opt(self.config, 'vt.list_guests'): - config = copy.copy(self.config) - set_opt(config, 'vt.config', None) - set_opt(config, 'vt.guest_os', None) - guest_listing(config) - if get_opt(self.config, 'vt.list_archs'): - config = copy.copy(self.config) - set_opt(config, 'vt.common.machine_type', None) - set_opt(config, 'vt.common.arch', None) - arch_listing(config) - - @staticmethod - def get_type_label_mapping(): + Avocado loader plugin to load avocado-vt tests """ - Get label mapping for display in test listing. - :returns: a dictionary with the test class as key and description - as value. - """ - return {VirtTest: 'VT', NotAvocadoVTTest: "!VT"} - - @staticmethod - def get_decorator_mapping(): - """ - Get label mapping for display in test listing. + name = 'vt' + + def __init__(self, config, extra_params): + """ + Following extra_params are supported: + * avocado_vt_extra_params: Will override the "vt_extra_params" + of this plugins "self.config" (extends the --vt-extra-params) + """ + vt_extra_params = extra_params.pop("avocado_vt_extra_params", None) + super(VirtTestLoader, self).__init__(config, extra_params) + # Avocado has renamed "args" to "config" in 84ae9a5d61, lets + # keep making the old name available for compatibility with + # new and old releases + if hasattr(self, 'config'): + self.args = self.config # pylint: disable=E0203 + # And in case an older Avocado is used, the Loader class will + # contain an "args" attribute instead + else: + self.config = self.args # pylint: disable=E0203 + if vt_extra_params: + # We don't want to override the original config + self.config = copy.deepcopy(self.config) + extra = get_opt(self.config, 'vt.extra_params') + if extra is not None: + extra += vt_extra_params + else: + extra = vt_extra_params + set_opt(self.config, 'vt.extra_params', extra) + + def get_extra_listing(self): + if get_opt(self.config, 'vt.list_guests'): + config = copy.copy(self.config) + set_opt(config, 'vt.config', None) + set_opt(config, 'vt.guest_os', None) + guest_listing(config) + if get_opt(self.config, 'vt.list_archs'): + config = copy.copy(self.config) + set_opt(config, 'vt.common.machine_type', None) + set_opt(config, 'vt.common.arch', None) + arch_listing(config) + + @staticmethod + def get_type_label_mapping(): + """ + Get label mapping for display in test listing. + + :returns: a dictionary with the test class as key and description + as value. + """ + return {VirtTest: 'VT', NotAvocadoVTTest: "!VT"} + + @staticmethod + def get_decorator_mapping(): + """ + Get label mapping for display in test listing. + + :return: a dictionary with the test class as key and decorator + function as value. + """ + term_support = output.TermSupport() + return {VirtTest: term_support.healthy_str, + NotAvocadoVTTest: term_support.fail_header_str} + + @staticmethod + def _report_bad_discovery(name, reason, which_tests): + if which_tests is loader.DiscoverMode.ALL: + return [(NotAvocadoVTTest, {"name": "%s: %s" % (name, reason)})] + else: + return [] - :return: a dictionary with the test class as key and decorator - function as value. - """ - term_support = output.TermSupport() - return {VirtTest: term_support.healthy_str, - NotAvocadoVTTest: term_support.fail_header_str} - - @staticmethod - def _report_bad_discovery(name, reason, which_tests): - if which_tests is loader.DiscoverMode.ALL: - return [(NotAvocadoVTTest, {"name": "%s: %s" % (name, reason)})] - else: - return [] - - def discover(self, url, which_tests=loader.DiscoverMode.DEFAULT): - try: - cartesian_parser = self._get_parser() - self._save_parser_cartesian_config(cartesian_parser) - except Exception as details: - return self._report_bad_discovery(url, details, which_tests) - if url is not None: + def discover(self, url, which_tests=loader.DiscoverMode.DEFAULT): try: - cartesian_parser.only_filter(url) - # If we have a LexerError, this means - # the url passed is invalid in the cartesian - # config parser, hence it should be ignored. - # just return an empty params list and let - # the other test plugins to handle the URL. - except cartesian_config.ParserError as details: + cartesian_parser = self._get_parser() + self._save_parser_cartesian_config(cartesian_parser) + except Exception as details: return self._report_bad_discovery(url, details, which_tests) - elif (which_tests is loader.DiscoverMode.DEFAULT and - not get_opt(self.config, 'vt.config')): - # By default don't run anything unless vt.config provided - return [] - # Create test_suite - test_suite = [] - for params in (_ for _ in cartesian_parser.get_dicts()): - test_suite.append((VirtTest, self.convert_parameters(params))) - if which_tests is loader.DiscoverMode.ALL and not test_suite: - return self._report_bad_discovery(url, "No matching tests", - which_tests) - return test_suite + if url is not None: + try: + cartesian_parser.only_filter(url) + # If we have a LexerError, this means + # the url passed is invalid in the cartesian + # config parser, hence it should be ignored. + # just return an empty params list and let + # the other test plugins to handle the URL. + except cartesian_config.ParserError as details: + return self._report_bad_discovery(url, details, which_tests) + elif (which_tests is loader.DiscoverMode.DEFAULT and + not get_opt(self.config, 'vt.config')): + # By default don't run anything unless vt.config provided + return [] + # Create test_suite + test_suite = [] + for params in (_ for _ in cartesian_parser.get_dicts()): + test_suite.append((VirtTest, self.convert_parameters(params))) + if which_tests is loader.DiscoverMode.ALL and not test_suite: + return self._report_bad_discovery(url, "No matching tests", + which_tests) + return test_suite diff --git a/avocado_vt/plugins/vt.py b/avocado_vt/plugins/vt.py index 8b8b471f59..6fc12b6ca0 100644 --- a/avocado_vt/plugins/vt.py +++ b/avocado_vt/plugins/vt.py @@ -18,7 +18,6 @@ import os -from avocado.core.loader import loader from avocado.core.plugin_interfaces import CLI from avocado.utils import path as utils_path @@ -27,7 +26,13 @@ from virttest.standalone_test import (SUPPORTED_LIBVIRT_URIS, SUPPORTED_TEST_TYPES) -from ..loader import VirtTestLoader + +try: + from avocado.core.loader import loader + from ..loader import VirtTestLoader + AVOCADO_LOADER_AVAILABLE = True +except ImportError: + AVOCADO_LOADER_AVAILABLE = False _PROVIDERS_DOWNLOAD_DIR = os.path.join(data_dir.get_test_providers_dir(), @@ -226,4 +231,5 @@ def run(self, config): Run test modules or simple tests. :param config: Command line args received from the run subparser. """ - loader.register_plugin(VirtTestLoader) + if AVOCADO_LOADER_AVAILABLE: + loader.register_plugin(VirtTestLoader) diff --git a/avocado_vt/plugins/vt_init.py b/avocado_vt/plugins/vt_init.py index 7dc2fc76ff..34d5ca8e72 100644 --- a/avocado_vt/plugins/vt_init.py +++ b/avocado_vt/plugins/vt_init.py @@ -1,7 +1,6 @@ import importlib from avocado.core import plugin_interfaces -from avocado.core.loader import loader from avocado.core.settings import settings from avocado.utils import path as utils_path @@ -15,6 +14,13 @@ SUPPORTED_TEST_TYPES, find_default_qemu_paths) +try: + from avocado.core.loader import loader + AVOCADO_LOADER_AVAILABLE = True +except ImportError: + AVOCADO_LOADER_AVAILABLE = False + + if hasattr(plugin_interfaces, 'Init'): class VtInit(plugin_interfaces.Init): @@ -273,6 +279,7 @@ def initialize(self): settings.merge_with_configs() - virt_loader = getattr(importlib.import_module('avocado_vt.loader'), - 'VirtTestLoader') - loader.register_plugin(virt_loader) + if AVOCADO_LOADER_AVAILABLE: + virt_loader = getattr(importlib.import_module('avocado_vt.loader'), + 'VirtTestLoader') + loader.register_plugin(virt_loader) diff --git a/avocado_vt/plugins/vt_list.py b/avocado_vt/plugins/vt_list.py index 4a40458b52..067a12afb3 100644 --- a/avocado_vt/plugins/vt_list.py +++ b/avocado_vt/plugins/vt_list.py @@ -19,14 +19,19 @@ import os import sys -from avocado.core.loader import loader from avocado.core.plugin_interfaces import CLI from virttest.compat import get_settings_value, add_option from .vt import add_basic_vt_options, add_qemu_bin_vt_option -from ..loader import VirtTestLoader from virttest._wrappers import load_source +try: + from avocado.core.loader import loader + from ..loader import VirtTestLoader + AVOCADO_LOADER_AVAILABLE = True +except ImportError: + AVOCADO_LOADER_AVAILABLE = False + # The original virt-test runner supports using autotest from a git checkout, # so we'll have to support that as well. The code below will pick up the @@ -120,4 +125,5 @@ def configure(self, parser): add_qemu_bin_vt_option(vt_compat_group_lister) def run(self, config): - loader.register_plugin(VirtTestLoader) + if AVOCADO_LOADER_AVAILABLE: + loader.register_plugin(VirtTestLoader)