# 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: property 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: property 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)