def create_url_shortcut(self, campaign_url): """ Create a shortcut to open given url :rtype: tuple :return: Status and output log """ try: if os.path.exists(Folders.REPORTS): output_path = os.path.join(Folders.REPORTS, self._report_name + ".html") if not os.path.isfile(output_path): LOGGER_FWK.info("CREATE_URL_SHORTCUT: Creating url shortcut to campaign result") html_content = "<html>\n" html_content += "<head>\n" html_content += "<meta http-equiv=\"refresh\" content=\"0; URL=%s\">\n" % campaign_url html_content += "</head>\n" html_content += "<body></body>\n" html_content += "</html>" with open(output_path, "w") as fd: fd.write(html_content) except Exception as ex: # pylint: disable=W0703 error_msg = "CREATE_URL_SHORTCUT: Fail, " + str(ex) LOGGER_FWK.error(error_msg) return Global.FAILURE, error_msg msg = "CREATE_URL_SHORTCUT: Created link to %s" % str(campaign_url) return Global.SUCCESS, msg
def update_report_file(self): """ Update the xml report file """ try: temp_test_report_file = os.path.join(tempfile.gettempdir(), "Temporary_TestReport.xml") processing_instruction = etree.ProcessingInstruction( "xml-stylesheet", "type=\"text/xsl\" href=\"report.xsl\"") with open(temp_test_report_file, 'w') as f_test_report: f_test_report.write( etree.tostring(processing_instruction, pretty_print=True, xml_declaration=True)) f_test_report.write( etree.tostring(self.document, pretty_print=True)) # Copy the temporary file into the test report shutil.move(temp_test_report_file, self.filename) # copy the XSL file in the same folder ad the XML file shutil.copy(self._xsl_path, self._base) except Exception as report_exception: LOGGER_FWK.warning("Fail to update test report '%s' ! (%s)" % (str(self.filename), str(report_exception)))
def load(self): """ Public method which acts as device configuration loader. :rtype: dict :return: A dict containing all device parameters """ self._load_cli_conf() self._load_bench_conf() self._load_device_conf() # Load the device config from the device catalog if not self.device_conf: _error( "ACS single mode : No device config found for device {0} !". format(self._device_model_name), AcsConfigException.INVALID_PARAMETER) # Override Current DUT parameters from Bench ... self._override_parameters_bench() # ... and CLI self._override_parameters_cli() LOGGER_FWK.info('Checking device model integrity...') # Asserts All Device Model is valid (Parameters) self._validate() return self.device_only_params
def add_folder(zip_file, folder): for root, _, files in os.walk(folder): for f in files: full_path = os.path.abspath(os.path.join(root, f)) path_inside_zip = os.path.relpath(full_path, os.path.abspath(folder)) LOGGER.info('File added: {0} as {1}'.format(full_path, path_inside_zip)) zip_file.write(full_path, path_inside_zip)
def _parse_bench_node(self, node): """ Parses XML `Phone` node(s) from Bench Catalog file and maps it into a python structure (dict) :return: A dict mapping XML configuration :rtype: AttributeDict :raise AcsConfigException.INVALID_BENCH_CONFIG: If a (or more) deprecated parameter(s) is/are found in a Phone node """ LOGGER_FWK.info( 'Loading optional device model parameters from CLI and/or BenchConfig ' 'for {0} ({1})...'.format(self._device_name, self._device_model_name)) buf_params = AttributeDict() # Storing value to avoid recomputing each call device_model_name = self.device_model_name if device_model_name: buf_params["Name"] = device_model_name if self.device_conf_filename: buf_params["DeviceConfigPath"] = self.device_conf_filename # Get phone properties for attrs in node.xpath(".//Parameter"): name, value, description = attrs.get("name"), attrs.get( "value"), attrs.get("description") if name in self.PROHIBITIVE_KEYS: # Do not allow to override internal keys # as it would lead to nasty & unexpected behavior !! continue # Not supported anymore, raise AcsConfigException.INVALID_BENCH_CONFIG !! if name and value: buf_params[name] = value self._bench_conf_deprecated[name] = (value, description) else: buf_params.update(attrs.attrib) # Report Errors if so if self.bench_contains_errors: LOGGER_FWK.error(self._report_errors()) _error( 'Invalid Bench Parameters format found! {0}'.format(', '.join( self._bench_conf_deprecated.keys())), AcsConfigException.INVALID_BENCH_CONFIG) # Extracting device modules if so buf_params.device_modules = self.extract_device_modules(node) return buf_params
def zip_folder(folder, filename): try: filename = filename + '.zip' try: zip_file = zipfile.ZipFile(filename, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) except RuntimeError: # if ZIP_DEFLATED not support, fallback to default zip_file = zipfile.ZipFile(filename, 'w', allowZip64=True) LOGGER.info('Create zip file: {0}'.format(filename)) add_folder(zip_file, folder) LOGGER.info("folder {0} has been properly zipped as {1}".format( folder, filename)) zip_file.close() status = Global.SUCCESS out_file = os.path.abspath(filename) except IOError as error: LOGGER.error('Cannot create zip file: {0} - {1}'.format( filename, error)) status = Global.FAILURE out_file = "" if status == Global.SUCCESS: LOGGER.info("ZIP FILE: {0}".format(out_file)) return status, out_file
def get_config_value(config_dict, config_dict_name, config_name, default_value=None, default_cast_type=str): """ Return the value of the given 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 config_name: string :param config_name: name of the property value to retrieve :type default_value: string :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 """ # Read the config value from dut config dictionary config_value = config_dict.get(config_name, default_value) # In case the config value is not None, trying to cast the value if config_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": config_value = str_to_bool(str(config_value).strip()) elif default_cast_type == "str_to_dict": config_value = str_to_dict(str(config_value).strip()) else: config_value = default_cast_type(config_value) except ValueError: debug_msg = "Wrong value used for dictionary %s entry: '%s'. Returning default value '%s' !" \ % (str(config_dict_name), str(config_name), str(default_value)) LOGGER_FWK.debug(debug_msg) config_value = default_value return config_value
def timezone(): """ Return host timezone :rtype: str :return: Timezone (i.e: 'Europe/Paris') """ # Trying to get local timezone try: import tzlocal host_localtimezone = str(tzlocal.get_localzone()) except Exception as tzlocal_exception: # Set default host time host_localtimezone = DEFAULT_TIMEZONE LOGGER_FWK.warning("Cannot get host timezone ! " "Use default timezone ('{0}') => {1}".format( host_localtimezone, str(tzlocal_exception))) return host_localtimezone
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
def check_keys(dictionary, keys): """ Check if keys are in given dictionary, raise an error if not. :type dictionary: dict :param dictionary: dict to test :type keys: string :param keys: keys to check :rtype: list :return: list of missing keys """ key_list = [] for element in keys: if element not in dictionary: LOGGER_FWK.error("KEY %s missing on your dictionary" % element) key_list.append(element) return key_list
def _override_parameters_bench(self): """ Override device config with device parameters available in bench config if applicable. """ device_model_name = self.device_model_name device_name = self._device_name if self.bench_conf: do_the_override = False if device_name == AcsConstants.DEFAULT_DEVICE_NAME: if "Name" not in self.bench_conf: # No device specified in the bench config for PHONE1 # Do the override then do_the_override = True elif self.bench_conf.Name == device_model_name: # Same device specified on the command line then in the bench config # Do the override do_the_override = True else: warning_msg = ( "Different device model specified on the command line ({0}) " "then in the bench config ({1}) for {2}! Related parameters specified " "in bench config will be ignored !").format( device_model_name, self.bench_conf.Name, AcsConstants.DEFAULT_DEVICE_NAME) LOGGER_FWK.warning(warning_msg) else: # For other phones (PHONE2, ...) we do the override every time do_the_override = True if do_the_override: for key, value in self.bench_conf.iteritems(): if key == "device_modules": for module, module_conf in value.iteritems(): self.device_conf.device_modules[ module] = module_conf else: self._override_through_sections( self.device_conf, key, value, self._bench_unknown_parameters)
def compute_timeout_from_file_size(file_path, min_timeout=0): """ Compute a timeout depending the file's size. :type file_path: str :param file_path: File from which a timeout will be computed :type min_timeout: int :param min_timeout: Minimum timeout (in sec) to set if the file size is too small :rtype: int :return: timeout (in sec) computed from the file size """ if os.path.isfile(file_path): app_size = os.path.getsize(file_path) timeout = int(app_size / 1024 / 4) if timeout < min_timeout: # Set a minimum installation timeout timeout = min_timeout LOGGER_FWK.debug("app size: %dB, timeout: %ds" % (app_size, timeout)) else: timeout = min_timeout return timeout
def create(module_name, device, global_conf): """ Create and return list of device module. :type module_name: str :param module_name: name of the module to be created :type device: py:class:`~acs.Device.Model.IDevice.py` :param module_name: device instance that request the module creation :type global_conf: dict :param global_conf: ACS global configuration :rtype: list of module """ modules = [] if device.config.device_modules and module_name in device.config.device_modules: module_configurations = device.config.device_modules[module_name] if not module_configurations: raise AcsConfigException( "Cannot load \"{0}\" device module".format(module_name), "Cannot find module configuration.") for module_configuration in module_configurations: module = DeviceModuleFactory._instantiate_module( module_name, module_configuration) module.device = device module.logger = logging.getLogger( "%s.%s" % (ACS_LOGGER_NAME, module_name.upper())) module.global_conf = global_conf module.name = module_name module.load_conf() DeviceModuleFactory._update_parameter(module, module_configuration, module_name) LOGGER_FWK.debug("Create Module '{0}' based on : {1}".format( module_name, module_configuration.class_name)) LOGGER_FWK.debug("Module default parameters values are:") for key, value in module.configuration.items(): LOGGER_FWK.debug("\t {0} : {1}".format(key, value)) LOGGER_DEVICE_STATS.info( "Create device_module={0}; device_module_class={1}; device_module_conf={2}" .format(module_name, module_configuration.class_name, module_configuration.config)) modules.append(module) return modules