Updated tox.ini to support new test environment
Closes-bug: 1611040 Change-Id: I83f9d18db23fb4d8282cdce623dafba84cd89a73
This commit is contained in:
parent
ddc6321e6d
commit
d91aff5de8
@ -465,13 +465,13 @@ class Backup(object):
|
|||||||
self.request = request
|
self.request = request
|
||||||
self.client = client(request)
|
self.client = client(request)
|
||||||
|
|
||||||
def list(self, json=False, limit=500, offset=0, search=None):
|
def list(self, json=False, limit=500, offset=0, search={}):
|
||||||
if search:
|
if search:
|
||||||
search = {"match": [{"_all": search}, ], }
|
search = {"match": [{"_all": search}, ], }
|
||||||
|
|
||||||
backups = self.client.backups.list(limit=limit,
|
backups = self.client.backups.list_all(limit=limit,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
search=search)
|
search=search)
|
||||||
|
|
||||||
if json:
|
if json:
|
||||||
return backups
|
return backups
|
||||||
|
@ -17,9 +17,9 @@ import logging
|
|||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.translation import ungettext_lazy
|
from django.utils.translation import ungettext_lazy
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
|
|
||||||
import disaster_recovery.api.api as freezer_api
|
import disaster_recovery.api.api as freezer_api
|
||||||
from disaster_recovery.utils import shield
|
from disaster_recovery.utils import shield
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import forms
|
from horizon import forms
|
||||||
|
86
disaster_recovery/tests/settings.py
Normal file
86
disaster_recovery/tests/settings.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# (c) Copyright 2014-2016 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import socket
|
||||||
|
|
||||||
|
from horizon.test.settings import * # noqa
|
||||||
|
|
||||||
|
SECRET_KEY = 'HELLA_SECRET!'
|
||||||
|
|
||||||
|
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': 'test'}}
|
||||||
|
|
||||||
|
|
||||||
|
socket.setdefaulttimeout(1)
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
|
||||||
|
TESTSERVER = 'http://testserver'
|
||||||
|
|
||||||
|
|
||||||
|
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
|
||||||
|
|
||||||
|
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
|
||||||
|
NOSE_ARGS = ['--nocapture',
|
||||||
|
'--nologcapture',
|
||||||
|
'--cover-package=windc']
|
||||||
|
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
|
||||||
|
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
|
||||||
|
|
||||||
|
OPENSTACK_ADDRESS = "localhost"
|
||||||
|
OPENSTACK_ADMIN_TOKEN = "openstack"
|
||||||
|
OPENSTACK_KEYSTONE_URL = "http://%s:5000/v2.0" % OPENSTACK_ADDRESS
|
||||||
|
OPENSTACK_KEYSTONE_ADMIN_URL = "http://%s:35357/v2.0" % OPENSTACK_ADDRESS
|
||||||
|
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"
|
||||||
|
FREEZER_API_URL = "test"
|
||||||
|
|
||||||
|
# Silence logging output during tests.
|
||||||
|
LOGGING = {
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
'handlers': {
|
||||||
|
'null': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'class': 'logging.NullHandler'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'django.db.backends': {
|
||||||
|
'handlers': ['null'],
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
|
'horizon': {
|
||||||
|
'handlers': ['null'],
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
|
'novaclient': {
|
||||||
|
'handlers': ['null'],
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
|
'keystoneclient': {
|
||||||
|
'handlers': ['null'],
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
|
'quantum': {
|
||||||
|
'handlers': ['null'],
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
|
'nose.plugins.manager': {
|
||||||
|
'handlers': ['null'],
|
||||||
|
'propagate': False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
manage.py
Executable file
23
manage.py
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
os.environ.setdefault(
|
||||||
|
"DJANGO_SETTINGS_MODULE", "disaster_recovery.tests.settings")
|
||||||
|
from django.core.management import execute_from_command_line # noqa
|
||||||
|
execute_from_command_line(sys.argv)
|
583
run_tests.sh
Executable file
583
run_tests.sh
Executable file
@ -0,0 +1,583 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
|
||||||
|
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 " -m, --manage Run a Django management command."
|
||||||
|
echo " --makemessages Create/Update English translation files."
|
||||||
|
echo " --compilemessages Compile all translation files."
|
||||||
|
echo " --check-only Do not update translation files (--makemessages only)."
|
||||||
|
echo " --pseudo Pseudo translate a language."
|
||||||
|
echo " -p, --pep8 Just run pep8"
|
||||||
|
echo " -8, --pep8-changed [<basecommit>]"
|
||||||
|
echo " Just run PEP8 and HACKING compliance check"
|
||||||
|
echo " on files changed since HEAD~1 (or <basecommit>)"
|
||||||
|
echo " -P, --no-pep8 Don't run pep8 by default"
|
||||||
|
echo " -t, --tabs Check for tab characters in files."
|
||||||
|
echo " -y, --pylint Just run pylint"
|
||||||
|
echo " -e, --eslint Just run eslint"
|
||||||
|
echo " -k, --karma Just run karma"
|
||||||
|
echo " -q, --quiet Run non-interactively. (Relatively) quiet."
|
||||||
|
echo " Implies -V if -N is not set."
|
||||||
|
echo " --only-selenium Run only the Selenium unit tests"
|
||||||
|
echo " --with-selenium Run unit tests including Selenium tests"
|
||||||
|
echo " --selenium-headless Run Selenium tests headless"
|
||||||
|
echo " --integration Run the integration tests (requires a running "
|
||||||
|
echo " OpenStack environment)"
|
||||||
|
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
|
||||||
|
#
|
||||||
|
root=`pwd -P`
|
||||||
|
venv=$root/.venv
|
||||||
|
venv_env_version=$venv/environments
|
||||||
|
with_venv=tools/with_venv.sh
|
||||||
|
included_dirs="disaster_recovery"
|
||||||
|
|
||||||
|
always_venv=0
|
||||||
|
backup_env=0
|
||||||
|
command_wrapper=""
|
||||||
|
destroy=0
|
||||||
|
force=0
|
||||||
|
just_pep8=0
|
||||||
|
just_pep8_changed=0
|
||||||
|
no_pep8=0
|
||||||
|
just_pylint=0
|
||||||
|
just_docs=0
|
||||||
|
just_tabs=0
|
||||||
|
just_eslint=0
|
||||||
|
just_karma=0
|
||||||
|
never_venv=0
|
||||||
|
quiet=0
|
||||||
|
restore_env=0
|
||||||
|
runserver=0
|
||||||
|
only_selenium=0
|
||||||
|
with_selenium=0
|
||||||
|
selenium_headless=0
|
||||||
|
integration=0
|
||||||
|
testopts=""
|
||||||
|
testargs=""
|
||||||
|
with_coverage=0
|
||||||
|
makemessages=0
|
||||||
|
compilemessages=0
|
||||||
|
check_only=0
|
||||||
|
pseudo=0
|
||||||
|
manage=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 {
|
||||||
|
# If running manage command, treat the rest of options as arguments.
|
||||||
|
if [ $manage -eq 1 ]; then
|
||||||
|
testargs="$testargs $1"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
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;;
|
||||||
|
-8|--pep8-changed) just_pep8_changed=1;;
|
||||||
|
-P|--no-pep8) no_pep8=1;;
|
||||||
|
-y|--pylint) just_pylint=1;;
|
||||||
|
-e|--eslint) just_eslint=1;;
|
||||||
|
-k|--karma) just_karma=1;;
|
||||||
|
-f|--force) force=1;;
|
||||||
|
-t|--tabs) just_tabs=1;;
|
||||||
|
-q|--quiet) quiet=1;;
|
||||||
|
-c|--coverage) with_coverage=1;;
|
||||||
|
-m|--manage) manage=1;;
|
||||||
|
--makemessages) makemessages=1;;
|
||||||
|
--compilemessages) compilemessages=1;;
|
||||||
|
--check-only) check_only=1;;
|
||||||
|
--pseudo) pseudo=1;;
|
||||||
|
--only-selenium) only_selenium=1;;
|
||||||
|
--with-selenium) with_selenium=1;;
|
||||||
|
--selenium-headless) selenium_headless=1;;
|
||||||
|
--integration) integration=1;;
|
||||||
|
--docs) just_docs=1;;
|
||||||
|
--runserver) runserver=1;;
|
||||||
|
--backup-environment) backup_env=1;;
|
||||||
|
--restore-environment) restore_env=1;;
|
||||||
|
--destroy-environment) destroy=1;;
|
||||||
|
-*) testopts="$testopts $1";;
|
||||||
|
*) testargs="$testargs $1"
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_management_command {
|
||||||
|
${command_wrapper} python $root/manage.py $testopts $testargs
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_server {
|
||||||
|
echo "Starting Django development server..."
|
||||||
|
${command_wrapper} python $root/manage.py runserver $testopts $testargs
|
||||||
|
echo "Server stopped."
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_pylint {
|
||||||
|
echo "Running pylint ..."
|
||||||
|
PYTHONPATH=$root ${command_wrapper} pylint --rcfile=.pylintrc -f parseable $included_dirs > 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_eslint {
|
||||||
|
echo "Running eslint ..."
|
||||||
|
if [ "`which npm`" == '' ] ; then
|
||||||
|
echo "npm is not present; please install, e.g. sudo apt-get install npm"
|
||||||
|
else
|
||||||
|
npm install
|
||||||
|
npm run lint
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_karma {
|
||||||
|
echo "Running karma ..."
|
||||||
|
npm install
|
||||||
|
npm run test
|
||||||
|
}
|
||||||
|
|
||||||
|
function warn_on_flake8_without_venv {
|
||||||
|
set +o errexit
|
||||||
|
${command_wrapper} python -c "import hacking" 2>/dev/null
|
||||||
|
no_hacking=$?
|
||||||
|
set -o errexit
|
||||||
|
if [ $never_venv -eq 1 -a $no_hacking -eq 1 ]; then
|
||||||
|
echo "**WARNING**:" >&2
|
||||||
|
echo "OpenStack hacking is not installed on your host. Its detection will be missed." >&2
|
||||||
|
echo "Please install or use virtual env if you need OpenStack hacking detection." >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_pep8 {
|
||||||
|
echo "Running flake8 ..."
|
||||||
|
warn_on_flake8_without_venv
|
||||||
|
DJANGO_SETTINGS_MODULE=disaster_recovery.test.settings ${command_wrapper} flake8
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_pep8_changed {
|
||||||
|
# NOTE(gilliard) We want use flake8 to check the entirety of every file that has
|
||||||
|
# a change in it. Unfortunately the --filenames argument to flake8 only accepts
|
||||||
|
# file *names* and there are no files named (eg) "nova/compute/manager.py". The
|
||||||
|
# --diff argument behaves surprisingly as well, because although you feed it a
|
||||||
|
# diff, it actually checks the file on disk anyway.
|
||||||
|
local base_commit=${testargs:-HEAD~1}
|
||||||
|
files=$(git diff --name-only $base_commit | tr '\n' ' ')
|
||||||
|
echo "Running flake8 on ${files}"
|
||||||
|
warn_on_flake8_without_venv
|
||||||
|
diff -u --from-file /dev/null ${files} | DJANGO_SETTINGS_MODULE=disaster_recovery.test.settings ${command_wrapper} flake8 --diff
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_sphinx {
|
||||||
|
echo "Building sphinx..."
|
||||||
|
DJANGO_SETTINGS_MODULE=disaster_recovery.test.settings ${command_wrapper} python setup.py build_sphinx
|
||||||
|
echo "Build complete."
|
||||||
|
}
|
||||||
|
|
||||||
|
function tab_check {
|
||||||
|
TAB_VIOLATIONS=`find $included_dirs -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 $included_dirs -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_venv {
|
||||||
|
echo "Cleaning environment..."
|
||||||
|
echo "Removing virtualenv..."
|
||||||
|
rm -rf $venv
|
||||||
|
echo "Virtualenv removed."
|
||||||
|
}
|
||||||
|
|
||||||
|
function environment_check {
|
||||||
|
echo "Checking environment."
|
||||||
|
if [ -f $venv_env_version ]; then
|
||||||
|
set +o errexit
|
||||||
|
cat requirements.txt test-requirements.txt | cmp $venv_env_version - > /dev/null
|
||||||
|
local env_check_result=$?
|
||||||
|
set -o errexit
|
||||||
|
if [ $env_check_result -eq 0 ]; then
|
||||||
|
# If the environment exists and is up-to-date then set our variables
|
||||||
|
command_wrapper="${root}/${with_venv}"
|
||||||
|
echo "Environment is up to date."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $always_venv -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
|
||||||
|
install_venv
|
||||||
|
else
|
||||||
|
# Set our command wrapper anyway.
|
||||||
|
command_wrapper="${root}/${with_venv}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanity_check {
|
||||||
|
# Anything that should be determined prior to running the tests, server, etc.
|
||||||
|
# Don't sanity-check anything environment-related in -N flag is set
|
||||||
|
if [ $never_venv -eq 0 ]; then
|
||||||
|
if [ ! -e ${venv} ]; then
|
||||||
|
echo "Virtualenv not found at $venv. Did install_venv.py succeed?"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Remove .pyc files. This is sanity checking because they can linger
|
||||||
|
# after old files are deleted.
|
||||||
|
find . -name "*.pyc" -exec rm -rf {} \;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 $venv /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
|
||||||
|
|
||||||
|
cp -r /tmp/.horizon_environment/$JOB_NAME/.venv ./ || true
|
||||||
|
echo "Environment restored successfully."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_venv {
|
||||||
|
# Install with install_venv.py
|
||||||
|
export PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE-/tmp/.pip_download_cache}
|
||||||
|
export PIP_USE_MIRRORS=true
|
||||||
|
if [ $quiet -eq 1 ]; then
|
||||||
|
export PIP_NO_INPUT=true
|
||||||
|
fi
|
||||||
|
echo "Fetching new src packages..."
|
||||||
|
rm -rf $venv/src
|
||||||
|
python tools/install_venv.py
|
||||||
|
command_wrapper="$root/${with_venv}"
|
||||||
|
# Make sure it worked and record the environment version
|
||||||
|
sanity_check
|
||||||
|
chmod -R 754 $venv
|
||||||
|
cat requirements.txt test-requirements.txt > $venv_env_version
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_tests {
|
||||||
|
sanity_check
|
||||||
|
|
||||||
|
if [ $with_selenium -eq 1 ]; then
|
||||||
|
export WITH_SELENIUM=1
|
||||||
|
elif [ $only_selenium -eq 1 ]; then
|
||||||
|
export WITH_SELENIUM=1
|
||||||
|
export SKIP_UNITTESTS=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $with_selenium -eq 0 -a $integration -eq 0 ]; then
|
||||||
|
testopts="$testopts --exclude-dir=disaster_recovery/test/integration_tests"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $selenium_headless -eq 1 ]; then
|
||||||
|
export SELENIUM_HEADLESS=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$testargs" ]; then
|
||||||
|
run_tests_all
|
||||||
|
else
|
||||||
|
run_tests_subset
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_tests_subset {
|
||||||
|
project=`echo $testargs | awk -F. '{print $1}'`
|
||||||
|
${command_wrapper} python $root/manage.py test --settings=$project.test.settings $testopts $testargs
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_tests_all {
|
||||||
|
echo "Running Freezer Web UI tests"
|
||||||
|
export NOSE_XUNIT_FILE=disaster_recovery/nosetests.xml
|
||||||
|
if [ "$NOSE_WITH_HTML_OUTPUT" = '1' ]; then
|
||||||
|
export NOSE_HTML_OUT_FILE='dashboard_nose_results.html'
|
||||||
|
fi
|
||||||
|
${command_wrapper} ${coverage_run} $root/manage.py test disaster_recovery --settings=disaster_recovery.test.settings $testopts
|
||||||
|
# get results of the openstack_dashboard tests
|
||||||
|
DASHBOARD_RESULT=$?
|
||||||
|
|
||||||
|
if [ $with_coverage -eq 1 ]; then
|
||||||
|
echo "Generating coverage reports"
|
||||||
|
${command_wrapper} python -m coverage.__main__ combine
|
||||||
|
${command_wrapper} python -m coverage.__main__ xml -i --include="horizon/*,openstack_dashboard/*" --omit='/usr*,setup.py,*egg*,.venv/*'
|
||||||
|
${command_wrapper} python -m coverage.__main__ html -i --include="horizon/*,openstack_dashboard/*" --omit='/usr*,setup.py,*egg*,.venv/*' -d reports
|
||||||
|
fi
|
||||||
|
# Remove the leftover coverage files from the -p flag earlier.
|
||||||
|
rm -f .coverage.*
|
||||||
|
|
||||||
|
PEP8_RESULT=0
|
||||||
|
if [ $no_pep8 -eq 0 ] && [ $only_selenium -eq 0 ]; then
|
||||||
|
run_pep8
|
||||||
|
PEP8_RESULT=$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
TEST_RESULT=$(($DASHBOARD_RESULT || $PEP8_RESULT))
|
||||||
|
if [ $TEST_RESULT -eq 0 ]; then
|
||||||
|
echo "Tests completed successfully."
|
||||||
|
else
|
||||||
|
echo "Tests failed."
|
||||||
|
fi
|
||||||
|
exit $TEST_RESULT
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_integration_tests {
|
||||||
|
export INTEGRATION_TESTS=1
|
||||||
|
|
||||||
|
if [ $selenium_headless -eq 1 ]; then
|
||||||
|
export SELENIUM_HEADLESS=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running Horizon integration tests..."
|
||||||
|
if [ -z "$testargs" ]; then
|
||||||
|
${command_wrapper} nosetests openstack_dashboard/test/integration_tests/tests
|
||||||
|
else
|
||||||
|
${command_wrapper} nosetests $testargs
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function babel_extract {
|
||||||
|
DOMAIN=$1
|
||||||
|
KEYWORDS="-k gettext_noop -k gettext_lazy -k ngettext_lazy:1,2"
|
||||||
|
KEYWORDS+=" -k ugettext_noop -k ugettext_lazy -k ungettext_lazy:1,2"
|
||||||
|
KEYWORDS+=" -k npgettext:1c,2,3 -k pgettext_lazy:1c,2 -k npgettext_lazy:1c,2,3"
|
||||||
|
|
||||||
|
${command_wrapper} pybabel extract -F ../babel-${DOMAIN}.cfg -o locale/${DOMAIN}.pot $KEYWORDS .
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_makemessages {
|
||||||
|
|
||||||
|
echo -n "freezer web ui: "
|
||||||
|
cd disaster_recovery
|
||||||
|
babel_extract django
|
||||||
|
FREEZER_PY_RESULT=$?
|
||||||
|
|
||||||
|
echo -n "freezer web ui javascript: "
|
||||||
|
babel_extract djangojs
|
||||||
|
FREEZER_JS_RESULT=$?
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
if [ $check_only -eq 1 ]; then
|
||||||
|
rm disaster_recovery/locale/django*.pot
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $(($FREEZER_PY_RESULT || $FREEZER_JS_RESULT))
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_compilemessages {
|
||||||
|
cd horizon
|
||||||
|
${command_wrapper} $root/manage.py compilemessages
|
||||||
|
HORIZON_PY_RESULT=$?
|
||||||
|
cd ../openstack_dashboard
|
||||||
|
${command_wrapper} $root/manage.py compilemessages
|
||||||
|
DASHBOARD_RESULT=$?
|
||||||
|
exit $(($HORIZON_PY_RESULT || $DASHBOARD_RESULT))
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_pseudo {
|
||||||
|
for lang in $testargs
|
||||||
|
# Use English pot file as the source file/pot file just like real Horizon translations
|
||||||
|
do
|
||||||
|
${command_wrapper} $root/tools/pseudo.py openstack_dashboard/locale/django.pot openstack_dashboard/locale/$lang/LC_MESSAGES/django.po $lang
|
||||||
|
${command_wrapper} $root/tools/pseudo.py openstack_dashboard/locale/djangojs.pot openstack_dashboard/locale/$lang/LC_MESSAGES/djangojs.po $lang
|
||||||
|
${command_wrapper} $root/tools/pseudo.py horizon/locale/django.pot horizon/locale/$lang/LC_MESSAGES/django.po $lang
|
||||||
|
${command_wrapper} $root/tools/pseudo.py horizon/locale/djangojs.pot horizon/locale/$lang/LC_MESSAGES/djangojs.po $lang
|
||||||
|
done
|
||||||
|
exit $?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ---------PREPARE THE ENVIRONMENT------------ #
|
||||||
|
|
||||||
|
# PROCESS ARGUMENTS, OVERRIDE DEFAULTS
|
||||||
|
for arg in "$@"; do
|
||||||
|
process_option $arg
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $quiet -eq 1 ] && [ $never_venv -eq 0 ] && [ $always_venv -eq 0 ]
|
||||||
|
then
|
||||||
|
always_venv=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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------------ #
|
||||||
|
|
||||||
|
# Run management commands
|
||||||
|
if [ $manage -eq 1 ]; then
|
||||||
|
run_management_command
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the docs
|
||||||
|
if [ $just_docs -eq 1 ]; then
|
||||||
|
run_sphinx
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update translation files
|
||||||
|
if [ $makemessages -eq 1 ]; then
|
||||||
|
run_makemessages
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Compile translation files
|
||||||
|
if [ $compilemessages -eq 1 ]; then
|
||||||
|
run_compilemessages
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate Pseudo translation
|
||||||
|
if [ $pseudo -eq 1 ]; then
|
||||||
|
run_pseudo
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# PEP8
|
||||||
|
if [ $just_pep8 -eq 1 ]; then
|
||||||
|
run_pep8
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $just_pep8_changed -eq 1 ]; then
|
||||||
|
run_pep8_changed
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pylint
|
||||||
|
if [ $just_pylint -eq 1 ]; then
|
||||||
|
run_pylint
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ESLint
|
||||||
|
if [ $just_eslint -eq 1 ]; then
|
||||||
|
run_eslint
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Karma
|
||||||
|
if [ $just_karma -eq 1 ]; then
|
||||||
|
run_karma
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tab checker
|
||||||
|
if [ $just_tabs -eq 1 ]; then
|
||||||
|
tab_check
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Integration tests
|
||||||
|
if [ $integration -eq 1 ]; then
|
||||||
|
run_integration_tests
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Django development server
|
||||||
|
if [ $runserver -eq 1 ]; then
|
||||||
|
run_server
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Full test suite
|
||||||
|
run_tests || exit
|
@ -1,22 +1,26 @@
|
|||||||
# The order of packages is significant, because pip processes them in the order
|
# The order of packages is significant, because pip processes them in the order
|
||||||
# of appearance. Changing the order has an impact on the overall integration
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
astroid<1.4.0 # breaks pylint 1.4.4
|
hacking>=0.11.0,<0.12 # Apache-2.0
|
||||||
hacking>=0.10.2,<0.11
|
|
||||||
coverage>=3.6
|
coverage>=3.6 # Apache-2.0
|
||||||
discover
|
mock>=2.0 # BSD
|
||||||
python-subunit>=0.0.18
|
mox>=0.5.3 # Apache-2.0
|
||||||
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
|
mox3>=0.7.0 # Apache-2.0
|
||||||
oslosphinx>=2.5.0 # Apache-2.0
|
oslo.config>=3.14.0 # Apache-2.0
|
||||||
oslotest>=1.10.0 # Apache-2.0
|
pylint==1.4.5 # GPLv2
|
||||||
testrepository>=0.0.18
|
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||||
testscenarios>=0.4
|
testtools>=1.4.0 # MIT
|
||||||
testtools>=1.4.0
|
unittest2 # BSD
|
||||||
pbr>=1.6
|
sphinx>=1.2.1,!=1.3b1,<1.3 # BSD
|
||||||
flake8>=2.2.4,<=2.4.1
|
oslosphinx>=2.5.0,!=3.4.0 # Apache-2.0
|
||||||
pytest
|
nose # LGPL
|
||||||
pytest-cov
|
nosehtmloutput>=0.0.3 # Apache-2.0
|
||||||
pytest-xdist
|
openstack.nose_plugin>=0.7 # Apache-2.0
|
||||||
pylint==1.4.4 # GNU GPL v2
|
django-nose>=1.4.4 # BSD
|
||||||
testresources>=0.2.4
|
nosexcover # BSD
|
||||||
mock>=1.2
|
|
||||||
|
# Horizon requirements
|
||||||
|
Django<1.9,>=1.8 # BSD
|
||||||
|
django-compressor>=2.0 # MIT
|
||||||
|
django_openstack_auth>=2.4.0 # Apache-2.0
|
@ -1,94 +0,0 @@
|
|||||||
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from horizon_web_ui.freezer_ui.api import api
|
|
||||||
from mock import patch
|
|
||||||
from openstack_auth import utils
|
|
||||||
import openstack_dashboard.test.helpers as helpers
|
|
||||||
|
|
||||||
|
|
||||||
@patch('freezer.apiclient.client')
|
|
||||||
class TestApi(helpers.TestCase):
|
|
||||||
CONFIG = {u'user_name': u'admin',
|
|
||||||
u'config_id': u'053a62e0-66a9-4a1c-ba58-6b7348d22166',
|
|
||||||
u'config_file': {u'start_datetime': u'1432736797',
|
|
||||||
u'repeat': u'1440',
|
|
||||||
u'max_priority': False,
|
|
||||||
u'encryption_password': u'secret',
|
|
||||||
u'src_file': u'fdsfsdds',
|
|
||||||
u'clients': [u'test-client'],
|
|
||||||
u'levels': 0,
|
|
||||||
u'proxy': u'',
|
|
||||||
u'container_name': u'dummy_container',
|
|
||||||
u'exclude': u'/tmp',
|
|
||||||
u'compression': u'gzip',
|
|
||||||
u'log_file': u'',
|
|
||||||
u'optimize': u'speed',
|
|
||||||
u'name': u'fdsfs'},
|
|
||||||
u'user_id': u'13c2b15308c04cdf86989ee7335eb504'}
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestApi, self).setUp()
|
|
||||||
|
|
||||||
# Usually this monkey patching happens in urls.py. This doesn't work
|
|
||||||
# here because we never invoke urls.py in this test. So we have to do
|
|
||||||
# it manually.
|
|
||||||
utils.patch_middleware_get_user()
|
|
||||||
|
|
||||||
def _setup_request(self):
|
|
||||||
super(TestApi, self)._setup_request()
|
|
||||||
# For some strange reason, Horizon sets the token to the token id
|
|
||||||
# rather than the token object. This fixes it.
|
|
||||||
self.request.session['token'] = self.token
|
|
||||||
|
|
||||||
def assert_client_got_created(self, client_mock):
|
|
||||||
client_mock.Client.assert_called_with(
|
|
||||||
token=self.request.session['token'].id,
|
|
||||||
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
|
||||||
endpoint=settings.FREEZER_API_URL)
|
|
||||||
|
|
||||||
def test_configuration_delete(self, client_mock):
|
|
||||||
api.configuration_delete(
|
|
||||||
self.request, u'053a62e0-66a9-4a1c-ba58-6b7348d22166')
|
|
||||||
|
|
||||||
self.assert_client_got_created(client_mock)
|
|
||||||
client_mock.Client().configs.delete.\
|
|
||||||
assert_called_once_with(u'053a62e0-66a9-4a1c-ba58-6b7348d22166')
|
|
||||||
|
|
||||||
def test_configuration_clone(self, client_mock):
|
|
||||||
client_mock.Client().configs.get.return_value = [self.CONFIG]
|
|
||||||
client_mock.Client().configs.\
|
|
||||||
create.return_value = u'28124cf0-6cd3-4b38-a0e9-b6f41568fa37'
|
|
||||||
|
|
||||||
result = api.configuration_clone(
|
|
||||||
self.request, u'053a62e0-66a9-4a1c-ba58-6b7348d22166')
|
|
||||||
|
|
||||||
self.assertEqual(result, u'28124cf0-6cd3-4b38-a0e9-b6f41568fa37')
|
|
||||||
self.assert_client_got_created(client_mock)
|
|
||||||
data = self.CONFIG[u'config_file']
|
|
||||||
data['name'] = 'fdsfs_clone'
|
|
||||||
client_mock.Client().configs.create.assert_called_once_with(data)
|
|
||||||
|
|
||||||
def test_configuration_get(self, client_mock):
|
|
||||||
client_mock.Client().configs.get.return_value = [self.CONFIG]
|
|
||||||
|
|
||||||
result = api.configuration_get(
|
|
||||||
self.request, u'053a62e0-66a9-4a1c-ba58-6b7348d22166')
|
|
||||||
|
|
||||||
self.assertEqual(1, len(result))
|
|
||||||
# Test if properties are accessible via object properties
|
|
||||||
self.assertEqual(u'admin', result[0].user_name)
|
|
||||||
# Test if nested properties are accessible via object properties
|
|
||||||
self.assertEqual(u'1432736797', result[0].start_datetime)
|
|
@ -1,44 +0,0 @@
|
|||||||
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
import json
|
|
||||||
from mock import patch
|
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
import openstack_dashboard.test.helpers as helpers
|
|
||||||
|
|
||||||
|
|
||||||
@patch('freezer.apiclient.client')
|
|
||||||
class TestRestApi(helpers.TestCase):
|
|
||||||
CLIENT_1 = {u'client': {u'hostname': u'jonas',
|
|
||||||
u'description': u'client description',
|
|
||||||
u'client_id': u'test-client',
|
|
||||||
u'config_ids': [u'fdaf2fwf2', u'fdsfdsfdsfs']},
|
|
||||||
u'user_id': u'13c2b15308c04cdf86989ee7335eb504'}
|
|
||||||
|
|
||||||
JSON_PREFIX = ')]}\',\n'
|
|
||||||
|
|
||||||
def test_clients_get(self, client_mock):
|
|
||||||
client_mock.Client().registration.list.return_value = [self.CLIENT_1]
|
|
||||||
url = reverse("horizon:freezer_ui:api_clients")
|
|
||||||
|
|
||||||
res = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
|
||||||
|
|
||||||
self.assertEqual(200, res.status_code)
|
|
||||||
self.assertEqual('application/json', res['content-type'])
|
|
||||||
self.assertEqual(self.JSON_PREFIX + json.dumps([self.CLIENT_1]),
|
|
||||||
res.content)
|
|
||||||
# there is no get ALL api at the moment, so we just fetch a big number
|
|
||||||
client_mock.Client().registration.list.assert_called_once_with(
|
|
||||||
limit=9999)
|
|
@ -1,20 +0,0 @@
|
|||||||
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
from horizon.test.settings import * # noqa
|
|
||||||
|
|
||||||
INSTALLED_APPS = ()
|
|
||||||
OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v2.0"
|
|
||||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"
|
|
||||||
FREEZER_API_URL = "test"
|
|
58
tools/install_venv.py
Normal file
58
tools/install_venv.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import install_venv_common as install_venv # noqa
|
||||||
|
|
||||||
|
|
||||||
|
def print_help(venv, root):
|
||||||
|
help = """
|
||||||
|
OpenStack development environment setup is complete.
|
||||||
|
OpenStack development uses virtualenv to track and manage Python
|
||||||
|
dependencies while in development and testing.
|
||||||
|
To activate the OpenStack virtualenv for the extent of your current shell
|
||||||
|
session you can run:
|
||||||
|
$ source %s/bin/activate
|
||||||
|
Or, if you prefer, you can run commands in the virtualenv on a case by case
|
||||||
|
basis by running:
|
||||||
|
$ %s/tools/with_venv.sh <your command>
|
||||||
|
Also, make test will automatically use the virtualenv.
|
||||||
|
"""
|
||||||
|
print(help % (venv, root))
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
|
||||||
|
if os.environ.get('tools_path'):
|
||||||
|
root = os.environ['tools_path']
|
||||||
|
venv = os.path.join(root, '.venv')
|
||||||
|
if os.environ.get('venv'):
|
||||||
|
venv = os.environ['venv']
|
||||||
|
|
||||||
|
pip_requires = os.path.join(root, 'requirements.txt')
|
||||||
|
test_requires = os.path.join(root, 'test-requirements.txt')
|
||||||
|
py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
|
||||||
|
project = 'OpenStack'
|
||||||
|
install = install_venv.InstallVenv(root, venv, pip_requires, test_requires,
|
||||||
|
py_version, project)
|
||||||
|
options = install.parse_args(argv)
|
||||||
|
install.check_python_version()
|
||||||
|
install.check_dependencies()
|
||||||
|
install.create_virtualenv(no_site_packages=options.no_site_packages)
|
||||||
|
install.install_dependencies()
|
||||||
|
print_help(venv, root)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.argv)
|
165
tools/install_venv_common.py
Normal file
165
tools/install_venv_common.py
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
"""Provides methods needed by installation script for OpenStack development
|
||||||
|
virtual environments.
|
||||||
|
Since this script is used to bootstrap a virtualenv from the system's Python
|
||||||
|
environment, it should be kept strictly compatible with Python 2.6.
|
||||||
|
Synced in from openstack-common
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import optparse
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class InstallVenv(object):
|
||||||
|
|
||||||
|
def __init__(self, root, venv, requirements,
|
||||||
|
test_requirements, py_version,
|
||||||
|
project):
|
||||||
|
self.root = root
|
||||||
|
self.venv = venv
|
||||||
|
self.requirements = requirements
|
||||||
|
self.test_requirements = test_requirements
|
||||||
|
self.py_version = py_version
|
||||||
|
self.project = project
|
||||||
|
|
||||||
|
def die(self, message, *args):
|
||||||
|
print(message % args, file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def check_python_version(self):
|
||||||
|
if sys.version_info < (2, 6):
|
||||||
|
self.die("Need Python Version >= 2.6")
|
||||||
|
|
||||||
|
def run_command_with_code(self, cmd, redirect_output=True,
|
||||||
|
check_exit_code=True):
|
||||||
|
"""Runs a command in an out-of-process shell.
|
||||||
|
Returns the output of that command. Working directory is self.root.
|
||||||
|
"""
|
||||||
|
if redirect_output:
|
||||||
|
stdout = subprocess.PIPE
|
||||||
|
else:
|
||||||
|
stdout = None
|
||||||
|
|
||||||
|
proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout)
|
||||||
|
output = proc.communicate()[0]
|
||||||
|
if check_exit_code and proc.returncode != 0:
|
||||||
|
self.die('Command "%s" failed.\n%s', ' '.join(cmd), output)
|
||||||
|
return (output, proc.returncode)
|
||||||
|
|
||||||
|
def run_command(self, cmd, redirect_output=True, check_exit_code=True):
|
||||||
|
return self.run_command_with_code(cmd, redirect_output,
|
||||||
|
check_exit_code)[0]
|
||||||
|
|
||||||
|
def get_distro(self):
|
||||||
|
if (os.path.exists('/etc/fedora-release') or
|
||||||
|
os.path.exists('/etc/redhat-release')):
|
||||||
|
return Fedora(
|
||||||
|
self.root, self.venv, self.requirements,
|
||||||
|
self.test_requirements, self.py_version, self.project)
|
||||||
|
else:
|
||||||
|
return Distro(
|
||||||
|
self.root, self.venv, self.requirements,
|
||||||
|
self.test_requirements, self.py_version, self.project)
|
||||||
|
|
||||||
|
def check_dependencies(self):
|
||||||
|
self.get_distro().install_virtualenv()
|
||||||
|
|
||||||
|
def create_virtualenv(self, no_site_packages=True):
|
||||||
|
"""Creates the virtual environment and installs PIP.
|
||||||
|
Creates the virtual environment and installs PIP only into the
|
||||||
|
virtual environment.
|
||||||
|
"""
|
||||||
|
if not os.path.isdir(self.venv):
|
||||||
|
print('Creating venv...', end=' ')
|
||||||
|
if no_site_packages:
|
||||||
|
self.run_command(['virtualenv', '-q', '--no-site-packages',
|
||||||
|
self.venv])
|
||||||
|
else:
|
||||||
|
self.run_command(['virtualenv', '-q', self.venv])
|
||||||
|
print('done.')
|
||||||
|
else:
|
||||||
|
print("venv already exists...")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def pip_install(self, *args):
|
||||||
|
self.run_command(['tools/with_venv.sh',
|
||||||
|
'pip', 'install', '--upgrade'] + list(args),
|
||||||
|
redirect_output=False)
|
||||||
|
|
||||||
|
def install_dependencies(self):
|
||||||
|
print('Installing dependencies with pip (this can take a while)...')
|
||||||
|
|
||||||
|
# First things first, make sure our venv has the latest pip and
|
||||||
|
# setuptools and pbr
|
||||||
|
self.pip_install('pip>=1.4')
|
||||||
|
self.pip_install('setuptools')
|
||||||
|
self.pip_install('pbr')
|
||||||
|
|
||||||
|
self.pip_install('-r', self.requirements, '-r', self.test_requirements)
|
||||||
|
|
||||||
|
def parse_args(self, argv):
|
||||||
|
"""Parses command-line arguments."""
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
parser.add_option('-n', '--no-site-packages',
|
||||||
|
action='store_true',
|
||||||
|
help="Do not inherit packages from global Python "
|
||||||
|
"install.")
|
||||||
|
return parser.parse_args(argv[1:])[0]
|
||||||
|
|
||||||
|
|
||||||
|
class Distro(InstallVenv):
|
||||||
|
|
||||||
|
def check_cmd(self, cmd):
|
||||||
|
return bool(self.run_command(['which', cmd],
|
||||||
|
check_exit_code=False).strip())
|
||||||
|
|
||||||
|
def install_virtualenv(self):
|
||||||
|
if self.check_cmd('virtualenv'):
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.check_cmd('easy_install'):
|
||||||
|
print('Installing virtualenv via easy_install...', end=' ')
|
||||||
|
if self.run_command(['easy_install', 'virtualenv']):
|
||||||
|
print('Succeeded')
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
print('Failed')
|
||||||
|
|
||||||
|
self.die('ERROR: virtualenv not found.\n\n%s development'
|
||||||
|
' requires virtualenv, please install it using your'
|
||||||
|
' favorite package management tool' % self.project)
|
||||||
|
|
||||||
|
|
||||||
|
class Fedora(Distro):
|
||||||
|
"""This covers all Fedora-based distributions.
|
||||||
|
Includes: Fedora, RHEL, CentOS, Scientific Linux
|
||||||
|
"""
|
||||||
|
|
||||||
|
def check_pkg(self, pkg):
|
||||||
|
return self.run_command_with_code(['rpm', '-q', pkg],
|
||||||
|
check_exit_code=False)[1] == 0
|
||||||
|
|
||||||
|
def install_virtualenv(self):
|
||||||
|
if self.check_cmd('virtualenv'):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.check_pkg('python-virtualenv'):
|
||||||
|
self.die("Please install 'python-virtualenv'.")
|
||||||
|
|
||||||
|
super(Fedora, self).install_virtualenv()
|
7
tools/with_venv.sh
Executable file
7
tools/with_venv.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
TOOLS_PATH=${TOOLS_PATH:-$(dirname $0)}
|
||||||
|
VENV_PATH=${VENV_PATH:-${TOOLS_PATH}}
|
||||||
|
VENV_DIR=${VENV_NAME:-/../.venv}
|
||||||
|
TOOLS=${TOOLS_PATH}
|
||||||
|
VENV=${VENV:-${VENV_PATH}/${VENV_DIR}}
|
||||||
|
source ${VENV}/bin/activate && "$@"
|
45
tox.ini
45
tox.ini
@ -1,35 +1,50 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py27,pep8,pylint
|
envlist = py27,py27dj18,pep8,py34,pylint
|
||||||
|
minversion = 1.6
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
|
setenv = VIRTUAL_ENV={envdir}
|
||||||
|
NOSE_WITH_OPENSTACK=1
|
||||||
|
NOSE_OPENSTACK_COLOR=1
|
||||||
|
NOSE_OPENSTACK_RED=0.05
|
||||||
|
NOSE_OPENSTACK_YELLOW=0.025
|
||||||
|
NOSE_OPENSTACK_SHOW_ELAPSED=1
|
||||||
install_command = pip install -U {opts} {packages}
|
install_command = pip install -U {opts} {packages}
|
||||||
setenv =
|
|
||||||
VIRTUAL_ENV={envdir}
|
|
||||||
deps = -r{toxinidir}/requirements.txt
|
deps = -r{toxinidir}/requirements.txt
|
||||||
-r{toxinidir}/test-requirements.txt
|
-r{toxinidir}/test-requirements.txt
|
||||||
commands = py.test -v --cov-report term-missing --cov disaster_recovery
|
http://tarballs.openstack.org/horizon/horizon-master.tar.gz
|
||||||
|
commands = python manage.py test {posargs}
|
||||||
|
|
||||||
[testenv:pep8]
|
[testenv:pep8]
|
||||||
commands = flake8
|
commands = flake8 {posargs}
|
||||||
|
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
|
|
||||||
[testenv:cover]
|
[testenv:cover]
|
||||||
commands = python setup.py testr --coverage --testr-args='{posargs}'
|
commands = python setup.py test --coverage --testr-args='{posargs}'
|
||||||
|
|
||||||
[flake8]
|
[testenv:py27dj18]
|
||||||
show-source = True
|
basepython = python2.7
|
||||||
ignore = E123,E125,H405,H238,H306,H701
|
commands =
|
||||||
builtins = _
|
python manage.py test {posargs}
|
||||||
exclude=.venv,.tox,dist,doc,test,*egg,tests,runtests.py
|
|
||||||
|
|
||||||
|
[testenv:py34dj18]
|
||||||
|
basepython = python3.4
|
||||||
|
commands =
|
||||||
|
python manage.py test {posargs}
|
||||||
|
|
||||||
|
[testenv:docs]
|
||||||
|
setenv = DJANGO_SETTINGS_MODULE=disaster_recovery.test.settings
|
||||||
|
commands = python setup.py build_sphinx
|
||||||
|
|
||||||
[testenv:pylint]
|
[testenv:pylint]
|
||||||
commands = pylint --rcfile .pylintrc disaster_recovery
|
commands = pylint --rcfile .pylintrc disaster_recovery
|
||||||
|
|
||||||
[testenv:docs]
|
[flake8]
|
||||||
commands =
|
exclude = .venv,.git,.tox,dist,*openstack/common*,*lib/python*,*egg,build,panel_template,dash_template,local_settings.py,*/local/*,*/test/test_plugins/*,.ropeproject,tools,doc
|
||||||
python setup.py build_sphinx
|
max-complexity = 20
|
||||||
|
ignore = H405,H404,H403,H401,H238,H306,H701
|
Loading…
x
Reference in New Issue
Block a user