Cut version 0.0.1b8
[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         if [ "${BASE}" == "zookeeper_test.py" ]; then
129             echo "(skipping zookeeper_test.py; if you have a zookeeper instance, fixme)"
130             continue
131         fi
132         make_header "${HDR}" "${GREEN}"
133         if [ ${COVERAGE} -eq 1 ]; then
134             coverage run --source ../src ${test} --unittests_ignore_perf >./test_output/${BASE}-output.txt 2>&1
135             if [[ " ${PERF_TESTS[*]} " =~ " ${BASE} " ]]; then
136                 echo "(re-running w/o coverage to record perf results)."
137                 ${test}
138             fi
139         else
140             ${test} >./test_output/${BASE}-output.txt 2>&1
141         fi
142         if [ $? -eq 0 ]; then
143             echo "OK"
144         else
145             FAILURES=$((FAILURES+1))
146             FAILED_TESTS="${FAILED_TESTS},${BASE} (python3 ${test})"
147         fi
148         TESTS_RUN=$((TESTS_RUN+1))
149     done
150 fi
151
152 if [ ${INTEGRATION} -eq 1 ]; then
153     for test in $(find ${ROOT} -name "*_itest.py" -print); do
154         BASE=$(basename ${test})
155         HDR="${BASE} (integration test)"
156         make_header "${HDR}" "${ORANGE}"
157         if [ ${COVERAGE} -eq 1 ]; then
158             coverage run --source ../src ${test} >./test_output/${BASE}-output.txt 2>&1
159         else
160             ${test} >./test_output/${BASE}-output.txt 2>&1
161         fi
162         if [ $? -eq 0 ]; then
163             echo "OK"
164         else
165             FAILURES=$((FAILURES+1))
166             FAILED_TESTS="${FAILED_TESTS},${BASE} (python3 ${test})"
167         fi
168         TESTS_RUN=$((TESTS_RUN+1))
169     done
170 fi
171
172 if [ ${COVERAGE} -eq 1 ]; then
173     make_header "Code Coverage Report" "${GREEN}"
174     coverage combine .coverage*
175     coverage report --omit=config-3.9.py,*_test.py,*_itest.py --sort=-cover
176     echo
177     echo "To recall this report w/o re-running the tests:"
178     echo
179     echo "  $ coverage report --omit=config-3.8.py,*_test.py,*_itest.py --sort=-cover"
180     echo
181     echo "...from the 'tests' directory.  Note that subsequent calls to "
182     echo "run_tests.sh with --coverage will klobber previous results.  See:"
183     echo
184     echo "    https://coverage.readthedocs.io/en/6.2/"
185     echo
186 fi
187
188 if [ ${FAILURES} -ne 0 ]; then
189     FAILED_TESTS=$(echo ${FAILED_TESTS} | sed 's/^,/__/g')
190     FAILED_TESTS=$(echo ${FAILED_TESTS} | sed 's/,/\n__/g')
191     if [ ${FAILURES} -eq 1 ]; then
192         echo -e "${RED}There was ${FAILURES}/${TESTS_RUN} failure:"
193     else
194         echo -e "${RED}There were ${FAILURES}/${TESTS_RUN} failures:"
195     fi
196     echo "${FAILED_TESTS}"
197     echo -e "${NC}"
198     exit ${FAILURES}
199 else
200     echo -e "${BLACK}${ON_GREEN}All (${TESTS_RUN}) test(s) passed.${NC}"
201     exit 0
202 fi