[5/11] Refactor test_volume file
Due to the situation, that we've already had more that 7000 lines of code in this file and it contains different test cases, it is reasonably to divide it into smaller files. This patch includes test cases that are connected with capabilities and getting volumes by active window test cases. Change-Id: If59f29b2fe6ebc526bf2f08a34f45ef5303442ce
This commit is contained in:
parent
b02818ec10
commit
be301c3d97
|
@ -29,7 +29,6 @@ import mock
|
|||
import os_brick
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_config import cfg
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import imageutils
|
||||
from oslo_utils import units
|
||||
import six
|
||||
|
@ -1042,29 +1041,6 @@ class VolumeTestCase(base.BaseVolumeTestCase):
|
|||
self.context,
|
||||
volume['id'])
|
||||
|
||||
def test_extra_capabilities(self):
|
||||
# Test valid extra_capabilities.
|
||||
fake_capabilities = {'key1': 1, 'key2': 2}
|
||||
|
||||
with mock.patch.object(jsonutils, 'loads') as mock_loads:
|
||||
mock_loads.return_value = fake_capabilities
|
||||
manager = vol_manager.VolumeManager()
|
||||
manager.stats = {'pools': {}}
|
||||
manager.driver.set_initialized()
|
||||
manager.publish_service_capabilities(self.context)
|
||||
self.assertTrue(mock_loads.called)
|
||||
volume_stats = manager.last_capabilities
|
||||
self.assertEqual(fake_capabilities['key1'],
|
||||
volume_stats['key1'])
|
||||
self.assertEqual(fake_capabilities['key2'],
|
||||
volume_stats['key2'])
|
||||
|
||||
def test_extra_capabilities_fail(self):
|
||||
with mock.patch.object(jsonutils, 'loads') as mock_loads:
|
||||
mock_loads.side_effect = exception.CinderException('test')
|
||||
self.assertRaises(exception.CinderException,
|
||||
vol_manager.VolumeManager)
|
||||
|
||||
def test_delete_busy_volume(self):
|
||||
"""Test volume survives deletion if driver reports it as busy."""
|
||||
volume = tests_utils.create_volume(self.context, **self.volume_params)
|
||||
|
@ -4530,163 +4506,6 @@ class VolumeTestCase(base.BaseVolumeTestCase):
|
|||
volume = objects.Volume.get_by_id(self.context, volume.id)
|
||||
self.assertEqual('deleting', volume.status)
|
||||
|
||||
@mock.patch.object(fake_driver.FakeLoggingVolumeDriver, 'get_volume_stats')
|
||||
@mock.patch.object(driver.BaseVD, '_init_vendor_properties')
|
||||
def test_get_capabilities(self, mock_init_vendor, mock_get_volume_stats):
|
||||
stats = {
|
||||
'volume_backend_name': 'lvm',
|
||||
'vendor_name': 'Open Source',
|
||||
'storage_protocol': 'iSCSI',
|
||||
'vendor_prefix': 'abcd'
|
||||
}
|
||||
expected = stats.copy()
|
||||
expected['properties'] = {
|
||||
'compression': {
|
||||
'title': 'Compression',
|
||||
'description': 'Enables compression.',
|
||||
'type': 'boolean'},
|
||||
'qos': {
|
||||
'title': 'QoS',
|
||||
'description': 'Enables QoS.',
|
||||
'type': 'boolean'},
|
||||
'replication_enabled': {
|
||||
'title': 'Replication',
|
||||
'description': 'Enables replication.',
|
||||
'type': 'boolean'},
|
||||
'thin_provisioning': {
|
||||
'title': 'Thin Provisioning',
|
||||
'description': 'Sets thin provisioning.',
|
||||
'type': 'boolean'},
|
||||
}
|
||||
|
||||
# Test to get updated capabilities
|
||||
discover = True
|
||||
mock_get_volume_stats.return_value = stats
|
||||
mock_init_vendor.return_value = ({}, None)
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities)
|
||||
mock_get_volume_stats.assert_called_once_with(True)
|
||||
|
||||
# Test to get existing original capabilities
|
||||
mock_get_volume_stats.reset_mock()
|
||||
discover = False
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities)
|
||||
self.assertFalse(mock_get_volume_stats.called)
|
||||
|
||||
# Normal test case to get vendor unique capabilities
|
||||
def init_vendor_properties(self):
|
||||
properties = {}
|
||||
self._set_property(
|
||||
properties,
|
||||
"abcd:minIOPS",
|
||||
"Minimum IOPS QoS",
|
||||
"Sets minimum IOPS if QoS is enabled.",
|
||||
"integer",
|
||||
minimum=10,
|
||||
default=100)
|
||||
return properties, 'abcd'
|
||||
|
||||
expected['properties'].update(
|
||||
{'abcd:minIOPS': {
|
||||
'title': 'Minimum IOPS QoS',
|
||||
'description': 'Sets minimum IOPS if QoS is enabled.',
|
||||
'type': 'integer',
|
||||
'minimum': 10,
|
||||
'default': 100}})
|
||||
|
||||
mock_get_volume_stats.reset_mock()
|
||||
mock_init_vendor.reset_mock()
|
||||
discover = True
|
||||
mock_init_vendor.return_value = (
|
||||
init_vendor_properties(self.volume.driver))
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities)
|
||||
self.assertTrue(mock_get_volume_stats.called)
|
||||
|
||||
@mock.patch.object(fake_driver.FakeLoggingVolumeDriver, 'get_volume_stats')
|
||||
@mock.patch.object(driver.BaseVD, '_init_vendor_properties')
|
||||
@mock.patch.object(driver.BaseVD, '_init_standard_capabilities')
|
||||
def test_get_capabilities_prefix_error(self, mock_init_standard,
|
||||
mock_init_vendor,
|
||||
mock_get_volume_stats):
|
||||
|
||||
# Error test case: propety does not match vendor prefix
|
||||
def init_vendor_properties(self):
|
||||
properties = {}
|
||||
self._set_property(
|
||||
properties,
|
||||
"aaa:minIOPS",
|
||||
"Minimum IOPS QoS",
|
||||
"Sets minimum IOPS if QoS is enabled.",
|
||||
"integer")
|
||||
self._set_property(
|
||||
properties,
|
||||
"abcd:compression_type",
|
||||
"Compression type",
|
||||
"Specifies compression type.",
|
||||
"string")
|
||||
|
||||
return properties, 'abcd'
|
||||
|
||||
expected = {
|
||||
'abcd:compression_type': {
|
||||
'title': 'Compression type',
|
||||
'description': 'Specifies compression type.',
|
||||
'type': 'string'}}
|
||||
|
||||
discover = True
|
||||
mock_get_volume_stats.return_value = {}
|
||||
mock_init_standard.return_value = {}
|
||||
mock_init_vendor.return_value = (
|
||||
init_vendor_properties(self.volume.driver))
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities['properties'])
|
||||
|
||||
@mock.patch.object(fake_driver.FakeLoggingVolumeDriver, 'get_volume_stats')
|
||||
@mock.patch.object(driver.BaseVD, '_init_vendor_properties')
|
||||
@mock.patch.object(driver.BaseVD, '_init_standard_capabilities')
|
||||
def test_get_capabilities_fail_override(self, mock_init_standard,
|
||||
mock_init_vendor,
|
||||
mock_get_volume_stats):
|
||||
|
||||
# Error test case: propety cannot override any standard capabilities
|
||||
def init_vendor_properties(self):
|
||||
properties = {}
|
||||
self._set_property(
|
||||
properties,
|
||||
"qos",
|
||||
"Minimum IOPS QoS",
|
||||
"Sets minimum IOPS if QoS is enabled.",
|
||||
"integer")
|
||||
self._set_property(
|
||||
properties,
|
||||
"ab::cd:compression_type",
|
||||
"Compression type",
|
||||
"Specifies compression type.",
|
||||
"string")
|
||||
|
||||
return properties, 'ab::cd'
|
||||
|
||||
expected = {
|
||||
'ab__cd:compression_type': {
|
||||
'title': 'Compression type',
|
||||
'description': 'Specifies compression type.',
|
||||
'type': 'string'}}
|
||||
|
||||
discover = True
|
||||
mock_get_volume_stats.return_value = {}
|
||||
mock_init_standard.return_value = {}
|
||||
mock_init_vendor.return_value = (
|
||||
init_vendor_properties(self.volume.driver))
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities['properties'])
|
||||
|
||||
@mock.patch.object(driver.BaseVD, 'get_backup_device')
|
||||
@mock.patch.object(driver.BaseVD, 'secure_file_operations_enabled')
|
||||
def test_get_backup_device(self, mock_secure, mock_get_backup):
|
||||
|
@ -5883,238 +5702,6 @@ class CopyVolumeToImageTestCase(base.BaseVolumeTestCase):
|
|||
self.assertTrue(mock_delete.called)
|
||||
|
||||
|
||||
class GetActiveByWindowTestCase(base.BaseVolumeTestCase):
|
||||
def setUp(self):
|
||||
super(GetActiveByWindowTestCase, self).setUp()
|
||||
self.ctx = context.get_admin_context(read_deleted="yes")
|
||||
self.db_vol_attrs = [
|
||||
{
|
||||
'id': fake.VOLUME_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True, 'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 2, 1, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME2_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True, 'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME3_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True, 'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME4_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME5_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
}
|
||||
]
|
||||
|
||||
self.db_snap_attrs = [
|
||||
{
|
||||
'id': fake.SNAPSHOT_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True,
|
||||
'status': fields.SnapshotStatus.DELETED,
|
||||
'deleted_at': datetime.datetime(1, 2, 1, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
|
||||
{
|
||||
'id': fake.SNAPSHOT2_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True,
|
||||
'status': fields.SnapshotStatus.DELETED,
|
||||
'deleted_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
{
|
||||
'id': fake.SNAPSHOT3_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True,
|
||||
'status': fields.SnapshotStatus.DELETED,
|
||||
'deleted_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
{
|
||||
'id': fake.SNAPSHOT_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
{
|
||||
'id': fake.SNAPSHOT2_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID
|
||||
}
|
||||
]
|
||||
|
||||
self.db_back_attrs = [
|
||||
{
|
||||
'id': fake.BACKUP_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': 1,
|
||||
'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 2, 1, 1, 1, 1)
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP2_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': 1,
|
||||
'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 3, 10, 1, 1, 1)
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP3_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': 1,
|
||||
'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 5, 1, 1, 1, 1)
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP4_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP5_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
},
|
||||
]
|
||||
|
||||
def test_volume_get_all_active_by_window(self):
|
||||
# Find all all volumes valid within a timeframe window.
|
||||
|
||||
# Not in window
|
||||
db.volume_create(self.ctx, self.db_vol_attrs[0])
|
||||
|
||||
# In - deleted in window
|
||||
db.volume_create(self.ctx, self.db_vol_attrs[1])
|
||||
|
||||
# In - deleted after window
|
||||
db.volume_create(self.ctx, self.db_vol_attrs[2])
|
||||
|
||||
# In - created in window
|
||||
db.volume_create(self.context, self.db_vol_attrs[3])
|
||||
|
||||
# Not of window.
|
||||
db.volume_create(self.context, self.db_vol_attrs[4])
|
||||
|
||||
volumes = db.volume_get_all_active_by_window(
|
||||
self.context,
|
||||
datetime.datetime(1, 3, 1, 1, 1, 1),
|
||||
datetime.datetime(1, 4, 1, 1, 1, 1),
|
||||
project_id=fake.PROJECT_ID)
|
||||
self.assertEqual(3, len(volumes))
|
||||
self.assertEqual(fake.VOLUME2_ID, volumes[0].id)
|
||||
self.assertEqual(fake.VOLUME3_ID, volumes[1].id)
|
||||
self.assertEqual(fake.VOLUME4_ID, volumes[2].id)
|
||||
|
||||
def test_snapshot_get_all_active_by_window(self):
|
||||
# Find all all snapshots valid within a timeframe window.
|
||||
db.volume_create(self.context, {'id': fake.VOLUME_ID})
|
||||
for i in range(5):
|
||||
self.db_vol_attrs[i]['volume_id'] = fake.VOLUME_ID
|
||||
|
||||
# Not in window
|
||||
del self.db_snap_attrs[0]['id']
|
||||
snap1 = objects.Snapshot(self.ctx, **self.db_snap_attrs[0])
|
||||
snap1.create()
|
||||
|
||||
# In - deleted in window
|
||||
del self.db_snap_attrs[1]['id']
|
||||
snap2 = objects.Snapshot(self.ctx, **self.db_snap_attrs[1])
|
||||
snap2.create()
|
||||
|
||||
# In - deleted after window
|
||||
del self.db_snap_attrs[2]['id']
|
||||
snap3 = objects.Snapshot(self.ctx, **self.db_snap_attrs[2])
|
||||
snap3.create()
|
||||
|
||||
# In - created in window
|
||||
del self.db_snap_attrs[3]['id']
|
||||
snap4 = objects.Snapshot(self.ctx, **self.db_snap_attrs[3])
|
||||
snap4.create()
|
||||
|
||||
# Not of window.
|
||||
del self.db_snap_attrs[4]['id']
|
||||
snap5 = objects.Snapshot(self.ctx, **self.db_snap_attrs[4])
|
||||
snap5.create()
|
||||
|
||||
snapshots = objects.SnapshotList.get_all_active_by_window(
|
||||
self.context,
|
||||
datetime.datetime(1, 3, 1, 1, 1, 1),
|
||||
datetime.datetime(1, 4, 1, 1, 1, 1)).objects
|
||||
self.assertEqual(3, len(snapshots))
|
||||
self.assertEqual(snap2.id, snapshots[0].id)
|
||||
self.assertEqual(fake.VOLUME_ID, snapshots[0].volume_id)
|
||||
self.assertEqual(snap3.id, snapshots[1].id)
|
||||
self.assertEqual(fake.VOLUME_ID, snapshots[1].volume_id)
|
||||
self.assertEqual(snap4.id, snapshots[2].id)
|
||||
self.assertEqual(fake.VOLUME_ID, snapshots[2].volume_id)
|
||||
|
||||
def test_backup_get_all_active_by_window(self):
|
||||
# Find all backups valid within a timeframe window.
|
||||
db.volume_create(self.context, {'id': fake.VOLUME_ID})
|
||||
for i in range(5):
|
||||
self.db_back_attrs[i]['volume_id'] = fake.VOLUME_ID
|
||||
|
||||
# Not in window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[0])
|
||||
|
||||
# In - deleted in window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[1])
|
||||
|
||||
# In - deleted after window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[2])
|
||||
|
||||
# In - created in window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[3])
|
||||
|
||||
# Not of window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[4])
|
||||
|
||||
backups = db.backup_get_all_active_by_window(
|
||||
self.context,
|
||||
datetime.datetime(1, 3, 1, 1, 1, 1),
|
||||
datetime.datetime(1, 4, 1, 1, 1, 1),
|
||||
project_id=fake.PROJECT_ID
|
||||
)
|
||||
self.assertEqual(3, len(backups))
|
||||
self.assertEqual(fake.BACKUP2_ID, backups[0].id)
|
||||
self.assertEqual(fake.BACKUP3_ID, backups[1].id)
|
||||
self.assertEqual(fake.BACKUP4_ID, backups[2].id)
|
||||
|
||||
|
||||
class ImageVolumeCacheTestCase(base.BaseVolumeTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from cinder import exception
|
||||
from cinder.tests import fake_driver
|
||||
from cinder.tests.unit import volume as base
|
||||
from cinder.volume import driver
|
||||
from cinder.volume import manager as vol_manager
|
||||
# import cinder.volume.targets.tgt
|
||||
|
||||
"""Tests for volume capabilities test cases."""
|
||||
|
||||
|
||||
class VolumeCapabilitiesTestCase(base.BaseVolumeTestCase):
|
||||
@mock.patch.object(fake_driver.FakeLoggingVolumeDriver, 'get_volume_stats')
|
||||
@mock.patch.object(driver.BaseVD, '_init_vendor_properties')
|
||||
def test_get_capabilities(self, mock_init_vendor, mock_get_volume_stats):
|
||||
stats = {
|
||||
'volume_backend_name': 'lvm',
|
||||
'vendor_name': 'Open Source',
|
||||
'storage_protocol': 'iSCSI',
|
||||
'vendor_prefix': 'abcd'
|
||||
}
|
||||
expected = stats.copy()
|
||||
expected['properties'] = {
|
||||
'compression': {
|
||||
'title': 'Compression',
|
||||
'description': 'Enables compression.',
|
||||
'type': 'boolean'},
|
||||
'qos': {
|
||||
'title': 'QoS',
|
||||
'description': 'Enables QoS.',
|
||||
'type': 'boolean'},
|
||||
'replication_enabled': {
|
||||
'title': 'Replication',
|
||||
'description': 'Enables replication.',
|
||||
'type': 'boolean'},
|
||||
'thin_provisioning': {
|
||||
'title': 'Thin Provisioning',
|
||||
'description': 'Sets thin provisioning.',
|
||||
'type': 'boolean'},
|
||||
}
|
||||
|
||||
# Test to get updated capabilities
|
||||
discover = True
|
||||
mock_get_volume_stats.return_value = stats
|
||||
mock_init_vendor.return_value = ({}, None)
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities)
|
||||
mock_get_volume_stats.assert_called_once_with(True)
|
||||
|
||||
# Test to get existing original capabilities
|
||||
mock_get_volume_stats.reset_mock()
|
||||
discover = False
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities)
|
||||
self.assertFalse(mock_get_volume_stats.called)
|
||||
|
||||
# Normal test case to get vendor unique capabilities
|
||||
def init_vendor_properties(self):
|
||||
properties = {}
|
||||
self._set_property(
|
||||
properties,
|
||||
"abcd:minIOPS",
|
||||
"Minimum IOPS QoS",
|
||||
"Sets minimum IOPS if QoS is enabled.",
|
||||
"integer",
|
||||
minimum=10,
|
||||
default=100)
|
||||
return properties, 'abcd'
|
||||
|
||||
expected['properties'].update(
|
||||
{'abcd:minIOPS': {
|
||||
'title': 'Minimum IOPS QoS',
|
||||
'description': 'Sets minimum IOPS if QoS is enabled.',
|
||||
'type': 'integer',
|
||||
'minimum': 10,
|
||||
'default': 100}})
|
||||
|
||||
mock_get_volume_stats.reset_mock()
|
||||
mock_init_vendor.reset_mock()
|
||||
discover = True
|
||||
mock_init_vendor.return_value = (
|
||||
init_vendor_properties(self.volume.driver))
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities)
|
||||
self.assertTrue(mock_get_volume_stats.called)
|
||||
|
||||
@mock.patch.object(fake_driver.FakeLoggingVolumeDriver, 'get_volume_stats')
|
||||
@mock.patch.object(driver.BaseVD, '_init_vendor_properties')
|
||||
@mock.patch.object(driver.BaseVD, '_init_standard_capabilities')
|
||||
def test_get_capabilities_prefix_error(self, mock_init_standard,
|
||||
mock_init_vendor,
|
||||
mock_get_volume_stats):
|
||||
|
||||
# Error test case: propety does not match vendor prefix
|
||||
def init_vendor_properties(self):
|
||||
properties = {}
|
||||
self._set_property(
|
||||
properties,
|
||||
"aaa:minIOPS",
|
||||
"Minimum IOPS QoS",
|
||||
"Sets minimum IOPS if QoS is enabled.",
|
||||
"integer")
|
||||
self._set_property(
|
||||
properties,
|
||||
"abcd:compression_type",
|
||||
"Compression type",
|
||||
"Specifies compression type.",
|
||||
"string")
|
||||
|
||||
return properties, 'abcd'
|
||||
|
||||
expected = {
|
||||
'abcd:compression_type': {
|
||||
'title': 'Compression type',
|
||||
'description': 'Specifies compression type.',
|
||||
'type': 'string'}}
|
||||
|
||||
discover = True
|
||||
mock_get_volume_stats.return_value = {}
|
||||
mock_init_standard.return_value = {}
|
||||
mock_init_vendor.return_value = (
|
||||
init_vendor_properties(self.volume.driver))
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities['properties'])
|
||||
|
||||
@mock.patch.object(fake_driver.FakeLoggingVolumeDriver, 'get_volume_stats')
|
||||
@mock.patch.object(driver.BaseVD, '_init_vendor_properties')
|
||||
@mock.patch.object(driver.BaseVD, '_init_standard_capabilities')
|
||||
def test_get_capabilities_fail_override(self, mock_init_standard,
|
||||
mock_init_vendor,
|
||||
mock_get_volume_stats):
|
||||
|
||||
# Error test case: propety cannot override any standard capabilities
|
||||
def init_vendor_properties(self):
|
||||
properties = {}
|
||||
self._set_property(
|
||||
properties,
|
||||
"qos",
|
||||
"Minimum IOPS QoS",
|
||||
"Sets minimum IOPS if QoS is enabled.",
|
||||
"integer")
|
||||
self._set_property(
|
||||
properties,
|
||||
"ab::cd:compression_type",
|
||||
"Compression type",
|
||||
"Specifies compression type.",
|
||||
"string")
|
||||
|
||||
return properties, 'ab::cd'
|
||||
|
||||
expected = {
|
||||
'ab__cd:compression_type': {
|
||||
'title': 'Compression type',
|
||||
'description': 'Specifies compression type.',
|
||||
'type': 'string'}}
|
||||
|
||||
discover = True
|
||||
mock_get_volume_stats.return_value = {}
|
||||
mock_init_standard.return_value = {}
|
||||
mock_init_vendor.return_value = (
|
||||
init_vendor_properties(self.volume.driver))
|
||||
capabilities = self.volume.get_capabilities(self.context,
|
||||
discover)
|
||||
self.assertEqual(expected, capabilities['properties'])
|
||||
|
||||
def test_extra_capabilities(self):
|
||||
# Test valid extra_capabilities.
|
||||
fake_capabilities = {'key1': 1, 'key2': 2}
|
||||
|
||||
with mock.patch.object(jsonutils, 'loads') as mock_loads:
|
||||
mock_loads.return_value = fake_capabilities
|
||||
manager = vol_manager.VolumeManager()
|
||||
manager.stats = {'pools': {}}
|
||||
manager.driver.set_initialized()
|
||||
manager.publish_service_capabilities(self.context)
|
||||
self.assertTrue(mock_loads.called)
|
||||
volume_stats = manager.last_capabilities
|
||||
self.assertEqual(fake_capabilities['key1'],
|
||||
volume_stats['key1'])
|
||||
self.assertEqual(fake_capabilities['key2'],
|
||||
volume_stats['key2'])
|
||||
|
||||
def test_extra_capabilities_fail(self):
|
||||
with mock.patch.object(jsonutils, 'loads') as mock_loads:
|
||||
mock_loads.side_effect = exception.CinderException('test')
|
||||
self.assertRaises(exception.CinderException,
|
||||
vol_manager.VolumeManager)
|
|
@ -0,0 +1,257 @@
|
|||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""Tests for Volume usage audit feature."""
|
||||
|
||||
import datetime
|
||||
|
||||
from cinder import context
|
||||
from cinder import db
|
||||
from cinder import objects
|
||||
from cinder.objects import fields
|
||||
from cinder.tests.unit import fake_constants as fake
|
||||
from cinder.tests.unit import volume as base
|
||||
|
||||
|
||||
class GetActiveByWindowTestCase(base.BaseVolumeTestCase):
|
||||
def setUp(self):
|
||||
super(GetActiveByWindowTestCase, self).setUp()
|
||||
self.ctx = context.get_admin_context(read_deleted="yes")
|
||||
self.db_vol_attrs = [
|
||||
{
|
||||
'id': fake.VOLUME_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True, 'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 2, 1, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME2_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True, 'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME3_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True, 'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME4_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.VOLUME5_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
}
|
||||
]
|
||||
|
||||
self.db_snap_attrs = [
|
||||
{
|
||||
'id': fake.SNAPSHOT_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True,
|
||||
'status': fields.SnapshotStatus.DELETED,
|
||||
'deleted_at': datetime.datetime(1, 2, 1, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
|
||||
{
|
||||
'id': fake.SNAPSHOT2_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True,
|
||||
'status': fields.SnapshotStatus.DELETED,
|
||||
'deleted_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
{
|
||||
'id': fake.SNAPSHOT3_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': True,
|
||||
'status': fields.SnapshotStatus.DELETED,
|
||||
'deleted_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
{
|
||||
'id': fake.SNAPSHOT_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID,
|
||||
},
|
||||
{
|
||||
'id': fake.SNAPSHOT2_ID,
|
||||
'project_id': 'p1',
|
||||
'created_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
'volume_id': fake.VOLUME_ID
|
||||
}
|
||||
]
|
||||
|
||||
self.db_back_attrs = [
|
||||
{
|
||||
'id': fake.BACKUP_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': 1,
|
||||
'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 2, 1, 1, 1, 1)
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP2_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': 1,
|
||||
'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 3, 10, 1, 1, 1)
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP3_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'deleted': 1,
|
||||
'status': 'deleted',
|
||||
'deleted_at': datetime.datetime(1, 5, 1, 1, 1, 1)
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP4_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 3, 10, 1, 1, 1),
|
||||
},
|
||||
{
|
||||
'id': fake.BACKUP5_ID,
|
||||
'host': 'devstack',
|
||||
'project_id': fake.PROJECT_ID,
|
||||
'created_at': datetime.datetime(1, 5, 1, 1, 1, 1),
|
||||
},
|
||||
]
|
||||
|
||||
def test_volume_get_all_active_by_window(self):
|
||||
# Find all all volumes valid within a timeframe window.
|
||||
|
||||
# Not in window
|
||||
db.volume_create(self.ctx, self.db_vol_attrs[0])
|
||||
|
||||
# In - deleted in window
|
||||
db.volume_create(self.ctx, self.db_vol_attrs[1])
|
||||
|
||||
# In - deleted after window
|
||||
db.volume_create(self.ctx, self.db_vol_attrs[2])
|
||||
|
||||
# In - created in window
|
||||
db.volume_create(self.context, self.db_vol_attrs[3])
|
||||
|
||||
# Not of window.
|
||||
db.volume_create(self.context, self.db_vol_attrs[4])
|
||||
|
||||
volumes = db.volume_get_all_active_by_window(
|
||||
self.context,
|
||||
datetime.datetime(1, 3, 1, 1, 1, 1),
|
||||
datetime.datetime(1, 4, 1, 1, 1, 1),
|
||||
project_id=fake.PROJECT_ID)
|
||||
self.assertEqual(3, len(volumes))
|
||||
self.assertEqual(fake.VOLUME2_ID, volumes[0].id)
|
||||
self.assertEqual(fake.VOLUME3_ID, volumes[1].id)
|
||||
self.assertEqual(fake.VOLUME4_ID, volumes[2].id)
|
||||
|
||||
def test_snapshot_get_all_active_by_window(self):
|
||||
# Find all all snapshots valid within a timeframe window.
|
||||
db.volume_create(self.context, {'id': fake.VOLUME_ID})
|
||||
for i in range(5):
|
||||
self.db_vol_attrs[i]['volume_id'] = fake.VOLUME_ID
|
||||
|
||||
# Not in window
|
||||
del self.db_snap_attrs[0]['id']
|
||||
snap1 = objects.Snapshot(self.ctx, **self.db_snap_attrs[0])
|
||||
snap1.create()
|
||||
|
||||
# In - deleted in window
|
||||
del self.db_snap_attrs[1]['id']
|
||||
snap2 = objects.Snapshot(self.ctx, **self.db_snap_attrs[1])
|
||||
snap2.create()
|
||||
|
||||
# In - deleted after window
|
||||
del self.db_snap_attrs[2]['id']
|
||||
snap3 = objects.Snapshot(self.ctx, **self.db_snap_attrs[2])
|
||||
snap3.create()
|
||||
|
||||
# In - created in window
|
||||
del self.db_snap_attrs[3]['id']
|
||||
snap4 = objects.Snapshot(self.ctx, **self.db_snap_attrs[3])
|
||||
snap4.create()
|
||||
|
||||
# Not of window.
|
||||
del self.db_snap_attrs[4]['id']
|
||||
snap5 = objects.Snapshot(self.ctx, **self.db_snap_attrs[4])
|
||||
snap5.create()
|
||||
|
||||
snapshots = objects.SnapshotList.get_all_active_by_window(
|
||||
self.context,
|
||||
datetime.datetime(1, 3, 1, 1, 1, 1),
|
||||
datetime.datetime(1, 4, 1, 1, 1, 1)).objects
|
||||
self.assertEqual(3, len(snapshots))
|
||||
self.assertEqual(snap2.id, snapshots[0].id)
|
||||
self.assertEqual(fake.VOLUME_ID, snapshots[0].volume_id)
|
||||
self.assertEqual(snap3.id, snapshots[1].id)
|
||||
self.assertEqual(fake.VOLUME_ID, snapshots[1].volume_id)
|
||||
self.assertEqual(snap4.id, snapshots[2].id)
|
||||
self.assertEqual(fake.VOLUME_ID, snapshots[2].volume_id)
|
||||
|
||||
def test_backup_get_all_active_by_window(self):
|
||||
# Find all backups valid within a timeframe window.
|
||||
db.volume_create(self.context, {'id': fake.VOLUME_ID})
|
||||
for i in range(5):
|
||||
self.db_back_attrs[i]['volume_id'] = fake.VOLUME_ID
|
||||
|
||||
# Not in window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[0])
|
||||
|
||||
# In - deleted in window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[1])
|
||||
|
||||
# In - deleted after window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[2])
|
||||
|
||||
# In - created in window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[3])
|
||||
|
||||
# Not of window
|
||||
db.backup_create(self.ctx, self.db_back_attrs[4])
|
||||
|
||||
backups = db.backup_get_all_active_by_window(
|
||||
self.context,
|
||||
datetime.datetime(1, 3, 1, 1, 1, 1),
|
||||
datetime.datetime(1, 4, 1, 1, 1, 1),
|
||||
project_id=fake.PROJECT_ID
|
||||
)
|
||||
self.assertEqual(3, len(backups))
|
||||
self.assertEqual(fake.BACKUP2_ID, backups[0].id)
|
||||
self.assertEqual(fake.BACKUP3_ID, backups[1].id)
|
||||
self.assertEqual(fake.BACKUP4_ID, backups[2].id)
|
Loading…
Reference in New Issue