Permalink
Browse files

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]
  • Loading branch information...
1 parent d499db3 commit d2965f8b458a210868f64261093a2372d0ef91d6 @paulp paulp committed Feb 1, 2013
Showing with 113 additions and 43 deletions.
  1. +113 −43 tools/partest-ack
View
@@ -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

0 comments on commit d2965f8

Please sign in to comment.