1#!/usr/bin/env bash
2
3# Copyright (C) 2017 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# A simple helper script that runs all of the atest unit tests.
18# There are 2 situations that we take care of:
19#   1. User wants to invoke this script directly.
20#   2. PREUPLOAD hook invokes this script.
21
22ATEST_DIR=$(dirname $0)
23[ "$(uname -s)" == "Darwin" ] && { realpath(){ echo "$(cd $(dirname $1);pwd -P)/$(basename $1)"; }; }
24ATEST_REAL_PATH=$(realpath $ATEST_DIR)
25RED='\033[0;31m'
26GREEN='\033[0;32m'
27NC='\033[0m' # No Color
28COVERAGE=false
29PYTHON=python3
30PIP=pip3
31
32function python3_checker() {
33    if ! which $PYTHON >/dev/null 2>&1; then
34        echo "python3 not found."; exit 1
35    fi
36}
37
38function get_pythonpath() {
39    echo "$ATEST_REAL_PATH:$PYTHONPATH"
40}
41
42function print_summary() {
43    local test_results=$1
44    if [[ $COVERAGE == true ]]; then
45        coverage report --show-missing
46        coverage html
47    fi
48    if [[ $test_results -eq 0 ]]; then
49        echo -e "${GREEN}All unittests pass${NC}!"
50    else
51        echo -e "${RED}There was a unittest failure${NC}"
52    fi
53}
54
55function module_checker() {
56    mods_to_check=(coverage)
57    for mod in ${mods_to_check[@]}; do
58        if ! $PIP freeze | grep $mod >/dev/null 2>&1; then
59            $PIP install -U --user $mod
60        fi
61        if ! (head -n1 $(which $mod) | grep -q $PYTHON); then
62            sed -i "1 s/python/$PYTHON/" $(which $mod)
63        fi
64    done
65}
66
67function run_atest_unittests() {
68    python3_checker
69    echo "Running tests..."
70    local run_cmd=$PYTHON
71    local rc=0
72    if [[ $COVERAGE == true ]]; then
73        module_checker
74        # Clear previously coverage data.
75        $PYTHON -m coverage erase
76        # Collect coverage data.
77        run_cmd="coverage run --source $ATEST_REAL_PATH --append"
78    fi
79
80    for test_file in $(find $ATEST_DIR -name "*_unittest.py"); do
81        if ! PYTHONPATH=$(get_pythonpath) $run_cmd $test_file; then
82          rc=1
83          echo -e "${RED}$t failed${NC}"
84        fi
85    done
86    echo
87    print_summary $rc
88    return $rc
89}
90
91# Let's check if anything is passed in, if not we assume the user is invoking
92# script, but if we get a list of files, assume it's the PREUPLOAD hook.
93read -ra PREUPLOAD_FILES <<< "$@"
94if [[ ${#PREUPLOAD_FILES[@]} -eq 0 ]]; then
95    run_atest_unittests; exit $?
96elif [[ "${#PREUPLOAD_FILES[@]}" -eq 1 && "${PREUPLOAD_FILES}" == "coverage" ]]; then
97    COVERAGE=true run_atest_unittests; exit $?
98else
99    for f in ${PREUPLOAD_FILES[@]}; do
100        # We only want to run this unittest if atest files have been touched.
101        if [[ $f == atest/* ]]; then
102            run_atest_unittests; exit $?
103        fi
104    done
105fi
106