From 559e05b0e8d1aa15771f0d7d02d60febad80fa56 Mon Sep 17 00:00:00 2001 From: Luis Daniel Castellanos Date: Fri, 12 Aug 2016 17:17:45 -0500 Subject: [PATCH] [WIP] Added code base for unit testing and code refactoring Added code base to write unit tests and refactored the solution code/structure, Also deleted files not needed for first version --- AUTHORS | 2 + ChangeLog | 6 + .../craton_tests.py | 17 +- craton_dashboard/api/craton.py | 9 +- .../{dashboards => content}/__init__.py | 0 .../fleet_management}/__init__.py | 0 .../fleet_management/inventory}/__init__.py | 0 .../fleet_management}/inventory/panel.py | 0 .../templates/fleet.inventory}/index.html | 4 +- .../fleet_management}/inventory/urls.py | 2 +- .../fleet_management}/inventory/views.py | 0 .../fleet_management/taskflows}/__init__.py | 0 .../fleet_management}/taskflows/panel.py | 0 .../templates/fleet.taskflows}/index.html | 4 +- .../fleet_management}/taskflows/urls.py | 2 +- .../fleet_management}/taskflows/views.py | 0 craton_dashboard/dashboards/__init__.pyc | Bin 109 -> 0 bytes .../dashboards/project/__init__.pyc | Bin 117 -> 0 bytes .../dashboards/project/fleet/__init__.pyc | Bin 123 -> 0 bytes .../dashboards/project/fleet/alerts/panel.py | 21 - .../dashboards/project/fleet/alerts/urls.py | 8 - .../dashboards/project/fleet/alerts/views.py | 25 - .../dashboards/project/fleet/auditor/panel.py | 21 - .../templates/fleet.auditor/index.html | 12 - .../dashboards/project/fleet/auditor/urls.py | 8 - .../dashboards/project/fleet/auditor/views.py | 25 - .../dashboards/project/fleet/panel.py | 21 - .../dashboards/project/fleet/panel.pyc | Bin 497 -> 0 bytes .../templates/fleet.reporting/index.html | 12 - .../project/fleet/reporting/urls.py | 8 - .../project/fleet/reporting/views.py | 25 - .../project/fleet/taskflows/__init__.py | 0 .../templates/fleet.taskflows/index.html | 12 - .../fleet/templates/regions/index.html | 12 - .../dashboards/project/fleet/urls.py | 8 - ...anel.py => _1720_fleet_taskflows_panel.py} | 6 +- ...anel.py => _1730_fleet_inventory_panel.py} | 2 +- .../enabled/_1760_fleet_reporting_panel.py | 25 - .../craton/alerts/alerts.controller.js | 0 .../project/craton/alerts/index.html | 4 - .../craton/auditor/auditor.controller.js | 0 .../project/craton/auditor/index.html | 5 - .../dashboard/project/craton/fleet.scss | 0 .../project/craton/regions/index.html | 5 - .../project/craton/reporting/index.html | 4 - .../craton/reporting/reporting.controller.js | 0 .../fleet_management/fleet_management.scss} | 0 .../fleet_managment.module.js} | 8 +- .../inventory/index.html | 2 +- .../inventory/inventory.controller.js | 0 .../taskflows/index.html | 2 +- .../taskflows/taskflows.controller.js | 0 .../fleet/inventory => test}/__init__.py | 0 .../test/api_tests/craton_tests.py | 29 + craton_dashboard/test/helpers.py | 61 ++ .../reporting/panel.py => test/settings.py} | 12 +- .../reporting => test/test_data}/__init__.py | 0 .../test/test_data/craton_data.py | 45 ++ .../test_data/keystone_data.py} | 25 +- craton_dashboard/test/test_data/utils.py | 52 ++ .../urls.py} | 15 +- craton_dashboard/tests/__init__.py | 0 craton_dashboard/tests/test_dummy.py | 7 - .../project/fleet/views.py => manage.py | 18 +- requirements.txt | 17 + run_test.sh | 553 ++++++++++++++++++ setup.cfg | 3 + test-requirements.txt | 11 + tools/install_venv.py | 159 +++++ tools/pip_install.sh | 71 +++ tools/with_venv.sh | 7 + 71 files changed, 1084 insertions(+), 328 deletions(-) rename craton_dashboard/enabled/_1750_fleet_auditor_panel.py => api_tests/craton_tests.py (53%) rename craton_dashboard/{dashboards => content}/__init__.py (100%) rename craton_dashboard/{dashboards/project/fleet => content/fleet_management}/__init__.py (100%) rename craton_dashboard/{dashboards/project => content/fleet_management/inventory}/__init__.py (100%) rename craton_dashboard/{dashboards/project/fleet => content/fleet_management}/inventory/panel.py (100%) rename craton_dashboard/{dashboards/project/fleet/alerts/templates/fleet.alerts => content/fleet_management/inventory/templates/fleet.inventory}/index.html (67%) rename craton_dashboard/{dashboards/project/fleet => content/fleet_management}/inventory/urls.py (64%) rename craton_dashboard/{dashboards/project/fleet => content/fleet_management}/inventory/views.py (100%) rename craton_dashboard/{dashboards/project/fleet/alerts => content/fleet_management/taskflows}/__init__.py (100%) rename craton_dashboard/{dashboards/project/fleet => content/fleet_management}/taskflows/panel.py (100%) rename craton_dashboard/{dashboards/project/fleet/inventory/templates/fleet.inventory => content/fleet_management/taskflows/templates/fleet.taskflows}/index.html (67%) rename craton_dashboard/{dashboards/project/fleet => content/fleet_management}/taskflows/urls.py (64%) rename craton_dashboard/{dashboards/project/fleet => content/fleet_management}/taskflows/views.py (100%) delete mode 100644 craton_dashboard/dashboards/__init__.pyc delete mode 100644 craton_dashboard/dashboards/project/__init__.pyc delete mode 100644 craton_dashboard/dashboards/project/fleet/__init__.pyc delete mode 100644 craton_dashboard/dashboards/project/fleet/alerts/panel.py delete mode 100644 craton_dashboard/dashboards/project/fleet/alerts/urls.py delete mode 100644 craton_dashboard/dashboards/project/fleet/alerts/views.py delete mode 100644 craton_dashboard/dashboards/project/fleet/auditor/panel.py delete mode 100644 craton_dashboard/dashboards/project/fleet/auditor/templates/fleet.auditor/index.html delete mode 100644 craton_dashboard/dashboards/project/fleet/auditor/urls.py delete mode 100644 craton_dashboard/dashboards/project/fleet/auditor/views.py delete mode 100644 craton_dashboard/dashboards/project/fleet/panel.py delete mode 100644 craton_dashboard/dashboards/project/fleet/panel.pyc delete mode 100644 craton_dashboard/dashboards/project/fleet/reporting/templates/fleet.reporting/index.html delete mode 100644 craton_dashboard/dashboards/project/fleet/reporting/urls.py delete mode 100644 craton_dashboard/dashboards/project/fleet/reporting/views.py delete mode 100644 craton_dashboard/dashboards/project/fleet/taskflows/__init__.py delete mode 100644 craton_dashboard/dashboards/project/fleet/taskflows/templates/fleet.taskflows/index.html delete mode 100644 craton_dashboard/dashboards/project/fleet/templates/regions/index.html delete mode 100644 craton_dashboard/dashboards/project/fleet/urls.py rename craton_dashboard/enabled/{_1730_fleet_taskflows_panel.py => _1720_fleet_taskflows_panel.py} (78%) rename craton_dashboard/enabled/{_1770_fleet_inventory_panel.py => _1730_fleet_inventory_panel.py} (92%) delete mode 100644 craton_dashboard/enabled/_1760_fleet_reporting_panel.py delete mode 100644 craton_dashboard/static/dashboard/project/craton/alerts/alerts.controller.js delete mode 100644 craton_dashboard/static/dashboard/project/craton/alerts/index.html delete mode 100644 craton_dashboard/static/dashboard/project/craton/auditor/auditor.controller.js delete mode 100644 craton_dashboard/static/dashboard/project/craton/auditor/index.html delete mode 100644 craton_dashboard/static/dashboard/project/craton/fleet.scss delete mode 100644 craton_dashboard/static/dashboard/project/craton/regions/index.html delete mode 100644 craton_dashboard/static/dashboard/project/craton/reporting/index.html delete mode 100644 craton_dashboard/static/dashboard/project/craton/reporting/reporting.controller.js rename craton_dashboard/{dashboards/project/fleet/auditor/__init__.py => static/dashboard/project/fleet_management/fleet_management.scss} (100%) rename craton_dashboard/static/dashboard/project/{craton/fleet.js => fleet_management/fleet_managment.module.js} (90%) rename craton_dashboard/static/dashboard/project/{craton => fleet_management}/inventory/index.html (77%) rename craton_dashboard/static/dashboard/project/{craton => fleet_management}/inventory/inventory.controller.js (100%) rename craton_dashboard/static/dashboard/project/{craton => fleet_management}/taskflows/index.html (78%) rename craton_dashboard/static/dashboard/project/{craton => fleet_management}/taskflows/taskflows.controller.js (100%) rename craton_dashboard/{dashboards/project/fleet/inventory => test}/__init__.py (100%) create mode 100644 craton_dashboard/test/api_tests/craton_tests.py create mode 100644 craton_dashboard/test/helpers.py rename craton_dashboard/{dashboards/project/fleet/reporting/panel.py => test/settings.py} (71%) rename craton_dashboard/{dashboards/project/fleet/reporting => test/test_data}/__init__.py (100%) create mode 100644 craton_dashboard/test/test_data/craton_data.py rename craton_dashboard/{enabled/_1720_fleet_regions_panel.py => test/test_data/keystone_data.py} (55%) create mode 100644 craton_dashboard/test/test_data/utils.py rename craton_dashboard/{enabled/_1740_fleet_alerts_panel.py => test/urls.py} (68%) delete mode 100644 craton_dashboard/tests/__init__.py delete mode 100644 craton_dashboard/tests/test_dummy.py rename craton_dashboard/dashboards/project/fleet/views.py => manage.py (65%) mode change 100644 => 100755 create mode 100755 run_test.sh create mode 100644 tools/install_venv.py create mode 100755 tools/pip_install.sh create mode 100755 tools/with_venv.sh diff --git a/AUTHORS b/AUTHORS index cf17014..5975b3e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,4 @@ +Chris Spencer Eddie Ramirez Eddie Ramirez +Luis Daniel Castellanos diff --git a/ChangeLog b/ChangeLog index 7fc6330..f041bff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ CHANGES ======= +* [WIP] Added code base for unit testing and code refactoring +* Added some files and stuff +* dummy test +* added test +* Added travis conf file +* Updated enable files and install instructions * Added base methods and classes for API * Added base .gitignore * Added regions panel diff --git a/craton_dashboard/enabled/_1750_fleet_auditor_panel.py b/api_tests/craton_tests.py similarity index 53% rename from craton_dashboard/enabled/_1750_fleet_auditor_panel.py rename to api_tests/craton_tests.py index 08c968d..51fc3e0 100644 --- a/craton_dashboard/enabled/_1750_fleet_auditor_panel.py +++ b/api_tests/craton_tests.py @@ -12,13 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -from django.utils.translation import ugettext_lazy as _ +from craton_dashboard import api +from craton_dashboard.test import helpers as test -PANEL = 'fleet.auditor' -PANEL_DASHBOARD = 'project' +class CratonApiTests(test.CratonAPITestCase): -PANEL_GROUP = 'fleet_management' - -ADD_PANEL = 'craton_dashboard.dashboards.project.fleet.auditor.panel.Auditor' + def test_regions_list(self): + regions = self.craton_regions.list() + cratonclient = self.stub_cratonclient() + cratonclient.regions = self.mox.CreateMockAnything() + cratonclient.regions.list().AndReturn(regions) + self.mox.ReplayAll() + result = api.craton.region_list(self.request) + self.assertEqual(len(regions), len(result)) diff --git a/craton_dashboard/api/craton.py b/craton_dashboard/api/craton.py index cec1a82..f18120a 100644 --- a/craton_dashboard/api/craton.py +++ b/craton_dashboard/api/craton.py @@ -14,12 +14,16 @@ from six.moves.urllib import request from django.conf import settings +from cratonclient.v1 import client as craton_client from horizon import exceptions from openstack_dashboard.api import base + def cratonclient(): - pass + url = base.url_for(request, 'craton') + c = craton_client.Client(session=request.session, url=url) + return c def project_create(request, **kwargs): pass @@ -42,8 +46,9 @@ def region_create(request, **kwargs): def region_delete(request, **kwargs): pass + def region_list(request, **kwargs): - pass + return cratonclient(request).regions.list(**kwargs) def region_show(request, **kwargs): pass diff --git a/craton_dashboard/dashboards/__init__.py b/craton_dashboard/content/__init__.py similarity index 100% rename from craton_dashboard/dashboards/__init__.py rename to craton_dashboard/content/__init__.py diff --git a/craton_dashboard/dashboards/project/fleet/__init__.py b/craton_dashboard/content/fleet_management/__init__.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/__init__.py rename to craton_dashboard/content/fleet_management/__init__.py diff --git a/craton_dashboard/dashboards/project/__init__.py b/craton_dashboard/content/fleet_management/inventory/__init__.py similarity index 100% rename from craton_dashboard/dashboards/project/__init__.py rename to craton_dashboard/content/fleet_management/inventory/__init__.py diff --git a/craton_dashboard/dashboards/project/fleet/inventory/panel.py b/craton_dashboard/content/fleet_management/inventory/panel.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/inventory/panel.py rename to craton_dashboard/content/fleet_management/inventory/panel.py diff --git a/craton_dashboard/dashboards/project/fleet/alerts/templates/fleet.alerts/index.html b/craton_dashboard/content/fleet_management/inventory/templates/fleet.inventory/index.html similarity index 67% rename from craton_dashboard/dashboards/project/fleet/alerts/templates/fleet.alerts/index.html rename to craton_dashboard/content/fleet_management/inventory/templates/fleet.inventory/index.html index 3a1a5b0..1db8d86 100644 --- a/craton_dashboard/dashboards/project/fleet/alerts/templates/fleet.alerts/index.html +++ b/craton_dashboard/content/fleet_management/inventory/templates/fleet.inventory/index.html @@ -8,5 +8,7 @@ {% endblock %} {% block main %} -
+ + {% endblock %} diff --git a/craton_dashboard/dashboards/project/fleet/inventory/urls.py b/craton_dashboard/content/fleet_management/inventory/urls.py similarity index 64% rename from craton_dashboard/dashboards/project/fleet/inventory/urls.py rename to craton_dashboard/content/fleet_management/inventory/urls.py index 71c5db6..d0e6905 100644 --- a/craton_dashboard/dashboards/project/fleet/inventory/urls.py +++ b/craton_dashboard/content/fleet_management/inventory/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import url -from craton_dashboard.dashboards.project.fleet.inventory import views +from craton_dashboard.content.fleet_management.inventory import views urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), diff --git a/craton_dashboard/dashboards/project/fleet/inventory/views.py b/craton_dashboard/content/fleet_management/inventory/views.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/inventory/views.py rename to craton_dashboard/content/fleet_management/inventory/views.py diff --git a/craton_dashboard/dashboards/project/fleet/alerts/__init__.py b/craton_dashboard/content/fleet_management/taskflows/__init__.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/alerts/__init__.py rename to craton_dashboard/content/fleet_management/taskflows/__init__.py diff --git a/craton_dashboard/dashboards/project/fleet/taskflows/panel.py b/craton_dashboard/content/fleet_management/taskflows/panel.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/taskflows/panel.py rename to craton_dashboard/content/fleet_management/taskflows/panel.py diff --git a/craton_dashboard/dashboards/project/fleet/inventory/templates/fleet.inventory/index.html b/craton_dashboard/content/fleet_management/taskflows/templates/fleet.taskflows/index.html similarity index 67% rename from craton_dashboard/dashboards/project/fleet/inventory/templates/fleet.inventory/index.html rename to craton_dashboard/content/fleet_management/taskflows/templates/fleet.taskflows/index.html index 3a1a5b0..bf0766d 100644 --- a/craton_dashboard/dashboards/project/fleet/inventory/templates/fleet.inventory/index.html +++ b/craton_dashboard/content/fleet_management/taskflows/templates/fleet.taskflows/index.html @@ -8,5 +8,7 @@ {% endblock %} {% block main %} -
+ + {% endblock %} diff --git a/craton_dashboard/dashboards/project/fleet/taskflows/urls.py b/craton_dashboard/content/fleet_management/taskflows/urls.py similarity index 64% rename from craton_dashboard/dashboards/project/fleet/taskflows/urls.py rename to craton_dashboard/content/fleet_management/taskflows/urls.py index 9afdfb9..a10b4cc 100644 --- a/craton_dashboard/dashboards/project/fleet/taskflows/urls.py +++ b/craton_dashboard/content/fleet_management/taskflows/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import url -from craton_dashboard.dashboards.project.fleet.taskflows import views +from craton_dashboard.content.fleet_management.taskflows import views urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), diff --git a/craton_dashboard/dashboards/project/fleet/taskflows/views.py b/craton_dashboard/content/fleet_management/taskflows/views.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/taskflows/views.py rename to craton_dashboard/content/fleet_management/taskflows/views.py diff --git a/craton_dashboard/dashboards/__init__.pyc b/craton_dashboard/dashboards/__init__.pyc deleted file mode 100644 index 97cf6ec4685fdec9c8cedf9a3e8f9f38d7550afb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmZSn%**viVNrN80~9atlE)JK diff --git a/craton_dashboard/dashboards/project/__init__.pyc b/craton_dashboard/dashboards/project/__init__.pyc deleted file mode 100644 index 8096d4ff69aef87f0ffb153186b56d8ac526d615..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117 zcmZSn%**voVNrN80~9aBo=2RlIX%Z~ztB -{% endblock %} - -{% block main %} -
-{% endblock %} diff --git a/craton_dashboard/dashboards/project/fleet/auditor/urls.py b/craton_dashboard/dashboards/project/fleet/auditor/urls.py deleted file mode 100644 index e7e9bad..0000000 --- a/craton_dashboard/dashboards/project/fleet/auditor/urls.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.conf.urls import url - -from craton_dashboard.dashboards.project.fleet.auditor import views - -urlpatterns = [ - url(r'^$', views.IndexView.as_view(), name='index'), -] - diff --git a/craton_dashboard/dashboards/project/fleet/auditor/views.py b/craton_dashboard/dashboards/project/fleet/auditor/views.py deleted file mode 100644 index 9b42f86..0000000 --- a/craton_dashboard/dashboards/project/fleet/auditor/views.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2016 Intel Corporation -# -# 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.utils.translation import ugettext_lazy as _ -from django.views import generic - -from horizon import exceptions -from horizon import forms -from horizon import tables - -class IndexView(generic.TemplateView): - template_name = 'project/fleet.auditor/index.html' - page_title = _('Auditor') - diff --git a/craton_dashboard/dashboards/project/fleet/panel.py b/craton_dashboard/dashboards/project/fleet/panel.py deleted file mode 100644 index 8b49c3e..0000000 --- a/craton_dashboard/dashboards/project/fleet/panel.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2016 Intel Corporation -# -# 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.utils.translation import ugettext_lazy as _ - -import horizon - -class Regions(horizon.Panel): - name = _('Regions') - slug = 'regions' diff --git a/craton_dashboard/dashboards/project/fleet/panel.pyc b/craton_dashboard/dashboards/project/fleet/panel.pyc deleted file mode 100644 index 5508868d26ff18de106c9a8a122b4595d53005d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 497 zcmb7A!A`?440YOWplK6GTo7MSF6|i!A;cLW)Ey>zslt+VtfR5P3 zp88Wu!UT$W%J+&O%qsmsCG^B|BC5*DPFEF9Lee=k7*4sO!i12|L*UI&r$oRB{4J$Q z`t`e$z4G~{cdcGxzA{>4er%R+q}3+dY=ey}s_?8k7E_UqDZpzMX{D`QHeh3XhP|}j uNTdfBbOr^FC`@7P`ex@WGV#i?LGxrNME`RY#&Cal_`?P126vayH2MW(BWZ~M diff --git a/craton_dashboard/dashboards/project/fleet/reporting/templates/fleet.reporting/index.html b/craton_dashboard/dashboards/project/fleet/reporting/templates/fleet.reporting/index.html deleted file mode 100644 index 3a1a5b0..0000000 --- a/craton_dashboard/dashboards/project/fleet/reporting/templates/fleet.reporting/index.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% block title %}{% trans "Craton" %}{% endblock %} -{% block page_header %}{% endblock %} - -{% block ng_route_base %} - -{% endblock %} - -{% block main %} -
-{% endblock %} diff --git a/craton_dashboard/dashboards/project/fleet/reporting/urls.py b/craton_dashboard/dashboards/project/fleet/reporting/urls.py deleted file mode 100644 index 5c4cc59..0000000 --- a/craton_dashboard/dashboards/project/fleet/reporting/urls.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.conf.urls import url - -from craton_dashboard.dashboards.project.fleet.reporting import views - -urlpatterns = [ - url(r'^$', views.IndexView.as_view(), name='index'), -] - diff --git a/craton_dashboard/dashboards/project/fleet/reporting/views.py b/craton_dashboard/dashboards/project/fleet/reporting/views.py deleted file mode 100644 index 5a84686..0000000 --- a/craton_dashboard/dashboards/project/fleet/reporting/views.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2016 Intel Corporation -# -# 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.utils.translation import ugettext_lazy as _ -from django.views import generic - -from horizon import exceptions -from horizon import forms -from horizon import tables - -class IndexView(generic.TemplateView): - template_name = 'project/fleet.reporting/index.html' - page_title = _('Reporting') - diff --git a/craton_dashboard/dashboards/project/fleet/taskflows/__init__.py b/craton_dashboard/dashboards/project/fleet/taskflows/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/craton_dashboard/dashboards/project/fleet/taskflows/templates/fleet.taskflows/index.html b/craton_dashboard/dashboards/project/fleet/taskflows/templates/fleet.taskflows/index.html deleted file mode 100644 index 3a1a5b0..0000000 --- a/craton_dashboard/dashboards/project/fleet/taskflows/templates/fleet.taskflows/index.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% block title %}{% trans "Craton" %}{% endblock %} -{% block page_header %}{% endblock %} - -{% block ng_route_base %} - -{% endblock %} - -{% block main %} -
-{% endblock %} diff --git a/craton_dashboard/dashboards/project/fleet/templates/regions/index.html b/craton_dashboard/dashboards/project/fleet/templates/regions/index.html deleted file mode 100644 index 3a1a5b0..0000000 --- a/craton_dashboard/dashboards/project/fleet/templates/regions/index.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% block title %}{% trans "Craton" %}{% endblock %} -{% block page_header %}{% endblock %} - -{% block ng_route_base %} - -{% endblock %} - -{% block main %} -
-{% endblock %} diff --git a/craton_dashboard/dashboards/project/fleet/urls.py b/craton_dashboard/dashboards/project/fleet/urls.py deleted file mode 100644 index 543d602..0000000 --- a/craton_dashboard/dashboards/project/fleet/urls.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.conf.urls import url - -from craton_dashboard.dashboards.project.fleet import views - -urlpatterns = [ - url(r'^$', views.IndexView.as_view(), name='index'), -] - diff --git a/craton_dashboard/enabled/_1730_fleet_taskflows_panel.py b/craton_dashboard/enabled/_1720_fleet_taskflows_panel.py similarity index 78% rename from craton_dashboard/enabled/_1730_fleet_taskflows_panel.py rename to craton_dashboard/enabled/_1720_fleet_taskflows_panel.py index 69e1883..0aa6a3d 100644 --- a/craton_dashboard/enabled/_1730_fleet_taskflows_panel.py +++ b/craton_dashboard/enabled/_1720_fleet_taskflows_panel.py @@ -21,6 +21,10 @@ PANEL_DASHBOARD = 'project' PANEL_GROUP = 'fleet_management' ADD_PANEL = ( - 'craton_dashboard.dashboards.project.fleet.taskflows.panel.Taskflows') + 'craton_dashboard.content.fleet_management.taskflows.panel.Taskflows') +ADD_INSTALLED_APPS = ['craton_dashboard', ] +ADD_ANGULAR_MODULES = ['horizon.dashboard.project.fleet_management'] + +AUTO_DISCOVER_STATIC_FILES = True diff --git a/craton_dashboard/enabled/_1770_fleet_inventory_panel.py b/craton_dashboard/enabled/_1730_fleet_inventory_panel.py similarity index 92% rename from craton_dashboard/enabled/_1770_fleet_inventory_panel.py rename to craton_dashboard/enabled/_1730_fleet_inventory_panel.py index 73d584b..c313a73 100644 --- a/craton_dashboard/enabled/_1770_fleet_inventory_panel.py +++ b/craton_dashboard/enabled/_1730_fleet_inventory_panel.py @@ -21,5 +21,5 @@ PANEL_DASHBOARD = 'project' PANEL_GROUP = 'fleet_management' ADD_PANEL = ( - 'craton_dashboard.dashboards.project.fleet.inventory.panel.Inventory') + 'craton_dashboard.content.fleet_management.inventory.panel.Inventory') diff --git a/craton_dashboard/enabled/_1760_fleet_reporting_panel.py b/craton_dashboard/enabled/_1760_fleet_reporting_panel.py deleted file mode 100644 index 6a2076e..0000000 --- a/craton_dashboard/enabled/_1760_fleet_reporting_panel.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2016 Intel Corporation -# -# 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.utils.translation import ugettext_lazy as _ - -PANEL = 'fleet.reporting' - -PANEL_DASHBOARD = 'project' - -PANEL_GROUP = 'fleet_management' - -ADD_PANEL = ( - 'craton_dashboard.dashboards.project.fleet.reporting.panel.Reporting') - diff --git a/craton_dashboard/static/dashboard/project/craton/alerts/alerts.controller.js b/craton_dashboard/static/dashboard/project/craton/alerts/alerts.controller.js deleted file mode 100644 index e69de29..0000000 diff --git a/craton_dashboard/static/dashboard/project/craton/alerts/index.html b/craton_dashboard/static/dashboard/project/craton/alerts/index.html deleted file mode 100644 index 570ab86..0000000 --- a/craton_dashboard/static/dashboard/project/craton/alerts/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -
- -
diff --git a/craton_dashboard/static/dashboard/project/craton/auditor/auditor.controller.js b/craton_dashboard/static/dashboard/project/craton/auditor/auditor.controller.js deleted file mode 100644 index e69de29..0000000 diff --git a/craton_dashboard/static/dashboard/project/craton/auditor/index.html b/craton_dashboard/static/dashboard/project/craton/auditor/index.html deleted file mode 100644 index 6cac28b..0000000 --- a/craton_dashboard/static/dashboard/project/craton/auditor/index.html +++ /dev/null @@ -1,5 +0,0 @@ - - -
- -
diff --git a/craton_dashboard/static/dashboard/project/craton/fleet.scss b/craton_dashboard/static/dashboard/project/craton/fleet.scss deleted file mode 100644 index e69de29..0000000 diff --git a/craton_dashboard/static/dashboard/project/craton/regions/index.html b/craton_dashboard/static/dashboard/project/craton/regions/index.html deleted file mode 100644 index 3d26a35..0000000 --- a/craton_dashboard/static/dashboard/project/craton/regions/index.html +++ /dev/null @@ -1,5 +0,0 @@ - -
- - -
diff --git a/craton_dashboard/static/dashboard/project/craton/reporting/index.html b/craton_dashboard/static/dashboard/project/craton/reporting/index.html deleted file mode 100644 index 0228ef8..0000000 --- a/craton_dashboard/static/dashboard/project/craton/reporting/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -
- -
diff --git a/craton_dashboard/static/dashboard/project/craton/reporting/reporting.controller.js b/craton_dashboard/static/dashboard/project/craton/reporting/reporting.controller.js deleted file mode 100644 index e69de29..0000000 diff --git a/craton_dashboard/dashboards/project/fleet/auditor/__init__.py b/craton_dashboard/static/dashboard/project/fleet_management/fleet_management.scss similarity index 100% rename from craton_dashboard/dashboards/project/fleet/auditor/__init__.py rename to craton_dashboard/static/dashboard/project/fleet_management/fleet_management.scss diff --git a/craton_dashboard/static/dashboard/project/craton/fleet.js b/craton_dashboard/static/dashboard/project/fleet_management/fleet_managment.module.js similarity index 90% rename from craton_dashboard/static/dashboard/project/craton/fleet.js rename to craton_dashboard/static/dashboard/project/fleet_management/fleet_managment.module.js index bcb98e8..15495d6 100644 --- a/craton_dashboard/static/dashboard/project/craton/fleet.js +++ b/craton_dashboard/static/dashboard/project/fleet_management/fleet_managment.module.js @@ -25,18 +25,18 @@ * Dashboard module to host various backup panels. */ angular - .module('horizon.dashboard.project.craton', []) + .module('horizon.dashboard.project.fleet_management', []) .config(config); config.$inject = [ - '$provide', + '$provide', '$windowProvider', '$routeProvider' ]; function config($provide, $windowProvider, $routeProvider) { - var basePath = $windowProvider.$get().STATIC_URL + 'dashboard/project/craton/'; - $provide.constant('horizon.dashboard.project.craton.basePath', basePath); + var basePath = $windowProvider.$get().STATIC_URL + 'dashboard/project/fleet_management/'; + $provide.constant('horizon.dashboard.project.fleet_management.basePath', basePath); var regions = '/project/regions', taskflows = '/project/fleet/taskflows', diff --git a/craton_dashboard/static/dashboard/project/craton/inventory/index.html b/craton_dashboard/static/dashboard/project/fleet_management/inventory/index.html similarity index 77% rename from craton_dashboard/static/dashboard/project/craton/inventory/index.html rename to craton_dashboard/static/dashboard/project/fleet_management/inventory/index.html index 2473f6d..bc032dc 100644 --- a/craton_dashboard/static/dashboard/project/craton/inventory/index.html +++ b/craton_dashboard/static/dashboard/project/fleet_management/inventory/index.html @@ -1,4 +1,4 @@ -
+
diff --git a/craton_dashboard/static/dashboard/project/craton/inventory/inventory.controller.js b/craton_dashboard/static/dashboard/project/fleet_management/inventory/inventory.controller.js similarity index 100% rename from craton_dashboard/static/dashboard/project/craton/inventory/inventory.controller.js rename to craton_dashboard/static/dashboard/project/fleet_management/inventory/inventory.controller.js diff --git a/craton_dashboard/static/dashboard/project/craton/taskflows/index.html b/craton_dashboard/static/dashboard/project/fleet_management/taskflows/index.html similarity index 78% rename from craton_dashboard/static/dashboard/project/craton/taskflows/index.html rename to craton_dashboard/static/dashboard/project/fleet_management/taskflows/index.html index e97ae37..4affe1c 100644 --- a/craton_dashboard/static/dashboard/project/craton/taskflows/index.html +++ b/craton_dashboard/static/dashboard/project/fleet_management/taskflows/index.html @@ -1,4 +1,4 @@ p -
+
diff --git a/craton_dashboard/static/dashboard/project/craton/taskflows/taskflows.controller.js b/craton_dashboard/static/dashboard/project/fleet_management/taskflows/taskflows.controller.js similarity index 100% rename from craton_dashboard/static/dashboard/project/craton/taskflows/taskflows.controller.js rename to craton_dashboard/static/dashboard/project/fleet_management/taskflows/taskflows.controller.js diff --git a/craton_dashboard/dashboards/project/fleet/inventory/__init__.py b/craton_dashboard/test/__init__.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/inventory/__init__.py rename to craton_dashboard/test/__init__.py diff --git a/craton_dashboard/test/api_tests/craton_tests.py b/craton_dashboard/test/api_tests/craton_tests.py new file mode 100644 index 0000000..51fc3e0 --- /dev/null +++ b/craton_dashboard/test/api_tests/craton_tests.py @@ -0,0 +1,29 @@ +# Copyright 2016 Intel Corporation +# +# 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 craton_dashboard import api +from craton_dashboard.test import helpers as test + + +class CratonApiTests(test.CratonAPITestCase): + + def test_regions_list(self): + regions = self.craton_regions.list() + cratonclient = self.stub_cratonclient() + cratonclient.regions = self.mox.CreateMockAnything() + cratonclient.regions.list().AndReturn(regions) + self.mox.ReplayAll() + result = api.craton.region_list(self.request) + + self.assertEqual(len(regions), len(result)) diff --git a/craton_dashboard/test/helpers.py b/craton_dashboard/test/helpers.py new file mode 100644 index 0000000..b185498 --- /dev/null +++ b/craton_dashboard/test/helpers.py @@ -0,0 +1,61 @@ +# Copyright 2016 Intel Corporation +# +# 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 mock + +from cratonclient.v1 import client as craton_client + +from openstack_dashboard.test import helpers + +from craton_dashboard import api +from craton_dashboard.test.test_data import utils + + +def create_stubs(stubs_to_create={}): + return helpers.create_stubs(stubs_to_create) + + +class CratonTestsMixin(object): + def _setup_test_data(self): + super(CratonTestsMixin, self)._setup_test_data() + utils.load_test_data(self) + self.policy_patcher = mock.patch( + 'openstack_auth.policy.check', lambda action, request: True) + self._policy_check = self.policy_patcher.start() + + +class TestCase(CratonTestsMixin, helpers.TestCase): + pass + +class BaseAdminViewTests(CratonTestsMixin, helpers.TestCase): + pass + +class CratonAPITestCase(CratonTestsMixin, helpers.APITestCase): + def setUp(self): + super(CratonAPITestCase, self).setUp() + + self._original_craton_client = api.craton.cratonclient + api.craton.cratonclient = lambda request: self.stub_cratonclient() + + def tearDown(self): + super(CratonAPITestCase, self).tearDown() + + api.craton.cratonclient = self._original_craton_client + + def stub_cratonclient(self): + if not hasattr(self, "cratonclient"): + self.mox.StubOutWithMock(craton_client, 'Client') + self.cratonclient = self.mox.CreateMock(craton_client.Client) + return self.cratonclient diff --git a/craton_dashboard/dashboards/project/fleet/reporting/panel.py b/craton_dashboard/test/settings.py similarity index 71% rename from craton_dashboard/dashboards/project/fleet/reporting/panel.py rename to craton_dashboard/test/settings.py index a9269e6..f9c2b98 100644 --- a/craton_dashboard/dashboards/project/fleet/reporting/panel.py +++ b/craton_dashboard/test/settings.py @@ -1,5 +1,3 @@ -# Copyright 2016 Intel Corporation -# # 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 @@ -12,10 +10,8 @@ # License for the specific language governing permissions and limitations # under the License. -from django.utils.translation import ugettext_lazy as _ +from horizon.test.settings import * # noqa +from openstack_dashboard.test.settings import * # noqa -import horizon - -class Reporting(horizon.Panel): - name = _('Reporting') - slug = 'fleet.reporting' +INSTALLED_APPS = list(INSTALLED_APPS) +# INSTALLED_APPS.append('craton_dashboard.dashboards.project.fleet.inventory') diff --git a/craton_dashboard/dashboards/project/fleet/reporting/__init__.py b/craton_dashboard/test/test_data/__init__.py similarity index 100% rename from craton_dashboard/dashboards/project/fleet/reporting/__init__.py rename to craton_dashboard/test/test_data/__init__.py diff --git a/craton_dashboard/test/test_data/craton_data.py b/craton_dashboard/test/test_data/craton_data.py new file mode 100644 index 0000000..6898311 --- /dev/null +++ b/craton_dashboard/test/test_data/craton_data.py @@ -0,0 +1,45 @@ +# Copyright 2016 Intel Corporation +# +# 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 cratonclient.v1 import regions + +from openstack_dashboard.test.test_data import utils + +def data(TEST): + URL = 'http://localhost/' + TEST.craton_regions = utils.TestDataContainer() + + # Regions + + region_1 = regions.Region(regions.RegionManager(None, URL), { + 'id': 1, + 'name': 'Region1', + 'note': 'TestNote', + 'project_id': 1 + }) + region_2 = regions.Region(regions.RegionManager(None, URL), { + 'id': 2, + 'name': 'Region2', + 'note': 'TestNote', + 'project_id': 1 + }) + region_3 = regions.Region(regions.RegionManager(None, URL), { + 'id': 3, + 'name': 'Region3', + 'note': 'TestNote', + 'project_id': 1 + }) + TEST.craton_regions.add(region_1) + TEST.craton_regions.add(region_2) + TEST.craton_regions.add(region_3) diff --git a/craton_dashboard/enabled/_1720_fleet_regions_panel.py b/craton_dashboard/test/test_data/keystone_data.py similarity index 55% rename from craton_dashboard/enabled/_1720_fleet_regions_panel.py rename to craton_dashboard/test/test_data/keystone_data.py index c3d3426..71cdc71 100644 --- a/craton_dashboard/enabled/_1720_fleet_regions_panel.py +++ b/craton_dashboard/test/test_data/keystone_data.py @@ -12,18 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -from django.utils.translation import ugettext_lazy as _ -PANEL = 'regions' +def data(TEST): -PANEL_DASHBOARD = 'project' - -PANEL_GROUP = 'fleet_management' - -ADD_PANEL = 'craton_dashboard.dashboards.project.fleet.panel.Regions' - -ADD_INSTALLED_APPS = ['craton_dashboard'] - -ADD_ANGULAR_MODULES = ['horizon.dashboard.project.craton'] - -AUTO_DISCOVER_STATIC_FILES = True + # Add craton to the keystone data + TEST.service_catalog.append( + {"type": "fleetmanagement", + "name": "craton", + "endpoints_links": [], + "endpoints": [ + {"region": "RegionOne", + "adminURL": "http://admin.craton.example.com:8080/v1.1", + "publicURL": "http://public.craton.example.com:8080/v1.1", + "internalURL": "http://int.craton.example.com:8080/v1.1"}]} + ) diff --git a/craton_dashboard/test/test_data/utils.py b/craton_dashboard/test/test_data/utils.py new file mode 100644 index 0000000..e6fdb68 --- /dev/null +++ b/craton_dashboard/test/test_data/utils.py @@ -0,0 +1,52 @@ +# Copyright 2016 Intel Corporation +# +# 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.test_data import utils + + +def load_test_data(load_onto=None): + from openstack_dashboard.test.test_data import ceilometer_data + from openstack_dashboard.test.test_data import cinder_data + from openstack_dashboard.test.test_data import exceptions + from openstack_dashboard.test.test_data import glance_data + from openstack_dashboard.test.test_data import heat_data + from openstack_dashboard.test.test_data import keystone_data + from openstack_dashboard.test.test_data import neutron_data + from openstack_dashboard.test.test_data import nova_data + from openstack_dashboard.test.test_data import swift_data + + from craton_dashboard.test.test_data import keystone_data \ + as craton_keystone_data + from craton_dashboard.test.test_data import craton_data + + # The order of these loaders matters, some depend on others. + loaders = ( + exceptions.data, + keystone_data.data, + glance_data.data, + nova_data.data, + cinder_data.data, + neutron_data.data, + swift_data.data, + heat_data.data, + ceilometer_data.data, + craton_data.data, + craton_keystone_data.data, + ) + if load_onto: + for data_func in loaders: + data_func(load_onto) + return load_onto + else: + return utils.TestData(*loaders) diff --git a/craton_dashboard/enabled/_1740_fleet_alerts_panel.py b/craton_dashboard/test/urls.py similarity index 68% rename from craton_dashboard/enabled/_1740_fleet_alerts_panel.py rename to craton_dashboard/test/urls.py index 04800c8..310976f 100644 --- a/craton_dashboard/enabled/_1740_fleet_alerts_panel.py +++ b/craton_dashboard/test/urls.py @@ -1,5 +1,3 @@ -# Copyright 2016 Intel Corporation -# # 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 @@ -12,13 +10,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -from django.utils.translation import ugettext_lazy as _ -PANEL = 'fleet.alerts' - -PANEL_DASHBOARD = 'project' - -PANEL_GROUP = 'fleet_management' - -ADD_PANEL = 'craton_dashboard.dashboards.project.fleet.alerts.panel.Alerts' +from django.conf import urls +import openstack_dashboard.urls +urlpatterns = [ + urls.url(r'', urls.include(openstack_dashboard.urls)) +] diff --git a/craton_dashboard/tests/__init__.py b/craton_dashboard/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/craton_dashboard/tests/test_dummy.py b/craton_dashboard/tests/test_dummy.py deleted file mode 100644 index 451428e..0000000 --- a/craton_dashboard/tests/test_dummy.py +++ /dev/null @@ -1,7 +0,0 @@ -import mock - - -class TestDummy(object): - - def test_dummy(self): - return True diff --git a/craton_dashboard/dashboards/project/fleet/views.py b/manage.py old mode 100644 new mode 100755 similarity index 65% rename from craton_dashboard/dashboards/project/fleet/views.py rename to manage.py index b9227af..a852a1b --- a/craton_dashboard/dashboards/project/fleet/views.py +++ b/manage.py @@ -1,5 +1,5 @@ -# Copyright 2016 Intel Corporation -# +#!/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 @@ -12,12 +12,12 @@ # License for the specific language governing permissions and limitations # under the License. -from django.utils.translation import ugettext_lazy as _ -from django.views import generic +import os +import sys -from horizon import exceptions - -class IndexView(generic.TemplateView): - template_name = 'project/regions/index.html' - page_title = _('Regions') +from django.core.management import execute_from_command_line +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", + "craton_dashboard.test.settings") + execute_from_command_line(sys.argv) diff --git a/requirements.txt b/requirements.txt index e69de29..5e3a0ec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,17 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. + +pbr>=1.6 # Apache-2.0 +# Horizon Core Requirements +Babel>=2.3.4 # BSD +Django<1.9,>=1.8 # BSD +django-compressor>=2.0 # MIT +django-openstack-auth>=2.3.0 # Apache-2.0 +iso8601>=0.1.11 # MIT +python-keystoneclient!=1.8.0,!=2.1.0,>=1.7.0 # Apache-2.0 +python-manilaclient>=1.10.0 # Apache-2.0 +python-neutronclient>=4.2.0 # Apache-2.0 +python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0 +python-saharaclient>=0.16.0 # Apache-2.0 +pytz>=2013.6 # MIT \ No newline at end of file diff --git a/run_test.sh b/run_test.sh new file mode 100755 index 0000000..d72da54 --- /dev/null +++ b/run_test.sh @@ -0,0 +1,553 @@ +#!/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="craton_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=craton_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=craton_dashboard.test.settings ${command_wrapper} flake8 --diff + exit +} + +function run_sphinx { + echo "Building sphinx..." + DJANGO_SETTINGS_MODULE=craton_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 craton_dashboard application tests" + export NOSE_XUNIT_FILE=craton_dashboard/nosetests.xml + if [ "$NOSE_WITH_HTML_OUTPUT" = '1' ]; then + export NOSE_HTML_OUT_FILE='craton_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 + if [ $with_selenium -eq 0 -a $integration -eq 0 ]; then + testopts="$testopts --exclude-dir=craton_dashboard/test/integration_tests" + fi + ${command_wrapper} ${coverage_run} $root/manage.py test craton_dashboard --settings=craton_dashboard.test.settings $testopts + # get results of the Horizon tests + CRATON_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=$(($CRATON_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 + + export HORIZON_INTEGRATION_TESTS_CONFIG_FILE="craton_dashboard/test/integration_tests/horizon.conf" + + echo "Running Horizon integration tests..." + if [ -z "$testargs" ]; then + ${command_wrapper} nosetests craton_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/setup.cfg b/setup.cfg index 9e2691b..1b95c81 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,7 +16,10 @@ classifiers = [ Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.3 Programming Language :: Python :: 3.4 + Programming Language :: Python :: 3.5 [files] packages = diff --git a/test-requirements.txt b/test-requirements.txt index 5a6032b..3119833 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,7 +1,18 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. + hacking<0.12,>=0.10.0 flake8_docstrings==0.2.1.post1 # MIT coverage>=3.6 +ddt>=1.0.1 # MIT +django-nose>=1.4.4 # BSD +reno>=1.8.0 # Apache2 +mock>=2.0 # BSD +mox3>=0.7.0 # Apache-2.0 +netifaces>=0.10.4 # MIT +nose-exclude # LGPL python-subunit>=0.0.18 sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 oslosphinx>=2.5.0 # Apache-2.0 diff --git a/tools/install_venv.py b/tools/install_venv.py new file mode 100644 index 0000000..d4e5363 --- /dev/null +++ b/tools/install_venv.py @@ -0,0 +1,159 @@ +# Copyright 2012 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Copyright 2012 OpenStack, LLC +# +# Copyright 2012 Nebula, 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. + +""" +Installation script for the OpenStack Dashboard development virtualenv. +""" + +import os +import subprocess +import sys + + +ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) +VENV = os.path.join(ROOT, '.venv') +WITH_VENV = os.path.join(ROOT, 'tools', 'with_venv.sh') +PIP_REQUIRES = os.path.join(ROOT, 'requirements.txt') +TEST_REQUIRES = os.path.join(ROOT, 'test-requirements.txt') +PIP_INSTALL_WRAPPER = os.path.join(ROOT, 'tools', 'pip_install.sh') + + +def die(message, *args): + print >> sys.stderr, message % args + sys.exit(1) + + +def run_command(cmd, redirect_output=True, check_exit_code=True, cwd=ROOT, + die_message=None): + """ + Runs a command in an out-of-process shell, returning the + output of that command. Working directory is ROOT. + """ + if redirect_output: + stdout = subprocess.PIPE + else: + stdout = None + + proc = subprocess.Popen(cmd, cwd=cwd, stdout=stdout) + output = proc.communicate()[0] + if check_exit_code and proc.returncode != 0: + if die_message is None: + die('Command "%s" failed.\n%s', ' '.join(cmd), output) + else: + die(die_message) + return output + + +HAS_EASY_INSTALL = bool(run_command(['which', 'easy_install'], + check_exit_code=False).strip()) +HAS_VIRTUALENV = bool(run_command(['which', 'virtualenv'], + check_exit_code=False).strip()) + + +def check_dependencies(): + """Make sure virtualenv is in the path.""" + + print ('Checking dependencies...') + if not HAS_VIRTUALENV: + print ('Virtual environment not found.') + # Try installing it via easy_install... + if HAS_EASY_INSTALL: + print ('Installing virtualenv via easy_install...', + run_command(['easy_install', 'virtualenv'], + die_message= + 'easy_install failed to install virtualenv' + '\ndevelopment requires virtualenv, please' + ' install it using your favorite tool')) + if not run_command(['which', 'virtualenv']): + die('ERROR: virtualenv not found in path.\n\ndevelopment ' + ' requires virtualenv, please install it using your' + ' favorite package management tool and ensure' + ' virtualenv is in your path') + print ('virtualenv installation done.') + else: + die('easy_install not found.\n\nInstall easy_install' + ' (python-setuptools in ubuntu) or virtualenv by hand,' + ' then rerun.') + print ('dependency check done.') + + +def create_virtualenv(venv=VENV): + """Creates the virtual environment and installs PIP only into the + virtual environment + """ + print 'Creating venv...', + run_command(['virtualenv', '-q', '--no-site-packages', VENV]) + print 'done.' + print 'Installing pip in virtualenv...', + if not run_command([WITH_VENV, 'easy_install', 'pip']).strip(): + die("Failed to install pip.") + print 'done.' + print 'Installing distribute in virtualenv...' + pip_install('distribute>=0.6.24') + print 'done.' + + +def pip_install(*args): + args = [WITH_VENV, 'pip', 'install', '--upgrade'] + list(args) + run_command(args, redirect_output=False) + + +def pip_install_with_horizon(*args): + args = [WITH_VENV, PIP_INSTALL_WRAPPER, 'unconstrained'] + list(args) + run_command(args, redirect_output=False) + + +def install_dependencies(venv=VENV): + print "Installing dependencies..." + print "(This may take several minutes, don't panic)" + pip_install_with_horizon('-r', TEST_REQUIRES) + pip_install_with_horizon('-r', PIP_REQUIRES) + + # Tell the virtual env how to "import dashboard" + py = 'python%d.%d' % (sys.version_info[0], sys.version_info[1]) + pthfile = os.path.join(venv, "lib", py, "site-packages", "dashboard.pth") + f = open(pthfile, 'w') + f.write("%s\n" % ROOT) + + +def install_horizon(): + print 'Installing horizon module in development mode...' + run_command([WITH_VENV, 'python', 'setup.py', 'develop'], cwd=ROOT) + + +def print_summary(): + summary = """ +Horizon development environment setup is complete. +To activate the virtualenv for the extent of your current shell session you +can run: +$ source .venv/bin/activate +""" + print summary + + +def main(): + check_dependencies() + create_virtualenv() + install_dependencies() + install_horizon() + print_summary() + +if __name__ == '__main__': + main() diff --git a/tools/pip_install.sh b/tools/pip_install.sh new file mode 100755 index 0000000..cfbbafc --- /dev/null +++ b/tools/pip_install.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# The original script is borrowed from neutron-* repos. + +# Many of horizon's repos suffer from the problem of depending on horizon, +# but it not existing on pypi. + +# This wrapper for tox's package installer will use the existing package +# if it exists, else use zuul-cloner if that program exists, else grab it +# from horizon master via a hard-coded URL. That last case should only +# happen with devs running unit tests locally. + +# From the tox.ini config page: +# install_command=ARGV +# default: +# pip install {opts} {packages} + +ZUUL_CLONER=/usr/zuul-env/bin/zuul-cloner +BRANCH_NAME=master +horizon_installed=$(echo "import horizon" | python 2>/dev/null ; echo $?) + +set -e + +zuul_install () { + if [ -x "$ZUUL_CLONER" ]; then + export ZUUL_BRANCH=${ZUUL_BRANCH-$BRANCH} + echo "ZUUL CLONER" > /tmp/tox_install.txt + cwd=$(/bin/pwd) + cd /tmp + $ZUUL_CLONER --cache-dir \ + /opt/git \ + --branch $BRANCH_NAME \ + git://git.openstack.org \ + openstack/horizon + cd openstack/horizon + $install_cmd -e . + cd "$cwd" + else + return 1 + fi +} + +usual_install () { + echo "PIP HARDCODE" > /tmp/tox_install.txt + if [ -z "$HORIZON_PIP_LOCATION" ]; then + HORIZON_PIP_LOCATION="git+https://git.openstack.org/openstack/horizon@$BRANCH_NAME#egg=horizon" + fi + $install_cmd -U -e ${HORIZON_PIP_LOCATION} + + if [ -z "$CRATON_CLIENT_PIP_LOCATION"]; then + CRATON_CLIENT_PIP_LOCATION="git+https://git.openstack.org/openstack/python-cratonclient@$BRANCH_NAME#egg=python-cratonclient" + fi + $install_cmd -U -e ${CRATON_CLIENT_PIP_LOCATION} +} + +install_cmd="pip install" +if [ "$1" = "constrained" ]; then + install_cmd="$install_cmd $2" + shift +fi +shift + +if [ $horizon_installed -eq 0 ]; then + echo "ALREADY INSTALLED" > /tmp/tox_install.txt + echo "Horizon already installed; using existing package" +else + zuul_install || usual_install +fi + +$install_cmd -U $* +exit $? \ No newline at end of file diff --git a/tools/with_venv.sh b/tools/with_venv.sh new file mode 100755 index 0000000..b15965f --- /dev/null +++ b/tools/with_venv.sh @@ -0,0 +1,7 @@ +#!/bin/bash +TOOLS_PATH=${TOOLS_PATH:-$(dirname $0)} +VENV_PATH=${VENV_PATH:-${TOOLS_PATH}} +VENV_DIR=${VENV_NAME:-/../.venv} +TOOLS=${TOOLS_PATH} +VENV=${VENV:-${VENV_PATH}/${VENV_DIR}} +source ${VENV}/bin/activate && "$@" \ No newline at end of file