Add tacker-horizon integration test framework

This patch implements an integration framework and adds basic
test cases to verify whether tacker-horizon is installed and
could be opened.

The integration test suite "tacker-horizon-integration-tests"
is added as a gate job in non-voting mode.

Selenium exception details:
The tacker-horizon consists of panel groups "VNF Management"
and "NFV Orchestration".

The selenium reports an exception ElementNotInteractableException
while opening pages for panel group "NFV Orchestration".
This exception occurs when an element is not clickable or is not
visible yet.

By default, panel group "VNF Management" is expanded hence test
cases for pages under this panel group pass.
As per openstack-dashboard integration test case logic, the panel
group "NFV Orchestration" is never clicked hence requested pages
are not visible.

[1] comprises of modified openstack-dashboard integration test
logic to fix the above selenium exception.

[1] https://review.opendev.org/c/openstack/horizon/+/803465
Implements: blueprint tacker-horizon-integration-test

Change-Id: I6a09b945506450d9947afbd92dbab9a4a6c30de4
This commit is contained in:
Manpreet Kaur 2021-05-12 17:48:44 +05:30
parent 3618f21972
commit b952869e6b
26 changed files with 256 additions and 144 deletions

View File

@ -1,3 +1,26 @@
- job:
name: tacker-horizon-integration-tests
parent: horizon-integration-tests
required-projects:
- name: openstack/horizon
- name: openstack/tacker
- name: openstack/python-tackerclient
- name: openstack/tacker-horizon
roles:
- zuul: openstack-infra/devstack
- zuul: openstack/horizon
irrelevant-files:
- ^.*\.rst$
- ^doc/.*$
- ^releasenotes/.*$
vars:
devstack_plugins:
tacker: https://git.openstack.org/openstack/tacker
tacker-horizon: https://git.openstack.org/openstack/tacker-horizon
devstack_services:
horizon: true
tox_envlist: integration
- project:
templates:
- check-requirements
@ -5,3 +28,7 @@
- openstack-lower-constraints-jobs-horizon
- openstack-python3-wallaby-jobs-horizon
- publish-openstack-docs-pti
check:
jobs:
- tacker-horizon-integration-tests:
voting: false

7
bindep.txt Normal file
View File

@ -0,0 +1,7 @@
# selenium tests
ffmpeg [selenium]
firefox [selenium]
xvfb [selenium platform:dpkg]
# already part of xorg-x11-server on openSUSE
xorg-x11-server-Xvfb [selenium platform:redhat]

View File

@ -86,11 +86,13 @@ PyYAML==3.12
requests==2.25.1
requestsexceptions==1.4.0
rfc3986==1.1.0
selenium==2.50.1
semantic-version==2.3.1
simplejson==3.13.2
snowballstemmer==1.2.1
stevedore==3.3.0
termcolor==1.1.0
testtools==2.2.0
traceback2==1.4.0
unittest2==1.1.0
urllib3==1.22

View File

@ -1,21 +0,0 @@
# 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 import helpers as test
class NscatalogTests(test.TestCase):
# Unit tests for nscatalog.
def test_me(self):
self.assertTrue(1 + 1 == 2)

View File

@ -1,21 +0,0 @@
# 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 import helpers as test
class VnffgcatalogTests(test.TestCase):
# Unit tests for vnffgcatalog.
def test_me(self):
self.assertTrue(1 + 1 == 2)

View File

@ -1,21 +0,0 @@
# 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 import helpers as test
class VnfmanagerTests(test.TestCase):
# Unit tests for vnffgmanager.
def test_me(self):
self.assertTrue(1 + 1 == 2)

View File

@ -10,11 +10,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack_dashboard.test import helpers as test
import unittest
class NsmanagerTests(test.TestCase):
class TestCase(unittest.TestCase):
def test_me(self):
self.assertTrue(1 + 1 == 2)
"""Test case base class for all unit tests."""

View File

@ -0,0 +1,4 @@
[plugin]
is_plugin=True
plugin_page_path=tacker_horizon.test.integration.pages
plugin_page_structure='{"NFV": {"VNF Management": {"_": ["VNF Catalog", "VNF Manager"]}, "NFV Orchestration": {"_": ["VIM Management", "VNFFG Catalog", "VNFFG Manager", "NS Catalog", "NS Manager"]}}}'

View File

@ -1,4 +1,3 @@
# Copyright 2015 Brocade Communications System, 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
@ -12,12 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack_dashboard.test import helpers as test
from openstack_dashboard.test.integration_tests.pages import basepage
class VnfmanagerTests(test.TestCase):
# Unit tests for vnfmanager.
def test_me(self):
self.assertTrue(1 + 1 == 2)
class NscatalogPage(basepage.BaseNavigationPage):
def __init__(self, driver, conf):
super(NscatalogPage, self).__init__(driver, conf)
self._page_title = "NS Catalog"

View File

@ -1,4 +1,3 @@
# Copyright 2016 Brocade Communications System, 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
@ -12,12 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack_dashboard.test import helpers as test
from openstack_dashboard.test.integration_tests.pages import basepage
class VimmanagerTests(test.TestCase):
# Unit tests for vimmanager.
def test_me(self):
self.assertTrue(1 + 1 == 2)
class NsmanagerPage(basepage.BaseNavigationPage):
def __init__(self, driver, conf):
super(NsmanagerPage, self).__init__(driver, conf)
self._page_title = "NS Manager"

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 openstack_dashboard.test.integration_tests.pages import basepage
class VimmanagementPage(basepage.BaseNavigationPage):
def __init__(self, driver, conf):
super(VimmanagementPage, self).__init__(driver, conf)
self._page_title = "VIM Management"

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 openstack_dashboard.test.integration_tests.pages import basepage
class VnffgcatalogPage(basepage.BaseNavigationPage):
def __init__(self, driver, conf):
super(VnffgcatalogPage, self).__init__(driver, conf)
self._page_title = "VNFFG Catalog"

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 openstack_dashboard.test.integration_tests.pages import basepage
class VnffgmanagerPage(basepage.BaseNavigationPage):
def __init__(self, driver, conf):
super(VnffgmanagerPage, self).__init__(driver, conf)
self._page_title = "VNFFG Manager"

View File

@ -1,4 +1,3 @@
# Copyright 2015 Brocade Communications System, 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
@ -12,12 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack_dashboard.test import helpers as test
from openstack_dashboard.test.integration_tests.pages import basepage
class VnfcatalogTests(test.TestCase):
# Unit tests for vnfcatalog.
def test_me(self):
self.assertTrue(1 + 1 == 2)
class VnfcatalogPage(basepage.BaseNavigationPage):
def __init__(self, driver, conf):
super(VnfcatalogPage, self).__init__(driver, conf)
self._page_title = "VNF Catalog"

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 openstack_dashboard.test.integration_tests.pages import basepage
class VnfmanagerPage(basepage.BaseNavigationPage):
def __init__(self, driver, conf):
super(VnfmanagerPage, self).__init__(driver, conf)
self._page_title = "VNF Manager"

View File

@ -0,0 +1,55 @@
#
# 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 TestTackerDashboardInstalled(helpers.TestCase):
def test_vnf_catalog_page_opened(self):
vnf_catalog = self.home_pg.go_to_nfv_vnfmanagement_vnfcatalogpage()
self.assertEqual(vnf_catalog.page_title,
'VNF Catalog - OpenStack Dashboard')
def test_vnf_manager_page_opened(self):
vnf_manager = self.home_pg.go_to_nfv_vnfmanagement_vnfmanagerpage()
self.assertEqual(vnf_manager.page_title,
'VNF Manager - OpenStack Dashboard')
def test_vim_page_opened(self):
vim = self.home_pg.go_to_nfv_nfvorchestration_vimmanagementpage()
self.assertEqual(vim.page_title,
'VIM - OpenStack Dashboard')
def test_vnffg_catalog_page_opened(self):
vnffg_catalog = (
self.home_pg.go_to_nfv_nfvorchestration_vnffgcatalogpage())
self.assertEqual(vnffg_catalog.page_title,
'VNFFG Catalog - OpenStack Dashboard')
def test_vnffg_manager_page_opened(self):
vnffg_manager = (
self.home_pg.go_to_nfv_nfvorchestration_vnffgmanagerpage())
self.assertEqual(vnffg_manager.page_title,
'VNFFG Manager - OpenStack Dashboard')
def test_ns_catalog_page_opened(self):
ns_catalog = self.home_pg.go_to_nfv_nfvorchestration_nscatalogpage()
self.assertEqual(ns_catalog.page_title,
'NS Catalog - OpenStack Dashboard')
def test_ns_manager_page_opened(self):
ns_manager = self.home_pg.go_to_nfv_nfvorchestration_nsmanagerpage()
self.assertEqual(ns_manager.page_title,
'NS Manager - OpenStack Dashboard')

View File

@ -12,58 +12,29 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
# Default to Horizons test settings to avoid any missing keys
from horizon.test.settings import * # noqa
from horizon.utils import secret_key as secret_key_utils
from openstack_dashboard.test.settings import * # noqa
import openstack_dashboard.enabled # noqa: F811
from openstack_dashboard.test.settings import * # noqa: F403,H303
from openstack_dashboard.utils import settings
DEBUG = True
import tacker_horizon.enabled
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, ".."))
# pop these keys to avoid log warnings about deprecation
# update_dashboards will populate them anyway
HORIZON_CONFIG.pop('dashboards', None) # noqa: F405
HORIZON_CONFIG.pop('default_dashboard', None) # noqa: F405
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_utils.generate_or_read_from_file(
os.path.join(TEST_DIR, '.secret_key_store'))
ROOT_URLCONF = 'tacker_horizon.test.urls'
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.staticfiles',
'django.contrib.messages',
'django.contrib.humanize',
'openstack_auth',
'compressor',
'horizon',
'openstack_dashboard',
'tacker_horizon',
# Update the dashboards with nfv dashboard enabled files
# and current INSTALLED_APPS
settings.update_dashboards(
[
openstack_dashboard.enabled,
tacker_horizon.enabled,
],
HORIZON_CONFIG, # noqa: F405
INSTALLED_APPS # noqa: F405
)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(TEST_DIR, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
'debug': DEBUG,
},
},
]
# Remove duplicated apps
INSTALLED_APPS = list(set(INSTALLED_APPS)) # noqa: F405

View File

@ -11,5 +11,8 @@ hacking>=4.0.0,<4.1.0 # Apache-2.0
#
coverage!=4.4,>=4.0 # Apache-2.0
nodeenv>=0.9.4 # BSD
# Horizon integration tests requirements
selenium>=2.50.1 # Apache-2.0
testtools>=2.2.0 # MIT
# This also needs xvfb library installed on your OS
xvfbwrapper>=0.1.3 #license: MIT

View File

@ -0,0 +1 @@
./manage.py

17
tools/find_executables.sh Normal file
View File

@ -0,0 +1,17 @@
#!/bin/bash
#
# This shell script helps in finding executable files, as by default Nose
# plugin ignores executable files. All the executable files need to be added
# in tools/executable_files.txt.
OUTPUT=`find . \( -name .tox -o -name .git \) -prune -o -type f -perm /a=x -print \
| grep -v -F -f ./tools/executable_files.txt`
if [ -n "$OUTPUT" ]; then
echo "Unexpected executable files are found:"
for f in $OUTPUT; do
echo $f
done
echo
echo "If you really need to add an executable file, add it to tools/executable_files.txt"
exit 1
fi

25
tox.ini
View File

@ -1,5 +1,5 @@
[tox]
envlist = py38,pep8,docs
envlist = py39,py38,py36,pep8,docs
minversion = 3.18.0
skipsdist = True
ignore_basepython_conflict = True
@ -15,12 +15,31 @@ deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
{envpython} {toxinidir}/manage.py test tacker_horizon --settings=tacker_horizon.test.settings {posargs}
{envpython} {toxinidir}/manage.py test tacker_horizon --settings=tacker_horizon.test.settings --exclude-tag integration {posargs}
[testenv:integration]
# Run integration tests only
passenv =
DISPLAY
FFMPEG_INSTALLED
setenv =
PYTHONHASHSEED=0
FFMPEG_INSTALLED=True
INTEGRATION_TESTS=1
SELENIUM_HEADLESS=False
HORIZON_INTEGRATION_TESTS_CONFIG_FILE=tacker_horizon/test/integration/horizon.conf
basepython = python3
commands = {envpython} {toxinidir}/manage.py test tacker_horizon --settings=tacker_horizon.test.settings --tag integration {posargs}
[testenv:py36]
basepython = python3.6
commands =
{envpython} {toxinidir}/manage.py test tacker_horizon --settings=tacker_horizon.test.settings {posargs}
{envpython} {toxinidir}/manage.py test tacker_horizon --settings=tacker_horizon.test.settings --exclude-tag integration {posargs}
[testenv:py39]
basepython = python3.9
commands =
{envpython} {toxinidir}/manage.py test tacker_horizon --settings=tacker_horizon.test.settings --exclude-tag integration {posargs}
[testenv:pep8]
basepython = python3