Browse Source

update files by working files.

changes/21/514521/1
Keiichi Hikita 4 years ago
parent
commit
6e046521a0
  1. 112
      .gitignore
  2. 16
      heat_dashboard/api/__init__.py
  3. 10
      heat_dashboard/api/heat.py
  4. 3
      heat_dashboard/api/rest/heat.py
  5. 2
      heat_dashboard/content/resource_types/panel.py
  6. 2
      heat_dashboard/content/resource_types/tables.py
  7. 3
      heat_dashboard/content/resource_types/tabs.py
  8. 2
      heat_dashboard/content/resource_types/urls.py
  9. 15
      heat_dashboard/content/resource_types/views.py
  10. 3
      heat_dashboard/content/stacks/forms.py
  11. 2
      heat_dashboard/content/stacks/mappings.py
  12. 39
      heat_dashboard/content/stacks/tables.py
  13. 19
      heat_dashboard/content/stacks/tabs.py
  14. 2
      heat_dashboard/content/stacks/urls.py
  15. 16
      heat_dashboard/content/stacks/views.py
  16. 2
      heat_dashboard/content/template_versions/panel.py
  17. 2
      heat_dashboard/content/template_versions/tables.py
  18. 7
      heat_dashboard/content/template_versions/tabs.py
  19. 5
      heat_dashboard/content/template_versions/urls.py
  20. 15
      heat_dashboard/content/template_versions/views.py
  21. 19
      heat_dashboard/enabled/_1620_project_stacks_panel.py
  22. 23
      heat_dashboard/enabled/_1630_project_resource_types_panel.py
  23. 22
      heat_dashboard/enabled/_1640_project_template_versions_panel.py
  24. 322
      heat_dashboard/test/settings.py
  25. 6
      heat_dashboard/test/tests/api/heat_rest_tests.py
  26. 7
      heat_dashboard/test/tests/api/heat_tests.py
  27. 5
      heat_dashboard/test/tests/content/test_resource_types.py
  28. 119
      heat_dashboard/test/tests/content/test_stacks.py
  29. 6
      heat_dashboard/test/tests/content/test_template_versions.py

112
.gitignore

@ -0,0 +1,112 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
ut_*_nose_results.html
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# own settings
.idea/*
# angular old versions
*angular-1.3.7*
*angular-1.5.6*
# backup files
*.bak

16
heat_dashboard/api/__init__.py

@ -31,25 +31,9 @@ In other words, Horizon developers not working on openstack_dashboard.api
shouldn't need to understand the finer details of APIs for
Keystone/Nova/Glance/Swift et. al.
"""
from openstack_dashboard.api import base
from openstack_dashboard.api import cinder
from openstack_dashboard.api import glance
from openstack_dashboard.api import heat
from openstack_dashboard.api import keystone
from openstack_dashboard.api import network
from openstack_dashboard.api import neutron
from openstack_dashboard.api import nova
from openstack_dashboard.api import swift
__all__ = [
"base",
"cinder",
"glance",
"heat",
"keystone",
"network",
"neutron",
"nova",
"swift",
]

10
heat_dashboard/api/heat.py

@ -12,15 +12,17 @@
import contextlib
import six
from six.moves.urllib import request
from django.conf import settings
from oslo_serialization import jsonutils
from heatclient import client as heat_client
from heatclient.common import template_format
from heatclient.common import template_utils
from heatclient.common import utils as heat_utils
from oslo_serialization import jsonutils
import six
from six.moves.urllib import request
from horizon import exceptions
from horizon.utils import functions as utils
from horizon.utils.memoized import memoized

3
heat_dashboard/api/rest/heat.py

@ -13,7 +13,8 @@
from django.views import generic
from openstack_dashboard import api
# from openstack_dashboard import api
from heat_dashboard import api
from openstack_dashboard.api.rest import urls
from openstack_dashboard.api.rest import utils as rest_utils

2
heat_dashboard/content/resource_types/panel.py

@ -18,6 +18,6 @@ import horizon
class ResourceTypes(horizon.Panel):
name = _("Resource Types")
slug = "stacks.resource_types"
slug = "resource_types"
permissions = ('openstack.services.orchestration',)
policy_rules = (("orchestration", "stacks:list_resource_types"),)

2
heat_dashboard/content/resource_types/tables.py

@ -24,7 +24,7 @@ class ResourceTypesFilterAction(tables.FilterAction):
class ResourceTypesTable(tables.DataTable):
name = tables.Column("resource_type",
verbose_name=_("Type"),
link="horizon:project:stacks.resource_types:details",)
link="horizon:project:resource_types:details",)
def get_object_id(self, resource):
return resource.resource_type

3
heat_dashboard/content/resource_types/tabs.py

@ -19,7 +19,8 @@ from horizon import tabs
class ResourceTypeOverviewTab(tabs.Tab):
name = _("Overview")
slug = "resource_type_overview"
template_name = "project/stacks.resource_types/_details.html"
# template_name = "project/stacks.resource_types/_details.html"
template_name = "project/resource_types/_details.html"
def get_context_data(self, request):
return {"r_type": self.tab_group.kwargs['rt'],

2
heat_dashboard/content/resource_types/urls.py

@ -13,7 +13,7 @@
from django.conf.urls import url
from openstack_dashboard.dashboards.project.stacks.resource_types import views
from heat_dashboard.content.resource_types import views
urlpatterns = [
url(r'^$', views.ResourceTypesView.as_view(), name='index'),

15
heat_dashboard/content/resource_types/views.py

@ -20,11 +20,14 @@ from horizon import exceptions
from horizon import tables
from horizon import tabs
from openstack_dashboard import api
import openstack_dashboard.dashboards.project.stacks.resource_types.tables \
as project_tables
import openstack_dashboard.dashboards.project.stacks.resource_types.tabs \
as project_tabs
# from openstack_dashboard import api
# import openstack_dashboard.dashboards.project.stacks.resource_types.tables \
# as project_tables
# import openstack_dashboard.dashboards.project.stacks.resource_types.tabs \
# as project_tabs
from heat_dashboard import api
import heat_dashboard.content.resource_types.tables as project_tables
import heat_dashboard.content.resource_types.tabs as project_tabs
class ResourceTypesView(tables.DataTableView):
@ -75,4 +78,4 @@ class DetailView(tabs.TabView):
@staticmethod
def get_redirect_url():
return reverse('horizon:project:stacks.resources:index')
return reverse('horizon:project:resource_types:index')

3
heat_dashboard/content/stacks/forms.py

@ -26,7 +26,8 @@ from horizon import exceptions
from horizon import forms
from horizon import messages
from openstack_dashboard import api
# from openstack_dashboard import api
from heat_dashboard import api
from openstack_dashboard.dashboards.project.images \
import utils as image_utils
from openstack_dashboard.dashboards.project.instances \

2
heat_dashboard/content/stacks/mappings.py

@ -142,7 +142,9 @@ def stack_output(output):
output = json.dumps(output, indent=2)
return safestring.mark_safe(u'<pre>%s</pre>' % html.escape(output))
static_url = getattr(settings, "STATIC_URL", "/static/")
resource_images = {
'LB_FAILED': static_url + 'dashboard/img/lb-red.svg',
'LB_DELETE': static_url + 'dashboard/img/lb-red.svg',

39
heat_dashboard/content/stacks/tables.py

@ -16,15 +16,17 @@ from django.template.defaultfilters import title
from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from heatclient import exc
from horizon import exceptions
from horizon import messages
from horizon import tables
from horizon.utils import filters
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.stacks import mappings
from heatclient import exc
# from openstack_dashboard import api
# from openstack_dashboard.dashboards.project.stacks import mappings
from heat_dashboard import api
from heat_dashboard.content.stacks import mappings
class LaunchStack(tables.LinkAction):
@ -96,11 +98,8 @@ class SuspendStack(tables.BatchAction):
)
def action(self, request, stack_id):
try:
api.heat.action_suspend(request, stack_id)
except Exception:
msg = _('Failed to suspend stack.')
exceptions.handle(request, msg)
# api.heat.action_suspend(request, stack_id)
api.heat.action_suspend(request, stack_id)
class ResumeStack(tables.BatchAction):
@ -126,11 +125,8 @@ class ResumeStack(tables.BatchAction):
)
def action(self, request, stack_id):
try:
api.heat.action_resume(request, stack_id)
except Exception:
msg = _('Failed to resume stack.')
exceptions.handle(request, msg)
# api.heat.action_resume(request, stack_id)
api.heat.action_resume(request, stack_id)
class ChangeStackTemplate(tables.LinkAction):
@ -164,11 +160,8 @@ class DeleteStack(tables.DeleteAction):
policy_rules = (("orchestration", "stacks:delete"),)
def delete(self, request, stack_id):
try:
api.heat.stack_delete(request, stack_id)
except Exception:
msg = _('Failed to delete stack.')
exceptions.handle(request, msg)
# api.heat.stack_delete(request, stack_id)
api.heat.stack_delete(request, stack_id)
def allowed(self, request, stack):
if stack is not None:
@ -184,6 +177,7 @@ class StacksUpdateRow(tables.Row):
def get_data(self, request, stack_id):
try:
# stack = api.heat.stack_get(request, stack_id)
stack = api.heat.stack_get(request, stack_id)
if stack.stack_status == 'DELETE_COMPLETE':
# returning 404 to the ajax call removes the
@ -351,8 +345,11 @@ class ResourcesUpdateRow(tables.Row):
try:
stack = self.table.stack
stack_identifier = '%s/%s' % (stack.stack_name, stack.id)
return api.heat.resource_get(
request, stack_identifier, resource_name)
# return api.heat.resource_get(
# request, stack_identifier, resource_name)
return api.heat.resource_get(request,
stack_identifier,
resource_name)
except exc.HTTPNotFound:
# returning 404 to the ajax call removes the
# row from the table on the ui

19
heat_dashboard/content/stacks/tabs.py

@ -16,14 +16,13 @@ from django.utils.translation import ugettext_lazy as _
from horizon import messages
from horizon import tabs
from openstack_dashboard import api
from openstack_dashboard import policy
from openstack_dashboard.dashboards.project.stacks \
import api as project_api
from openstack_dashboard.dashboards.project.stacks import mappings
from openstack_dashboard.dashboards.project.stacks \
import tables as project_tables
from heat_dashboard import api
from heat_dashboard.content.stacks import api as project_api
from heat_dashboard.content.stacks import mappings
from heat_dashboard.content.stacks import tables as project_tables
from openstack_dashboard import policy
LOG = logging.getLogger(__name__)
@ -33,6 +32,7 @@ class StackTopologyTab(tabs.Tab):
name = _("Topology")
slug = "topology"
template_name = "project/stacks/_detail_topology.html"
# template_name = "stacks/_detail_topology.html"
preload = False
def allowed(self, request):
@ -55,6 +55,7 @@ class StackOverviewTab(tabs.Tab):
name = _("Overview")
slug = "overview"
template_name = "project/stacks/_detail_overview.html"
# template_name = "stacks/_detail_overview.html"
def allowed(self, request):
return policy.check(
@ -71,6 +72,7 @@ class ResourceOverviewTab(tabs.Tab):
name = _("Overview")
slug = "resource_overview"
template_name = "project/stacks/_resource_overview.html"
# template_name = "stacks/_resource_overview.html"
def get_context_data(self, request):
resource = self.tab_group.kwargs['resource']
@ -85,6 +87,7 @@ class StackEventsTab(tabs.Tab):
name = _("Events")
slug = "events"
template_name = "project/stacks/_detail_events.html"
# template_name = "stacks/_detail_events.html"
preload = False
def allowed(self, request):
@ -116,6 +119,7 @@ class StackResourcesTab(tabs.Tab):
name = _("Resources")
slug = "resources"
template_name = "project/stacks/_detail_resources.html"
# template_name = "stacks/_detail_resources.html"
preload = False
def allowed(self, request):
@ -148,6 +152,7 @@ class StackTemplateTab(tabs.Tab):
name = _("Template")
slug = "stack_template"
template_name = "project/stacks/_stack_template.html"
# template_name = "stacks/_stack_template.html"
def allowed(self, request):
return policy.check(

2
heat_dashboard/content/stacks/urls.py

@ -12,7 +12,7 @@
from django.conf.urls import url
from openstack_dashboard.dashboards.project.stacks import views
from heat_dashboard.content.stacks import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),

16
heat_dashboard/content/stacks/views.py

@ -19,23 +19,21 @@ from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponse
from django.utils.translation import ugettext_lazy as _
import django.views.generic
from heat_dashboard import api
from heat_dashboard.content.stacks import api as project_api
from heat_dashboard.content.stacks import forms as project_forms
from heat_dashboard.content.stacks import tables as project_tables
from heat_dashboard.content.stacks import tabs as project_tabs
from horizon import exceptions
from horizon import forms
from horizon import tables
from horizon import tabs
from horizon.utils import memoized
from horizon import views
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.stacks \
import api as project_api
from openstack_dashboard.dashboards.project.stacks \
import forms as project_forms
from openstack_dashboard.dashboards.project.stacks \
import tables as project_tables
from openstack_dashboard.dashboards.project.stacks \
import tabs as project_tabs
class IndexView(tables.DataTableView):

2
heat_dashboard/content/template_versions/panel.py

@ -18,6 +18,6 @@ import horizon
class TemplateVersions(horizon.Panel):
name = _("Template Versions")
slug = "stacks.template_versions"
slug = "template_versions"
permissions = ('openstack.services.orchestration',)
policy_rules = (("orchestration", "stacks:list_template_versions"),)

2
heat_dashboard/content/template_versions/tables.py

@ -21,7 +21,7 @@ class TemplateVersionsTable(tables.DataTable):
version = tables.Column(
"version",
verbose_name=_("Version"),
link="horizon:project:stacks.template_versions:details",)
link="horizon:project:template_versions:details",)
type = tables.Column(
"type",
verbose_name=_("Type"),

7
heat_dashboard/content/template_versions/tabs.py

@ -18,14 +18,15 @@ from horizon import tabs
from openstack_dashboard import api
from openstack_dashboard import policy
from openstack_dashboard.dashboards.project.stacks.template_versions \
import tables as project_tables
# from openstack_dashboard.dashboards.project.stacks.template_versions \
# import tables as project_tables
from heat_dashboard.content.template_versions import tables as project_tables
class TemplateFunctionsTab(tabs.Tab):
name = _("Template Functions")
slug = "template_functions"
template_name = "project/stacks.template_versions/_details.html"
template_name = "project/template_versions/_details.html"
preload = False
def allowed(self, request):

5
heat_dashboard/content/template_versions/urls.py

@ -13,8 +13,9 @@
from django.conf.urls import url
from openstack_dashboard.dashboards.project.stacks.template_versions \
import views
# from openstack_dashboard.dashboards.project.stacks.template_versions \
# import views
from heat_dashboard.content.template_versions import views
urlpatterns = [

15
heat_dashboard/content/template_versions/views.py

@ -18,16 +18,19 @@ from horizon import exceptions
from horizon import tables
from horizon import tabs
from openstack_dashboard import api
import openstack_dashboard.dashboards.project.stacks.template_versions.tables \
as project_tables
import openstack_dashboard.dashboards.project.stacks.template_versions.tabs \
as project_tabs
# from openstack_dashboard import api
# import openstack_dashboard.dashboards.project.\
# stacks.template_versions.tables as project_tables
# import openstack_dashboard.dashboards.project.\
# stacks.template_versions.tabs as project_tabs
from heat_dashboard import api
import heat_dashboard.content.template_versions.tables as project_tables
import heat_dashboard.content.template_versions.tabs as project_tabs
class TemplateVersionsView(tables.DataTableView):
table_class = project_tables.TemplateVersionsTable
template_name = 'project/stacks.template_versions/index.html'
template_name = 'project/template_versions/index.html'
page_title = _("Template Versions")
def get_data(self):

19
heat_dashboard/enabled/_1620_project_stacks_panel.py

@ -1,3 +1,15 @@
# 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.
# The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'stacks'
# The slug of the dashboard the PANEL associated with. Required.
@ -6,4 +18,9 @@ PANEL_DASHBOARD = 'project'
PANEL_GROUP = 'orchestration'
# Python panel class of the PANEL to be added.
ADD_PANEL = 'openstack_dashboard.dashboards.project.stacks.panel.Stacks'
ADD_PANEL = 'heat_dashboard.content.stacks.panel.Stacks'
# Automatically discover static resources in installed apps
AUTO_DISCOVER_STATIC_FILES = True
# ADD_INSTALLED_APPS = ['heat_dashboard.content.stacks', ]

23
heat_dashboard/enabled/_1630_project_resource_types_panel.py

@ -1,10 +1,27 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'stacks.resource_types'
PANEL = 'resource_types'
# The slug of the dashboard the PANEL associated with. Required.
PANEL_DASHBOARD = 'project'
# The slug of the panel group the PANEL is associated with.
PANEL_GROUP = 'orchestration'
# Python panel class of the PANEL to be added.
ADD_PANEL = ('openstack_dashboard.dashboards.project.'
'stacks.resource_types.panel.ResourceTypes')
ADD_PANEL = 'heat_dashboard.content.resource_types.panel.ResourceTypes'
# Automatically discover static resources in installed apps
AUTO_DISCOVER_STATIC_FILES = True
# ADD_INSTALLED_APPS = ['heat_dashboard.content.resource_types', ]
DISABLED = False

22
heat_dashboard/enabled/_1640_project_template_versions_panel.py

@ -1,10 +1,26 @@
# 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.
# The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'stacks.template_versions'
PANEL = 'template_versions'
# The slug of the dashboard the PANEL associated with. Required.
PANEL_DASHBOARD = 'project'
# The slug of the panel group the PANEL is associated with.
PANEL_GROUP = 'orchestration'
# Python panel class of the PANEL to be added.
ADD_PANEL = ('openstack_dashboard.dashboards.project.'
'stacks.template_versions.panel.TemplateVersions')
ADD_PANEL = 'heat_dashboard.content.template_versions.panel.TemplateVersions'
# Automatically discover static resources in installed apps
AUTO_DISCOVER_STATIC_FILES = True
# ADD_INSTALLED_APPS = ['heat_dashboard.content.template_versions', ]

322
heat_dashboard/test/settings.py

@ -1,310 +1,24 @@
# 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
# 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
#
# 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 tempfile
import six
from django.utils.translation import pgettext_lazy
from horizon.test.settings import * # noqa: F403,H303
from horizon.utils import secret_key
from openstack_dashboard import exceptions
from horizon.utils.escape import monkeypatch_escape
# this is used to protect from client XSS attacks, but it's worth
# enabling in our test setup to find any issues it might cause
monkeypatch_escape()
from openstack_dashboard.utils import settings as settings_utils
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, ".."))
MEDIA_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '..', 'media'))
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '..', 'static'))
STATIC_URL = '/static/'
WEBROOT = '/'
SECRET_KEY = secret_key.generate_or_read_from_file(
os.path.join(tempfile.gettempdir(), '.secret_key_store'))
ROOT_URLCONF = 'openstack_dashboard.test.urls'
TEMPLATES[0]['DIRS'] = [
os.path.join(TEST_DIR, 'templates')
]
TEMPLATES[0]['OPTIONS']['context_processors'].append(
'openstack_dashboard.context_processors.openstack'
)
CUSTOM_THEME_PATH = 'themes/default'
# 'key', 'label', 'path'
AVAILABLE_THEMES = [
(
'default',
pgettext_lazy('Default style theme', 'Default'),
'themes/default'
), (
'material',
pgettext_lazy("Google's Material Design style theme", "Material"),
'themes/material'
),
]
SELECTABLE_THEMES = [
(
'default',
pgettext_lazy('Default style theme', 'Default'),
'themes/default'
),
]
# Theme Static Directory
THEME_COLLECTION_DIR = 'themes'
COMPRESS_OFFLINE = False
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.staticfiles',
'django.contrib.messages',
'django.contrib.humanize',
'django_nose',
'openstack_auth',
'compressor',
'horizon',
'openstack_dashboard',
)
AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',)
SITE_BRANDING = 'OpenStack'
HORIZON_CONFIG = {
"password_validator": {
"regex": '^.{8,18}$',
"help_text": "Password must be between 8 and 18 characters."
},
'user_home': None,
'help_url': "http://docs.openstack.org",
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
'angular_modules': [],
'js_files': [],
}
ANGULAR_FEATURES = {
'images_panel': False, # Use the legacy panel so unit tests are still run
'flavors_panel': False,
'roles_panel': False,
}
STATICFILES_DIRS = settings_utils.get_xstatic_dirs(
settings_utils.BASE_XSTATIC_MODULES, HORIZON_CONFIG
)
# Load the pluggable dashboard settings
import openstack_dashboard.enabled
INSTALLED_APPS = list(INSTALLED_APPS) # Make sure it's mutable
settings_utils.update_dashboards(
[
openstack_dashboard.enabled,
],
HORIZON_CONFIG,
INSTALLED_APPS,
)
OPENSTACK_PROFILER = {'enabled': False}
settings_utils.find_static_files(HORIZON_CONFIG, AVAILABLE_THEMES,
THEME_COLLECTION_DIR, ROOT_PATH)
# Set to 'legacy' or 'direct' to allow users to upload images to glance via
# Horizon server. When enabled, a file form field will appear on the create
# image form. If set to 'off', there will be no file form field on the create
# image form. See documentation for deployment considerations.
HORIZON_IMAGES_UPLOAD_MODE = 'legacy'
AVAILABLE_REGIONS = [
('http://localhost:5000/v2.0', 'local'),
('http://remote:5000/v2.0', 'remote'),
]
OPENSTACK_API_VERSIONS = {
"identity": 3,
"image": 2
}
OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v2.0"
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'test_domain'
OPENSTACK_KEYSTONE_FEDERATION_MANAGEMENT = True
OPENSTACK_KEYSTONE_BACKEND = {
'name': 'native',
'can_edit_user': True,
'can_edit_group': True,
'can_edit_project': True,
'can_edit_domain': True,
'can_edit_role': True
}
OPENSTACK_CINDER_FEATURES = {
'enable_backup': True,
}
OPENSTACK_NEUTRON_NETWORK = {
'enable_router': True,
'enable_quotas': False, # Enabled in specific tests only
'enable_distributed_router': False,
}
OPENSTACK_HYPERVISOR_FEATURES = {
'can_set_mount_point': False,
'can_set_password': True,
}
OPENSTACK_IMAGE_BACKEND = {
'image_formats': [
('', 'Select format'),
('aki', 'AKI - Amazon Kernel Image'),
('ami', 'AMI - Amazon Machine Image'),
('ari', 'ARI - Amazon Ramdisk Image'),
('iso', 'ISO - Optical Disk Image'),
('ploop', 'PLOOP - Virtuozzo/Parallels Loopback Disk'),
('qcow2', 'QCOW2 - QEMU Emulator'),
('raw', 'Raw'),
('vdi', 'VDI'),
('vhd', 'VHD'),
('vmdk', 'VMDK')
]
}
LOGGING['loggers'].update(
{
'openstack_dashboard': {
'handlers': ['test'],
'propagate': False,
},
'openstack_auth': {
'handlers': ['test'],
'propagate': False,
},
'novaclient': {
'handlers': ['test'],
'propagate': False,
},
'keystoneclient': {
'handlers': ['test'],
'propagate': False,
},
'glanceclient': {
'handlers': ['test'],
'propagate': False,
},
'neutronclient': {
'handlers': ['test'],
'propagate': False,
},
'iso8601': {
'handlers': ['null'],
'propagate': False,
},
}
)
SECURITY_GROUP_RULES = {
'all_tcp': {
'name': 'ALL TCP',
'ip_protocol': 'tcp',
'from_port': '1',
'to_port': '65535',
},
'http': {
'name': 'HTTP',
'ip_protocol': 'tcp',
'from_port': '80',
'to_port': '80',
},
}
NOSE_ARGS = ['--nocapture',
'--nologcapture',
'--cover-package=openstack_dashboard',
'--cover-inclusive',
'--all-modules']
# TODO(amotoki): Need to investigate why --with-html-output
# is unavailable in python3.
# NOTE(amotoki): Most horizon plugins import this module in their test
# settings and they do not necessarily have nosehtmloutput in test-reqs.
# Assuming nosehtmloutput potentially breaks plugins tests,
# we check the availability of htmloutput module (from nosehtmloutput).
try:
import htmloutput # noqa: F401
has_html_output = True
except ImportError:
has_html_output = False
if six.PY2 and has_html_output:
NOSE_ARGS += ['--with-html-output',
'--html-out-file=ut_openstack_dashboard_nose_results.html']
POLICY_FILES_PATH = os.path.join(ROOT_PATH, "conf")
POLICY_FILES = {
'identity': 'keystone_policy.json',
'compute': 'nova_policy.json'
}
# The openstack_auth.user.Token object isn't JSON-serializable ATM
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
# 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.
REST_API_SETTING_1 = 'foo'
REST_API_SETTING_2 = 'bar'
REST_API_SECURITY = 'SECURITY'
REST_API_REQUIRED_SETTINGS = ['REST_API_SETTING_1']
REST_API_ADDITIONAL_SETTINGS = ['REST_API_SETTING_2']
from horizon.test.settings import * # noqa
from openstack_dashboard.test.settings import * # noqa
ALLOWED_PRIVATE_SUBNET_CIDR = {'ipv4': [], 'ipv6': []}
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS.append('heat_dashboard.content.stacks')
INSTALLED_APPS.append('heat_dashboard.content.resource_types')
INSTALLED_APPS.append('heat_dashboard.content.template_versions')
# --------------------
# Test-only settings
# --------------------
# TEST_GLOBAL_MOCKS_ON_PANELS: defines what and how methods should be
# mocked globally for unit tests and Selenium tests.
# 'method' is required. 'return_value' and 'side_effect'
# are optional and passed to mock.patch().
TEST_GLOBAL_MOCKS_ON_PANELS = {
'aggregates': {
'method': ('openstack_dashboard.dashboards.admin'
'.aggregates.panel.Aggregates.can_access'),
'return_value': True,
},
'trunk': {
'method': ('openstack_dashboard.dashboards.project'
'.trunks.panel.Trunks.can_access'),
'return_value': True,
},
'qos': {
'method': ('openstack_dashboard.dashboards.project'
'.network_qos.panel.NetworkQoS.can_access'),
'return_value': True,
},
}
# further implementation
# INSTALLED_APPS.append('heat_dashboard.content.template_generator')

6
heat_dashboard/test/tests/api/heat_rest_tests.py

@ -15,9 +15,11 @@ import json
import mock
# from openstack_dashboard.api.rest import heat
# from openstack_dashboard.test import helpers as test
from heat_dashboard.api.rest import heat
from heat_dashboard.test import helpers as test
from openstack_dashboard import api
from openstack_dashboard.api.rest import heat
from openstack_dashboard.test import helpers as test
class ValidateRestTestCase(test.TestCase):

7
heat_dashboard/test/tests/api/heat_tests.py

@ -14,9 +14,12 @@ import six
from django.conf import settings
from django.test.utils import override_settings
# from openstack_dashboard import api
# from openstack_dashboard.test import helpers as test
from heat_dashboard import api
from heat_dashboard.test import helpers as test
from horizon import exceptions
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test
class HeatApiTests(test.APITestCase):

5
heat_dashboard/test/tests/content/test_resource_types.py

@ -16,8 +16,9 @@ from django import http
from mox3.mox import IsA
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test
# from openstack_dashboard import api
from heat_dashboard import api
from heat_dashboard.test import helpers as test
class ResourceTypesTests(test.TestCase):

119
heat_dashboard/test/tests/content/test_stacks.py

@ -20,16 +20,23 @@ from django.core.urlresolvers import reverse
from django import http
from django.test.utils import override_settings
from django.utils import html
from heatclient.common import template_format as hc_format
from mox3.mox import IsA
import six
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.stacks import api as project_api
from openstack_dashboard.dashboards.project.stacks import forms
from openstack_dashboard.dashboards.project.stacks import mappings
from openstack_dashboard.dashboards.project.stacks import tables
from openstack_dashboard.test import helpers as test
from heatclient.common import template_format as hc_format
from heat_dashboard import api
from heat_dashboard.test import helpers as test
from openstack_dashboard import api as dashboard_api
# from openstack_dashboard.dashboards.project.stacks import api as project_api
# from openstack_dashboard.dashboards.project.stacks import forms
# from openstack_dashboard.dashboards.project.stacks import mappings
# from openstack_dashboard.dashboards.project.stacks import tables
from heat_dashboard.content.stacks import forms
from heat_dashboard.content.stacks import mappings
from heat_dashboard.content.stacks import tables
INDEX_TEMPLATE = 'horizon/common/_data_table_view.html'
@ -234,7 +241,7 @@ class StackTests(test.TestCase):
settings.API_RESULT_PAGE_SIZE)
@test.create_stubs({api.heat: ('stack_create', 'template_validate'),
api.neutron: ('network_list_for_tenant', )})
dashboard_api.neutron: ('network_list_for_tenant', )})
def test_launch_stack(self):
template = self.stack_templates.first()
stack = self.stacks.first()
@ -252,11 +259,11 @@ class StackTests(test.TestCase):
parameters=IsA(dict),
password='password',
files=None)
api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
.AndReturn(self.networks.list())
api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
.AndReturn(self.networks.list())
self.mox.ReplayAll()
@ -292,7 +299,7 @@ class StackTests(test.TestCase):
self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({api.heat: ('stack_create', 'template_validate'),
api.neutron: ('network_list_for_tenant', )})
dashboard_api.neutron: ('network_list_for_tenant', )})
def test_launch_stack_with_environment(self):
template = self.stack_templates.first()
environment = self.stack_environments.first()
@ -313,11 +320,11 @@ class StackTests(test.TestCase):
parameters=IsA(dict),
password='password',
files=None)
api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
.AndReturn(self.networks.list())
api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
.AndReturn(self.networks.list())
self.mox.ReplayAll()
@ -384,10 +391,11 @@ class StackTests(test.TestCase):
}
}
}
api.heat.template_validate(IsA(http.HttpRequest),
files={},
template=hc_format.parse(template['data'])) \
.AndReturn(template['validate'])
api.heat.template_validate(
IsA(http.HttpRequest),
files={},
template=hc_format.parse(template['data']))\
.AndReturn(template['validate'])
self.mox.ReplayAll()
@ -471,10 +479,11 @@ class StackTests(test.TestCase):
]
}
}
api.heat.template_validate(IsA(http.HttpRequest),
files={},
template=hc_format.parse(template['data'])) \
.AndReturn(template['validate'])
api.heat.template_validate(
IsA(http.HttpRequest),
files={},
template=hc_format.parse(template['data'])).\
AndReturn(template['validate'])
self.mox.ReplayAll()
@ -546,10 +555,11 @@ class StackTests(test.TestCase):
}
stack = self.stacks.first()
api.heat.template_validate(IsA(http.HttpRequest),
files={},
template=hc_format.parse(template['data'])) \
.AndReturn(template['validate'])
api.heat.template_validate(
IsA(http.HttpRequest),
files={},
template=hc_format.parse(template['data']))\
.AndReturn(template['validate'])
api.heat.stack_create(IsA(http.HttpRequest),
stack_name=stack.stack_name,
@ -587,10 +597,12 @@ class StackTests(test.TestCase):
'name="__param_param{0}" type="{1}"/>')
self.assertContains(res, input_str.format(1, 'text'), html=True)
# the custom number spinner produces an input element
# that doesn't match the input_strs above
# validate with id alone
self.assertContains(res, 'id="id___param_param2"')
self.assertContains(
res,
'<input autocomplete="off" class="form-control" '
'id="id___param_param2" name="__param_param2" '
'type="number"/>',
html=True)
self.assertContains(res, input_str.format(3, 'text'), html=True)
self.assertContains(res, input_str.format(4, 'text'), html=True)
self.assertContains(
@ -619,7 +631,7 @@ class StackTests(test.TestCase):
@test.create_stubs({api.heat: ('stack_update', 'stack_get', 'template_get',
'template_validate'),
api.neutron: ('network_list_for_tenant', )})
dashboard_api.neutron: ('network_list_for_tenant', )})
def test_edit_stack_template(self):
template = self.stack_templates.first()
stack = self.stacks.first()
@ -656,8 +668,8 @@ class StackTests(test.TestCase):
api.heat.stack_update(IsA(http.HttpRequest),
stack_id=stack.id,
**fields)
api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
.AndReturn(self.networks.list())
self.mox.ReplayAll()
@ -703,10 +715,10 @@ class StackTests(test.TestCase):
def test_launch_stack_form_invalid_name_point(self):
self._test_launch_stack_invalid_name('.StartWithPoint')
@test.create_stubs({api.neutron: ('network_list_for_tenant', )})
@test.create_stubs({dashboard_api.neutron: ('network_list_for_tenant', )})
def _test_launch_stack_invalid_name(self, name):
api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest),
self.tenant.id) \
.AndReturn(self.networks.list())
self.mox.ReplayAll()
@ -844,17 +856,21 @@ class StackTests(test.TestCase):
self.assertIn('stack-green.svg', d3_data)
self.assertIn('Create Complete', d3_data)
@test.create_stubs({api.heat: ('stack_get', 'template_get'),
project_api: ('d3_data',)})
# @test.create_stubs({api.heat: ('stack_get', 'template_get'),
# project_api: ('d3_data',)})
@test.create_stubs({api.heat: ('stack_get', 'template_get',
'resources_list')})
def test_detail_stack_overview(self):
stack = self.stacks.first()
template = self.stack_templates.first()
api.heat.stack_get(IsA(http.HttpRequest), stack.id) \
.MultipleTimes().AndReturn(stack)
api.heat.resources_list(IsA(http.HttpRequest), stack.id) \
.MultipleTimes().AndReturn([])
api.heat.template_get(IsA(http.HttpRequest), stack.id) \
.AndReturn(json.loads(template.validate))
project_api.d3_data(IsA(http.HttpRequest), stack_id=stack.id) \
.AndReturn(json.dumps({"nodes": [], "stack": {}}))
# project_api.d3_data(IsA(http.HttpRequest), stack_id=stack.id) \
# .AndReturn(json.dumps({"nodes": [], "stack": {}}))
self.mox.ReplayAll()
url = '?'.join([reverse(DETAIL_URL, args=[stack.id]),
@ -866,17 +882,26 @@ class StackTests(test.TestCase):
'project/stacks/_detail_overview.html')
self.assertEqual(stack.stack_name, overview_data.stack_name)
@test.create_stubs({api.heat: ('stack_get', 'template_get'),
project_api: ('d3_data',)})
# @test.create_stubs({api.heat: ('stack_get',
# 'template_get', 'resources_list'),
# project_api: ('d3_data',)})
@test.create_stubs({api.heat: ('stack_get', 'template_get',
'resources_list')})
def test_detail_stack_resources(self):
stack = self.stacks.first()
template = self.stack_templates.first()
api.heat.stack_get(IsA(http.HttpRequest), stack.id) \
.MultipleTimes().AndReturn(stack)
api.heat.resources_list(IsA(http.HttpRequest), stack.id) \
.MultipleTimes().AndReturn([])
api.heat.template_get(IsA(http.HttpRequest), stack.id) \
.AndReturn(json.loads(template.validate))
project_api.d3_data(IsA(http.HttpRequest), stack_id=stack.id) \
.AndReturn(json.dumps({"nodes": [], "stack": {}}))
# Needs to move into JSONView test
# because this part will be called from Ajax
# project_api.d3_data(IsA(http.HttpRequest), stack_id=stack.id) \
# .AndReturn(json.dumps({"nodes": [], "stack": {}}))
self.mox.ReplayAll()
url = '?'.join([reverse(DETAIL_URL, args=[stack.id]),

6
heat_dashboard/test/tests/content/test_template_versions.py

@ -16,8 +16,10 @@ from django import http
from mox3.mox import IsA
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test
# from openstack_dashboard import api
# from openstack_dashboard.test import helpers as test
from heat_dashboard import api
from heat_dashboard.test import helpers as test
class TemplateVersionsTests(test.TestCase):

Loading…
Cancel
Save