Convert project tests into mock: api_access/backups/overview/snapshots

Partially-Implements: blueprint mock-framework-in-unit-tests
Change-Id: I5a61d26d21f14ec44e8e82f6539196d53b6783fd
This commit is contained in:
Akihiro Motoki 2018-01-08 05:21:49 +09:00
parent d4c1c29cbb
commit dd560d95fd
4 changed files with 393 additions and 296 deletions

View File

@ -12,11 +12,9 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from mox3.mox import IsA
import six import six
import yaml import yaml
from django.http import HttpRequest
from django import template from django import template
from django.template import loader from django.template import loader
from django.test.utils import override_settings from django.test.utils import override_settings
@ -36,23 +34,22 @@ RECREATE_CREDS_URL = reverse(API_URL + ":recreate_credentials")
class APIAccessTests(test.TestCase): class APIAccessTests(test.TestCase):
@test.create_mocks({api.keystone: ('create_ec2_credentials',
'list_ec2_credentials')})
def test_ec2_download_view(self): def test_ec2_download_view(self):
creds = self.ec2.first() creds = self.ec2.first()
self.mock_list_ec2_credentials.return_value = []
self.mox.StubOutWithMock(api.keystone, "list_ec2_credentials") self.mock_create_ec2_credentials.return_value = creds
self.mox.StubOutWithMock(api.keystone, "create_ec2_credentials")
api.keystone.list_ec2_credentials(IsA(HttpRequest), self.user.id) \
.AndReturn([])
api.keystone.create_ec2_credentials(IsA(HttpRequest),
self.user.id,
self.tenant.id).AndReturn(creds)
self.mox.ReplayAll()
res = self.client.get(EC2_URL) res = self.client.get(EC2_URL)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
self.assertEqual(res['content-type'], 'application/zip') self.assertEqual(res['content-type'], 'application/zip')
self.mock_list_ec2_credentials.assert_called_once_with(
test.IsHttpRequest(), self.user.id)
self.mock_create_ec2_credentials.assert_called_once_with(
test.IsHttpRequest(), self.user.id, self.tenant.id)
def test_openrcv2_credentials(self): def test_openrcv2_credentials(self):
res = self.client.get(OPENRCV2_URL) res = self.client.get(OPENRCV2_URL)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
@ -81,42 +78,32 @@ class APIAccessTests(test.TestCase):
self.assertIn(p_id.encode('utf-8'), res.content) self.assertIn(p_id.encode('utf-8'), res.content)
self.assertIn(domain.encode('utf-8'), res.content) self.assertIn(domain.encode('utf-8'), res.content)
@test.create_stubs({api.keystone: ("list_ec2_credentials",)}) @test.create_mocks({api.keystone: ('list_ec2_credentials',)})
def test_credential_api(self): def test_credential_api(self):
certs = self.ec2.list() certs = self.ec2.list()
api.keystone.list_ec2_credentials(IsA(HttpRequest), self.user.id) \ self.mock_list_ec2_credentials.return_value = certs
.AndReturn(certs)
self.mox.ReplayAll()
res = self.client.get(CREDS_URL) res = self.client.get(CREDS_URL)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
credentials = 'project/api_access/credentials.html' credentials = 'project/api_access/credentials.html'
self.assertTemplateUsed(res, credentials) self.assertTemplateUsed(res, credentials)
self.assertEqual(self.user.id, res.context['openrc_creds']['user'].id) self.assertEqual(self.user.id, res.context['openrc_creds']['user'].id)
self.assertEqual(certs[0].access, self.assertEqual(certs[0].access,
res.context['ec2_creds']['ec2_access_key']) res.context['ec2_creds']['ec2_access_key'])
self.mock_list_ec2_credentials.assert_called_once_with(
test.IsHttpRequest(), self.user.id)
@test.create_stubs({api.keystone: ("list_ec2_credentials", @test.create_mocks({api.keystone: ('create_ec2_credentials',
"create_ec2_credentials", 'list_ec2_credentials',
"delete_user_ec2_credentials",)}) 'delete_user_ec2_credentials')})
def _test_recreate_user_credentials(self, exists_credentials=True): def _test_recreate_user_credentials(self, exists_credentials=True):
old_creds = self.ec2.list() if exists_credentials else [] old_creds = self.ec2.list() if exists_credentials else []
new_creds = self.ec2.first() new_creds = self.ec2.first()
api.keystone.list_ec2_credentials( self.mock_list_ec2_credentials.return_value = old_creds
IsA(HttpRequest),
self.user.id).AndReturn(old_creds)
if exists_credentials: if exists_credentials:
api.keystone.delete_user_ec2_credentials( self.mock_delete_user_ec2_credentials.return_value = []
IsA(HttpRequest), self.mock_create_ec2_credentials.return_value = new_creds
self.user.id,
old_creds[0].access).AndReturn([])
api.keystone.create_ec2_credentials(
IsA(HttpRequest),
self.user.id,
self.tenant.id).AndReturn(new_creds)
self.mox.ReplayAll()
res_get = self.client.get(RECREATE_CREDS_URL) res_get = self.client.get(RECREATE_CREDS_URL)
self.assertEqual(res_get.status_code, 200) self.assertEqual(res_get.status_code, 200)
@ -128,6 +115,16 @@ class APIAccessTests(test.TestCase):
self.assertNoFormErrors(res_post) self.assertNoFormErrors(res_post)
self.assertRedirectsNoFollow(res_post, INDEX_URL) self.assertRedirectsNoFollow(res_post, INDEX_URL)
self.mock_list_ec2_credentials.assert_called_once_with(
test.IsHttpRequest(), self.user.id)
if exists_credentials:
self.mock_delete_user_ec2_credentials.assert_called_once_with(
test.IsHttpRequest(), self.user.id, old_creds[0].access)
else:
self.mock_delete_user_ec2_credentials.assert_not_called()
self.mock_create_ec2_credentials.assert_called_once_with(
test.IsHttpRequest(), self.user.id, self.tenant.id)
def test_recreate_user_credentials(self): def test_recreate_user_credentials(self):
self._test_recreate_user_credentials() self._test_recreate_user_credentials()

View File

@ -11,12 +11,10 @@
# under the License. # under the License.
from django.conf import settings from django.conf import settings
from django import http
from django.test.utils import override_settings from django.test.utils import override_settings
from django.urls import reverse from django.urls import reverse
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils.http import urlunquote from django.utils.http import urlunquote
from mox3.mox import IsA
from openstack_dashboard import api from openstack_dashboard import api
from openstack_dashboard.dashboards.project.backups \ from openstack_dashboard.dashboards.project.backups \
@ -29,24 +27,23 @@ INDEX_URL = reverse('horizon:project:backups:index')
class VolumeBackupsViewTests(test.TestCase): class VolumeBackupsViewTests(test.TestCase):
@test.create_stubs({api.cinder: ('tenant_absolute_limits', @test.create_mocks({api.cinder: ('volume_list',
'volume_backup_list_paged', 'volume_backup_list_paged')})
'volume_list'),
api.nova: ('server_list',)})
def _test_backups_index_paginated(self, marker, sort_dir, backups, url, def _test_backups_index_paginated(self, marker, sort_dir, backups, url,
has_more, has_prev): has_more, has_prev):
api.cinder.volume_backup_list_paged( self.mock_volume_backup_list_paged.return_value = [backups,
IsA(http.HttpRequest), marker=marker, sort_dir=sort_dir, has_more, has_prev]
paginate=True).AndReturn([backups, has_more, has_prev]) self.mock_volume_list.return_value = self.cinder_volumes.list()
api.cinder.volume_list(IsA(http.HttpRequest)).AndReturn(
self.cinder_volumes.list())
self.mox.ReplayAll()
res = self.client.get(urlunquote(url)) res = self.client.get(urlunquote(url))
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html') self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')
self.mock_volume_backup_list_paged.assert_called_once_with(
test.IsHttpRequest(), marker=marker, sort_dir=sort_dir,
paginate=True)
self.mock_volume_list.assert_called_once_with(test.IsHttpRequest())
self.mox.UnsetStubs()
return res return res
@override_settings(API_RESULT_PAGE_SIZE=1) @override_settings(API_RESULT_PAGE_SIZE=1)
@ -112,21 +109,14 @@ class VolumeBackupsViewTests(test.TestCase):
backups = res.context['volume_backups_table'].data backups = res.context['volume_backups_table'].data
self.assertItemsEqual(backups, expected_backups) self.assertItemsEqual(backups, expected_backups)
@test.create_stubs({api.cinder: ('volume_backup_create', 'volume_get')}) @test.create_mocks({api.cinder: ('volume_backup_create',
'volume_get')})
def test_create_backup_available(self): def test_create_backup_available(self):
volume = self.volumes.first() volume = self.volumes.first()
backup = self.cinder_volume_backups.first() backup = self.cinder_volume_backups.first()
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \ self.mock_volume_get.return_value = volume
AndReturn(volume) self.mock_volume_backup_create.return_value = backup
api.cinder.volume_backup_create(IsA(http.HttpRequest),
volume.id,
backup.container_name,
backup.name,
backup.description,
force=False) \
.AndReturn(backup)
self.mox.ReplayAll()
formData = {'method': 'CreateBackupForm', formData = {'method': 'CreateBackupForm',
'tenant_id': self.tenant.id, 'tenant_id': self.tenant.id,
@ -142,22 +132,25 @@ class VolumeBackupsViewTests(test.TestCase):
self.assertMessageCount(error=0, warning=0) self.assertMessageCount(error=0, warning=0)
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({api.cinder: ('volume_backup_create', 'volume_get')}) self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
volume.id)
self.mock_volume_backup_create.assert_called_once_with(
test.IsHttpRequest(),
volume.id,
backup.container_name,
backup.name,
backup.description,
force=False)
@test.create_mocks({api.cinder: ('volume_backup_create',
'volume_get')})
def test_create_backup_in_use(self): def test_create_backup_in_use(self):
# The second volume in the cinder test volume data is in-use # The second volume in the cinder test volume data is in-use
volume = self.volumes.list()[1] volume = self.volumes.list()[1]
backup = self.cinder_volume_backups.first() backup = self.cinder_volume_backups.first()
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \ self.mock_volume_get.return_value = volume
AndReturn(volume) self.mock_volume_backup_create.return_value = backup
api.cinder.volume_backup_create(IsA(http.HttpRequest),
volume.id,
backup.container_name,
backup.name,
backup.description,
force=True) \
.AndReturn(backup)
self.mox.ReplayAll()
formData = {'method': 'CreateBackupForm', formData = {'method': 'CreateBackupForm',
'tenant_id': self.tenant.id, 'tenant_id': self.tenant.id,
@ -172,8 +165,17 @@ class VolumeBackupsViewTests(test.TestCase):
self.assertNoFormErrors(res) self.assertNoFormErrors(res)
self.assertMessageCount(error=0, warning=0) self.assertMessageCount(error=0, warning=0)
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
volume.id)
self.mock_volume_backup_create.assert_called_once_with(
test.IsHttpRequest(),
volume.id,
backup.container_name,
backup.name,
backup.description,
force=True)
@test.create_stubs({api.cinder: ('volume_list', @test.create_mocks({api.cinder: ('volume_list',
'volume_backup_list_paged', 'volume_backup_list_paged',
'volume_backup_delete')}) 'volume_backup_delete')})
def test_delete_volume_backup(self): def test_delete_volume_backup(self):
@ -181,14 +183,10 @@ class VolumeBackupsViewTests(test.TestCase):
volumes = self.cinder_volumes.list() volumes = self.cinder_volumes.list()
backup = self.cinder_volume_backups.first() backup = self.cinder_volume_backups.first()
api.cinder.volume_backup_list_paged( self.mock_volume_backup_list_paged.return_value = [vol_backups,
IsA(http.HttpRequest), marker=None, sort_dir='desc', False, False]
paginate=True).AndReturn([vol_backups, False, False]) self.mock_volume_list.return_value = volumes
api.cinder.volume_list(IsA(http.HttpRequest)). \ self.mock_volume_backup_delete.return_value = None
AndReturn(volumes)
api.cinder.volume_backup_delete(IsA(http.HttpRequest), backup.id)
self.mox.ReplayAll()
formData = {'action': formData = {'action':
'volume_backups__delete__%s' % backup.id} 'volume_backups__delete__%s' % backup.id}
@ -196,17 +194,21 @@ class VolumeBackupsViewTests(test.TestCase):
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)
self.mock_volume_backup_list_paged.assert_called_once_with(
test.IsHttpRequest(), marker=None, sort_dir='desc',
paginate=True)
self.mock_volume_list.assert_called_once_with(test.IsHttpRequest())
self.mock_volume_backup_delete.assert_called_once_with(
test.IsHttpRequest(), backup.id)
@test.create_stubs({api.cinder: ('volume_backup_get', 'volume_get')}) @test.create_mocks({api.cinder: ('volume_backup_get',
'volume_get')})
def test_volume_backup_detail_get(self): def test_volume_backup_detail_get(self):
backup = self.cinder_volume_backups.first() backup = self.cinder_volume_backups.first()
volume = self.cinder_volumes.get(id=backup.volume_id) volume = self.cinder_volumes.get(id=backup.volume_id)
api.cinder.volume_backup_get(IsA(http.HttpRequest), backup.id). \ self.mock_volume_backup_get.return_value = backup
AndReturn(backup) self.mock_volume_get.return_value = volume
api.cinder.volume_get(IsA(http.HttpRequest), backup.volume_id). \
AndReturn(volume)
self.mox.ReplayAll()
url = reverse('horizon:project:backups:detail', url = reverse('horizon:project:backups:detail',
args=[backup.id]) args=[backup.id])
@ -214,15 +216,17 @@ class VolumeBackupsViewTests(test.TestCase):
self.assertTemplateUsed(res, 'horizon/common/_detail.html') self.assertTemplateUsed(res, 'horizon/common/_detail.html')
self.assertEqual(res.context['backup'].id, backup.id) self.assertEqual(res.context['backup'].id, backup.id)
self.mock_volume_backup_get.assert_called_once_with(
test.IsHttpRequest(), backup.id)
self.mock_volume_get.assert_called_once_with(
test.IsHttpRequest(), backup.volume_id)
@test.create_stubs({api.cinder: ('volume_backup_get',)}) @test.create_mocks({api.cinder: ('volume_backup_get',)})
def test_volume_backup_detail_get_with_exception(self): def test_volume_backup_detail_get_with_exception(self):
# Test to verify redirect if get volume backup fails # Test to verify redirect if get volume backup fails
backup = self.cinder_volume_backups.first() backup = self.cinder_volume_backups.first()
api.cinder.volume_backup_get(IsA(http.HttpRequest), backup.id).\ self.mock_volume_backup_get.side_effect = self.exceptions.cinder
AndRaise(self.exceptions.cinder)
self.mox.ReplayAll()
url = reverse('horizon:project:backups:detail', url = reverse('horizon:project:backups:detail',
args=[backup.id]) args=[backup.id])
@ -231,17 +235,17 @@ class VolumeBackupsViewTests(test.TestCase):
self.assertNoFormErrors(res) self.assertNoFormErrors(res)
self.assertMessageCount(error=1) self.assertMessageCount(error=1)
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
self.mock_volume_backup_get.assert_called_once_with(
test.IsHttpRequest(), backup.id)
@test.create_stubs({api.cinder: ('volume_backup_get', 'volume_get')}) @test.create_mocks({api.cinder: ('volume_backup_get',
'volume_get')})
def test_volume_backup_detail_with_missing_volume(self): def test_volume_backup_detail_with_missing_volume(self):
# Test to check page still loads even if volume is deleted # Test to check page still loads even if volume is deleted
backup = self.cinder_volume_backups.first() backup = self.cinder_volume_backups.first()
api.cinder.volume_backup_get(IsA(http.HttpRequest), backup.id). \ self.mock_volume_backup_get.return_value = backup
AndReturn(backup) self.mock_volume_get.side_effect = self.exceptions.cinder
api.cinder.volume_get(IsA(http.HttpRequest), backup.volume_id). \
AndRaise(self.exceptions.cinder)
self.mox.ReplayAll()
url = reverse('horizon:project:backups:detail', url = reverse('horizon:project:backups:detail',
args=[backup.id]) args=[backup.id])
@ -249,20 +253,19 @@ class VolumeBackupsViewTests(test.TestCase):
self.assertTemplateUsed(res, 'horizon/common/_detail.html') self.assertTemplateUsed(res, 'horizon/common/_detail.html')
self.assertEqual(res.context['backup'].id, backup.id) self.assertEqual(res.context['backup'].id, backup.id)
self.mock_volume_backup_get.assert_called_once_with(
test.IsHttpRequest(), backup.id)
self.mock_volume_get.assert_called_once_with(
test.IsHttpRequest(), backup.volume_id)
@test.create_stubs({api.cinder: ('volume_list', @test.create_mocks({api.cinder: ('volume_list',
'volume_backup_restore',)}) 'volume_backup_restore')})
def test_restore_backup(self): def test_restore_backup(self):
backup = self.cinder_volume_backups.first() backup = self.cinder_volume_backups.first()
volumes = self.cinder_volumes.list() volumes = self.cinder_volumes.list()
api.cinder.volume_list(IsA(http.HttpRequest)). \ self.mock_volume_list.return_value = volumes
AndReturn(volumes) self.mock_volume_backup_restore.return_value = backup
api.cinder.volume_backup_restore(IsA(http.HttpRequest),
backup.id,
backup.volume_id). \
AndReturn(backup)
self.mox.ReplayAll()
formData = {'method': 'RestoreBackupForm', formData = {'method': 'RestoreBackupForm',
'backup_id': backup.id, 'backup_id': backup.id,
@ -278,3 +281,6 @@ class VolumeBackupsViewTests(test.TestCase):
self.assertMessageCount(info=1) self.assertMessageCount(info=1)
self.assertRedirectsNoFollow(res, self.assertRedirectsNoFollow(res,
reverse('horizon:project:volumes:index')) reverse('horizon:project:volumes:index'))
self.mock_volume_list.assert_called_once_with(test.IsHttpRequest())
self.mock_volume_backup_restore.assert_called_once_with(
test.IsHttpRequest(), backup.id, backup.volume_id)

View File

@ -19,12 +19,11 @@
import datetime import datetime
import logging import logging
from django import http
from django.test.utils import override_settings from django.test.utils import override_settings
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from mox3.mox import IsA import mock
from openstack_dashboard import api from openstack_dashboard import api
from openstack_dashboard.test import helpers as test from openstack_dashboard.test import helpers as test
@ -36,52 +35,87 @@ INDEX_URL = reverse('horizon:project:overview:index')
class UsageViewTests(test.TestCase): class UsageViewTests(test.TestCase):
@test.create_stubs({api.nova: ('usage_get', @test.create_mocks({api.nova: (
'tenant_absolute_limits', 'usage_get',
'extension_supported')}) ('tenant_absolute_limits', 'nova_tenant_absolute_limits'),
def _stub_nova_api_calls(self, nova_stu_enabled=True, 'extension_supported',
)})
def _stub_nova_api_calls(self,
nova_stu_enabled=True,
tenant_limits_exception=False, tenant_limits_exception=False,
stu_exception=False, overview_days_range=None): stu_exception=False, overview_days_range=1):
api.nova.extension_supported( self.mock_extension_supported.side_effect = [nova_stu_enabled,
'SimpleTenantUsage', IsA(http.HttpRequest)) \ nova_stu_enabled]
.AndReturn(nova_stu_enabled)
api.nova.extension_supported(
'SimpleTenantUsage', IsA(http.HttpRequest)) \
.AndReturn(nova_stu_enabled)
if tenant_limits_exception: if tenant_limits_exception:
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True)\ self.mock_nova_tenant_absolute_limits.side_effect = \
.AndRaise(tenant_limits_exception) tenant_limits_exception
else: else:
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \ self.mock_nova_tenant_absolute_limits.return_value = \
.AndReturn(self.limits['absolute']) self.limits['absolute']
if nova_stu_enabled: if nova_stu_enabled:
self._nova_stu_enabled(stu_exception, self._nova_stu_enabled(stu_exception,
overview_days_range=overview_days_range) overview_days_range=overview_days_range)
@test.create_stubs({api.cinder: ('tenant_absolute_limits',)}) def _check_nova_api_calls(self,
def _stub_cinder_api_calls(self): nova_stu_enabled=True,
api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \ tenant_limits_exception=False,
.AndReturn(self.cinder_limits['absolute']) stu_exception=False, overview_days_range=1):
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_extension_supported, 2,
mock.call('SimpleTenantUsage', test.IsHttpRequest()))
self.mock_nova_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True)
if nova_stu_enabled:
self._check_stu_enabled(stu_exception,
overview_days_range=overview_days_range)
else:
self.mock_usage_get.assert_not_called()
@test.create_stubs({api.neutron: ('is_extension_supported', @test.create_mocks({api.cinder: (
'floating_ip_supported', ('tenant_absolute_limits', 'cinder_tenant_absolute_limits'),
)})
def _stub_cinder_api_calls(self):
self.mock_cinder_tenant_absolute_limits.return_value = \
self.cinder_limits['absolute']
def _check_cinder_api_calls(self):
self.mock_cinder_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest())
@test.create_mocks({api.neutron: ('security_group_list',
'tenant_floating_ip_list', 'tenant_floating_ip_list',
'security_group_list')}) 'floating_ip_supported',
'is_extension_supported')})
def _stub_neutron_api_calls(self, neutron_sg_enabled=True): def _stub_neutron_api_calls(self, neutron_sg_enabled=True):
api.neutron.is_extension_supported( self.mock_is_extension_supported.return_value = neutron_sg_enabled
IsA(http.HttpRequest), self.mock_floating_ip_supported.return_value = True
'security-group').AndReturn(neutron_sg_enabled) self.mock_tenant_floating_ip_list.return_value = \
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \ self.floating_ips.list()
.AndReturn(True)
api.neutron.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
if neutron_sg_enabled: if neutron_sg_enabled:
api.neutron.security_group_list(IsA(http.HttpRequest)) \ self.mock_security_group_list.return_value = \
.AndReturn(self.security_groups.list()) self.security_groups.list()
def _check_neutron_api_calls(self, neutron_sg_enabled=True):
self.mock_is_extension_supported.assert_called_once_with(
test.IsHttpRequest(), 'security-group')
self.mock_floating_ip_supported.assert_called_once_with(
test.IsHttpRequest())
self.mock_tenant_floating_ip_list.assert_called_once_with(
test.IsHttpRequest())
if neutron_sg_enabled:
self.mock_security_group_list.assert_called_once_with(
test.IsHttpRequest())
else:
self.mock_security_group_list.assert_not_called()
def _nova_stu_enabled(self, exception=False, overview_days_range=1): def _nova_stu_enabled(self, exception=False, overview_days_range=1):
if exception:
self.mock_usage_get.side_effect = exception
else:
usage = api.nova.NovaUsage(self.usages.first())
self.mock_usage_get.return_value = usage
def _check_stu_enabled(self, exception=False, overview_days_range=1):
now = timezone.now() now = timezone.now()
if overview_days_range: if overview_days_range:
start_day = now - datetime.timedelta(days=overview_days_range) start_day = now - datetime.timedelta(days=overview_days_range)
@ -91,14 +125,8 @@ class UsageViewTests(test.TestCase):
start_day.day, 0, 0, 0, 0) start_day.day, 0, 0, 0, 0)
end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0) end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
if exception: self.mock_usage_get.assert_called_once_with(
api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id, test.IsHttpRequest(), self.tenant.id, start, end)
start, end) \
.AndRaise(exception)
else:
api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
start, end) \
.AndReturn(api.nova.NovaUsage(self.usages.first()))
def _common_assertions(self, nova_stu_enabled, def _common_assertions(self, nova_stu_enabled,
maxTotalFloatingIps=float("inf")): maxTotalFloatingIps=float("inf")):
@ -131,41 +159,35 @@ class UsageViewTests(test.TestCase):
overview_days_range=overview_days_range) overview_days_range=overview_days_range)
self._stub_neutron_api_calls() self._stub_neutron_api_calls()
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
self.mox.ReplayAll()
self._common_assertions(nova_stu_enabled) self._common_assertions(nova_stu_enabled)
self._check_nova_api_calls(nova_stu_enabled,
overview_days_range=overview_days_range)
self._check_neutron_api_calls()
self._check_cinder_api_calls()
def test_usage_nova_network(self): def test_usage_nova_network(self):
self._test_usage_nova_network(nova_stu_enabled=True) self._test_usage_nova_network(nova_stu_enabled=True)
def test_usage_nova_network_disabled(self): def test_usage_nova_network_disabled(self):
self._test_usage_nova_network(nova_stu_enabled=False) self._test_usage_nova_network(nova_stu_enabled=False)
@test.create_stubs({api.base: ('is_service_enabled',), @test.create_mocks({api.base: ('is_service_enabled',),
api.cinder: ('is_volume_service_enabled',)}) api.cinder: ('is_volume_service_enabled',)})
def _test_usage_nova_network(self, nova_stu_enabled): def _test_usage_nova_network(self, nova_stu_enabled):
self._stub_nova_api_calls(nova_stu_enabled) self._stub_nova_api_calls(nova_stu_enabled)
self.mock_is_service_enabled.return_value = False
api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \ self.mock_is_volume_service_enabled.return_value = False
.MultipleTimes().AndReturn(False)
api.cinder.is_volume_service_enabled(IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(False)
self.mox.ReplayAll()
self._common_assertions(nova_stu_enabled, maxTotalFloatingIps=10) self._common_assertions(nova_stu_enabled, maxTotalFloatingIps=10)
self._check_nova_api_calls(nova_stu_enabled)
@test.create_stubs({api.nova: ('usage_get', self.mock_is_service_enabled.assert_called_once_with(
'extension_supported')}) test.IsHttpRequest(), 'network')
def _stub_nova_api_calls_unauthorized(self, exception): self.mock_is_volume_service_enabled.assert_called_once_with(
api.nova.extension_supported( test.IsHttpRequest())
'SimpleTenantUsage', IsA(http.HttpRequest)) \
.AndReturn(True)
self._nova_stu_enabled(exception)
def test_unauthorized(self): def test_unauthorized(self):
self.mox.ReplayAll()
url = reverse('horizon:admin:volumes:index') url = reverse('horizon:admin:volumes:index')
# Avoid the log message in the test # Avoid the log message in the test
@ -186,47 +208,61 @@ class UsageViewTests(test.TestCase):
def test_usage_csv_disabled(self): def test_usage_csv_disabled(self):
self._test_usage_csv(nova_stu_enabled=False) self._test_usage_csv(nova_stu_enabled=False)
def _test_usage_csv(self, nova_stu_enabled=True, overview_days_range=None): def _test_usage_csv(self, nova_stu_enabled=True, overview_days_range=1):
self._stub_nova_api_calls(nova_stu_enabled, self._stub_nova_api_calls(nova_stu_enabled,
overview_days_range=overview_days_range) overview_days_range=overview_days_range)
self._stub_neutron_api_calls() self._stub_neutron_api_calls()
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:overview:index') + res = self.client.get(reverse('horizon:project:overview:index') +
"?format=csv") "?format=csv")
self.assertTemplateUsed(res, 'project/overview/usage.csv') self.assertTemplateUsed(res, 'project/overview/usage.csv')
self.assertIsInstance(res.context['usage'], usage.ProjectUsage) self.assertIsInstance(res.context['usage'], usage.ProjectUsage)
self._check_nova_api_calls(nova_stu_enabled,
overview_days_range=overview_days_range)
self._check_neutron_api_calls()
self._check_cinder_api_calls()
def test_usage_exception_usage(self): def test_usage_exception_usage(self):
self._stub_nova_api_calls(stu_exception=self.exceptions.nova) self._stub_nova_api_calls(stu_exception=self.exceptions.nova)
self._stub_neutron_api_calls() self._stub_neutron_api_calls()
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:overview:index')) res = self.client.get(reverse('horizon:project:overview:index'))
self.assertTemplateUsed(res, 'project/overview/usage.html') self.assertTemplateUsed(res, 'project/overview/usage.html')
self.assertEqual(res.context['usage'].usage_list, []) self.assertEqual(res.context['usage'].usage_list, [])
self._check_nova_api_calls(stu_exception=self.exceptions.nova)
self._check_neutron_api_calls()
self._check_cinder_api_calls()
def test_usage_exception_quota(self): def test_usage_exception_quota(self):
self._stub_nova_api_calls(tenant_limits_exception=self.exceptions.nova) self._stub_nova_api_calls(tenant_limits_exception=self.exceptions.nova)
self._stub_neutron_api_calls() self._stub_neutron_api_calls()
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:overview:index')) res = self.client.get(reverse('horizon:project:overview:index'))
self.assertTemplateUsed(res, 'project/overview/usage.html') self.assertTemplateUsed(res, 'project/overview/usage.html')
self.assertEqual(res.context['usage'].quotas, {}) self.assertEqual(res.context['usage'].quotas, {})
self._check_nova_api_calls(
tenant_limits_exception=self.exceptions.nova)
self._check_neutron_api_calls()
self._check_cinder_api_calls()
def test_usage_default_tenant(self): def test_usage_default_tenant(self):
self._stub_nova_api_calls() self._stub_nova_api_calls()
self._stub_neutron_api_calls() self._stub_neutron_api_calls()
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:overview:index')) res = self.client.get(reverse('horizon:project:overview:index'))
self.assertTemplateUsed(res, 'project/overview/usage.html') self.assertTemplateUsed(res, 'project/overview/usage.html')
self.assertIsInstance(res.context['usage'], usage.ProjectUsage) self.assertIsInstance(res.context['usage'], usage.ProjectUsage)
self._check_nova_api_calls()
self._check_neutron_api_calls()
self._check_cinder_api_calls()
@test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True}) @test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True})
def test_usage_with_neutron(self): def test_usage_with_neutron(self):
self._test_usage_with_neutron(neutron_sg_enabled=True) self._test_usage_with_neutron(neutron_sg_enabled=True)
@ -239,38 +275,60 @@ class UsageViewTests(test.TestCase):
def test_usage_with_neutron_floating_ip_disabled(self): def test_usage_with_neutron_floating_ip_disabled(self):
self._test_usage_with_neutron(neutron_fip_enabled=False) self._test_usage_with_neutron(neutron_fip_enabled=False)
@test.create_stubs({api.neutron: ('tenant_quota_get',
'is_extension_supported',
'floating_ip_supported',
'tenant_floating_ip_list',
'security_group_list')})
def _test_usage_with_neutron_prepare(self): def _test_usage_with_neutron_prepare(self):
self._stub_nova_api_calls() self._stub_nova_api_calls()
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
def _test_usage_with_neutron(self, neutron_sg_enabled=True, def _check_nova_cinder_calls_with_neutron_prepare(self):
self._check_nova_api_calls()
self._check_cinder_api_calls()
@test.create_mocks({api.neutron: ('tenant_quota_get',
'is_extension_supported',
'floating_ip_supported',
'tenant_floating_ip_list',
'security_group_list')})
def _test_usage_with_neutron(self,
neutron_sg_enabled=True,
neutron_fip_enabled=True): neutron_fip_enabled=True):
self._test_usage_with_neutron_prepare() self._test_usage_with_neutron_prepare()
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'quotas').AndReturn(True) self.mock_is_extension_supported.side_effect = [True,
api.neutron.is_extension_supported( neutron_sg_enabled]
IsA(http.HttpRequest), self.mock_floating_ip_supported.return_value = neutron_fip_enabled
'security-group').AndReturn(neutron_sg_enabled)
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
.AndReturn(neutron_fip_enabled)
if neutron_fip_enabled: if neutron_fip_enabled:
api.neutron.tenant_floating_ip_list(IsA(http.HttpRequest)) \ self.mock_tenant_floating_ip_list.return_value = \
.AndReturn(self.floating_ips.list()) self.floating_ips.list()
if neutron_sg_enabled: if neutron_sg_enabled:
api.neutron.security_group_list(IsA(http.HttpRequest)) \ self.mock_security_group_list.return_value = \
.AndReturn(self.security_groups.list()) self.security_groups.list()
api.neutron.tenant_quota_get(IsA(http.HttpRequest), self.tenant.id) \ self.mock_tenant_quota_get.return_value = self.neutron_quotas.first()
.AndReturn(self.neutron_quotas.first())
self.mox.ReplayAll()
self._test_usage_with_neutron_check(neutron_sg_enabled, self._test_usage_with_neutron_check(neutron_sg_enabled,
neutron_fip_enabled) neutron_fip_enabled)
self.mock_is_extension_supported.assert_has_calls([
mock.call(test.IsHttpRequest(), 'quotas'),
mock.call(test.IsHttpRequest(), 'security-group'),
])
self.assertEqual(2, self.mock_is_extension_supported.call_count)
self.mock_floating_ip_supported.assert_called_once_with(
test.IsHttpRequest())
if neutron_fip_enabled:
self.mock_tenant_floating_ip_list.assert_called_once_with(
test.IsHttpRequest())
else:
self.mock_tenant_floating_ip_list.assert_not_called()
if neutron_sg_enabled:
self.mock_security_group_list.assert_called_once_with(
test.IsHttpRequest())
else:
self.mock_security_group_list.assert_not_called()
self.mock_tenant_quota_get.assert_called_once_with(
test.IsHttpRequest(), self.tenant.id)
self._check_nova_cinder_calls_with_neutron_prepare()
def _test_usage_with_neutron_check(self, neutron_sg_enabled=True, def _test_usage_with_neutron_check(self, neutron_sg_enabled=True,
neutron_fip_expected=True, neutron_fip_expected=True,
max_fip_expected=50, max_fip_expected=50,
@ -290,47 +348,57 @@ class UsageViewTests(test.TestCase):
self.assertEqual(max_security_groups, max_sg_expected) self.assertEqual(max_security_groups, max_sg_expected)
@test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True}) @test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True})
def test_usage_with_neutron_quotas_ext_error(self): @mock.patch.object(api.neutron, 'is_extension_supported')
def test_usage_with_neutron_quotas_ext_error(self,
mock_is_extension_supported):
self._test_usage_with_neutron_prepare() self._test_usage_with_neutron_prepare()
api.neutron.is_extension_supported( mock_is_extension_supported.side_effect = self.exceptions.neutron
IsA(http.HttpRequest), 'quotas').AndRaise(self.exceptions.neutron)
self.mox.ReplayAll()
self._test_usage_with_neutron_check(neutron_fip_expected=False, self._test_usage_with_neutron_check(neutron_fip_expected=False,
max_fip_expected=float("inf"), max_fip_expected=float("inf"),
max_sg_expected=float("inf")) max_sg_expected=float("inf"))
mock_is_extension_supported.assert_called_once_with(
test.IsHttpRequest(), 'quotas')
self._check_nova_cinder_calls_with_neutron_prepare()
@test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True}) @test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True})
def test_usage_with_neutron_sg_ext_error(self): @mock.patch.object(api.neutron, 'is_extension_supported')
def test_usage_with_neutron_sg_ext_error(self,
mock_is_extension_supported):
self._test_usage_with_neutron_prepare() self._test_usage_with_neutron_prepare()
api.neutron.is_extension_supported( mock_is_extension_supported.side_effect = [
IsA(http.HttpRequest), 'quotas').AndReturn(True) True, # quotas
api.neutron.is_extension_supported( self.exceptions.neutron, # security-group
IsA(http.HttpRequest), ]
'security-group').AndRaise(self.exceptions.neutron)
self.mox.ReplayAll()
self._test_usage_with_neutron_check(neutron_fip_expected=False, self._test_usage_with_neutron_check(neutron_fip_expected=False,
max_fip_expected=float("inf"), max_fip_expected=float("inf"),
max_sg_expected=float("inf")) max_sg_expected=float("inf"))
self.assertEqual(2, mock_is_extension_supported.call_count)
mock_is_extension_supported.assert_has_calls([
mock.call(test.IsHttpRequest(), 'quotas'),
mock.call(test.IsHttpRequest(), 'security-group'),
])
self._check_nova_cinder_calls_with_neutron_prepare()
def test_usage_with_cinder(self): def test_usage_with_cinder(self):
self._test_usage_cinder(cinder_enabled=True) self._test_usage_cinder(cinder_enabled=True)
def test_usage_without_cinder(self): def test_usage_without_cinder(self):
self._test_usage_cinder(cinder_enabled=False) self._test_usage_cinder(cinder_enabled=False)
@test.create_stubs({api.base: ('is_service_enabled',), @test.create_mocks({api.base: ('is_service_enabled',),
api.cinder: ('is_volume_service_enabled',)}) api.cinder: ('is_volume_service_enabled',)})
def _test_usage_cinder(self, cinder_enabled): def _test_usage_cinder(self, cinder_enabled):
self._stub_nova_api_calls(True) self._stub_nova_api_calls(nova_stu_enabled=True)
if cinder_enabled: if cinder_enabled:
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \ self.mock_is_service_enabled.return_value = False
.MultipleTimes().AndReturn(False) self.mock_is_volume_service_enabled.return_value = cinder_enabled
api.cinder.is_volume_service_enabled(IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(cinder_enabled)
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:overview:index')) res = self.client.get(reverse('horizon:project:overview:index'))
usages = res.context['usage'] usages = res.context['usage']
@ -344,13 +412,27 @@ class UsageViewTests(test.TestCase):
else: else:
self.assertNotIn('totalVolumesUsed', usages.limits) self.assertNotIn('totalVolumesUsed', usages.limits)
self._check_nova_api_calls(nova_stu_enabled=True)
if cinder_enabled:
self._check_cinder_api_calls()
self.mock_is_service_enabled.assert_called_once_with(
test.IsHttpRequest(), 'network')
self.mock_is_volume_service_enabled.assert_called_once_with(
test.IsHttpRequest())
def _test_usage_charts(self): def _test_usage_charts(self):
self._stub_nova_api_calls(False) self._stub_nova_api_calls(nova_stu_enabled=False)
self._stub_neutron_api_calls() self._stub_neutron_api_calls()
self._stub_cinder_api_calls() self._stub_cinder_api_calls()
self.mox.ReplayAll()
return self.client.get(reverse('horizon:project:overview:index')) res = self.client.get(reverse('horizon:project:overview:index'))
self._check_nova_api_calls(nova_stu_enabled=False)
self._check_neutron_api_calls()
self._check_cinder_api_calls()
return res
def test_usage_charts_created(self): def test_usage_charts_created(self):
res = self._test_usage_charts() res = self._test_usage_charts()

View File

@ -17,14 +17,12 @@
# under the License. # under the License.
from django.conf import settings from django.conf import settings
from django import http
from django.test.utils import override_settings from django.test.utils import override_settings
from django.urls import reverse from django.urls import reverse
from django.utils.http import urlunquote from django.utils.http import urlunquote
from mox3.mox import IsA import mock
from openstack_dashboard import api from openstack_dashboard import api
from openstack_dashboard.api import cinder
from openstack_dashboard.dashboards.project.snapshots \ from openstack_dashboard.dashboards.project.snapshots \
import tables as snapshot_tables import tables as snapshot_tables
from openstack_dashboard.test import helpers as test from openstack_dashboard.test import helpers as test
@ -35,28 +33,29 @@ INDEX_URL = reverse('horizon:project:snapshots:index')
class VolumeSnapshotsViewTests(test.TestCase): class VolumeSnapshotsViewTests(test.TestCase):
@test.create_stubs({api.cinder: ('tenant_absolute_limits', @test.create_mocks({api.cinder: ('volume_snapshot_list_paged',
'volume_snapshot_list_paged', 'volume_list'),
'volume_list',),
api.base: ('is_service_enabled',)}) api.base: ('is_service_enabled',)})
def _test_snapshots_index_paginated(self, marker, sort_dir, snapshots, url, def _test_snapshots_index_paginated(self, marker, sort_dir, snapshots, url,
has_more, has_prev): has_more, has_prev):
api.base.is_service_enabled(IsA(http.HttpRequest), 'volumev3') \ self.mock_is_service_enabled.return_value = True
.AndReturn(True) self.mock_volume_snapshot_list_paged.return_value = [snapshots,
api.base.is_service_enabled(IsA(http.HttpRequest), 'volumev3') \ has_more,
.AndReturn(True) has_prev]
api.cinder.volume_snapshot_list_paged( self.mock_volume_list.return_value = self.cinder_volumes.list()
IsA(http.HttpRequest), marker=marker, sort_dir=sort_dir,
paginate=True).AndReturn([snapshots, has_more, has_prev])
api.cinder.volume_list(IsA(http.HttpRequest)).AndReturn(
self.cinder_volumes.list())
self.mox.ReplayAll()
res = self.client.get(urlunquote(url)) res = self.client.get(urlunquote(url))
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html') self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')
self.mox.UnsetStubs() self.assert_mock_multiple_calls_with_same_arguments(
self.mock_is_service_enabled, 2,
mock.call(test.IsHttpRequest(), 'volumev3'))
self.mock_volume_snapshot_list_paged.assert_called_once_with(
test.IsHttpRequest(), marker=marker, sort_dir=sort_dir,
paginate=True)
self.mock_volume_list.assert_called_once_with(test.IsHttpRequest())
return res return res
@override_settings(API_RESULT_PAGE_SIZE=1) @override_settings(API_RESULT_PAGE_SIZE=1)
@ -122,42 +121,36 @@ class VolumeSnapshotsViewTests(test.TestCase):
snapshots = res.context['volume_snapshots_table'].data snapshots = res.context['volume_snapshots_table'].data
self.assertItemsEqual(snapshots, expected_snapshots) self.assertItemsEqual(snapshots, expected_snapshots)
@test.create_stubs({cinder: ('volume_get',), @test.create_mocks({api.cinder: ('volume_get',),
quotas: ('tenant_limit_usages',)}) quotas: ('tenant_limit_usages',)})
def test_create_snapshot_get(self): def test_create_snapshot_get(self):
volume = self.cinder_volumes.first() volume = self.cinder_volumes.first()
cinder.volume_get(IsA(http.HttpRequest), volume.id) \ self.mock_volume_get.return_value = volume
.AndReturn(volume)
snapshot_used = len(self.cinder_volume_snapshots.list()) snapshot_used = len(self.cinder_volume_snapshots.list())
usage_limit = {'maxTotalVolumeGigabytes': 250, usage_limit = {'maxTotalVolumeGigabytes': 250,
'totalGigabytesUsed': 20, 'totalGigabytesUsed': 20,
'totalSnapshotsUsed': snapshot_used, 'totalSnapshotsUsed': snapshot_used,
'maxTotalSnapshots': 6} 'maxTotalSnapshots': 6}
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ self.mock_tenant_limit_usages.return_value = usage_limit
AndReturn(usage_limit)
self.mox.ReplayAll()
url = reverse('horizon:project:volumes:create_snapshot', url = reverse('horizon:project:volumes:create_snapshot',
args=[volume.id]) args=[volume.id])
res = self.client.get(url) res = self.client.get(url)
self.assertTemplateUsed(res, 'project/volumes/create_snapshot.html') self.assertTemplateUsed(res, 'project/volumes/create_snapshot.html')
self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
volume.id)
self.mock_tenant_limit_usages.assert_called_once_with(
test.IsHttpRequest())
@test.create_stubs({cinder: ('volume_get', @test.create_mocks({api.cinder: ('volume_get',
'volume_snapshot_create',)}) 'volume_snapshot_create')})
def test_create_snapshot_post(self): def test_create_snapshot_post(self):
volume = self.cinder_volumes.first() volume = self.cinder_volumes.first()
snapshot = self.cinder_volume_snapshots.first() snapshot = self.cinder_volume_snapshots.first()
cinder.volume_get(IsA(http.HttpRequest), volume.id) \ self.mock_volume_get.return_value = volume
.AndReturn(volume) self.mock_volume_snapshot_create.return_value = snapshot
cinder.volume_snapshot_create(IsA(http.HttpRequest),
volume.id,
snapshot.name,
snapshot.description,
force=False) \
.AndReturn(snapshot)
self.mox.ReplayAll()
formData = {'method': 'CreateSnapshotForm', formData = {'method': 'CreateSnapshotForm',
'tenant_id': self.tenant.id, 'tenant_id': self.tenant.id,
@ -169,21 +162,23 @@ class VolumeSnapshotsViewTests(test.TestCase):
res = self.client.post(url, formData) res = self.client.post(url, formData)
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({cinder: ('volume_get', self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
'volume_snapshot_create',)}) volume.id)
self.mock_volume_snapshot_create.assert_called_once_with(
test.IsHttpRequest(),
volume.id,
snapshot.name,
snapshot.description,
force=False)
@test.create_mocks({api.cinder: ('volume_get',
'volume_snapshot_create')})
def test_force_create_snapshot(self): def test_force_create_snapshot(self):
volume = self.cinder_volumes.get(name='my_volume') volume = self.cinder_volumes.get(name='my_volume')
snapshot = self.cinder_volume_snapshots.first() snapshot = self.cinder_volume_snapshots.first()
cinder.volume_get(IsA(http.HttpRequest), volume.id) \ self.mock_volume_get.return_value = volume
.AndReturn(volume) self.mock_volume_snapshot_create.return_value = snapshot
cinder.volume_snapshot_create(IsA(http.HttpRequest),
volume.id,
snapshot.name,
snapshot.description,
force=True) \
.AndReturn(snapshot)
self.mox.ReplayAll()
formData = {'method': 'CreateSnapshotForm', formData = {'method': 'CreateSnapshotForm',
'tenant_id': self.tenant.id, 'tenant_id': self.tenant.id,
@ -195,23 +190,27 @@ class VolumeSnapshotsViewTests(test.TestCase):
res = self.client.post(url, formData) res = self.client.post(url, formData)
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({api.cinder: ('volume_snapshot_list_paged', self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
volume.id)
self.mock_volume_snapshot_create.assert_called_once_with(
test.IsHttpRequest(),
volume.id,
snapshot.name,
snapshot.description,
force=True)
@test.create_mocks({api.cinder: ('volume_snapshot_list_paged',
'volume_list', 'volume_list',
'volume_snapshot_delete', 'volume_snapshot_delete')})
'tenant_absolute_limits')})
def test_delete_volume_snapshot(self): def test_delete_volume_snapshot(self):
vol_snapshots = self.cinder_volume_snapshots.list() vol_snapshots = self.cinder_volume_snapshots.list()
volumes = self.cinder_volumes.list() volumes = self.cinder_volumes.list()
snapshot = self.cinder_volume_snapshots.first() snapshot = self.cinder_volume_snapshots.first()
api.cinder.volume_snapshot_list_paged( self.mock_volume_snapshot_list_paged.return_value = [vol_snapshots,
IsA(http.HttpRequest), paginate=True, marker=None, False, False]
sort_dir='desc').AndReturn([vol_snapshots, False, False]) self.mock_volume_list.return_value = volumes
api.cinder.volume_list(IsA(http.HttpRequest)). \ self.mock_volume_snapshot_delete.return_value = None
AndReturn(volumes)
api.cinder.volume_snapshot_delete(IsA(http.HttpRequest), snapshot.id)
self.mox.ReplayAll()
formData = {'action': 'volume_snapshots__delete__%s' % snapshot.id} formData = {'action': 'volume_snapshots__delete__%s' % snapshot.id}
res = self.client.post(INDEX_URL, formData) res = self.client.post(INDEX_URL, formData)
@ -219,19 +218,20 @@ class VolumeSnapshotsViewTests(test.TestCase):
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
self.assertMessageCount(success=1) self.assertMessageCount(success=1)
@test.create_stubs({api.cinder: ('volume_snapshot_get', 'volume_get')}) self.mock_volume_snapshot_list_paged.assert_called_once_with(
test.IsHttpRequest(), paginate=True, marker=None, sort_dir='desc')
self.mock_volume_list.assert_called_once_with(test.IsHttpRequest())
self.mock_volume_snapshot_delete.assert_called_once_with(
test.IsHttpRequest(), snapshot.id)
@test.create_mocks({api.cinder: ('volume_get',
'volume_snapshot_get')})
def test_volume_snapshot_detail_get(self): def test_volume_snapshot_detail_get(self):
volume = self.cinder_volumes.first() volume = self.cinder_volumes.first()
snapshot = self.cinder_volume_snapshots.first() snapshot = self.cinder_volume_snapshots.first()
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \ self.mock_volume_get.return_value = volume
AndReturn(volume) self.mock_volume_snapshot_get.return_value = snapshot
api.cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id). \
AndReturn(snapshot)
api.cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id). \
AndReturn(volume)
self.mox.ReplayAll()
url = reverse('horizon:project:snapshots:detail', url = reverse('horizon:project:snapshots:detail',
args=[snapshot.id]) args=[snapshot.id])
@ -240,14 +240,20 @@ class VolumeSnapshotsViewTests(test.TestCase):
self.assertTemplateUsed(res, 'horizon/common/_detail.html') self.assertTemplateUsed(res, 'horizon/common/_detail.html')
self.assertEqual(res.context['snapshot'].id, snapshot.id) self.assertEqual(res.context['snapshot'].id, snapshot.id)
@test.create_stubs({api.cinder: ('volume_snapshot_get',)}) self.mock_volume_get.assert_has_calls([
mock.call(test.IsHttpRequest(), volume.id),
mock.call(test.IsHttpRequest(), snapshot.volume_id),
])
self.assertEqual(2, self.mock_volume_get.call_count)
self.mock_volume_snapshot_get.assert_called_once_with(
test.IsHttpRequest(), snapshot.id)
@test.create_mocks({api.cinder: ('volume_snapshot_get',)})
def test_volume_snapshot_detail_get_with_exception(self): def test_volume_snapshot_detail_get_with_exception(self):
# Test to verify redirect if get volume snapshot fails # Test to verify redirect if get volume snapshot fails
snapshot = self.cinder_volume_snapshots.first() snapshot = self.cinder_volume_snapshots.first()
api.cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id).\ self.mock_volume_snapshot_get.side_effect = self.exceptions.cinder
AndRaise(self.exceptions.cinder)
self.mox.ReplayAll()
url = reverse('horizon:project:snapshots:detail', url = reverse('horizon:project:snapshots:detail',
args=[snapshot.id]) args=[snapshot.id])
@ -255,38 +261,36 @@ class VolumeSnapshotsViewTests(test.TestCase):
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({api.cinder: ('volume_snapshot_get', 'volume_get')}) self.mock_volume_snapshot_get.assert_called_once_with(
test.IsHttpRequest(), snapshot.id)
@test.create_mocks({api.cinder: ('volume_get',
'volume_snapshot_get')})
def test_volume_snapshot_detail_with_volume_get_exception(self): def test_volume_snapshot_detail_with_volume_get_exception(self):
# Test to verify redirect if get volume fails # Test to verify redirect if get volume fails
volume = self.cinder_volumes.first() volume = self.cinder_volumes.first()
snapshot = self.cinder_volume_snapshots.first() snapshot = self.cinder_volume_snapshots.first()
api.cinder.volume_get(IsA(http.HttpRequest), volume.id). \ self.mock_volume_get.side_effect = self.exceptions.cinder
AndRaise(self.exceptions.cinder) self.mock_volume_snapshot_get.return_value = snapshot
api.cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id). \
AndReturn(snapshot)
self.mox.ReplayAll()
url = reverse('horizon:project:snapshots:detail', url = reverse('horizon:project:snapshots:detail',
args=[snapshot.id]) args=[snapshot.id])
res = self.client.get(url) res = self.client.get(url)
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
volume.id)
self.mock_volume_snapshot_get.assert_called_once_with(
test.IsHttpRequest(), snapshot.id)
@test.create_stubs({cinder: ('volume_snapshot_update', @test.create_mocks({api.cinder: ('volume_snapshot_update',
'volume_snapshot_get')}) 'volume_snapshot_get')})
def test_update_snapshot(self): def test_update_snapshot(self):
snapshot = self.cinder_volume_snapshots.first() snapshot = self.cinder_volume_snapshots.first()
cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id) \ self.mock_volume_snapshot_get.return_value = snapshot
.AndReturn(snapshot) self.mock_volume_snapshot_update.return_value = snapshot
cinder.volume_snapshot_update(IsA(http.HttpRequest),
snapshot.id,
snapshot.name,
snapshot.description) \
.AndReturn(snapshot)
self.mox.ReplayAll()
formData = {'method': 'UpdateSnapshotForm', formData = {'method': 'UpdateSnapshotForm',
'name': snapshot.name, 'name': snapshot.name,
@ -295,3 +299,11 @@ class VolumeSnapshotsViewTests(test.TestCase):
args=[snapshot.id]) args=[snapshot.id])
res = self.client.post(url, formData) res = self.client.post(url, formData)
self.assertRedirectsNoFollow(res, INDEX_URL) self.assertRedirectsNoFollow(res, INDEX_URL)
self.mock_volume_snapshot_get.assert_called_once_with(
test.IsHttpRequest(), snapshot.id)
self.mock_volume_snapshot_update.assert_called_once_with(
test.IsHttpRequest(),
snapshot.id,
snapshot.name,
snapshot.description)