summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-01-31 16:35:35 -0800
committerPaul Phillips <paulp@improving.org>2013-01-31 16:46:51 -0800
commitd2965f8b458a210868f64261093a2372d0ef91d6 (patch)
tree4acd1a2c043160719ad492cd862fccfb7843056c /tools
parentd499db3800b6460cfd575e650953980211d4026b (diff)
downloadscala-d2965f8b458a210868f64261093a2372d0ef91d6.tar.gz
scala-d2965f8b458a210868f64261093a2372d0ef91d6.tar.bz2
scala-d2965f8b458a210868f64261093a2372d0ef91d6.zip
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 <regex> [-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 <path> select tests appearing in commits where <path> 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]
Diffstat (limited to 'tools')
-rwxr-xr-xtools/partest-ack156
1 files changed, 113 insertions, 43 deletions
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 <<EOM
-Usage: $0 <regex> [ack options]
+Usage: $0 <regex> [-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 <path> select tests appearing in commits where <path> 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