Пример #1
0
    def test_register_all_tc_types(self):
        # Set up mocks
        plugin_class = mock.MagicMock()
        plugin_class.init = mock.MagicMock()
        plugin_class.get_bench_api = mock.MagicMock()
        plugin_class.get_parsers = mock.MagicMock()
        plugin_class.get_external_services = mock.MagicMock()
        mock_bench = mock.MagicMock(spec=[])
        mock_bench.logger = mock.MagicMock(return_value=mock.MagicMock())
        mock_bench_function = mock.MagicMock()
        mock_parser = mock.MagicMock()
        plugin_class.get_bench_api.return_value = {
            "mock_func": mock_bench_function
        }
        plugin_class.get_external_services.return_value = {
            "mock_class": mock.MagicMock
        }
        plugin_class.get_parsers.return_value = {"mock_parser": mock_parser}
        mock_parsermanager = mock.MagicMock()
        mock_parsermanager.add_parser = mock.MagicMock()
        mock_parsermanager.has_parser = mock.MagicMock(return_value=False)

        pm = PluginManager(bench=mock_bench, responseparser=mock_parsermanager)
        pm.register_tc_plugins("test_plugin", plugin_class)

        # Asserts
        self.assertEqual(len(pm.registered_plugins), 1)
        self.assertEqual(pm.registered_plugins[0], "test_plugin")
        self.assertEqual(len(pm._external_services), 1)
        mock_parsermanager.has_parser.assert_called_once_with("mock_parser")
        mock_parsermanager.add_parser.assert_called_once_with(
            "mock_parser", mock_parser)
Пример #2
0
 def _init_pluginmanager(self):
     """
     Initialize PluginManager and load run wide plugins.
     """
     self.pluginmanager = PluginManager(logger=self.logger)
     self.logger.debug("Registering execution wide plugins:")
     self.pluginmanager.load_default_run_plugins()
     self.pluginmanager.load_custom_run_plugins(self.args.plugin_path)
     self.logger.debug("Execution wide plugins loaded and registered.")
Пример #3
0
 def test_load_custom_plugin_exception(self, mock_importer):
     mock_bench = mock.MagicMock(spec=[])
     mock_parsermanager = mock.MagicMock()
     mock_importer.import_module = mock.MagicMock(side_effect=[ImportError])
     pm = PluginManager(bench=mock_bench, responseparser=mock_parsermanager)
     with self.assertRaises(PluginException):
         pm.load_custom_tc_plugins(
             os.path.join(os.path.dirname(os.path.abspath(__file__)),
                          "test_plugin/load_test_plugins.py"))
Пример #4
0
 def test_load_custom_plugins(self):
     modules = sys.modules
     mock_bench = mock.MagicMock(spec=[])
     mock_parsermanager = mock.MagicMock()
     pm = PluginManager(bench=mock_bench, responseparser=mock_parsermanager)
     pm.register_tc_plugins = mock.MagicMock()
     pm.load_custom_tc_plugins(
         os.path.join(os.path.dirname(os.path.abspath(__file__)),
                      "test_plugin/load_test_plugins.py"))
     sys.modules = modules
     pm.register_tc_plugins.assert_called_once()
Пример #5
0
    def init(self, benchapi, logger=None):
        """
        Initialize Parser and Plugin managers.

        :return: Nothing
        """
        self._env = benchapi.env
        if logger:
            self._logger = logger
        self._parser_manager = ParserManager(self._logger)
        self._pluginmanager = PluginManager(responseparser=self._parser_manager,
                                            bench=benchapi,
                                            logger=self._logger)
Пример #6
0
    def test_register_and_start_service(self):
        # Set up mocks
        plugin_class = mock.MagicMock()
        plugin_class.init = mock.MagicMock()
        plugin_class.get_bench_api = mock.MagicMock()
        plugin_class.get_parsers = mock.MagicMock()
        plugin_class.get_external_services = mock.MagicMock()

        mock_bench = mock.MagicMock(spec=[])
        mock_bench.logger = mock.MagicMock(return_value=mock.MagicMock())

        plugin_class.get_bench_api.return_value = None
        mock_class = mock.MagicMock()
        plugin_class.get_external_services.return_value = {
            "mock_class": mock_class
        }
        plugin_class.get_parsers.return_value = None

        mock_parsermanager = mock.MagicMock()

        pm = PluginManager(bench=mock_bench, responseparser=mock_parsermanager)
        pm.register_tc_plugins("test_plugin", plugin_class)
        pm.start_external_service("mock_class")
        self.assertEqual(len(pm._started_services), 1)
        pm.stop_external_services()

        self.assertEqual(len(pm._started_services), 0)
        self.assertEqual(len(pm._external_services), 1)
        mock_class.assert_called_once()
Пример #7
0
    def test_register_start_stop_service(self):  # pylint: disable=invalid-name
        plugin_class = mock.MagicMock()
        plugin_class.init = mock.MagicMock()
        plugin_class.get_bench_api = mock.MagicMock()
        plugin_class.get_parsers = mock.MagicMock()
        plugin_class.get_external_services = mock.MagicMock()

        mock_bench = mock.MagicMock(spec=[])
        mock_bench.logger = mock.MagicMock(return_value=mock.MagicMock())

        plugin_class.get_bench_api.return_value = None
        mocked_service = mock.MagicMock()
        mocked_service.start = mock.MagicMock()
        mocked_service.stop = mock.MagicMock(side_effect=[PluginException])
        mock_class = mock.MagicMock(return_value=mocked_service)
        plugin_class.get_external_services.return_value = {
            "mock_class": mock_class
        }
        plugin_class.get_parsers.return_value = None

        mock_parsermanager = mock.MagicMock()

        pluginmanager = PluginManager(bench=mock_bench,
                                      responseparser=mock_parsermanager)
        pluginmanager.register_tc_plugins("test_plugin", plugin_class)
        pluginmanager.start_external_service("mock_class")
        self.assertEqual(len(pluginmanager._started_services), 1)
        pluginmanager.stop_external_services()

        self.assertEqual(len(pluginmanager._started_services), 0)
        self.assertEqual(len(pluginmanager._external_services), 1)
        mock_class.assert_called_once()
Пример #8
0
    def test_register_raises_pluginexception(self):
        plugin_class = mock.MagicMock()
        plugin_class.init = mock.MagicMock()
        plugin_class.get_bench_api = mock.MagicMock()

        mock_bench = mock.MagicMock(spec=[])
        mock_bench.logger = mock.MagicMock(return_value=mock.MagicMock())
        mock_bench_function = mock.MagicMock()
        mock_parser = mock.MagicMock()
        plugin_class.get_bench_api.return_value = {
            "mock_func": mock_bench_function
        }
        mock_parsermanager = mock.MagicMock()
        mock_parsermanager.add_parser = mock.MagicMock()
        mock_parsermanager.has_parser = mock.MagicMock(return_value=False)

        pm = PluginManager(bench=mock_bench, responseparser=mock_parsermanager)
        pm.registered_plugins = ["test_plugin"]
        with self.assertRaises(PluginException):
            pm.register_tc_plugins("test_plugin", plugin_class)
Пример #9
0
    def test_start_service_raises_exception(self):
        # Set up mocks
        plugin_class = mock.MagicMock()
        plugin_class.init = mock.MagicMock()
        plugin_class.get_bench_api = mock.MagicMock()
        plugin_class.get_parsers = mock.MagicMock()
        plugin_class.get_external_services = mock.MagicMock()

        mock_bench = mock.MagicMock(spec=[])
        mock_bench.logger = mock.MagicMock(return_value=mock.MagicMock())

        plugin_class.get_bench_api.return_value = None
        mocked_service = mock.MagicMock()
        mock_class = mock.MagicMock(return_value=mocked_service)
        mocked_service.start = mock.MagicMock()
        mocked_service.start.side_effect = [PluginException]
        plugin_class.get_external_services.return_value = {
            "mock_class": mock_class
        }
        plugin_class.get_parsers.return_value = None

        mock_parsermanager = mock.MagicMock()

        pm = PluginManager(bench=mock_bench, responseparser=mock_parsermanager)
        pm.register_tc_plugins("test_plugin", plugin_class)
        with self.assertRaises(PluginException):
            pm.start_external_service("mock_class")
            mocked_service.start.assert_called_once()
Пример #10
0
 def test_load_defaults(self):
     bench = mock.MagicMock(spec=[])
     bench.logger = mock.MagicMock(return_value=mock.MagicMock())
     rp = mock.MagicMock()
     rp.append = mock.MagicMock()
     rp.has_parser = mock.MagicMock(return_value=False)
     pm = PluginManager(bench=bench, responseparser=rp)
     pm.load_default_tc_plugins()
     pm.load_default_run_plugins()
     length = len(default_plugins)
     self.assertEqual(len(pm.registered_plugins), length)
Пример #11
0
class Plugins(object):
    """
    This Mixer manage Test used Plugins.
    """
    def __init__(self, logger, env, args, config):
        super(Plugins, self).__init__()
        self._parser_manager = None
        self._pluginmanager = None
        self._logger = logger
        self._env = env
        self._args = args
        self._config = config

    def init(self, benchapi, logger=None):
        """
        Initialize Parser and Plugin managers.

        :return: Nothing
        """
        self._env = benchapi.env
        if logger:
            self._logger = logger
        self._parser_manager = ParserManager(self._logger)
        self._pluginmanager = PluginManager(responseparser=self._parser_manager,
                                            bench=benchapi,
                                            logger=self._logger)

    def load_plugins(self):
        """
        Initialize PluginManager and Load bench related plugins.

        :return: Nothing
        """
        self._pluginmanager.load_default_tc_plugins()
        self._pluginmanager.load_custom_tc_plugins(self._args.plugin_path)

    @property
    def pluginmanager(self):
        """
        Getter for PluginManager.

        :return: PluginManager
        """
        return self._pluginmanager

    @pluginmanager.setter
    def pluginmanager(self, value):
        """
        Setter for PluginManager.
        """
        self._pluginmanager = value

    # All required external services starting here
    def start_external_services(self):
        """
        Start ExtApps required by test case.

        :return: Nothing
        """
        apps = get(self._config, 'requirements.external.apps', [])
        for app in apps:
            # Check if we have an environment configuration for this app
            conf = app
            try:
                conf = merge(conf, self._env["extApps"][app["name"]])
            except KeyError:
                self._logger.warning("Unable to merge configuration for app %s", app,
                                     exc_info=True if not self._args.silent else False)

            if 'name' in app:
                try:
                    self.pluginmanager.start_external_service(app['name'], conf=conf)
                except PluginException:
                    self._logger.error("Failed to start requested external services.")
                    raise EnvironmentError("Failed to start requested external services.")
                self._logger.info("done")
            else:
                conf_path = None
                conf_cmd = None
                try:
                    conf_path = conf["path"]
                except KeyError:
                    self._logger.warning("No path defined for app %s", app)
                try:
                    conf_cmd = conf["cmd"]
                except KeyError:
                    self._logger.warning("No command defined for app %s", app)
                appname = 'generic'
                newapp = GenericProcess(name=appname, path=conf_path, cmd=conf_cmd)
                newapp.ignore_return_code = True
                newapp.start_process()

    def stop_external_services(self):
        """
        Stop external services started via PluginManager
        """
        self._logger.debug("Stop external services if any")
        self.pluginmanager.stop_external_services()

    def parse_response(self, cmd, response):
        """
        Parse a response for command cmd.

        :param cmd: Command
        :param response: Response
        :return: Parsed response (usually dict)
        """
        return self._parser_manager.parse(cmd, response)
Пример #12
0
class IceteaManager(object):
    """
    IceteaManager class. This is the master of the entire run. The primary entry point into
    execution is the run method.
    """
    def __init__(self):
        """
        Constructor for IceteaManager. Appends libraries to sys.path, loads the test case
        metadata schema, parses arguments and initializes logging.
        """
        self.libpath = os.sep.join(
            os.path.abspath(__file__).split(os.sep)[:-1])
        sys.path.append(self.libpath)
        libpath2 = os.sep.join(self.libpath.split(os.sep)[:-1])
        sys.path.append(libpath2)
        # Initialize TCMetaSchema with correct libpath
        TCMetaSchema(self.libpath)
        self.args, self.unknown = IceteaManager._parse_arguments()
        # If called with --clean, clean up logs.
        if self.args.clean:
            _cleanlogs(silent=self.args.silent, log_location=self.args.log)

        LogManager.init_base_logging(
            self.args.log,
            verbose=self.args.verbose,
            silent=self.args.silent,
            color=self.args.color,
            no_file=(self.args.list or self.args.listsuites),
            truncate=not self.args.disable_log_truncate)

        self.logger = LogManager.get_logger("icetea")
        self.pluginmanager = None
        self.resourceprovider = ResourceProvider(self.args)
        self._init_pluginmanager()
        self.resourceprovider.set_pluginmanager(self.pluginmanager)

    @staticmethod
    def list_suites(suitedir="./testcases/suites", cloud=False):
        """
        Static method for listing suites from both local source and cloud.
        Uses PrettyTable to generate the table.

        :param suitedir: Local directory for suites.
        :param cloud: cloud module
        :return: PrettyTable object or None if no test cases were found
        """
        suites = []
        suites.extend(TestSuite.get_suite_files(suitedir))

        # no suitedir, or no suites -> append cloud.get_campaigns()

        if cloud:
            names = cloud.get_campaign_names()
            if names:
                suites.append("------------------------------------")
                suites.append("FROM CLOUD:")
                suites.extend(names)
        if not suites:
            return None

        from prettytable import PrettyTable
        table = PrettyTable(["Testcase suites"])
        for suite in suites:
            table.add_row([suite])
        return table

    @staticmethod
    def _parse_arguments():
        """
        Static method for paring arguments
        """
        parser = get_base_arguments(get_parser())
        parser = get_tc_arguments(parser)
        args, unknown = parser.parse_known_args()
        return args, unknown

    def check_args(self):
        """
        Validates that a valid number of arguments were received and that all arguments were
        recognised.

        :return: True or False.
        """
        parser = get_base_arguments(get_parser())
        parser = get_tc_arguments(parser)
        # Disable "Do not use len(SEQ) as condition value"
        # pylint: disable=C1801
        if len(sys.argv) < 2:
            self.logger.error("Icetea called with no arguments! ")
            parser.print_help()
            return False
        elif not self.args.ignore_invalid_params and self.unknown:
            self.logger.error(
                "Unknown parameters received, exiting. "
                "To ignore this add --ignore_invalid_params flag.")
            self.logger.error("Following parameters were unknown: {}".format(
                self.unknown))
            parser.print_help()
            return False
        return True

    def _init_pluginmanager(self):
        """
        Initialize PluginManager and load run wide plugins.
        """
        self.pluginmanager = PluginManager(logger=self.logger)
        self.logger.debug("Registering execution wide plugins:")
        self.pluginmanager.load_default_run_plugins()
        self.pluginmanager.load_custom_run_plugins(self.args.plugin_path)
        self.logger.debug("Execution wide plugins loaded and registered.")

    def run(self, args=None):
        """
        Runs the set of tests within the given path.
        """
        # Disable "Too many branches" and "Too many return statemets" warnings
        # pylint: disable=R0912,R0911
        retcodesummary = ExitCodes.EXIT_SUCCESS
        self.args = args if args else self.args

        if not self.check_args():
            return retcodesummary

        if self.args.clean:
            if not self.args.tc and not self.args.suite:
                return retcodesummary

        # If called with --version print version and exit
        version = get_fw_version()
        if self.args.version and version:
            print(version)
            return retcodesummary
        elif self.args.version and not version:
            print(
                "Unable to get version. Have you installed Icetea correctly?")
            return retcodesummary

        self.logger.info(
            "Using Icetea version {}".format(version) if version else
            "Unable to get Icetea version. Is Icetea installed?")

        # If cloud set, import cloud, get parameters from environment, initialize cloud
        cloud = self._init_cloud(self.args.cloud)

        # Check if called with listsuites. If so, print out suites either from cloud or from local
        if self.args.listsuites:
            table = self.list_suites(self.args.suitedir, cloud)
            if table is None:
                self.logger.error("No suites found!")
                retcodesummary = ExitCodes.EXIT_FAIL
            else:
                print(table)
            return retcodesummary

        try:
            testsuite = TestSuite(logger=self.logger,
                                  cloud_module=cloud,
                                  args=self.args)
        except SuiteException as error:
            self.logger.error(
                "Something went wrong in suite creation! {}".format(error))
            retcodesummary = ExitCodes.EXIT_INCONC
            return retcodesummary

        if self.args.list:
            if self.args.cloud:
                testsuite.update_testcases()
            testcases = testsuite.list_testcases()
            print(testcases)
            return retcodesummary

        results = self.runtestsuite(testsuite=testsuite)

        if not results:
            retcodesummary = ExitCodes.EXIT_SUCCESS
        elif results.failure_count(
        ) and self.args.failure_return_value is True:
            retcodesummary = ExitCodes.EXIT_FAIL
        elif results.inconclusive_count(
        ) and self.args.failure_return_value is True:
            retcodesummary = ExitCodes.EXIT_INCONC

        return retcodesummary

    def runtestsuite(self, testsuite):
        """
        Runs a single test suite

        :param testsuite: TestSuite
        :return: ResultList
        """
        if testsuite.status == TestStatus.READY:
            results = testsuite.run()
        else:
            results = ResultList()
        # Disable "Expression is assigned to nothing" warning
        # pylint: disable=W0106
        [handler.flush() for handler in self.logger.handlers]
        results.save(heads={'Build': '', 'Branch': self.args.branch})
        sys.stdout.flush()
        self._cleanup_resourceprovider()
        return results

    # Disable "String statement has no effect" warning
    # pylint: disable=W0105
    """
        PRIVATE FUNCTIONS HERE
    """

    def _cleanup_resourceprovider(self):
        """
        Calls cleanup for ResourceProvider of this run.

        :return: Nothing
        """
        # Disable too broad exception warning
        # pylint: disable=W0703
        self.resourceprovider = ResourceProvider(self.args)
        try:
            self.resourceprovider.cleanup()
            self.logger.info("Cleanup done.")
        except Exception as error:
            self.logger.error("Cleanup failed! %s", error)

    def _init_cloud(self, cloud_arg):
        """
        Initializes Cloud module if cloud_arg is set.

        :param cloud_arg: taken from args.cloud
        :return: cloud module object instance
        """
        # Disable too broad exception warning
        # pylint: disable=W0703
        cloud = None
        if cloud_arg:
            try:
                if hasattr(self.args, "cm"):
                    cloud_module = self.args.cm if self.args.cm else None
                    self.logger.info(
                        "Creating cloud module {}.".format(cloud_module))
                else:
                    cloud_module = None

                cloud = Cloud(host=None,
                              module=cloud_module,
                              logger=self.logger,
                              args=self.args)
            except Exception as error:
                self.logger.warning(
                    "Cloud module could not be initialized: {}".format(error))
                cloud = None
        return cloud