From 01d6e5363018b151e680562e9f75ce5a768d255d Mon Sep 17 00:00:00 2001 From: Chad Roberts Date: Thu, 29 Oct 2015 21:47:36 -0400 Subject: [PATCH] Removing all code from previous dashboard incarnation Clearing out all of the old code from the Sahara dashboard repo in preparation for bringing the new code back into the repo for the Mitaka release. Change-Id: I83cb932c35987ea80ac9233bd355355398b9164b --- .mailmap | 4 - .testr.conf | 7 - MANIFEST.in | 11 - README.rst | 10 +- manage.py | 23 + openstack-common.conf | 4 - requirements.txt | 9 + run_tests.sh | 548 ++++++++++ .../__init__.py | 0 .../enabled}/__init__.py | 0 .../test}/__init__.py | 0 sahara-dashboard/test/settings.py | 185 ++++ saharadashboard/tests/README.rst | 54 - saharadashboard/tests/base.py | 970 ------------------ .../cluster_template_tests/negative_tests.py | 48 - .../test_create_cluster_template.py | 77 -- .../tests/cluster_tests/__init__.py | 0 .../tests/cluster_tests/test_clusters.py | 158 --- saharadashboard/tests/configs/__init__.py | 0 .../tests/configs/config.conf.sample | 33 - saharadashboard/tests/configs/config.py | 169 --- .../tests/image_registry_tests/__init__.py | 0 .../test_for_image_registry.py | 42 - .../node_group_template_tests/__init__.py | 0 .../negative_tests.py | 50 - .../test_create_node_group_template.py | 61 -- saharadashboard/tests/resources/README.rst | 82 -- saharadashboard/tests/resources/edp-job.jar | Bin 15641 -> 0 bytes saharadashboard/tests/resources/edp-job.pig | 3 - saharadashboard/tests/resources/edp-lib.jar | Bin 3745 -> 0 bytes saharadashboard/utils/__init__.py | 0 saharadashboard/utils/hacking/__init__.py | 0 saharadashboard/utils/hacking/checks.py | 49 - saharadashboard/version.py | 18 - setup.cfg | 52 +- test-requirements.txt | 16 +- tox.ini | 54 +- 37 files changed, 846 insertions(+), 1891 deletions(-) delete mode 100644 .mailmap delete mode 100644 .testr.conf delete mode 100644 MANIFEST.in create mode 100755 manage.py delete mode 100644 openstack-common.conf create mode 100644 run_tests.sh rename {saharadashboard => sahara-dashboard}/__init__.py (100%) rename {saharadashboard/tests => sahara-dashboard/enabled}/__init__.py (100%) rename {saharadashboard/tests/cluster_template_tests => sahara-dashboard/test}/__init__.py (100%) create mode 100644 sahara-dashboard/test/settings.py delete mode 100644 saharadashboard/tests/README.rst delete mode 100644 saharadashboard/tests/base.py delete mode 100644 saharadashboard/tests/cluster_template_tests/negative_tests.py delete mode 100644 saharadashboard/tests/cluster_template_tests/test_create_cluster_template.py delete mode 100644 saharadashboard/tests/cluster_tests/__init__.py delete mode 100644 saharadashboard/tests/cluster_tests/test_clusters.py delete mode 100644 saharadashboard/tests/configs/__init__.py delete mode 100644 saharadashboard/tests/configs/config.conf.sample delete mode 100644 saharadashboard/tests/configs/config.py delete mode 100644 saharadashboard/tests/image_registry_tests/__init__.py delete mode 100644 saharadashboard/tests/image_registry_tests/test_for_image_registry.py delete mode 100644 saharadashboard/tests/node_group_template_tests/__init__.py delete mode 100644 saharadashboard/tests/node_group_template_tests/negative_tests.py delete mode 100644 saharadashboard/tests/node_group_template_tests/test_create_node_group_template.py delete mode 100644 saharadashboard/tests/resources/README.rst delete mode 100644 saharadashboard/tests/resources/edp-job.jar delete mode 100644 saharadashboard/tests/resources/edp-job.pig delete mode 100644 saharadashboard/tests/resources/edp-lib.jar delete mode 100644 saharadashboard/utils/__init__.py delete mode 100644 saharadashboard/utils/hacking/__init__.py delete mode 100644 saharadashboard/utils/hacking/checks.py delete mode 100644 saharadashboard/version.py diff --git a/.mailmap b/.mailmap deleted file mode 100644 index 5000261a..00000000 --- a/.mailmap +++ /dev/null @@ -1,4 +0,0 @@ -# Format is: -# -# -Timur Nurlygayanov diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index eda6a422..00000000 --- a/.testr.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover saharadashboard/tests $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index a60d5f1a..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,11 +0,0 @@ -include AUTHORS -include README.rst -include ChangeLog -include LICENSE - -include saharadashboard/templates/**.html - -exclude .gitignore -exclude .gitreview - -global-exclude *.pyc diff --git a/README.rst b/README.rst index ff321470..cf741184 100644 --- a/README.rst +++ b/README.rst @@ -4,14 +4,8 @@ OpenStack Dashboard plugin for Sahara project NOTE: ===== -Sahara Dashboard is now integrated into the Horizon project. http://github.com/openstack/horizon -The panels can now be found in the data_processing module of Projects Dashboard. -https://github.com/openstack/horizon/tree/master/openstack_dashboard/dashboards/project/data_processing - -This repository will now contain only selenium based tests for the Data Processing Panels. - -This change is not meant to be backported to stable/icehouse or any other tags or branches. -So you can still use Sahara Dasboard as a separate dashboard with stable/icehouse version of Horizon. +As of the Mitaka release, the dashboard for sahara is now maintained +outside of the horzon codebase, in the repository. Links: ------ diff --git a/manage.py b/manage.py new file mode 100755 index 00000000..c89c3ba5 --- /dev/null +++ b/manage.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +# 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 + +from django.core.management import execute_from_command_line + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", + "sahara-dashboard.test.settings") + execute_from_command_line(sys.argv) diff --git a/openstack-common.conf b/openstack-common.conf deleted file mode 100644 index 610937a4..00000000 --- a/openstack-common.conf +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] -modules=importutils -base=saharadashboard - diff --git a/requirements.txt b/requirements.txt index 30806d5a..25f60423 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,12 @@ # process, which may cause wedges in the gate later. pbr>=1.6 +# Horizon Core Requirements +Babel>=1.3 +Django<1.9,>=1.8 +django-compressor>=1.4 +django-openstack-auth>=2.0.0 +iso8601>=0.1.9 +python-keystoneclient!=1.8.0,>=1.6.0 +python-manilaclient>=1.3.0 +python-saharaclient>=0.10.0 diff --git a/run_tests.sh b/run_tests.sh new file mode 100644 index 00000000..1f6d0c17 --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,548 @@ +#!/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 []" + echo " Just run PEP8 and HACKING compliance check" + echo " on files changed since HEAD~1 (or )" + 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 " -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="sahara-dashboard" + +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 +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;; + -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 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=sahara-dashboard.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=sahara-dashboard.test.settings ${command_wrapper} flake8 --diff + exit +} + +function run_sphinx { + echo "Building sphinx..." + DJANGO_SETTINGS_MODULE=sahara-dashboard.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 [ $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 Sahara-Dashboard application tests" + export NOSE_XUNIT_FILE=sahara-dashboard/nosetests.xml + if [ "$NOSE_WITH_HTML_OUTPUT" = '1' ]; then + export NOSE_HTML_OUT_FILE='sahara_dashboard_nose_results.html' + fi + if [ $with_coverage -eq 1 ]; then + ${command_wrapper} python -m coverage.__main__ erase + coverage_run="python -m coverage.__main__ run -p" + fi + ${command_wrapper} ${coverage_run} $root/manage.py test sahara-dashboard --settings=sahara-dashboard.test.settings $testopts + # get results of the Horizon tests + SAHARA_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 --omit='/usr*,setup.py,*egg*,.venv/*' + ${command_wrapper} python -m coverage.__main__ html -i --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=$(($SAHARA_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 run_makemessages { + OPTS="-l en --no-obsolete --settings=openstack_dashboard.test.settings" + DASHBOARD_OPTS="--extension=html,txt,csv --ignore=openstack" + echo -n "horizon: " + cd horizon + ${command_wrapper} $root/manage.py makemessages $OPTS + HORIZON_PY_RESULT=$? + echo -n "horizon javascript: " + ${command_wrapper} $root/manage.py makemessages -d djangojs $OPTS + HORIZON_JS_RESULT=$? + echo -n "openstack_dashboard: " + cd ../openstack_dashboard + ${command_wrapper} $root/manage.py makemessages $DASHBOARD_OPTS $OPTS + DASHBOARD_RESULT=$? + cd .. + if [ $check_only -eq 1 ]; then + git checkout -- horizon/locale/en/LC_MESSAGES/django*.po + git checkout -- openstack_dashboard/locale/en/LC_MESSAGES/django.po + fi + exit $(($HORIZON_PY_RESULT || $HORIZON_JS_RESULT || $DASHBOARD_RESULT)) +} + +function run_compilemessages { + OPTS="--settings=openstack_dashboard.test.settings" + cd horizon + ${command_wrapper} $root/manage.py compilemessages $OPTS + HORIZON_PY_RESULT=$? + cd ../openstack_dashboard + ${command_wrapper} $root/manage.py compilemessages $OPTS + DASHBOARD_RESULT=$? + cd .. + # English is the source language, so compiled catalogs are unnecessary. + rm -vf horizon/locale/en/LC_MESSAGES/django*.mo + rm -vf openstack_dashboard/locale/en/LC_MESSAGES/django.mo + exit $(($HORIZON_PY_RESULT || $DASHBOARD_RESULT)) +} + +function run_pseudo { + for lang in $testargs + # Use English po file as the source file/pot file just like real Horizon translations + do + ${command_wrapper} $root/tools/pseudo.py openstack_dashboard/locale/en/LC_MESSAGES/django.po openstack_dashboard/locale/$lang/LC_MESSAGES/django.po $lang + ${command_wrapper} $root/tools/pseudo.py horizon/locale/en/LC_MESSAGES/django.po horizon/locale/$lang/LC_MESSAGES/django.po $lang + ${command_wrapper} $root/tools/pseudo.py horizon/locale/en/LC_MESSAGES/djangojs.po 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 + +# 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 \ No newline at end of file diff --git a/saharadashboard/__init__.py b/sahara-dashboard/__init__.py similarity index 100% rename from saharadashboard/__init__.py rename to sahara-dashboard/__init__.py diff --git a/saharadashboard/tests/__init__.py b/sahara-dashboard/enabled/__init__.py similarity index 100% rename from saharadashboard/tests/__init__.py rename to sahara-dashboard/enabled/__init__.py diff --git a/saharadashboard/tests/cluster_template_tests/__init__.py b/sahara-dashboard/test/__init__.py similarity index 100% rename from saharadashboard/tests/cluster_template_tests/__init__.py rename to sahara-dashboard/test/__init__.py diff --git a/sahara-dashboard/test/settings.py b/sahara-dashboard/test/settings.py new file mode 100644 index 00000000..28dc23da --- /dev/null +++ b/sahara-dashboard/test/settings.py @@ -0,0 +1,185 @@ +# +# 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 importlib +import os +import six + +from horizon.test.settings import * # noqa +from horizon.utils import secret_key +from openstack_dashboard import exceptions + + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +TEST_DIR = os.path.dirname(os.path.abspath(__file__)) +ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, "..")) + +MEDIA_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '..', 'media')) +MEDIA_URL = '/media/' +STATIC_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '..', 'static')) +STATIC_URL = '/static/' + +SECRET_KEY = secret_key.generate_or_read_from_file( + os.path.join(TEST_DIR, '.secret_key_store')) +ROOT_URLCONF = 'sahara-dashboard.test.urls' +TEMPLATE_DIRS = ( + os.path.join(TEST_DIR, 'templates'), +) + +TEMPLATE_CONTEXT_PROCESSORS += ( + 'openstack_dashboard.context_processors.openstack', +) + +INSTALLED_APPS = ( + 'django.contrib.contenttypes', + 'django.contrib.auth', + 'django.contrib.sessions', + 'django.contrib.staticfiles', + 'django.contrib.messages', + 'django.contrib.humanize', + 'django_nose', + 'openstack_auth', + 'compressor', + 'horizon', + 'openstack_dashboard', + 'openstack_dashboard.dashboards', +) + +AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',) + +SITE_BRANDING = 'OpenStack' + +HORIZON_CONFIG = { + "password_validator": { + "regex": '^.{8,18}$', + "help_text": "Password must be between 8 and 18 characters." + }, + 'user_home': None, + 'help_url': "http://docs.openstack.org", + 'exceptions': {'recoverable': exceptions.RECOVERABLE, + 'not_found': exceptions.NOT_FOUND, + 'unauthorized': exceptions.UNAUTHORIZED}, + 'angular_modules': [], + 'js_files': [], +} + +# Load the pluggable dashboard settings +from openstack_dashboard.utils import settings +dashboard_module_names = [ + 'openstack_dashboard.enabled', + 'openstack_dashboard.local.enabled', + 'sahara-dashboard.enabled', +] +dashboard_modules = [] +# All dashboards must be enabled for the namespace to get registered, which is +# needed by the unit tests. +for module_name in dashboard_module_names: + module = importlib.import_module(module_name) + dashboard_modules.append(module) + for submodule in six.itervalues(settings.import_submodules(module)): + if getattr(submodule, 'DISABLED', None): + delattr(submodule, 'DISABLED') +INSTALLED_APPS = list(INSTALLED_APPS) # Make sure it's mutable +settings.update_dashboards(dashboard_modules, HORIZON_CONFIG, INSTALLED_APPS) + +# Set to True to allow users to upload images to glance via Horizon server. +# When enabled, a file form field will appear on the create image form. +# See documentation for deployment considerations. +HORIZON_IMAGES_ALLOW_UPLOAD = True + +AVAILABLE_REGIONS = [ + ('http://localhost:5000/v2.0', 'local'), + ('http://remote:5000/v2.0', 'remote'), +] + +OPENSTACK_API_VERSIONS = { + "identity": 3 +} + +OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v2.0" +OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_" + +OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True +OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'test_domain' + +OPENSTACK_KEYSTONE_BACKEND = { + 'name': 'native', + 'can_edit_user': True, + 'can_edit_group': True, + 'can_edit_project': True, + 'can_edit_domain': True, + 'can_edit_role': True +} + +OPENSTACK_CINDER_FEATURES = { + 'enable_backup': True, +} + +OPENSTACK_NEUTRON_NETWORK = { + 'enable_lb': True +} + +OPENSTACK_HYPERVISOR_FEATURES = { + 'can_set_mount_point': True, + + # NOTE: as of Grizzly this is not yet supported in Nova so enabling this + # setting will not do anything useful + 'can_encrypt_volumes': False +} + +LOGGING['loggers']['openstack_dashboard'] = { + 'handlers': ['test'], + 'propagate': False, +} + +LOGGING['loggers']['selenium'] = { + 'handlers': ['test'], + 'propagate': False, +} + +LOGGING['loggers']['sahara-dashboard'] = { + 'handlers': ['test'], + 'propagate': False, +} + +SECURITY_GROUP_RULES = { + 'all_tcp': { + 'name': 'ALL TCP', + 'ip_protocol': 'tcp', + 'from_port': '1', + 'to_port': '65535', + }, + 'http': { + 'name': 'HTTP', + 'ip_protocol': 'tcp', + 'from_port': '80', + 'to_port': '80', + }, +} + +NOSE_ARGS = ['--nocapture', + '--nologcapture', + '--cover-package=openstack_dashboard', + '--cover-inclusive', + '--all-modules'] + +POLICY_FILES_PATH = os.path.join(ROOT_PATH, "conf") +POLICY_FILES = { + 'identity': 'keystone_policy.json', + 'compute': 'nova_policy.json' +} + +# The openstack_auth.user.Token object isn't JSON-serializable ATM +SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' diff --git a/saharadashboard/tests/README.rst b/saharadashboard/tests/README.rst deleted file mode 100644 index 86af2e1b..00000000 --- a/saharadashboard/tests/README.rst +++ /dev/null @@ -1,54 +0,0 @@ -Sahara Dashboard Selenium Tests -===================================== - - -Main goal of Selenium Tests ----------- - -Selenium tests for Sahara Dashboard are designed to check the correctness of the Sahara Dashboard Horizon plug-in. - - -How to run UI tests: ----------- - -It's assumed that sahara and horizon are already installed and running. - -Information about installation and start of sahara and horizon can be found on the sahara site - http://docs.openstack.org/developer/sahara/#user-guide - in tabs Sahara Installation Guide and Sahara UI Installation Guide. - -1. Go to sahara dashboard path. -2. Create config file for selenium tests - `saharadashboard/tests/configs/config.py`. - You can take a look at the sample config file - `saharadashboard/tests/configs/config.py.sample`. - All values used in `saharadashboard/tests/configs/parameters.py` file are - defaults, so, if they are applicable for your environment then you can skip - config file creation. - -3. Install virtual framebuffer X server for X Version 11 (Xvfb): - sudo apt-get -y install xvfb - -4. Install Firefox: - sudo add-apt-repository ppa:ubuntu-mozilla-security/ppa - sudo apt-get update - sudo apt-get install firefox libstdc++5 - -5. To run ui tests you should use the corresponding tox env: `tox -e uitests`. - If need to run only one test module, use: - - tox -e uitests -- '' - - may be equal 'cluster', 'cluster_template', 'image_registry', 'node_group_template', 'image_registry', 'vanilla', 'hdp' - It's full list of actual modules. - - -Coverage: ----------- - --Clusters --Cluster templates --Node group templates --Image registry --Data sources --Job binaries --Jobs --Job executions diff --git a/saharadashboard/tests/base.py b/saharadashboard/tests/base.py deleted file mode 100644 index 692fe0ca..00000000 --- a/saharadashboard/tests/base.py +++ /dev/null @@ -1,970 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 logging -import os -import time -import traceback - -import selenium.common.exceptions as selenim_except -from selenium import webdriver -import selenium.webdriver.common.by as by -from swiftclient import client as swift_client -import unittest2 - -import saharadashboard.tests.configs.config as cfg - - -logger = logging.getLogger('swiftclient') -logger.setLevel(logging.WARNING) - - -class UITestCase(unittest2.TestCase): - - @classmethod - def setUpClass(cls): - try: - cls.ifFail = False - cls.driver = webdriver.Firefox() - cls.driver.get(cfg.common.base_url + "/") - cls.find_clear_send(by.By.ID, "id_username", cfg.common.user) - cls.find_clear_send(by.By.ID, "id_password", cfg.common.password) - cls.driver.find_element_by_xpath( - "//button[@type='submit']").click() - except Exception: - traceback.print_exc() - cls.ifFail = True - pass - - def setUp(self): - if self.ifFail: - self.fail("setUpClass method is fail") - self.await_element(by.By.CLASS_NAME, 'clearfix', - 'authorization failed') - - def image_registry(self, image_name, user_name=None, description=None, - tags_to_add=None, tags_to_remove=None, positive=True, - close_window=True, message=''): - if positive: - message = 'Success: Successfully updated image.' - self.image_registry_helper(image_name, user_name, description, - tags_to_add, tags_to_remove, positive, - close_window, message, 'Registry') - - def edit_tags_by_image_name(self, image_name, user_name=None, - description=None, tags_to_add=None, - positive=True, message=None, close_window=True, - tags_to_remove=None): - if positive: - message = 'Success: Successfully updated image.' - self.image_registry_helper(image_name, user_name, description, - tags_to_add, tags_to_remove, positive, - close_window, message, 'Edit') - - def create_node_group_template( - self, name, list_processes, plugin, flavor=None, params=None, - storage={'type': 'Ephemeral Drive'}, description=None, - positive=True, message=None, close_window=True): - driver = self.driver - if not flavor: - flavor = cfg.common.flavor - driver.get(cfg.common.base_url + - "/project/data_processing/nodegroup_templates/") - self.await_element(by.By.ID, "nodegroup_templates__action_create") - driver.find_element_by_id("nodegroup_templates__action_create").click() - self.choose_plugin_name(plugin.plugin_name, plugin.hadoop_version, - name, description, "id_nodegroup_name") - self.driver.find_element_by_xpath( - "//select[@id='id_flavor']/option[text()='%s']" % flavor).click() - self.driver.find_element_by_xpath( - "//*[@id='id_storage']/option[text()='%s']" - % storage['type']).click() - if storage['type'] == "Cinder Volume": - self.find_clear_send(by.By.ID, "id_volumes_per_node", - storage['volume_per_node']) - self.find_clear_send(by.By.ID, "id_volumes_size", - storage['volume_size']) - if cfg.common.floating_ip_pool: - self.driver.find_element_by_xpath( - "//*[@id='id_floating_ip_pool']/option[text()='%s']" - % cfg.common.floating_ip_pool).click() - if cfg.common.auto_security_groups != driver.find_element_by_id( - "id_autogroup").is_selected(): - driver.find_element_by_id("id_autogroup").click() - if cfg.common.security_groups: - # create dictionary with existing security groups - actual_groups = {} - for sec_group in driver.find_elements_by_xpath( - "//label[contains(@for, 'id_groups_')]"): - actual_groups[sec_group.text] = sec_group - # search specified in config file security groups of existing - for sec_group in cfg.common.security_groups: - if sec_group not in actual_groups: - self.fail("Security group with name %s not " - "found. Aborting." % sec_group) - if not actual_groups[sec_group].is_selected(): - actual_groups[sec_group].click() - processes = [] - for process in list_processes: - number_pr = self.search_id_processes(process, plugin) - driver.find_element_by_id( - "id_processes_%s" % str(number_pr)).click() - processes.append(driver.find_element_by_id( - "id_processes_%s" % str(number_pr)). - find_element_by_xpath('..').text) - if params: - self.config_helper(params) - self.click_visible_key("//input[@value='Create']") - if not message: - message = "Success: Created Node Group Template %s" % name - if close_window: - self.check_create_object( - name, positive, message, - [{2: [name]}, - {3: [plugin.plugin_overview_name]}, - {4: [plugin.hadoop_version]}, {5: processes}]) - else: - self.error_helper(message) - - def create_cluster_template( - self, name, node_groups, plugin, description=None, - close_window=True, anti_affinity_groups=None, positive=True, - message=None, params=None): - driver = self.driver - driver.get(cfg.common.base_url + - "/project/data_processing/cluster_templates/") - self.await_element(by.By.ID, "cluster_templates__action_create") - driver.find_element_by_id("cluster_templates__action_create").click() - self.choose_plugin_name(plugin.plugin_name, plugin.hadoop_version, - name, description, "id_cluster_template_name") - if anti_affinity_groups: - for group in anti_affinity_groups: - driver.find_element_by_id( - "id_anti_affinity_%s" % self.search_id_processes( - group, plugin)).click() - driver.find_element_by_link_text("Node Groups").click() - number_to_add = 0 - node_groups_list = [] - for node_group, count in node_groups.items(): - driver.find_element_by_xpath( - "//select[@id='template_id']/option[text()='%s']" - % node_group).click() - driver.find_element_by_id("add_group_button").click() - self.find_clear_send(by.By.ID, "count_%d" % number_to_add, count) - node_groups_list.append("%s: %d" % (node_group, count)) - number_to_add += 1 - if params: - self.config_helper(params) - self.click_visible_key("//input[@value='Create']") - if not message: - message = "Success: Created Cluster Template %s" % name - if close_window: - self.check_create_object( - name, positive, message, - [{2: [name]}, - {3: [plugin.plugin_overview_name]}, - {4: [plugin.hadoop_version]}, {5: node_groups_list}, - {6: [description if description else '']}]) - else: - self.error_helper(message) - - def create_cluster(self, name, cluster_template, plugin, keypair=None, - close_window=True, description=None, positive=True, - await_run=True, message=None): - driver = self.driver - driver.get(cfg.common.base_url + "/project/data_processing/clusters/") - self.await_element(by.By.ID, "clusters__action_create") - driver.find_element_by_id("clusters__action_create").click() - self.choose_plugin_name(plugin.plugin_name, plugin.hadoop_version, - name, description, "id_cluster_name") - driver.find_element_by_xpath("//select[@id='id_cluster_template']/" - "option[text()='%s']" % - cluster_template).click() - driver.find_element_by_xpath("//select[@id='id_image']/option" - "[text()='%s']" % - plugin.base_image).click() - if not keypair: - keypair = cfg.common.keypair - driver.find_element_by_xpath("//select[@id='id_keypair']" - "/option[text()='%s']" % keypair).click() - if cfg.common.neutron_management_network: - driver.find_element_by_xpath( - "//select[@id='id_neutron_management_network']/option[text()=" - "'%s']" % cfg.common.neutron_management_network).click() - self.click_visible_key("//input[@value='Create']") - if not message: - message = 'Success: Created Cluster %s' % name - if close_window: - self.check_create_object(name, positive, message) - else: - self.error_helper(message) - if await_run: - self.await_cluster_active(name) - - def create_data_source(self, name, url, close_window=True, - description=None, positive=True, message=None): - - driver = self.driver - driver.get(cfg.common.base_url + - "/project/data_processing/data_sources/") - self.await_element(by.By.ID, "data_sources__action_create data source") - driver.find_element_by_id( - "data_sources__action_create data source").click() - - self.await_element(by.By.ID, "id_data_source_name") - - self.find_clear_send(by.By.ID, "id_data_source_name", name) - self.find_clear_send(by.By.ID, "id_data_source_url", url) - self.find_clear_send(by.By.ID, "id_data_source_credential_user", - cfg.common.user) - self.find_clear_send(by.By.ID, "id_data_source_credential_pass", - cfg.common.password) - if description: - self.find_clear_send(by.By.ID, "id_data_source_description", - description) - - driver.find_element_by_xpath("//input[@value='Create']").click() - - if not message: - message = 'Success: Data source created' - if close_window: - self.check_create_object(name, positive, message) - else: - self.error_helper(message) - - def create_job_binary(self, name, parameters_of_storage, description=None, - positive=True, message=None, close_window=True): - - driver = self.driver - storage_type = parameters_of_storage['storage_type'] - driver.get(cfg.common.base_url + - "/project/data_processing/job_binaries/") - self.await_element(by.By.ID, "job_binaries__action_create job binary") - driver.find_element_by_id( - "job_binaries__action_create job binary").click() - - self.await_element(by.By.ID, "id_job_binary_name") - - self.find_clear_send(by.By.ID, "id_job_binary_name", name) - driver.find_element_by_xpath("//select[@id='id_job_binary_type']/optio" - "n[text()='%s']" % storage_type).click() - - if storage_type == 'Swift': - self.find_clear_send(by.By.ID, "id_job_binary_url", - parameters_of_storage['url']) - self.find_clear_send(by.By.ID, "id_job_binary_username", - cfg.common.user) - self.find_clear_send(by.By.ID, "id_job_binary_password", - cfg.common.password) - - elif storage_type == 'Internal database': - internal_binary = parameters_of_storage['Internal binary'] - driver.find_element_by_xpath( - "//select[@id='id_job_binary_internal']/option[text()" - "='%s']" % internal_binary).click() - if internal_binary == '*Upload a new file': - file = '%s/saharadashboard/tests/resources/%s' % ( - os.getcwd(), parameters_of_storage['filename']) - driver.find_element_by_id('id_job_binary_file').send_keys(file) - - elif internal_binary == '*Create a script': - self.find_clear_send(by.By.ID, "id_job_binary_script_name", - parameters_of_storage['script_name']) - self.find_clear_send(by.By.ID, "id_job_binary_script", - parameters_of_storage['script_text']) - - if description: - self.find_clear_send(by.By.ID, "id_job_binary_description", - description) - - driver.find_element_by_xpath("//input[@value='Create']").click() - - if not message: - message = 'Success: Successfully created job binary' - if close_window: - self.check_create_object(name, positive, message) - else: - self.error_helper(message) - - def create_job(self, name, job_type, main=None, libs=None, - close_window=True, description=None, positive=True, - message=None): - - driver = self.driver - driver.get(cfg.common.base_url + "/project/data_processing/jobs/") - self.await_element(by.By.ID, "jobs__action_create job") - driver.find_element_by_id("jobs__action_create job").click() - - self.await_element(by.By.ID, "id_job_name") - self.find_clear_send(by.By.ID, "id_job_name", name) - driver.find_element_by_xpath( - "//select[@id='id_job_type']/option[text()='%s']" - % job_type).click() - if main: - driver.find_element_by_xpath( - "//select[@id='id_main_binary']/option[text()='%s']" - % main).click() - if description: - self.find_clear_send(by.By.ID, "id_job_description", description) - if libs: - driver.find_element_by_link_text('Libs').click() - self.await_element(by.By.ID, "id_lib_binaries") - for lib in libs: - driver.find_element_by_xpath( - "//select[@id='id_lib_binaries']/option[text()='%s']" - % lib).click() - driver.find_element_by_id('add_lib_button').click() - - driver.find_element_by_xpath("//input[@value='Create']").click() - - if not message: - message = 'Success: Job created' - if close_window: - self.check_create_object(name, positive, message) - else: - self.error_helper(message) - - def launch_job_on_existing_cluster(self, name, input, output, cluster, - configure=None, positive=True, - message=None, close_window=True, - await_launch=True): - - driver = self.driver - driver.get(cfg.common.base_url + "/project/data_processing/jobs/") - self.await_element(by.By.ID, "jobs__action_create job") - - action_column = driver.find_element_by_link_text( - name).find_element_by_xpath('../../td[4]') - action_column.find_element_by_class_name('dropdown-toggle').click() - action_column.find_element_by_link_text( - 'Launch On Existing Cluster').click() - - self.await_element(by.By.ID, "id_job_input") - driver.find_element_by_xpath( - "//select[@id='id_job_input']/option[text()='%s']" % input).click() - driver.find_element_by_xpath( - "//select[@id='id_job_output']/option[text()='%s']" % - output).click() - driver.find_element_by_xpath( - "//select[@id='id_cluster']/option[text()='%s']" % cluster).click() - - if configure: - driver.find_element_by_link_text('Configure').click() - for config_part, values in configure.items(): - config_number = 1 - for config, value in values.items(): - driver.find_element_by_id( - config_part).find_element_by_link_text('Add').click() - driver.find_element_by_xpath( - '//*[@id="%s"]/table/tbody/tr[%i]/td[1]/input' % ( - config_part, config_number)).send_keys(config) - driver.find_element_by_xpath( - '//*[@id="%s"]/table/tbody/tr[%i]/td[2]/input' % ( - config_part, config_number)).send_keys(value) - config_number += 1 - - driver.find_element_by_xpath("//input[@value='Launch']").click() - - if not message: - message = 'Success: Job launched' - if close_window: - self.check_create_object(name, positive, message, - check_create_element=False) - if await_launch: - self.await_launch_job(name) - - else: - self.error_helper(message) - - def delete_node_group_templates(self, names, undelete_names=None, - finally_delete=False): - url = "/project/data_processing/nodegroup_templates/" - delete_button_id = 'nodegroup_templates__action_' \ - 'delete_nodegroup_template' - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete) - - def delete_cluster_templates(self, names, undelete_names=None, - finally_delete=False): - url = "/project/data_processing/cluster_templates/" - delete_button_id = "cluster_templates__action_delete_cluster_template" - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete) - - def delete_clusters(self, names, undelete_names=None, - finally_delete=False, await_delete=False): - url = "/project/data_processing/clusters/" - delete_button_id = "clusters__action_delete" - msg = "Success: Deleted Cluster" - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete, succes_msg=msg, - await_delete=await_delete) - - def delete_data_sources(self, names, undelete_names=None, - finally_delete=False): - url = "/project/data_processing/data_sources/" - delete_button_id = "data_sources__action_delete" - msg = "Success: Deleted Data source" - err_msg = 'Error: Unable to delete data source' - info_msg = 'Info: Deleted Data source' - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete, msg, err_msg, info_msg) - - def delete_job_binaries(self, names, undelete_names=None, - finally_delete=False): - - url = "/project/data_processing/job_binaries/" - delete_button_id = "job_binaries__action_delete" - - msg = "Success: Deleted Job binary" - err_msg = 'Error: Unable to delete job binary' - info_msg = 'Info: Deleted Job binary' - - if not undelete_names and len(names) > 1: - msg = "Success: Deleted Job binarie" - - if undelete_names and len(names) - len(undelete_names) > 1: - info_msg = 'Info: Deleted Job binarie' - - if undelete_names and len(undelete_names) > 1: - err_msg = 'Error: Unable to delete job binarie' - - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete, msg, err_msg, info_msg) - - def delete_jobs(self, names, undelete_names=None, finally_delete=False): - url = "/project/data_processing/jobs/" - delete_button_id = "jobs__action_delete" - msg = "Success: Deleted Job" - err_msg = 'Error: Unable to delete job' - info_msg = 'Info: Deleted Job' - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete, msg, err_msg, info_msg) - - def delete_job_executions(self, names, undelete_names=None, - finally_delete=False, await_delete=False): - url = "/project/data_processing/job_executions/" - delete_button_id = 'job_executions__action_delete' - msg = "Success: Deleted Job execution" - err_msg = "Error: Unable to delete job execution" - info_msg = "Info: Deleted Job execution" - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete, msg, err_msg, info_msg, - await_delete) - - def unregister_images(self, names, undelete_names=None, - finally_delete=False): - url = '/project/data_processing/data_image_registry/' - delete_button_id = "image_registry__action_Unregister" - msg = "Success: Unregistered Image" - self.delete_and_validate(url, delete_button_id, names, undelete_names, - finally_delete, succes_msg=msg,) - -# -------------------------helpers_methods------------------------------------- - - @staticmethod - def connect_to_swift(): - return swift_client.Connection( - authurl=cfg.common.keystone_url, - user=cfg.common.user, - key=cfg.common.password, - tenant_name=cfg.common.tenant, - auth_version=2 - ) - - @staticmethod - def delete_swift_container(swift, container): - - try: - objects = [obj['name'] for obj - in swift.get_container(container)[1]] - except Exception: - return - - for obj in objects: - - swift.delete_object(container, obj) - - try: - swift.delete_container(container) - except Exception: - return - - @classmethod - def find_clear_send(cls, by_find, find_element, send): - cls.driver.find_element(by=by_find, value=find_element).clear() - cls.driver.find_element(by=by_find, value=find_element).send_keys(send) - - def click_visible_key(self, xpath): - keys = self.driver.find_elements_by_xpath(xpath) - for key in keys: - if key.is_displayed(): - key.click() - - def delete_and_validate(self, url, delete_button_id, names, undelete_names, - finally_delete, - succes_msg='Success: Deleted Template', - error_msg='Error: Unable to delete template', - info_msg='Info: Deleted Template', - await_delete=False,): - driver = self.driver - driver.refresh() - driver.get(cfg.common.base_url + url) - - if finally_delete: - try: - self.await_element(by.By.ID, delete_button_id, await_count=3) - except selenim_except.NoSuchElementException: - return - else: - self.await_element(by.By.ID, delete_button_id) - - for name in names: - # choose checkbox for this element - checkbox = None - retry_count = 0 - while not checkbox: - if retry_count > 10: - self.fail("id of job execution didn't obtained") - try: - checkbox = driver.find_element_by_link_text( - name).find_element_by_xpath( - "../../td[1]/input") - except selenim_except.StaleElementReferenceException: - time.sleep(1) - retry_count += 1 - except selenim_except.NoSuchElementException: - if not finally_delete: - print ("element with name %s not found " - "for delete" % name) - raise - if not checkbox.is_selected(): - checkbox.click() - # click deletebutton - driver.find_element_by_id(delete_button_id).click() - # wait window to confirm the deletion - self.await_element(by.By.CLASS_NAME, "btn-primary") - # confirm the deletion - driver.find_element_by_class_name("btn-primary").click() - if finally_delete: - return - exp_del_obj = list(set(names).symmetric_difference(set( - undelete_names if undelete_names else []))) - if not undelete_names: - if len(names) > 1: - succes_msg += "s" - succes_msg += ": " - self.check_alert("alert-success", succes_msg, names, deleted=True, - await_delete=await_delete) - elif not exp_del_obj: - if len(undelete_names) > 1: - error_msg += "s" - error_msg += ": " - self.check_alert("alert-danger", error_msg, undelete_names, - deleted=False) - else: - if len(undelete_names) > 1: - error_msg += "s" - error_msg += ": " - if len(exp_del_obj) > 1: - info_msg += "s" - info_msg += ": " - self.check_alert("alert-danger", error_msg, undelete_names, - deleted=False) - self.check_alert("alert-info", info_msg, exp_del_obj, deleted=True, - await_delete=await_delete) - driver.refresh() - - def error_helper(self, message): - driver = self.driver - messages = message.split(", ") - self.await_element(by.By.CLASS_NAME, "error") - errors = driver.find_elements_by_class_name("error") - for message in messages: - mes = message.split(":") - if len(mes) > 1: - # if word count for error mesage > 1, then error message - # can be on the open tab or on another - if len(mes) > 2: - # if word count for error mesage > 2, then error message - # on another tab - # Click the tab indicated in the message - driver.find_element_by_link_text(mes.pop(0)).click() - error = errors.pop(0).text.split("\n") - self.assertEqual(mes[0], error[0]) - self.assertEqual(mes[1], error[1]) - else: - self.assertEqual(mes[0], errors.pop(0).text) - self.assertEqual(errors, []) - driver.refresh() - - def config_helper(self, config_list): - driver = self.driver - for pair in config_list: - for par, value in pair.iteritems(): - if len(par.split(":")) > 1: - config_blog = driver.find_element_by_link_text( - par.split(":")[0]) - config_blog.click() - - # Find class for config blog for for unambiguous - # finding buttons - config_class = driver.find_element_by_id( - config_blog.get_attribute('data-target').lstrip("#")) - - config_id = "id_CONF:%s" % par.split(":")[0].split(" ")[0] - if config_id == "id_CONF:General": - config_id = "id_CONF:general" - par = par.split(":")[1] - if par == "Show_param": - show_button = config_class.find_element_by_class_name( - "full-config-show") - hide_button = config_class.find_element_by_class_name( - "full-config-hide") - if value: - self.waiting_element_in_visible_state( - button=show_button) - show_button.click() - self.waiting_element_in_visible_state( - button=hide_button) - else: - self.waiting_element_in_visible_state( - button=hide_button) - hide_button.click() - self.waiting_element_in_visible_state( - button=show_button) - elif par == "Filter": - filter_button = config_class.find_element_by_css_selector( - "input.form-control.field-filter") - filter_button.clear() - filter_button.send_keys(value) - - else: - self.waiting_element_in_visible_state( - by.By.ID, "%s:%s" % (config_id, par)) - if isinstance(value, bool): - if driver.find_element_by_id( - "%s:%s" % (config_id, - par)).is_selected() != value: - driver.find_element_by_id( - "%s:%s" % (config_id, par)).click() - else: - self.find_clear_send( - by.By.ID, "%s:%s" % (config_id, par), value) - - def image_registry_helper(self, image_name, user_name, description, - tags_to_add, tags_to_remove, positive, - close_window, message, operation): - driver = self.driver - list_for_check_tags = [] - driver.get(cfg.common.base_url + - "/project/data_processing/data_image_registry/") - self.await_element(by.By.ID, "image_registry__action_register") - if operation == 'Registry': - driver.find_element_by_id( - "image_registry__action_register").click() - else: - # Add existing tags in the list - list_for_check_tags = driver.\ - find_element(by=by.By.LINK_TEXT, value=image_name).\ - find_element_by_xpath('../../td[3]').text.split('\n') - # Click "Edit Tags" - driver.find_element(by=by.By.LINK_TEXT, value=image_name).\ - find_element_by_xpath('../../td[4]').\ - find_element(by=by.By.LINK_TEXT, value='Edit Tags').click() - self.await_element(by.By.ID, 'id_user_name') - if operation == 'Registry': - driver.find_element_by_xpath("//select[@id='id_image_id']" - "/option[text()='%s']" - % image_name).click() - if user_name: - self.find_clear_send(by.By.ID, 'id_user_name', user_name) - if description: - self.find_clear_send(by.By.ID, 'id_description', user_name) - if tags_to_add: - for tag in tags_to_add: - for first, second in tag.iteritems(): - if first in ["vanilla", 'hdp']: - driver.find_element_by_xpath( - "//select[@id='plugin_select']/option[text()='%s']" - % first).click() - driver.find_element_by_xpath( - "//select[@id='data_processing_version_%s']" - "/option[text()='%s']" % (first, second)).click() - driver.find_element_by_id('add_all_btn').click() - if first not in list_for_check_tags: - list_for_check_tags.append(first) - if second not in list_for_check_tags: - list_for_check_tags.append(second) - elif first == 'custom_tag': - self.find_clear_send(by.By.ID, '_sahara_image_tag', - second) - driver.find_element_by_id('add_tag_btn').click() - if second not in list_for_check_tags: - list_for_check_tags.append(second) - else: - self.fail("Tag:%s, %s is unknown" % (first, second)) - if tags_to_remove: - for tag in tags_to_remove: - # click "x" in tag - driver.find_element_by_xpath( - "//div[@id='image_tags_list']//span[contains(.,'%s')]//i" - % tag).click() - if tag in list_for_check_tags: - list_for_check_tags.remove(tag) - driver.find_element_by_id('edit_image_tags_btn').click() - if positive: - self.check_create_object(image_name, positive, message, - [{3: list_for_check_tags}]) - else: - if not close_window: - self.error_helper(message) - else: - self.check_create_object(image_name, positive, message) - - def choose_plugin_name(self, plugin_name, hadoop_version, name, - description, id_name): - self.await_element(by.By.ID, "id_plugin_name") - self.driver.find_element_by_xpath( - "//select[@id='id_plugin_name']/option[text()='%s']" % - plugin_name).click() - if plugin_name == "Hortonworks Data Platform": - version_id = "id_hdp_version" - elif plugin_name == "Vanilla Apache Hadoop": - version_id = "id_vanilla_version" - else: - self.fail("plugin_name:%s is wrong" % plugin_name) - self.driver.find_element_by_id(version_id).find_element_by_xpath( - "option[text()='%s']" % hadoop_version).click() - self.driver.find_element_by_xpath("//input[@value='Create']").click() - self.await_element(by.By.ID, id_name) - self.find_clear_send(by.By.ID, id_name, name) - if description: - self.find_clear_send(by.By.ID, "id_description", description) - - def check_alert(self, alert, expected_message, list_obj, deleted=True, - await_delete=False): - self.await_element(by.By.CLASS_NAME, alert) - actual_message = self.find_alert_message( - alert, first_character=2, last_character=len(expected_message) + 2) - self.assertEqual(actual_message, expected_message) - not_expected_objs = list(set(self.find_alert_message( - alert, first_character=len(expected_message) + 2).split( - ", ")).symmetric_difference(set(list_obj))) - if not_expected_objs: - self.fail("have deleted objects: %s" % not_expected_objs) - if deleted: - errmsg = "object with name:{} is not deleted" - else: - errmsg = "object with name:{} is deleted" - for name in list_obj: - if await_delete: - await_count = 0 - while self.does_element_present(by.By.LINK_TEXT, - name) == deleted: - self.driver.refresh() - time.sleep(5) - await_count += 1 - if await_count > 12: - self.fail(errmsg.format(name)) - return - if self.does_element_present(by.By.LINK_TEXT, name) == deleted: - self.fail(errmsg.format(name)) - delete_attempts_count = 0 - for name in list_obj: - while self.does_element_present(by.By.LINK_TEXT, name) == deleted: - if delete_attempts_count > cfg.common.await_element: - if deleted: - errmsg = "object with name:%s is not deleted" % name - else: - errmsg = "object with name:%s is deleted" % name - self.fail(errmsg) - time.sleep(1) - delete_attempts_count += 1 - - def find_alert_message(self, name, first_character=None, - last_character=None): - driver = self.driver - return str(driver.find_element_by_class_name("%s" % name).text[ - first_character:last_character]) - - def search_id_processes(self, process, plugin): - return plugin.processes[process] - - def waiting_element_in_visible_state(self, how=None, what=None, - button=None): - if not button: - button = self.driver.find_element(by=how, value=what) - for i in range(cfg.common.await_element): - if button.is_displayed(): - break - time.sleep(1) - else: - self.fail("time out for await visible: %s , %s" % (how, what)) - - def does_element_present(self, how, what): - try: - self.driver.find_element(by=how, value=what) - except Exception as e: - print(e.message) - return False - return True - - def await_element(self, by, value, message="", - await_count=cfg.common.await_element): - for i in range(await_count): - if self.does_element_present(by, value): - break - time.sleep(1) - else: - if not message: - message = "time out for await: %s , %s" % (by, value) - print(message) - raise selenim_except.NoSuchElementException - - def check_create_object(self, name, positive, expected_message, - check_columns=None, check_create_element=True): - driver = self.driver - expected_alert = "alert-danger" - unexpected_alert = "alert-success" - if positive: - expected_alert = "alert-success" - unexpected_alert = "alert-danger" - for i in range(cfg.common.await_element): - if self.does_element_present(by.By.CLASS_NAME, expected_alert): - break - elif self.does_element_present(by.By.CLASS_NAME, unexpected_alert): - fail_mesg = self.driver.find_element( - by=by.By.CLASS_NAME, value=unexpected_alert).text[2:] - self.fail("Result of creation %s is not expected: %s != %s" - % (name, expected_message, fail_mesg)) - time.sleep(1) - else: - self.fail("alert check:%s time out" % expected_alert) - actual_message = self.driver.find_element( - by=by.By.CLASS_NAME, value=expected_alert).text[2:] - if check_create_element and positive: - self.assertEqual(expected_message, str(actual_message)) - if not self.does_element_present(by.By.LINK_TEXT, name): - self.fail("object with name:%s not found" % name) - if check_columns: - for column in check_columns: - for column_number, expected_values in column.iteritems(): - actual_values = driver.\ - find_element_by_link_text(name).\ - find_element_by_xpath( - '../../td[%d]' % column_number).\ - text.split('\n') - self.assertItemsEqual(actual_values, expected_values) - else: - if expected_message: - self.assertEqual(expected_message, str(actual_message)) - self.driver.refresh() - - def await_cluster_active(self, name): - driver = self.driver - i = 1 - while True: - - if i > cfg.common.cluster_creation_timeout * 60: - self.fail( - 'cluster is not getting status \'Active\', ' - 'passed %d minutes' % cfg.common.cluster_creation_timeout) - - try: - status = driver.find_element_by_link_text( - "selenium-cl").find_element_by_xpath("../../td[3]").text - except selenim_except.StaleElementReferenceException: - status = 'unknown' - - if str(status) == 'Error': - self.fail('Cluster state == \'Error\'.') - - if str(status) == 'Active': - break - - time.sleep(5) - i += 5 - - def await_launch_job(self, job_name): - driver = self.driver - driver.get(cfg.common.base_url + - "/project/data_processing/job_executions/") - self.await_element(by.By.ID, 'job_executions') - - job_id = None - retry_count = 0 - while not job_id: - if retry_count > 10: - self.fail("id of job execution didn't obtained") - try: - job_id = driver.find_element_by_id( - 'job_executions').find_elements_by_class_name( - 'ajax-update')[0].get_attribute('id') - self.job_id = job_id.split("_")[-1] - # TODO(vrovachev): replace find job_id on commented code - # after resolve bug 1391469 - # job_id = driver.find_element_by_id( - # 'job_executions').find_element_by_link_text( - # job_name).find_element_by_xpath( - # '../..').get_attribute('id') - except selenim_except.StaleElementReferenceException: - time.sleep(1) - retry_count += 1 - - status = None - retry_count = 0 - while not status: - if retry_count > 10: - self.fail("id of job execution didn't obtained") - try: - status = driver.find_element_by_id( - job_id).find_element_by_xpath( - "td[contains(@class, 'status_')]").text - except selenim_except.StaleElementReferenceException: - time.sleep(1) - retry_count += 1 - - timeout = cfg.common.job_launch_timeout * 60 - - while str(status) != 'SUCCEEDED': - - if timeout <= 0: - self.fail( - 'Job did not return to \'SUCCEEDED\' status within ' - '%d minute(s).' % cfg.common.job_launch_timeout) - - if status == 'KILLED': - self.fail('Job status == \'KILLED\'.') - - status = None - retry_count = 0 - while not status: - if retry_count > 10: - self.fail("id of job execution didn't obtained") - try: - status = driver.find_element_by_id( - job_id).find_element_by_xpath( - "td[contains(@class, 'status_')]").text - except selenim_except.StaleElementReferenceException: - time.sleep(1) - retry_count += 1 - - time.sleep(1) - timeout -= 1 - - @classmethod - def tearDownClass(cls): - cls.driver.quit() diff --git a/saharadashboard/tests/cluster_template_tests/negative_tests.py b/saharadashboard/tests/cluster_template_tests/negative_tests.py deleted file mode 100644 index 602f55e5..00000000 --- a/saharadashboard/tests/cluster_template_tests/negative_tests.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 testtools import testcase -import unittest2 - -from saharadashboard.tests import base -import saharadashboard.tests.configs.config as cfg - - -class UINegativeCreateClusterTemplateTest(base.UITestCase): - - @testcase.attr('cluster_template', 'vanilla') - @unittest2.skip - @unittest2.skipIf(cfg.vanilla.skip_plugin_tests, - 'tests for vanilla plugin skipped') - def test_create_vanilla_cluster_template_with_wrong_fields(self): - self.create_node_group_template('selenium-master', ["NN", "JT"], - cfg.vanilla) - self.create_node_group_template('selenium-worker', ["DN", "TT"], - cfg.vanilla) - self.create_cluster_template( - "", {'selenium-master': 1, 'selenium-worker': 2}, cfg.vanilla, - anti_affinity_groups=["NN", "DN", "TT"], - params=[{"General Parameters:Enable Swift": False}, - {"HDFS Parameters:io.file.buffer.size": "str"}, - {"MapReduce Parameters:mapreduce.job.counters.max": - "str"}], - positive=False, close_window=False, - message='Details, HDFS Parameters, MapReduce Parameters, ' - 'Template Name:This field is required., ' - 'HDFS Parameters:io.file.buffer.size:Enter a whole number., ' - 'MapReduce Parameters:mapreduce.job.counters.max:' - 'Enter a whole number.') - self.delete_node_group_templates(["selenium-master", - "selenium-worker"]) diff --git a/saharadashboard/tests/cluster_template_tests/test_create_cluster_template.py b/saharadashboard/tests/cluster_template_tests/test_create_cluster_template.py deleted file mode 100644 index f15185fe..00000000 --- a/saharadashboard/tests/cluster_template_tests/test_create_cluster_template.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 testtools import testcase -import unittest2 - -from saharadashboard.tests import base -import saharadashboard.tests.configs.config as cfg - - -class UICreateClusterTemplate(base.UITestCase): - - @testcase.attr('cluster_template', 'vanilla') - @unittest2.skipIf(cfg.vanilla.skip_plugin_tests, - 'tests for vanilla plugin skipped') - def test_create_cluster_template_for_vanilla(self): - self.create_node_group_template('selenium-master', ["NN", "JT"], - cfg.vanilla) - self.create_node_group_template('selenium-worker', ["DN", "TT"], - cfg.vanilla) - self.create_node_group_template('selenium-delete', ["NN", "OZ"], - cfg.vanilla) - self.create_cluster_template( - "selenium-clstr-tmpl", {'selenium-master': 1, - 'selenium-worker': 2}, - cfg.vanilla, anti_affinity_groups=["NN", "DN", "TT"], - params=[{"General Parameters:Enable Swift": False}, - {"HDFS Parameters:dfs.replication": 2}, - {"MapReduce Parameters:mapred.output.compress": False}]) - msg = 'Error: Cluster template with name \'selenium-clstr-tmpl\'' \ - ' already exists' - self.create_cluster_template('selenium-clstr-tmpl', - {'selenium-delete': 1, - 'selenium-worker': 2}, - cfg.vanilla, positive=False, message=msg) - self.delete_node_group_templates(["selenium-master", "selenium-worker", - "selenium-delete"], - undelete_names=["selenium-master", - "selenium-worker"]) - self.delete_cluster_templates(['selenium-clstr-tmpl']) - self.delete_node_group_templates(["selenium-master", - "selenium-worker"]) - - @testcase.attr('cluster_template', 'hdp') - @unittest2.skipIf(cfg.hdp.skip_plugin_tests, - 'tests for hdp plugin skipped') - def test_create_cluster_template_for_hdp(self): - self.create_node_group_template( - 'selenium-hdp-master', - ["NN", "JT", "SNN", "GANGLIA_SERVER", "NAGIOS_SERVER", - "AMBARI_SERVER"], cfg.hdp) - self.create_node_group_template( - 'selenium-hdp-worker', - ["TT", "DN", "HDFS_CLIENT", "MAPREDUCE_CLIENT"], cfg.hdp) - self.create_cluster_template( - "selenium-hdp", {'selenium-hdp-master': 1, - 'selenium-hdp-worker': 2}, cfg.hdp, - description="hdp plugin", anti_affinity_groups=["NN", "DN", "TT"], - params=[{"General Parameters:Show_param": True}, - {"hadoop_heapsize": 512}, - {"HDFS Parameters:Show_param": True}, - {"HDFS Parameters:dfs.replication": 2}]) - self.delete_cluster_templates(['selenium-hdp']) - self.delete_node_group_templates(["selenium-hdp-master", - "selenium-hdp-worker"]) diff --git a/saharadashboard/tests/cluster_tests/__init__.py b/saharadashboard/tests/cluster_tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/saharadashboard/tests/cluster_tests/test_clusters.py b/saharadashboard/tests/cluster_tests/test_clusters.py deleted file mode 100644 index f6f782be..00000000 --- a/saharadashboard/tests/cluster_tests/test_clusters.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 random -import string - -from testtools import testcase -import unittest2 - -from saharadashboard.tests import base -import saharadashboard.tests.configs.config as cfg - - -class UICreateCluster(base.UITestCase): - - def setUp(self): - super(UICreateCluster, self).setUp() - self.pass_test = False - self.processes = ["NN", "JT"] - self.await_run = False - self.master_storage = {'type': 'Ephemeral Drive'} - self.anty_affinity = [] - if not cfg.vanilla.skip_edp_test: - self.swift = self.connect_to_swift() - self.processes = ["NN", "JT", "OZ"] - self.await_run = True - if cfg.common.cinder: - self.master_storage = {"type": "Cinder Volume", - "volume_per_node": 1, - "volume_size": 5} - if cfg.common.anty_affinity: - self.anty_affinity = "NN", "DN", "TT" - - @testcase.attr('cluster', 'vanilla') - @unittest2.skipIf(cfg.vanilla.skip_plugin_tests, - 'tests for vanilla plugin skipped') - def test_create_vanilla_cluster(self): - - self.create_node_group_template('selenium-master', self.processes, - cfg.vanilla, - storage=self.master_storage) - self.create_node_group_template('selenium-worker', ["DN", "TT"], - cfg.vanilla) - self.create_node_group_template('selenium-del1', ["NN", "JT", - "DN", "TT"], - cfg.vanilla) - self.create_node_group_template('selenium-del2', - ["DN", "TT", "OZ"], - cfg.vanilla) - self.create_cluster_template("selenium-cl-tmpl", - {'selenium-master': 1, - 'selenium-worker': 1}, cfg.vanilla, - anti_affinity_groups=self.anty_affinity) - self.create_cluster_template("selenium-cl-tmpl2", - {'selenium-master': 1, - 'selenium-del2': 2}, - cfg.vanilla, - anti_affinity_groups=["NN", "DN", - "TT", "JT"]) - self.create_cluster(cfg.vanilla.cluster_name, 'selenium-cl-tmpl', - cfg.vanilla, await_run=self.await_run) - if not cfg.vanilla.skip_edp_test: - self.edp_helper() - self.delete_node_group_templates(["selenium-master", - "selenium-worker", - "selenium-del1", - "selenium-del2"], - undelete_names=["selenium-master", - "selenium-worker", - "selenium-del2"]) - self.delete_cluster_templates(['selenium-cl-tmpl', - 'selenium-cl-tmpl2'], - undelete_names=["selenium-cl-tmpl"]) - self.delete_node_group_templates(["selenium-master", - "selenium-worker", - "selenium-del2"], - undelete_names=[ - "selenium-master", - "selenium-worker"]) - self.delete_clusters([cfg.vanilla.cluster_name], await_delete=True) - self.delete_cluster_templates(["selenium-cl-tmpl"]) - self.delete_node_group_templates(["selenium-master", - "selenium-worker"]) - self.pass_test = True - - def edp_helper(self): - self.swift.put_container('selenium-container') - self.swift.put_object( - 'selenium-container', 'input', ''.join(random.choice( - ':' + ' ' + '\n' + string.ascii_lowercase) - for x in range(10000))) - - self.create_data_source( - 'input', 'selenium-container.sahara/input') - self.create_data_source( - 'output', 'selenium-container.sahara/output') - - parameters_of_storage = { - 'storage_type': 'Internal database', - 'Internal binary': '*Upload a new file', - 'filename': 'edp-lib.jar'} - - self.create_job_binary('edp-lib.jar', parameters_of_storage) - - parameters_of_storage = { - 'storage_type': 'Internal database', - 'Internal binary': '*Create a script', - 'script_name': 'edp-job.pig', - 'script_text': open('saharadashboard/tests/resources/' - 'edp-job.pig').read()} - - self.create_job_binary('edp-job.pig', parameters_of_storage) - - self.create_job( - 'selenium-job', 'Pig', 'edp-job.pig', ['edp-lib.jar']) - self.launch_job_on_existing_cluster( - 'selenium-job', 'input', 'output', cfg.vanilla.cluster_name) - - self.delete_swift_container(self.swift, 'selenium-container') - if getattr(self, "job_id", None): - self.delete_job_executions([self.job_id], await_delete=True) - self.delete_jobs(['selenium-job']) - self.delete_job_binaries(['edp-lib.jar', 'edp-job.pig']) - self.delete_data_sources(['input', 'output']) - - def cleanup(self): - if not cfg.vanilla.skip_edp_test: - self.delete_swift_container(self.swift, 'selenium-container') - if getattr(self, "job_id", None): - self.delete_job_executions([self.job_id], finally_delete=True) - self.delete_jobs(['selenium-job'], finally_delete=True) - self.delete_job_binaries(['edp-lib.jar', 'edp-job.pig'], - finally_delete=True) - self.delete_data_sources(['input', 'output'], finally_delete=True) - self.delete_clusters([cfg.vanilla.cluster_name], finally_delete=True) - self.delete_cluster_templates(['selenium-cl-tmpl', - 'selenium-cl-tmpl2'], - finally_delete=True) - self.delete_node_group_templates(["selenium-master", "selenium-worker", - "selenium-del1", "selenium-del2"], - finally_delete=True) - - def tearDown(self): - if not self.pass_test: - self.cleanup() - super(UICreateCluster, self).tearDown() diff --git a/saharadashboard/tests/configs/__init__.py b/saharadashboard/tests/configs/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/saharadashboard/tests/configs/config.conf.sample b/saharadashboard/tests/configs/config.conf.sample deleted file mode 100644 index 6d49da64..00000000 --- a/saharadashboard/tests/configs/config.conf.sample +++ /dev/null @@ -1,33 +0,0 @@ -[common] -base_url = "http://127.0.0.1:8080" -user = "admin" -password = "admin" -keypair = 'jenkins' -tenant = 'admin' -auto_security_groups = False -security_groups = default -flavor = 'm1.minniemouse' -# uncomment this parameters if quantum in OpenStack -# neutron_management_network = '' -# floating_ip_pool = '' -keystone_url = 'http://127.0.0.1:5000/v2.0' -# in minutes -cluster_creation_timeout = 10 -# in seconds -await_element = 10 -# in minutes -job_launch_timeout = 5 -image_name_for_register = 'image_name' -image_name_for_edit = 'image_name' -[vanilla] -skip_plugin_tests = False -plugin_name = "Vanilla Apache Hadoop" -plugin_overview_name = "vanilla" -hadoop_version = "1.2.1" -processes = NN: 0, DN: 1, SNN: 2, OZ: 3, TT: 4, JT: 5 -base_image = "image_name" -[hdp] -skip_plugin_tests = False -plugin_name = "Hortonworks Data Platform" -hadoop_version = "1.3.2" -base_image = "image_name" \ No newline at end of file diff --git a/saharadashboard/tests/configs/config.py b/saharadashboard/tests/configs/config.py deleted file mode 100644 index e65cf1ac..00000000 --- a/saharadashboard/tests/configs/config.py +++ /dev/null @@ -1,169 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 - -from oslo_config import cfg - -common_group = cfg.OptGroup(name='common', title="common configs") - -CommonGroup = [ - cfg.StrOpt('base_url', - default='http://127.0.0.1:8080', - help="sahara url"), - cfg.StrOpt('user', - default='admin', - help="keystone user"), - cfg.StrOpt('password', - default='pass', - help="password for keystone user"), - cfg.StrOpt('keypair', - default='public-jenkins', - help='keypair for create cluster'), - cfg.StrOpt('tenant', - default='admin', - help='keystone tenant'), - cfg.BoolOpt('auto_security_groups', - default=False, - help="Security Groups for sahara cluster"), - cfg.ListOpt('security_groups', - default=None, - help="Security Groups for sahara cluster"), - cfg.StrOpt('flavor', - default='m1.minniemouse', - help='OpenStack flavor name for image.'), - cfg.StrOpt('neutron_management_network', - default=None, - help='Private network for quantum.' - 'Must be specified in create cluster tab'), - cfg.StrOpt('floating_ip_pool', - default=None, - help='Public network for quantum.' - 'Must be specified in create nodegroup template tab'), - cfg.StrOpt('keystone_url', - default='http://127.0.0.1:5000/v2.0', - help='url for keystone authentication'), - cfg.BoolOpt('anty_affinity', - default=False, - help="Parameter for enable/disable Anty Affinity " - "Groups for Sahara cluster"), - cfg.BoolOpt('cinder', - default=False, - help="Parameter for enable/disable attach volume disk " - "to node for Sahara cluster"), - cfg.IntOpt('cluster_creation_timeout', - default=10, - help="cluster timeout in minutes"), - cfg.IntOpt('await_element', - default=15, - help="await each web element in seconds"), - cfg.StrOpt('image_name_for_register', - default='fedora_19', - help='Image name for register to Sahara'), - cfg.StrOpt('image_name_for_edit', - default='latest-ci-image', - help='Image name for edit in image registry in Sahara'), - cfg.IntOpt('job_launch_timeout', - default=5, - help='Timeout for job launch (in minutes); ' - 'minimal value is 1.'), -] - -vanilla_group = cfg.OptGroup(name='vanilla', title="vanilla configs") - -VanillaGroup = [ - cfg.BoolOpt('skip_plugin_tests', - default=False, - help=""" - If this variable is True then - tests for vanilla will be skipped - """), - cfg.BoolOpt('skip_edp_test', default=True), - cfg.StrOpt('plugin_name', - default='Vanilla Apache Hadoop', - help="plugin title, default: Vanilla Apache Hadoop"), - cfg.StrOpt('plugin_overview_name', - default='vanilla', - help="plugin name in overview"), - cfg.StrOpt('cluster_name', - default="selenium-cl", - help="Name of vanilla cluster"), - cfg.StrOpt('hadoop_version', - default='1.2.1', - help="hadoop version for plugin"), - cfg.DictOpt('processes', - default={"NN": 0, "DN": 1, "SNN": 2, - "OZ": 3, "TT": 4, "JT": 5, "hiveserver": 6}, - help='numbers of processes for vanilla in saharadashboard'), - cfg.StrOpt('base_image', - default='ubuntu_sahara_latest', - help="image name for start vanilla cluster") -] - -hdp_group = cfg.OptGroup(name='hdp', title="hdp configs") - -HdpGroup = [ - cfg.BoolOpt('skip_plugin_tests', - default=False, - help=""" - If this variable is True then - tests for hdp will be skipped - """), - cfg.StrOpt('plugin_name', - default='Hortonworks Data Platform', - help="plugin title, default: Hortonworks Data Platform"), - cfg.StrOpt('plugin_overview_name', - default='hdp', - help="plugin name in overview"), - cfg.StrOpt('hadoop_version', - default='1.3.2', - help="hadoop version for plugin"), - cfg.DictOpt('processes', - default={ - "NN": 0, "DN": 1, "SNN": 2, "HDFS_CLIENT": 3, - " ZOOKEEPER_SERVER": 4, "ZOOKEEPER_CLIENT": 5, - "AMBARI_SERVER": 6, "HCAT": 7, "SQOOP": 8, - "JT": 9, "TT": 10, "MAPREDUCE_CLIENT": 11, - "HIVE_SERVER": 12, "HIVE_METASTORE": 13, - "HIVE_CLIENT": 14, "MYSQL_SERVER": 15, - "PIG": 16, "WEBHCAT_SERVER": 17, "OOZIE_SERVER": 18, - "OOZIE_CLIENT": 19, "GANGLIA_SERVER": 20, - "NAGIOS_SERVER": 21, "HBASE_MASTER": 22, - "HBASE_REGIONSERVER": 23, "HBASE_CLIENT": 24 - }, help='numbers of processes for hdp in saharadashboard'), - cfg.StrOpt('base_image', - default='ib-centos-6-4-64-hdp-13', - help="image name for start hdp cluster") -] - - -def register_config(config, config_group, config_opts): - - config.register_group(config_group) - config.register_opts(config_opts, config_group) - -path = os.path.join("%s/saharadashboard/tests/configs/config.conf" - % os.getcwd()) - -if os.path.exists(path): - cfg.CONF([], project='saharadashboard', default_config_files=[path]) - -register_config(cfg.CONF, common_group, CommonGroup) -register_config(cfg.CONF, vanilla_group, VanillaGroup) -register_config(cfg.CONF, hdp_group, HdpGroup) - -common = cfg.CONF.common -vanilla = cfg.CONF.vanilla -hdp = cfg.CONF.hdp diff --git a/saharadashboard/tests/image_registry_tests/__init__.py b/saharadashboard/tests/image_registry_tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/saharadashboard/tests/image_registry_tests/test_for_image_registry.py b/saharadashboard/tests/image_registry_tests/test_for_image_registry.py deleted file mode 100644 index 39aa68d9..00000000 --- a/saharadashboard/tests/image_registry_tests/test_for_image_registry.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 testtools import testcase - -from saharadashboard.tests import base -import saharadashboard.tests.configs.config as cfg - - -class UIImageRegistry(base.UITestCase): - - @testcase.attr('image_registry') - def test_edit_tags_for_image(self): - self.edit_tags_by_image_name(cfg.common.image_name_for_edit, - tags_to_add=[ - {cfg.hdp.plugin_overview_name: - cfg.hdp.hadoop_version}, - {'custom_tag': 'blabla'}]) - self.edit_tags_by_image_name(cfg.common.image_name_for_edit, - tags_to_add=[{'custom_tag': 'qweqwe'}], - tags_to_remove=['qweqwe', 'blabla']) - - @testcase.attr('image_registry') - def test_registry_vanilla_image(self): - self.image_registry(cfg.common.image_name_for_register, - user_name='cloud_user', - tags_to_add=[{cfg.vanilla.plugin_overview_name: - cfg.vanilla.hadoop_version}, - {'custom_tag': 'blabla'}]) - self.unregister_images([cfg.common.image_name_for_register]) diff --git a/saharadashboard/tests/node_group_template_tests/__init__.py b/saharadashboard/tests/node_group_template_tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/saharadashboard/tests/node_group_template_tests/negative_tests.py b/saharadashboard/tests/node_group_template_tests/negative_tests.py deleted file mode 100644 index cb0eb975..00000000 --- a/saharadashboard/tests/node_group_template_tests/negative_tests.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 testtools import testcase -import unittest2 - -from saharadashboard.tests import base -import saharadashboard.tests.configs.config as cfg - - -class UINegativeCreateNodeGroupTemplate(base.UITestCase): - - @testcase.attr('node_group_template', 'vanilla') - @unittest2.skipIf(cfg.vanilla.skip_plugin_tests, - 'tests for vanilla plugin skipped') - def test_create_vanilla_node_group_template_with_wrong_parameters(self): - self.create_node_group_template( - "", ["NN", "JT"], cfg.vanilla, flavor="m1.small", - params=[{"HDFS Parameters:dfs.datanode.handler.count": "str"}, - {"MapReduce Parameters:io.sort.mb": "str"}], - positive=False, close_window=False, - message='Configure Node Group Template, ' - 'HDFS Parameters, MapReduce Parameters, ' - 'Template Name:This field is required., ' - 'HDFS Parameters:dfs.datanode.handler.count:' - 'Enter a whole number., ' - 'MapReduce Parameters:io.sort.mb:' - 'Enter a whole number.') - - @testcase.attr('node_group_template', 'vanilla') - @unittest2.skipIf(cfg.vanilla.skip_plugin_tests, - 'tests for vanilla plugin skipped') - def test_create_vanilla_node_group_template_with_missing_parameters(self): - self.create_node_group_template( - "", [], cfg.vanilla, positive=False, close_window=False, - message='Configure Node Group Template, ' - 'Template Name:This field is required., ' - 'Processes:This field is required.') diff --git a/saharadashboard/tests/node_group_template_tests/test_create_node_group_template.py b/saharadashboard/tests/node_group_template_tests/test_create_node_group_template.py deleted file mode 100644 index c83ad6db..00000000 --- a/saharadashboard/tests/node_group_template_tests/test_create_node_group_template.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# 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 testtools import testcase -import unittest2 - -from saharadashboard.tests import base -import saharadashboard.tests.configs.config as cfg - - -class UICreateNodeGroupTemplate(base.UITestCase): - - @testcase.attr('node_group_template', 'vanilla') - @unittest2.skipIf(cfg.vanilla.skip_plugin_tests, - 'tests for vanilla plugin skipped') - def test_create_node_group_template_vanilla(self): - self.create_node_group_template( - "selenium-vanilla", ["NN", "JT"], cfg.vanilla, flavor="m1.small", - storage={'type': "Cinder Volume", 'volume_per_node': '2', - 'volume_size': '6'}, description='selenium-test', - params=[{"HDFS Parameters:Show_param": True}, - {"hadoop.native.lib": False}, {"Filter": "heap"}, - {"Name Node Heap Size": 512}, - {"Data Node Heap Size": 512}, - {"Show_param": False}, {"Filter": ""}, - {"dfs.datanode.max.xcievers": 3555}, - {"MapReduce Parameters:io.sort.mb": 200}, - {"mapred.child.java.opts": "-Xmx300m"}]) - msg = "Error: NodeGroup template with name 'selenium-vanilla'" \ - " already exists" - self.create_node_group_template("selenium-vanilla", ["NN", "JT"], - cfg.vanilla, positive=False, - message=msg) - self.delete_node_group_templates(['selenium-vanilla']) - - @testcase.attr('node_group_template', 'hdp') - @unittest2.skipIf(cfg.hdp.skip_plugin_tests, - 'tests for hdp plugin skipped') - def test_create_node_group_template_hdp(self): - self.create_node_group_template( - "sel-hdp", ["NN", "JT", "HDFS_CLIENT", "AMBARI_SERVER"], cfg.hdp, - flavor="m1.small", storage={'type': "Cinder Volume", - 'volume_per_node': '2', - 'volume_size': '6'}, - description='selenium-test') - msg = "Error: NodeGroup template with name 'sel-hdp' already exists" - self.create_node_group_template("sel-hdp", ["NN", "JT"], cfg.hdp, - positive=False, message=msg) - self.delete_node_group_templates(['sel-hdp']) diff --git a/saharadashboard/tests/resources/README.rst b/saharadashboard/tests/resources/README.rst deleted file mode 100644 index e849207c..00000000 --- a/saharadashboard/tests/resources/README.rst +++ /dev/null @@ -1,82 +0,0 @@ -README for resources -===================================== - -Resources in this directory using for check EDP for Sahara. -For this purpose the cluster with oozie by process is created. -With these resources created and launched jobs. -Success of performance of jobs is checked. - -Pig job -------------------------------------- - -Description. ------------- - -Resources 'edp-job.pig' and 'edp-lib.jar' used for create oozie job -that deletes all symbols in line after ":". - -Example: --------- - -input file: -""" -qweqwe -qweqweqwe: -qweqweqwe:qwe -:ertertert -asd -""" - -output file: -""" -qweqwe -qweqweqwe -asd -""" - -Sources. --------- - -Link for 'edp-job.pig': -https://github.com/apache/oozie/blob/branch-4.0/examples/src/main/apps/pig/id.pig - -Source for 'edp-lib.jar': -https://github.com/apache/oozie/blob/branch-4.0/examples/src/main/java/org/apache/oozie/example/DateList.java - - -MapReduce job -------------------------------------- - -Description. ------------- - -Resource 'edp-job.jar' used for create oozie job -which counts the characters in file and displays values ​​at end of each line. - -Example: --------- - -input file: -""" -qweqwe -qweqweqwe: -qweqweqwe:qwe -:ertertert -asd -""" - -output file: -""" -qweqwe 6 -qweqweqwe: 16 -qweqweqwe:qwe 29 -:ertertert 39 -asd 42 -""" - -Sources. --------- - -Sources for 'edp-job.jar': -https://github.com/apache/oozie/blob/branch-4.0/examples/src/main/java/org/apache/oozie/example/SampleMapper.java -https://github.com/apache/oozie/blob/branch-4.0/examples/src/main/java/org/apache/oozie/example/SampleReducer.java \ No newline at end of file diff --git a/saharadashboard/tests/resources/edp-job.jar b/saharadashboard/tests/resources/edp-job.jar deleted file mode 100644 index 04388a958325568618c807f4e5d764f303a765f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15641 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 XB*9*b5`lo;zJAVM?~s4QPeA_<2*LpM diff --git a/saharadashboard/tests/resources/edp-job.pig b/saharadashboard/tests/resources/edp-job.pig deleted file mode 100644 index 4141906e..00000000 --- a/saharadashboard/tests/resources/edp-job.pig +++ /dev/null @@ -1,3 +0,0 @@ -A = load '$INPUT' using PigStorage(':') as (fruit: chararray); -B = foreach A generate com.hadoopbook.pig.Trim(fruit); -store B into '$OUTPUT' USING PigStorage(); diff --git a/saharadashboard/tests/resources/edp-lib.jar b/saharadashboard/tests/resources/edp-lib.jar deleted file mode 100644 index 2eba7023ec8e6cf6ec5a0df4f32a8c976f94e946..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3745 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.10.0 +-e git://github.com/openstack/horizon.git#egg=horizon +hacking<0.11,>=0.10.0 coverage>=3.6 +ddt>=0.7.0 +django-nose>=1.2 discover mock>=1.2 -oslo.config>=2.6.0 # Apache-2.0 -pylint==1.4.4 # GNU GPL v2 -python-keystoneclient!=1.8.0,>=1.6.0 -python-swiftclient>=2.2.0 -selenium +mox3>=0.7.0 +python-subunit>=0.0.18 +sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 +oslosphinx>=2.5.0 # Apache-2.0 testrepository>=0.0.18 +testscenarios>=0.4 testtools>=1.4.0 -unittest2 diff --git a/tox.ini b/tox.ini index 3eb627c9..61f61517 100644 --- a/tox.ini +++ b/tox.ini @@ -1,25 +1,19 @@ [tox] minversion = 1.6 +envlist = py27,pep8,py27dj17 skipsdist = True -envlist = py26,py27,pep8 [testenv] usedevelop = True install_command = pip install -U {opts} {packages} setenv = - VIRTUAL_ENV={envdir} -deps = - -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt + VIRTUAL_ENV={envdir} +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +commands = /bin/bash run_tests.sh -N --no-pep8 {posargs} -[testenv:uitests] -commands = python setup.py testr --slowest --testr-args="--concurrency 1 {posargs}" - -[testenv:cover] -commands = python setup.py testr --coverage --testr-args='--concurrency 1 {posargs}' - -[tox:jenkins] -downloadcache = ~/cache/pip +[testenv:py27] +setenv = DJANGO_SETTINGS_MODULE=manila_ui.test.settings [testenv:pep8] commands = flake8 @@ -27,12 +21,30 @@ commands = flake8 [testenv:venv] commands = {posargs} -[flake8] -# H904 Wrap long lines in parentheses instead of a backslash -ignore = H904 -show-source = true -builtins = _ -exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,tools,horizon +[testenv:py27dj17] +basepython = python2.7 +commands = pip install django>=1.7,<1.8 + /bin/bash run_tests.sh -N --no-pep8 {posargs} -[hacking] -local-check-factory = saharadashboard.utils.hacking.checks.factory +# Django-1.8 is LTS +[testenv:py27dj18] +basepython = python2.7 +commands = pip install django>=1.8,<1.9 + /bin/bash run_tests.sh -N --no-pep8 {posargs} + +[testenv:cover] +commands = python setup.py testr --coverage --testr-args='{posargs}' + +[testenv:docs] +commands = python setup.py build_sphinx + +[testenv:debug] +commands = oslo_debug_helper {posargs} + +[flake8] +show-source = True +# E123, E125 skipped as they are invalid PEP-8. +# H405 multi line docstring summary not separated with an empty line +ignore = E123,E125,H405 +builtins = _ +exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,.ropeproject,tools