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