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