| # 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. |
| |
| # Get testable module names from module_info.json. |
| # Will return null if module_info.json doesn't exist. |
| _fetch_testable_modules() { |
| [ -z $ANDROID_PRODUCT_OUT ] && { exit 0; } |
| $PYTHON - << END |
| import hashlib |
| import os |
| import pickle |
| import sys |
| |
| atest_dir = os.path.join(os.environ['ANDROID_BUILD_TOP'], 'tools/tradefederation/core/atest') |
| sys.path.append(atest_dir) |
| import module_info |
| |
| module_info_json = os.path.join(os.environ["ANDROID_PRODUCT_OUT"] ,"module-info.json") |
| |
| # TODO: This method should be implemented while making module-info.json. |
| def get_serialised_filename(mod_info): |
| """Determine the serialised filename used for reading testable modules. |
| |
| mod_info: the path of module-info.json. |
| |
| Returns: a path string hashed with md5 of module-info.json. |
| /dev/shm/atest_e89e37a2e8e45be71567520b8579ffb8 (Linux) |
| /tmp/atest_e89e37a2e8e45be71567520b8579ffb8 (MacOSX) |
| """ |
| serial_filename = "/tmp/atest_" if sys.platform == "darwin" else "/dev/shm/atest_" |
| with open(mod_info, 'r') as mod_info_obj: |
| serial_filename += hashlib.md5(mod_info_obj.read().encode('utf-8')).hexdigest() |
| return serial_filename |
| |
| # TODO: This method should be implemented while making module-info.json. |
| def create_serialised_file(serial_file): |
| modules = module_info.ModuleInfo().get_testable_modules() |
| with open(serial_file, 'wb') as serial_file_obj: |
| pickle.dump(modules, serial_file_obj, protocol=2) |
| |
| if os.path.isfile(module_info_json): |
| latest_serial_file = get_serialised_filename(module_info_json) |
| # When module-info.json changes, recreate a serialisation file. |
| if not os.path.exists(latest_serial_file): |
| create_serialised_file(latest_serial_file) |
| else: |
| with open(latest_serial_file, 'rb') as serial_file_obj: |
| print("\n".join(pickle.load(serial_file_obj))) |
| else: |
| print("") |
| END |
| } |
| |
| # This function invoke get_args() and return each item |
| # of the list for tab completion candidates. |
| _fetch_atest_args() { |
| [ -z $ANDROID_BUILD_TOP ] && { exit 0; } |
| $PYTHON - << END |
| import os |
| import sys |
| |
| atest_dir = os.path.join(os.environ['ANDROID_BUILD_TOP'], 'tools/tradefederation/core/atest') |
| sys.path.append(atest_dir) |
| |
| import atest_arg_parser |
| |
| parser = atest_arg_parser.AtestArgParser() |
| parser.add_atest_args() |
| print("\n".join(parser.get_args())) |
| END |
| } |
| |
| # 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() { |
| find -maxdepth 5 -type f -name TEST_MAPPING |sed 's/^.\///g'| xargs dirname 2>/dev/null |
| } |
| |
| # The main tab completion function. |
| _atest() { |
| # Not support completion on Darwin since the bash version of it |
| # is too old to fully support useful built-in commands/functions |
| # such as compopt, _get_comp_words_by_ref and __ltrim_colon_completions. |
| [[ "$(uname -s)" == "Darwin" ]] && return 0 |
| |
| local cur prev |
| COMPREPLY=() |
| cur="${COMP_WORDS[COMP_CWORD]}" |
| prev="${COMP_WORDS[COMP_CWORD-1]}" |
| _get_comp_words_by_ref -n : cur prev || true |
| |
| case "$cur" in |
| -*) |
| COMPREPLY=($(compgen -W "$(_fetch_atest_args)" -- $cur)) |
| ;; |
| */*) |
| ;; |
| *) |
| local candidate_args=$(ls; _fetch_testable_modules) |
| COMPREPLY=($(compgen -W "$candidate_args" -- $cur)) |
| ;; |
| esac |
| |
| case "$prev" in |
| --generate-baseline|--generate-new-metrics) |
| COMPREPLY=(5) ;; |
| --list-modules|-L) |
| # TODO: genetate the list automately when the API is availble. |
| 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. |
| [[ ! $- =~ 'i' ]] && return 0 |
| |
| # Use Py2 as the default interpreter. This script is aiming for being |
| # compatible with both Py2 and Py3. |
| PYTHON= |
| if [ -x "$(which python2)" ]; then |
| PYTHON=$(which python2) |
| elif [ -x "$(which python3)" ]; then |
| PYTHON=$(which python3) |
| else |
| PYTHON="/usr/bin/env python" |
| fi |
| |
| # 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-src) |
| for exec in "${_atest_executables[*]}"; do |
| complete -F _atest $_atest_comp_options $exec 2>/dev/null || \ |
| complete -F _atest -o default $exec |
| done |
| |
| # Install atest-src for the convenience of debugging. |
| local atest_src="$(gettop)/tools/tradefederation/core/atest/atest.py" |
| [[ -f "$atest_src" ]] && alias atest-src="$atest_src" |
| } |
| |
| _atest_main |