def parse_catalog_file(self, catalog_file):
        """
        Parse catalog and validate regarding loaded xml schema (if any)
        Return it as a dictionary

        :type catalog_file: string
        :param catalog_file: Catalog file to parse

        :rtype: dict
        :return: Dictionary containing catalog elements
        """
        parameter_dictionary = {}
        # Validate and parse the xml file
        parameter_catalog_etree = self.validate_catalog_file(catalog_file)

        if parameter_catalog_etree:
            for parameter_node in parameter_catalog_etree.getroot():
                # Get the parameter name
                if PARAMETER_NAME_TAG in parameter_node.attrib:
                    parameter_name = parameter_node.attrib[PARAMETER_NAME_TAG]
                    parameter_dictionary[parameter_name] = {}

                    for parameter_children in parameter_node:
                        # Get all element of the parameter node
                        if OVERRIDE_ATTRIB not in parameter_children.attrib:
                            parameter_dictionary[parameter_name][
                                parameter_children.
                                tag] = parameter_children.text
                        else:
                            parameter_dictionary[parameter_name][parameter_children.tag] = \
                                (str_to_bool(parameter_children.attrib[OVERRIDE_ATTRIB]), parameter_children.text)
        return parameter_dictionary
Exemple #2
0
    def get_value(self, key, default_value=None, default_cast_type=str):
        """
        Return the value of the given device config name
        The type of the value can be checked before assignment
        A default value can be given in case the config name does not exist

        :type key: string
        :param key: name of the property value to retrieve

        :type default_value: object
        :param default_value: default_value of the property

        :type default_cast_type: type object
        :param default_cast_type: type to cast (int, str, list ...)
        By default cast into str type.

        :rtype: string or type of default_cast_type
        :return: config value
        """
        value = self.get(key, default_value)

        # In case the config value is not None, trying to cast the value
        if value is not None:
            # Cast the value to the given type
            # Stripping is done to suppress end and start spaces of values
            try:
                if default_cast_type == "str_to_bool":
                    value = str_to_bool(str(value).strip())
                elif default_cast_type == "str_to_dict":
                    value = str_to_dict(str(value))
                else:
                    value = default_cast_type(value)
            except ValueError:
                LOGGER_FWK.debug(
                    "Cannot convert {0} to {1}, return {2}".format(
                        key, default_cast_type, default_value))
                value = default_value

        # Store new value
        # TODO: do not store the value for now because of side effects, need to see if it's expected behavior
        # self[key] = value
        return value
Exemple #3
0
    def __init__(self, device):
        """
        Constructor

        :type  device: object
        :param device: instance of the device
        """

        self._dut_instance = device
        self._current_time = datetime.now().strftime("%Y-%m-%d_%Hh%M.%S")

        # Device general parameters
        self._wait_btwn_cmd = self._dut_instance.get_config(
            "waitBetweenCmd", 5, float)
        self._uecmd_default_timeout = self._dut_instance.get_config(
            "defaultTimeout", 50, int)

        # This option will force to retrieve all embedded logs, to be sure to have crash logs, ap logs ...
        # on critical failures
        retrieve_device_log_on_critical = self._dut_instance.get_config(
            "retrieveDeviceLogOnCriticalFailure", "False", "str_to_bool")

        # Application log parameters
        self._application_log_enable = self._dut_instance.get_config(
            "retrieveApplicationLog", "True",
            "str_to_bool") or retrieve_device_log_on_critical

        device_name = self._dut_instance.whoami().get("device", "")
        if not device_name:
            error_msg = "Device name cannot be found from device instance!"
            raise AcsConfigException(AcsConfigException.INSTANTIATION_ERROR,
                                     error_msg)
        report_tree = self._dut_instance.get_report_tree()
        # Create everything application logging requires only if required
        if self._application_log_enable:
            self._clean_application_logs = self._dut_instance.get_config(
                "cleanApplicationLog", "True",
                "str_to_bool") or retrieve_device_log_on_critical
            self._application_log_options = self._dut_instance.get_config(
                "applicationLogOptions",
                "pull_timer:60,aplog_pull_timeout:60,log_location:/logs",
                "str_to_dict")
            self._application_log_folder = report_tree.get_subfolder_path(
                subfolder_name=LOG_SUBFOLDERS[0], device_name=device_name)
            self._aplog_reg_device = re.compile(APLOG_PATTERN_DEVICE)
            self._aplog_reg_host = re.compile(APLOG_PATTERN_HOST)
            self._aplog_group_id = 1
            self.__aplog_timer = None
            self.__is_application_logger_started = False

        # Modem log parameters
        self._modem_log_enable = self._dut_instance.get_config(
            "retrieveModemTrace", "False", "str_to_bool")

        # Create everything modem logging requires only if required
        if self._modem_log_enable:
            self._clean_modem_logs = self._dut_instance.get_config(
                "cleanModemTrace", "False", "str_to_bool")
            self._modem_trace_options = self._dut_instance.get_config(
                "modemTraceOptions",
                "hsi_speed:h,trace_level:2,trace_location:emmc,file_size_option:1,pull_timeout:60",
                "str_to_dict")
            self._modem_log_folder = report_tree.get_subfolder_path(
                subfolder_name=LOG_SUBFOLDERS[1], device_name=device_name)
            self._modem_api = self._dut_instance.get_uecmd("Modem")
            self.__is_modem_logger_started = False

        # PTI log parameters
        self._pti_log_enable = self._dut_instance.get_config(
            "retrievePTITrace", "False", "str_to_bool")

        # Create everything PTI logging requires only if required
        if self._pti_log_enable:
            self._pti_probe = self._dut_instance.get_config("PTIProbe", "FIDO")
            self._pti_cmdline = self._dut_instance.get_config(
                "enableAplogptiCmdLine",
                "adb shell setprop persist.service.aplogpti.enable 1")
            self._pti_log_folder = report_tree.get_subfolder_path(
                subfolder_name=LOG_SUBFOLDERS[2], device_name=device_name)
            self._pti_log = None
            self._pti_log_file = None
            self._total_pti_log = 0
            self.__init_pti_log()

        # UART (Serial) log parameters
        # It is possible to log on several serial port at the same time
        # For each port, the user can decide to listen to it or not:
        # Value of retrieveSerialTrace is an ordered list of booleans separated by ;
        self._serial_log_enable_list = self._dut_instance.get_config(
            "retrieveSerialTrace", "False").replace(" ", "").split(";")
        self._num_of_serial_confs = len(self._serial_log_enable_list)

        # Value of serialPort is an ordered list of string separated by ;
        self._serial_port_list = self._dut_instance.get_config(
            "serialPort", "COM1").replace(" ", "").split(";")
        num_of_serial_port_confs = len(self._serial_port_list)

        # Value of serialBaudRate is an ordered list of integers separated by ;
        self._serial_baudrate_list = self._dut_instance.get_config(
            "serialBaudRate", "115200").replace(" ", "").split(";")
        num_of_serial_baud_rate_confs = len(self._serial_baudrate_list)

        # Value of serialHdwFlowControl is an ordered list of integers separated by ;
        self._serial_hw_flow_control_list = self._dut_instance.get_config(
            "serialHdwFlowControl", "False").replace(" ", "").split(";")
        num_of_serial_hw_control_confs = len(self._serial_hw_flow_control_list)

        # Check that confs are complete, no element are missing
        if not all(x == self._num_of_serial_confs
                   for x in (num_of_serial_port_confs,
                             num_of_serial_baud_rate_confs,
                             num_of_serial_hw_control_confs)):
            raise AcsConfigException(AcsConfigException.INVALID_BENCH_CONFIG,
                                     "Missing serial log information")

        # Create everything serial (UART) logging requires only if required, for all ports
        conf_id = 0
        self._serial_confs = {}
        is_serial_conf_enable = False

        # Add all serial configuration to a same dictionary
        while conf_id < self._num_of_serial_confs:
            self._serial_confs[(ENABLE + str(conf_id))] = str_to_bool(
                self._serial_log_enable_list[conf_id])

            if self._serial_confs[(ENABLE + str(conf_id))]:
                is_serial_conf_enable = True

                if self._serial_port_list[conf_id] is not "":
                    self._serial_confs[
                        PORT + str(conf_id)] = self._serial_port_list[conf_id]
                else:
                    self._serial_confs[PORT + str(conf_id)] = "COM1"

                if self._serial_baudrate_list[conf_id].isdigit():
                    self._serial_confs[BAUDRATE + str(conf_id)] = int(
                        self._serial_baudrate_list[conf_id])
                else:
                    self._serial_confs[BAUDRATE + str(conf_id)] = 115200

                self._serial_confs[HWCTRLFLOW + str(conf_id)] = str_to_bool(
                    self._serial_hw_flow_control_list[conf_id])
            conf_id += 1

        # Create folder for SERIAL only if required
        if is_serial_conf_enable:
            self._serial_log_folder = report_tree.get_subfolder_path(
                subfolder_name=LOG_SUBFOLDERS[3], device_name=device_name)
            self.__init_serial_log()

        # Callback dictionary
        self.__start_log = {
            "MODEM": self.__start_modem_log,
            "APPLICATION": self.__start_application_log,
            "PTI": self.__start_pti_log,
            "SERIAL": self.__start_serial_log
        }

        self.__stop_log = {
            "MODEM": self.__stop_modem_log,
            "APPLICATION": self.__stop_application_log,
            "PTI": self.__stop_pti_log,
            "SERIAL": self.__stop_serial_log
        }

        self.__retrieve_log = {
            "MODEM": self.__retrieve_modem_log,
            "APPLICATION": self.__retrieve_application_log
        }

        self.__erase_log = {"APPLICATION": self.__erase_application_log}
Exemple #4
0
    def check_pars(self, global_conf):
        """
        Check that test step parameters are compliant with type defined in the Parameter Catalog
        Raise an AcsConfigException in case the parameter is not compliant

        :type global_conf: dict
        :param global_conf: global configuration containing info on usecase catalogs, test step catalogs ...
        """
        teststep_dictionary = self._factory.get_test_step_catalog(global_conf)
        test_step_name = self.get_attr(TestStepConstants.STR_TS_ID.lower())
        if teststep_dictionary is None:
            raise AcsConfigException(AcsConfigException.INSTANTIATION_ERROR,
                                     "TestStep catalog not found and is needed to check test step parameters!")

        if test_step_name and test_step_name in teststep_dictionary:
            for ts_param in teststep_dictionary[test_step_name][TestStepConstants.STR_PARAMETERS]:
                # Lower case is used be Parameters class
                ts_param_name = ts_param.lower()
                ts_param_value = self.get_attr(ts_param_name)
                blank_allow = teststep_dictionary[test_step_name][TestStepConstants.STR_PARAMETERS][ts_param].get(
                    TestStepConstants.STR_PARAM_BLANK)
                if blank_allow is not None:
                    blank_allow = str_to_bool(blank_allow)
                is_optional = teststep_dictionary[test_step_name][TestStepConstants.STR_PARAMETERS][ts_param].get(
                    TestStepConstants.STR_PARAM_IS_OPTIONAL)
                if is_optional is not None:
                    is_optional = str_to_bool(is_optional)

                # If is_optional, does not raise error if not set, just set value, then continue
                if ts_param_value is None and is_optional:
                    self.__dict__[ts_param_name] = None
                    continue

                # Raise an error in case the parameter is empty
                if ts_param_value is not None and (blank_allow or str(ts_param_value).strip() != ""):
                    # Get the type to cast the parameter
                    ts_param_type = teststep_dictionary[test_step_name][TestStepConstants.STR_PARAMETERS][
                        ts_param].get(TestStepConstants.STR_PARAM_TYPE)
                    # Get the possible values of the parameter
                    ts_possible_values = teststep_dictionary[test_step_name][TestStepConstants.STR_PARAMETERS][
                        ts_param].get(TestStepConstants.STR_PARAM_POSSIBLE_VALUES)

                    # Check if the cast is necessary
                    if str(type(ts_param_value).__name__) != ts_param_type:
                        # Cast the parameter into given type
                        value_to_check = self.__cast_param_type(ts_param, ts_param_value, ts_param_type)
                    else:
                        value_to_check = ts_param_value

                    # Check possible values
                    # Sometimes value_to_check is in fact a list of values (comma or semicolon separated),
                    # hence it's necessary to check each of them.
                    if ts_possible_values:
                        if isinstance(value_to_check, basestring):
                            self._check_multiple_values(ts_param, value_to_check, ts_param_type, ts_possible_values)
                        else:
                            self.__check_possible_values(
                                ts_param, value_to_check, ts_param_type, ts_possible_values)

                    # Update the parameter value
                    self.__dict__[ts_param_name] = value_to_check
                else:
                    raise AcsConfigException(
                        AcsConfigException.INVALID_PARAMETER,
                        "'{0:s}' parameter is mandatory and shall have a non empty value !".format(ts_param))