1#! /bin/bash 2 3YELLOW="\033[1;33m" 4NOCOLOR="\033[0m" 5BLUE="\033[1;34m" 6RED="\033[1;91m" 7 8function happy_hedgehog { 9 echo -e "\t${BLUE}" 10 echo -e "\t ___------__" 11 echo -e "\t |\__-- /\ _-" 12 echo -e "\t |/_ __ -" 13 echo -e "\t // \ / \ /__" 14 echo -e "\t | 0 | 0 |__ --_ Gotta go fast!" 15 echo -e "\t \\____-- __ \ ___-" 16 echo -e "\t ( @ __/ / /_" 17 echo -e "\t -_____--- --_" 18 echo -e "\t // \ \\ ___-" 19 echo -e "\t //|\__/ \\ \\" 20 echo -e "\t \_-\_____/ \-\\" 21 echo -e "\t // \\--\|" 22 echo -e "\t ${RED}____${BLUE}// ||${RED}_" 23 echo -e "\t${RED} /_____\ /___\\" 24 echo -e "${NOCOLOR}" 25} 26 27function sad_hedgehog { 28 echo -e "\t${BLUE}" 29 echo -e "\t ___------__" 30 echo -e "\t |\__-- /\ _-" 31 echo -e "\t |/_ __ -" 32 echo -e "\t // \ / \ /__" 33 echo -e "\t | 0 | 0 |__ --_ Gotta go sllloowwww!" 34 echo -e "\t \\____-- __ \ ___-" 35 echo -e "\t ( @ __ / /_" 36 echo -e "\t -_____--- --_" 37 echo -e "\t // \ \\ ___-" 38 echo -e "\t //|\__/ \\ \\" 39 echo -e "\t \_-\_____/ \-\\" 40 echo -e "\t // \\--\|" 41 echo -e "\t ${RED} ____${BLUE}// ||${RED}_" 42 echo -e "\t${RED} /_____\ /___\\" 43 echo -e "{$NOCOLOR}" 44} 45 46function check_environment { 47 if [[ -z "${ANDROID_BUILD_TOP}" ]] || [[ -z "${ANDROID_HOST_OUT}" ]] ; then 48 echo -e "${RED}ANDROID_BUILD_TOP${NOCOLOR} or ${RED}ANDROID_HOST_OUT${NOCOLOR} is not set for host run" 49 echo -e "Navigate to android root and run:" 50 echo -e "${YELLOW}" 51 echo -e ". build/envsetup.sh" 52 echo -e "lunch <fish>" 53 echo -e "${NOCOLOR}" 54 echo 55 exit 1 56 fi 57 if ! [ -x "$(command -v python3.9)" ] ; then 58 echo -e "${RED}You must have python 3.9 installed${NOCOLOR}" 59 exit 1 60 fi 61 python3.9 -m virtualenv --version 62 if [[ $? -ne 0 ]] ; then 63 echo "${RED}virtualenv not installed for python3.9${NOCOLOR}" 64 echo "${RED}Please run 'python3.9 -m pip install virtualenv' to install it${NOCOLOR}" 65 exit 1 66 fi 67} 68 69ASHMEM_OUT="/dev/shm/out" 70ASHMEM_DIST="${ASHMEM_OUT}/dist" 71ASHMEM_VENV="${ASHMEM_DIST}/bluetooth_venv" 72ASHMEM_GOTTA_GO_FAST="/dev/shm/gottagofast" 73ASHMEM_HOST_LOGS="${ASHMEM_GOTTA_GO_FAST}/logs" 74ASHMEM_OUT_TARGET="${ASHMEM_GOTTA_GO_FAST}/target" 75ASHMEM_SOONG="${ASHMEM_GOTTA_GO_FAST}/out/soong" 76CERT_HOST_LOGS="/tmp/logs/HostOnlyCert" 77CERT_DEVICE_LOGS="TODO: Add this" 78CERT_TEST_VENV=${ANDROID_BUILD_TOP}/out/dist/bluetooth_venv 79OUT_TARGET="${ANDROID_BUILD_TOP}/out/target" 80TEST_CONFIG="${ANDROID_BUILD_TOP}/system/bt/gd/cert/host_config.json" 81TEST_FILTER="-tf ${ANDROID_BUILD_TOP}/system/bt/gd/cert/all_cert_testcases" 82CPP_BUILD_TARGET="bluetooth_stack_with_facade root-canal bluetooth_packets_python3" 83RUST_BUILD_TARGET="bluetooth_with_facades root-canal bluetooth_packets_python3" 84BUILD_TARGET=$CPP_BUILD_TARGET 85 86CLEAN_VENV=false 87GOTTA_GO_FAST=false 88NUM_REPETITIONS="1" 89SKIP_SOONG_BUILD=false 90USE_ASHMEM_VENV=true 91VERBOSE_MODE=false 92DEVICE_TEST=false 93 94# Directory for test configs to modify 95CONFIG_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 96 97## Verify devices connected and valid 98DUT_SERIAL="DUT Not Set" 99DUT_ADB="DUT Not Set" 100DUT_NAME="DUT Not Set" 101 102# Used for position arguments needed for later 103POSITIONAL=() 104function parse_options { 105 while [[ $# -gt 0 ]] 106 do 107 key="$1" 108 case $key in 109 # This will delete the existing venv before running the test 110 # If you updated external libraries such as ACTS, you need to add this flag 111 --clean) 112 CLEAN_VENV=true 113 shift # past argument 114 ;; 115 --help) 116 echo 117 echo -e "${YELLOW}Help menu${NOCOLOR}" 118 echo -e "===================================" 119 echo -e "${BLUE} --clean${NOCOLOR}" 120 echo -e " Clean the virtul environment; use if ACTS has been updated." 121 echo -e "${BLUE} --disable-ashmem-venv${NOCOLOR}" 122 echo -e " Places the virtual environment on disk rather than in ashmem which is default." 123 echo -e "${BLUE} --gotta-go-fast${NOCOLOR}" 124 echo -e " Makes use of ashmem as best as possible for targeted speed increases." 125 echo -e "${BLUE} --device${NOCOLOR}" 126 echo -e " Run the test on the 2 real devices." 127 echo -e "${BLUE} --rust${NOCOLOR}" 128 echo -e " Run the test using the rust implementation on the 2 real devices." 129 echo -e "${BLUE} --rhost${NOCOLOR}" 130 echo -e " Run the test using the rust implementation on the host." 131 echo -e "${BLUE} --repeat=<N>${NOCOLOR}" 132 echo -e " Repeat the test sequence N (int) number of times." 133 echo -e "${BLUE} --skip-soong-build${NOCOLOR}" 134 echo -e " Skips building soong targets. Use when you are just modifying simple python files." 135 echo -e "${BLUE} --test_config=<configfile>${NOCOLOR}" 136 echo -e " Override default test configuration." 137 echo -e "${BLUE} --verbose${NOCOLOR}" 138 echo -e " Displays device logs and test logs to output." 139 echo 140 echo -e "Usage: $0 [--clean|--host|--repeat=<N>|--test_config=<config>] [TestGroupName[:IndividualTestName]]" 141 echo -e " ${YELLOW}e.g." 142 echo -e " $0 --host --clean SecurityTest" 143 echo -e " $0 --host --verbose SecurityTest:test_dut_initiated_display_only_display_only ${NOCOLOR}" 144 echo 145 shift 146 exit 0 147 ;; 148 # This will cause the bluetooth_venv to NOT be created in ashmem 149 # Using ashmem increases --clean build times by 40% (~21 seconds on my machine) 150 --disable-ashmem-venv) 151 USE_ASHMEM_VENV=false 152 shift # past argument 153 ;; 154 --gotta-go-fast) 155 GOTTA_GO_FAST=true 156 shift # past argument 157 ;; 158 --device) 159 TEST_CONFIG="${ANDROID_BUILD_TOP}/system/bt/gd/cert/devices_config.json" 160 DEVICE_TEST=true 161 shift # past argument 162 ;; 163 # Repeat running the specified test cases by N times in one single setup 164 --repeat=*) 165 NUM_REPETITIONS="${key#*=}" 166 shift # past argument 167 ;; 168 --skip-soong-build) 169 SKIP_SOONG_BUILD=true 170 shift 171 ;; 172 --test_config=*) 173 TEST_CONFIG="${key#*=}" 174 shift # past argument 175 ;; 176 --rust) 177 BUILD_TARGET=$RUST_BUILD_TARGET 178 export RUST_BACKTRACE=1 179 TEST_CONFIG=$ANDROID_BUILD_TOP/system/bt/gd/cert/rust_android_devices_config.json 180 DEVICE_TEST=true 181 shift # past argument 182 ;; 183 --rhost) 184 export RUST_BACKTRACE=1 185 BUILD_TARGET=$RUST_BUILD_TARGET 186 TEST_CONFIG=$ANDROID_BUILD_TOP/system/bt/gd/cert/rust_host_config.json 187 shift # past argument 188 ;; 189 # This will log everything to both log file and stdout 190 --verbose) 191 VERBOSE_MODE=true 192 shift # past argument 193 ;; 194 *) # unknown option 195 POSITIONAL+=("$1") # save it in an array for later 196 shift # past argument 197 ;; 198 esac 199 done 200 set -- "${POSITIONAL[@]}" # restore positional parameters 201 202 # Set the test filter 203 if [[ -n "$1" ]] ; then 204 TEST_FILTER="-tc $1" 205 fi 206 207 INSTALL_ARGS="--reuse-acts" 208 if [ "$CLEAN_VENV" == true ] ; then 209 echo -e "${YELLOW}Cleaning up existing virtualenv${NOCOLOR}" 210 rm -rf $CERT_TEST_VENV/* 211 rm -rf $CERT_TEST_VENV 212 mkdir -p ${CERT_TEST_VENV} 213 INSTALL_ARGS="" 214 else 215 echo -e "${YELLOW}Try to reuse existing virtualenv at ${CERT_TEST_VENV}${NOCOLOR}" 216 fi 217 218} 219 220function select_devices { 221 if [ "$DEVICE_TEST" == true ] ; then 222 RR="$(cat ${TEST_CONFIG}|grep \"CERT\\\|DUT\")" 223 if [ "$RR" != "" ]; then 224 DUT_SERIAL="$(menu-adb DUT)" 225 DUT_ADB="adb -s ${DUT_SERIAL}" 226 DUT_NAME="$(adb devices -l | grep -v "List of device" | grep ${DUT_SERIAL} | awk '{ print $6 }' | cut -d ':' -f 2)" 227 CERT_SERIAL="$(menu-adb CERT)" 228 CERT_ADB="adb -s ${CERT_SERIAL}" 229 CERT_NAME="$(adb devices -l | grep -v "List of device" | grep ${CERT_SERIAL} | awk '{ print $6 }' | cut -d ':' -f 2)" 230 231 if [ "${CERT_SERIAL}" == "${DUT_SERIAL}" ]; then 232 echo 233 echo "ERROR: CERT and DUT cannot be the same device, or you only have one device connected!" 234 echo 235 exit 1 236 fi 237 238 ## Set android devices in config 239 pushd . 240 cd "${CONFIG_DIR}" 241 popd 242 sed -i "s/\"DUT\"/\"${DUT_SERIAL}\"/g" ${TEST_CONFIG} 243 sed -i "s/\"CERT\"/\"${CERT_SERIAL}\"/g" ${TEST_CONFIG} 244 fi 245 fi 246} 247 248function soong_build { 249 if [ "$CLEAN_VENV" == true ] ; then 250 $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --build-mode --"modules-in-a-dir" --dir="${ANDROID_BUILD_TOP}/system/bt/gd" dist $BUILD_TARGET -j20 251 if [[ $? -ne 0 ]] ; then 252 echo "Failed to build ${BUILD_TARGET}" 253 exit 1 254 fi 255 else 256 $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --build-mode --"all-modules" --dir="${ANDROID_BUILD_TOP}/system/bt/gd" $BUILD_TARGET -j20 257 if [[ $? -ne 0 ]] ; then 258 echo "Failed to build ${BUILD_TARGET}" 259 exit 1 260 fi 261 fi 262} 263 264function setup_venv { 265 # Make venv in memory, decreases --clean build times by 40% 266 # Caveat is you lose the venv if the computer reboots 267 if [ "${USE_ASHMEM_VENV}" == true ] ; then 268 echo -e "${BLUE}Using ashmem virtual environment.${NOCOLOR}" 269 if [[ ! -L ${CERT_TEST_VENV} ]] ; then 270 echo -e "${BLUE}" 271 echo -ne "Creating ashmem dist folder..." 272 mkdir -p "${ASHMEM_VENV}" 273 # Ensure the directory doesn't exist 274 rm -rf "${CERT_TEST_VENV}" 275 echo -e "Done" 276 echo -ne "Sym linking ${ASHMEM_VENV} to ${CERT_TEST_VENV}..." 277 ln -s "${ASHMEM_VENV}" "${CERT_TEST_VENV}" 278 echo -e "Done" 279 echo -e "${NOCOLOR}" 280 fi 281 else 282 echo -e "${RED}Not using ashmem virtual environment.${NOCOLOR}" 283 if [[ -L ${CERT_TEST_VENV} ]] ; then 284 echo -e "${RED}" 285 echo -en "Removing sym link from ${ASHMEM_VENV} to ${CERT_TEST_VENV}..." 286 rm -rf ""${ASHMEM_VENV} "${CERT_TEST_VENV}" 287 echo -e "Done" 288 echo -en "Cleaning up memory..." 289 rm -rf "${ASHMEM_VENV}" 290 echo -e "Done" 291 echo -e "${NOCOLOR}" 292 fi 293 fi 294 python3.9 -m virtualenv --python `which python3.9` "${CERT_TEST_VENV}" 295 if [[ $? -ne 0 ]] ; then 296 echo "Error setting up virtualenv" 297 exit 1 298 fi 299 300 unzip -o -q "${ANDROID_BUILD_TOP}/out/dist/bluetooth_cert_tests.zip" -d "${CERT_TEST_VENV}/acts" 301 if [[ $? -ne 0 ]] ; then 302 echo "Error unzipping bluetooth_cert_tests.zip" 303 exit 1 304 fi 305 306 venv_common 307} 308 309function incremental_venv { 310#LINT.IfChange 311 HOST_BIN="${ANDROID_BUILD_TOP}/out/host/linux-x86/bin" 312 HOST_LIB="${ANDROID_BUILD_TOP}/out/host/linux-x86/lib64" 313 DEST_DIR="${ANDROID_BUILD_TOP}/out/dist/bluetooth_venv/acts" 314 DEST_LIB_DIR="${DEST_DIR}/lib64" 315 cp {$HOST_BIN,$DEST_DIR}/bluetooth_stack_with_facade 316 cp {$HOST_BIN,$DEST_DIR}/bluetooth_with_facades 317 cp {$HOST_BIN,$DEST_DIR}/root-canal 318 319 cp {$HOST_LIB,$DEST_DIR}/bluetooth_packets_python3.so 320 321 cp {$HOST_LIB,$DEST_LIB_DIR}/libbase.so 322 cp {$HOST_LIB,$DEST_LIB_DIR}/libbluetooth_gd.so 323 cp {$HOST_LIB,$DEST_LIB_DIR}/libc++.so 324 cp {$HOST_LIB,$DEST_LIB_DIR}/libchrome.so 325 cp {$HOST_LIB,$DEST_LIB_DIR}/libcrypto-host.so 326 cp {$HOST_LIB,$DEST_LIB_DIR}/libevent-host.so 327 cp {$HOST_LIB,$DEST_LIB_DIR}/libgrpc++_unsecure.so 328 cp {$HOST_LIB,$DEST_LIB_DIR}/libgrpc++.so 329 cp {$HOST_LIB,$DEST_LIB_DIR}/libgrpc_wrap.so 330 cp {$HOST_LIB,$DEST_LIB_DIR}/liblog.so 331 cp {$HOST_LIB,$DEST_LIB_DIR}/libssl-host.so 332 cp {$HOST_LIB,$DEST_LIB_DIR}/libz-host.so 333 cp {$HOST_LIB,$DEST_LIB_DIR}/libprotobuf-cpp-full.so 334 cp {$HOST_LIB,$DEST_LIB_DIR}/libunwindstack.so 335 cp {$HOST_LIB,$DEST_LIB_DIR}/liblzma.so 336 cp {$HOST_LIB,$DEST_LIB_DIR}/libbacktrace.so 337 338 for i in `find ${ANDROID_BUILD_TOP}/system/bt/gd -name "*.py" -type f`; do 339 cp {${ANDROID_BUILD_TOP}/system/bt/gd,$DEST_DIR}${i#${ANDROID_BUILD_TOP}/system/bt/gd} 340 done 341#LINT.ThenChange(../Android.mk) 342 343 venv_common 344} 345 346function venv_common { 347 $(echo "${CERT_TEST_VENV}/bin/python" "${CERT_TEST_VENV}/acts/setup.py" --quiet build --force) 348 if [[ $? -ne 0 ]] ; then 349 echo "Error building GD Python libraries" 350 echo -e "${YELLOW}NOTE:${NOCOLOR} To build external libraries the first time, please add --clean option." 351 exit 1 352 fi 353 354 $(echo "${CERT_TEST_VENV}/bin/python" "${CERT_TEST_VENV}/acts/setup.py" --quiet install --skip-build --force "${INSTALL_ARGS}") 355 if [[ $? -ne 0 ]] ; then 356 echo "Error installing GD Python libraries" 357 exit 1 358 fi 359 360"${CERT_TEST_VENV}/bin/python" -c " 361import bluetooth_packets_python3 as bp3 362bp3.BaseStruct 363" 364if [[ $? -ne 0 ]] ; then 365 echo "Setup failed as bluetooth_packets_python3 cannot be imported" 366 exit 1 367fi 368 369if [ "${VERBOSE_MODE}" == true ] ; then 370 TEMP_CONFIG=/tmp/temp_acts_config.json 371 cat "${TEST_CONFIG}" | "${CERT_TEST_VENV}/bin/python" -c " 372import sys 373import json 374from acts import keys 375config = json.load(sys.stdin) 376config['verbose_mode'] = True 377print(json.dumps(config)) 378 " > "${TEMP_CONFIG}" 379 TEST_CONFIG="${TEMP_CONFIG}" 380 if [[ $? -ne 0 ]] ; then 381 echo "Setup failed as verbose mode is chosen but cannot be enabled" 382 exit 1 383 fi 384fi 385} 386 387function gotta_go_fast { 388 if [ "${GOTTA_GO_FAST}" == true ] ; then 389 # Call here to explicitly note the flag is in use 390 happy_hedgehog 391 if [[ ! -L "${CERT_HOST_LOGS}" ]] ; then 392 rm -rf "${CERT_HOST_LOGS}" 393 mkdir -p "${ASHMEM_HOST_LOGS}" 394 ln -s "${ASHMEM_HOST_LOGS}" "${CERT_HOST_LOGS}" 395 fi 396 397 if [[ ! -L "${OUT_TARGET}" ]] ; then 398 rm -rf "${OUT_TARGET}" 399 mkdir -p "${ASHMEM_OUT_TARGET}" 400 ln -s "${ASHMEM_OUT_TARGET}" "${OUT_TARGET}" 401 fi 402 else 403 if [[ -L "${CERT_HOST_LOGS}" ]] ; then 404 # Call here so we don't spam anyone not using the flag 405 sad_hedgehog 406 rm -rf "${CERT_HOST_LOGS}" 407 rm -rf "${ASHMEM_HOST_LOGS}" 408 fi 409 410 if [[ -L "${OUT_TARGET}" ]] ; then 411 rm -rf "${OUT_TARGET}" 412 rm -rf "${ASHMEM_OUT_TARGET}" 413 fi 414 fi 415} 416 417function run_tests { 418 for n in $(seq "${NUM_REPETITIONS}"); do 419 $(echo "${CERT_TEST_VENV}/bin/python" "${CERT_TEST_VENV}/bin/act.py" \ 420 -c "${TEST_CONFIG}" \ 421 "${TEST_FILTER}" \ 422 -tp "${CERT_TEST_VENV}"/acts) 423 done 424 425 if [ "${CLEAN_VENV}" != true ] ; then 426 echo -e "${YELLOW}NOTE:${NOCOLOR} Completed tests using existing external libraries in virtualenv." 427 echo -e "${YELLOW}NOTE:${NOCOLOR} To update external libraries, please add --clean option." 428 fi 429} 430 431function menu-adb() { 432 TMP=$(adb devices -l | grep -v "List of device" | awk '{ print $1 }') 433 # TODO(optedoblivion): If the device doesn't have a name (offline), it misnames them 434 NTMP=$(adb devices -l | grep -v "List of device" | awk '{ print $6 }' | cut -d ':' -f 2) 435 SERIALS=($TMP) 436 DEVICES=($NTMP) 437 LEN=${#SERIALS[@]} 438 result=0 439 if [ $LEN -lt 1 ]; then 440 echo "No devices connected!" 441 return 1 442 fi 443 444 if [ "$LEN" == "" ]; then 445 LEN=0 446 fi 447 448 answer=0 449 450 DEVICE_NAME="$1 device" 451 452 if [ $LEN -gt 1 ]; then 453 echo "+-------------------------------------------------+" 1>&2 454 echo "| Choose a ${DEVICE_NAME}: " 1>&2 455 echo "+-------------------------------------------------+" 1>&2 456 echo "| |" 1>&2 457 let fixed_len=$LEN-1 458 for i in `seq 0 $fixed_len`; 459 do 460 serial=${SERIALS[i]} 461 device=${DEVICES[i]} 462 echo "| $i) $serial $device" 1>&2 463 ## TODO[MSB]: Find character count, fill with space and ending box wall 464 done 465 echo "| |" 1>&2 466 echo "+-------------------------------------------------+" 1>&2 467 echo 1>&2 468 echo -n "Index number: " 1>&2 469 read answer 470 fi 471 472 if [ $answer -ge $LEN ]; then 473 echo 474 echo "Please choose a correct index!" 1>&2 475 echo 476 return 1 477 fi 478 479 SERIAL=${SERIALS[$answer]} 480 echo $SERIAL 481} 482 483function main { 484 check_environment 485 parse_options $@ 486 select_devices 487 if [[ "${SKIP_SOONG_BUILD}" != true ]] ; then 488 soong_build 489 fi 490 if [ "$CLEAN_VENV" == true ] ; then 491 setup_venv 492 else 493 incremental_venv 494 fi 495 gotta_go_fast 496 run_tests 497} 498 499main $@ 500