Adding integration test support

* Update requirements for selenium testing
* Add gate scripts
* Add draft integration test config and test stub
* Update tox for running integration tests

A patch for gate job is: I76ab460a110d93b0186ca126858f79ac9e89f09b

Change-Id: I5ca1bf7003a9882648cdfbeab21d2ada37b951f1
This commit is contained in:
Mark Vanderwiel 2016-02-02 11:53:13 -06:00
parent 73444f99f8
commit e221f7482a
15 changed files with 400 additions and 0 deletions

View File

@ -0,0 +1,78 @@
#
# Configuration filed based on Tempest's tempest.conf.sample
#
[dashboard]
# Where the dashboard can be found (string value)
dashboard_url=http://localhost/dashboard/
# Login page for the dashboard (string value)
login_url=http://localhost/dashboard/auth/login/
# Dashboard help page url (string value)
help_url=http://docs.openstack.org/
[selenium]
# Timeout in seconds to wait for a page to become available
# (integer value)
page_timeout=30
# Output directory for screenshots.
# (string value)
screenshots_directory=integration_tests_screenshots
# Implicit timeout to wait until element become available,
# this timeout is used for every find_element, find_elements call.
# (integer value)
implicit_wait=10
# Explicit timeout is used for long lasting operations,
# methods using explicit timeout are usually prefixed with 'wait',
# those methods ignore implicit_wait when looking up web elements.
# (integer value)
explicit_wait=300
[image]
# http accessible image (string value)
http_image=http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz
[identity]
# Username to use for non-admin API requests. (string value)
username=demo
# API key to use when authenticating. (string value)
password=secretadmin
# Administrative Username to use for admin API requests.
# (string value)
admin_username=admin
# API key to use when authenticating as admin. (string value)
admin_password=secretadmin
[scenario]
# ssh username for image file (string value)
ssh_user=cirros
[launch_instances]
#available zone to launch instances
available_zone=nova
#image_name to launch instances
image_name=cirros-0.3.4-x86_64-uec (24.0 MB)
[plugin]
is_plugin=True
plugin_page_path=neutron_lbaas_dashboard.tests.integration_tests.pages
plugin_page_structure={
"Project":
{
"Network":
{
"-":
[
"Load Balancers"
]
}
}
}

View File

@ -0,0 +1,22 @@
# 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 openstack_dashboard.test.integration_tests.pages import basepage
class LoadbalancersPage(basepage.BaseNavigationPage):
TABLE_IMAGE_COLUMN = 'name'
def __init__(self, driver, conf):
super(LoadbalancersPage, self).__init__(driver, conf)
self._page_title = "Load Balancers"

View File

@ -0,0 +1,27 @@
# 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 openstack_dashboard.test.integration_tests import helpers
class TestLoadbalancers(helpers.TestCase):
def setUp(self):
super(TestLoadbalancers, self).setUp()
self.home_pg.go_to_network_loadbalancerspage()
def test_loadbalancers(self):
self._save_screenshot(None)
# TODO(MRV): Place holder for tests
def tearDown(self):
super(TestLoadbalancers, self).tearDown()

View File

@ -0,0 +1,188 @@
#
# 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 = 'neutron_lbaas_dashboard.tests.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',
'neutron_lbaas_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': False,
'enable_firewall': False,
'enable_vpn': False
}
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']['neutron_lbaas_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'

View File

@ -0,0 +1,20 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from django.conf import urls
import openstack_dashboard.urls
urlpatterns = urls.patterns(
'',
urls.url(r'', urls.include(openstack_dashboard.urls))
)

View File

@ -6,12 +6,17 @@ hacking<0.11,>=0.10.0
http://tarballs.openstack.org/horizon/horizon-master.tar.gz#egg=horizon
coverage>=3.6 # Apache-2.0
ddt>=1.0.1 # MIT
discover # BSD
django-nose>=1.2 # BSD
python-subunit>=0.0.18 # Apache-2.0/BSD
nose-exclude # LGPL
selenium>=2.50.1 # Apache-2.0
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
testrepository>=0.0.18 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
testtools>=1.4.0 # MIT
# This also needs xvfb library installed on your OS
xvfbwrapper>=0.1.3 #license: MIT

View File

@ -0,0 +1,5 @@
#!/bin/bash
set -ex
export LBAAS_DASHBOARD_SCREENSHOTS_DIR=/opt/stack/new/neutron-lbaas-dashboard/.tox/py27integration/src/horizon/openstack_dashboard/test/integration_tests/integration_tests_screenshots

View File

@ -0,0 +1,17 @@
#!/bin/bash
# This script will be executed inside post_test_hook function in devstack gate
set -x
source commons $@
set +e
cd /opt/stack/new/neutron-lbaas-dashboard
sudo -H -u stack tox -e py27integration
retval=$?
set -e
if [ -d ${NEUTRON_LBAAS_DASHBOARD_SCREENSHOTS_DIR}/ ]; then
cp -r ${NEUTRON_LBAAS_DASHBOARD_SCREENSHOTS_DIR}/ /home/jenkins/workspace/gate-neutron-lbaas-dashboard-dsvm-integration/
fi
exit $retval

View File

@ -0,0 +1,28 @@
#!/bin/bash
# This script will be executed inside pre_test_hook function in devstack gate
set -ex
source commons $@
# Enable LBaaS V2 Neutron plugin
DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin neutron-lbaas https://git.openstack.org/openstack/neutron-lbaas"
ENABLED_SERVICES+=",q-lbaasv2"
DISABLED_SERVICES+="q-lbaas"
# Enable default recommended implementation for LBaaS v2, Octavia
ENABLED_SERVICES+=",octavia,o-cw,o-hk,o-hm,o-api"
DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin octavia https://git.openstack.org/openstack/octavia"
DEVSTACK_LOCAL_CONFIG+=$'\n'"[[post-config|/etc/octavia/octavia.conf]]"
DEVSTACK_LOCAL_CONFIG+=$'\n'"[controller_worker]"
DEVSTACK_LOCAL_CONFIG+=$'\n'"amphora_driver = amphora_noop_driver"
DEVSTACK_LOCAL_CONFIG+=$'\n'"compute_driver = compute_noop_driver"
DEVSTACK_LOCAL_CONFIG+=$'\n'"network_driver = network_noop_driver"
# Enable LBaaS v2 Horizon plugin
DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin neutron-lbaas-dashboard https://git.openstack.org/openstack/neutron-lbaas-dashboard"
export DEVSTACK_LOCAL_CONFIG
export ENABLED_SERVICES
export DISABLED_SERVICES

10
tox.ini
View File

@ -16,6 +16,7 @@ setenv =
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
whitelist_externals = /usr/bin/npm
/bin/bash
commands = python manage.py test
[testenv:pep8]
@ -24,6 +25,15 @@ commands = flake8
[testenv:venv]
commands = {posargs}
[testenv:py27integration]
basepython = python2.7
setenv =
INTEGRATION_TESTS=1
SELENIUM_HEADLESS=1
HORIZON_INTEGRATION_TESTS_CONFIG_FILE=neutron_lbaas_dashboard/tests/integration_tests/horizon.conf
DJANGO_SETTINGS_MODULE=neutron_lbaas_dashboard.tests.settings
commands = nosetests neutron_lbaas_dashboard/tests/integration_tests/tests {posargs}
[testenv:cover]
commands = python setup.py test --coverage --testr-args='{posargs}'