Example #1
0
    def take_bug_report(self,
                        test_name=None,
                        begin_time=None,
                        timeout=300,
                        destination=None):
        """Takes a bug report on the device and stores it in a file.

        Args:
            test_name: Name of the test method that triggered this bug report.
            begin_time: Timestamp of when the test started. If not set, then
                this will default to the current time.
            timeout: float, the number of seconds to wait for bugreport to
                complete, default is 5min.
            destination: string, path to the directory where the bugreport
                should be saved.

        Returns:
            A string that is the absolute path to the bug report on the host.
        """
        prefix = DEFAULT_BUG_REPORT_NAME
        if test_name:
            prefix = '%s,%s' % (DEFAULT_BUG_REPORT_NAME, test_name)
        if begin_time is None:
            begin_time = mobly_logger.get_log_file_timestamp()

        new_br = True
        try:
            stdout = self.adb.shell('bugreportz -v').decode('utf-8')
            # This check is necessary for builds before N, where adb shell's ret
            # code and stderr are not propagated properly.
            if 'not found' in stdout:
                new_br = False
        except adb.AdbError:
            new_br = False

        if destination is None:
            destination = os.path.join(self.log_path, 'BugReports')
        br_path = utils.abs_path(destination)
        utils.create_dir(br_path)
        filename = self.generate_filename(prefix, str(begin_time), 'txt')
        if new_br:
            filename = filename.replace('.txt', '.zip')
        full_out_path = os.path.join(br_path, filename)
        # in case device restarted, wait for adb interface to return
        self.wait_for_boot_completion()
        self.log.debug('Start taking bugreport.')
        if new_br:
            out = self.adb.shell('bugreportz', timeout=timeout).decode('utf-8')
            if not out.startswith('OK'):
                raise DeviceError(self, 'Failed to take bugreport: %s' % out)
            br_out_path = out.split(':')[1].strip()
            self.adb.pull([br_out_path, full_out_path])
        else:
            # shell=True as this command redirects the stdout to a local file
            # using shell redirection.
            self.adb.bugreport(' > "%s"' % full_out_path,
                               shell=True,
                               timeout=timeout)
        self.log.debug('Bugreport taken at %s.', full_out_path)
        return full_out_path
Example #2
0
def load_test_config_file(test_config_path, tb_filters=None):
    """Processes the test configuration file provied by user.

    Loads the configuration file into a dict, unpacks each testbed
    config into its own dict, and validate the configuration in the
    process.

    Args:
        test_config_path: Path to the test configuration file.
        tb_filters: A subset of test bed names to be pulled from the config
            file. If None, then all test beds will be selected.

    Returns:
        A list of test configuration dicts to be passed to
        test_runner.TestRunner.
    """
    configs = _load_config_file(test_config_path)
    if tb_filters:
        tbs = []
        for tb in configs[keys.Config.key_testbed.value]:
            if tb[keys.Config.key_testbed_name.value] in tb_filters:
                tbs.append(tb)
        if len(tbs) != len(tb_filters):
            raise MoblyConfigError(
                'Expect to find %d test bed configs, found %d. Check if'
                ' you have the correct test bed names.' %
                (len(tb_filters), len(tbs)))
        configs[keys.Config.key_testbed.value] = tbs
    mobly_params = configs.get(keys.Config.key_mobly_params.value, {})
    # Decide log path.
    log_path = mobly_params.get(keys.Config.key_log_path.value,
                                _DEFAULT_LOG_PATH)
    if ENV_MOBLY_LOGPATH in os.environ:
        log_path = os.environ[ENV_MOBLY_LOGPATH]
    log_path = utils.abs_path(log_path)
    # Validate configs
    _validate_test_config(configs)
    _validate_testbed_configs(configs[keys.Config.key_testbed.value])
    # Transform config dict from user-facing key mapping to internal config object.
    test_configs = []
    for original_bed_config in configs[keys.Config.key_testbed.value]:
        test_run_config = TestRunConfig()
        test_run_config.testbed_name = original_bed_config[
            keys.Config.key_testbed_name.value]
        # Deprecated, use testbed_name
        test_run_config.test_bed_name = test_run_config.testbed_name
        test_run_config.log_path = log_path
        test_run_config.controller_configs = original_bed_config.get(
            keys.Config.key_testbed_controllers.value, {})
        test_run_config.user_params = original_bed_config.get(
            keys.Config.key_testbed_test_params.value, {})
        test_configs.append(test_run_config)
    return test_configs
Example #3
0
    def take_bug_report(self,
                        test_name,
                        begin_time,
                        timeout=300,
                        destination=None):
        """Takes a bug report on the device and stores it in a file.

        Args:
            test_name: Name of the test method that triggered this bug report.
            begin_time: Timestamp of when the test started.
            timeout: float, the number of seconds to wait for bugreport to
                complete, default is 5min.
            destination: string, path to the directory where the bugreport
                should be saved.
        """
        new_br = True
        try:
            stdout = self.adb.shell('bugreportz -v').decode('utf-8')
            # This check is necessary for builds before N, where adb shell's ret
            # code and stderr are not propagated properly.
            if 'not found' in stdout:
                new_br = False
        except adb.AdbError:
            new_br = False
        if destination:
            br_path = utils.abs_path(destination)
        else:
            br_path = os.path.join(self.log_path, 'BugReports')
        utils.create_dir(br_path)
        base_name = ',%s,%s.txt' % (begin_time, self._normalized_serial)
        if new_br:
            base_name = base_name.replace('.txt', '.zip')
        test_name_len = utils.MAX_FILENAME_LEN - len(base_name)
        out_name = test_name[:test_name_len] + base_name
        full_out_path = os.path.join(br_path, out_name.replace(' ', r'\ '))
        # in case device restarted, wait for adb interface to return
        self.wait_for_boot_completion()
        self.log.info('Taking bugreport for %s.', test_name)
        if new_br:
            out = self.adb.shell('bugreportz', timeout=timeout).decode('utf-8')
            if not out.startswith('OK'):
                raise DeviceError(self, 'Failed to take bugreport: %s' % out)
            br_out_path = out.split(':')[1].strip()
            self.adb.pull([br_out_path, full_out_path])
        else:
            # shell=True as this command redirects the stdout to a local file
            # using shell redirection.
            self.adb.bugreport(' > "%s"' % full_out_path,
                               shell=True,
                               timeout=timeout)
        self.log.info('Bugreport for %s taken at %s.', test_name,
                      full_out_path)
Example #4
0
def _load_config_file(path):
    """Loads a test config file.

    The test config file has to be in YAML format.

    Args:
        path: A string that is the full path to the config file, including the
              file name.

    Returns:
        A dict that represents info in the config file.
    """
    with open(utils.abs_path(path), 'r') as f:
        conf = yaml.load(f)
        return conf
Example #5
0
def load_test_config_file(test_config_path, tb_filters=None):
    """Processes the test configuration file provied by user.

    Loads the configuration file into a json object, unpacks each testbed
    config into its own json object, and validate the configuration in the
    process.

    Args:
        test_config_path: Path to the test configuration file.
        tb_filters: A subset of test bed names to be pulled from the config
                    file. If None, then all test beds will be selected.

    Returns:
        A list of test configuration json objects to be passed to
        test_runner.TestRunner.
    """
    configs = utils.load_config(test_config_path)
    if tb_filters:
        tbs = []
        for tb in configs[keys.Config.key_testbed.value]:
            if tb[keys.Config.key_testbed_name.value] in tb_filters:
                tbs.append(tb)
        if len(tbs) != len(tb_filters):
            raise MoblyConfigError(
                ("Expect to find %d test bed configs, found %d. Check if"
                 " you have the correct test bed names.") %
                (len(tb_filters), len(tbs)))
        configs[keys.Config.key_testbed.value] = tbs

    if (not keys.Config.key_log_path.value in configs and
            _ENV_MOBLY_LOGPATH in os.environ):
        print('Using environment log path: %s' %
              (os.environ[_ENV_MOBLY_LOGPATH]))
        configs[keys.Config.key_log_path.value] = os.environ[_ENV_MOBLY_LOGPATH]
    if (not keys.Config.key_test_paths.value in configs and
            _ENV_MOBLY_TESTPATHS in os.environ):
        print('Using environment test paths: %s' %
              (os.environ[_ENV_MOBLY_TESTPATHS]))
        configs[keys.Config.key_test_paths.value] = os.environ[
            _ENV_MOBLY_TESTPATHS].split(_PATH_SEPARATOR)

    _validate_test_config(configs)
    _validate_testbed_configs(configs[keys.Config.key_testbed.value])
    k_log_path = keys.Config.key_log_path.value
    configs[k_log_path] = utils.abs_path(configs[k_log_path])
    config_path, _ = os.path.split(utils.abs_path(test_config_path))
    configs[keys.Config.key_config_path] = config_path
    tps = configs[keys.Config.key_test_paths.value]
    # Unpack testbeds into separate json objects.
    beds = configs.pop(keys.Config.key_testbed.value)
    config_jsons = []
    # TODO: See if there is a better way to do this: b/29836695
    config_path, _ = os.path.split(utils.abs_path(test_config_path))
    configs[keys.Config.key_config_path] = config_path
    for original_bed_config in beds:
        new_test_config = dict(configs)
        new_test_config[keys.Config.key_testbed.value] = original_bed_config
        # Keys in each test bed config will be copied to a level up to be
        # picked up for user_params. If the key already exists in the upper
        # level, the local one defined in test bed config overwrites the
        # general one.
        new_test_config.update(original_bed_config)
        config_jsons.append(new_test_config)
    return config_jsons
Example #6
0
 def __init__(self, test_name, log_path, record):
     self._name = test_name
     self._record = record
     self._signature = '%s-%s' % (test_name, record.begin_time)
     self._output_dir_path = utils.abs_path(
         os.path.join(log_path, self._signature))
Example #7
0
 def __init__(self, test_name, log_path, record):
   self._name = test_name
   self._record = record
   self._output_dir_path = utils.abs_path(
       os.path.join(log_path, self._record.signature))