普通文本  |  219行  |  8.17 KB

#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import json
import logging

from vts.runners.host import const
from vts.runners.host import errors
from vts.runners.host import keys
from vts.utils.python.file import target_file_utils
from vts.utils.python.hal import hal_service_name_utils


def CanRunHidlHalTest(test_instance,
                      dut,
                      shell=None,
                      run_as_compliance_test=False):
    """Checks HAL precondition of a test instance.

    Args:
        test_instance: the test instance which inherits BaseTestClass.
        dut: the AndroidDevice under test.
        shell: the ShellMirrorObject to execute command on the device.
               If not specified, the function creates one from dut.
        run_as_compliance_test: boolean, whether it is a compliance test.

    Returns:
        True if the precondition is satisfied; False otherwise.
    """
    if shell is None:
        dut.shell.InvokeTerminal("check_hal_preconditions")
        shell = dut.shell.check_hal_preconditions

    opt_params = [
        keys.ConfigKeys.IKEY_ABI_BITNESS,
        keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE,
        keys.ConfigKeys.IKEY_PRECONDITION_FILE_PATH_PREFIX,
        keys.ConfigKeys.IKEY_PRECONDITION_LSHAL,
    ]
    test_instance.getUserParams(opt_param_names=opt_params)

    bitness = str(getattr(test_instance, keys.ConfigKeys.IKEY_ABI_BITNESS, ""))

    hwbinder_service_name = str(
        getattr(test_instance,
                keys.ConfigKeys.IKEY_PRECONDITION_HWBINDER_SERVICE, ""))
    if hwbinder_service_name:
        if not hwbinder_service_name.startswith("android.hardware."):
            logging.error("The given hwbinder service name %s is invalid.",
                          hwbinder_service_name)
        else:
            cmd_results = shell.Execute("ps -A")
            hwbinder_service_name += "@"
            if (any(cmd_results[const.EXIT_CODE]) or
                    hwbinder_service_name not in cmd_results[const.STDOUT][0]):
                logging.warn("The required hwbinder service %s not found.",
                             hwbinder_service_name)
                return False

    file_path_prefix = getattr(test_instance, "file_path_prefix", "")
    if file_path_prefix and bitness:
        logging.debug("FILE_PATH_PREFIX: %s", file_path_prefix)
        logging.debug("Test bitness: %s", bitness)
        tag = "_" + bitness + "bit"
        if tag in file_path_prefix:
            for path_prefix in file_path_prefix[tag]:
                if not target_file_utils.Exists(path_prefix, shell):
                    msg = (
                        "The required file (prefix: {}) for {}-bit testcase "
                        "not found.").format(path_prefix, bitness)
                    logging.warn(msg)
                    return False

    hal = str(
        getattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_LSHAL, ""))
    if hal:
        testable, _ = hal_service_name_utils.GetHalServiceName(
            shell, hal, bitness, run_as_compliance_test)
        return testable

    logging.debug("Precondition check pass.")
    return True

def CheckFeaturePrecondition(test_instance, dut, shell=None):
    """Checks feature precondition of a test instance.

    Args:
        test_instance: the test instance which inherits BaseTestClass.
        dut: the AndroidDevice under test.
        shell: the ShellMirrorObject to execute command on the device.
               If not specified, the function creates one from dut.

    Returns:
        True if the devise has the required feature; False otherwise.
    """
    opt_params = [
        keys.ConfigKeys.IKEY_PRECONDITION_FEATURE,
    ]
    test_instance.getUserParams(opt_param_names=opt_params)

    feature = str(
        getattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_FEATURE, ""))
    if feature:
        # If system is not running, needs to start the framework first.
        if not dut.isFrameworkRunning():
            if not dut.start():
                logging.warn("Failed to start Android framework.")
                return False

        if shell is None:
            dut.shell.InvokeTerminal("check_feature_precondition")
            shell = dut.shell.check_feature_precondition

        cmd_results = shell.Execute("LD_LIBRARY_PATH= pm list features")
        if (any(cmd_results[const.EXIT_CODE])
                or feature not in cmd_results[const.STDOUT][0]):
            logging.warn("The required feature %s not found.", feature)
            return False
    logging.debug("Feature precondition check pass.")
    return True

def MeetFirstApiLevelPrecondition(test_instance, dut=None):
    """Checks first API level precondition of a test instance.

    If the device's ro.product.first_api_level is 0, this function checks
    ro.build.version.sdk.

    Args:
        test_instance: the test instance which inherits BaseTestClass.
        dut: the AndroidDevice under test.

    Returns:
        True if the device's first API level is greater than or equal to the
        value of the precondition; False otherwise.
    """
    opt_params = [keys.ConfigKeys.IKEY_PRECONDITION_FIRST_API_LEVEL]
    test_instance.getUserParams(opt_param_names=opt_params)
    if not hasattr(test_instance,
                   keys.ConfigKeys.IKEY_PRECONDITION_FIRST_API_LEVEL):
        return True

    precond_level_attr = getattr(
        test_instance, keys.ConfigKeys.IKEY_PRECONDITION_FIRST_API_LEVEL, 0)
    try:
        precond_level = int(precond_level_attr)
    except ValueError:
        logging.error("Cannot parse first API level precondition: %s",
                      precond_level_attr)
        return True

    if not dut:
        logging.debug("Read first API level from the first device.")
        dut = test_instance.android_devices[0]
    device_level = dut.getLaunchApiLevel(strict=False)
    if not device_level:
        logging.error("Cannot read first API level from device. "
                      "Assume it meets the precondition.")
        return True

    logging.debug("Device's first API level=%d; precondition=%d", device_level,
                  precond_level)
    return device_level >= precond_level


def CheckSysPropPrecondition(test_instance, dut, shell=None):
    """Checks sysprop precondition of a test instance.

    Args:
        test_instance: the test instance which inherits BaseTestClass.
        dut: the AndroidDevice under test.
        shell: the ShellMirrorObject to execute command on the device.
               If not specified, the function creates one from dut.

    Returns:
        False if precondition is not met (i.e., to skip tests),
        True otherwise (e.g., when no sysprop precondition is set;
        the precondition is satisfied;
        there is an error in retrieving the target sysprop; or
        the specified sysprop is undefined)
    """
    if not hasattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_SYSPROP):
        return True

    precond_sysprop = str(
        getattr(test_instance, keys.ConfigKeys.IKEY_PRECONDITION_SYSPROP, ''))
    if "=" not in precond_sysprop:
        logging.error("precondition-sysprop value is invalid.")
        return True

    if shell is None:
        dut.shell.InvokeTerminal("check_sysprop_precondition")
        shell = dut.shell.check_sysprop_precondition

    sysprop_key, sysprop_value = precond_sysprop.split('=')
    cmd_results = shell.Execute('getprop %s' % sysprop_key)
    if any(cmd_results[const.EXIT_CODE]):
        logging.error('Failed to read sysprop:\n%s', sysprop_key)
        return True
    else:
        value = cmd_results[const.STDOUT][0].strip()
        if len(value) == 0:
            return True
        elif value != sysprop_value:
            return False
    return True