
Two fixes related to one broken workflow. First, 1227918 is a lack of support for trove backends that don't have volume support enabled. To fix this, the user can now enter into 0 for the volume size to work around this. This alters how the value is passed troveclient. Working with trove team to get a programmatic way to determine is volume support is enabled. Second, 1228416 is broken javascript when trying to launch a database instance due to a couple of factors. The template for the help is mislinked to use the project/instance one. Two, the fields in the flavor that trove returns are different than the fields that nova returns for flavor. This causes an exception when trying to generate the quota/usage graphs on the right hand side of the form. Since the javascript is looking for hardcoded values, this is not a trivial fix so the offensive code has been removed until it can be revisited. Additionally, there is no guarantee that the nova backend trove uses is the same as the one regular compute uses. Needs more thought/work. Combined bug fixes because they are closely related to the same action. Change-Id: Ia378896d1d52067ac136c55ece9b527f44dd646b Closes-bug: #1227918 Closes-bug: #1228416
199 lines
7.0 KiB
Python
199 lines
7.0 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2013 Mirantis Inc.
|
|
# Copyright 2013 Rackspace Hosting.
|
|
#
|
|
# 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.core.urlresolvers import reverse # noqa
|
|
from django import http
|
|
|
|
from mox import IsA # noqa
|
|
|
|
from openstack_dashboard import api
|
|
from openstack_dashboard.test import helpers as test
|
|
|
|
if api.trove.with_trove:
|
|
from troveclient import common
|
|
|
|
INDEX_URL = reverse('horizon:project:databases:index')
|
|
LAUNCH_URL = reverse('horizon:project:databases:launch')
|
|
DETAILS_URL = reverse('horizon:project:databases:detail', args=['id'])
|
|
|
|
|
|
class DatabaseTests(test.TestCase):
|
|
def setUp(self):
|
|
if not api.trove.with_trove:
|
|
self.skipTest('Skip trove related tests.')
|
|
super(DatabaseTests, self).setUp()
|
|
|
|
@test.create_stubs(
|
|
{api.trove: ('instance_list', 'flavor_list')})
|
|
def test_index(self):
|
|
# Mock database instances
|
|
databases = common.Paginated(self.databases.list())
|
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
|
.AndReturn(databases)
|
|
# Mock flavors
|
|
api.trove.flavor_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.flavors.list())
|
|
|
|
self.mox.ReplayAll()
|
|
res = self.client.get(INDEX_URL)
|
|
self.assertTemplateUsed(res, 'project/databases/index.html')
|
|
|
|
@test.create_stubs(
|
|
{api.trove: ('instance_list', 'flavor_list')})
|
|
def test_index_flavor_exception(self):
|
|
# Mock database instances
|
|
databases = common.Paginated(self.databases.list())
|
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
|
.AndReturn(databases)
|
|
# Mock flavors
|
|
api.trove.flavor_list(IsA(http.HttpRequest))\
|
|
.AndRaise(self.exceptions.trove)
|
|
|
|
self.mox.ReplayAll()
|
|
res = self.client.get(INDEX_URL)
|
|
self.assertTemplateUsed(res, 'project/databases/index.html')
|
|
self.assertMessageCount(res, error=1)
|
|
|
|
@test.create_stubs(
|
|
{api.trove: ('instance_list',)})
|
|
def test_index_list_exception(self):
|
|
# Mock database instances
|
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
|
.AndRaise(self.exceptions.trove)
|
|
|
|
self.mox.ReplayAll()
|
|
res = self.client.get(INDEX_URL)
|
|
self.assertTemplateUsed(res, 'project/databases/index.html')
|
|
self.assertMessageCount(res, error=1)
|
|
|
|
@test.create_stubs(
|
|
{api.trove: ('instance_list', 'flavor_list')})
|
|
def test_index_pagination(self):
|
|
# Mock database instances
|
|
databases = common.Paginated(self.databases.list(),
|
|
next_marker="foo")
|
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
|
.AndReturn(databases)
|
|
# Mock flavors
|
|
api.trove.flavor_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.flavors.list())
|
|
|
|
self.mox.ReplayAll()
|
|
res = self.client.get(INDEX_URL)
|
|
self.assertTemplateUsed(res, 'project/databases/index.html')
|
|
self.assertContains(
|
|
res, 'marker=6ddc36d9-73db-4e23-b52e-368937d72719')
|
|
|
|
@test.create_stubs(
|
|
{api.trove: ('instance_list', 'flavor_list')})
|
|
def test_index_flavor_list_exception(self):
|
|
#Mocking instances
|
|
databases = common.Paginated(self.databases.list())
|
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
|
.AndReturn(databases)
|
|
#Mocking flavor list with raising an exception
|
|
api.trove.flavor_list(IsA(http.HttpRequest))\
|
|
.AndRaise(self.exceptions.trove)
|
|
|
|
self.mox.ReplayAll()
|
|
|
|
res = self.client.get(INDEX_URL)
|
|
|
|
self.assertTemplateUsed(res, 'project/databases/index.html')
|
|
self.assertMessageCount(res, error=1)
|
|
|
|
@test.create_stubs({
|
|
api.trove: ('flavor_list', 'backup_list',)})
|
|
def test_launch_instance(self):
|
|
api.trove.flavor_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.flavors.list())
|
|
api.trove.backup_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.database_backups.list())
|
|
|
|
self.mox.ReplayAll()
|
|
res = self.client.get(LAUNCH_URL)
|
|
self.assertTemplateUsed(res, 'project/databases/launch.html')
|
|
|
|
@test.create_stubs({
|
|
api.trove: ('flavor_list', 'backup_list', 'instance_create',)})
|
|
def test_create_simple_instance(self):
|
|
api.trove.flavor_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.flavors.list())
|
|
api.trove.backup_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.database_backups.list())
|
|
|
|
# Actual create database call
|
|
api.trove.instance_create(
|
|
IsA(http.HttpRequest),
|
|
IsA(unicode),
|
|
IsA(int),
|
|
IsA(unicode),
|
|
databases=None,
|
|
restore_point=None,
|
|
users=None).AndReturn(self.databases.first())
|
|
|
|
self.mox.ReplayAll()
|
|
post = {
|
|
'name': "MyDB",
|
|
'volume': '1',
|
|
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
|
}
|
|
|
|
res = self.client.post(LAUNCH_URL, post)
|
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
|
|
|
@test.create_stubs({
|
|
api.trove: ('flavor_list', 'backup_list', 'instance_create',)})
|
|
def test_create_simple_instance_exception(self):
|
|
trove_exception = self.exceptions.nova
|
|
api.trove.flavor_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.flavors.list())
|
|
api.trove.backup_list(IsA(http.HttpRequest))\
|
|
.AndReturn(self.database_backups.list())
|
|
|
|
# Actual create database call
|
|
api.trove.instance_create(
|
|
IsA(http.HttpRequest),
|
|
IsA(unicode),
|
|
IsA(int),
|
|
IsA(unicode),
|
|
databases=None,
|
|
restore_point=None,
|
|
users=None).AndRaise(trove_exception)
|
|
|
|
self.mox.ReplayAll()
|
|
post = {
|
|
'name': "MyDB",
|
|
'volume': '1',
|
|
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
|
}
|
|
|
|
res = self.client.post(LAUNCH_URL, post)
|
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
|
|
|
@test.create_stubs(
|
|
{api.trove: ('instance_get', 'flavor_get',)})
|
|
def test_details(self):
|
|
api.trove.instance_get(IsA(http.HttpRequest), IsA(unicode))\
|
|
.AndReturn(self.databases.first())
|
|
api.trove.flavor_get(IsA(http.HttpRequest), IsA(str))\
|
|
.AndReturn(self.flavors.first())
|
|
|
|
self.mox.ReplayAll()
|
|
res = self.client.get(DETAILS_URL)
|
|
self.assertTemplateUsed(res, 'project/databases/detail.html')
|