Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 621d7d77 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge changes I44f2e73a,I1755c0c4,Iee69245a,Ie7f4e084 am: 82f1b9f2

Change-Id: Ia1d1e4f9a074c19fe002d52279a4b5b4933adfa6
parents 62d8226b 82f1b9f2
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -11,9 +11,15 @@ bluetooth_cert_test_file_list := $(addprefix $(LOCAL_PATH)/,$(bluetooth_cert_tes
bluetooth_cert_test_file_list += \
bluetooth_cert_test_file_list += \
    $(HOST_OUT_EXECUTABLES)/bluetooth_stack_with_facade \
    $(HOST_OUT_EXECUTABLES)/bluetooth_stack_with_facade \
    $(HOST_OUT_SHARED_LIBRARIES)/bluetooth_packets_python3.so \
    $(HOST_OUT_SHARED_LIBRARIES)/bluetooth_packets_python3.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libbase.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libbluetooth_gd.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libbluetooth_gd.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libc++.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libc++.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libchrome.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libevent-host.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \
    $(HOST_OUT_SHARED_LIBRARIES)/liblog.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libz-host.so \
    $(HOST_OUT_SHARED_LIBRARIES)/libprotobuf-cpp-full.so \
    $(TARGET_OUT_EXECUTABLES)/bluetooth_stack_with_facade \
    $(TARGET_OUT_EXECUTABLES)/bluetooth_stack_with_facade \
    $(TARGET_OUT_SHARED_LIBRARIES)/libbluetooth_gd.so \
    $(TARGET_OUT_SHARED_LIBRARIES)/libbluetooth_gd.so \
    $(TARGET_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \
    $(TARGET_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \
+9 −1
Original line number Original line Diff line number Diff line
@@ -20,7 +20,7 @@ import time
from mobly import asserts
from mobly import asserts
from datetime import datetime, timedelta
from datetime import datetime, timedelta
from acts.base_test import BaseTestClass
from acts.base_test import BaseTestClass
from cert.event_stream import EventStream
from cert.event_stream import EventStream, FilteringEventStream
from cert.truth import assertThat
from cert.truth import assertThat


# Test packet nesting
# Test packet nesting
@@ -386,3 +386,11 @@ class CertSelfTest(BaseTestClass):
            logging.debug(e)
            logging.debug(e)
            return True  # Failed as expected
            return True  # Failed as expected
        return False
        return False

    def test_filtering_event_stream_none_filter_function(self):
        with EventStream(FetchEvents(events=[1, 2, 3],
                                     delay_ms=50)) as event_stream:
            filtered_event_stream = FilteringEventStream(event_stream, None)
            assertThat(filtered_event_stream)\
                .emits(lambda data: data.value_ == 1)\
                .then(lambda data: data.value_ == 3)
+3 −2
Original line number Original line Diff line number Diff line
@@ -39,7 +39,7 @@ class IEventStream(ABC):
class FilteringEventStream(IEventStream):
class FilteringEventStream(IEventStream):


    def __init__(self, stream, filter_fn):
    def __init__(self, stream, filter_fn):
        self.filter_fn = filter_fn
        self.filter_fn = filter_fn if filter_fn else lambda x: x
        self.event_queue = SimpleQueue()
        self.event_queue = SimpleQueue()
        self.stream = stream
        self.stream = stream


@@ -264,11 +264,12 @@ def NOT_FOR_YOU_assert_event_occurs(
        try:
        try:
            current_event = istream.get_event_queue().get(
            current_event = istream.get_event_queue().get(
                timeout=remaining.total_seconds())
                timeout=remaining.total_seconds())
            logging.debug("current_event: %s", current_event)
            if match_fn(current_event):
            if match_fn(current_event):
                event_list.append(current_event)
                event_list.append(current_event)
        except Empty:
        except Empty:
            continue
            continue
    logging.debug("Done waiting for event")
    logging.debug("Done waiting for event, received %d", len(event_list))
    asserts.assert_true(
    asserts.assert_true(
        len(event_list) >= at_least_times,
        len(event_list) >= at_least_times,
        msg=("Expected at least %d events, but got %d" % (at_least_times,
        msg=("Expected at least %d events, but got %d" % (at_least_times,
+15 −1
Original line number Original line Diff line number Diff line
@@ -14,6 +14,7 @@
#   See the License for the specific language governing permissions and
#   See the License for the specific language governing permissions and
#   limitations under the License.
#   limitations under the License.


from acts import asserts
from acts.base_test import BaseTestClass
from acts.base_test import BaseTestClass
from facade import rootservice_pb2 as facade_rootservice
from facade import rootservice_pb2 as facade_rootservice


@@ -24,6 +25,14 @@ import signal
import subprocess
import subprocess




def is_subprocess_alive(process, timeout_seconds=1):
    try:
        process.wait(timeout=timeout_seconds)
        return False
    except subprocess.TimeoutExpired as exp:
        return True


class GdFacadeOnlyBaseTestClass(BaseTestClass):
class GdFacadeOnlyBaseTestClass(BaseTestClass):


    def setup_class(self, dut_module, cert_module):
    def setup_class(self, dut_module, cert_module):
@@ -54,9 +63,14 @@ class GdFacadeOnlyBaseTestClass(BaseTestClass):
                env=os.environ.copy(),
                env=os.environ.copy(),
                stdout=self.rootcanal_logs,
                stdout=self.rootcanal_logs,
                stderr=self.rootcanal_logs)
                stderr=self.rootcanal_logs)
            asserts.assert_true(
                self.rootcanal_process,
                msg="Cannot start root-canal at " + str(rootcanal))
            asserts.assert_true(
                is_subprocess_alive(self.rootcanal_process),
                msg="root-canal stopped immediately after running")
            for gd_device in gd_devices:
            for gd_device in gd_devices:
                gd_device["rootcanal_port"] = rootcanal_hci_port
                gd_device["rootcanal_port"] = rootcanal_hci_port

        self.register_controller(
        self.register_controller(
            importlib.import_module('cert.gd_device'), builtin=True)
            importlib.import_module('cert.gd_device'), builtin=True)


+124 −15
Original line number Original line Diff line number Diff line
@@ -23,18 +23,21 @@ import socket
import subprocess
import subprocess
import time
import time


from acts import asserts
from acts import context
from acts import context
from acts.controllers.adb import AdbProxy
from acts.controllers.adb import AdbProxy, AdbError


import grpc
import grpc


from cert.environment_provider import PRODUCT_DEVICE
from cert.environment_provider import PRODUCT_DEVICE
from cert.gd_base_test_facade_only import is_subprocess_alive


ANDROID_PRODUCT_OUT = os.path.join(
ANDROID_PRODUCT_OUT = os.path.join(
    os.getcwd(), "out/dist/bluetooth_cert_test/out/target/product",
    os.getcwd(), "out/dist/bluetooth_cert_test/out/target/product",
    PRODUCT_DEVICE)
    PRODUCT_DEVICE)


WAIT_CHANNEL_READY_TIMEOUT = 10
WAIT_CHANNEL_READY_TIMEOUT = 10
WAIT_FOR_DEVICE_TIMEOUT = 180




def replace_vars(string, config):
def replace_vars(string, config):
@@ -77,26 +80,31 @@ class GdDeviceBase:


        self.serial_number = serial_number
        self.serial_number = serial_number
        if self.serial_number:
        if self.serial_number:
            self.ad = AdbProxy(serial_number)
            self.adb = AdbProxy(self.serial_number)
            self.ad.shell("date " + time.strftime("%m%d%H%M%Y.%S"))
            self.ensure_verity_disabled()
            self.ad.tcp_forward(int(grpc_port), int(grpc_port))
            asserts.assert_true(
            self.ad.tcp_forward(
                self.adb.ensure_root(),
                msg="device %s cannot run as root after enabling verity" %
                self.serial_number)
            self.adb.shell("date " + time.strftime("%m%d%H%M%Y.%S"))
            self.adb.tcp_forward(int(grpc_port), int(grpc_port))
            self.adb.tcp_forward(
                int(grpc_root_server_port), int(grpc_root_server_port))
                int(grpc_root_server_port), int(grpc_root_server_port))
            self.ad.reverse("tcp:%s tcp:%s" % (signal_port, signal_port))
            self.adb.reverse("tcp:%s tcp:%s" % (signal_port, signal_port))
            self.ad.push(
            self.push_or_die(
                os.path.join(ANDROID_PRODUCT_OUT,
                os.path.join(ANDROID_PRODUCT_OUT,
                             "system/bin/bluetooth_stack_with_facade"),
                             "system/bin/bluetooth_stack_with_facade"),
                "system/bin")
                "system/bin")
            self.ad.push(
            self.push_or_die(
                os.path.join(ANDROID_PRODUCT_OUT,
                os.path.join(ANDROID_PRODUCT_OUT,
                             "system/lib64/libbluetooth_gd.so"), "system/lib64")
                             "system/lib64/libbluetooth_gd.so"), "system/lib64")
            self.ad.push(
            self.push_or_die(
                os.path.join(ANDROID_PRODUCT_OUT,
                os.path.join(ANDROID_PRODUCT_OUT,
                             "system/lib64/libgrpc++_unsecure.so"),
                             "system/lib64/libgrpc++_unsecure.so"),
                "system/lib64")
                "system/lib64")
            self.ad.shell("logcat -c")
            self.ensure_no_output(self.adb.shell("logcat -c"))
            self.ad.shell("rm /data/misc/bluetooth/logs/btsnoop_hci.log")
            self.adb.shell("rm /data/misc/bluetooth/logs/btsnoop_hci.log")
            self.ad.shell("svc bluetooth disable")
            self.ensure_no_output(self.adb.shell("svc bluetooth disable"))


        tester_signal_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tester_signal_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tester_signal_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
        tester_signal_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
@@ -111,6 +119,13 @@ class GdDeviceBase:
            env=os.environ.copy(),
            env=os.environ.copy(),
            stdout=self.backing_process_logs,
            stdout=self.backing_process_logs,
            stderr=self.backing_process_logs)
            stderr=self.backing_process_logs)
        asserts.assert_true(
            self.backing_process,
            msg="Cannot start backing_process at " + " ".join(cmd))
        asserts.assert_true(
            is_subprocess_alive(self.backing_process),
            msg="backing_process stopped immediately after running " +
            " ".join(cmd))
        tester_signal_socket.accept()
        tester_signal_socket.accept()
        tester_signal_socket.close()
        tester_signal_socket.close()


@@ -131,11 +146,11 @@ class GdDeviceBase:
                          (self.label, backing_process_return_code))
                          (self.label, backing_process_return_code))


        if self.serial_number:
        if self.serial_number:
            self.ad.shell("logcat -d -f /data/misc/bluetooth/logs/system_log")
            self.adb.shell("logcat -d -f /data/misc/bluetooth/logs/system_log")
            self.ad.pull(
            self.adb.pull(
                "/data/misc/bluetooth/logs/btsnoop_hci.log %s" % os.path.join(
                "/data/misc/bluetooth/logs/btsnoop_hci.log %s" % os.path.join(
                    self.log_path_base, "%s_btsnoop_hci.log" % self.label))
                    self.log_path_base, "%s_btsnoop_hci.log" % self.label))
            self.ad.pull(
            self.adb.pull(
                "/data/misc/bluetooth/logs/system_log %s" % os.path.join(
                "/data/misc/bluetooth/logs/system_log %s" % os.path.join(
                    self.log_path_base, "%s_system_log" % self.label))
                    self.log_path_base, "%s_system_log" % self.label))


@@ -145,3 +160,97 @@ class GdDeviceBase:
            future.result(timeout=WAIT_CHANNEL_READY_TIMEOUT)
            future.result(timeout=WAIT_CHANNEL_READY_TIMEOUT)
        except grpc.FutureTimeoutError:
        except grpc.FutureTimeoutError:
            logging.error("wait channel ready timeout")
            logging.error("wait channel ready timeout")

    def ensure_no_output(self, result):
        """
        Ensure a command has not output
        """
        asserts.assert_true(
            result is None or len(result) == 0,
            msg="command returned something when it shouldn't: %s" % result)

    def push_or_die(self, src_file_path, dst_file_path, push_timeout=300):
        """Pushes a file to the Android device

        Args:
            src_file_path: The path to the file to install.
            dst_file_path: The destination of the file.
            push_timeout: How long to wait for the push to finish in seconds
        """
        try:
            self.adb.ensure_root()
            self.ensure_verity_disabled()
            out = self.adb.push(
                '%s %s' % (src_file_path, dst_file_path), timeout=push_timeout)
            if 'error' in out:
                asserts.fail('Unable to push file %s to %s due to %s' %
                             (src_file_path, dst_file_path, out))
        except Exception as e:
            asserts.fail(
                msg='Unable to push file %s to %s due to %s' %
                (src_file_path, dst_file_path, e),
                extras=e)

    def ensure_verity_disabled(self):
        """Ensures that verity is enabled.

        If verity is not enabled, this call will reboot the phone. Note that
        this only works on debuggable builds.
        """
        logging.debug("Disabling verity and remount for %s", self.serial_number)
        asserts.assert_true(self.adb.ensure_root(),
                            "device %s cannot run as root", self.serial_number)
        # The below properties will only exist if verity has been enabled.
        system_verity = self.adb.getprop('partition.system.verified')
        vendor_verity = self.adb.getprop('partition.vendor.verified')
        if system_verity or vendor_verity:
            self.adb.disable_verity()
            self.reboot()
        self.adb.remount()
        self.adb.wait_for_device(timeout=WAIT_FOR_DEVICE_TIMEOUT)

    def reboot(self, timeout_minutes=15.0):
        """Reboots the device.

        Reboot the device, wait for device to complete booting.
        """
        logging.debug("Rebooting %s", self.serial_number)
        self.adb.reboot()

        timeout_start = time.time()
        timeout = timeout_minutes * 60
        # Android sometimes return early after `adb reboot` is called. This
        # means subsequent calls may make it to the device before the reboot
        # goes through, return false positives for getprops such as
        # sys.boot_completed.
        while time.time() < timeout_start + timeout:
            try:
                self.adb.get_state()
                time.sleep(.1)
            except AdbError:
                # get_state will raise an error if the device is not found. We
                # want the device to be missing to prove the device has kicked
                # off the reboot.
                break
        minutes_left = timeout_minutes - (time.time() - timeout_start) / 60.0
        self.wait_for_boot_completion(timeout_minutes=minutes_left)

    def wait_for_boot_completion(self, timeout_minutes=15.0):
        """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
        """
        timeout_start = time.time()
        timeout = timeout_minutes * 60

        self.adb.wait_for_device(timeout=WAIT_FOR_DEVICE_TIMEOUT)
        while time.time() < timeout_start + timeout:
            try:
                completed = self.adb.getprop("sys.boot_completed")
                if completed == '1':
                    return
            except AdbError:
                # adb shell calls may fail during certain period of booting
                # process, which is normal. Ignoring these errors.
                pass
            time.sleep(5)
        asserts.fail(msg='Device %s booting process timed out.' %
                     self.serial_number)
Loading