tuskar-ui/run_tests.sh
Gabriel Hurley 7cd53c2506 Adds function to count tab characters in files to run_test.sh.
In case you're frustrated by mixed use of tab characters and
spaces for indentation, this function finds tab characters in
all the Python, CSS, Javascript and HTML files in the project,
and lists out any offending files that contain tabs.

Returns proper exit codes in case we someday want to gate on
this check.

Change-Id: I70195e9d00368a5d177cd3792921028e0bcd9b53
2011-11-14 23:46:41 -08:00

450 lines
13 KiB
Bash
Executable File

#!/bin/bash
set -o errexit
# ---------------UPDATE ME-------------------------------#
# Increment me any time the environment should be rebuilt.
# This includes dependncy changes, directory renames, etc.
# Simple integer secuence: 1, 2, 3...
environment_version=3
#--------------------------------------------------------#
function usage {
echo "Usage: $0 [OPTION]..."
echo "Run Horizon's test suite(s)"
echo ""
echo " -V, --virtual-env Always use virtualenv. Install automatically"
echo " if not present"
echo " -N, --no-virtual-env Don't use virtualenv. Run tests in local"
echo " environment"
echo " -c, --coverage Generate reports using Coverage"
echo " -f, --force Force a clean re-build of the virtual"
echo " environment. Useful when dependencies have"
echo " been added."
echo " -p, --pep8 Just run pep8"
echo " -t, --tabs Check for tab characters in files."
echo " -y, --pylint Just run pylint"
echo " -q, --quiet Run non-interactively. (Relatively) quiet."
echo " --with-selenium Run unit tests including Selenium tests"
echo " --runserver Run the Django development server for"
echo " openstack-dashboard in the virtual"
echo " environment."
echo " --docs Just build the documentation"
echo " --backup-environment Make a backup of the environment on exit"
echo " --restore-environment Restore the environment before running"
echo " --destroy-environment DEstroy the environment and exit"
echo " -h, --help Print this usage message"
echo ""
echo "Note: with no options specified, the script will try to run the tests in"
echo " a virtual environment, If no virtualenv is found, the script will ask"
echo " if you would like to create one. If you prefer to run tests NOT in a"
echo " virtual environment, simply pass the -N option."
exit
}
# DEFAULTS FOR RUN_TESTS.SH
#
venv=openstack-dashboard/.dashboard-venv
django_with_venv=openstack-dashboard/tools/with_venv.sh
dashboard_with_venv=tools/with_venv.sh
always_venv=0
never_venv=0
force=0
with_coverage=0
selenium=0
testargs=""
django_wrapper=""
dashboard_wrapper=""
just_pep8=0
just_pylint=0
just_docs=0
just_tabs=0
runserver=0
quiet=0
backup_env=0
restore_env=0
destroy=0
# Jenkins sets a "JOB_NAME" variable, if it's not set, we'll make it "default"
[ "$JOB_NAME" ] || JOB_NAME="default"
function process_option {
case "$1" in
-h|--help) usage;;
-V|--virtual-env) always_venv=1; never_venv=0;;
-N|--no-virtual-env) always_venv=0; never_venv=1;;
-p|--pep8) just_pep8=1;;
-y|--pylint) just_pylint=1;;
-f|--force) force=1;;
-t|--tabs) just_tabs=1;;
-q|--quiet) quiet=1;;
-c|--coverage) with_coverage=1;;
--with-selenium) selenium=1;;
--docs) just_docs=1;;
--runserver) runserver=1;;
--backup-environment) backup_env=1;;
--restore-environment) restore_env=1;;
--destroy-environment) destroy=1;;
*) testargs="$testargs $1"
esac
}
function run_server {
echo "Starting Django development server..."
${django_wrapper} python openstack-dashboard/dashboard/manage.py runserver
echo "Server stopped."
}
function run_pylint {
echo "Running pylint ..."
PYLINT_INCLUDE="openstack-dashboard/dashboard horizon/horizon"
${django_wrapper} pylint --rcfile=.pylintrc -f parseable $PYLINT_INCLUDE > pylint.txt || true
CODE=$?
grep Global -A2 pylint.txt
if [ $CODE -lt 32 ]
then
echo "Completed successfully."
exit 0
else
echo "Completed with problems."
exit $CODE
fi
}
function run_pep8 {
echo "Running pep8 ..."
rm -f pep8.txt
PEP8_EXCLUDE=vcsversion.py
PEP8_OPTIONS="--exclude=$PEP8_EXCLUDE --repeat"
PEP8_INCLUDE="openstack-dashboard/dashboard horizon/horizon"
echo "${django_wrapper} pep8 $PEP8_OPTIONS $PEP8_INCLUDE > pep8.txt"
${django_wrapper} pep8 $PEP8_OPTIONS $PEP8_INCLUDE > pep8.txt || true
PEP8_COUNT=`wc -l pep8.txt | awk '{ print $1 }'`
if [ $PEP8_COUNT -ge 1 ]; then
echo "PEP8 violations found ($PEP8_COUNT):"
cat pep8.txt
echo "Please fix all PEP8 violations before committing."
else
echo "No violations found. Good job!"
fi
}
function run_sphinx {
echo "Building sphinx..."
echo "export DJANGO_SETTINGS_MODULE=dashboard.settings"
export DJANGO_SETTINGS_MODULE=dashboard.settings
echo "${django_wrapper} sphinx-build -b html docs/source docs/build/html"
${django_wrapper} sphinx-build -b html docs/source docs/build/html
echo "Build complete."
}
function tab_check {
TAB_VIOLATIONS=`find horizon/horizon openstack-dashboard/dashboard -type f -regex ".*\.\(css\|js\|py\|html\)" -print0 | xargs -0 awk '/\t/' | wc -l`
if [ $TAB_VIOLATIONS -gt 0 ]; then
echo "TABS! $TAB_VIOLATIONS of them! Oh no!"
HORIZON_FILES=`find horizon/horizon openstack-dashboard/dashboard -type f -regex ".*\.\(css\|js\|py|\html\)"`
for TABBED_FILE in $HORIZON_FILES
do
TAB_COUNT=`awk '/\t/' $TABBED_FILE | wc -l`
if [ $TAB_COUNT -gt 0 ]; then
echo "$TABBED_FILE: $TAB_COUNT"
fi
done
fi
return $TAB_VIOLATIONS;
}
function destroy_buildout {
echo "Removing buildout files..."
rm -rf horizon/bin
rm -rf horizon/eggs
rm -rf horizon/parts
rm -rf horizon/develop-eggs
rm -rf horizon/horizon.egg-info
echo "Buildout files removed."
}
function destroy_venv {
echo "Cleaning virtualenv..."
destroy_buildout
echo "Removing virtualenv..."
rm -rf openstack-dashboard/.dashboard-venv
echo "Virtualenv removed."
rm -f .environment_version
echo "Environment cleaned."
}
function environment_check {
echo "Checking environment."
if [ -f .environment_version ]; then
ENV_VERS=`cat .environment_version`
if [ $ENV_VERS -eq $environment_version ]; then
if [ -e ${venv} ]; then
# If the environment exists and is up-to-date then set our variables
django_wrapper="${django_with_venv}"
dashboard_wrapper="${dashboard_with_venv}"
echo "Environment is up to date."
return 0
fi
fi
fi
if [ $quiet -eq 1 ]; then
install_venv
else
if [ ! -e ${venv} ]; then
echo -e "Environment not found. Install? (Y/n) \c"
else
echo -e "Your environment appears to be out of date. Update? (Y/n) \c"
fi
read update_env
if [ "x$update_env" = "xY" -o "x$update_env" = "x" -o "x$update_env" = "xy" ]; then
# Buildout doesn't play nice with upgrading everytime; kill it to be safe
destroy_buildout
install_venv
fi
fi
}
function sanity_check {
# Anything that should be determined prior to running the tests, server, etc.
if [ ! -e ${venv} ]; then
echo "Virtualenv not found at openstack-dashboard/.dashboard-venv. Did install_venv.py succeed?"
exit 1
fi
if [ ! -f horizon/bin/test ]; then
echo "Error: Test script not found at horizon/bin/test. Did buildout succeed?"
exit 1
fi
if [ ! -f horizon/bin/coverage ]; then
echo "Error: Coverage script not found at horizon/bin/coverage. Did buildout succeed?"
exit 1
fi
if [ ! -f horizon/bin/seleniumrc ]; then
echo "Error: Selenium script not found at horizon/bin/seleniumrc. Did buildout succeed?"
exit 1
fi
}
function backup_environment {
if [ $backup_env -eq 1 ]; then
echo "Backing up environment \"$JOB_NAME\"..."
if [ ! -e ${venv} ]; then
echo "Environment not installed. Cannot back up."
return 0
fi
if [ -d /tmp/.horizon_environment/$JOB_NAME ]; then
mv /tmp/.horizon_environment/$JOB_NAME /tmp/.horizon_environment/$JOB_NAME.old
rm -rf /tmp/.horizon_environment/$JOB_NAME
fi
mkdir -p /tmp/.horizon_environment/$JOB_NAME
cp -r openstack-dashboard/.dashboard-venv /tmp/.horizon_environment/$JOB_NAME/
cp -r horizon/bin /tmp/.horizon_environment/$JOB_NAME/
cp -r horizon/eggs /tmp/.horizon_environment/$JOB_NAME/
cp -r horizon/parts /tmp/.horizon_environment/$JOB_NAME/
cp -r horizon/develop-eggs /tmp/.horizon_environment/$JOB_NAME/
cp -r horizon/horizon.egg-info /tmp/.horizon_environment/$JOB_NAME/
cp .environment_version /tmp/.horizon_environment/$JOB_NAME/
# Remove the backup now that we've completed successfully
rm -rf /tmp/.horizon_environment/$JOB_NAME.old
echo "Backup completed"
fi
}
function restore_environment {
if [ $restore_env -eq 1 ]; then
echo "Restoring environment from backup..."
if [ ! -d /tmp/.horizon_environment/$JOB_NAME ]; then
echo "No backup to restore from."
return 0
fi
destroy_buildout
cp -r /tmp/.horizon_environment/$JOB_NAME/.dashboard-venv openstack-dashboard/
cp -r /tmp/.horizon_environment/$JOB_NAME/bin horizon/
cp -r /tmp/.horizon_environment/$JOB_NAME/eggs horizon/
cp -r /tmp/.horizon_environment/$JOB_NAME/parts horizon/
cp -r /tmp/.horizon_environment/$JOB_NAME/develop-eggs horizon/
cp -r /tmp/.horizon_environment/$JOB_NAME/horizon.egg-info horizon/
cp -r /tmp/.horizon_environment/$JOB_NAME/.environment_version ./
echo "Environment restored successfully."
fi
}
function install_venv {
# Install openstack-dashboard with install_venv.py
export PIP_DOWNLOAD_CACHE=/tmp/.pip_download_cache
export PIP_USE_MIRRORS=true
cd openstack-dashboard
python tools/install_venv.py
cd ..
# Install horizon with buildout
if [ ! -d /tmp/.buildout_cache ]; then
mkdir -p /tmp/.buildout_cache
fi
cd horizon
python bootstrap.py
bin/buildout
cd ..
django_wrapper="${django_with_venv}"
dashboard_wrapper="${dashboard_with_venv}"
# Make sure it worked and record the environment version
sanity_check
chmod -R 754 openstack-dashboard/.dashboard-venv
echo $environment_version > .environment_version
}
function wait_for_selenium {
# Selenium can sometimes take several seconds to start.
STARTED=`grep -irn "Started SocketListener on 0.0.0.0:4444" .selenium_log`
if [ $? -eq 0 ]; then
echo "Selenium server started."
return 0
fi
echo -n "."
sleep 1
wait_for_selenium
}
function stop_selenium {
if [ $selenium -eq 1 ]; then
echo "Stopping Selenium server..."
SELENIUM_JOB=`ps -elf | grep "seleniumrc" | grep -v grep`
if [ $? -eq 0 ]; then
kill `echo "${SELENIUM_JOB}" | awk '{print $4}'`
echo "Selenium process stopped."
else
echo "No selenium process running."
fi
rm -f .selenium_log
fi
}
function run_tests {
sanity_check
if [ $selenium -eq 1 ]; then
stop_selenium
echo "Starting Selenium server..."
rm -f .selenium_log
${django_wrapper} horizon/bin/seleniumrc > .selenium_log &
wait_for_selenium
fi
echo "Running Horizon application tests"
${django_wrapper} coverage erase
${django_wrapper} coverage run horizon/bin/test
# get results of the Horizon tests
OPENSTACK_RESULT=$?
echo "Running openstack-dashboard (Django project) tests"
cd openstack-dashboard
if [ -f local/local_settings.py ]; then
cp local/local_settings.py local/local_settings.py.bak
fi
cp local/local_settings.py.example local/local_settings.py
if [ $selenium -eq 1 ]; then
${dashboard_wrapper} coverage run dashboard/manage.py test --with-selenium --with-cherrypyliveserver
else
${dashboard_wrapper} coverage run dashboard/manage.py test
fi
# get results of the openstack-dashboard tests
DASHBOARD_RESULT=$?
if [ -f local/local_settings.py.bak ]; then
cp local/local_settings.py.bak local/local_settings.py
rm local/local_settings.py.bak
fi
cd ..
if [ $with_coverage -eq 1 ]; then
echo "Generating coverage reports"
${django_wrapper} coverage combine
${django_wrapper} coverage xml -i --omit='/usr*,setup.py,*egg*'
${django_wrapper} coverage html -i --omit='/usr*,setup.py,*egg*' -d reports
fi
stop_selenium
if [ $(($OPENSTACK_RESULT || $DASHBOARD_RESULT)) -eq 0 ]; then
echo "Tests completed successfully."
else
echo "Tests failed."
fi
exit $(($OPENSTACK_RESULT || $DASHBOARD_RESULT))
}
# ---------PREPARE THE ENVIRONMENT------------ #
# PROCESS ARGUMENTS, OVERRIDE DEFAULTS
for arg in "$@"; do
process_option $arg
done
# If destroy is set, just blow it away and exit.
if [ $destroy -eq 1 ]; then
destroy_venv
exit 0
fi
# Ignore all of this if the -N flag was set
if [ $never_venv -eq 0 ]; then
# Restore previous environment if desired
if [ $restore_env -eq 1 ]; then
restore_environment
fi
# Remove the virtual environment if --force used
if [ $force -eq 1 ]; then
destroy_venv
fi
# Then check if it's up-to-date
environment_check
# Create a backup of the up-to-date environment if desired
if [ $backup_env -eq 1 ]; then
backup_environment
fi
fi
# ---------EXERCISE THE CODE------------ #
# Build the docs
if [ $just_docs -eq 1 ]; then
run_sphinx
exit $?
fi
# PEP8
if [ $just_pep8 -eq 1 ]; then
run_pep8
exit $?
fi
# Pylint
if [ $just_pylint -eq 1 ]; then
run_pylint
exit $?
fi
# Tab checker
if [ $just_tabs -eq 1 ]; then
tab_check
exit $?
fi
# Django development server
if [ $runserver -eq 1 ]; then
run_server
exit $?
fi
# Full test suite
run_tests || exit