From d2965f8b458a210868f64261093a2372d0ef91d6 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 31 Jan 2013 16:35:35 -0800 Subject: Overhaul of tools/partest-ack. I decided what would be really handy for test selection is being able to run all the tests which were created or modified at the same time as something else. Right now that is at file granularity, though it would be simple enough to generalize it such that any expression which can be translated to a set of git commits can also be turned into a selection of tests. I added some other options as well: Usage: $0 [-dfquvp] [ack options] -d pass --debug to partest -f pass --failed to partest -q DON'T pass --show-log and --show-diff to partest -u pass --update-check to partest -v pass --verbose to partest -p select tests appearing in commits where was also modified Example usage: > tools/partest-ack -p src/compiler/scala/tools/nsc/typechecker/Checkable.scala % tests-modified-in-same-commit ... 12 # 12 tests to run. Testing individual files testing: [...]/files/pos/t6537.scala [ OK ] Testing individual files testing: [...]/files/neg/unchecked-impossible.scala [ OK ] testing: [...]/files/neg/t1872.scala [ OK ] testing: [...]/files/neg/t4302.scala [ OK ] testing: [...]/files/neg/unchecked-knowable.scala [ OK ] testing: [...]/files/neg/unchecked-abstract.scala [ OK ] [etc] --- tools/partest-ack | 156 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 43 deletions(-) (limited to 'tools/partest-ack') diff --git a/tools/partest-ack b/tools/partest-ack index 0c8244257b..f7d5063292 100755 --- a/tools/partest-ack +++ b/tools/partest-ack @@ -2,36 +2,18 @@ # # wrapper around partest for fine-grained test selection via ack -args="$@" - -pathMatches () { - ack --noenv --text --files-with-matches "$@" test/files - - for p in $(find test/files/* -print); do - [[ $p =~ $1 ]] && echo "$p" - done -} - -testIds () { - pathMatches "$@" | \ - perl -pe 's#^(test/files/[^/]+/[^/.]+).*$#$1#' | \ - sort -u -} -testPaths () { - for id in "$@"; do - if [[ -d $id ]]; then - echo $id - elif [[ -f ${id}.scala ]]; then - echo "${id}.scala" - else - echo >&2 "No test corresponds to $id" - fi - done -} +declare quiet failed update partest_debug file_regex partest_args ack_args cotouched [[ $# -gt 0 ]] || { cat < [ack options] +Usage: $0 [-dfquvp] [ack options] + + -d pass --debug to partest + -f pass --failed to partest + -q DON'T pass --show-log and --show-diff to partest + -u pass --update-check to partest + -v pass --verbose to partest + -p select tests appearing in commits where was also modified Given a regular expression (and optionally, any arguments accepted by ack) runs all the tests for which any associated file matches the regex. Associated @@ -42,30 +24,118 @@ You must have ack installed: http://betterthangrep.com/ack-standalone Examples: - % tools/partest-ack monad - Found 4 tests matching 'ack monad' + > tools/partest-ack monad + % tests-with-matching-paths ... 2 + % tests-with-matching-code ... 2 + # 4 tests to run. - Testing individual files - testing: [...]/files/pos/tcpoly_boundedmonad.scala [ OK ] - testing: [...]/files/pos/tcpoly_ticket2096.scala [ OK ] - testing: [...]/files/run/tcpoly_monads.scala [ OK ] - testing: [...]/files/presentation/callcc-interpreter [ OK ] + > tools/partest-ack -p src/library/scala/Enumeration.scala + % tests-modified-in-same-commit ... 84 + # 84 tests to run. - % tools/partest-ack monad -i # -i == ignore case - Found 12 tests matching 'ack monad -i' - - Testing individual files - [etc] + > tools/partest-ack -f + % tests-which-failed ... 42 + # 42 tests to run. EOM exit 0 } -paths=$(testPaths $(testIds "$@")) -if [[ -z $paths ]]; then +# The leading : in :achs suppresses some errors. Each letter is a valid +# option. If an option takes an argument, a colon follows it, e.g. +# it would be :ach:s if -h took an argument. +while getopts :fuvdp: opt; do + case $opt in + d) partest_debug=true && partest_args="$partest_args --debug" ;; + f) failed=true && partest_args="$partest_args --failed" ;; + p) cotouched="$cotouched $OPTARG" ;; + q) quiet=true ;; + u) partest_args="$partest_args --update-check" ;; + v) partest_args="$partest_args --verbose" ;; + :) echo "Option -$OPTARG requires an argument." >&2 ;; # this case is called for a missing option argument + *) echo "Unrecognized argument $OPTARG" ;; # this is the catch-all implying an unknown option + esac +done + +shift $((OPTIND-1)) +file_regex="$1" +ack_args="$*" + +tests () { + find test/files -mindepth 2 -maxdepth 2 -name '*.scala' -o -type d +} + +pathsToTests () { + for path in $(perl -pe 's#^(test/files/[^/]+/[^/.]+).*$#$1#'); do + if [[ -d "$path" ]]; then + echo "$path" + elif [[ -f "$path.scala" ]]; then + echo "$path.scala" + fi + done | sort -u +} + +tests-with-matching-paths() { + local re="$1" + for p in $(find test/files -type f); do + [[ $p =~ $re ]] && echo "$p" + done +} + +tests-which-failed () { + for f in $(find test/files -name '*.log'); do + echo ${f%-*} + done +} + +tests-modified-in-same-commit() { + [[ $# -gt 0 ]] && \ + for rev in $(git rev-list HEAD -- "$@"); do + git --no-pager show --pretty="format:" --name-only "$rev" -- test/files + done +} + +tests-with-matching-code() { + ack --noenv --text --files-with-matches "$@" -- test/files +} + +countStdout () { + local -i count=0 + while read line; do + printf "$line\n" + count+=1 + done + + printf >&2 " $count\n" +} + +testRun () { + printf >&2 "%% %-30s ... " "$1" + "$@" | pathsToTests | countStdout +} + +allMatches() { + [[ -n $file_regex ]] && testRun tests-with-matching-paths $file_regex + [[ -n $cotouched ]] && testRun tests-modified-in-same-commit $cotouched + [[ -n $ack_args ]] && testRun tests-with-matching-code $ack_args + [[ -n $failed ]] && testRun tests-which-failed +} + +paths=$(allMatches | sort -u) +[[ -n $quiet ]] || partest_args="--show-diff --show-log $partest_args" + +if [[ -z $paths ]] && [[ -z $failed ]]; then echo >&2 "No matching tests." else count=$(echo $(echo "$paths" | wc -w)) - echo "Found $count tests matching 'ack $@'" - test/partest $paths + + # Output a command line which will re-run these same tests. + echo "# $count tests to run." + printf "%-52s %s\n" "test/partest $partest_args" "\\" + for path in $paths; do + printf " %-50s %s\n" "$path" "\\" + done + echo ' ""' + + test/partest $partest_args $paths fi -- cgit v1.2.3