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

Commit 1817a2a0 authored by Jack He's avatar Jack He
Browse files

Cert: Use setuptools to provision GD cert tests

* Create setup.py that implements setup() from setuptools to
  provision GD cert tests in an enviornment
* Change makefile configuration such that both GD tests and the
  latest ACTS framework is packed in the same file. This helps
  prevent version mismatch between GD cert tests and ACTS framework
* Output a single bluetooth_cert_tests.zip that include above packages
  instead of two separate ZIP archives
* Running "gd/setup.py install" will install both GD tests and ACTS
  framework and it is recommended to do this in virtual environment
* Package target binaries into generic directory name "target/" so that
  GD cert tests do no need to know the name of the product being tested
* Find GD root directory via its relative with cert library directory
  so that we do not rely on os.getcwd()
* Added two more flags to gd/cert/run to allow custom test config,
  and the ability to re-use existing virtualenv
* Generate python file must be in a files sub-directory to avoid
  packing the resultant zip archive in itself

Test: source gd/cert/run --host
Bug: 150321998
Change-Id: I34b05b0ad121c8df35207f437a0326b52a4645e2
parent 9f37feac
Loading
Loading
Loading
Loading
+16 −15
Original line number Diff line number Diff line
@@ -143,6 +143,9 @@ cc_binary {
    generated_headers: [
        "BluetoothGeneratedPackets_h",
        "BluetoothFacadeGeneratedStub_h",
        // Needed here to guarantee that generated zip file is created before
        // bluetooth_cert_tests.zip is packaged
        "BluetoothFacadeAndCertGeneratedStub_py",
    ],
    generated_sources: [
        "BluetoothFacadeGeneratedStub_cc",
@@ -464,25 +467,23 @@ genrule {
        "protoc-gen-grpc-python-plugin",
        "soong_zip",
    ],
    cmd: "mkdir -p $(genDir)/packages/modules/Bluetooth/system/gd && " +
        "$(location aprotoc) -Ipackages/modules/Bluetooth/system/gd -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-python-plugin) $(in) --grpc_out=$(genDir)/packages/modules/Bluetooth/system/gd --python_out=$(genDir)/packages/modules/Bluetooth/system/gd && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/facade/__init__.py && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/hal/__init__.py && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/hci/__init__.py && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/hci/facade/__init__.py && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/l2cap/classic/__init__.py && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/l2cap/le/__init__.py && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/neighbor/facade/__init__.py && " +
        "touch $(genDir)/packages/modules/Bluetooth/system/gd/security/__init__.py && " +
        "$(location soong_zip) -C $(genDir) -D $(genDir) -o $(out)",
    cmd: "mkdir -p $(genDir)/files && " +
        "$(location aprotoc) -Ipackages/modules/Bluetooth/system/gd -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-python-plugin) $(in) --grpc_out=$(genDir)/files --python_out=$(genDir)/files && " +
        "mkdir -p $(genDir)/files/cert && " +
        "touch $(genDir)/files/cert/__init__.py && " +
        "touch $(genDir)/files/facade/__init__.py && " +
        "touch $(genDir)/files/hal/__init__.py && " +
        "touch $(genDir)/files/hci/__init__.py && " +
        "touch $(genDir)/files/hci/facade/__init__.py && " +
        "touch $(genDir)/files/l2cap/classic/__init__.py && " +
        "touch $(genDir)/files/l2cap/le/__init__.py && " +
        "touch $(genDir)/files/neighbor/facade/__init__.py && " +
        "touch $(genDir)/files/security/__init__.py && " +
        "$(location soong_zip) -C $(genDir)/files -D $(genDir)/files -o $(out)",
    srcs: [
        ":BluetoothFacadeProto",
    ],
    out: ["bluetooth_cert_generated_py.zip"],
    dist: {
        targets: ["bluetooth_stack_with_facade"],
    },

}

cc_defaults {
+92 −44
Original line number Diff line number Diff line
LOCAL_PATH := $(call my-dir)

bluetooth_cert_test_file_list := \
LOCAL_cert_test_sources := \
	$(call all-named-files-under,*.py,.) \
    $(call all-named-files-under,*.proto,cert facade hal hci/cert hci/facade l2cap/classic \
	    l2cap/classic/cert neighbor/facade security) \
	cert/all_cert_testcases
LOCAL_cert_test_sources := \
	$(filter-out gd_cert_venv% venv%, $(LOCAL_cert_test_sources))
LOCAL_cert_test_sources := \
	$(addprefix $(LOCAL_PATH)/, $(LOCAL_cert_test_sources))

bluetooth_cert_test_file_list := $(addprefix $(LOCAL_PATH)/,$(bluetooth_cert_test_file_list))
LOCAL_host_executables := \
	$(HOST_OUT_EXECUTABLES)/bluetooth_stack_with_facade

bluetooth_cert_test_file_list += \
    $(HOST_OUT_EXECUTABLES)/bluetooth_stack_with_facade \
    $(HOST_OUT_SHARED_LIBRARIES)/bluetooth_packets_python3.so \
LOCAL_host_root_canal_executables := \
	$(HOST_OUT_NATIVE_TESTS)/root-canal/root-canal

LOCAL_host_python_extension_libraries := \
	$(HOST_OUT_SHARED_LIBRARIES)/bluetooth_packets_python3.so

LOCAL_host_libraries := \
	$(HOST_OUT_SHARED_LIBRARIES)/libbase.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libbluetooth_gd.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libc++.so \
@@ -19,28 +26,69 @@ bluetooth_cert_test_file_list += \
	$(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 \
	$(HOST_OUT_SHARED_LIBRARIES)/libprotobuf-cpp-full.so

LOCAL_target_executables := \
	$(TARGET_OUT_EXECUTABLES)/bluetooth_stack_with_facade

LOCAL_target_libraries := \
	$(TARGET_OUT_SHARED_LIBRARIES)/libbluetooth_gd.so \
    $(TARGET_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \
    $(HOST_OUT_NATIVE_TESTS)/root-canal/root-canal
	$(TARGET_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so

bluetooth_cert_env_provider_path := \
    $(call intermediates-dir-for,PACKAGING,bluetooth_cert_test_package,HOST)/packages/modules/Bluetooth/system/gd/cert/environment_provider.py
bluetooth_cert_src_and_bin_zip := \
	$(call intermediates-dir-for,PACKAGING,bluetooth_cert_src_and_bin,HOST)/bluetooth_cert_src_and_bin.zip

$(bluetooth_cert_env_provider_path):
	@mkdir -p $(dir $@)
	$(hide) echo "PRODUCT_DEVICE = \"$(PRODUCT_DEVICE)\"" > $@
# Assume 64-bit OS
$(bluetooth_cert_src_and_bin_zip): PRIVATE_cert_test_sources := $(LOCAL_cert_test_sources)
$(bluetooth_cert_src_and_bin_zip): PRIVATE_host_executables := $(LOCAL_host_executables)
$(bluetooth_cert_src_and_bin_zip): PRIVATE_host_root_canal_executables := $(LOCAL_host_root_canal_executables)
$(bluetooth_cert_src_and_bin_zip): PRIVATE_host_python_extension_libraries := $(LOCAL_host_python_extension_libraries)
$(bluetooth_cert_src_and_bin_zip): PRIVATE_host_libraries := $(LOCAL_host_libraries)
$(bluetooth_cert_src_and_bin_zip): PRIVATE_target_executables := $(LOCAL_target_executables)
$(bluetooth_cert_src_and_bin_zip): PRIVATE_target_libraries := $(LOCAL_target_libraries)
$(bluetooth_cert_src_and_bin_zip): $(SOONG_ZIP) $(LOCAL_cert_test_sources) \
		$(LOCAL_host_executables) $(LOCAL_host_root_canal_executables) $(LOCAL_host_libraries) \
		$(LOCAL_target_executables) $(LOCAL_target_libraries) $(LOCAL_host_python_extension_libraries)
	$(hide) $(SOONG_ZIP) -d -o $@ \
		-C packages/modules/Bluetooth/system/gd $(addprefix -f ,$(PRIVATE_cert_test_sources)) \
		-C $(HOST_OUT_EXECUTABLES) $(addprefix -f ,$(PRIVATE_host_executables)) \
		-C $(HOST_OUT_NATIVE_TESTS)/root-canal $(addprefix -f ,$(PRIVATE_host_root_canal_executables)) \
		-C $(HOST_OUT_SHARED_LIBRARIES) $(addprefix -f ,$(PRIVATE_host_python_extension_libraries)) \
		-P lib64 \
		-C $(HOST_OUT_SHARED_LIBRARIES) $(addprefix -f ,$(PRIVATE_host_libraries)) \
		-P target \
		-C $(TARGET_OUT_EXECUTABLES) $(addprefix -f ,$(PRIVATE_target_executables)) \
		-C $(TARGET_OUT_SHARED_LIBRARIES) $(addprefix -f ,$(PRIVATE_target_libraries))

bluetooth_cert_zip_path := \
    $(call intermediates-dir-for,PACKAGING,bluetooth_cert_test_package,HOST)/bluetooth_cert_test.zip
# TODO: Find a better way to locate output from SOONG genrule()
LOCAL_cert_generated_py_zip := \
	$(SOONG_OUT_DIR)/.intermediates/packages/modules/Bluetooth/system/gd/BluetoothFacadeAndCertGeneratedStub_py/gen/bluetooth_cert_generated_py.zip

$(bluetooth_cert_zip_path): PRIVATE_BLUETOOTH_CERT_TEST_FILE_LIST := $(bluetooth_cert_test_file_list)
LOCAL_acts_zip := $(HOST_OUT)/acts-dist/acts.zip

$(bluetooth_cert_zip_path): PRIVATE_BLUETOOTH_CERT_ENV_PROVIDER_PATH := $(bluetooth_cert_env_provider_path)
bluetooth_cert_tests_py_package_zip := \
	$(call intermediates-dir-for,PACKAGING,bluetooth_cert_tests_py_package,HOST)/bluetooth_cert_tests.zip

$(bluetooth_cert_zip_path) : $(SOONG_ZIP) $(bluetooth_cert_env_provider_path) $(bluetooth_cert_test_file_list)
	$(hide) $(SOONG_ZIP) -d -o $@ $(addprefix -f ,$(PRIVATE_BLUETOOTH_CERT_TEST_FILE_LIST)) \
		-C $(call intermediates-dir-for,PACKAGING,bluetooth_cert_test_package,HOST) -f $(PRIVATE_BLUETOOTH_CERT_ENV_PROVIDER_PATH)
$(bluetooth_cert_tests_py_package_zip): PRIVATE_cert_src_and_bin_zip := $(bluetooth_cert_src_and_bin_zip)
$(bluetooth_cert_tests_py_package_zip): PRIVATE_acts_zip := $(LOCAL_acts_zip)
$(bluetooth_cert_tests_py_package_zip): PRIVATE_cert_generated_py_zip := $(LOCAL_cert_generated_py_zip)
$(bluetooth_cert_tests_py_package_zip): $(SOONG_ZIP) $(LOCAL_acts_zip) \
		$(bluetooth_cert_src_and_bin_zip) $(bluetooth_cert_generated_py_zip)
	@echo "Packaging Bluetooth Cert Tests into $@"
	@rm -rf $(dir $@)bluetooth_cert_tests
	@rm -rf $(dir $@)acts
	@mkdir -p $(dir $@)bluetooth_cert_tests
	@mkdir -p $(dir $@)acts
	$(hide) unzip -o -q $(PRIVATE_acts_zip) "tools/test/connectivity/acts/framework/*" -d $(dir $@)acts
	$(hide) unzip -o -q $(PRIVATE_cert_src_and_bin_zip) -d $(dir $@)bluetooth_cert_tests
	$(hide) unzip -o -q $(PRIVATE_cert_generated_py_zip) -d $(dir $@)bluetooth_cert_tests
	# Make all subdirectory of gd Python pacakages except lib64 and target
	$(hide) for f in `find $(dir $@)bluetooth_cert_tests -type d -name "*" \
					-not -path "$(dir $@)bluetooth_cert_tests/target*" \
					-not -path "$(dir $@)bluetooth_cert_tests/lib64*"` \
			; do (touch -a $$f/__init__.py) ; done
	$(hide) $(SOONG_ZIP) -d -o $@ -C $(dir $@)bluetooth_cert_tests -D $(dir $@)bluetooth_cert_tests \
		-P acts_framework \
		-C $(dir $@)acts/tools/test/connectivity/acts/framework -D $(dir $@)acts/tools/test/connectivity/acts/framework

$(call dist-for-goals,bluetooth_stack_with_facade,$(bluetooth_cert_zip_path):bluetooth_cert_test.zip)
$(call dist-for-goals,bluetooth_stack_with_facade,$(bluetooth_cert_tests_py_package_zip):bluetooth_cert_tests.zip)
 No newline at end of file
+6 −4
Original line number Diff line number Diff line
@@ -21,9 +21,13 @@ from facade import rootservice_pb2 as facade_rootservice
import importlib
import logging
import os
from pathlib import Path
import signal
import subprocess

# GD root is the parent directory of cert
GD_ROOT = str(Path(__file__).absolute().parents[1])


def is_subprocess_alive(process, timeout_seconds=1):
    try:
@@ -49,9 +53,7 @@ class GdFacadeOnlyBaseTestClass(BaseTestClass):
            self.rootcanal_logs = open(rootcanal_logpath, 'w')
            rootcanal_config = self.controller_configs['rootcanal']
            rootcanal_hci_port = str(rootcanal_config.get("hci_port", "6402"))
            rootcanal = os.path.join(
                os.getcwd(),
                "out/host/linux-x86/nativetest64/root-canal/root-canal")
            rootcanal = os.path.join(GD_ROOT, "root-canal")
            self.rootcanal_process = subprocess.Popen(
                [
                    rootcanal,
@@ -59,7 +61,7 @@ class GdFacadeOnlyBaseTestClass(BaseTestClass):
                    rootcanal_hci_port,
                    str(rootcanal_config.get("link_layer_port", "6403"))
                ],
                cwd=os.getcwd(),
                cwd=GD_ROOT,
                env=os.environ.copy(),
                stdout=self.rootcanal_logs,
                stderr=self.rootcanal_logs)
+10 −14
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ import logging
import os
from builtins import open
import json
from pathlib import Path
import signal
import socket
import subprocess
@@ -29,16 +30,14 @@ from acts.controllers.adb import AdbProxy, AdbError

import grpc

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

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

WAIT_CHANNEL_READY_TIMEOUT = 10
WAIT_FOR_DEVICE_TIMEOUT = 180

# GD root is the parent directory of cert
GD_ROOT = str(Path(__file__).absolute().parents[1])


def replace_vars(string, config):
    serial_number = config.get("serial_number")
@@ -49,8 +48,7 @@ def replace_vars(string, config):
        rootcanal_port = ""
    if serial_number == "DUT" or serial_number == "CERT":
        raise Exception("Did you forget to configure the serial number?")
    android_host_out = os.path.join(os.getcwd(), "out/host/linux-x86")
    return string.replace("$ANDROID_HOST_OUT", android_host_out) \
    return string.replace("$GD_ROOT", GD_ROOT) \
                 .replace("$(grpc_port)", config.get("grpc_port")) \
                 .replace("$(grpc_root_server_port)", config.get("grpc_root_server_port")) \
                 .replace("$(rootcanal_port)", rootcanal_port) \
@@ -92,15 +90,13 @@ class GdDeviceBase:
                int(grpc_root_server_port), int(grpc_root_server_port))
            self.adb.reverse("tcp:%s tcp:%s" % (signal_port, signal_port))
            self.push_or_die(
                os.path.join(ANDROID_PRODUCT_OUT,
                             "system/bin/bluetooth_stack_with_facade"),
                os.path.join(GD_ROOT, "target", "bluetooth_stack_with_facade"),
                "system/bin")
            self.push_or_die(
                os.path.join(ANDROID_PRODUCT_OUT,
                             "system/lib64/libbluetooth_gd.so"), "system/lib64")
                os.path.join(GD_ROOT, "target", "libbluetooth_gd.so"),
                "system/lib64")
            self.push_or_die(
                os.path.join(ANDROID_PRODUCT_OUT,
                             "system/lib64/libgrpc++_unsecure.so"),
                os.path.join(GD_ROOT, "target", "libgrpc++_unsecure.so"),
                "system/lib64")
            self.ensure_no_output(self.adb.shell("logcat -c"))
            self.adb.shell("rm /data/misc/bluetooth/logs/btsnoop_hci.log")
@@ -115,7 +111,7 @@ class GdDeviceBase:

        self.backing_process = subprocess.Popen(
            cmd,
            cwd=os.getcwd(),
            cwd=GD_ROOT,
            env=os.environ.copy(),
            stdout=self.backing_process_logs,
            stderr=self.backing_process_logs)
+2 −2
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
                    "label": "cert_stack",
                    "cmd":
                    [
                        "$ANDROID_HOST_OUT/bin/bluetooth_stack_with_facade",
                        "$GD_ROOT/bluetooth_stack_with_facade",
                        "--grpc-port=$(grpc_port)",
                        "--root-server-port=$(grpc_root_server_port)",
                        "--rootcanal-port=$(rootcanal_port)",
@@ -34,7 +34,7 @@
                    "label": "stack_under_test",
                    "cmd":
                    [
                        "$ANDROID_HOST_OUT/bin/bluetooth_stack_with_facade",
                        "$GD_ROOT/bluetooth_stack_with_facade",
                        "--grpc-port=$(grpc_port)",
                        "--root-server-port=$(grpc_root_server_port)",
                        "--rootcanal-port=$(rootcanal_port)",
Loading