1#!/bin/bash 2# 3# Copyright 2014 Google Inc. All rights reserved. 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# Test automation script. 18# 19# Usage: 20# test.sh [function name] 21# 22# Examples: 23# $ ./test.sh py-unit # run Python unit tests 24# $ ./test.sh all # all tests 25# $ ./test.sh lint # run lint checks 26# If no function is provided all of the unit tests will be run. 27 28set -o nounset 29set -o pipefail 30set -o errexit 31 32. util.sh 33 34readonly THIS_DIR=$(dirname $0) 35readonly REPO_ROOT=$THIS_DIR 36readonly CLIENT_DIR=$REPO_ROOT/client/python 37 38# 39# Fully Automated Tests 40# 41 42# Run all Python unit tests. 43# 44# Or pass a particular test to run with the correct PYTHONPATH, e.g. 45# 46# $ ./test.sh py-unit tests/fastrand_test.py 47# 48# TODO: Separate out deterministic tests from statistical tests (which may 49# rarely fail) 50py-unit() { 51 export PYTHONPATH=$CLIENT_DIR # to find client library 52 53 if test $# -gt 0; then 54 "$@" 55 else 56 set +o errexit 57 58 # -e: exit at first failure 59 find $REPO_ROOT -name \*_test.py | sh -x -e 60 fi 61 62 local exit_code=$? 63 64 if test $exit_code -eq 0; then 65 echo 'ALL TESTS PASSED' 66 else 67 echo 'FAIL' 68 exit 1 69 fi 70 set -o errexit 71} 72 73# All tests 74all() { 75 banner "Running Python unit tests" 76 py-unit 77 echo 78 79 banner "Running R unit tests" 80 r-unit 81} 82 83# 84# Lint 85# 86lint() { 87 banner "Linting Python source files" 88 py-lint 89 echo 90 91 banner "Linting Documentation files" 92 doc-lint 93} 94 95python-lint() { 96 # E111: indent not a multiple of 4. We are following the Google/Chrome 97 # style and using 2 space indents. 98 if pep8 --ignore=E111 "$@"; then 99 echo 100 echo 'LINT PASSED' 101 else 102 echo 103 echo 'LINT FAILED' 104 exit 1 105 fi 106} 107 108py-lint() { 109 which pep8 >/dev/null || die "pep8 not installed ('sudo apt-get install pep8' on Ubuntu)" 110 111 # - Skip _tmp dir, because we are downloading cpplint.py there, and it has 112 # pep8 lint errors 113 # - Exclude setup.py, because it's a config file and uses "invalid" 'name = 114 # 1' style (spaces around =). 115 find $REPO_ROOT \ 116 \( -name _tmp -a -prune \) -o \ 117 \( -name \*.py -a -print \) \ 118 | grep -v /setup.py \ 119 | xargs --verbose -- $0 python-lint 120} 121 122r-unit() { 123 set -o xtrace # show tests we're running 124 125 # This one needs to be run from the root dir 126 tests/compare_dist_test.R 127 128 tests/gen_counts_test.R 129 130 tests/gen_true_values_test.R 131 132 analysis/R/decode_test.R 133 134 analysis/test/run_tests.R 135} 136 137doc-lint() { 138 which tidy >/dev/null || die "tidy not found" 139 for doc in _tmp/report.html _tmp/doc/*.html; do 140 echo $doc 141 # -e: show only errors and warnings 142 # -q: quiet 143 tidy -e -q $doc || true 144 done 145} 146 147# This isn't a strict check, but can help. 148# TODO: Add words to whitelist. 149spell-all() { 150 which spell >/dev/null || die "spell not found" 151 spell README.md doc/*.md | sort | uniq 152} 153 154# 155# Smoke Tests. These can be manually run. 156# 157 158gen-true-values() { 159 local num_unique_values=10 160 local num_clients=10 161 local values_per_client=2 162 local num_cohorts=4 163 local out=_tmp/reports.csv 164 165 tests/gen_true_values.R \ 166 exp $num_unique_values $num_clients $values_per_client $num_cohorts $out 167 wc -l $out 168 cat $out 169} 170 171if test $# -eq 0 ; then 172 all 173else 174 "$@" 175fi 176