def __init__(self, tc_name, global_config): """ Constructor """ # Call the LAB_EM_USE_CASE init method EmUsecaseBase.__init__(self, tc_name, global_config) # Read CHARGER_TYPE from TC parameters self.__charger_type = self._tc_parameters.get_param_value( "CHARGER_TYPE", "SDP") # Read load to activate self.__load = self._tc_parameters.get_param_value("LOAD") # Activate Loadmodule instance self.__load_module = LoadModule() # Add list of LOAD to the loadmodule self.__load_module.add_load(self.__load) # get target and initialise measurment self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_UPPER_CURRENT_DRAWN_THAN_CHG_CURRENT", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, self.tcd_to_test) self.__scheduled_timer = 60
def set_up(self): EmUsecaseBase.set_up(self) if self.__load != "NO_LOAD": # Activate Loadmodule instance self.__load_module = LoadModule() # Add list of LOAD to the loadmodule self.__load_module.add_load(self.__load) # Set the brightness mode to manual self.phonesystem_api.set_brightness_mode("manual") time.sleep(2) # set brightness to 100% self.phonesystem_api.set_display_brightness(100) time.sleep(2) # Set screen timeout to 30 minutes self.phonesystem_api.set_screen_timeout(self.__screen_timeout) time.sleep(1) # wake up the board if necessary if not self.phonesystem_api.get_screen_status(): self._io_card.press_power_button(0.3) time.sleep(1) # run a load upon parameter configuration if self.__load != "NO_LOAD": # start HIGH LOAD self.__load_module.start_load() time.sleep(10) return Global.SUCCESS, "No errors"
def __init__(self, tc_name, global_config): EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # get the tc parameters self.__tested_capacity = self._tc_parameters.get_param_value( "TESTED_CAPACITY", default_cast_type=int) self.__charger = self._tc_parameters.get_param_value("CHARGER") self.__load = self._tc_parameters.get_param_value("LOAD") self.__jump_allowed = self._tc_parameters.get_param_value( "JUMP_ALLOWED", default_cast_type=float) self.__time_to_log = self._tc_parameters.get_param_value( "PLUG_DURATION", default_cast_type=int) # vars self.__time_to_charge = 60 self.__time_to_discharge = 60 self.__reports_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") # create a report file self.__em_meas_tab = XMLMeasurementFile(self.__reports_file_name) # Activate Loadmodule instance self.__load_module = LoadModule() self.__load_module.add_load(self.__load)
def __init__(self, tc_name, global_config): EmUsecaseBase.__init__(self, tc_name, global_config) # get base module self.em_core_module = UcBatteryModule(self) # get the tc parameters self.__tested_capacity = self._tc_parameters.get_param_value( "TESTED_CAPACITY", default_cast_type=int) self.__charger = self._tc_parameters.get_param_value("CHARGER") self.__status = self._tc_parameters.get_param_value("STATUS").upper() self.__load = self._tc_parameters.get_param_value("LOAD") # vars self.__time_to_charge = 60 self.__time_to_discharge = 60 self.__reports_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__time_to_log = 60 # create a report file self.__report_file_handler = XMLMeasurementFile( self.__reports_file_name) # Activate Loadmodule instance self.__load_module = LoadModule() self.__load_module.add_load(self.__load) # delay to launch autologger self.__autolog_delay = 20
def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() self.__raw_behavior = str( self._tc_parameters.get_param_value("CYCLE_BEHAVIOR")).upper() load = self._tc_parameters.get_param_value("LOAD") self.__charger_type = self._tc_parameters.get_param_value( "CHARGER_TYPE") # Load Module Initialization self.__load_module = LoadModule() self.__load_module.add_load(load) # Initialize EM xml object # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) # track the case where DUT is lost to gather em info later self.__fail_to_get_em_info = False
def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # Read the battery capacity expected for the init of the test self.__high_load_timeout = self._tc_parameters.get_param_value("HIGH_LOAD_DISCHARGE_TIME", default_cast_type=int) self.__light_load_timeout = self._tc_parameters.get_param_value("LIGHT_LOAD_DISCHARGE_TIME", default_cast_type=int) self.__light_load = self._tc_parameters.get_param_value("LIGHT_LOAD", "") self.__high_load = self._tc_parameters.get_param_value("HIGH_LOAD") self.__load_module = LoadModule() self.__load_module.add_load(self.__light_load) self.__load_module.add_load(self.__high_load) #----------------------------------------------------------------------- # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_BATT_CRIT_THRESHOLD_ADAPTED", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets) # Initialize EM xml object # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name)
def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() setup_load = self._tc_parameters.get_param_value("SETUP_TECHNO", "") self.__cooldown = self._tc_parameters.get_param_value("SETUP_TIME_COOLDOWN_BOARD", 120, default_cast_type=int) self.__start_temp = self._tc_parameters.get_param_value("SETUP_START_TEMPERATURE", 30, default_cast_type=int) self.__temp_target = self._tc_parameters.get_param_value("TARGET_MAX_TEMPERATURE", default_cast_type=int) self.__benchmark_module = BenchmarkModule() self.__load_module = LoadModule() self.__load_module.add_load(setup_load) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "temperature_report.xml") self.__temp_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "benchmark_score_report.xml") self.__benchamrk_tab = XMLMeasurementFile(meas_file_name) self.__temp_camera = self._em.get_thermal_camera("THERMAL_CAMERA") self.__pic_folder = self._saving_directory self.__ref_temp = None self.__host_test_start_time = None self.__bk_delay = 30
def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() setup_load = self._tc_parameters.get_param_value("SETUP_TECHNO", "") self.__record_duration = self._tc_parameters.get_param_value("VIDEO_RECORD_DURATION", 120, default_cast_type=int) self.__cooldown = self._tc_parameters.get_param_value("SETUP_TIME_COOLDOWN_BOARD", 120, default_cast_type=int) self.__start_temp = self._tc_parameters.get_param_value("SETUP_START_TEMPERATURE", 30, default_cast_type=int) self.__host_media = self._tc_parameters.get_param_value("MEDIA_TO_RECORD", "", default_cast_type=str) self.__host_monitor = self._tc_parameters.get_param_value("MONITOR_ON_WHICH_MEDIA_IS_PLAY", -1, default_cast_type=int) self.__temp_target = self._tc_parameters.get_param_value("TARGET_MAX_TEMPERATURE", default_cast_type=int) # load targets in order to measure iteration self.__video_capture_mod = VideoCaptureModule() self.__load_module = LoadModule() self.__load_module.add_load(setup_load) self.__video_record_api = self._device.get_uecmd("VideoRecorder", True) self.__media_player = None if self.__host_media != "": self.__media_player = MediaPlayer() # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "temperature_report.xml") self.__temp_meas_tab = XMLMeasurementFile(meas_file_name) self.__temp_camera = self._em.get_thermal_camera("THERMAL_CAMERA") self.__pic_folder = self._saving_directory self.__ref_temp = None
def __init__(self, tc_name, global_config): EmUsecaseBase.__init__(self, tc_name, global_config) # get parameters self.__charger_to_use = self._tc_parameters.get_param_value("CHARGER") self.__load = self._tc_parameters.get_param_value("LOAD") self.__time_to_charge_full = self._tc_parameters.get_param_value( "TIME_TO_FULL", default_cast_type=int) self.__exit_maint_threshold = self._tc_parameters.get_param_value( "EXIT_MAINTENANCE_CHARGING_THRESHOLD", default_cast_type=float) self.__time_to_stabilize_board = self._tc_parameters.get_param_value( "TIME_TO_STABILIZE_BOARD", default_cast_type=int) self.__test_type = str( self._tc_parameters.get_param_value("TEST_TYPE")).upper() self.__test_timeout = self._tc_parameters.get_param_value( "TEST_TIMEOUT", default_cast_type=int) # create a report file to save all charge/discharge value for debug self.__report_file_handler = XMLMeasurementFile( os.path.join(self._saving_directory, "em_meas_report.xml")) # instance of load module self.__load_module = LoadModule() self.__load_module.add_load(self.__load) # constant self.__full_status = "FULL" self.__charging_status = "CHARGING"
def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # misc parameter self.__battery_critical_threshold = self._tc_parameters.get_param_value( "BATTERY_CRITICAL_THRESHOLD", default_cast_type=int) load_to_apply_in_setup = self._tc_parameters.get_param_value( "LOAD_DURING_DISCHARGE", "") # call parameter self.__call_timeout = self._tc_parameters.get_param_value( "CALL_HOLD_TIME", default_cast_type=int) self.__hands_free_activation = self._tc_parameters.get_param_value( "HANDS_FREE_ACTIVATION", default_cast_type="str_to_bool") self.__fake_emergency_phone_number = self._tc_parameters.get_param_value( "PHONE_NUMBER", "012345") call_type = self._tc_parameters.get_param_value("CALL_TYPE") # Summarize the parameters self._logger.info("[TESTCASE]\tBattery Critical Threshold: %s%%" % self.__battery_critical_threshold) self._logger.info("[TESTCASE]\tEmergency Phone Number : %s" % self.__fake_emergency_phone_number) self._logger.info( "[TESTCASE]\tthe holding time of the call when battery reach critical level: %ss" % self.__call_timeout) self._logger.info("[TESTCASE]\tType of the call : %s" % call_type) self._logger.info("[TESTCASE]\tActivation of Hands Free : %s" % self.__hands_free_activation) # Initial Emergency Number if call_type == "3G": # Initialization of module 3g self.__telmodule = TelephonyModule3g() elif call_type == "2G": # Initialization of module 3g self.__telmodule = TelephonyModule2g() else: txt = "Type of the call is not correct => Quit the test" self._logger.error(txt) raise AcsConfigException(AcsConfigException.INVALID_PARAMETER, txt) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) # Store the initial list of emergency number from UECmdTypes self.__initial_ue_command_em_number = UECmdTypes.EMERGENCY_NUMBERS_LIST # init load module used to discharge board self.__load_module = LoadModule() self.__load_module.add_load(load_to_apply_in_setup) self.__initial_emergency_numbers = None self.__original_airplane_state = None
def __init__(self, tc_name, global_config): """ Constructor """ # Call the LabEmBaseCommon Init function EmUsecaseBase.__init__(self, tc_name, global_config) # pylint: disable=W0233 load_off = self._tc_parameters.get_param_value("LOAD_OFF", "") self.__load_module = LoadModule() self.__load_module.add_load(load_off)
def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() self.__zone_to_inspect = str( self._tc_parameters.get_param_value("THERMAL_ZONE_TO_MONITOR", "ANY")).upper().strip() self.__record_duration = self._tc_parameters.get_param_value( "VIDEO_RECORD_DURATION", 120, default_cast_type=int) self.__host_media = self._tc_parameters.get_param_value( "MEDIA_TO_RECORD", "", default_cast_type=str) self.__host_monitor = self._tc_parameters.get_param_value( "MONITOR_ON_WHICH_MEDIA_IS_PLAY", -1, default_cast_type=int) setup_load = self._tc_parameters.get_param_value("SETUP_TECHNO", "") self.__start_temp = self._tc_parameters.get_param_value( "SETUP_START_TEMPERATURE", 30, default_cast_type=int) self.__cooldown = self._tc_parameters.get_param_value( "SETUP_TIME_COOLDOWN_BOARD", 120, default_cast_type=int) use_camera_to_cooldown = self._tc_parameters.get_param_value( "SETUP_COOLDOWN_WITH_CAMERA", False, default_cast_type=str_to_bool) self.__temp_camera = None if use_camera_to_cooldown: self.__temp_camera = self._em.get_thermal_camera("THERMAL_CAMERA") # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_COOLING_ACTION_VIDEO_CAPTURE", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, consider_all_target=True) self.__video_capture_mod = VideoCaptureModule() self.__parser_api = self._device.get_uecmd("Aplog", True) self.__load_module = LoadModule() self.__load_module.add_load(setup_load) self.__video_record_api = self._device.get_uecmd("VideoRecorder", True) self.__media_player = None if self.__host_media != "": self.__media_player = MediaPlayer() # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) self.__ref_temp = None self.__pic_folder = self._saving_directory meas_file_name = os.path.join(self._saving_directory, "temperature_report.xml") self.__temp_meas_tab = XMLMeasurementFile(meas_file_name)
def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # High load load = self._tc_parameters.get_param_value("LOAD") self.__charger_type = self._tc_parameters.get_param_value("CHARGER_TYPE") self.__timeout_dut_adjust_charging_param = self._tc_parameters.get_param_value("TIME_TO_LET_DUT_ADJUST_CHARGING_PARAM", default_cast_type=int) self.__timeout_dut_adapt_temp = self._tc_parameters.get_param_value("TIME_TO_LET_DUT_ADAPT_TO_TEST_TEMP", 3600, default_cast_type=int) # Read TEMPERATURE from test case xml file self.tc_module = None self.__max_temperature = self._tc_parameters.get_param_value("MAX_TEMPERATURE") self.__min_temperature = self._tc_parameters.get_param_value("MIN_TEMPERATURE") if "ROOM" not in [self.__min_temperature, self.__max_temperature]: # get temperature chamber equipment if not room temperature self.__max_temperature = int(self.__max_temperature) self.__min_temperature = int(self.__min_temperature) self.tc_module = ThermalChamberModule(self._ambient_temperature) # inform module that this is not a default thermal test self.tc_module.set_test_type("SPECIFIC") self.__temperature = int((self.__min_temperature + self.__max_temperature) / 2) else: self.__temperature = "ROOM" # Summarize the parameters self._logger.info("Type of the charger: %s" % self.__charger_type) self._logger.info("Test MAX temperature: %s" % self.__max_temperature) self._logger.info("Test MIN temperature: %s" % self.__min_temperature) self._logger.info("Load to use during test: %s" % load) self._logger.info("Time to see change on DUT behavior at tested temperature: %s" % self.__timeout_dut_adjust_charging_param) # Load Module Initialization self.__load_module = LoadModule() self.__load_module.add_load(load) # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_ADJUST_CHARGING_PARAM_WITH_MAINT", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # get target and initialize measurement self._em_meas_verdict.load_target(self._em_targets, self.tcd_to_test) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) self.__charger_is_data_cable = None
def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() self.__zone_to_inspect = str( self._tc_parameters.get_param_value("THERMAL_ZONE_TO_MONITOR", "ANY")).upper().strip() setup_load = self._tc_parameters.get_param_value("SETUP_TECHNO", "") self.__cooldown = self._tc_parameters.get_param_value( "SETUP_TIME_COOLDOWN_BOARD", 1800, default_cast_type=int) self.__start_temp = self._tc_parameters.get_param_value( "SETUP_START_TEMPERATURE", 30, default_cast_type=int) use_camera_to_cooldown = self._tc_parameters.get_param_value( "SETUP_COOLDOWN_WITH_CAMERA", False, default_cast_type=str_to_bool) self.__temp_camera = None if use_camera_to_cooldown: self.__temp_camera = self._em.get_thermal_camera("THERMAL_CAMERA") self.__benchmark_module = BenchmarkModule() self.__load_module = LoadModule() self.__load_module.add_load(setup_load) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "temperature_report.xml") self.__temp_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "benchmark_score_report.xml") self.__benchamrk_tab = XMLMeasurementFile(meas_file_name) self.__ref_temp = None self.__pic_folder = self._saving_directory self.__host_test_start_time = None self.__bk_delay = 30 self.__parser_api = self._device.get_uecmd("Aplog", True) # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_COOLING_ACTION_BENCHMARK", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, consider_all_target=True)
def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # Type of the charger self.__charger_type = self._tc_parameters.get_param_value( "CHARGER_TYPE") self.__load = self._tc_parameters.get_param_value( "LOAD_TO_HELP_DISCHARGE_IN_SETUP") # charge to Full Timeout self.__charge_full_timeout = self._tc_parameters.get_param_value( "CHARGE_TO_FULL_DURATION", default_cast_type=int) # capacity that match with first full self.__first_full_capacity = self._tc_parameters.get_param_value( "CAPACITY_AT_WHICH_FULL_FIRST_APPEAR", 100, default_cast_type=int) self.__what_to_check = str( self._tc_parameters.get_param_value("WHAT_TO_CHECK")).upper() # Summarize the parameters self._logger.info("Charger type to plug during FULL charging: %s" % self.__charger_type) self._logger.info("Capacity at which FULL shall first appear: %d" % self.__first_full_capacity) self._logger.info("Test expected start capacity : %s" % self.em_core_module.batt_start_capacity) # Load Module Initialization self.__load_module = LoadModule() self.__load_module.add_load(self.__load) # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_BATT_FULL_IDENTIFICATION", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, consider_all_target=True) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name)
class LabEmInitBoard(EmUsecaseBase): """ Lab Energy Management class. """ # This is the default bench type where this test can be run DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call the LabEmBaseCommon Init function EmUsecaseBase.__init__(self, tc_name, global_config) # pylint: disable=W0233 load_off = self._tc_parameters.get_param_value("LOAD_OFF", "") self.__load_module = LoadModule() self.__load_module.add_load(load_off) def set_up(self): """ Initialize the test """ EmUsecaseBase.set_up(self) return Global.SUCCESS, "No errors" def run_test_body(self): """ Execute the test """ EmUsecaseBase.run_test_body(self) # compare values with targets self.__load_module.stop_load() self.em_api.clean_autolog() self.em_api.clean_daemon_files() return Global.SUCCESS, "No errors" def tear_down(self): """ End and dispose the test """ EmUsecaseBase.tear_down(self) return Global.SUCCESS, "No errors"
def __init__(self, tc_name, global_config): """ Constructor """ # Call the LAB_EM_USE_CASE init method EmUsecaseBase.__init__(self, tc_name, global_config) # Read load to activate self.__load = self._tc_parameters.get_param_value("LOAD") # Read the critical treshold self.__critical_threshold = self._tc_parameters.get_param_value( "CRITICAL_THRESHOLD", default_cast_type=float) # Read the accuracy for crtical threshold self.__accuracy = self._tc_parameters.get_param_value( "ACCURACY", default_cast_type=float) # Calculate the real threshold self.__calculateThreshold = self.__critical_threshold * ( 1.0 - self.__accuracy / 100) # Activate Loadmodule instance self.__load_module = LoadModule() # Add list of LOAD to the loadmodule self.__load_module.add_load(self.__load) self.em_core_module.io_card_init_state[ "BatteryType"] = self.phone_info["BATTERY"]["BATTID_TYPE"] # - Battery self.em_core_module.io_card_init_state["Battery"] = True # - Platform self.em_core_module.io_card_init_state["Platform"] = "ON" self.em_core_module.io_card_init_state[ "USBChargerType"] = self._io_card.USB_HOST_PC self.em_core_module.io_card_init_state["USBCharger"] = True # get target and initialise measurements self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_REPORT_CRITICAL_BATT_ON_VBATT_THRESHOLD", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets) # charger to use self.__charger_type = "SDP" self.em_core_module.eqp_init_state["BATT"][ "VoltageLevel"] = self.em_core_module.vbatt
def __init__(self, tc_name, global_config): EmUsecaseBase.__init__(self, tc_name, global_config) # get the tc parameters self.__min_range = self._tc_parameters.get_param_value( "MIN_RANGE", default_cast_type=int) self.__max_range = self._tc_parameters.get_param_value( "MAX_RANGE", default_cast_type=int) self.__charging_timeout = self._tc_parameters.get_param_value( "CHARGING_TIMEOUT", default_cast_type=int) self.__discharging_timeout = self._tc_parameters.get_param_value( "DISCHARGING_TIMEOUT", default_cast_type=int) self.__polling_delay = self._tc_parameters.get_param_value( "DATA_POLLING_DELAY", default_cast_type=int) self.__load = self._tc_parameters.get_param_value("LOAD") self.__target = str( self._tc_parameters.get_param_value("TARGET")).lower() self.__crit_batt_voltage = self._tc_parameters.get_param_value( "CRIT_VBATT_VOLTAGE", default_cast_type=float) self.__full_voltage_th = self._tc_parameters.get_param_value( "FULL_VOLTAGE_THRESHOLD", default_cast_type=float) self.__full_volt_offset = self._tc_parameters.get_param_value( "FULL_VOLTAGE_OFFSET", default_cast_type=float) self._critt_batt_offset = self._tc_parameters.get_param_value( "CRIT_VBATT_OFFSET", default_cast_type=float) # vars self.__time_to_charge = 500 self.__time_to_discharge = 500 self.__reports_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") # create a report file self.__report_file_handler = XMLMeasurementFile( self.__reports_file_name) # Activate Loadmodule instance self.__load_module = LoadModule() self.__load_module.add_load(self.__load)
def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # Read the battery capacity expected for the init of the test self.__discharge_timeout = self._tc_parameters.get_param_value( "DISCHARGE_TIMEOUT", default_cast_type=int) self.__cable_type = self._tc_parameters.get_param_value( "CABLE_TYPE_DURING_DISCHARGE") load_to_apply_in_setup = self._tc_parameters.get_param_value( "LOAD_TO_HELP_DISCHARGE") #----------------------------------------------------------------------- # Get load Parameters self.__load_module = LoadModule() self.__load_module.add_load(load_to_apply_in_setup) #----------------------------------------------------------------------- # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_BATT_LOW_CAP_SHUTDOWN", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, self.tcd_to_test) # Initialize EM measurement file xml object meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) self.__charger_is_data_cable = None self.__parser_api = self._device.get_uecmd("Aplog", True)
class LabEmTempMonitorVideoCapture(EmUsecaseBase): """ Class Lab temperature during Video Capture """ DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() setup_load = self._tc_parameters.get_param_value("SETUP_TECHNO", "") self.__record_duration = self._tc_parameters.get_param_value("VIDEO_RECORD_DURATION", 120, default_cast_type=int) self.__cooldown = self._tc_parameters.get_param_value("SETUP_TIME_COOLDOWN_BOARD", 120, default_cast_type=int) self.__start_temp = self._tc_parameters.get_param_value("SETUP_START_TEMPERATURE", 30, default_cast_type=int) self.__host_media = self._tc_parameters.get_param_value("MEDIA_TO_RECORD", "", default_cast_type=str) self.__host_monitor = self._tc_parameters.get_param_value("MONITOR_ON_WHICH_MEDIA_IS_PLAY", -1, default_cast_type=int) self.__temp_target = self._tc_parameters.get_param_value("TARGET_MAX_TEMPERATURE", default_cast_type=int) # load targets in order to measure iteration self.__video_capture_mod = VideoCaptureModule() self.__load_module = LoadModule() self.__load_module.add_load(setup_load) self.__video_record_api = self._device.get_uecmd("VideoRecorder", True) self.__media_player = None if self.__host_media != "": self.__media_player = MediaPlayer() # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "temperature_report.xml") self.__temp_meas_tab = XMLMeasurementFile(meas_file_name) self.__temp_camera = self._em.get_thermal_camera("THERMAL_CAMERA") self.__pic_folder = self._saving_directory self.__ref_temp = None #------------------------------------------------------------------------------ def set_up(self): """ Initialize the test """ # Call LabPwrMeasBase base Setup function EmUsecaseBase.set_up(self) # reset the ref value self.__ref_temp = None # check that media exist if self.__media_player is None: self._logger.warning("no media was set to be launched on the HOST side, no media will be play during video capture") else: if not os.path.exists(self.__host_media): error_msg = "The video %s you want to play on the host side does not exist" % self.__host_media self._logger.error(error_msg) raise AcsConfigException(AcsConfigException.FILE_NOT_FOUND, error_msg) # clean video storage self.__video_record_api.clean_video_storage() # init camera connection self.__temp_camera.init() self.__temp_camera.delete_all_pictures() # Update Battery Information em_info = self.update_battery_info() if self.em_core_module.is_batt_capacity_below_target(em_info, self.em_core_module.batt_min_capacity): # charge part self.em_core_module.monitor_charging(self.em_core_module.batt_min_capacity, self.em_core_module.charge_time, self.__em_meas_tab) self.__video_capture_mod.setup() self.phonesystem_api.set_screen_timeout(3600) self._device.switch_off() # remove any cable after this self._io_card.remove_cable("ALL") # do the thermal camera setting during the off phase to let the board cooldown self._setup_camera() # wait a given time to let the board cool down start_temp_seen = False wait_time = self.__cooldown + 15 self._logger.info("waiting at most %ss+15s to let the board cool down below %s degree" % (str(self.__cooldown), str(self.__start_temp))) start_time = time.time() while time.time() - start_time < wait_time: cam_meas = self.__temp_camera.get_measurement_from_box() try: self.__temp_meas_tab.add_dict_measurement(cam_meas) self.__temp_meas_tab.add_measurement([self.get_time_tuple(), (self._em_cst.COMMENTS, "Setup: cooling down the board")]) self.__temp_meas_tab.switch_to_next_meas() except Exception as e: msg = "error happen when filling temperature value in file: %s" % str(e) self._logger.error(msg) if cam_meas["MAXT"][0] <= self.__start_temp: self._logger.info("the MAX temperature seen is %s, test can continue " % str(cam_meas["MAXT"])) # take a ref picture pic_path = self.__temp_camera.take_picture("ref_phone_off") self.__temp_camera.pull_picture(pic_path, self.__pic_folder) start_temp_seen = True self.__ref_temp = cam_meas["MAXT"][0] break if not start_temp_seen: cam_meas = self.__temp_camera.get_measurement_from_box() pic_path = self.__temp_camera.take_picture("pic_temp_after_cooldown_fail") self.__temp_camera.pull_picture(pic_path, self.__pic_folder) error_msg = "The board fail to cool down below %s degree after spending %ss in OFF state, the last temperature seen was %s degree" % (self.__start_temp, self.__cooldown, str(cam_meas["MAXT"])) self._logger.error(error_msg) self._device.switch_on() raise DeviceException(DeviceException.INVALID_DEVICE_STATE, error_msg) # turn on board and launch every load self._device.switch_on() self.em_api.get_thermal_sensor_info() # start all environment load self.__load_module.start_load() # start HOST Video if not self.__media_player is None: self.__media_player.play(self.__host_media, self.__host_monitor) # media may take time to start start_time = time.time() while time.time() - start_time < 10: time.sleep(1) if self.__media_player.is_playing(): break if not self.__media_player.is_playing(): error_msg = "Fail to start the video playback on the HOST side" self._logger.error(error_msg) raise AcsBaseException(AcsBaseException.OPERATION_FAILED, error_msg) # collect a ref temperature before starting the test once board is on cam_meas = self.__temp_camera.get_measurement_from_box() self.__temp_meas_tab.add_dict_measurement(cam_meas) self.__temp_meas_tab.add_measurement([self.get_time_tuple(), (self._em_cst.COMMENTS, "Setup: Temperature just before starting the test")]) self.__temp_meas_tab.switch_to_next_meas() # start video recording self.phonesystem_api.wake_screen() self.phonesystem_api.set_phone_lock(False) raw_video_filename, _ = self.__video_capture_mod.start_recording() # Check if the video file exist if not self.__video_record_api.check_video_exist(raw_video_filename): self._logger.error("Recording fail to start, retry again") raw_video_filename, _ = self.__video_capture_mod.start_recording() # Check if the video file exist if not self.__video_record_api.check_video_exist(raw_video_filename): screen_path = self._device.screenshot(filename=os.path.join(self.__pic_folder, "camera_record_fail.png")) error_msg = "Fail to see the raw video file generated during the record, it seems that the video record may has not started." if screen_path is not None: error_msg += "\nPlease check the screenshot at %s." % screen_path self._logger.error(error_msg) raise DeviceException(DeviceException.FILE_SYSTEM_ERROR, error_msg) return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def run_test_body(self): """ run test """ EmUsecaseBase.run_test_body(self) # remove any cable self._device.disconnect_board() self._io_card.remove_cable("ALL") self._logger.info("Monitoring temperature during %ss " % str(self.__record_duration)) # do the monitoring job maxt = self.__temp_camera.get_measurement_from_box()["MAXT"] last_max_temp_seen = maxt[0] unit = maxt[1] pic_path = None start_time = time.time() while time.time() - start_time < self.__record_duration: # we want to monitor and see the highest temperature seen by the board cam_meas = self.__temp_camera.get_measurement_from_box() max_temp = cam_meas["MAXT"][0] if max_temp > last_max_temp_seen: # save a picture of each highest temperature seen pic_path = self.__temp_camera.take_picture("max_during_record") last_max_temp_seen = max_temp try: self.__temp_meas_tab.add_dict_measurement(cam_meas) self.__temp_meas_tab.add_measurement([self.get_time_tuple(), (self._em_cst.COMMENTS, "Runtest: video record ongoing")]) self.__temp_meas_tab.switch_to_next_meas() except Exception as e: msg = "error happen when filling temperature value in file: %s" % str(e) self._logger.error(msg) # reconnect usb cable self._io_card.usb_host_pc_connector(True) if pic_path is not None: self.__temp_camera.pull_picture(pic_path, self.__pic_folder) time.sleep(self.usb_sleep) self._device.connect_board() # check if board did not went off during the test boot_mode = self._device.get_boot_mode() if boot_mode != "MOS": error_msg = "The board is seen not booted in MOS but in %s at the end of the test , cant compute result" % (boot_mode) self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # get a proof that video was still running self._device.screenshot(filename=os.path.join(self.__pic_folder, "test_end_board_screen.png")) self.__video_capture_mod.stop_recording() # stop HOST Video if not self.__media_player is None: self.__media_player.stop() verdict = Global.FAILURE msg = "The ref temperature when board is OFF was at %s %s.\n" % (self.__ref_temp, unit) msg += "The max temperature seen on the DUT during %ss of video recording is %s %s" % (self.__record_duration, last_max_temp_seen, unit) if last_max_temp_seen > self.__temp_target : msg += " which is above" else: msg += " which is below or equal to" verdict = Global.SUCCESS msg += " the target not to exceed : %s degree" % (self.__temp_target) self._logger.info(msg) return verdict, msg def tear_down(self): """ End and dispose the test """ EmUsecaseBase.tear_down(self) try: self.__temp_camera.set_linear_temperature_mode(False) self.__temp_camera.delete_all_pictures() except Exception as e: self._logger.error("error happen when releasing thermal camera %s" % str(e)) finally: self.__temp_camera.release() if not self.__media_player is None: self.__media_player.stop() # stop all load self.em_core_module.clean_up() self.__load_module.stop_load() # stop any remaining video capture self.__video_record_api.force_stop() self.__video_record_api.restore_camera_setup() self.__video_record_api.clean_video_storage() return Global.SUCCESS, "No errors" def _setup_camera(self): """ setup the camera """ self.__temp_camera.auto_setup() x, y, h, w = self.__temp_camera.get_image_geometry() self.__temp_camera.set_linear_temperature_mode(True) self.__temp_camera.configure_measurement_box(True, x, y, h, w)
class LabEmTurnOffDisplay(EmUsecaseBase): """ Lab Energy Management class. """ DEDICATED_BENCH = "POWER_SUPPLY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # Read STABILIZATION_TIME from TC parameters self.__stabilization_time = int( self._tc_parameters.get_param_value("STABILIZATION_TIME")) # prepare LOAD self.__load = self._tc_parameters.get_param_value("LOAD", "NO_LOAD") self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_TURN_OFF_DISPLAY", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, self.tcd_to_test) # Measure current from Vbatt self._pwrs = self._em.get_power_supply("BATT") self.__load_module = None self.__screen_timeout = 60 * 60 #------------------------------------------------------------------------------ def set_up(self): EmUsecaseBase.set_up(self) if self.__load != "NO_LOAD": # Activate Loadmodule instance self.__load_module = LoadModule() # Add list of LOAD to the loadmodule self.__load_module.add_load(self.__load) # Set the brightness mode to manual self.phonesystem_api.set_brightness_mode("manual") time.sleep(2) # set brightness to 100% self.phonesystem_api.set_display_brightness(100) time.sleep(2) # Set screen timeout to 30 minutes self.phonesystem_api.set_screen_timeout(self.__screen_timeout) time.sleep(1) # wake up the board if necessary if not self.phonesystem_api.get_screen_status(): self._io_card.press_power_button(0.3) time.sleep(1) # run a load upon parameter configuration if self.__load != "NO_LOAD": # start HIGH LOAD self.__load_module.start_load() time.sleep(10) return Global.SUCCESS, "No errors" def run_test_body(self): """ Execute the test """ # Call LAB_EM_BASE Run function EmUsecaseBase.run_test_body(self) # get ibatt with display on ibatt_screen_on = self.em_core_module.get_battery_current() self._logger.info("Screen On : IBatt = %s %s" % (ibatt_screen_on[0], ibatt_screen_on[1])) # switch off the screen by pressing power on button during 0.5 second self._io_card.press_power_button(0.5) # sleep 5 s time.sleep(5) # check_screen status screen_status = self.phonesystem_api.get_screen_status() self._meas_list.add("SCREEN_STATUS", screen_status, "") # now get ibatt value with display off ibatt_screen_off = self.em_core_module.get_battery_current() self._logger.info("Screen Off : IBatt = %s %s" % (ibatt_screen_off[0], ibatt_screen_off[1])) self._meas_list.add( "SAVED_IBATT", (ibatt_screen_on[0] - ibatt_screen_off[0], ibatt_screen_off[1])) # Close connection self._device.disconnect_board() # Remove data cable self._io_card.usb_connector(False) # turn screen off time.sleep(2) self._io_card.press_power_button(0.5) # now just wait x second min and check IBATT value self._logger.info( "Wait %ss in order to stabilize the battery current" % str(self.__stabilization_time)) time.sleep(self.__stabilization_time) # now get ibatt value with display off ibatt_screen_off_after_waiting = self.em_core_module.get_battery_current( ) self._meas_list.add("WAIT_FOR_MIN_IBATT", (ibatt_screen_off_after_waiting[0], ibatt_screen_off_after_waiting[1])) # generate em verdict self._em_meas_verdict.compare_list(self._meas_list, self._em_targets) self._em_meas_verdict.judge() self._meas_list.clean() return self._em_meas_verdict.get_current_result_v2() def tear_down(self): """ End and dispose the test """ # connect usb host cable self._io_card.usb_host_pc_connector(True) # Close connection self._device.connect_board() # stop the laod if it was started if self.__load != "NO_LOAD" and self.is_board_and_acs_ok(): # Stop HIGH LOAD self.__load_module.stop_load() # call the base EmUsecaseBase.tear_down(self) return Global.SUCCESS, "No errors"
class LabEmTestChargingBattTemp(EmUsecaseBase): """ Lab Energy Management class. """ DEDICATED_BENCH = "BATTERY_BENCH" __ACTION = { "CHARGE_RESUME": { "START": "OVERHEAT", "STOP": "GOOD" }, "CHARGE_STOP": { "START": "GOOD", "STOP": "OVERHEAT" } } def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # High load load = self._tc_parameters.get_param_value("SETUP_LOAD") self.__charger_type = self._tc_parameters.get_param_value( "CHARGER_TYPE") self.__timeout_dut_adjust_stop_temp = self._tc_parameters.get_param_value( "TIME_TO_ADJUST_TO_STOP_TEMPERATURE", default_cast_type=int) self.__timeout_dut_adapt_start_temp = self._tc_parameters.get_param_value( "TIME_TO_ADJUST_TO_START_TEMPERATURE", 3600, default_cast_type=int) # Read TEMPERATURE from test case xml file self.tc_module = None self.__start_max_temperature = self._tc_parameters.get_param_value( "START_MAX_TEMPERATURE") self.__start_min_temperature = self._tc_parameters.get_param_value( "START_MIN_TEMPERATURE") self.__stop_temp = self._tc_parameters.get_param_value( "STOP_TEMPERATURE") self.__action_to_peform = str( self._tc_parameters.get_param_value("WHAT_TO_CHECK")).upper() # ROOM is only for debug purpose if "ROOM" not in [ self.__stop_temp, self.__start_max_temperature, self.__start_min_temperature ]: self.__start_max_temperature = int(self.__start_max_temperature) self.__start_min_temperature = int(self.__start_min_temperature) # get temperature chamber equipment if not room temperature self.__stop_temp = int(self.__stop_temp) self.tc_module = ThermalChamberModule(self._ambient_temperature) # inform module that this is not a default thermal test self.__start_temperature = int( (self.__start_min_temperature + self.__start_max_temperature) / 2) self.tc_module.set_test_type("SPECIFIC") else: self.__start_temperature = "ROOM" # Summarize the parameters self._logger.info("Type of the charger: %s" % self.__charger_type) self._logger.info("Test start MAX temperature: %s" % self.__start_max_temperature) self._logger.info("Test start MIN temperature: %s" % self.__start_min_temperature) self._logger.info("Test stop temperature: %s" % self.__stop_temp) self._logger.info("What we want to check: %s" % self.__action_to_peform) self._logger.info( "Time to see change on DUT behavior at tested temperature: %s" % self.__timeout_dut_adjust_stop_temp) # Load Module Initialization self.__load_module = LoadModule() self.__load_module.add_load(load) # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_TEST_CHARGING_BATT_TEMP", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # get target and initialize measurement self._em_meas_verdict.load_target(self._em_targets, self.tcd_to_test) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) self.__charger_is_data_cable = None #------------------------------------------------------------------------------ def set_up(self): """ Initialize the test """ # Call the UseCaseBase Setup function EmUsecaseBase.set_up(self) # Check specific option if they are chosen if self.__charger_type not in self._io_card.SUPPORTED_DEVICE_TYPE: txt = "io card does not support charger type %s " % self.__charger_type self._logger.error(txt) raise AcsConfigException(AcsConfigException.INVALID_PARAMETER, txt) # Update Battery Information em_info = self.update_battery_info() if self.em_core_module.is_batt_capacity_above_target( em_info, self.em_core_module.batt_max_capacity): # Discharge if we are too high self.em_core_module.monitor_discharging( self.em_core_module.batt_max_capacity, self.em_core_module.discharge_time, self.__em_meas_tab, self.__load_module) if self.tc_module is not None: self.tc_module.set_up_eq() self.tc_module.get_eq().set_regulation(True) self.tc_module.get_eq().set_temperature(self.__start_temperature) # set the temperature self.em_api.set_thermal_management(False) # a reboot is required to apply this change self._device.reboot() self.phonesystem_api.set_screen_timeout(3600) # do this job one time in case of B2B if self.__charger_is_data_cable is None: self.__charger_is_data_cable = self.em_core_module.is_host_connection_available_when_charger_plug( self.__charger_type, True) self._logger.info("test sequences will adjust to this") # wait that the board see the test temperature remaining_time = time.time() self.em_core_module.adjust_batt_temp( self.__start_min_temperature, self.__start_max_temperature, self.__timeout_dut_adapt_start_temp, self.tc_module, self.__em_meas_tab) remaining_time = max( self.__timeout_dut_adapt_start_temp - (time.time() - remaining_time), 120) self.__track_battery_health_change(remaining_time) return Global.SUCCESS, "No errors" def __track_battery_health_change(self, test_timeout): """ track a battery health change """ exceed_timeout = True timeout = time.time() + test_timeout crash__alowed = 3 while time.time() < timeout: try: # try to read measurement msic_reg = self.update_battery_info() thermal_conf = self.em_api.get_thermal_sensor_info() # store result on xml self.__em_meas_tab.add_dict_measurement(msic_reg) self.__em_meas_tab.add_dict_measurement(thermal_conf) # temporary workaround to detect the end condition batt_health = str(msic_reg["BATTERY"]["HEALTH"][0]).upper() if self.__ACTION[ self.__action_to_peform]["START"] == batt_health: exceed_timeout = False break except AcsBaseException as e: crash__alowed -= 1 # try to catch why uecmd may fail if not self.is_board_and_acs_ok(): txt = "connection with DUT lost during change waiting on DUT battery health" else: txt = "error happened during change waiting on DUT on DUT battery health: " + str( e) self._logger.error(txt) if crash__alowed <= 0: raise DeviceException(DeviceException.OPERATION_FAILED, txt) finally: # Store various information self.__em_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "SETUP:Waiting for the DUT to modify its battery health inside [%s;%s] degree celsius" % (self.__start_min_temperature, self.__start_max_temperature)) ]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() # exist if we see the expected battery health if exceed_timeout: txt = "timeout exceeded (%ss) to see a change on battery health inside [%s,%s] degree celsius" % ( str(test_timeout), self.__start_min_temperature, self.__start_max_temperature) #------------------------------------------------------------------------------ def run_test_body(self): """ Execute the test """ # Call LAB_EM_BASE Run function EmUsecaseBase.run_test_body(self) if self.__charger_is_data_cable: self.__test_with_data(self.__stop_temp) else: self.__test_without_data(self.__stop_temp) # value comparing are done in private function self._em_meas_verdict.judge() return self._em_meas_verdict.get_current_result_v2() #------------------------------------------------------------------------------ def tear_down(self): """ End and dispose the test """ # call tear down after some operations EmUsecaseBase.tear_down(self) if self.tc_module is not None: # Go to the ambient temperature self.tc_module.release_eq() # clean the board state and retrieve logs self.em_core_module.clean_up() # restore thermal management setting self.em_api.set_thermal_management(True) # a reboot is required to apply this change self._device.reboot() return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def __test_with_data(self, temperature): """ test charging resume or stop while a data cable is plugged """ self._logger.info( "test if %s when we move from [%s;%s] degree celsius to %s degree celsius with an active data connection" % (self.__action_to_peform, self.__start_min_temperature, self.__start_max_temperature, self.__stop_temp)) # when we are here, it means that we are already at START charging temperature condition msic_reg = self.update_battery_info() self._meas_list.add_dict("EM_INFO_START_TEMP", msic_reg) self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, clean_meas_list=True) # change the test temperature if self.tc_module is not None: self.tc_module.get_eq().set_temperature(temperature) # monitor temp until we are outside the start temp test_timeout = self.__timeout_dut_adjust_stop_temp last_batt_temp = self.update_battery_info()["BATTERY"]["TEMP"][0] if self.__start_min_temperature <= last_batt_temp <= self.__start_max_temperature: consumed_time = time.time() self._logger.info( "check that DUT is moving outside START temperature [%s;%s] degree celsius" % (self.__start_min_temperature, self.__start_max_temperature)) exceed_timeout = True timeout = time.time() + test_timeout while time.time() < timeout: try: # try to read measurement msic_reg = self.update_battery_info() thermal_conf = self.em_api.get_thermal_sensor_info() # store result on xml self.__em_meas_tab.add_dict_measurement(msic_reg) self.__em_meas_tab.add_dict_measurement(thermal_conf) last_batt_temp = msic_reg["BATTERY"]["TEMP"][0] except AcsBaseException as e: # try to catch why uecmd may fail if not self.is_board_and_acs_ok(): txt = "connection with DUT lost during temperature change to exit range [%s;%s] degree celsius" % ( self.__start_min_temperature, self.__start_max_temperature) else: txt = "error happened during temperature change to exit range [%s;%s] degree celsius : %s" % ( self.__start_min_temperature, self.__start_max_temperature, str(e)) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) finally: # Store various information self.__em_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "RUNTEST:Waiting for the DUT to move outside [%s;%s] degree celsius" % (self.__start_min_temperature, self.__start_max_temperature)) ]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() # exit if the battery temp match with test temp if not (self.__start_min_temperature <= last_batt_temp <= self.__start_max_temperature): self._logger.info( "The DUT has reached %s degree celsius which is outside [%s;%s] !" % (last_batt_temp, self.__start_min_temperature, self.__start_max_temperature)) exceed_timeout = False break # remove the time spent to track for the change from allowed test duration consumed_time = time.time() - consumed_time test_timeout = test_timeout - consumed_time if exceed_timeout: txt = "timeout exceeded (%ss) to move the DUT temperature outside [%s,%s] degree celsius" % ( str(self.__timeout_dut_adjust_stop_temp), self.__start_min_temperature, self.__start_max_temperature) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) # once here we wait until a change is seen result = False exceed_timeout = True msic_reg = None time_take_to_see_a_change = time.time() timeout = time.time() + test_timeout while time.time() < timeout and not result: try: # try to read measurement msic_reg = self.update_battery_info() thermal_conf = self.em_api.get_thermal_sensor_info() # store result on xml self.__em_meas_tab.add_dict_measurement(msic_reg) self.__em_meas_tab.add_dict_measurement(thermal_conf) # temporary workaround to detect the end condition batt_health = str(msic_reg["BATTERY"]["HEALTH"][0]).upper() if batt_health != self.__ACTION[ self.__action_to_peform]["START"]: self._meas_list.add_dict("EM_INFO_STOP_TEMP", msic_reg) if self._em_meas_verdict.test_list(self._meas_list, self._em_targets): self._meas_list.add( "TIME_TO_SEE_A_CHANGE", time.time() - time_take_to_see_a_change, "second") self._em_meas_verdict.compare_list( self._meas_list, self._em_targets, clean_meas_list=True) result = True except AcsBaseException as e: # try to catch why uecmd may fail if not self.is_board_and_acs_ok(): txt = "connection with DUT lost during change waiting on DUT behavior" else: txt = "error happened during change waiting on DUT behavior: " + str( e) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) finally: # Store various information self.__em_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "RUNTEST:Waiting for the DUT to modify its behavior outside [%s;%s] degree celsius" % (self.__start_min_temperature, self.__start_max_temperature)) ]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() # exist if we see the expected battery health if result: exceed_timeout = False break if exceed_timeout: txt = "timeout exceeded (%ss) to see a change on battery/charger behavior outside [%s,%s] degree celsius" % ( str(self.__timeout_dut_adjust_stop_temp), self.__start_min_temperature, self.__start_max_temperature) # take the last em info read if msic_reg is not None: self._meas_list.add_dict("EM_INFO_STOP_TEMP", msic_reg) self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, clean_meas_list=True) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) def __test_without_data(self, temperature): """ test charging resume or stop while a data cable is not plugged """ self._logger.info( "test if %s when we move from [%s;%s] degree celsius to %s degree celsius without an active data connection" % (self.__action_to_peform, self.__start_min_temperature, self.__start_max_temperature, self.__stop_temp)) self.em_api.clean_autolog() # choose function to put in logger self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_UEVENT, "sequenced") self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_THERMAL, "sequenced") self.em_api.set_autolog_duration(self.__timeout_dut_adjust_stop_temp) # start non persistent autolog with a short period of data polling self.em_api.start_auto_logger(30, 10, "sequenced") # switch charger self._device.disconnect_board() self._io_card.simulate_insertion(self.__charger_type) self._logger.info( "wait 60s to capture the first em info at START temperature") time.sleep(60) # remove the time spent in adjusting the temperature chamber and wait what it left remaning_time = time.time() self.tc_module.get_eq().set_temperature(temperature) self.tc_module.get_eq().wait_for_temperature(temperature) remaning_time = time.time() - remaning_time remaning_time = self.__timeout_dut_adjust_stop_temp + 60 - remaning_time if remaning_time > 0: self._logger.info("wait %ss to see any change on DUT behavior" % str(remaning_time)) time.sleep(self.__timeout_dut_adjust_stop_temp + 60) self._io_card.usb_host_pc_connector(True) # wait x seconds time.sleep(self.usb_sleep) # connect board self._device.connect_board() self.em_api.stop_auto_logger() # parse autolog response and reset them msic_list = self.em_api.get_autolog_msic_registers() thermal_list = self.em_api.get_autolog_thermal_sensor_info() self.em_api.clean_autolog() log_length = len(msic_list) start_time = None stop_time = None battery_health_change = False for i in range(log_length): try: # get battery/charger info if len(msic_list) > i: msic_dict = msic_list[i] if len(msic_dict) > 1: msic_dict = msic_dict[1] # first track when we are outside the range if start_time is None: batt_temp = msic_dict["BATTERY"]["TEMP"][0] if not (self.__start_min_temperature <= batt_temp <= self.__start_max_temperature): start_time = msic_dict["TIME_STAMP"][0] start_time = time.mktime( time.strptime(start_time, "%Y-%m-%d_%Hh%M.%S")) # else track when we notice a change on battery health elif stop_time is None: if msic_dict["BATTERY"]["HEALTH"][0].upper( ) != self.__ACTION[ self.__action_to_peform]["START"]: battery_health_change = True self._meas_list.add_dict( "EM_INFO_STOP_TEMP", msic_dict) # test if the verdict comparison is true if self._em_meas_verdict.test_list( self._meas_list, self._em_targets): self._em_meas_verdict.compare_list( self._meas_list, self._em_targets, clean_meas_list=True) stop_time = msic_dict["TIME_STAMP"][0] stop_time = time.mktime( time.strptime(stop_time, "%Y-%m-%d_%Hh%M.%S")) stop_time -= start_time # store result on xml self.__em_meas_tab.add_dict_measurement(msic_dict) # get thermal info if len(thermal_list) > i: thermal_dict = thermal_list[i] if len(thermal_dict) > 1: # store result on xml self.__em_meas_tab.add_dict_measurement( thermal_dict[1]) finally: self.__em_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "RUNTEST:Waiting temperature change without data cable plug" ) ]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() # compute verdict by taking the last batt info seen if log_length > 0: self._meas_list.add_dict("EM_INFO_START_TEMP", msic_list[1][1]) # get the duration it takes to see the right info if stop_time is not None: self._meas_list.add("TIME_TO_SEE_A_CHANGE", stop_time, "second") if not battery_health_change: self._meas_list.add_dict("EM_INFO_STOP_TEMP", msic_list[-1][1]) self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, clean_meas_list=True)
class LabEmBattCritThresholdAdapted(EmUsecaseBase): """ Lab Energy Management base class. """ DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # Read the battery capacity expected for the init of the test self.__high_load_timeout = self._tc_parameters.get_param_value("HIGH_LOAD_DISCHARGE_TIME", default_cast_type=int) self.__light_load_timeout = self._tc_parameters.get_param_value("LIGHT_LOAD_DISCHARGE_TIME", default_cast_type=int) self.__light_load = self._tc_parameters.get_param_value("LIGHT_LOAD", "") self.__high_load = self._tc_parameters.get_param_value("HIGH_LOAD") self.__load_module = LoadModule() self.__load_module.add_load(self.__light_load) self.__load_module.add_load(self.__high_load) #----------------------------------------------------------------------- # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_BATT_CRIT_THRESHOLD_ADAPTED", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets) # Initialize EM xml object # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) #------------------------------------------------------------------------------ def set_up(self): """ Initialize the test """ # Call the UseCaseBase Setup function EmUsecaseBase.set_up(self) # init capacity self.update_battery_info() # discharge battery if str(self.em_core_module.batt_start_capacity).isdigit() and \ (self.batt_capacity > self.em_core_module.batt_start_capacity): # add video to the setup discharge load self.em_core_module.monitor_discharging(self.em_core_module.batt_start_capacity, self.em_core_module.discharge_time, self.__em_meas_tab, self.__load_module) # help board to discharge faster return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def run_test_body(self): """ here we discharge twice to compare the voltage at shutdown level. Shutdown level is at 0% of capacity on android system. it may change on other """ EmUsecaseBase.run_test_body(self) msic = self.update_battery_info() # get voltage unit unit = msic["BATTERY"]["VOLTAGE"][1] def __discharge_part(load, load_timeout, text): self.__load_module.stop_load() self.__load_module.start_load(load) self.__discharge_to_off_without_data(load_timeout) error_text = "" # plug a data cable to see if the board boot in COS or MOS self.__retrieve_the_board_to_mos() if self.is_board_and_acs_ok(): voltage = self.__retrieve_autolog_result(text) # exit here if we fail to get the voltage at 0% if voltage is None: error_text = "load %s never reach 0%% of capacity" % str(load) if error_text != "": # leave here as test is KO if 0% not seen self._meas_list.add("DELTA_BETWEEN_HIGH_AND_LIGHT_LOAD", "CAPACITY_AT_ZERO_NEVER_REACHED", "") self._logger.error(error_text) raise DeviceException(DeviceException.OPERATION_FAILED, error_text) return voltage # First discharge with the load that take more time to discharge light_voltage = __discharge_part(self.__light_load, self.__light_load_timeout, "light_load") if self.is_board_and_acs_ok() and light_voltage is not None: # if board capacity is too low then charge a little bit if self.batt_capacity + 1 < int(self.em_core_module.batt_start_capacity): self.em_core_module.monitor_charging(self.em_core_module.batt_start_capacity, 120, self.__em_meas_tab) # Discharge with high load high_voltage = __discharge_part(self.__high_load, self.__high_load_timeout, "high_load") if high_voltage is not None: # generate em verdict self._meas_list.add("DELTA_BETWEEN_HIGH_AND_LIGHT_LOAD", high_voltage - light_voltage, unit) self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, True) self._em_meas_verdict.judge(ignore_blocked_tc=True) # Save data report in xml file return(self._em_meas_verdict.get_current_result(), self._em_meas_verdict.save_data_report_file()) def tear_down(self): """ End and dispose the test """ # call tear down after some operations EmUsecaseBase.tear_down(self) # check the board health, get the aplog, and charge again if necessary load_stopped = False if self.is_board_and_acs_ok(): # restore setting that does not persist on reboot self.__load_module.stop_load(raise_error=False) load_stopped = True # clean the board state and retrieve logs self.em_core_module.clean_up() if not load_stopped: self.__load_module.stop_load(raise_error=False) return Global.SUCCESS, "No errors" def __discharge_to_off_without_data(self, timeout): """ discharge board until shutdown designed for a short discharge period(like discharging from 20% to 0). If discharge fail to reach shutdown , it will discharge for the all of the shutdown timeout set """ # start non persistent autolog with a short period of data polling # choose function to put in logger self.em_api.clean_autolog() self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_THERMAL, "sequenced") self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_UEVENT, "sequenced") self.em_api.start_auto_logger(60, 1, "sequenced") # disconnect board and plug the wanted cable self._device.disconnect_board() self._io_card.ac_charger_connector(False) self._io_card.usb_connector(False) # wait for 0% of battery capacity or connection lost self._logger.info("Waiting %ss to let the board discharge from %s%% to off" % (timeout, self.batt_capacity)) time.sleep(timeout) self._io_card.usb_host_pc_connector(True) time.sleep(self.usb_sleep) mode = self._device.get_boot_mode() if mode == "MOS": self._device.connect_board() self.update_battery_info() self.__load_module.restart_load(consider_only_checkable_load=True) self._logger.info("board not yet turn off, Waiting %ss to let the board discharge from %s%% to off" % ( timeout / 2, self.batt_capacity)) self._device.disconnect_board() self._io_card.usb_host_pc_connector(False) def __retrieve_the_board_to_mos(self): """ retrieve the board. """ # plug a data cable to see if the board boot in COS or MOS self._io_card.usb_host_pc_connector(True) time.sleep(self.usb_sleep) mode = self._device.get_boot_mode() if mode != "MOS": # wait for a while to let the board boot if self.phone_info.get("DATA_WHILE_CHARGING") is True: self._logger.info("Waiting 5 minutes for the board to boot") time.sleep(300) self._logger.info("Waiting at most 15 minutes to see the boot mode") end_time = time.time() + 900 while time.time() < end_time: mode = self._device.get_boot_mode() if mode in ["COS", "MOS"]: self._logger.info("Board seen booted in %s after %ss" % (mode, abs((time.time() - end_time) + 900))) break if mode != "MOS": # plug a charge and charge it for a while self._io_card.wall_charger_connector(True) self._logger.info("Waiting 20 minutes to charge the board with a wall charger") time.sleep(1200) # plug a data cable to see if the board boot is still in COS self._io_card.wall_charger_connector(False) self._io_card.usb_host_pc_connector(True) mode = self._device.get_boot_mode() self._logger.info("Waiting at most 10 minutes to detect the boot mode") end_time = time.time() + 600 while time.time() < end_time: mode = self._device.get_boot_mode() if mode != "UNKNOWN": self._logger.info("Board seen booted in %s after %ss" % (mode, abs((time.time() - end_time) + 600))) break # if the boot mode is not unknown , try to reboot the board if mode == "UNKNOWN": self.em_core_module.reboot_board("HARD") # if in MOS connect board elif mode != "MOS": self._device.reboot(skip_failure=True) # after all of this , try to connect ACS mode = self._device.get_boot_mode() if mode == "MOS": # else we are in MOS thus connecting ACS self._device.connect_board() # finally do action here only if board is well booted if not self.is_board_and_acs_ok(): tmp_txt = "failed to retrieve the board in MAIN OS and connect ACS after shutdown link to load testing" self._logger.error(tmp_txt) raise DeviceException(DeviceException.OPERATION_FAILED, tmp_txt) def __retrieve_autolog_result(self, text): """ retrieve data from autolog. return voltage when capacity reach the first 0%. """ # get info from autologger result = None self.update_battery_info() self.em_api.stop_auto_logger() msic_list = self.em_api.get_autolog_msic_registers() thermal_list = self.em_api.get_autolog_thermal_sensor_info() self.em_api.clean_autolog() # get the highest logs length log_length = max(len(thermal_list), len(msic_list)) for i in range(log_length): try: # get battery/charger info if len(msic_list) > i: msic_dict = msic_list[i][1] if len(msic_dict) > 1: # get the voltage for the first 0% reported # FIXME: maybe check the 0 from aplog to catch exactly what board see if result is None and msic_dict["BATTERY"]["CAPACITY"][0] == 0: result = msic_dict["BATTERY"]["VOLTAGE"][0] self.__em_meas_tab.add_dict_measurement(msic_dict) # get thermal info if len(thermal_list) > i: thermal_dict = thermal_list[i][1] if len(thermal_dict) > 1: # store result on xml self.__em_meas_tab.add_dict_measurement(thermal_dict) # reset error measurement_fail = 0 except AcsBaseException as e: # try to reconnect to the board if uecmd failed self._logger.error("fail to get measurement: " + str(e)) measurement_fail += 1 # stop the usecase if measurement fail several times. if measurement_fail >= self._consecutive_meas_error: tmp_txt = "Measurement failed after %s times, abort usecase" % \ self._consecutive_meas_error self._logger.error(tmp_txt) # leave here ,this is not used to generate this test verdict # so not error raised return finally: # Store various information self.__em_meas_tab.add_measurement([self.get_time_tuple(), (self._em_cst.COMMENTS, "RUNTEST : Discharge without data cable with load : %s" % text)]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() return result
class LabEmBattCheckChargingStatusWithLoad(EmUsecaseBase): """ Lab Energy Management class. """ DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): EmUsecaseBase.__init__(self, tc_name, global_config) # get base module self.em_core_module = UcBatteryModule(self) # get the tc parameters self.__tested_capacity = self._tc_parameters.get_param_value( "TESTED_CAPACITY", default_cast_type=int) self.__charger = self._tc_parameters.get_param_value("CHARGER") self.__status = self._tc_parameters.get_param_value("STATUS").upper() self.__load = self._tc_parameters.get_param_value("LOAD") # vars self.__time_to_charge = 60 self.__time_to_discharge = 60 self.__reports_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__time_to_log = 60 # create a report file self.__report_file_handler = XMLMeasurementFile( self.__reports_file_name) # Activate Loadmodule instance self.__load_module = LoadModule() self.__load_module.add_load(self.__load) # delay to launch autologger self.__autolog_delay = 20 # --------------------------------------- def set_up(self): EmUsecaseBase.set_up(self) # get the tested capacity batt_info = self.update_battery_info() # initial state is dut charge at max_range if self.em_core_module.is_batt_capacity_below_target( batt_info, self.__tested_capacity): self._logger.info("Device capacity is %s : going to %s" % (self.batt_capacity, self.__tested_capacity)) self.em_core_module.monitor_charging(self.__tested_capacity, self.__time_to_charge, self.__report_file_handler) else: self._logger.info("Device capacity is %s : going to %s" % (self.batt_capacity, self.__tested_capacity)) self.em_core_module.monitor_discharging( self.__tested_capacity, self.__time_to_discharge, self.__report_file_handler, load_module=self.__load_module) return Global.SUCCESS, "No errors" # --------------------------------------- def run_test_body(self): EmUsecaseBase.run_test_body(self) status_list = [] # clean autolog self.em_api.clean_autolog() # choose to log msic register in autolog self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_UEVENT, "sequenced") # set time to log self.em_api.set_autolog_duration(self.__time_to_log) # start the autologger we put a first delay to have time to unplugged usb_HOST self.em_api.start_auto_logger(self.__autolog_delay, 1, "sequenced") # start the load self.__load_module.start_load() # disconnect board self._device.disconnect_board() self._io_card.remove_cable("ALL") # plug charger self._io_card.simulate_insertion(self.__charger) # wait a while time.sleep(self.__time_to_log + self.__autolog_delay) # connect usb_HOST self._io_card.usb_host_pc_connector(True) # connect board self._device.connect_board() time.sleep(self.usb_sleep) # stop auto logger self.em_api.stop_auto_logger() # get the results msic_list = self.em_api.get_autolog_msic_registers() # check if tested status is seen for measure_index in range(len(msic_list)): status_list.append( msic_list[measure_index][1]['BATTERY']['STATUS'][0].upper()) # fill autolog result in file self.em_core_module.fill_autolog_result(msic_list, [], self.__report_file_handler, "Results of autologger") # raise an error if status is not seen if self.__status not in status_list: msg = "Status %s not seen on plug" % self.__status raise DeviceException(DeviceException.OPERATION_FAILED, msg) return Global.SUCCESS, "No errors" # --------------------------------------- def tear_down(self): EmUsecaseBase.tear_down(self) # stop load self.em_core_module.clean_up() self.__load_module.stop_load() return Global.SUCCESS, "No errors"
class LabEmBattFullIdentification(EmUsecaseBase): """ Lab Energy Management class. """ DEDICATED_BENCH = "BATTERY_BENCH" __ACTION = [ "CAPACITY_JUMP_NEAR_FULL", "CAPACITY_AT_WHICH_FIRST_FULL_APPEAR", "TIME_TO_CHARGE_TO_FULL_FROM_START_CAPACITY", "TIME_TO_SEE_FULL_AT_MAX_CAPACITY", "CHARGE_STOP_ONCE_FULL" ] def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # Type of the charger self.__charger_type = self._tc_parameters.get_param_value( "CHARGER_TYPE") self.__load = self._tc_parameters.get_param_value( "LOAD_TO_HELP_DISCHARGE_IN_SETUP") # charge to Full Timeout self.__charge_full_timeout = self._tc_parameters.get_param_value( "CHARGE_TO_FULL_DURATION", default_cast_type=int) # capacity that match with first full self.__first_full_capacity = self._tc_parameters.get_param_value( "CAPACITY_AT_WHICH_FULL_FIRST_APPEAR", 100, default_cast_type=int) self.__what_to_check = str( self._tc_parameters.get_param_value("WHAT_TO_CHECK")).upper() # Summarize the parameters self._logger.info("Charger type to plug during FULL charging: %s" % self.__charger_type) self._logger.info("Capacity at which FULL shall first appear: %d" % self.__first_full_capacity) self._logger.info("Test expected start capacity : %s" % self.em_core_module.batt_start_capacity) # Load Module Initialization self.__load_module = LoadModule() self.__load_module.add_load(self.__load) # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_BATT_FULL_IDENTIFICATION", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, consider_all_target=True) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) #------------------------------------------------------------------------------ def set_up(self): """ Initialize the test """ # Call the UseCaseBase Setup function EmUsecaseBase.set_up(self) # Check expected result first if self.__what_to_check not in self.__ACTION: txt = "wrong value for TC parameter WHAT_TO_CHECK %s, can only be %s" % ( self.__what_to_check, str(self.__ACTION)) self._logger.error(txt) raise AcsConfigException(AcsConfigException.INVALID_PARAMETER, txt) # Update Battery Information em_info = self.update_battery_info() if self.em_core_module.is_batt_capacity_above_target( em_info, self.em_core_module.batt_start_capacity): # Discharge part self.em_core_module.monitor_discharging( self.em_core_module.batt_start_capacity, self.em_core_module.discharge_time, self.__em_meas_tab, self.__load_module) elif self.em_core_module.is_batt_capacity_below_target( em_info, self.em_core_module.batt_start_capacity): # Charge part self.em_core_module.monitor_charging( self.em_core_module.batt_start_capacity, self.em_core_module.charge_time, self.__em_meas_tab) return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def run_test_body(self): """ Execute the test Check the end of the main battery charge """ # Call LAB_EM_BASE Run function EmUsecaseBase.run_test_body(self) # first of all charge to full em_info_list = self.__charge_without_data() start_index = None full_seen = False index = 0 # search for the first iteration of the capacity at which full appear for em_dico in em_info_list: if em_dico["BATTERY"]["CAPACITY"][ 0] == self.__first_full_capacity and start_index is None: start_index = index if em_dico["BATTERY"]["STATUS"][0] == "FULL": full_seen = True break index += 1 # all the test above consider that the FULL status has already been seen # else an error is raised here if not full_seen: txt = "Battery FULL status was not reached after waiting %ss with %s plugged" % ( self.__charge_full_timeout, self.__charger_type) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) if self.__what_to_check == "CAPACITY_AT_WHICH_FIRST_FULL_APPEAR": self.__check_first_full_capacity(em_info_list) elif self.__what_to_check == "TIME_TO_SEE_FULL_AT_MAX_CAPACITY": self.__check_first_full_timeout(em_info_list, start_index) elif self.__what_to_check == "TIME_TO_CHARGE_TO_FULL_FROM_START_CAPACITY": self.__check_charge_to_full_timeout(em_info_list) elif self.__what_to_check == "CAPACITY_JUMP_NEAR_FULL": self.__check_capacity_jump(em_info_list, start_index) elif self.__what_to_check == "CHARGE_STOP_ONCE_FULL": self.__check_charge_stop(em_info_list) # compare values with targets self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, clean_meas_list=True) self._em_meas_verdict.judge() return self._em_meas_verdict.get_current_result_v2() def tear_down(self): """ End and dispose the test """ # call tear down after some operations EmUsecaseBase.tear_down(self) # clean the board state and retrieve logs self.em_core_module.clean_up() self.__load_module.clean() return Global.SUCCESS, "No errors" def __charge_without_data(self): """ charge without a data cable plug :rtype: list :return: list of em dictionary """ adjusted_time = 90 self._logger.info( "Trying to charge board from %s%% to FULL during %ss" % (self.batt_capacity, self.__charge_full_timeout)) self.em_api.clean_autolog() # choose function to put in logger self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_UEVENT, "sequenced") self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_THERMAL, "sequenced") self.em_api.set_autolog_duration(self.__charge_full_timeout) # start non persistent autolog with a short period of data polling self.em_api.start_auto_logger(30, 10, "sequenced") # switch charger self._device.disconnect_board() # connect WALL Charger self._io_card.simulate_insertion(self.__charger_type) # wait x min self._logger.info("waiting %ss (+ %ss adjusted) to reach FULL status" % (self.__charge_full_timeout, adjusted_time)) time.sleep(self.__charge_full_timeout + adjusted_time) self._io_card.usb_host_pc_connector(True) # wait x seconds time.sleep(self.usb_sleep) # connect board self._device.connect_board() self.em_api.stop_auto_logger() # parse autolog response and reset them msic_list = self.em_api.get_autolog_msic_registers() thermal_list = self.em_api.get_autolog_thermal_sensor_info() self.em_api.clean_autolog() # get the highest logs length log_length = max(len(thermal_list), len(msic_list)) em_info_list = [] for i in range(log_length): try: # get battery/charger info if len(msic_list) > i: msic_dict = msic_list[i] if len(msic_dict) > 1: msic_dict = msic_dict[1] # store result on xml em_info_list.append(msic_dict) self.__em_meas_tab.add_dict_measurement(msic_dict) # get thermal info if len(thermal_list) > i: thermal_dict = thermal_list[i] if len(thermal_dict) > 1: # store result on xml self.__em_meas_tab.add_dict_measurement( thermal_dict[1]) finally: self.__em_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "RUNTEST:charging board to FULL") ]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() return em_info_list def __check_capacity_jump(self, em_info_list, start_index): """ check if there is capacity jump when charging to full """ self._logger.info( "Check if capacity jump happen when we are near to FULL ...") # Check if start index is superior than 0 , else we can't evaluate the jump state if start_index in [0, None]: txt = "Can't compute capacity jump as the first measurement was already at %s%% which is the capacity where battery FULL should firstly appear" % self.__first_full_capacity self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) end_capacity = em_info_list[start_index]["BATTERY"]["CAPACITY"][0] start_capacity = em_info_list[start_index - 1]["BATTERY"]["CAPACITY"][0] measured_jump = end_capacity - start_capacity self._meas_list.add("CAPACITY_JUMP_AT_MAX_CAPACITY", measured_jump, "none") def __check_charge_to_full_timeout(self, em_info_list): """ Check the time it takes to see status FULL from start capacity """ self._logger.info( "Check the time it takes to see status FULL from the start capacity at %s%%" % self.em_core_module.batt_start_capacity) stop_time = None start_time = em_info_list[0]["TIME_STAMP"][0] start_time = time.mktime(time.strptime(start_time, "%Y-%m-%d_%Hh%M.%S")) # search for the FULL for em_dico in em_info_list: if em_dico["BATTERY"]["STATUS"][0] == "FULL": stop_time = em_dico["TIME_STAMP"][0] stop_time = time.mktime( time.strptime(stop_time, "%Y-%m-%d_%Hh%M.%S")) break # raise error if full is not seen if stop_time is None: txt = "Battery FULL status was never seen" self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) self._meas_list.add("TIME_TO_CHARGE_TO_FULL", stop_time - start_time, "second") def __check_first_full_capacity(self, em_info_list): """ check that the first full seen appear at the right capacity """ self._logger.info( "check that the first FULL seen appear at the right capacity") full_capacity = None for em_dico in em_info_list: if em_dico["BATTERY"]["STATUS"][0] == "FULL": full_capacity = em_dico["BATTERY"]["CAPACITY"][0] break if full_capacity != self.__first_full_capacity: txt = "Battery FULL status was seen at %s%% of capacity instead of expecting %s%%" % ( full_capacity, self.__first_full_capacity) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) self._meas_list.add("CAPACITY_AT_WHICH_FIRST_FULL_APPEAR", full_capacity, "none") def __check_first_full_timeout(self, em_info_list, start_index): """ Check the time it takes to see status FULL once max capacity is seen """ self._logger.info( "Check the time it takes to see status FULL from the first %s%% of capacity seen ..." % self.__first_full_capacity) if start_index is None: txt = "Can't compute the time it takes to see FULL status once %s%% capacity is reached: this capacity was never reached" % self.__first_full_capacity self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) stop_time = None stop_capacity = None start_time = em_info_list[start_index]["TIME_STAMP"][0] start_time = time.mktime(time.strptime(start_time, "%Y-%m-%d_%Hh%M.%S")) # search for the FULL for em_dico in em_info_list: if em_dico["BATTERY"]["STATUS"][0] == "FULL": stop_time = em_dico["TIME_STAMP"][0] stop_time = time.mktime( time.strptime(stop_time, "%Y-%m-%d_%Hh%M.%S")) stop_capacity = em_dico["BATTERY"]["CAPACITY"][0] break # raise error if full is not seen if stop_capacity is not None and stop_capacity != self.__first_full_capacity: txt = "Battery FULL status was seen at %s%% of capacity instead of expecting %s%%" % ( stop_capacity, self.__first_full_capacity) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) self._meas_list.add("TIME_TO_SEE_FULL_AT_MAX_CAPACITY", stop_time - start_time, "second") def __check_charge_stop(self, em_info_list): """ Check that the charge stop once FULL is reached """ self._logger.info("Check that the charge stop once FULL is reached") result = False # search for the FULL for em_dico in em_info_list: if em_dico["BATTERY"]["STATUS"][0] == "FULL" and em_dico[ "CHARGER"]["ENABLE_CHARGING"][0] == 0: self._meas_list.add_dict("EM_INFO", em_dico) result = True break if not result: txt = "The charge did not stop after battery FULL reached" self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt)
class LabEmAdjustParamWithMaint(EmUsecaseBase): """ Lab Energy Management class. """ DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() # High load load = self._tc_parameters.get_param_value("LOAD") self.__charger_type = self._tc_parameters.get_param_value("CHARGER_TYPE") self.__timeout_dut_adjust_charging_param = self._tc_parameters.get_param_value("TIME_TO_LET_DUT_ADJUST_CHARGING_PARAM", default_cast_type=int) self.__timeout_dut_adapt_temp = self._tc_parameters.get_param_value("TIME_TO_LET_DUT_ADAPT_TO_TEST_TEMP", 3600, default_cast_type=int) # Read TEMPERATURE from test case xml file self.tc_module = None self.__max_temperature = self._tc_parameters.get_param_value("MAX_TEMPERATURE") self.__min_temperature = self._tc_parameters.get_param_value("MIN_TEMPERATURE") if "ROOM" not in [self.__min_temperature, self.__max_temperature]: # get temperature chamber equipment if not room temperature self.__max_temperature = int(self.__max_temperature) self.__min_temperature = int(self.__min_temperature) self.tc_module = ThermalChamberModule(self._ambient_temperature) # inform module that this is not a default thermal test self.tc_module.set_test_type("SPECIFIC") self.__temperature = int((self.__min_temperature + self.__max_temperature) / 2) else: self.__temperature = "ROOM" # Summarize the parameters self._logger.info("Type of the charger: %s" % self.__charger_type) self._logger.info("Test MAX temperature: %s" % self.__max_temperature) self._logger.info("Test MIN temperature: %s" % self.__min_temperature) self._logger.info("Load to use during test: %s" % load) self._logger.info("Time to see change on DUT behavior at tested temperature: %s" % self.__timeout_dut_adjust_charging_param) # Load Module Initialization self.__load_module = LoadModule() self.__load_module.add_load(load) # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_ADJUST_CHARGING_PARAM_WITH_MAINT", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # get target and initialize measurement self._em_meas_verdict.load_target(self._em_targets, self.tcd_to_test) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) self.__charger_is_data_cable = None #------------------------------------------------------------------------------ def set_up(self): """ Initialize the test """ # Call the UseCaseBase Setup function EmUsecaseBase.set_up(self) # Check specific option if they are chosen if self.__charger_type not in self._io_card.SUPPORTED_DEVICE_TYPE: txt = "io card does not support charger type %s " % self.__charger_type self._logger.error(txt) raise AcsConfigException(AcsConfigException.INVALID_PARAMETER, txt) if self.tc_module is not None: self.tc_module.set_up_eq() self.tc_module.get_eq().set_regulation(True) start_temp = self.__temperature low_temp = self.phone_info["BATTERY"]["THERMAL_CHARGING_LOW_LIMIT"] high_temp = self.phone_info["BATTERY"]["THERMAL_CHARGING_HIGH_LIMIT"] # avoid setting temperature at not charging temp but near it if start_temp <= low_temp: self._logger.info("test temperature at %s is <= the min temperature for charging:%s, adjusting it" % (self.__temperature, low_temp)) start_temp = low_temp + 10 elif start_temp >= high_temp : self._logger.info("test temperature at %s is >= the max temperature for charging:%s, adjusting it" % (self.__temperature, high_temp)) start_temp = high_temp - 10 self.tc_module.get_eq().set_temperature(start_temp) # set the temperature self.em_api.set_thermal_management(False) # a reboot is required to apply this change self._device.reboot() # do this job one time in case of B2B if self.__charger_is_data_cable is None: self.__charger_is_data_cable = self.em_core_module.is_host_connection_available_when_charger_plug(self.__charger_type) self._logger.info("test sequences will adjust to this") # Update Battery Information em_info = self.update_battery_info() # we want to start at given capacity if self.em_core_module.is_batt_capacity_above_target(em_info, self.em_core_module.batt_start_capacity): # Discharge part self.em_core_module.monitor_discharging(self.em_core_module.batt_start_capacity, self.em_core_module.discharge_time, self.__em_meas_tab, self.__load_module) elif self.em_core_module.is_batt_capacity_below_target(em_info, self.em_core_module.batt_start_capacity): # charge part self.em_core_module.monitor_charging(self.em_core_module.batt_start_capacity, self.em_core_module.charge_time, self.__em_meas_tab) # wait that the board see the test temperature self.__wait_for_temp(self.__temperature) return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def run_test_body(self): """ Execute the test """ # Call LAB_EM_BASE Run function EmUsecaseBase.run_test_body(self) if self.__charger_is_data_cable: self.__test_with_data(self.__temperature) else: self.__test_without_data(self.__temperature) # value comparing are done in private function self._em_meas_verdict.judge() return self._em_meas_verdict.get_current_result_v2() #------------------------------------------------------------------------------ def tear_down(self): """ End and dispose the test """ # call tear down after some operations EmUsecaseBase.tear_down(self) if self.tc_module is not None: # Go to the ambient temperature self.tc_module.release_eq() # clean the board state and retrieve logs self.em_core_module.clean_up() # restore thermal management setting self.em_api.set_thermal_management(True) # a reboot is required to apply this change self._device.reboot() return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def __wait_for_temp(self, temperature): """ wait that the DUT see the test temperature """ # heat the DUT self._logger.info("check that DUT is between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature)) last_batt_temp = self.update_battery_info()["BATTERY"]["TEMP"][0] if self.tc_module is not None and not (self.__min_temperature <= last_batt_temp <= self.__max_temperature): self.phonesystem_api.sleep_screen() exceed_timeout = True self.tc_module.get_eq().set_temperature(temperature) self.tc_module.get_eq().wait_for_temperature(temperature) timeout_to_see_temp_change = 300 start_time_to_see_temp_change = time.time() timeout = time.time() + self.__timeout_dut_adapt_temp while time.time() < timeout: self._logger.info("wait 60s") time.sleep(60) try: # try to read measurement msic_reg = self.update_battery_info() thermal_conf = self.em_api.get_thermal_sensor_info() # store result on xml self.__em_meas_tab.add_dict_measurement(msic_reg) self.__em_meas_tab.add_dict_measurement(thermal_conf) local_temp = msic_reg["BATTERY"]["TEMP"][0] if last_batt_temp != local_temp: start_time_to_see_temp_change = time.time() last_batt_temp = local_temp # stop usecase if board take too long to reach battery capacity if (time.time() - start_time_to_see_temp_change) > timeout_to_see_temp_change: self._logger.info("DUT temperature did not change in %ss, adjusting chamber temperature" % timeout_to_see_temp_change) if local_temp < self.__min_temperature: temperature += 1 elif local_temp > self.__max_temperature: temperature -= 1 self.tc_module.get_eq().set_temperature(temperature) start_time_to_see_temp_change = time.time() except AcsBaseException as e: # try to catch why uecmd may fail if not self.is_board_and_acs_ok(): txt = "connection with DUT lost during temperature change to be between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature) else: txt = "error happened during temperature change to let it see [%s;%s] degree celsius : %s" % (self.__min_temperature, self.__max_temperature, str(e)) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) finally: # Store various information self.__em_meas_tab.add_measurement([self.get_time_tuple(), (self._em_cst.COMMENTS, "SETUP:Waiting for the DUT to reach [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature))]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() # exit if the battery temp match with test temp if self.__min_temperature <= last_batt_temp <= self.__max_temperature: self._logger.info("The DUT has reached %s degree celsius which is between expected target [%s;%s] !" % (last_batt_temp, self.__min_temperature, self.__max_temperature)) exceed_timeout = False break if exceed_timeout: txt = "timeout exceeded (%ss) to heat up the DUT to %s degree celsius" % (str(self.__timeout_dut_adapt_temp), temperature) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) def __test_with_data(self, temperature): """ test that we can see the CC & CV expected for this temperature with a data cable plug """ self._logger.info("testing charger and battery behavior at [%s;%s] degree celsius while data is active" % (self.__min_temperature, self.__max_temperature)) # init var full_constently_seen = False maintenance_constently_seen = False full_seen_one_time = False maintenance_seen_one_time = False maitenance_started = False msic_reg = self.update_battery_info() # timeout to see CC and CV updated timeout = time.time() + self.__timeout_dut_adjust_charging_param while time.time() < timeout and not maitenance_started: self._logger.info("wait 60s") time.sleep(60) try: # try to read measurement msic_reg = self.update_battery_info() thermal_conf = self.em_api.get_thermal_sensor_info() # store result on xml self.__em_meas_tab.add_dict_measurement(msic_reg) self.__em_meas_tab.add_dict_measurement(thermal_conf) # compare values with targets if msic_reg["BATTERY"]["STATUS"] == "FULL": full_constently_seen = True full_seen_one_time = True else: full_constently_seen = False # check that we reach maintenance charging if msic_reg["CHARGER"]["ENABLE_CHARGING"] == 0 and full_constently_seen: maintenance_constently_seen = True maintenance_seen_one_time = True else: maintenance_constently_seen = False if maintenance_constently_seen and full_constently_seen: # compute verdict by taking the last batt info seen self._meas_list.add_dict("EM_INFO", msic_reg) self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, clean_meas_list=True) maitenance_started = True except AcsBaseException as e: # try to catch why uecmd may fail if not self.is_board_and_acs_ok(): txt = "connection with DUT lost during change waiting on DUT behavior" else: txt = "error happened during change waiting on DUT behavior: " + str(e) self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) finally: # Store various information self.__em_meas_tab.add_measurement([self.get_time_tuple(), (self._em_cst.COMMENTS, "RUNTEST:Waiting for the DUT behavior to change at [%s;%s] degree" % (self.__min_temperature, self.__max_temperature))]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() if maintenance_constently_seen and full_constently_seen: break txt = "" # check that board reach full if not full_constently_seen: if not full_seen_one_time: txt = "battery FULL state was never reached at a temperature between [%s;%s] degree celsius " % (self.__min_temperature, self.__max_temperature) else: txt = "battery FULL state was seen but lost at a temperature between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature) # check that maintenance have started if we reach full elif not maintenance_constently_seen: if not maintenance_seen_one_time: txt = "MAINTENANCE charging state was never reached at a temperature between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature) else: txt = "MAINTENANCE charging was seen but lost at a temperature between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature) if txt != "": self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) def __test_without_data(self, temperature): """ test that we can see the CC & CV expected for this temperature without a data cable plug """ self._logger.info("testing charger and battery behavior at [%s;%s] degree celsius while data is not active" % (self.__min_temperature, self.__max_temperature)) self.em_api.clean_autolog() # choose function to put in logger self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_UEVENT, "sequenced") self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_THERMAL, "sequenced") self.em_api.set_autolog_duration(self.__timeout_dut_adjust_charging_param) # start non persistent autolog with a short period of data polling self.em_api.start_auto_logger(30, 10, "sequenced") # switch charger self._device.disconnect_board() # connect WALL Charger self._io_card.simulate_insertion(self.__charger_type) # wait x min self._logger.info("wait %ss to see any change on DUT behavior" % str(self.__timeout_dut_adjust_charging_param + 60)) time.sleep(self.__timeout_dut_adjust_charging_param + 60) self._io_card.usb_host_pc_connector(True) # wait x seconds time.sleep(self.usb_sleep) # connect board self._device.connect_board() self.em_api.stop_auto_logger() # parse autolog response and reset them msic_list = self.em_api.get_autolog_msic_registers() thermal_list = self.em_api.get_autolog_thermal_sensor_info() self.em_api.clean_autolog() # init var full_constently_seen = False maintenance_constently_seen = False full_seen_one_time = False maintenance_seen_one_time = False # get the highest logs length log_length = max(len(thermal_list), len(msic_list)) for i in range(log_length): try: # get battery/charger info if len(msic_list) > i: msic_dict = msic_list[i] if len(msic_dict) > 1: msic_dict = msic_dict[1] # store result on xml self.__em_meas_tab.add_dict_measurement(msic_dict) # check that we reach full and stay in this state if msic_dict["BATTERY"]["STATUS"][0] == "FULL": full_constently_seen = True full_seen_one_time = True else: full_constently_seen = False # check that we reach maintenance charging if msic_dict["CHARGER"]["ENABLE_CHARGING"][0] == 0 and full_constently_seen: maintenance_constently_seen = True maintenance_seen_one_time = True else: maintenance_constently_seen = False # get thermal info if len(thermal_list) > i: thermal_dict = thermal_list[i] if len(thermal_dict) > 1: # store result on xml self.__em_meas_tab.add_dict_measurement(thermal_dict[1]) finally: self.__em_meas_tab.add_measurement( [self.get_time_tuple(), (self._em_cst.COMMENTS, "RUNTEST:Waiting for the DUT behavior to change when it is between [%s;%s] degree and not data cable plug" % (self.__min_temperature, self.__max_temperature))]) # switch meas to next meas self.__em_meas_tab.switch_to_next_meas() txt = "" # check that board reach full if not full_constently_seen: if not full_seen_one_time: txt = "battery FULL state was never reached at a temperature between [%s;%s] degree celsius " % (self.__min_temperature, self.__max_temperature) else: txt = "battery FULL state was seen but lost at a temperature between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature) # check that maintenance have started if we reach full elif not maintenance_constently_seen: if not maintenance_seen_one_time: txt = "MAINTENANCE charging state was never reached at a temperature between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature) else: txt = "MAINTENANCE charging was seen but lost at a temperature between [%s;%s] degree celsius" % (self.__min_temperature, self.__max_temperature) if txt != "": self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) # compute verdict by taking the last batt info seen self._meas_list.add_dict("EM_INFO", msic_list[-1][1]) self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, clean_meas_list=True)
class LabEmFuelGauging(EmUsecaseBase): """ Lab Energy Management class. """ __CYCLE_BEHAVIOR_VAL = [ "CHARGE_DISCHARGE", "DISCHARGE_CHARGE", "CHARGE_ONLY", "DISCHARGE_ONLY" ] DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call LAB_EM_BASE Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() self.__raw_behavior = str( self._tc_parameters.get_param_value("CYCLE_BEHAVIOR")).upper() load = self._tc_parameters.get_param_value("LOAD") self.__charger_type = self._tc_parameters.get_param_value( "CHARGER_TYPE") # Load Module Initialization self.__load_module = LoadModule() self.__load_module.add_load(load) # Initialize EM xml object # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) # track the case where DUT is lost to gather em info later self.__fail_to_get_em_info = False # ------------------------------------------------------------------------------ def set_up(self): """ Initialize the test """ # Call the UseCaseBase Setup function EmUsecaseBase.set_up(self) if self.__raw_behavior not in self.__raw_behavior: tmp_txt = "Unknown value for CYCLE_BEHAVIOR, expected value must be in % and we got %s" % ( self.__CYCLE_BEHAVIOR_VAL, self.__raw_behavior) self._logger.error(tmp_txt) raise AcsConfigException(AcsConfigException.INVALID_PARAMETER, tmp_txt) return Global.SUCCESS, "No errors" def run_test_body(self): """ Execute the test """ # Call LAB_EM_BASE Run function EmUsecaseBase.run_test_body(self) self.__fail_to_get_em_info = False # if we reach here it means that we have the correct value in behavior sorted_behavior = self.__raw_behavior.split("_") for action in sorted_behavior: action = action.strip() # Charge/discharge battery depending of fuel gauging option used if action == "CHARGE": # after a discharge board may be totally off , try to charge it a little bit if not self.is_board_and_acs_ok(): if self.__boot_in_mos_board( self.em_core_module.charge_time): self.__bring_board_above_vbatt_MOS_boot() self.__retrieve_lost_em_info() # Update Battery Information em_info = self.update_battery_info() if self.em_core_module.is_batt_capacity_below_target( em_info, self.em_core_module.batt_max_capacity): self.em_core_module.monitor_charging( self.em_core_module.batt_max_capacity, self.em_core_module.charge_time, self.__em_meas_tab) else: self._logger.info( "Cant charge the board as battery capacity is above the max capacity" ) elif action == "DISCHARGE": # Update Battery Information em_info = self.update_battery_info() if self.em_core_module.is_batt_capacity_above_target( em_info, self.em_core_module.batt_min_capacity): self.__monitor_discharging_with_load( self.em_core_module.batt_min_capacity, self.em_core_module.discharge_time, self.__em_meas_tab, self.__load_module) else: self._logger.info( "Cant discharge the board as battery capacity is below the min capacity" ) return Global.SUCCESS, "No errors" def clean_up(self): """ charge the board if necessary and retrieve applications logs. """ # Check that we are in the right boot mode, if not try to boot in the right one if self._device.get_boot_mode() not in ["MOS", "UNKNOWN"]: self._device.reboot(skip_failure=True) # if board if off , try tosee if it is not because of an bad plugged cable if self._device.get_boot_mode() == "UNKNOWN": self._io_card.usb_host_pc_connector(True) time.sleep(self.usb_sleep) if self._device.get_boot_mode() == "MOS": self._device.connect_board() # check if phone battery is too low and # charge it for a while (even if the board is down) # this try except give a final chance to get aplog in case of a crash try: if self.is_board_and_acs_ok(): self.update_battery_info() # enter here if we are not in MOS or in MOS with low voltage or capacity if (self._device.get_boot_mode() != "MOS") or ( -1 < self.batt_voltage <= self.vbatt_mos_shutdown) or ( -1 < self.batt_capacity <= 10): self.__boot_in_mos_board() except AcsBaseException as e: self._logger.error( "error happened during board charge process in clean_up") raise e finally: if self.is_board_and_acs_ok(): self.get_application_logs() def tear_down(self): """ End and dispose the test """ # call tear down after some operations EmUsecaseBase.tear_down(self) if self.is_board_and_acs_ok(): self.__load_module.stop_load() self.__retrieve_lost_em_info() # clean the board state and retrieve logs self.clean_up() if self.is_board_and_acs_ok(): self.__retrieve_lost_em_info() return Global.SUCCESS, "No errors" # ------------------------------------------------------------------------------ def __retrieve_lost_em_info(self): """ retrieve lost em info """ if self.__fail_to_get_em_info == True: self._logger.info("try to retrieve lost EM information") try: em_info = self.em_api.get_autolog_msic_registers() except AcsBaseException as e: self._logger.error(e) em_info = None try: thermal_list = self.em_api.get_autolog_thermal_sensor_info() except AcsBaseException as e: self._logger.error(e) thermal_list = None if thermal_list is not None or em_info is not None: self.em_core_module.fill_autolog_result( em_info, thermal_list, self.__em_meas_tab, "log from DUT connection lost") self.__fail_to_get_em_info = False def __monitor_discharging_with_load(self, input_min_capacity, discharge_time, meas_tab=None, load_module=None): """ monitor the discharging through dcp. :type input_min_capacity: int :param input_min_capacity: max battery capacity :type discharge_time: int :param discharge_time: time to spend with dcp plug in seconds :type meas_tab: XMLMeasurementFile :param meas_tab: object that represent store monitoring results :type load_module: LoadModule :param load_module: object that handle the load activation :rtype: float :return: return the discharge ration time/capacity """ self.update_battery_info() # set a fake value to capacity if status dead is wanted # cosmetic text computing good_text = "DEAD" # convert min_capacity into int min_capacity = -1 if str(input_min_capacity).isdigit(): min_capacity = int(input_min_capacity) if min_capacity > -1: good_text = str(min_capacity) + "%" # reset consecutive error if self.batt_capacity > min_capacity: self._logger.info( "Start to discharge battery until %s before %s seconds" % (good_text, self.em_core_module.discharging_time_limit)) # launch uecmd to help the discharge self._logger.info("load detected") self.__load_module.start_load() self.__discharge_when_no_data(min_capacity, good_text, discharge_time, meas_tab, load_module) #------------------------------------------------------------------------------------------------ def __boot_in_mos_board(self, charge_time=None): """ try to bring the board to boot in mos by doing several actions. :type charge_time: int :param charge_time: charging time in second :rtype : bool :return : True if boot mode is MOS """ self._logger.info("Try to boot board in MOS") if charge_time is None: charge_time = self.em_core_module._charge_empty_batt_time # get boot mode to see if we can check battery info boot_mode = self._device.get_boot_mode() if boot_mode != "MOS": # if we don't know the boot mode then plug usb host to see the mode self._device.disconnect_board() if boot_mode == "UNKNOWN": self._io_card.usb_host_pc_connector(True) time.sleep(self.usb_sleep) boot_mode = self._device.get_boot_mode() self._logger.debug("boot mode before charging : %s" % boot_mode) # charge the board in the fastest way for a defined duration self._logger.info("try to charge board during %ss" % charge_time) # connect USB DCP self._io_card.wall_charger_connector(True) # wait time to retrieve board from 0% time.sleep(charge_time) # Following step consider that we do not have data while charging , this way to do cover more DUT types. if boot_mode in ["COS", "UNKNOWN"]: cos_transition = 120 # once charged, press power button to boot self._io_card.press_power_button(self.pwr_btn_boot) # wait some time with the wall charger inserted to let the board charge a little bit if the boot did not work self._logger.debug( "wait %ss for boot transition happening after pushing power button" % cos_transition) time.sleep(cos_transition) boot_timeout = self._device.get_boot_timeout() # check in which mode we are self._io_card.usb_host_pc_connector(True) stop_time = time.time() + boot_timeout self._logger.debug("try to see boot mode before %ss" % boot_timeout) while time.time() < stop_time: boot_mode = self._device.get_boot_mode() if boot_mode != "UNKNOWN": break if boot_mode != "MOS": # force to reboot in MOS in case of POS or ROS self._device.reboot() boot_mode = self._device.get_boot_mode() self._logger.debug( "boot mode after charging %ss and trying to boot is : %s" % (charge_time, boot_mode)) return boot_mode == "MOS" def __bring_board_above_vbatt_MOS_boot(self): """ After a boot, we need to ensure that VBATT is enough high to avoid shutdown due to cable removal this is typically the case when you are able to boot in MOS with 0% of capacity """ self._logger.info("Try to bring board above MOS") boot_mode = self._device.get_boot_mode() if boot_mode == "MOS": self._device.connect_board() if self._device.is_available(): capacity = self.update_battery_info()["BATTERY"]["CAPACITY"][0] # create the msg but dont mean to use it msg = "Capacity is below 1 percent, trying to charge the board a little bit before continuing the test" else: capacity = 0 msg = "fail to read capacity after boot, we will charge the board and try again" if capacity < 1: self._logger.info(msg) # try to charge the board above MOS boot threshold tries = 2 timer = 450 while capacity < 1 and tries > 0: # connect WALL Charger self._device.disconnect_board() self._io_card.wall_charger_connector(True) # wait x min self._logger.info("Charge phone during %ss" % timer) time.sleep(timer) # connect pc host self._io_card.usb_host_pc_connector(True) # wait x seconds time.sleep(self.usb_sleep) # connect board boot_mode = self._device.get_boot_mode() if boot_mode != "UNKNOWN": self._device.connect_board() if self._device.is_available(): capacity = self.update_battery_info( )["BATTERY"]["CAPACITY"][0] tries -= 1 # try to boot in right mode if not MOS boot_mode = self._device.get_boot_mode() if boot_mode == "MOS": if not self._device.is_available(): self._device.connect_board() elif boot_mode != "UNKNOWN": self._device.reboot() if not self.is_board_and_acs_ok(): boot_mode = self._device.get_boot_mode() txt = "Fail to make board boot in MOS after having charging it, current boot mode is %s" % boot_mode self._logger.error(txt) raise DeviceException(DeviceException.OPERATION_FAILED, txt) #--------------------------------------------------------------------------------- def __discharge_when_no_data(self, min_capacity, good_text, discharge_time, meas_tab, load_module): """ private function served to monitor discharging when there is no data during charge. attempt to use a smart discharging way to adjust the battery capacity :type load_module: LoadModule :param load_module: object that handle the load activation """ # init var self.__fail_to_get_em_info = False measurement_fail = 0 connection_shutdown_counter = 0 adjusted_discharging_time = discharge_time ratio_d = 0 last_capacity = self.batt_capacity phone_as_reboot = False # start autolog here self.em_api.clean_autolog() # need to set the polling self.em_api.set_persistent_autolog(True) self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_THERMAL, "sequenced") self.em_api.add_fct_to_auto_logger(self.em_api.AUTOLOG_UEVENT, "sequenced") self.em_api.start_auto_logger(0, 5, "sequenced") # use thread to avoid blocking action when computing measurement lock = threading.Lock() thread_list = [] timeout_capacity_increase = 900 + discharge_time start_time_capacity_increase = time.time() end_time = time.time() + self.em_core_module.discharging_time_limit # count the number of discharge in case of small discharge time to take into account the whole waiting time # when doing discharge time adjustment discharge_iteration = 1 while self.batt_capacity > min_capacity and measurement_fail < 4: self.__fail_to_get_em_info = True # discharge only if we have data before if connection_shutdown_counter == 0: self.em_core_module.discharge_battery( adjusted_discharging_time) if self._device.get_boot_mode() != "MOS": connection_shutdown_counter += 1 # consider stopping the test if shutdown happen when capacity was low if connection_shutdown_counter < 0 and last_capacity < 10: self._logger.info( "connection lost happened when capacity was <10, stopping the discharge" ) break else: # try to boot the board in MOS boot_mode = self._device.get_boot_mode() if boot_mode == "UNKNOWN": self._io_card.press_power_button(self.pwr_btn_boot) start_time = time.time() self._logger.info( "Waiting atmost 60s to see boot transition") while time.time() - start_time < 60: boot_mode = self._device.get_boot_mode() if boot_mode != "UNKNOWN": break # Push power button elif boot_mode != "MOS": self._device.reboot(skip_failure=True) if self._device.get_boot_mode() != "MOS": connection_shutdown_counter += 1 if connection_shutdown_counter >= 2: self._logger.info( "battery must be empty or refuse to boot in MOS, stop discharging" ) break else: self._device.connect_board() connection_shutdown_counter = 0 phone_as_reboot = True if connection_shutdown_counter == 0: try: # parse autolog response and reset them self.update_battery_info() if self._device.get_boot_mode() == "MOS": msic_list = self.em_api.get_autolog_msic_registers() thermal_list = self.em_api.get_autolog_thermal_sensor_info( ) self.em_api.reset_running_log() # move to thread next computing t = threading.Thread( target=self.__threaded_feed_meas, args= (lock, msic_list, thermal_list, meas_tab, "SETUP:Discharge with load when no data connection" )) thread_list.append(t) t.start() self.__fail_to_get_em_info = False # compute the smart charging lost_capacity = last_capacity - self.batt_capacity self._logger.info( "%s capacity decreased during %ss" % (lost_capacity, adjusted_discharging_time)) # Detect if battery is charging or not decreasing if it is the case stop usecase if lost_capacity > 0: next_theorical_capacity = self.batt_capacity - lost_capacity # means that the timer is too long and we may be below the wanted capacity # we need to reduce the charging time # compute a ration capacity/second ratio_d = float( adjusted_discharging_time * discharge_iteration) / float(lost_capacity) adjusted_discharging_time = int( max((self.batt_capacity - min_capacity), 1) * ratio_d) if next_theorical_capacity < min_capacity: # limit the discharge time to 60s at min adjusted_discharging_time = min( adjusted_discharging_time, 60) # we are above the capacity thus we can wait a bigger time else: # limit the discharge time to 3600s at max adjusted_discharging_time = min( adjusted_discharging_time, 3600) start_time_capacity_increase = time.time() self._logger.info( "next adjusted discharging time will be %ss" % adjusted_discharging_time) # update last capacity only if we are not charging last_capacity = self.batt_capacity discharge_iteration = 1 else: discharge_iteration + 1 if load_module is not None and not ( (time.time() - start_time_capacity_increase) > timeout_capacity_increase): load_module.restart_load( consider_only_checkable_load=True) # stop usecase if board take too long to reach battery capacity if (time.time() - start_time_capacity_increase ) > timeout_capacity_increase: tmp_txt = "board capacity keep increasing during more than %ss instead of decreasing; abort usecase" % timeout_capacity_increase self._logger.error(tmp_txt) raise DeviceException(DeviceException.TIMEOUT_REACHED, tmp_txt) # reset error measurement_fail = 0 except Exception as e: # exit if we meet not decreasing capacity case if e.get_generic_error_message( ) == DeviceException.TIMEOUT_REACHED: raise e # in case of crash we consider that capacity increase timeout should be reset start_time_capacity_increase = time.time() # try to reconnect to the board if uecmd failed self._logger.error("fail to get measurement: " + str(e)) measurement_fail += 1 # stop usecase if board take too long to reach battery max capacity if time.time() > end_time: tmp_txt = "Phone failed to reach %s before %ss" % ( good_text, self.em_core_module.discharging_time_limit) self._logger.error(tmp_txt) raise DeviceException(DeviceException.TIMEOUT_REACHED, tmp_txt) # Restore load in case of reboot if phone_as_reboot and self.is_board_and_acs_ok(): # stop charging through usb load_module.restart_load() phone_as_reboot = False #------------------------------WHILE END----------------------------------------# try: # if device is off after discharging, exist with a warning if self.is_board_and_acs_ok(): self.phonesystem_api.clean_autolog() load_module.stop_load() else: tmp_txt = "The connection was lost during monitor discharging" self._logger.warning(tmp_txt) except Exception as e: tmp_txt = "non blocking error happen when trying to clean board after discharge: %s" % str( e) self._logger.error(tmp_txt) finally: # parse the thread list and wait then delete all started threads for thread_ele in thread_list: thread_ele.join() del thread_ele del thread_list def __threaded_feed_meas(self, lock, msic_list, thermal_list, meas_tab, general_msg): """ use a thread to fill the measurement file to avoid discharging/charging the board during measurement computing """ lock.acquire() try: self.em_core_module.fill_autolog_result(msic_list, thermal_list, meas_tab, general_msg) finally: lock.release()
class LabEmUpperCurrentDrawnThanChgCurrent(EmUsecaseBase): """ Lab Energy Management class. """ DEDICATED_BENCH = "POWER_SUPPLY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call the LAB_EM_USE_CASE init method EmUsecaseBase.__init__(self, tc_name, global_config) # Read CHARGER_TYPE from TC parameters self.__charger_type = self._tc_parameters.get_param_value( "CHARGER_TYPE", "SDP") # Read load to activate self.__load = self._tc_parameters.get_param_value("LOAD") # Activate Loadmodule instance self.__load_module = LoadModule() # Add list of LOAD to the loadmodule self.__load_module.add_load(self.__load) # get target and initialise measurment self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_UPPER_CURRENT_DRAWN_THAN_CHG_CURRENT", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, self.tcd_to_test) self.__scheduled_timer = 60 #------------------------------------------------------------------------------ def set_up(self): """ Initialize the test: """ EmUsecaseBase.set_up(self) # Load module to have a high current drawn self.__load_module.start_load() return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def run_test_body(self): """ Execute the test """ # Set API to start in x seconds to read and store all MSIC registers pid = self.em_api.get_msic_registers("scheduled", self.__scheduled_timer) # Disconnect board from ACS self._device.disconnect_board() # Plug charger self.em_core_module.plug_charger(self.__charger_type, True) # IBatt measurement meas_ibatt = self.em_core_module.get_battery_current() # add ibatt to measure list to target comparison self._meas_list.add("IBATT", meas_ibatt) # wait for stabilize current time.sleep(self.__scheduled_timer) # Measure current from usb meas_icharger = self.em_core_module.get_charger_current( self.__charger_type) self._meas_list.add("IUSB", meas_icharger) self.em_core_module.unplug_charger(self.__charger_type) # wait for charger to be unplugged time.sleep(self.usb_sleep) # plug data self._io_card.usb_host_pc_connector(True) # wait for data to be fully plugged time.sleep(self.usb_sleep) self._device.connect_board() # Read Platform OS and compare MSIC registers with expected values msic_registers = self.em_api.get_msic_registers("read", pid) # Read Platform OS and compare MSIC registers with expected values self._meas_list.add_dict("MSIC_REGISTER", msic_registers, msic_registers["TIME_STAMP"][0]) # generate em verdict self._em_meas_verdict.compare_list(self._meas_list, self._em_targets) self._em_meas_verdict.judge() self._meas_list.clean() return self._em_meas_verdict.get_current_result_v2() #------------------------------------------------------------------------------ def tear_down(self): """ End and dispose the test """ # desactivate load self.__load_module.stop_load() EmUsecaseBase.tear_down(self) return Global.SUCCESS, "No errors"
class LabEmCoolingActionVideoCapture(EmUsecaseBase): """ Class Lab cooling action during Video Capture """ DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() self.__zone_to_inspect = str( self._tc_parameters.get_param_value("THERMAL_ZONE_TO_MONITOR", "ANY")).upper().strip() self.__record_duration = self._tc_parameters.get_param_value( "VIDEO_RECORD_DURATION", 120, default_cast_type=int) self.__host_media = self._tc_parameters.get_param_value( "MEDIA_TO_RECORD", "", default_cast_type=str) self.__host_monitor = self._tc_parameters.get_param_value( "MONITOR_ON_WHICH_MEDIA_IS_PLAY", -1, default_cast_type=int) setup_load = self._tc_parameters.get_param_value("SETUP_TECHNO", "") self.__start_temp = self._tc_parameters.get_param_value( "SETUP_START_TEMPERATURE", 30, default_cast_type=int) self.__cooldown = self._tc_parameters.get_param_value( "SETUP_TIME_COOLDOWN_BOARD", 120, default_cast_type=int) use_camera_to_cooldown = self._tc_parameters.get_param_value( "SETUP_COOLDOWN_WITH_CAMERA", False, default_cast_type=str_to_bool) self.__temp_camera = None if use_camera_to_cooldown: self.__temp_camera = self._em.get_thermal_camera("THERMAL_CAMERA") # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_COOLING_ACTION_VIDEO_CAPTURE", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, consider_all_target=True) self.__video_capture_mod = VideoCaptureModule() self.__parser_api = self._device.get_uecmd("Aplog", True) self.__load_module = LoadModule() self.__load_module.add_load(setup_load) self.__video_record_api = self._device.get_uecmd("VideoRecorder", True) self.__media_player = None if self.__host_media != "": self.__media_player = MediaPlayer() # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) self.__ref_temp = None self.__pic_folder = self._saving_directory meas_file_name = os.path.join(self._saving_directory, "temperature_report.xml") self.__temp_meas_tab = XMLMeasurementFile(meas_file_name) #------------------------------------------------------------------------------ def set_up(self): """ Initialize the test """ # Call LabPwrMeasBase base Setup function EmUsecaseBase.set_up(self) # first turn off board for a while to allow it to cool down if self.__media_player is None: self._logger.warning( "no media was set to be launched on the HOST side, no media will be play during video capture" ) else: if not os.path.exists(self.__host_media): error_msg = "The video %s you want to play on the host side does not exist" % self.__host_media self._logger.error(error_msg) raise AcsConfigException(AcsConfigException.FILE_NOT_FOUND, error_msg) # check that logs you want to parse exist: stop_tag = "TEST_IF_COOLING_INTENT_EXIST-" + time.strftime( "-%Y-%m-%d_%Hh%M.%S") self.__parser_api.inject_tag(stop_tag) cooling_intents = self.__parser_api.find_txt_between_tag( self.__parser_api.PUPDR_MISC_TAG.get("MAIN_BOOT"), stop_tag, self.__parser_api.THERMAL_TAG.get("COOLING_INTENT"), raise_error=False) if len(cooling_intents) <= 0: # it means that cooling intent does not exist, we cant do the test error_msg = "No thermal throttling/de-throttling message has been seen since last boot, check if thermal service is working on your DUT or an update of the thermal parser may be necessary" self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) ####################################### SETUP CAMERAS ########################################### if self.__temp_camera is not None: # init camera connection self.__temp_camera.init() self.__temp_camera.delete_all_pictures() # clean video storage self.__video_record_api.clean_video_storage() # Update Battery Information ####################################### CHARGE BOARD ########################################### em_info = self.update_battery_info() if self.em_core_module.is_batt_capacity_below_target( em_info, self.em_core_module.batt_min_capacity): # charge part self.em_core_module.monitor_charging( self.em_core_module.batt_min_capacity, self.em_core_module.charge_time, self.__em_meas_tab) ####################################### COOLDOWN BOARD ########################################### self.phonesystem_api.set_screen_timeout(3600) self.__video_capture_mod.setup() self._device.switch_off() # remove any cable after this self._io_card.remove_cable("ALL") if self.__temp_camera is not None: # do the thermal camera setting during the off phase to let the board cool down self._setup_camera() # wait a given time to let the board cool down self._monitor_board_temp(self.__cooldown, self.__start_temp) else: # wait a given time to let the board cool down wait_time = self.__cooldown + 15 self._logger.info( "waiting %ss+15s to let the board cool down while it should be OFF" % str(self.__cooldown)) time.sleep(wait_time) # turn on board and launch every load self._device.switch_on() # this measurement is done only for debugging purpose self.em_api.get_thermal_sensor_info() # start all environment load self.__load_module.start_load() if self.__temp_camera is not None: # collect a ref temperature before starting the test once board is on cam_meas = self.__temp_camera.get_measurement_from_box() self.__temp_meas_tab.add_dict_measurement(cam_meas) self.__temp_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "Setup: Temperature just before starting the test") ]) self.__temp_meas_tab.switch_to_next_meas() return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def run_test_body(self): """ run test """ EmUsecaseBase.run_test_body(self) # inject a start tag with the host date as unique id start_tag = "START_WAITING_FOR_INTENT-" + time.strftime( "-%Y-%m-%d_%Hh%M.%S") if not self.__parser_api.inject_tag(start_tag): error_msg = "The tag [%s] failed to be injected on logs" % ( start_tag) self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # start HOST Video if not self.__media_player is None: self.__media_player.play(self.__host_media, self.__host_monitor) # media may take time to start start_time = time.time() while time.time() - start_time < 10: time.sleep(1) if self.__media_player.is_playing(): break if not self.__media_player.is_playing(): error_msg = "Fail to start the video playback on the HOST side" self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # start video recording self.phonesystem_api.wake_screen() self.phonesystem_api.set_phone_lock(False) raw_video_filename, _ = self.__video_capture_mod.start_recording() # Check if the video file exist if not self.__video_record_api.check_video_exist(raw_video_filename): self._logger.error("Recording fail to start, retry again") raw_video_filename, _ = self.__video_capture_mod.start_recording() # Check if the video file exist if not self.__video_record_api.check_video_exist( raw_video_filename): screen_path = self._device.screenshot(filename=os.path.join( self.__pic_folder, "camera_record_start_fail.png")) error_msg = "Fail to see the raw video file generated during the record, it seems that the video record may has not started." if screen_path is not None: error_msg += "\nPlease check the screenshot at %s." % screen_path self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # remove any cable self._device.disconnect_board() self._io_card.remove_cable("ALL") self._logger.info("waiting %ss to let the video recording be done" % str(self.__record_duration)) time.sleep(self.__record_duration) # reconnect usb cable self._io_card.usb_host_pc_connector(True) time.sleep(self.usb_sleep) self._device.connect_board() # check if board did not went off during the test boot_mode = self._device.get_boot_mode() if boot_mode != "MOS": error_msg = "The board is seen not booted in MOS but in %s at the end of the test , cant compute result" % ( boot_mode) self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # get a screenshot to check if camera is still recording self._device.screenshot(filename=os.path.join( self.__pic_folder, "test_end_board_screen.png")) self.__video_capture_mod.stop_recording() # inject a stop tag with the host date as unique id stop_tag = "STOP_WAITING_FOR_INTENT-" + time.strftime( "-%Y-%m-%d_%Hh%M.%S") if not self.__parser_api.inject_tag(stop_tag): error_msg = "The tag [%s] failed to be injected on logs " % ( stop_tag) self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # stop HOST Video if not self.__media_player is None: self.__media_player.stop() # get start intent to extract the time start_intent = self.__parser_api.find_txt_between_tag( start_tag, stop_tag, self.__video_record_api.CAMERA_TAG.get("RECORD_START"), raise_error=True)[0] # "ACS_TAG_INJECTOR: START_WAITING_FOR_INTENT--2014-12-22_11h40.22" cooling_intents = self.__parser_api.find_txt_between_tag( start_tag, stop_tag, self.__parser_api.THERMAL_TAG.get("COOLING_INTENT"), raise_error=False) action_seen = False local_msg = "" action_before_video = False # parse every zone to analyze only the wanted one for cooling_intent in cooling_intents: result = self.__parser_api.parse_thermal_cooling_event( cooling_intent) if result is not None: zone, level, temperature = result zone = zone.upper() # this way allow to compare simple str to several monitored zone # if we are in ANY case, compute the first seen and leave the test here if self.__zone_to_inspect in ["ANY", zone]: # get the time structure for the cooling intent thermal_time_structure, thermal_millisec = self.__parser_api.get_log_date( cooling_intent) time_cooling_happen = float( calendar.timegm(thermal_time_structure)) + ( float(thermal_millisec) * 0.001) # get the time structure for start intent start_time_structure, start_millisec = self.__parser_api.get_log_date( start_intent) time_intent_sent = float( calendar.timegm(start_time_structure)) + ( float(start_millisec) * 0.001) # if the time between cooling action and the video camera start is < 0 then it is a pass but with a warning spend_time = time_cooling_happen - time_intent_sent if spend_time < 0: self._meas_list.add( "TIME_TAKEN_TO_SEE_FIRST_COOLING_ACTION", spend_time, "SECOND") local_msg += "A cooling action has been seen %ss before video recording start: zone=%s level=%s temperature=%s.\n" % ( abs(spend_time), zone, level, temperature) action_before_video = True else: self._meas_list.add( "TIME_TAKEN_TO_SEE_FIRST_COOLING_ACTION", spend_time, "SECOND") local_msg += "First cooling action seen %ss after video recording start: zone=%s level=%s temperature=%s.\n" % ( spend_time, zone, level, temperature) action_seen = True break msg = "no cooling action seen." if local_msg != "": msg = local_msg if action_before_video == True: msg += "A manual check on cooling actions before video start is required to see if it is a real FAIL or PASS.." # generate em verdict if not action_seen: self._meas_list.add("TIME_TAKEN_TO_SEE_FIRST_COOLING_ACTION", self.__record_duration, "SECOND") self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, True) self._em_meas_verdict.judge() verdict, verdict_msg = self._em_meas_verdict.get_current_result_v2() msg = msg + "\n" + verdict_msg return verdict, msg def tear_down(self): """ End and dispose the test """ EmUsecaseBase.tear_down(self) if self.__temp_camera is not None: try: self.__temp_camera.delete_all_pictures() self.__temp_camera.set_linear_temperature_mode(False) except Exception as e: self._logger.error( "error happen when releasing thermal camera %s" % str(e)) finally: self.__temp_camera.release() if not self.__media_player is None: self.__media_player.stop() # stop all load self.em_core_module.clean_up() self.__load_module.stop_load() # stop any remaining video capture self.__video_record_api.force_stop() self.__video_record_api.restore_camera_setup() self.__video_record_api.clean_video_storage() return Global.SUCCESS, "No errors" def _setup_camera(self): """ setup the camera """ self.__temp_camera.auto_setup() x, y, h, w = self.__temp_camera.get_image_geometry() self.__temp_camera.set_linear_temperature_mode(True) self.__temp_camera.configure_measurement_box(True, x, y, h, w) def _monitor_board_temp(self, monitor_timeout, target_temp): """ monitor board temperature until it reach given value or a value below it. :todo: this function only monitor for cooling condition, it may be change to offer the possibility to monitor for heating one """ start_temp_seen = False wait_time = monitor_timeout + 15 self._logger.info( "waiting at most %ss+15s to let the board cool down below %s degree" % (str(monitor_timeout), str(target_temp))) start_time = time.time() while time.time() - start_time < wait_time: cam_meas = self.__temp_camera.get_measurement_from_box() try: self.__temp_meas_tab.add_dict_measurement(cam_meas) self.__temp_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "Setup: cooling down the board") ]) self.__temp_meas_tab.switch_to_next_meas() except Exception as e: msg = "error happen when filling temperature value in file: %s" % str( e) self._logger.error(msg) if cam_meas["MAXT"][0] <= target_temp: self._logger.info( "the MAX temperature seen is %s, test can continue " % str(cam_meas["MAXT"])) # take a ref picture pic_path = self.__temp_camera.take_picture("ref_phone_off") self.__temp_camera.pull_picture(pic_path, self.__pic_folder) start_temp_seen = True self.__ref_temp = cam_meas["MAXT"][0] break if not start_temp_seen: cam_meas = self.__temp_camera.get_measurement_from_box() pic_path = self.__temp_camera.take_picture( "pic_temp_after_cooldown_fail") self.__temp_camera.pull_picture(pic_path, self.__pic_folder) error_msg = "The board fail to cool down below %s degree after spending %ss in OFF state, the last temperature seen was %s degree" % ( target_temp, monitor_timeout, str(cam_meas["MAXT"])) self._logger.error(error_msg) self._device.switch_on() raise DeviceException(DeviceException.INVALID_DEVICE_STATE, error_msg)
class LabEmCoolingActionBenchmark(EmUsecaseBase): """ Montinor cooling action during benchmark """ DEDICATED_BENCH = "BATTERY_BENCH" def __init__(self, tc_name, global_config): """ Constructor """ # Call UseCase base Init function EmUsecaseBase.__init__(self, tc_name, global_config) # init fuel gauging parameters self.em_core_module.init_fg_param() self.__zone_to_inspect = str( self._tc_parameters.get_param_value("THERMAL_ZONE_TO_MONITOR", "ANY")).upper().strip() setup_load = self._tc_parameters.get_param_value("SETUP_TECHNO", "") self.__cooldown = self._tc_parameters.get_param_value( "SETUP_TIME_COOLDOWN_BOARD", 1800, default_cast_type=int) self.__start_temp = self._tc_parameters.get_param_value( "SETUP_START_TEMPERATURE", 30, default_cast_type=int) use_camera_to_cooldown = self._tc_parameters.get_param_value( "SETUP_COOLDOWN_WITH_CAMERA", False, default_cast_type=str_to_bool) self.__temp_camera = None if use_camera_to_cooldown: self.__temp_camera = self._em.get_thermal_camera("THERMAL_CAMERA") self.__benchmark_module = BenchmarkModule() self.__load_module = LoadModule() self.__load_module.add_load(setup_load) # measurement file meas_file_name = os.path.join(self._saving_directory, "EM_meas_report.xml") self.__em_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "temperature_report.xml") self.__temp_meas_tab = XMLMeasurementFile(meas_file_name) meas_file_name = os.path.join(self._saving_directory, "benchmark_score_report.xml") self.__benchamrk_tab = XMLMeasurementFile(meas_file_name) self.__ref_temp = None self.__pic_folder = self._saving_directory self.__host_test_start_time = None self.__bk_delay = 30 self.__parser_api = self._device.get_uecmd("Aplog", True) # Call ConfigsParser to parse Energy_Management self._em_targets = self._target_file.parse_energy_management_targets( "LAB_EM_COOLING_ACTION_BENCHMARK", self._tc_parameters.get_params_as_dict(), self._device.get_phone_model()) # load targets in order to measure iteration self._em_meas_verdict.load_target(self._em_targets, consider_all_target=True) #------------------------------------------------------------------------------ def __push_score(self, score_list): """ take in entry the result for get_score() and format the benchmark score for TCR upload in order to upload all the score together :type score_list: list :param score_list: a list of dictionary containing score from benchmarks :rtype: dict of dict :return: return a dict of dictionary """ result = {} i = 0 # get the highest number of digit in score list, for example 2 for 10 max_iter_count = len(str(len(score_list))) max_logged_iteration = 1 # search for the highest logged iteration for dico in score_list: digit_length = len(str(dico.get(BenchmarkModule.DITER, 1))) # we consider that the value is always a digit when it is returned if digit_length > max_logged_iteration: max_logged_iteration = digit_length for dico in score_list: i += 1 # push dico on sysfs self.__benchamrk_tab.add_dict_measurement(dico) self.__benchamrk_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "Getting benchmark scores") ]) self.__benchamrk_tab.switch_to_next_meas() # push dico on TCR if len(dico) > 1: score_dico = {} score_iter = dico.get(BenchmarkModule.DITER) if score_iter is None: i_str = str(i).zfill(max_iter_count) iter_tag = "BENCHMARK_MANUAL_COUNT_ITERATION_%s" % i_str else: score_iter = str(score_iter).zfill(max_logged_iteration) iter_tag = "BENCHMARK_ITERATION_%s" % score_iter for key, value in dico.iteritems(): # store everything under iteration tag except iteration if key != BenchmarkModule.DITER: score_dico[key] = value result[iter_tag] = score_dico if len(result) > 0: LiveReporting.instance().update_running_tc_info(test_info=result) return result def set_up(self): """ Initialize the test """ EmUsecaseBase.set_up(self) self.__benchmark_module.setup() if self.__temp_camera is not None: # init camera connection self.__temp_camera.init() self.__temp_camera.delete_all_pictures() # check that logs you want to parse exist: stop_tag = "TEST_IF_COOLING_INTENT_EXIST-" + time.strftime( "-%Y-%m-%d_%Hh%M.%S") self.__parser_api.inject_tag(stop_tag) cooling_intents = self.__parser_api.find_txt_between_tag( self.__parser_api.PUPDR_MISC_TAG.get("MAIN_BOOT"), stop_tag, self.__parser_api.THERMAL_TAG.get("COOLING_INTENT"), raise_error=False) if len(cooling_intents) <= 0: # it means that cooling intent does not exist, we cant do the test error_msg = "No thermal throttling/de-throttling message has been seen since last boot, check if thermal service is working on your DUT or an update of the thermal parser may be necessary" self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) ####################################### CHARGE BOARD ########################################### # Update Battery Information em_info = self.update_battery_info() if self.em_core_module.is_batt_capacity_below_target( em_info, self.em_core_module.batt_min_capacity): # charge part self.em_core_module.monitor_charging( self.em_core_module.batt_min_capacity, self.em_core_module.charge_time, self.__em_meas_tab) ####################################### COOL DOWN BOARD ########################################### self.phonesystem_api.set_screen_timeout(3600) self._device.switch_off() # remove any cable after this self._io_card.remove_cable("ALL") if self.__temp_camera is not None: # do the thermal camera setting during the off phase to let the board cool down self._setup_camera() # wait a given time to let the board cool down self._monitor_board_temp(self.__cooldown, self.__start_temp) else: # wait a given time to let the board cool down wait_time = self.__cooldown + 15 self._logger.info( "waiting %ss+15s to let the board cool down while it should be OFF" % str(self.__cooldown)) time.sleep(wait_time) # turn on board and launch every load self._device.switch_on() # this measurement is done only for debugging purpose self.em_api.get_thermal_sensor_info() # start all environment load self.__load_module.start_load() if self.__temp_camera is not None: # collect a ref temperature before starting the test once board is on cam_meas = self.__temp_camera.get_measurement_from_box() self.__temp_meas_tab.add_dict_measurement(cam_meas) self.__temp_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "Setup: Temperature just before starting the test") ]) self.__temp_meas_tab.switch_to_next_meas() ####################################### START BENCHMARK ########################################### self.phonesystem_api.wake_screen() self.phonesystem_api.set_phone_lock(False) self.__benchmark_module.execute_test(background=True, delay=self.__bk_delay) self.__host_test_start_time = time.time() start_timeout = 60 running = False start_time = time.time() self._logger.info( "wait at most %ss to see that benchmark has been launched" % str(start_timeout)) while time.time() - start_time < start_timeout: running = self.__benchmark_module.is_running() if running: break if not running: txt = "benchmark fail to start after waiting %ss" % str( start_timeout) self._logger.error(txt) self._logger.error("benchmark execution logs for debugging : %s " % self.__benchmark_module.get_output_log()) raise DeviceException(DeviceException.OPERATION_FAILED, txt) self.__benchmark_module.check_crash() return Global.SUCCESS, "No errors" #------------------------------------------------------------------------------ def run_test_body(self): """ run test """ EmUsecaseBase.run_test_body(self) ####################################### TAG TEST START, WAIT FOR TEST, THEN TAG TEST END ########################################### # inject a start tag with the host date as unique id start_tag = "START_WAITING_FOR_INTENT-" + time.strftime( "-%Y-%m-%d_%Hh%M.%S") if not self.__parser_api.inject_tag(start_tag): error_msg = "The tag [%s] failed to be injected on logs" % ( start_tag) self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # remove any cable self._device.disconnect_board() self._io_card.remove_cable("ALL") bk_duration = self.__benchmark_module.get_exec_whole_duration() delay_left = self.__bk_delay - (time.time() - self.__host_test_start_time) if delay_left > 1: self._logger.info( "Waiting %ss to align benckmark launching time with beginning of waiting duration" % str(delay_left)) time.sleep(delay_left) start_time = time.time() self._logger.info("waiting %ss of benchmark execution" % str(bk_duration)) time.sleep(bk_duration) stop_time = time.time() # reconnect usb cable warning_crash = False self._io_card.usb_host_pc_connector(True) time.sleep(self.usb_sleep) self._device.connect_board() # check if board did not went off during the test boot_mode = self._device.get_boot_mode() if boot_mode != "MOS": error_msg = "The board is seen not booted in MOS but in %s at the end of the test , cant compute result" % ( boot_mode) self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) self._device.screenshot(filename=os.path.join( self.__pic_folder, "test_end_board_screen.png")) # inject a stop tag with the host date as unique id stop_tag = "STOP_WAITING_FOR_INTENT-" + time.strftime( "-%Y-%m-%d_%Hh%M.%S") if not self.__parser_api.inject_tag(stop_tag): error_msg = "The tag [%s] failed to be injected on logs " % ( stop_tag) self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) ####################################### CHECK BENCHMARK CRASH ########################################### # first check that there were no crashes start_date = self.__benchmark_module.get_start_date() crash_date, _ = self.__benchmark_module.get_crash() # if a crash happen but after that the test end , then the test may be passed with a warning if start_date is not None: if crash_date is not None: bk_exact_duration = crash_date - start_date host_exact_duration = stop_time - start_time if bk_exact_duration <= host_exact_duration: self.__benchmark_module.check_crash() else: warning_crash = True else: error_msg = "Cant retrieve benchmark start date, it seems that the benchmark may have not been started" self._logger.error(error_msg) raise DeviceException(DeviceException.OPERATION_FAILED, error_msg) # try to stop the benchmark, if it fail, continue the measurement try: self.__benchmark_module.stop_execution() except Exception as e: self._logger.error("error happen when stopping benchmark %s" % str(e)) # upload benchmark result try: score_list = self.__benchmark_module.get_score() self.__push_score(score_list) except Exception as e: self._logger.error( "Error happen when trying to upload benchmark: %s" % str(e)) ####################################### SEARCH FOR COOLING ACTION ########################################### # get start intent to extract the time start_intent = self.__parser_api.find_txt_between_tag( start_tag, stop_tag, self.__benchmark_module.BENCHMARK_START_TAG, raise_error=True)[0] # "ACS_TAG_INJECTOR: START_WAITING_FOR_INTENT--2014-12-22_11h40.22" cooling_intents = self.__parser_api.find_txt_between_tag( start_tag, stop_tag, self.__parser_api.THERMAL_TAG.get("COOLING_INTENT"), raise_error=False) action_seen = False local_msg = "" action_before_benchmark = False # parse every zone to analyze only the wanted one for cooling_intent in cooling_intents: result = self.__parser_api.parse_thermal_cooling_event( cooling_intent) if result is not None: zone, level, temperature = result zone = zone.upper() # this way allow to compare simple str to several monitored zone # if we are in ANY case, compute the first seen and leave the test here if self.__zone_to_inspect in ["ANY", zone]: # get the time structure for the cooling intent thermal_time_structure, thermal_millisec = self.__parser_api.get_log_date( cooling_intent) time_cooling_happen = float( calendar.timegm(thermal_time_structure)) + ( float(thermal_millisec) * 0.001) # get the time structure for start intent start_time_structure, start_millisec = self.__parser_api.get_log_date( start_intent) time_intent_sent = float( calendar.timegm(start_time_structure)) + ( float(start_millisec) * 0.001) spend_time = time_cooling_happen - time_intent_sent if spend_time < 0: self._meas_list.add( "TIME_TAKEN_TO_SEE_FIRST_COOLING_ACTION", spend_time, "SECOND") local_msg += "A cooling action has been seen %ss before benchmark start and after board was cool down : zone=%s level=%s temperature=%s.\n" % ( abs(spend_time), zone, level, temperature) action_before_benchmark = True else: self._meas_list.add( "TIME_TAKEN_TO_SEE_FIRST_COOLING_ACTION", spend_time, "SECOND") local_msg += "First cooling action seen %ss after benchmark start: zone=%s level=%s temperature=%s.\n" % ( spend_time, zone, level, temperature) action_seen = True break msg = "no cooling action seen." if local_msg != "": msg = local_msg if action_before_benchmark == True: msg += "A manual check on cooling actions before benchmark is required to see if it is a real FAIL or PASS.." # generate em verdict if not action_seen: self._meas_list.add("TIME_TAKEN_TO_SEE_FIRST_COOLING_ACTION", bk_duration, "SECOND") self._em_meas_verdict.compare_list(self._meas_list, self._em_targets, True) self._em_meas_verdict.judge() verdict, verdict_msg = self._em_meas_verdict.get_current_result_v2() msg = msg + "\n" + verdict_msg if warning_crash: msg = "A crash happened but it was after the test end, result can be computed.\n" + msg msg += "\nBenchmark scores may be seen in file %s" % self.__benchamrk_tab.get_report_path( ) return verdict, msg def tear_down(self): """ End and dispose the test """ EmUsecaseBase.tear_down(self) benchmark_stopped = False # stop benchmark here to prevent it from running in loop while charging below if self.is_board_and_acs_ok(): try: self.__benchmark_module.clean() benchmark_stopped = True except Exception as e: self._logger.error("error happen when stopping benchmark %s" % str(e)) # stop camera anyway if self.__temp_camera is not None: try: self.__temp_camera.delete_all_pictures() self.__temp_camera.set_linear_temperature_mode(False) except Exception as e: self._logger.error( "error happen when releasing thermal camera %s" % str(e)) finally: self.__temp_camera.release() # stop all load self.em_core_module.clean_up() self.__load_module.stop_load() if not benchmark_stopped: self.__benchmark_module.clean() # stop benchmark return Global.SUCCESS, "No errors" def _setup_camera(self): """ setup the camera """ self.__temp_camera.auto_setup() x, y, h, w = self.__temp_camera.get_image_geometry() self.__temp_camera.set_linear_temperature_mode(True) self.__temp_camera.configure_measurement_box(True, x, y, h, w) def _monitor_board_temp(self, monitor_timeout, target_temp): """ monitor board temperature until it reach given value or a value below it. :todo: this function only monitor for cooling condition, it may be change to offer the possibility to monitor for heating one """ start_temp_seen = False wait_time = monitor_timeout + 15 self._logger.info( "waiting at most %ss+15s to let the board cool down below %s degree" % (str(monitor_timeout), str(target_temp))) start_time = time.time() while time.time() - start_time < wait_time: cam_meas = self.__temp_camera.get_measurement_from_box() try: self.__temp_meas_tab.add_dict_measurement(cam_meas) self.__temp_meas_tab.add_measurement([ self.get_time_tuple(), (self._em_cst.COMMENTS, "Setup: cooling down the board") ]) self.__temp_meas_tab.switch_to_next_meas() except Exception as e: msg = "error happen when filling temperature value in file: %s" % str( e) self._logger.error(msg) if cam_meas["MAXT"][0] <= target_temp: self._logger.info( "the MAX temperature seen is %s, test can continue " % str(cam_meas["MAXT"])) # take a ref picture pic_path = self.__temp_camera.take_picture("ref_phone_off") self.__temp_camera.pull_picture(pic_path, self.__pic_folder) start_temp_seen = True self.__ref_temp = cam_meas["MAXT"][0] break if not start_temp_seen: cam_meas = self.__temp_camera.get_measurement_from_box() pic_path = self.__temp_camera.take_picture( "pic_temp_after_cooldown_fail") self.__temp_camera.pull_picture(pic_path, self.__pic_folder) error_msg = "The board fail to cool down below %s degree after spending %ss in OFF state, the last temperature seen was %s degree" % ( target_temp, monitor_timeout, str(cam_meas["MAXT"])) self._logger.error(error_msg) self._device.switch_on() raise DeviceException(DeviceException.INVALID_DEVICE_STATE, error_msg)