Grails R14 Error (Memory quota exceeded) on Heroku
May 13th, 2014
Explains how to resolve the Grails R14 Error when it is encountered on Heroku.
When refactoring code in bulk, I occasionally run into a scenario where it’s simpler to make the change all at once and run the tests afterwards than it is to test after every iteration of the change. Some examples include renaming method or variable names (or anything with an IDE’s find-and-replace feature), changing internationalized text, or adding/removing a method call. However, the full test suite for a project can take a very long time to run, so I initially test only the modified (and related) classes. I figured it would be nice to have a script automatically test the modified files for me, so I tried my hand at writing one.
Granted, this is my first bash script so I may have missed some standards/conventions, but I did my best to keep up with best practices. The script will grab the list of modified files from git, parse their “base” file names, and then pass those names appended with the wildcard character (*) to grails test-app. It’s pretty simple, and I wasn’t able to find any scripts that already did this, so I figured it would be a good chance to brush up on my bash scripting skills.
Without further ado, here is the script itself:
#!/bin/sh
usage(){
echo "Usage: `basename $0` [-h] [-r] [-t testOptions] [<directory>...]\n"
echo ' -h Show this help message.'
echo ' -r Remove the default directories, and only use the ones provided. Without the flag, the provided directories will be appended to the default list.'
echo ' -t Options to pass to "grails test-app". Default: none.'
echo ' See: http://grails.org/doc/latest/ref/Command%20Line/test-app.html'
}
# Parse the arguments
testOpts=
directories='grails-app src/groovy'
while getopts “hrt:” option
do
case ${option} in
h) usage; exit 0;;
r) directories='';;
t) testOpts=${OPTARG};;
*) usage; exit 1;;
esac
done
shift $(( OPTIND-1 ))
directories+=" ${*}"
# Get the modified files
modifiedFiles=`git diff --name-only HEAD ${directories}`
regex="([^/]*)\.groovy"
testPatterns=''
for filename in ${modifiedFiles}; do
if [[ ${filename} =~ ${regex} ]]; then
testPatterns+="${BASH_REMATCH[1]}* "
fi
done
# Run the tests
if [ -n "${testPatterns}" ]; then
echo "Calling... grails test-app ${testOpts} ${testPatterns}\n"
grails test-app ${testOpts} ${testPatterns}
else
echo "No modified classes found to test."
fi
Simply copy that into a .sh file, chmod +x permissions to it, and (optionally) add an alias (e.g. alias gitTestModified=’~/scripts/gitTestModified.sh’) in your .bashrc to easily invoke it. So with our example, we could call it with:gitTestModified
By default the script takes no arguments and simply checks the following directories for modified .groovy files (as according to git diff HEAD):grails-app src/groovy
This list can be appended simply by passing some bulk arguments to the script. For example, to check for tests that were modified as well, we can do:gitTestModified test # Add 'test' to the directories to search for git changes
If there are modified files, the tests will be invoked. If not, then a simple message will pop up saying so.
gitTestModified also allows a -r flag to exclusively check the directories passed in, overriding the defaults in the script. So the following call would look ONLY in the ‘test’ directory:gitTestModified -r test # Only check the 'test' directory for git changes
Once changed files are found and parsed, the filenames are appended with the wildcard (*) and passed to grails test-app. Since the typical Grails test naming convention is
If we want to pass additional arguments to grails test-app, so we can for example, run only tests that failed last time, we can do so using the -t option and then providing the arguments:gitTestModified -t "-rerun" # Only run tests that failed last time we called test-app
Since these arguments are passed directly to grails test-app, it’s best to wrap them in quotes due to the dashes and potential spaces. This also means we can append additional tests to run:gitTestModified -t "-unit MyExtraTests.groovy"
Finally, the script has a -h flag to display its usage information:
Usage: gitTestModified.sh [-h] [-r] [-t testOptions] [...]</code>
-h Show this help message.
-r Only check the directories provided. Otherwise, the provided directories will be appended to the directory list.
-t Options to pass to "grails test-app". Default: none.
See: http://grails.org/doc/latest/ref/Command%20Line/test-app.html
gitTestModified also outputs each call to grails test-app both for easier debugging and for easy copying/pasting in case you want to run the tests independently.
The script currently only checks for .groovy files, and relies on git diff HEAD to get its list of changed files, so committed changes may not show up in that list. It only checks .groovy files (not .java), but you can change the regex variable in the script if you need Java files too. It’s also my first major bash script, so it may be a little rough around the edges. If you’d like to fork it and/or improve on it, I’ve uploaded the code on GitHub.
Happy refactoring!
Igor Shults
Explains how to resolve the Grails R14 Error when it is encountered on Heroku.
Gradle build code will sometimes need to be reused across the enterprise. Here are a few ways to do so.
Using controller filters to configure tracking and logging of Hibernate statistics in HTTP requests.
Igor is a self-driven developer with a desire to apply and expand his current skill set. He has experience working with companies of all sizes on the whole application stack, from the database to the front-end. He enjoys working in collaborative environments involving discussion and planning around data modeling and product development.