diff options
Diffstat (limited to 'tools/partest-ack')
-rwxr-xr-x | tools/partest-ack | 158 |
1 files changed, 79 insertions, 79 deletions
diff --git a/tools/partest-ack b/tools/partest-ack index f7d5063292..551f92684f 100755 --- a/tools/partest-ack +++ b/tools/partest-ack @@ -2,18 +2,29 @@ # # wrapper around partest for fine-grained test selection via ack -declare quiet failed update partest_debug file_regex partest_args ack_args cotouched +declare quiet failed update partest_debug +declare cotouched since sortCommand +declare -a ack_args partest_args scalac_args + +base="$(cd "$(dirname "$0")"/.. && pwd)" +cd "$base" || { echo "Could not change to base directory $base" && exit 1; } +filesdir="test/files" +sortCommand="sort -u" + +# have to enumerate good test dirs since partest chokes and fails +# on continuations, bench, etc. tests +pathRegex="$filesdir/(pos|neg|jvm|run|scalap|presentation)/[^/.]+([.]scala)?\$" [[ $# -gt 0 ]] || { cat <<EOM 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 + -q pass --terse 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 + -s <time> select tests touched since <time> (git format, e.g. 1.month.ago) + -r run tests in random order Given a regular expression (and optionally, any arguments accepted by ack) runs all the tests for which any associated file matches the regex. Associated @@ -24,118 +35,107 @@ You must have ack installed: http://betterthangrep.com/ack-standalone Examples: - > tools/partest-ack monad - % tests-with-matching-paths ... 2 - % tests-with-matching-code ... 2 - # 4 tests to run. + > tools/partest-ack 'case (class|object) Baz' + % testsWithMatchingPaths ... 0 + % testsWithMatchingCode ... 3 + # 3 tests to run. + + > tools/partest-ack -s 12.hours.ago + % testsTouchedSinceGitTime ... 33 + # 33 tests to run. > tools/partest-ack -p src/library/scala/Enumeration.scala - % tests-modified-in-same-commit ... 84 - # 84 tests to run. + % testsModifiedInSameCommit ... 80 + # 80 tests to run. > tools/partest-ack -f % tests-which-failed ... 42 # 42 tests to run. + + > tools/partest-ack "kinds of the type arguments" + % testsWithMatchingPaths ... 0 + % testsWithMatchingCode ... 6 + # 6 tests to run. EOM exit 0 } -# 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 +while getopts :fuvdrp:s: opt; do case $opt in - d) partest_debug=true && partest_args="$partest_args --debug" ;; - f) failed=true && partest_args="$partest_args --failed" ;; + f) failed=true && 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 + r) sortCommand="randomSort" ;; + s) since="$OPTARG" ;; + q) partest_args+=" --terse" ;; + u) partest_args+=" --update-check" ;; + v) partest_args+=" --verbose" ;; + :) echo "Option -$OPTARG requires an argument." >&2 ;; + *) ack_args+="-$OPTARG" ;; # don't drop unknown args, assume they're for ack esac done shift $((OPTIND-1)) -file_regex="$1" -ack_args="$*" +ack_args=( "${ack_args[@]}" "$@" ) -tests () { - find test/files -mindepth 2 -maxdepth 2 -name '*.scala' -o -type d -} +# Echo the argument only if it matches our idea of a test and exists. +isPath () { [[ "$1" =~ $pathRegex ]] && [[ -e "$1" ]]; } -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" +# Filter stdin down to actual test paths. +asTestPaths () { + while read p; do + p1="${p%.*}" + isPath "$p1" && echo "$p1" + isPath "$p1.scala" && echo "$p1.scala" 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 -} +# These methods all just create paths which may or may not be tests +# all are filtered through "asTestPaths" which limits the output to actual tests +regexPathTests () { find "$filesdir" | ack --noenv "$@"; } +failedTests () { for p in $(find "$filesdir" -name '*.log'); do p1=${p%.log} && p2=${p1%-*} && echo "$p2"; done; } +sinceTests() { git log --since="$@" --name-only --pretty="format:" -- "$filesdir"; } +regexCodeTests () { ack --noenv --text --files-with-matches "$@" -- "$filesdir"; } +sameCommitTests() { for rev in $(git rev-list HEAD -- "$@"); do git --no-pager show --pretty="format:" --name-only "$rev" -- "$filesdir"; done; } countStdout () { local -i count=0 while read line; do - printf "$line\n" - count+=1 + printf "$line\n" && count+=1 done printf >&2 " $count\n" } +randomSort () { + sort -u | while read line; do echo "$RANDOM $line"; done | sort | sed -E 's/^[0-9]+ //' +} + testRun () { - printf >&2 "%% %-30s ... " "$1" - "$@" | pathsToTests | countStdout + local description="$1" && shift + printf >&2 "%% tests %-25s ... " "$description" + "$@" | asTestPaths | sort -u | countStdout | egrep -v '^[ ]*$' } 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 + [[ -n $ack_args ]] && testRun "with matching paths" regexPathTests "${ack_args[@]}" + [[ -n $ack_args ]] && testRun "with matching code" regexCodeTests "${ack_args[@]}" + [[ -n $cotouched ]] && testRun "modified in same commit" sameCommitTests $cotouched + [[ -n $since ]] && testRun "modified since time" sinceTests "$since" + [[ -n $failed ]] && testRun "failed on last run" failedTests } -paths=$(allMatches | sort -u) -[[ -n $quiet ]] || partest_args="--show-diff --show-log $partest_args" +paths=$(allMatches | $sortCommand) -if [[ -z $paths ]] && [[ -z $failed ]]; then - echo >&2 "No matching tests." -else - count=$(echo $(echo "$paths" | wc -w)) +[[ -z $paths ]] && [[ -z $failed ]] && echo >&2 "No matching tests." && exit 0; - # 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 ' ""' +count=$(echo $(echo "$paths" | wc -w)) +[[ "$count" -eq 0 ]] && echo >&2 "No tests to run." && exit 0; + +# Output a command line which will re-run these same tests. +echo "# $count tests to run." +printf "%-52s %s\n" "$base/test/partest ${partest_args[@]}" "\\" +for path in $paths; do printf " %-50s %s\n" "$path" "\\"; done +echo ' ""' - test/partest $partest_args $paths -fi +test/partest "${partest_args[@]}" $paths |