Beispiel #1
0
class RPTestcase(unittest.TestCase):
    def test_init(self, mock_rplogger_get, mock_logman):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())
        self.res_pro = ResourceProvider(MockArgs())
        mock_logman.get_resourceprovider_logger.assert_called_once_with(
            "ResourceProvider", "RSP", True)

    def test_init_with_no_file_logging(self, mock_rplogger_get, mock_logman):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())
        mock_arguments = MockArgs()
        mock_arguments.list = True
        self.res_pro = ResourceProvider(mock_arguments)
        mock_logman.get_resourceprovider_logger.assert_called_once_with(
            "ResourceProvider", "RSP", False)

    def test_init_with_list(self, mock_rplogger_get, mock_logman):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())
        args = MockArgs()
        args.list = True
        self.res_pro = ResourceProvider(args)
        mock_logman.get_resourceprovider_logger.assert_called_once_with(
            "ResourceProvider", "RSP", False)

    def test_allocate_duts_errors(self, mock_rplogger_get, mock_logman):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())
        self.res_pro = ResourceProvider(MockArgs())

        mock_resconf = mock.MagicMock()
        mock_pluginmanager = mock.MagicMock()
        mock_pluginmanager.get_allocator = mock.MagicMock(
            return_value=MockAllocator)
        self.res_pro.set_pluginmanager(mock_pluginmanager)

        mock_resconf.count_hardware = mock.MagicMock(return_value=0)
        mock_resconf.get_dut_configuration = mock.MagicMock(return_value=[])
        mock_resconf.count_duts = mock.MagicMock(return_value=0)
        self.res_pro._duts = [MockDut()]
        self.res_pro._resource_configuration = mock_resconf
        # Test raise when allocation fails
        with self.assertRaises(ResourceInitError):
            self.res_pro.allocate_duts(mock_resconf)

    def test_allocate_duts_success(self, mock_rplogger_get, mock_logman):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())

        self.res_pro = ResourceProvider(MockArgs())

        mock_resconf = mock.MagicMock()
        mock_resconf.count_hardware = mock.MagicMock(return_value=1)
        mock_resconf.get_dut_configuration = mock.MagicMock(
            return_value=[mock.MagicMock()])
        mock_resconf.count_duts = mock.MagicMock(return_value=1)
        self.res_pro._duts = [MockDut()]
        self.res_pro._resource_configuration = mock_resconf
        self.res_pro.allocator = mock.MagicMock()
        self.res_pro.allocator.allocate = mock.MagicMock()
        self.res_pro.allocate_duts(mock_resconf)
        self.res_pro.allocator.allocate.assert_called_once_with(
            mock_resconf, args=self.res_pro.args)

    def test_allocator_get(self, mock_rplogger_get, mock_logman):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())
        m_args = MockArgs()
        mock_resconf = mock.MagicMock()
        mock_resconf.count_hardware = mock.MagicMock(return_value=1)
        mock_resconf.get_dut_configuration = mock.MagicMock(
            return_value=[mock.MagicMock()])
        mock_resconf.count_duts = mock.MagicMock(return_value=1)
        self.res_pro = ResourceProvider(m_args)
        self.res_pro._resource_configuration = mock_resconf
        mock_pluginmanager = mock.MagicMock()
        self.res_pro.set_pluginmanager(mock_pluginmanager)
        mock_allocator = mock.MagicMock()
        mock_pluginmanager.get_allocator = mock.MagicMock(
            side_effect=[mock_allocator, None])
        self.res_pro.allocate_duts(mock_resconf)
        mock_allocator.assert_called_once_with(m_args, None, dict())

        self.res_pro.allocator = None
        with self.assertRaises(ResourceInitError):
            self.res_pro.allocate_duts(mock_resconf)

    def test_config_file_reading(self, mock_rplogger_get, mock_logman):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())
        filepath = os.path.abspath(
            os.path.join(__file__, os.path.pardir, "tests",
                         "allocator_config.json"))
        self.res_pro = ResourceProvider(MockArgs())

        with open(filepath, "r") as cfg_file:
            test_data = json.load(cfg_file)

        self.res_pro = ResourceProvider(MockArgs())
        retval = self.res_pro._read_allocator_config("testallocator", filepath)
        self.assertEquals(retval, test_data.get("testallocator"))

    @mock.patch("icetea_lib.ResourceProvider.ResourceProvider.json")
    def test_config_file_errors(self, mock_rplogger_get, mock_logman,
                                mocked_json):
        mock_logman.get_resourceprovider_logger = mock.MagicMock(
            return_value=MockLogger())
        self.res_pro = ResourceProvider(MockArgs())
        with self.assertRaises(ResourceInitError):
            self.res_pro._read_allocator_config("generic", "does_not_exist")
        with self.assertRaises(ResourceInitError):
            not_a_file = os.path.abspath(
                os.path.join(__file__, os.path.pardir, "tests"))
            self.res_pro._read_allocator_config("generic", not_a_file)
        with self.assertRaises(ResourceInitError):
            no_config_here = os.path.abspath(
                os.path.join(__file__, os.path.pardir, "suites",
                             "dummy_suite.json"))
            self.res_pro._read_allocator_config("generic", no_config_here)

        with self.assertRaises(ResourceInitError):
            mocked_json.load = mock.MagicMock()
            mocked_json.load.side_effect = [ValueError]
            filepath = os.path.abspath(
                os.path.join(__file__, os.path.pardir, "tests",
                             "allocator_config.json"))
            self.res_pro._read_allocator_config("testallocator", filepath)

    def tearDown(self):
        self.res_pro.cleanup()
        self.res_pro.__metaclass__._instances.clear()
Beispiel #2
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