Migration from old pyutilz package name (which, in turn, came from
[pyutils.git] / tests / run_tests_serially.sh
1 #!/bin/bash
2
3 # Run tests in serial.  Invoke from within tests/ directory.
4
5 ROOT=..
6 DOCTEST=0
7 UNITTEST=0
8 INTEGRATION=0
9 FAILURES=0
10 TESTS_RUN=0
11 COVERAGE=0
12 PERF_TESTS=("string_utils_test.py")
13
14
15 if [ -f color_vars.sh ]; then
16     source color_vars.sh
17 fi
18
19
20 dup() {
21     if [ $# -ne 2 ]; then
22         echo "Usage: dup <string> <count>"
23         return
24     fi
25     local times=$(seq 1 $2)
26     for x in ${times}; do
27         echo -n "$1"
28     done
29 }
30
31 make_header() {
32     if [ $# -ne 2 ]; then
33         echo "Usage: make_header <required title> <color>"
34         return
35     fi
36     local title="$1"
37     local title_len=${#title}
38     title_len=$((title_len + 4))
39     local width=70
40     local left=4
41     local right=$(($width-($title_len+$left)))
42     local color="$2"
43     dup '-' $left
44     echo -ne "[ ${color}${title}${NC} ]"
45     dup '-' $right
46     echo
47 }
48
49 function usage() {
50     echo "Usage: $0 [-a]|[-i][-u][-d] [--coverage]"
51     echo
52     echo "Runs tests under ${ROOT}.  Options control which test types:"
53     echo
54     echo "    -a | --all . . . . . . . . . . . . Run all types of tests"
55     echo "    -d | --doctests  . . . . . . . . . Run doctests"
56     echo "    -u | --unittests . . . . . . . . . Run unittests"
57     echo "    -i | --integration . . . . . . . . Run integration tests"
58     echo
59     exit 1
60 }
61
62 while [[ $# -gt 0 ]]; do
63     key="$1"
64     case $key in
65         -a|--all)
66             DOCTEST=1
67             UNITTEST=1
68             INTEGRATION=1
69             ;;
70         -d|--doctests)
71             DOCTEST=1
72             ;;
73         -u|--unittests)
74             UNITTEST=1
75             ;;
76         -i|--integration)
77             INTEGRATION=1
78             ;;
79         --coverage)
80             COVERAGE=1
81             ;;
82         *)    # unknown option
83             echo "Argument $key was not recognized."
84             echo
85             usage
86             exit 1
87             ;;
88     esac
89     shift
90 done
91
92 if [ $(expr ${DOCTEST} + ${UNITTEST} + ${INTEGRATION}) -eq 0 ]; then
93     usage
94     exit 2
95 fi
96
97 if [ ${COVERAGE} -eq 1 ]; then
98     coverage erase
99 fi
100
101 FAILED_TESTS=""
102 if [ ${DOCTEST} -eq 1 ]; then
103     for doctest in $(find ${ROOT} -name "*.py" -exec grep -l "import doctest" {} \;); do
104         BASE=$(basename ${doctest})
105         HDR="${BASE} (doctest)"
106         make_header "${HDR}" "${CYAN}"
107         if [ ${COVERAGE} -eq 1 ]; then
108             OUT=$( coverage run --source ../src ${doctest} >./test_output/${BASE}-output.txt 2>&1 )
109         else
110             OUT=$( python3 ${doctest} >./test_output/${BASE}-output.txt 2>&1 )
111         fi
112         TESTS_RUN=$((TESTS_RUN+1))
113         FAILED=$( echo "${OUT}" | grep '\*\*\*Test Failed\*\*\*' | wc -l )
114         if [ $FAILED == 0 ]; then
115             echo "OK"
116         else
117             echo -e "${FAILED}"
118             FAILURES=$((FAILURES+1))
119             FAILED_TESTS="${FAILED_TESTS},${BASE} (python3 ${doctest})"
120         fi
121     done
122 fi
123
124 if [ ${UNITTEST} -eq 1 ]; then
125     for test in $(find ${ROOT} -name "*_test.py" -print); do
126         BASE=$(basename ${test})
127         HDR="${BASE} (unittest)"
128         make_header "${HDR}" "${GREEN}"
129         if [ ${COVERAGE} -eq 1 ]; then
130             coverage run --source ../src ${test} --unittests_ignore_perf >./test_output/${BASE}-output.txt 2>&1
131             if [[ " ${PERF_TESTS[*]} " =~ " ${BASE} " ]]; then
132                 echo "(re-running w/o coverage to record perf results)."
133                 ${test}
134             fi
135         else
136             ${test} >./test_output/${BASE}-output.txt 2>&1
137         fi
138         if [ $? -eq 0 ]; then
139             echo "OK"
140         else
141             FAILURES=$((FAILURES+1))
142             FAILED_TESTS="${FAILED_TESTS},${BASE} (python3 ${test})"
143         fi
144         TESTS_RUN=$((TESTS_RUN+1))
145     done
146 fi
147
148 if [ ${INTEGRATION} -eq 1 ]; then
149     for test in $(find ${ROOT} -name "*_itest.py" -print); do
150         BASE=$(basename ${test})
151         HDR="${BASE} (integration test)"
152         make_header "${HDR}" "${ORANGE}"
153         if [ ${COVERAGE} -eq 1 ]; then
154             coverage run --source ../src ${test} >./test_output/${BASE}-output.txt 2>&1
155         else
156             ${test} >./test_output/${BASE}-output.txt 2>&1
157         fi
158         if [ $? -eq 0 ]; then
159             echo "OK"
160         else
161             FAILURES=$((FAILURES+1))
162             FAILED_TESTS="${FAILED_TESTS},${BASE} (python3 ${test})"
163         fi
164         TESTS_RUN=$((TESTS_RUN+1))
165     done
166 fi
167
168 if [ ${COVERAGE} -eq 1 ]; then
169     make_header "Code Coverage Report" "${GREEN}"
170     coverage combine .coverage*
171     coverage report --omit=config-3.9.py,*_test.py,*_itest.py --sort=-cover
172     echo
173     echo "To recall this report w/o re-running the tests:"
174     echo
175     echo "  $ coverage report --omit=config-3.8.py,*_test.py,*_itest.py --sort=-cover"
176     echo
177     echo "...from the 'tests' directory.  Note that subsequent calls to "
178     echo "run_tests.sh with --coverage will klobber previous results.  See:"
179     echo
180     echo "    https://coverage.readthedocs.io/en/6.2/"
181     echo
182 fi
183
184 if [ ${FAILURES} -ne 0 ]; then
185     FAILED_TESTS=$(echo ${FAILED_TESTS} | sed 's/^,/__/g')
186     FAILED_TESTS=$(echo ${FAILED_TESTS} | sed 's/,/\n__/g')
187     if [ ${FAILURES} -eq 1 ]; then
188         echo -e "${RED}There was ${FAILURES}/${TESTS_RUN} failure:"
189     else
190         echo -e "${RED}There were ${FAILURES}/${TESTS_RUN} failures:"
191     fi
192     echo "${FAILED_TESTS}"
193     echo -e "${NC}"
194     exit ${FAILURES}
195 else
196     echo -e "${BLACK}${ON_GREEN}All (${TESTS_RUN}) test(s) passed.${NC}"
197     exit 0
198 fi