From 2a7b111307e43f07b44e5d2414aa05fc36468136 Mon Sep 17 00:00:00 2001
From: Ivan Kolodyazhny <e0ne@e0ne.info>
Date: Fri, 1 Feb 2019 22:19:01 +0200
Subject: [PATCH] Add vitrage-dashboard integration tests

This patch adds basic tests to verify that vitrage-dashboard is
installed and could be opened.

Also it removes oslotest which is not used.

vitrage-dashboard-integration-tests job is added in a non-voting mode.

Change-Id: I03c6a28014a73605b72441a0241e1dc1cd3f908c
---
 .zuul.yaml                                    | 25 ++++++++++++
 bindep.txt                                    |  6 +++
 manage.py                                     | 23 +++++++++++
 test-requirements.txt                         |  5 ++-
 tools/executable_files.txt                    |  1 +
 tools/find_executables.sh                     |  3 +-
 tox.ini                                       | 20 +++++++---
 vitrage_dashboard/dashboard/tests/base.py     |  4 +-
 .../dashboard/tests/integration/__init__.py   |  0
 .../dashboard/tests/integration/horizon.conf  |  4 ++
 .../tests/integration/pages/__init__.py       |  0
 .../integration/pages/project/__init__.py     |  0
 .../pages/project/vitrage/__init__.py         |  0
 .../pages/project/vitrage/alarmspage.py       | 21 ++++++++++
 .../pages/project/vitrage/entitygraphpage.py  | 21 ++++++++++
 .../pages/project/vitrage/templatespage.py    | 21 ++++++++++
 .../pages/project/vitrage/topologypage.py     | 21 ++++++++++
 .../dashboard/tests/integration/test_basic.py | 35 +++++++++++++++++
 vitrage_dashboard/dashboard/tests/settings.py | 39 +++++++++++++++++++
 vitrage_dashboard/enabled/__init__.py         |  0
 20 files changed, 239 insertions(+), 10 deletions(-)
 create mode 100644 bindep.txt
 create mode 100755 manage.py
 create mode 100644 tools/executable_files.txt
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/__init__.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/horizon.conf
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/pages/__init__.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/pages/project/__init__.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/__init__.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/alarmspage.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/entitygraphpage.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/templatespage.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/topologypage.py
 create mode 100644 vitrage_dashboard/dashboard/tests/integration/test_basic.py
 create mode 100644 vitrage_dashboard/dashboard/tests/settings.py
 create mode 100644 vitrage_dashboard/enabled/__init__.py

diff --git a/.zuul.yaml b/.zuul.yaml
index 6b9468e..9fa6ba6 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -1,3 +1,26 @@
+- job:
+    name: vitrage-dashboard-integration-tests
+    parent: horizon-integration-tests
+    required-projects:
+      - name: openstack/horizon
+      - name: openstack/vitrage
+      - name: openstack/python-vitrageclient
+      - name: openstack/vitrage-dashboard
+    roles:
+      - zuul: openstack-infra/devstack
+      - zuul: openstack/horizon
+    irrelevant-files:
+      - ^.*\.rst$
+      - ^doc/.*$
+      - ^releasenotes/.*$
+    vars:
+      devstack_plugins:
+        vitrage: https://git.openstack.org/openstack/vitrage
+        vitrage-dashboard: https://git.openstack.org/openstack/vitrage-dashboard
+      devstack_services:
+        horizon: true
+      tox_envlist: integration
+
 - project:
     templates:
       - openstack-python-jobs-horizon
@@ -15,4 +38,6 @@
             vars:
               node_version: 4
             voting: false
+        - vitrage-dashboard-integration-tests:
+            voting: false
 
diff --git a/bindep.txt b/bindep.txt
new file mode 100644
index 0000000..144e285
--- /dev/null
+++ b/bindep.txt
@@ -0,0 +1,6 @@
+# selenium tests
+firefox [selenium]
+xvfb [selenium platform:dpkg]
+# already part of xorg-x11-server on openSUSE
+xorg-x11-server-Xvfb [selenium platform:redhat]
+
diff --git a/manage.py b/manage.py
new file mode 100755
index 0000000..3739a22
--- /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",
+                          "vitrage_dashboard.dashboard.tests.settings")
+    execute_from_command_line(sys.argv)
diff --git a/test-requirements.txt b/test-requirements.txt
index e8b563b..920874c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -9,8 +9,11 @@ python-subunit>=0.0.18
 sphinx>=1.6.2 # BSD
 nodeenv>=0.9.4 # BSD
 openstackdocstheme>=1.24.0 # Apache-2.0
-oslotest>=1.10.0 # Apache-2.0
 testrepository>=0.0.18
 testscenarios>=0.4
 testtools>=1.4.0
 reno>=1.8.0 # Apache-2.0
+
+# integration tests requirements
+selenium>=2.50.1 # Apache-2.0
+xvfbwrapper>=0.1.3 #license: MIT
diff --git a/tools/executable_files.txt b/tools/executable_files.txt
new file mode 100644
index 0000000..32a891a
--- /dev/null
+++ b/tools/executable_files.txt
@@ -0,0 +1 @@
+./manage.py
diff --git a/tools/find_executables.sh b/tools/find_executables.sh
index a0700cd..5a2f2f0 100644
--- a/tools/find_executables.sh
+++ b/tools/find_executables.sh
@@ -1,4 +1,5 @@
-OUTPUT=`find . \( -name .tox -o -name .git \) -prune -o -type f -perm /a=x -print`
+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
diff --git a/tox.ini b/tox.ini
index 39ba330..370d49f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,12 +8,24 @@ usedevelop = True
 install_command = pip install -U {opts} {packages}
 setenv =
    VIRTUAL_ENV={envdir}
+   PYTHONUNBUFFERED = 1
 deps =
    -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
    -r{toxinidir}/test-requirements.txt
    -r{toxinidir}/requirements.txt
-commands = /bin/rm -f .testrepository/times.dbm
-           python setup.py test --slowest --testr-args='{posargs}'
+commands = {envpython} {toxinidir}/manage.py test vitrage_dashboard {posargs} --exclude-tag integration {posargs}
+
+[testenv:integration]
+# Run integration tests only
+passenv = AVCONV_INSTALLED
+setenv =
+  PYTHONHASHSEED=0
+  INTEGRATION_TESTS=1
+  SELENIUM_HEADLESS=1
+  HORIZON_INTEGRATION_TESTS_CONFIG_FILE=vitrage_dashboard/dashboard/tests/integration/horizon.conf
+basepython = python2.7
+commands = {envpython} {toxinidir}/manage.py test vitrage_dashboard --tag integration {posargs}
+
 
 [testenv:pep8]
 basepython = python3
@@ -49,10 +61,6 @@ commands = python setup.py test --coverage --testr-args='{posargs}'
 basepython = python3
 commands = python setup.py build_sphinx
 
-[testenv:debug]
-basepython = python3
-commands = oslo_debug_helper {posargs}
-
 [flake8]
 # E123, E125 skipped as they are invalid PEP-8.
 
diff --git a/vitrage_dashboard/dashboard/tests/base.py b/vitrage_dashboard/dashboard/tests/base.py
index 2159808..7e8cde6 100644
--- a/vitrage_dashboard/dashboard/tests/base.py
+++ b/vitrage_dashboard/dashboard/tests/base.py
@@ -13,9 +13,9 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-from oslotest import base
+import unittest
 
 
-class TestCase(base.BaseTestCase):
+class TestCase(unittest.TestCase):
 
     """Test case base class for all unit tests."""
diff --git a/vitrage_dashboard/dashboard/tests/integration/__init__.py b/vitrage_dashboard/dashboard/tests/integration/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/vitrage_dashboard/dashboard/tests/integration/horizon.conf b/vitrage_dashboard/dashboard/tests/integration/horizon.conf
new file mode 100644
index 0000000..2506e89
--- /dev/null
+++ b/vitrage_dashboard/dashboard/tests/integration/horizon.conf
@@ -0,0 +1,4 @@
+[plugin]
+is_plugin=True
+plugin_page_path=vitrage_dashboard.dashboard.tests.integration.pages
+plugin_page_structure='{"Project": {"Vitrage": {"_": ["Topology", "Alarms", "Entity Graph", "Templates"]}}}'
diff --git a/vitrage_dashboard/dashboard/tests/integration/pages/__init__.py b/vitrage_dashboard/dashboard/tests/integration/pages/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/vitrage_dashboard/dashboard/tests/integration/pages/project/__init__.py b/vitrage_dashboard/dashboard/tests/integration/pages/project/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/__init__.py b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/alarmspage.py b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/alarmspage.py
new file mode 100644
index 0000000..c62953d
--- /dev/null
+++ b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/alarmspage.py
@@ -0,0 +1,21 @@
+#
+#    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 AlarmsPage(basepage.BaseNavigationPage):
+    def __init__(self, driver, conf):
+        super(AlarmsPage, self).__init__(driver, conf)
+        self._page_title = "Alarms Analysis"
diff --git a/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/entitygraphpage.py b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/entitygraphpage.py
new file mode 100644
index 0000000..d9ede0c
--- /dev/null
+++ b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/entitygraphpage.py
@@ -0,0 +1,21 @@
+#
+#    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 EntitygraphPage(basepage.BaseNavigationPage):
+    def __init__(self, driver, conf):
+        super(EntitygraphPage, self).__init__(driver, conf)
+        self._page_title = "Entity Graph"
diff --git a/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/templatespage.py b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/templatespage.py
new file mode 100644
index 0000000..88250ed
--- /dev/null
+++ b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/templatespage.py
@@ -0,0 +1,21 @@
+#
+#    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 TemplatesPage(basepage.BaseNavigationPage):
+    def __init__(self, driver, conf):
+        super(TemplatesPage, self).__init__(driver, conf)
+        self._page_title = "Templates List"
diff --git a/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/topologypage.py b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/topologypage.py
new file mode 100644
index 0000000..0ba729f
--- /dev/null
+++ b/vitrage_dashboard/dashboard/tests/integration/pages/project/vitrage/topologypage.py
@@ -0,0 +1,21 @@
+#
+#    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 TopologyPage(basepage.BaseNavigationPage):
+    def __init__(self, driver, conf):
+        super(TopologyPage, self).__init__(driver, conf)
+        self._page_title = "Topology"
diff --git a/vitrage_dashboard/dashboard/tests/integration/test_basic.py b/vitrage_dashboard/dashboard/tests/integration/test_basic.py
new file mode 100644
index 0000000..cbbe0e0
--- /dev/null
+++ b/vitrage_dashboard/dashboard/tests/integration/test_basic.py
@@ -0,0 +1,35 @@
+#
+#    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 TestVitrageDashboardInstalled(helpers.TestCase):
+    # TODO(e0ne): investigate issue with Network Topology confilct
+    # and implement test
+
+    def test_alarms_page_opened(self):
+        alarms_page = self.home_pg.go_to_project_vitrage_alarmspage()
+        self.assertEqual(alarms_page.page_title,
+                         'Alarms Analysis - OpenStack Dashboard')
+
+    def test_entity_graph_page_opened(self):
+        egraph_page = self.home_pg.go_to_project_vitrage_entitygraphpage()
+        self.assertEqual(egraph_page.page_title,
+                         'Entity Graph - OpenStack Dashboard')
+
+    def test_templates_page_opened(self):
+        templates_page = self.home_pg.go_to_project_vitrage_templatespage()
+        self.assertEqual(templates_page.page_title,
+                         'Templates List - OpenStack Dashboard')
diff --git a/vitrage_dashboard/dashboard/tests/settings.py b/vitrage_dashboard/dashboard/tests/settings.py
new file mode 100644
index 0000000..c5f5cd5
--- /dev/null
+++ b/vitrage_dashboard/dashboard/tests/settings.py
@@ -0,0 +1,39 @@
+#
+#    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.
+
+# Default to Horizons test settings to avoid any missing keys
+
+import openstack_dashboard.enabled  # noqa: F811
+from openstack_dashboard.test.settings import *  # noqa: F403,H303
+from openstack_dashboard.utils import settings
+
+import vitrage_dashboard.enabled
+
+# 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
+
+# Update the dashboards with heat_dashboard enabled files
+# and current INSTALLED_APPS
+settings.update_dashboards(
+    [
+        openstack_dashboard.enabled,
+        vitrage_dashboard.enabled,
+    ],
+    HORIZON_CONFIG,  # noqa: F405
+    INSTALLED_APPS  # noqa: F405
+)
+
+# Remove duplicated apps
+INSTALLED_APPS = list(set(INSTALLED_APPS))  # noqa: F405
diff --git a/vitrage_dashboard/enabled/__init__.py b/vitrage_dashboard/enabled/__init__.py
new file mode 100644
index 0000000..e69de29