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; 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 -m
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        else
61            if ! (head -n1 $(which $mod) | grep -q $PYTHON); then
62                sed -i "1 s/python/$PYTHON/" $(which $mod)
63            fi
64        fi
65    done
66}
67
68function run_atest_unittests() {
69    python3_checker
70    echo "Running tests..."
71    local run_cmd=$PYTHON
72    local rc=0
73    if [[ $COVERAGE == true ]]; then
74        module_checker
75        # Clear previously coverage data.
76        $PYTHON -m coverage erase
77        # Collect coverage data.
78        run_cmd="coverage run --source $ATEST_REAL_PATH --append"
79    fi
80
81    for test_file in $(find $ATEST_DIR -name "*_unittest.py"); do
82        if ! PYTHONPATH=$(get_pythonpath) $run_cmd $test_file; then
83          rc=1
84          echo -e "${RED}$t failed${NC}"
85        fi
86    done
87    echo
88    print_summary $rc
89    return $rc
90}
91
92# Let's check if anything is passed in, if not we assume the user is invoking
93# script, but if we get a list of files, assume it's the PREUPLOAD hook.
94read -ra PREUPLOAD_FILES <<< "$@"
95if [[ ${#PREUPLOAD_FILES[@]} -eq 0 ]]; then
96    run_atest_unittests; exit $?
97elif [[ "${#PREUPLOAD_FILES[@]}" -eq 1 && "${PREUPLOAD_FILES}" == "coverage" ]]; then
98    COVERAGE=true run_atest_unittests; exit $?
99else
100    for f in ${PREUPLOAD_FILES[@]}; do
101        # We only want to run this unittest if atest files have been touched.
102        if [[ $f == atest/* ]]; then
103            run_atest_unittests; exit $?
104        fi
105    done
106fi
107