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
Beispiel #2
0
    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)
Beispiel #4
0
    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
Beispiel #6
0
    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)
Beispiel #12
0
    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
Beispiel #14
0
    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"
Beispiel #17
0
    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)
Beispiel #19
0
    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)
Beispiel #21
0
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)
Beispiel #23
0
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
Beispiel #24
0
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"
Beispiel #29
0
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)
Beispiel #30
0
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)