Beispiel #1
0
    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)
Beispiel #2
0
 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)
Beispiel #3
0
    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"))
Beispiel #4
0
    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)
Beispiel #5
0
    def init(self, commands, logger=None):
        """
        Initialize ResourceConfig and ResourceProvider

        :return: Nothing
        """
        if logger:
            self._logger = logger
        # Create ResourceProvider object and resolve the resource requirements from configuration
        self._resource_provider = ResourceProvider(self._args)
        # @todo need better way to handle forceflash_once option
        # because provider is singleton instance.
        self._resource_provider.args.forceflash = self._args.forceflash
        self._resource_configuration = ResourceConfig(logger=self._logger)
        self._resource_provider.resolve_configuration(self._configuration.config,
                                                      self._resource_configuration)
        self._commands = commands
Beispiel #6
0
    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)
Beispiel #7
0
    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)
Beispiel #8
0
    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)
Beispiel #9
0
    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)
Beispiel #10
0
 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)
Beispiel #11
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 #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
Beispiel #13
0
class ResourceFunctions(object):
    """
    ResourceFunctions manage test required resources, like DUT's.
    It provide public API's to get individual DUT's object or iterator over all DUT's.
    """
    def __init__(self, args, logger, configuration, **kwargs):
        super(ResourceFunctions, self).__init__(**kwargs)
        self._allocation_context = None
        self._resource_configuration = ResourceConfig()
        self._resource_provider = None
        self._starttime = None
        self._dutinformations = None
        self._commands = None
        self._duts = []
        self._args = args
        self._logger = logger
        self._configuration = configuration

    def init(self, commands, logger=None):
        """
        Initialize ResourceConfig and ResourceProvider

        :return: Nothing
        """
        if logger:
            self._logger = logger
        # Create ResourceProvider object and resolve the resource requirements from configuration
        self._resource_provider = ResourceProvider(self._args)
        # @todo need better way to handle forceflash_once option
        # because provider is singleton instance.
        self._resource_provider.args.forceflash = self._args.forceflash
        self._resource_configuration = ResourceConfig(logger=self._logger)
        self._resource_provider.resolve_configuration(self._configuration.config,
                                                      self._resource_configuration)
        self._commands = commands

    def init_duts(self, benchapi):
        """
        Initialize Duts, and the network sniffer.

        :return: Nothing
        """
        # Validate dut configurations
        self.validate_dut_configs(self.resource_configuration.get_dut_configuration(),
                                  self._logger)
        # Initialize duts
        if self.resource_configuration.count_duts() > 0:
            self._initialize_duts()
            benchapi._nwsniffer.init_sniffer()
        else:
            self._logger.debug("This TC doesn't use DUT's")
        self._starttime = time.time()

    def duts_release(self):
        """
        Release Duts.

        :return: Nothing
        """
        try:
            # try to close node's by nicely by `exit` command
            # if it didn't work, kill it by OS process kill command
            # also close reading threads if any
            self._logger.debug("Close dut connections")
            # pylint: disable=unused-variable
            for i, dut in self.duts_iterator():
                try:
                    dut.close_dut()
                    dut.close_connection()
                except Exception:  # pylint: disable=broad-except
                    # We want to catch all uncaught Exceptions here.
                    self._logger.error("Exception while closing dut %s!",
                                       dut.dut_name,
                                       exc_info=True if not self._args.silent else False)
                finally:
                    if hasattr(self._resource_provider.allocator, "share_allocations"):
                        if getattr(self._resource_provider.allocator, "share_allocations"):
                            pass
                        else:
                            self._logger.debug("Releasing dut {}".format(dut.index))
                            self.resource_provider.allocator.release(dut=dut)
                    else:
                        self._logger.debug("Releasing dut {}".format(dut.index))
                        self.resource_provider.allocator.release(dut=dut)

            self._logger.debug("Close dut threads")

            # finalize dut thread
            for ind, dut in self.duts_iterator():
                while not dut.finished():
                    time.sleep(0.5)
                    self._logger.debug("Dut #%i is not finished yet..", ind)
        except KeyboardInterrupt:
            self._logger.debug("key interrupt")
            for ind, dut in self.duts_iterator():
                dut.kill_received = True
            self._duts_delete()

    def get_start_time(self):
        """
        Get start time.

        :return: None if test has not started, start time stamp fetched with time.time() otherwise.
        """
        return self._starttime

    @property
    def resource_configuration(self):
        """
        Getter for __resource_configuration.

        :return: ResourceConfig
        """
        return self._resource_configuration

    @resource_configuration.setter
    def resource_configuration(self, value):
        """
        Setter for __resource_configuration.

        :param value: ResourceConfig
        :return: Nothing
        """
        self._resource_configuration = value

    def dut_count(self):
        """
        Getter for dut count from resource configuration.

        :return: int
        """
        if self.resource_configuration:
            return self.resource_configuration.count_duts()
        return 0

    def get_dut_count(self):
        """
        Get dut count.

        :return: int
        """
        return self.dut_count()

    @property
    def resource_provider(self):
        """
        Getter for __resource_provider

        :return: ResourceProvider
        """
        return self._resource_provider

    @property
    def duts(self):
        """
        Get _duts.

        :return: list
        """
        return self._duts

    @duts.setter
    def duts(self, value):
        """
        set a list as _duts.

        :param value: list
        :return: Nothing
        """
        self._duts = value

    @property
    def dut_indexes(self):
        """
        Get a list with dut indexes.

        :return: list
        """
        return range(1, self._resource_configuration.count_duts() + 1)

    def _duts_delete(self):
        """
        Reset internal __duts list to empty list.

        :return: Nothing
        """
        self._logger.debug("delete duts")
        self._duts = []

    def duts_iterator_all(self):
        """
        Yield indexes and related duts.
        """
        for ind, dut in enumerate(self.duts):
            yield ind, dut

    def duts_iterator(self):
        """
        Yield indexes and related duts that are for this test case.
        """
        for ind, dut in enumerate(self.duts):
            if self.is_my_dut_index(ind):
                yield ind, dut

    def is_allowed_dut_index(self, dut_index):
        """
        Check if dut_index is one of the duts for this test case.

        :param dut_index: int
        :return: Boolean
        """
        return dut_index in self.dut_indexes

    def get_dut(self, k):
        """
        Get dut object.

        :param k: index or nickname of dut.
        :return: Dut
        """
        dut_index = k
        if isinstance(k, str):
            dut_index = self.get_dut_index(k)

        if dut_index > len(self.duts) or dut_index < 1:
            self._logger.error("Invalid DUT number")
            raise ValueError("Invalid DUT number when calling get_dut(%i)" % dut_index)
        return self.duts[dut_index - 1]

    def get_node_endpoint(self, endpoint_id, bench):
        """
        get NodeEndPoint object for dut endpoint_id.

        :param endpoint_id: nickname of dut
        :return: NodeEndPoint
        """
        if isinstance(endpoint_id, string_types):
            endpoint_id = self.get_dut_index(endpoint_id)
        return NodeEndPoint(bench, endpoint_id)

    def is_my_dut_index(self, dut_index):
        """
        :return: Boolean
        """
        if self._args.my_duts:
            myduts = self._args.my_duts.split(',')
            if str(dut_index) in myduts:
                return True
            return False
        else:
            return True

    @property
    def dutinformations(self):
        """
        Getter for DutInformation list.

        :return: list
        """
        if self._allocation_context:
            return self._allocation_context.get_dutinformations()
        return list()

    @dutinformations.setter
    def dutinformations(self, value):
        if self._allocation_context:
            self._allocation_context.dutinformations = value

    def reset_dut(self, dut_index='*'):
        """
        Reset dut k.

        :param dut_index: index of dut to reset. Default is *, which causes all duts to be reset.
        :return: Nothing
        """
        if dut_index == '*':
            for ind in self.resource_configuration.get_dut_range():
                if self.is_my_dut_index(ind):
                    self.reset_dut(ind)
            return
        method = None
        if self._args.reset == "hard" or self._args.reset == "soft":
            self._logger.debug("Sending reset %s to dut %d", self._args.reset, dut_index - 1)
            method = self._args.reset
        self.duts[dut_index - 1].init_wait_register()
        self.duts[dut_index - 1].reset(method)
        self._logger.debug("Waiting for dut %d to initialize", dut_index)
        result = self.duts[dut_index - 1].wait_init()
        if not result:
            self._logger.warning("Cli initialization trigger not found. Maybe your application"
                                 " started before we started reading? Try adding --reset"
                                 " to your run command.")
            raise DutConnectionError("Dut cli failed to initialize within set timeout!")
        if self._args.sync_start:
            self._commands.sync_cli(dut_index)
        self._logger.debug("CLI initialized")
        self.duts[dut_index - 1].init_cli()

    def _open_dut_connections(self, allocations):
        """
        Internal helper. Registers waiting for cli initialization and handles the wait
        as well as opens connections.
        """
        for dut in self._duts:
            dut.init_wait_register()

        try:
            allocations.open_dut_connections()
        except DutConnectionError:
            self._logger.exception("Error while opening DUT connections!")
            for dut in self._duts:
                dut.close_dut()
                dut.close_connection()
            raise

        for ind, dut in self.duts_iterator():
            self._logger.info("Waiting for dut %d to initialize.", ind + 1)
            res = dut.wait_init()
            if not res:
                self._logger.warning("Cli initialization trigger not found. Maybe your application"
                                     " started before we started reading? Try adding --reset"
                                     " to your run command.")
                raise DutConnectionError("Dut cli failed to initialize within set timeout!")
            if self._args.sync_start:
                self._logger.info("Synchronizing the command line interface.")
                try:
                    self._commands.sync_cli(dut.index)
                except TestStepError:
                    raise DutConnectionError("Synchronized start for dut {} failed!".format(
                        dut.index))

    def _alloc_error_helper(self):
        """
        Helper for exception handling in the __init_duts method.
        """
        d_info_list = []
        for i, resource in enumerate(self.resource_configuration.get_dut_configuration()):
            dutinfo = DutInformation(resource.get("platform_name"), None, i)
            d_info_list.append(dutinfo)
        self._dutinformations = d_info_list

    def get_platforms(self):
        """
        Get list of dut platforms.

        :return: list
        """
        plat_list = []
        for info in self.dutinformations:
            plat_list.append(info.platform)
        return plat_list

    def get_serialnumbers(self):
        """
        Get list of dut serial numbers.

        :return: list
        """
        serial_number_list = []
        for info in self.dutinformations:
            serial_number_list.append(info.resource_id)
        return serial_number_list

    # Internal function to Initialize cli dut's
    def _initialize_duts(self):
        """
        Internal function to initialize duts

        :return: Nothing
        :raises: DutConnectionError if correct amount of duts were not initialized or if reset
        failed or if cli initialization wait loop timed out.
        """

        # Initialize command line interface
        self._logger.info("Initialize DUT's connections")

        try:
            allocations = self.resource_provider.allocate_duts(self.resource_configuration)
        except (AllocationError, ResourceInitError):
            self._alloc_error_helper()
            raise
        self._allocation_context = allocations
        allocations.set_logger(self._logger)
        allocations.set_resconf(self.resource_configuration)

        try:
            self._duts = allocations.init_duts(args=self._args)

            if len(self._duts) != self.resource_configuration.count_duts():
                raise AllocationError("Unable to initialize required amount of duts.")
        except AllocationError:
            self._alloc_error_helper()
            raise

        self._open_dut_connections(allocations)

        for ind, dut in self.duts_iterator():
            dut.Testcase = self._configuration.name
            dut.init_cli()
            self._logger.debug("DUT[%i]: Cli initialized.", ind)

        for ind, dut in self.duts_iterator():
            self._logger.debug("DUT[%i]: %s", ind, dut.comport)

        self._logger.debug("Initialized %d %s "
                           "for this testcase.", len(self._duts),
                           "dut" if len(self._duts) == 1 else "duts")

    def validate_dut_configs(self, dut_configuration_list, logger):
        """
        Validate dut configurations.

        :param dut_configuration_list: dictionary with dut configurations
        :param logger: logger to be used
        :raises EnvironmentError if something is wrong
        """
        # for now we validate only binaries - if it exists or not.
        if not self._args.skip_flash:
            for conf in dut_configuration_list:
                try:
                    binar = conf.get("application").get("bin")
                    if binar:
                        build = Build.init(binar)
                        if not build.is_exists():
                            logger.warning("Binary '{}' not found".format(binar))
                            raise EnvironmentError("Binary not found")
                except(KeyError, AttributeError):
                    pass

        if logger is not None:
            logger.debug("Configurations seems to be ok")

    def get_dut_versions(self, commands):
        """
        Get nname results and set them to duts.

        :return: Nothing
        """
        resps = commands.command('*', "nname")
        for i, resp in enumerate(resps):
            self.duts[i].version = resp.parsed

    def get_dut_nick(self, dut_index):
        """
        Get nick of dut index k.

        :param dut_index: index of dut
        :return: string
        """
        nick = str(dut_index)
        int_index_in_duts = dut_index in self._configuration.config["requirements"]["duts"]
        str_index_in_duts = False
        if not int_index_in_duts:
            str_index_in_duts = nick in self._configuration.config["requirements"]["duts"]
        if str_index_in_duts:
            nick_in_indexed_reqs = "nick" in self._configuration.config[
                "requirements"]["duts"][nick]
        elif int_index_in_duts:
            nick_in_indexed_reqs = "nick" in self._configuration.config[
                "requirements"]["duts"][dut_index]
        else:
            nick_in_indexed_reqs = False
        if int_index_in_duts and nick_in_indexed_reqs:
            return self._configuration.config["requirements"]["duts"][dut_index]['nick']
        elif str_index_in_duts and nick_in_indexed_reqs:
            return self._configuration.config["requirements"]["duts"][nick]['nick']
        return nick

    def get_dut_index(self, nick):
        """
        Get index of dut with nickname nick.

        :param nick: string
        :return: integer > 1
        """
        for dut_index, dut in enumerate(self.resource_configuration.get_dut_configuration()):
            nickname = dut.get("nick")
            if nickname and nickname == nick:
                return dut_index + 1
        raise ValueError("Cannot find DUT by nick '%s'" % nick)

    def is_my_dut(self, k):
        """
        :return: Boolean
        """
        if self._args.my_duts:
            myduts = self._args.my_duts.split(',')
            if str(k) in myduts:
                return True
            return False
        else:
            return True