blob: 3a496ce423373f59c69b07ec48b1fe6b75a8f850 [file] [log] [blame]
# Copyright 2018, 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.
# This function returns devices recognised by adb.
_fetch_adb_devices() {
while read dev; do echo $dev | awk '{print $1}'; done < <(adb devices | egrep -v "^List|^$"||true)
}
# This function returns all paths contain TEST_MAPPING.
_fetch_test_mapping_files() {
[[ -z $ANDROID_BUILD_TOP ]] && return 0
find -maxdepth 5 -type f -name TEST_MAPPING |sed 's/^.\///g'| xargs dirname 2>/dev/null
}
function _pip_install() {
_deb_installer python3-venv python3-pip || return 1
_activate_venv || return 1
requirements=(venv pyinstrument snakeviz)
for mod in "${requirements[@]}"; do
if ! _has_py_module $mod; then
echo "Installing $mod..."
pip3 install $mod >/dev/null
if [ "$?" -ne 0 ]; then
echo "pip3 install $mod failure."
return 1
fi
fi
done
}
function _has_py_module() {
[[ -z "$1" ]] && { echo "requires a module name."; return 1; }
cmd="python3 -c '
import importlib.util as ut
print(0 if ut.find_spec(\"$1\") else 1)
'"
return $(eval "$cmd")
}
function _deb_installer() {
[[ -z "$@" ]] && { echo "requires a package name."; return 1; }
declare -a missing_pkgs
for pkg in "$@"; do
if ! $(dpkg -l $pkg | egrep -q '^ii'); then
missing_pkgs+=($pkg)
fi
done
if [ ${#missing_pkgs[@]} -gt 0 ]; then
echo -n "$(tput setaf 3)${missing_pkgs[@]}$(tput sgr0) are required. "
read -p "Do you want to procees? [N/y] " answer
case "$answer" in
[yY])
sudo apt install "${missing_pkgs[@]}" -y
;;
*)
echo "No action taken. Exiting."; return 1
;;
esac
fi
}
function _activate_venv() {
local VENV="$ANDROID_HOST_OUT/.atest_venv"
[[ ! -d "$VENV" ]] && python3 -m venv "$VENV"
source "$VENV/bin/activate" || {
echo unable to activate venv.
deactivate
return 1
}
}
function _atest_profile_cli() {
echo "_atest_profile_cli is deprecated. Use _atest_pyinstrument instead."
return 1
}
function _atest_pyinstrument() {
local T="$ANDROID_BUILD_TOP"
profile="$HOME/.atest/$(date +'%FT%H-%M-%S').pyisession"
_pip_install || return 1
m atest && python3 $T/tools/asuite/atest/profiler.py pyinstrument $profile\
$ANDROID_SOONG_HOST_OUT/bin/atest-dev --no-metrics "$@"
if [ "$?" -eq 0 ]; then
pyinstrument -t --load $profile || deactivate
fi
deactivate
}
function _atest_profile_web() {
echo _atest_profile_web is deprecated. Use _atest_cprofile_snakeviz instead.
return 1
}
function _atest_cprofile_snakeviz() {
local T="$ANDROID_BUILD_TOP"
profile="$HOME/.atest/$(date +'%F_%H-%M-%S').pstats"
_pip_install || return 1
m atest && python3 $T/tools/asuite/atest/profiler.py cProfile $profile \
$ANDROID_SOONG_HOST_OUT/bin/atest-dev --no-metrics "$@"
if [ "$?" -eq 0 ]; then
echo "$(tput bold)Use Ctrl-C to stop.$(tput sgr0)"
snakeviz $profile >/dev/null || deactivate
fi
deactivate
}
# The main tab completion function.
_atest() {
COMPREPLY=()
local cmd=$(which $1)
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
_get_comp_words_by_ref -n : cur prev || true
if [[ "$cmd" == *prebuilts/asuite/atest/linux-x86/atest ]]; then
# prebuilts/asuite/atest/linux-x86/atest is shell script wrapper around
# atest-py3, which is what we should actually use.
cmd=$ANDROID_BUILD_TOP/prebuilts/asuite/atest/linux-x86/atest-py3
fi
case "$cur" in
-*)
COMPREPLY=($(compgen -W "$(unzip -p $cmd atest/atest_flag_list_for_completion.txt)" -- $cur))
;;
*/*)
;;
*)
# Use grep instead of compgen -W because compgen -W is very slow. It takes
# ~0.7 seconds for compgen to read the all_modules.txt file.
# TODO(b/256228056) This fails if $cur has special characters in it
COMPREPLY=($(ls | grep "^$cur"; grep "^$cur" $ANDROID_PRODUCT_OUT/all_modules.txt 2>/dev/null))
;;
esac
case "$prev" in
--iterations|--retry-any-failure|--rerun-until-failure)
COMPREPLY=(10) ;;
--list-modules|-L)
# TODO: genetate the list automately when the API is available.
COMPREPLY=($(compgen -W "cts vts" -- $cur)) ;;
--serial|-s)
local adb_devices="$(_fetch_adb_devices)"
if [ -n "$adb_devices" ]; then
COMPREPLY=($(compgen -W "$(_fetch_adb_devices)" -- $cur))
else
# Don't complete files/dirs when there'is no devices.
compopt -o nospace
COMPREPLY=("")
fi ;;
--test-mapping|-p)
local mapping_files="$(_fetch_test_mapping_files)"
if [ -n "$mapping_files" ]; then
COMPREPLY=($(compgen -W "$mapping_files" -- $cur))
else
# Don't complete files/dirs when TEST_MAPPING wasn't found.
compopt -o nospace
COMPREPLY=("")
fi ;;
esac
__ltrim_colon_completions "$cur" "$prev" || true
return 0
}
function _atest_main() {
# Only use this in interactive mode.
# Warning: below check must be "return", not "exit". "exit" won't break the
# build in interactive shell(e.g VM), but will result in build breakage in
# non-interactive shell(e.g docker container); therefore, using "return"
# adapts both conditions.
[[ ! $- =~ 'i' ]] && return 0
# Complete file/dir name first by using option "nosort".
# BASH version <= 4.3 doesn't have nosort option.
# Note that nosort has no effect for zsh.
local _atest_comp_options="-o default -o nosort"
local _atest_executables=(atest
atest-dev
atest-py3
_atest_pyinstrument
_atest_cprofile_snakeviz)
for exec in "${_atest_executables[*]}"; do
complete -F _atest $_atest_comp_options $exec 2>/dev/null || \
complete -F _atest -o default $exec
done
function atest-src() {
echo "atest-src is deprecated, use m atest && atest-dev instead" >&2
return 1
}
# Use prebuilt python3 for atest-dev
function atest-dev() {
atest_dev="$ANDROID_SOONG_HOST_OUT/bin/atest-dev"
if [ ! -f $atest_dev ]; then
echo "Cannot find atest-dev. Run 'm atest' to generate one."
return 1
fi
PREBUILT_TOOLS_DIR="$ANDROID_BUILD_TOP/prebuilts/build-tools/path/linux-x86"
PATH=$PREBUILT_TOOLS_DIR:$PATH $atest_dev "$@"
}
}
_atest_main