Switch Cinder-related tests to mock

This patch changes mox to mock for the following test module:
* openstack_dashboard/dashboards/admin/volumes/tests.py

Change-Id: Id487feb397207b3544c9398a446077e3f6a39b1a
Partially-Implements: blueprint mock-framework-in-unit-tests
This commit is contained in:
Ivan Kolodyazhny 2017-10-06 16:36:08 +03:00
parent e94992f025
commit 14a350d013
2 changed files with 156 additions and 158 deletions

View File

@ -16,10 +16,9 @@ import copy
from django.conf import settings
from django.core.urlresolvers import reverse
from django import http
from django.test.utils import override_settings
from django.utils.http import urlunquote
from mox3.mox import IsA
import mock
from openstack_dashboard import api
from openstack_dashboard.api import cinder
@ -44,76 +43,77 @@ class VolumeTests(test.BaseAdminViewTests):
del att['instance']
super(VolumeTests, self).tearDown()
@test.create_stubs({api.nova: ('server_list', 'server_get'),
cinder: ('volume_list_paged',
'volume_snapshot_list'),
keystone: ('tenant_list',)})
def _test_index(self, instanceless_volumes=False):
@mock.patch.object(keystone, 'tenant_list')
@mock.patch.object(cinder, 'volume_snapshot_list')
@mock.patch.object(cinder, 'volume_list_paged')
@mock.patch.object(api.nova, 'server_list')
def _test_index(self, instanceless_volumes, mock_server_list,
mock_volume_list, mock_snapshot_list, mock_tenant_list):
volumes = self.cinder_volumes.list()
if instanceless_volumes:
for volume in volumes:
volume.attachments = []
else:
server = self.servers.first()
cinder.volume_list_paged(IsA(http.HttpRequest), sort_dir="desc",
marker=None, paginate=True,
search_opts={'all_tenants': True})\
.AndReturn([volumes, False, False])
cinder.volume_snapshot_list(IsA(http.HttpRequest), search_opts={
'all_tenants': True}).AndReturn([])
mock_volume_list.return_value = [volumes, False, False]
mock_snapshot_list.return_value = []
if not instanceless_volumes:
api.nova.server_get(IsA(http.HttpRequest),
server.id).AndReturn(server)
api.nova.server_list(IsA(http.HttpRequest), search_opts={
'all_tenants': True}, detailed=False) \
.AndReturn([self.servers.list(), False])
keystone.tenant_list(IsA(http.HttpRequest)) \
.AndReturn([self.tenants.list(), False])
mock_server_list.return_value = [self.servers.list(), False]
mock_tenant_list.return_value = [[self.tenants.list(), False]]
self.mox.ReplayAll()
res = self.client.get(INDEX_URL)
if not instanceless_volumes:
mock_server_list.assert_called_once_with(
test.IsHttpRequest(), search_opts={'all_tenants': True})
mock_volume_list.assert_called_once_with(
test.IsHttpRequest(), sort_dir="desc", marker=None, paginate=True,
search_opts={'all_tenants': True})
mock_snapshot_list.assert_called_once_with(
test.IsHttpRequest(), search_opts={'all_tenants': True})
mock_tenant_list.assert_called_once()
self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')
volumes = res.context['volumes_table'].data
self.assertItemsEqual(volumes, self.cinder_volumes.list())
def test_index_without_attachments(self):
self._test_index(instanceless_volumes=True)
self._test_index(True)
def test_index_with_attachments(self):
self._test_index(instanceless_volumes=False)
self._test_index(False)
@test.create_stubs({api.nova: ('server_list', 'server_get'),
cinder: ('volume_list_paged',
'volume_snapshot_list'),
keystone: ('tenant_list',)})
@mock.patch.object(keystone, 'tenant_list')
@mock.patch.object(cinder, 'volume_snapshot_list')
@mock.patch.object(cinder, 'volume_list_paged')
@mock.patch.object(api.nova, 'server_list')
def _test_index_paginated(self, marker, sort_dir, volumes, url,
has_more, has_prev):
has_more, has_prev, mock_server_list,
mock_volume_list, mock_snapshot_list,
mock_tenant_list):
vol_snaps = self.cinder_volume_snapshots.list()
server = self.servers.first()
cinder.volume_list_paged(IsA(http.HttpRequest), sort_dir=sort_dir,
marker=marker, paginate=True,
search_opts={'all_tenants': True}) \
.AndReturn([volumes, has_more, has_prev])
api.cinder.volume_snapshot_list(
IsA(http.HttpRequest), search_opts=None).AndReturn(vol_snaps)
api.nova.server_list(IsA(http.HttpRequest), search_opts={
'all_tenants': True}, detailed=False) \
.AndReturn([self.servers.list(), False])
api.nova.server_get(IsA(http.HttpRequest),
server.id).AndReturn(server)
keystone.tenant_list(IsA(http.HttpRequest)) \
.AndReturn([self.tenants.list(), False])
self.mox.ReplayAll()
mock_volume_list.return_value = [volumes, has_more, has_prev]
mock_snapshot_list.return_value = vol_snaps
mock_server_list.return_value = [self.servers.list(), False]
mock_tenant_list.return_value = [self.tenants.list(), False]
res = self.client.get(urlunquote(url))
mock_server_list.assert_called_once_with(
test.IsHttpRequest(), search_opts={'all_tenants': True})
mock_volume_list.assert_called_once_with(test.IsHttpRequest(),
sort_dir=sort_dir,
marker=marker, paginate=True,
search_opts={
'all_tenants': True})
mock_snapshot_list.assert_called_once_with(
test.IsHttpRequest(), search_opts={'all_tenants': True})
mock_tenant_list.assert_called_once()
self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')
self.assertEqual(res.status_code, 200)
self.mox.UnsetStubs()
return res
@override_settings(FILTER_DATA_FIRST={'admin.volumes': True})
@ -123,7 +123,7 @@ class VolumeTests(test.BaseAdminViewTests):
volumes = res.context['volumes_table'].data
self.assertItemsEqual(volumes, [])
def ensure_attachments_exist(self, volumes):
def _ensure_attachments_exist(self, volumes):
volumes = copy.copy(volumes)
for volume in volumes:
if not volume.attachments:
@ -134,14 +134,14 @@ class VolumeTests(test.BaseAdminViewTests):
@override_settings(API_RESULT_PAGE_SIZE=2)
def test_index_paginated(self):
size = settings.API_RESULT_PAGE_SIZE
mox_volumes = self.ensure_attachments_exist(self.cinder_volumes.list())
mox_volumes = self._ensure_attachments_exist(
self.cinder_volumes.list())
# get first page
expected_volumes = mox_volumes[:size]
url = INDEX_URL
res = self._test_index_paginated(marker=None, sort_dir="desc",
volumes=expected_volumes, url=url,
has_more=True, has_prev=False)
res = self._test_index_paginated(None, "desc", expected_volumes, url,
True, False)
volumes = res.context['volumes_table'].data
self.assertItemsEqual(volumes, expected_volumes)
@ -150,9 +150,8 @@ class VolumeTests(test.BaseAdminViewTests):
marker = expected_volumes[0].id
next = volume_tables.VolumesTable._meta.pagination_param
url = INDEX_URL + "?%s=%s" % (next, marker)
res = self._test_index_paginated(marker=marker, sort_dir="desc",
volumes=expected_volumes, url=url,
has_more=True, has_prev=True)
res = self._test_index_paginated(marker, "desc", expected_volumes, url,
True, True)
volumes = res.context['volumes_table'].data
self.assertItemsEqual(volumes, expected_volumes)
@ -161,25 +160,24 @@ class VolumeTests(test.BaseAdminViewTests):
marker = expected_volumes[0].id
next = volume_tables.VolumesTable._meta.pagination_param
url = INDEX_URL + "?%s=%s" % (next, marker)
res = self._test_index_paginated(marker=marker, sort_dir="desc",
volumes=expected_volumes, url=url,
has_more=False, has_prev=True)
res = self._test_index_paginated(marker, "desc", expected_volumes, url,
False, True)
volumes = res.context['volumes_table'].data
self.assertItemsEqual(volumes, expected_volumes)
@override_settings(API_RESULT_PAGE_SIZE=2)
def test_index_paginated_prev(self):
size = settings.API_RESULT_PAGE_SIZE
mox_volumes = self.ensure_attachments_exist(self.cinder_volumes.list())
mox_volumes = self._ensure_attachments_exist(
self.cinder_volumes.list())
# prev from some page
expected_volumes = mox_volumes[size:2 * size]
marker = mox_volumes[0].id
prev = volume_tables.VolumesTable._meta.prev_pagination_param
url = INDEX_URL + "?%s=%s" % (prev, marker)
res = self._test_index_paginated(marker=marker, sort_dir="asc",
volumes=expected_volumes, url=url,
has_more=False, has_prev=True)
res = self._test_index_paginated(marker, "asc", expected_volumes, url,
False, True)
volumes = res.context['volumes_table'].data
self.assertItemsEqual(volumes, expected_volumes)
@ -188,35 +186,36 @@ class VolumeTests(test.BaseAdminViewTests):
marker = mox_volumes[0].id
prev = volume_tables.VolumesTable._meta.prev_pagination_param
url = INDEX_URL + "?%s=%s" % (prev, marker)
res = self._test_index_paginated(marker=marker, sort_dir="asc",
volumes=expected_volumes, url=url,
has_more=True, has_prev=False)
res = self._test_index_paginated(marker, "asc", expected_volumes, url,
True, False)
volumes = res.context['volumes_table'].data
self.assertItemsEqual(volumes, expected_volumes)
@test.create_stubs({cinder: ('volume_reset_state',
'volume_get')})
def test_update_volume_status(self):
@mock.patch.object(cinder, 'volume_get')
@mock.patch.object(cinder, 'volume_reset_state')
def test_update_volume_status(self, mock_reset, mock_volume_get):
volume = self.volumes.first()
formData = {'status': 'error'}
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
cinder.volume_reset_state(IsA(http.HttpRequest),
volume.id,
formData['status'])
self.mox.ReplayAll()
mock_volume_get.return_value = volume
res = self.client.post(
reverse('horizon:admin:volumes:update_status',
args=(volume.id,)),
formData)
mock_reset.assert_called_once_with(test.IsHttpRequest(),
volume.id, formData['status'])
mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
volume.id)
self.assertNoFormErrors(res)
@test.create_stubs({cinder: ('volume_manage',
'volume_type_list',
'availability_zone_list',
'extension_supported')})
def test_manage_volume(self):
@mock.patch.object(cinder, 'extension_supported')
@mock.patch.object(cinder, 'availability_zone_list')
@mock.patch.object(cinder, 'volume_type_list')
@mock.patch.object(cinder, 'volume_manage')
def test_manage_volume(self, mock_manage, mock_type_list, mock_az_list,
mock_extension):
metadata = {'key': u'k1',
'value': u'v1'}
formData = {'host': 'host-1',
@ -228,18 +227,17 @@ class VolumeTests(test.BaseAdminViewTests):
'availability_zone': 'nova',
'metadata': metadata['key'] + '=' + metadata['value'],
'bootable': False}
cinder.volume_type_list(
IsA(http.HttpRequest)). \
AndReturn(self.cinder_volume_types.list())
cinder.availability_zone_list(
IsA(http.HttpRequest)). \
AndReturn(self.availability_zones.list())
cinder.extension_supported(
IsA(http.HttpRequest),
'AvailabilityZones'). \
AndReturn(True)
cinder.volume_manage(
IsA(http.HttpRequest),
mock_type_list.return_value = self.cinder_volume_types.list()
mock_az_list.return_value = self.availability_zones.list()
mock_extension.return_value = True
res = self.client.post(
reverse('horizon:admin:volumes:manage'),
formData)
mock_manage.assert_called_once_with(
test.IsHttpRequest(),
host=formData['host'],
identifier=formData['identifier'],
id_type=formData['id_type'],
@ -249,15 +247,15 @@ class VolumeTests(test.BaseAdminViewTests):
availability_zone=formData['availability_zone'],
metadata={metadata['key']: metadata['value']},
bootable=formData['bootable'])
self.mox.ReplayAll()
res = self.client.post(
reverse('horizon:admin:volumes:manage'),
formData)
mock_type_list.assert_called_once()
mock_az_list.assert_called_once()
mock_extension.assert_called_once_with(test.IsHttpRequest(),
'AvailabilityZones')
self.assertNoFormErrors(res)
@test.create_stubs({cinder: ('volume_unmanage',
'volume_get')})
def test_unmanage_volume(self):
@mock.patch.object(cinder, 'volume_get')
@mock.patch.object(cinder, 'volume_unmanage')
def test_unmanage_volume(self, mock_unmanage, mock_get):
# important - need to get the v2 cinder volume which has host data
volume_list = [x for x in self.cinder_volumes.list()
if x.name == 'v2_volume']
@ -266,111 +264,105 @@ class VolumeTests(test.BaseAdminViewTests):
'host_name': 'host@backend-name#pool',
'volume_id': volume.id}
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
cinder.volume_unmanage(IsA(http.HttpRequest), volume.id). \
AndReturn(volume)
self.mox.ReplayAll()
mock_get.return_value = volume
mock_unmanage.return_value = volume
res = self.client.post(
reverse('horizon:admin:volumes:unmanage',
args=(volume.id,)),
formData)
mock_unmanage.assert_called_once_with(test.IsHttpRequest(), volume.id)
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
self.assertNoFormErrors(res)
@test.create_stubs({cinder: ('pool_list',
'volume_get',)})
def test_volume_migrate_get(self):
@mock.patch.object(cinder, 'volume_get')
@mock.patch.object(cinder, 'pool_list')
def test_volume_migrate_get(self, mock_pool, mock_get):
volume = self.cinder_volumes.get(name='v2_volume')
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndReturn(volume)
cinder.pool_list(IsA(http.HttpRequest)) \
.AndReturn(self.cinder_pools.list())
self.mox.ReplayAll()
mock_pool.return_value = self.cinder_pools.list()
mock_get.return_value = volume
url = reverse('horizon:admin:volumes:migrate',
args=[volume.id])
res = self.client.get(url)
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
mock_pool.assert_called_once()
self.assertTemplateUsed(res,
'admin/volumes/migrate_volume.html')
@test.create_stubs({cinder: ('volume_get',)})
def test_volume_migrate_get_volume_get_exception(self):
@mock.patch.object(cinder, 'volume_get')
def test_volume_migrate_get_volume_get_exception(self, mock_get):
volume = self.cinder_volumes.get(name='v2_volume')
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndRaise(self.exceptions.cinder)
self.mox.ReplayAll()
mock_get.side_effect = self.exceptions.cinder
url = reverse('horizon:admin:volumes:migrate',
args=[volume.id])
res = self.client.get(url)
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({cinder: ('pool_list',
'volume_get',)})
def test_volume_migrate_list_pool_get_exception(self):
@mock.patch.object(cinder, 'volume_get')
@mock.patch.object(cinder, 'pool_list')
def test_volume_migrate_list_pool_get_exception(self, mock_pool, mock_get):
volume = self.cinder_volumes.get(name='v2_volume')
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndReturn(volume)
cinder.pool_list(IsA(http.HttpRequest)) \
.AndRaise(self.exceptions.cinder)
self.mox.ReplayAll()
mock_get.return_value = volume
mock_pool.side_effect = self.exceptions.cinder
url = reverse('horizon:admin:volumes:migrate',
args=[volume.id])
res = self.client.get(url)
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
mock_pool.assert_called_once()
self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({cinder: ('pool_list',
'volume_get',
'volume_migrate',)})
def test_volume_migrate_post(self):
@mock.patch.object(cinder, 'volume_migrate')
@mock.patch.object(cinder, 'volume_get')
@mock.patch.object(cinder, 'pool_list')
def test_volume_migrate_post(self, mock_pool, mock_get, mock_migtate):
volume = self.cinder_volumes.get(name='v2_volume')
host = self.cinder_pools.first().name
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndReturn(volume)
cinder.pool_list(IsA(http.HttpRequest)) \
.AndReturn(self.cinder_pools.list())
cinder.volume_migrate(IsA(http.HttpRequest),
volume.id,
host,
False) \
.AndReturn(None)
self.mox.ReplayAll()
mock_get.return_value = volume
mock_pool.return_value = self.cinder_pools.list()
mock_migtate.return_value = None
url = reverse('horizon:admin:volumes:migrate',
args=[volume.id])
res = self.client.post(url, {'host': host, 'volume_id': volume.id})
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
mock_pool.assert_called_once()
mock_migtate.assert_called_once_with(test.IsHttpRequest(),
volume.id, host, False)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, INDEX_URL)
@test.create_stubs({cinder: ('pool_list',
'volume_get',
'volume_migrate',)})
def test_volume_migrate_post_api_exception(self):
@mock.patch.object(cinder, 'volume_migrate')
@mock.patch.object(cinder, 'volume_get')
@mock.patch.object(cinder, 'pool_list')
def test_volume_migrate_post_api_exception(self, mock_pool, mock_get,
mock_migtate):
volume = self.cinder_volumes.get(name='v2_volume')
host = self.cinder_pools.first().name
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndReturn(volume)
cinder.pool_list(IsA(http.HttpRequest)) \
.AndReturn(self.cinder_pools.list())
cinder.volume_migrate(IsA(http.HttpRequest),
volume.id,
host,
False) \
.AndRaise(self.exceptions.cinder)
self.mox.ReplayAll()
mock_get.return_value = volume
mock_pool.return_value = self.cinder_pools.list()
mock_migtate.side_effect = self.exceptions.cinder
url = reverse('horizon:admin:volumes:migrate',
args=[volume.id])
res = self.client.post(url, {'host': host, 'volume_id': volume.id})
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
mock_pool.assert_called_once()
mock_migtate.assert_called_once_with(test.IsHttpRequest(), volume.id,
host, False)
self.assertRedirectsNoFollow(res, INDEX_URL)
def test_get_volume_status_choices_without_current(self):
@ -381,16 +373,15 @@ class VolumeTests(test.BaseAdminViewTests):
self.assertNotIn(current_status,
[status[0] for status in status_choices])
@test.create_stubs({cinder: ('volume_get',)})
def test_update_volume_status_get(self):
@mock.patch.object(cinder, 'volume_get')
def test_update_volume_status_get(self, mock_get):
volume = self.cinder_volumes.get(name='v2_volume')
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndReturn(volume)
self.mox.ReplayAll()
mock_get.return_value = volume
url = reverse('horizon:admin:volumes:update_status',
args=[volume.id])
res = self.client.get(url)
status_option = "<option value=\"%s\"></option>" % volume.status
mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)
self.assertNotContains(res, status_option)

View File

@ -30,6 +30,7 @@ from django.conf import settings
from django.contrib.messages.storage import default_storage
from django.core.handlers import wsgi
from django.core import urlresolvers
from django import http as http_request
from django.test.client import RequestFactory
from django.test import utils as django_test_utils
from django.utils import http
@ -693,3 +694,9 @@ def mock_factory(r):
mocked = mock_obj_to_dict(r)
mocked.configure_mock(**r)
return mocked
class IsHttpRequest(object):
"""Class to compare param is django.http.HttpRequest."""
def __eq__(self, other):
return isinstance(other, http_request.HttpRequest)