• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018, The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# Get testable module names from module_info.json.
16# Will return null if module_info.json doesn't exist.
17_fetch_testable_modules() {
18    [ -z $ANDROID_PRODUCT_OUT ] && { exit 0; }
19    $PYTHON - << END
20import hashlib
21import os
22import pickle
23import sys
24
25atest_dir = os.path.join(os.environ['ANDROID_BUILD_TOP'], 'tools/tradefederation/core/atest')
26sys.path.append(atest_dir)
27import module_info
28
29module_info_json = os.path.join(os.environ["ANDROID_PRODUCT_OUT"] ,"module-info.json")
30
31# TODO: This method should be implemented while making module-info.json.
32def get_serialised_filename(mod_info):
33    """Determine the serialised filename used for reading testable modules.
34
35    mod_info: the path of module-info.json.
36
37    Returns: a path string hashed with md5 of module-info.json.
38            /dev/shm/atest_e89e37a2e8e45be71567520b8579ffb8 (Linux)
39            /tmp/atest_e89e37a2e8e45be71567520b8579ffb8     (MacOSX)
40    """
41    serial_filename = "/tmp/atest_" if sys.platform == "darwin" else "/dev/shm/atest_"
42    with open(mod_info, 'r') as mod_info_obj:
43        serial_filename += hashlib.md5(mod_info_obj.read().encode('utf-8')).hexdigest()
44    return serial_filename
45
46# TODO: This method should be implemented while making module-info.json.
47def create_serialised_file(serial_file):
48    modules = module_info.ModuleInfo().get_testable_modules()
49    with open(serial_file, 'wb') as serial_file_obj:
50        pickle.dump(modules, serial_file_obj, protocol=2)
51
52if os.path.isfile(module_info_json):
53    latest_serial_file = get_serialised_filename(module_info_json)
54    # When module-info.json changes, recreate a serialisation file.
55    if not os.path.exists(latest_serial_file):
56        create_serialised_file(latest_serial_file)
57    else:
58        with open(latest_serial_file, 'rb') as serial_file_obj:
59            print("\n".join(pickle.load(serial_file_obj)))
60else:
61    print("")
62END
63}
64
65# This function invoke get_args() and return each item
66# of the list for tab completion candidates.
67_fetch_atest_args() {
68    [ -z $ANDROID_BUILD_TOP ] && { exit 0; }
69    $PYTHON - << END
70import os
71import sys
72
73atest_dir = os.path.join(os.environ['ANDROID_BUILD_TOP'], 'tools/tradefederation/core/atest')
74sys.path.append(atest_dir)
75
76import atest_arg_parser
77
78parser = atest_arg_parser.AtestArgParser()
79parser.add_atest_args()
80print("\n".join(parser.get_args()))
81END
82}
83
84# This function returns devices recognised by adb.
85_fetch_adb_devices() {
86    while read dev; do echo $dev | awk '{print $1}'; done < <(adb devices | egrep -v "^List|^$"||true)
87}
88
89# This function returns all paths contain TEST_MAPPING.
90_fetch_test_mapping_files() {
91    find -maxdepth 5 -type f -name TEST_MAPPING |sed 's/^.\///g'| xargs dirname 2>/dev/null
92}
93
94# The main tab completion function.
95_atest() {
96    # Not support completion on Darwin since the bash version of it
97    # is too old to fully support useful built-in commands/functions
98    # such as compopt, _get_comp_words_by_ref and __ltrim_colon_completions.
99    [[ "$(uname -s)" == "Darwin" ]] && return 0
100
101    local cur prev
102    COMPREPLY=()
103    cur="${COMP_WORDS[COMP_CWORD]}"
104    prev="${COMP_WORDS[COMP_CWORD-1]}"
105    _get_comp_words_by_ref -n : cur prev || true
106
107    case "$cur" in
108        -*)
109            COMPREPLY=($(compgen -W "$(_fetch_atest_args)" -- $cur))
110            ;;
111        */*)
112            ;;
113        *)
114            local candidate_args=$(ls; _fetch_testable_modules)
115            COMPREPLY=($(compgen -W "$candidate_args" -- $cur))
116            ;;
117    esac
118
119    case "$prev" in
120        --generate-baseline|--generate-new-metrics)
121            COMPREPLY=(5) ;;
122        --list-modules|-L)
123            # TODO: genetate the list automately when the API is availble.
124            COMPREPLY=($(compgen -W "cts vts" -- $cur)) ;;
125        --serial|-s)
126            local adb_devices="$(_fetch_adb_devices)"
127            if [ -n "$adb_devices" ]; then
128                COMPREPLY=($(compgen -W "$(_fetch_adb_devices)" -- $cur))
129            else
130                # Don't complete files/dirs when there'is no devices.
131                compopt -o nospace
132                COMPREPLY=("")
133            fi ;;
134        --test-mapping|-p)
135            local mapping_files="$(_fetch_test_mapping_files)"
136            if [ -n "$mapping_files" ]; then
137                COMPREPLY=($(compgen -W "$mapping_files" -- $cur))
138            else
139                # Don't complete files/dirs when TEST_MAPPING wasn't found.
140                compopt -o nospace
141                COMPREPLY=("")
142            fi ;;
143    esac
144    __ltrim_colon_completions "$cur" "$prev" || true
145    return 0
146}
147
148function _atest_main() {
149    # Only use this in interactive mode.
150    [[ ! $- =~ 'i' ]] && return 0
151
152    # Use Py2 as the default interpreter. This script is aiming for being
153    # compatible with both Py2 and Py3.
154    PYTHON=
155    if [ -x "$(which python2)" ]; then
156        PYTHON=$(which python2)
157    elif [ -x "$(which python3)" ]; then
158        PYTHON=$(which python3)
159    else
160        PYTHON="/usr/bin/env python"
161    fi
162
163    # Complete file/dir name first by using option "nosort".
164    # BASH version <= 4.3 doesn't have nosort option.
165    # Note that nosort has no effect for zsh.
166    local _atest_comp_options="-o default -o nosort"
167    local _atest_executables=(atest atest-dev atest-src)
168    for exec in "${_atest_executables[*]}"; do
169        complete -F _atest $_atest_comp_options $exec 2>/dev/null || \
170        complete -F _atest -o default $exec
171    done
172
173    # Install atest-src for the convenience of debugging.
174    local atest_src="$(gettop)/tools/tradefederation/core/atest/atest.py"
175    [[ -f "$atest_src" ]] && alias atest-src="$atest_src"
176}
177
178_atest_main
179