OSDN Git Service

Cert: Use setuptools to provision GD cert tests
authorJack He <siyuanh@google.com>
Wed, 18 Mar 2020 09:52:54 +0000 (02:52 -0700)
committerJack He <siyuanh@google.com>
Thu, 19 Mar 2020 18:59:55 +0000 (11:59 -0700)
* 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

gd/Android.bp
gd/Android.mk
gd/cert/gd_base_test_facade_only.py
gd/cert/gd_device_base.py
gd/cert/host_config.json
gd/cert/python3.8-gd [deleted file]
gd/cert/run
gd/cert/run_pts_l2cap.sh
gd/cert/set_up_acts.sh [deleted file]
gd/cert/set_up_virtualenv.sh
gd/setup.py [new file with mode: 0644]

index ae4ba23..6fb243f 100644 (file)
@@ -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)/system/bt/gd && " +
-        "$(location aprotoc) -Isystem/bt/gd -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-python-plugin) $(in) --grpc_out=$(genDir)/system/bt/gd --python_out=$(genDir)/system/bt/gd && " +
-        "touch $(genDir)/system/bt/gd/facade/__init__.py && " +
-        "touch $(genDir)/system/bt/gd/hal/__init__.py && " +
-        "touch $(genDir)/system/bt/gd/hci/__init__.py && " +
-        "touch $(genDir)/system/bt/gd/hci/facade/__init__.py && " +
-        "touch $(genDir)/system/bt/gd/l2cap/classic/__init__.py && " +
-        "touch $(genDir)/system/bt/gd/l2cap/le/__init__.py && " +
-        "touch $(genDir)/system/bt/gd/neighbor/facade/__init__.py && " +
-        "touch $(genDir)/system/bt/gd/security/__init__.py && " +
-        "$(location soong_zip) -C $(genDir) -D $(genDir) -o $(out)",
+    cmd: "mkdir -p $(genDir)/files && " +
+        "$(location aprotoc) -Isystem/bt/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 {
index 966e53b..1dc9af6 100644 (file)
@@ -1,46 +1,94 @@
 LOCAL_PATH := $(call my-dir)
 
-bluetooth_cert_test_file_list := \
-    $(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
-
-bluetooth_cert_test_file_list := $(addprefix $(LOCAL_PATH)/,$(bluetooth_cert_test_file_list))
-
-bluetooth_cert_test_file_list += \
-    $(HOST_OUT_EXECUTABLES)/bluetooth_stack_with_facade \
-    $(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)/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)/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_SHARED_LIBRARIES)/libbluetooth_gd.so \
-    $(TARGET_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \
-    $(HOST_OUT_NATIVE_TESTS)/root-canal/root-canal
-
-bluetooth_cert_env_provider_path := \
-    $(call intermediates-dir-for,PACKAGING,bluetooth_cert_test_package,HOST)/system/bt/gd/cert/environment_provider.py
-
-$(bluetooth_cert_env_provider_path):
-       @mkdir -p $(dir $@)
-       $(hide) echo "PRODUCT_DEVICE = \"$(PRODUCT_DEVICE)\"" > $@
-
-bluetooth_cert_zip_path := \
-    $(call intermediates-dir-for,PACKAGING,bluetooth_cert_test_package,HOST)/bluetooth_cert_test.zip
-
-$(bluetooth_cert_zip_path): PRIVATE_BLUETOOTH_CERT_TEST_FILE_LIST := $(bluetooth_cert_test_file_list)
-
-$(bluetooth_cert_zip_path): PRIVATE_BLUETOOTH_CERT_ENV_PROVIDER_PATH := $(bluetooth_cert_env_provider_path)
-
-$(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)
-
-$(call dist-for-goals,bluetooth_stack_with_facade,$(bluetooth_cert_zip_path):bluetooth_cert_test.zip)
+LOCAL_cert_test_sources := \
+       $(call all-named-files-under,*.py,.) \
+       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))
+
+LOCAL_host_executables := \
+       $(HOST_OUT_EXECUTABLES)/bluetooth_stack_with_facade
+
+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 \
+       $(HOST_OUT_SHARED_LIBRARIES)/libchrome.so \
+       $(HOST_OUT_SHARED_LIBRARIES)/libevent-host.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
+
+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
+
+bluetooth_cert_src_and_bin_zip := \
+       $(call intermediates-dir-for,PACKAGING,bluetooth_cert_src_and_bin,HOST)/bluetooth_cert_src_and_bin.zip
+
+# 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 system/bt/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))
+
+# TODO: Find a better way to locate output from SOONG genrule()
+LOCAL_cert_generated_py_zip := \
+       $(SOONG_OUT_DIR)/.intermediates/system/bt/gd/BluetoothFacadeAndCertGeneratedStub_py/gen/bluetooth_cert_generated_py.zip
+
+LOCAL_acts_zip := $(HOST_OUT)/acts-dist/acts.zip
+
+bluetooth_cert_tests_py_package_zip := \
+       $(call intermediates-dir-for,PACKAGING,bluetooth_cert_tests_py_package,HOST)/bluetooth_cert_tests.zip
+
+$(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_tests_py_package_zip):bluetooth_cert_tests.zip)
\ No newline at end of file
index 1412e64..13ea6c0 100644 (file)
@@ -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)
index 7c00cfc..47c226a 100644 (file)
@@ -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)
index 9de9d70..582876e 100644 (file)
@@ -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)",
diff --git a/gd/cert/python3.8-gd b/gd/cert/python3.8-gd
deleted file mode 100755 (executable)
index 6aa24b2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/bash
-BLUETOOTH_CERT_TEST_ENV=$ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test_env
-PYTHONPATH=$BLUETOOTH_CERT_TEST_ENV/out/host/linux-x86/lib64:$BLUETOOTH_CERT_TEST_ENV/system/bt/gd:$PYTHONPATH \
- python3.8 "$@"
index 9634691..afa5057 100755 (executable)
@@ -12,6 +12,7 @@ $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --build-mode --"all-modules" --dir=
 
 TEST_CONFIG="$ANDROID_BUILD_TOP/system/bt/gd/cert/android_devices_config.json"
 TEST_FILTER="-tf $ANDROID_BUILD_TOP/system/bt/gd/cert/all_cert_testcases"
+REUSE_VENV=false
 
 POSITIONAL=()
 while [[ $# -gt 0 ]]
@@ -26,6 +27,19 @@ case $key in
     TEST_CONFIG=$ANDROID_BUILD_TOP/system/bt/gd/cert/host_config.json
     shift # past argument
     ;;
+    --test_file=*)
+    TEST_FILTER="-tc ${key#*=}"
+    shift # past argument
+    ;;
+    --test_config=*)
+    TEST_CONFIG="${key#*=}"
+    shift # past argument
+    ;;
+    # This will speed up the test by overwriting existing venv
+    --reuse_venv)
+    REUSE_VENV=true
+    shift # past argument
+    ;;
     *)    # unknown option
     POSITIONAL+=("$1") # save it in an array for later
     shift # past argument
@@ -34,21 +48,40 @@ esac
 done
 set -- "${POSITIONAL[@]}" # restore positional parameters
 
-BLUETOOTH_CERT_TEST_ENV=$ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test_env
-rm -rf BLUETOOTH_CERT_TEST_ENV
-mkdir -p $BLUETOOTH_CERT_TEST_ENV
+CERT_TEST_VENV=$ANDROID_BUILD_TOP/out/dist/bluetooth_venv
 
-unzip -o -q $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py.zip \
-   -d $BLUETOOTH_CERT_TEST_ENV
+if [ "$REUSE_VENV" != true ] ; then
+  rm -rf $CERT_TEST_VENV
+fi
 
-unzip -o -q $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test.zip \
-   -d $BLUETOOTH_CERT_TEST_ENV
+python3.8 -m virtualenv --python `which python3.8` $CERT_TEST_VENV
+if [[ $? -ne 0 ]] ; then
+    echo "Error setting up virtualenv"
+    return 1
+fi
+
+unzip -o -q $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_tests.zip -d $CERT_TEST_VENV/acts
+if [[ $? -ne 0 ]] ; then
+    echo "Error unzipping bluetooth_cert_tests.zip"
+    return 1
+fi
+
+$CERT_TEST_VENV/bin/python $CERT_TEST_VENV/acts/setup.py install
+if [[ $? -ne 0 ]] ; then
+    echo "Error installing GD libraries"
+    return 1
+fi
+
+$CERT_TEST_VENV/bin/python -c "
+import bluetooth_packets_python3 as bp3
+bp3.BaseStruct
+"
+if [[ $? -ne 0 ]] ; then
+  echo "Setup failed as bluetooth_packets_python3 cannot be imported"
+  return 1
+fi
 
-pushd .
-cd $ANDROID_BUILD_TOP
-PYTHONPATH=$BLUETOOTH_CERT_TEST_ENV/out/host/linux-x86/lib64:$BLUETOOTH_CERT_TEST_ENV/system/bt/gd:$PYTHONPATH \
-    python3.8 `which act.py`\
-      -c $TEST_CONFIG \
-      $TEST_FILTER \
-      -tp $ANDROID_BUILD_TOP/system/bt/gd
-popd
\ No newline at end of file
+$CERT_TEST_VENV/bin/python $CERT_TEST_VENV/bin/act.py \
+    -c $TEST_CONFIG \
+    $TEST_FILTER \
+    -tp $CERT_TEST_VENV/acts
index 92fc7cd..356b31f 100755 (executable)
@@ -1,9 +1,5 @@
 #! /bin/bash
 
-unzip -u $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py.zip -d $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py
-
-# For bluetooth_packets_python3
-pushd .
-cd $ANDROID_BUILD_TOP
-python3.8-gd `which act.py` -c $ANDROID_BUILD_TOP/system/bt/gd/cert/pts.json -tf $ANDROID_BUILD_TOP/system/bt/gd/cert/pts_l2cap_testcase -tp $ANDROID_BUILD_TOP/system/bt/gd
-popd
\ No newline at end of file
+source $ANDROID_BUILD_TOP/system/bt/cert/run \
+  --test_config=$ANDROID_BUILD_TOP/system/bt/gd/cert/pts.json \
+  --test_file=$ANDROID_BUILD_TOP/system/bt/gd/cert/pts_l2cap_testcase
\ No newline at end of file
diff --git a/gd/cert/set_up_acts.sh b/gd/cert/set_up_acts.sh
deleted file mode 100755 (executable)
index 60bfdd2..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /bin/bash
-#
-# Script to setup environment to execute bluetooth certification stack
-#
-# for more info, see go/acts
-
-## Android build main build setup script relative to top level android source root
-BUILD_SETUP=./build/envsetup.sh
-
-function UsageAndroidTree {
-    cat<<EOF
-Ensure invoked from within the android source tree
-EOF
-}
-
-function UsageSourcedNotExecuted {
-    cat<<EOF
-Ensure script is SOURCED and not executed to persist the build setup
-e.g.
-source $0
-EOF
-}
-
-function UpFind {
-    while [[ $PWD != / ]] ; do
-        rc=$(find "$PWD" -maxdepth 1 "$@")
-        if [ -n "$rc" ]; then
-            echo $(dirname "$rc")
-            return
-        fi
-        cd ..
-    done
-}
-
-function SetUpAndroidBuild {
-    pushd .
-    android_root=$(UpFind -name out -type d)
-    if [[ -z $android_root ]] ; then
-        UsageAndroidTree
-        return
-    fi
-    echo "Found android root $android_root"
-    cd $android_root && . $BUILD_SETUP
-    echo "Sourced build setup rules"
-    cd $android_root && lunch
-    popd
-}
-
-function SetupPython38 {
-    echo "Setting up python3.8"
-    sudo apt-get install python3.8-dev
-}
-
-function CompileBluetoothPacketsPython3 {
-    echo "bluetooth_packets_python3 is not found, compiling"
-    croot
-    make -j bluetooth_packets_python3
-}
-
-if [[ "${BASH_SOURCE[0]}" == "${0}" ]] ; then
-    UsageSourcedNotExecuted
-    return 1
-fi
-
-if [[ -z "$ANDROID_BUILD_TOP" ]] ; then
-    SetUpAndroidBuild
-fi
-
-## Check python3.8 is installed properly
-## Need Python 3.8 because bluetooth_packets_python3 is compiled against
-## Python 3.8 headers
-dpkg -l python3.8-dev > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
-    SetupPython38
-fi
-
-## Check bluetooth_packets_python3 is compiled succssfully
-PYTHONPATH=$PYTHONPATH:$ANDROID_BUILD_TOP/out/host/linux-x86/lib64 python3.8 -c "
-import bluetooth_packets_python3 as bp3
-bp3.BaseStruct
-"
-if [[ $? -ne 0 ]] ; then
-  pushd .
-  CompileBluetoothPacketsPython3
-  popd
-  python3.8 -c "
-import bluetooth_packets_python3 as bp3
-bp3.BaseStruct
-"
-  if [[ $? -ne 0 ]] ; then
-    echo "Setup failed as bluetooth_packets_python3 cannot be found"
-  else
-    echo "Found bluetooth_packets_python3 after compilation"
-  fi
-else
-  echo "Found bluetooth_packets_python3"
-fi
-
-## All is good now so go ahead with the acts setup
-pushd .
-cd $ANDROID_BUILD_TOP/tools/test/connectivity/acts/framework/
-sudo python3.8 setup.py develop
-if [[ $? -eq 0 ]] ; then
-    echo "cert setup complete"
-else
-    echo "cert setup failed"
-fi
-popd
-
index 50f3d48..0c07691 100644 (file)
@@ -5,9 +5,9 @@
 # Usage
 #  1. cd system/bt/gd
 #  2. source cert/set_up_virtualenv.sh
-#  3. source gd_cert_venv/bin/activate
-#  4. [run tests, do development, hack]
-#  5. deactivate (or just close the terminal window)
+#  4. [run tests, do development, hack] using vevn/bin/python
+#
+# Note: Just use the virtualized Python binary, no need to activate
 
 ## Android build main build setup script relative to top level android source root
 BUILD_SETUP=./build/envsetup.sh
@@ -61,12 +61,6 @@ function SetupPip3 {
     sudo apt-get install python3-pip
 }
 
-function CompileBluetoothPacketsPython3 {
-    echo "bluetooth_packets_python3 is not found, compiling"
-    croot
-    make -j bluetooth_packets_python3
-}
-
 # Deactivate existing virtual environment, if any, ignore errors
 deactivate > /dev/null 2>&1
 
@@ -102,120 +96,49 @@ if [[ -z "$ANDROID_BUILD_TOP" ]] ; then
     SetUpAndroidBuild
 fi
 
-## Check bluetooth_packets_python3 is compiled succssfully
-$ANDROID_BUILD_TOP/system/bt/gd/cert/python3.8-gd -c "
-import bluetooth_packets_python3 as bp3
-bp3.BaseStruct
-"
-if [[ $? -ne 0 ]] ; then
-  pushd .
-  CompileBluetoothPacketsPython3
-  popd
-  $ANDROID_BUILD_TOP/system/bt/gd/cert/python3.8-gd -c "
-import bluetooth_packets_python3 as bp3
-bp3.BaseStruct
-"
-  if [[ $? -ne 0 ]] ; then
-    echo "Setup failed as bluetooth_packets_python3 cannot be found"
-    return 1
-  else
-    echo "Found bluetooth_packets_python3 after compilation"
-  fi
-else
-  echo "Found bluetooth_packets_python3"
-fi
-
 ## Compile and unzip test artifacts
-if [[ ! -f "$ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py.zip" || ! -f "$ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test.zip" ]]; then
-    echo "bluetooth_cert_generated_py.zip OR bluetooth_cert_test.zip is not found, compiling"
-    m -j dist bluetooth_stack_with_facade
-    if [[ ! -f "$ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py.zip" || ! -f "$ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test.zip" ]]; then
-        echo "Failed to compile bluetooth_stack_with_facade"
-        return 1
-    fi
-fi
-unzip -u $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py.zip -d $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py
+echo "Compiling bluetooth_stack_with_facade ..."
+$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --build-mode --"all-modules" --dir="$(pwd)" dist bluetooth_stack_with_facade
 if [[ $? -ne 0 ]] ; then
-    echo "Failed to unzip bluetooth_cert_generated_py.zip"
+    echo "Failed to compile bluetooth_stack_with_facade"
     return 1
 fi
-unzip -u $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test.zip -d $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test
-if [[ $? -ne 0 ]] ; then
-    echo "Failed to unzip bluetooth_cert_test.zip"
+if [[ ! -f "$ANDROID_BUILD_TOP/out/dist/bluetooth_cert_tests.zip" ]]; then
+    echo "Cannot find bluetooth_cert_tests.zip after compilation"
     return 1
 fi
 
-# Set-up virtualenv
-pushd .
-cd $ANDROID_BUILD_TOP/system/bt/gd
-virtualenv -p python3.8 gd_cert_venv
+CERT_TEST_VENV=$ANDROID_BUILD_TOP/out/dist/bluetooth_venv
+
+rm -rf $CERT_TEST_VENV
+
+python3.8 -m virtualenv --python `which python3.8` $CERT_TEST_VENV
 if [[ $? -ne 0 ]] ; then
     echo "Error setting up virtualenv"
-    popd
     return 1
 fi
-popd
-
-# Set up artifacts
-pushd .
-cd $ANDROID_BUILD_TOP/system/bt/gd/gd_cert_venv/lib/python3.8/site-packages
-# Python generated code
-ln -sfT $ANDROID_BUILD_TOP/tools/test/connectivity/acts/framework/acts acts
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test/system/bt/gd/cert cert
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py/system/bt/gd/facade facade
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py/system/bt/gd/hal hal
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py/system/bt/gd/hci hci
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py/system/bt/gd/l2cap l2cap
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py/system/bt/gd/neighbor neighbor
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_generated_py/system/bt/gd/security security
-# Native libraries
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test/out/host/linux-x86/lib64/bluetooth_packets_python3.so bluetooth_packets_python3.so
-# Per systrace, Python only load from python3.8/lib64 directory for plugin imported native libraries
-mkdir -p $ANDROID_BUILD_TOP/system/bt/gd/gd_cert_venv/lib/python3.8/lib64
-cd $ANDROID_BUILD_TOP/system/bt/gd/gd_cert_venv/lib/python3.8/lib64
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test/out/host/linux-x86/lib64/libc++.so libc++.so
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test/out/host/linux-x86/lib64/libbluetooth_gd.so libbluetooth_gd.so
-ln -sfT $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_test/out/host/linux-x86/lib64/libgrpc++_unsecure.so libgrpc++_unsecure.so
-# Binaries
-cd $ANDROID_BUILD_TOP/system/bt/gd/gd_cert_venv/bin
-ln -sfT $ANDROID_BUILD_TOP/out/host/linux-x86/bin/bluetooth_stack_with_facade bluetooth_stack_with_facade
-ln -sfT $ANDROID_BUILD_TOP/out/host/linux-x86/nativetest64/root-canal/root-canal root-canal
-popd
-
-# Activate virtualenv
-pushd .
-source $ANDROID_BUILD_TOP/system/bt/gd/gd_cert_venv/bin/activate
+
+unzip -o -q $ANDROID_BUILD_TOP/out/dist/bluetooth_cert_tests.zip -d $CERT_TEST_VENV/acts
 if [[ $? -ne 0 ]] ; then
-    echo "Failed to activate virtualenv"
-    deactivate
-    popd
-    return 1
-fi
-popd
-if [[ -z "$ANDROID_BUILD_TOP" ]] ; then
-    echo "Failed to inherit Android build environment"
-    deactivate
+    echo "Error unzipping bluetooth_cert_tests.zip"
     return 1
 fi
 
-## Set up ACTS
-# sudo is no longer needed since we are in a virtual environment
-python3.8 $ANDROID_BUILD_TOP/tools/test/connectivity/acts/framework/setup.py develop
+$CERT_TEST_VENV/bin/python $CERT_TEST_VENV/acts/setup.py install
 if [[ $? -ne 0 ]] ; then
-    echo "ACTS setup failed"
-    deactivate
+    echo "Error installing GD libraries"
     return 1
 fi
 
-pip3 install protobuf
+$CERT_TEST_VENV/bin/python -c "
+import bluetooth_packets_python3 as bp3
+bp3.BaseStruct
+"
 if [[ $? -ne 0 ]] ; then
-    echo "Failed to install protobuf"
-    deactivate
-    return 1
+  echo "Setup failed as bluetooth_packets_python3 cannot be imported"
+  return 1
 fi
 
-deactivate
-
 echo ""
 echo "Please mark GD root directory as \"Project Sources and Headers\" in IDE"
 echo "If still seeing errors, invalidate cached and restart"
diff --git a/gd/setup.py b/gd/setup.py
new file mode 100644 (file)
index 0000000..a2a2145
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+#
+#   Copyright 2020 - 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.
+
+from distutils import log
+import logging
+import os
+from setuptools import setup, find_packages
+from setuptools.command.install import install
+from setuptools.command.develop import develop
+import subprocess
+import sys
+
+install_requires = [
+    'grpcio',
+]
+
+
+def setup_acts_for_cmd_or_die(cmd_str):
+    acts_framework_dir = os.path.abspath('acts_framework')
+    acts_setup_bin = os.path.join(acts_framework_dir, 'setup.py')
+    cmd = [sys.executable, acts_setup_bin, cmd_str]
+    subprocess.check_call(cmd, cwd=acts_framework_dir)
+
+
+class InstallLocalPackagesForInstallation(install):
+
+    def run(self):
+        self.announce('Installing ACTS for installation', log.INFO)
+        setup_acts_for_cmd_or_die("install")
+        self.announce('ACTS installed for installation.', log.INFO)
+        install.run(self)
+
+
+class InstallLocalPackagesForDevelopment(develop):
+
+    def run(self):
+        logging.info('Installing ACTS for development')
+        setup_acts_for_cmd_or_die("develop")
+        logging.info('ACTS installed for development')
+        develop.run(self)
+
+
+def main():
+    # Relative path from calling directory to this file
+    our_dir = os.path.dirname(__file__)
+    # Must cd into this dir for package resolution to work
+    # This won't affect the calling shell
+    os.chdir(our_dir)
+    setup(
+        name='bluetooth_cert_tests',
+        version='1.0',
+        author='Android Open Source Project',
+        license='Apache2.0',
+        description="""Bluetooth Cert Tests Package""",
+        # Include root package so that bluetooth_packets_python3.so can be
+        # included as well
+        packages=[''] + find_packages(exclude='acts_framework'),
+        install_requires=install_requires,
+        package_data={
+            '': [
+                'root-canal', 'bluetooth_stack_with_facade', '*.so',
+                'lib64/*.so', 'target/*'
+            ],
+            'cert': ['all_test_cases'],
+        },
+        cmdclass={
+            'install': InstallLocalPackagesForInstallation,
+            'develop': InstallLocalPackagesForDevelopment,
+        })
+
+
+if __name__ == '__main__':
+    main()