Merge "Make service object UUID not nullable"

This commit is contained in:
Zuul 2017-10-27 05:11:41 +00:00 committed by Gerrit Code Review
commit c877c08a23
18 changed files with 250 additions and 103 deletions

@ -568,9 +568,6 @@ def service_get_by_uuid(context, service_uuid):
@require_admin_context
def service_create(context, values):
if not values.get('uuid'):
values['uuid'] = str(uuid.uuid4())
service_ref = models.Service()
service_ref.update(values)
if not CONF.enable_new_services:
@ -600,14 +597,11 @@ def service_update(context, service_id, values):
def service_uuids_online_data_migration(context, max_count):
from cinder.objects import service
total = 0
updated = 0
total = model_query(context, models.Service).filter_by(uuid=None).count()
db_services = model_query(context, models.Service).filter_by(
uuid=None).limit(max_count)
uuid=None).limit(max_count).all()
for db_service in db_services:
total += 1
# The conversion in the Service object code
# will generate a UUID and save it for us.
service_obj = service.Service._from_db_object(

@ -136,6 +136,7 @@ OBJ_VERSIONS.add('1.25', {'Group': '1.2'})
OBJ_VERSIONS.add('1.26', {'Snapshot': '1.5'})
OBJ_VERSIONS.add('1.27', {'Backup': '1.5', 'BackupImport': '1.5'})
OBJ_VERSIONS.add('1.28', {'Service': '1.5'})
OBJ_VERSIONS.add('1.29', {'Service': '1.6'})
class CinderObjectRegistry(base.VersionedObjectRegistry):

@ -39,7 +39,8 @@ class Service(base.CinderPersistentObject, base.CinderObject,
# Version 1.3: Add replication fields
# Version 1.4: Add cluster fields
# Version 1.5: Add UUID field
VERSION = '1.5'
# Version 1.6: Modify UUID field to be not nullable
VERSION = '1.6'
OPTIONAL_FIELDS = ('cluster',)
@ -66,7 +67,7 @@ class Service(base.CinderPersistentObject, base.CinderObject,
'frozen': fields.BooleanField(default=False),
'active_backend_id': fields.StringField(nullable=True),
'uuid': fields.StringField(nullable=True),
'uuid': fields.StringField(),
}
def obj_make_compatible(self, primitive, target_version):
@ -86,8 +87,10 @@ class Service(base.CinderPersistentObject, base.CinderObject,
def _from_db_object(context, service, db_service, expected_attrs=None):
expected_attrs = expected_attrs or []
for name, field in service.fields.items():
if name in Service.OPTIONAL_FIELDS:
if ((name == 'uuid' and not db_service.get(name)) or
name in service.OPTIONAL_FIELDS):
continue
value = db_service.get(name)
if isinstance(field, fields.IntegerField):
value = value or 0

@ -770,7 +770,8 @@ class AdminActionsTest(BaseAdminTest):
mock_service_get_all):
mock_service_get_all.return_value = [
{'availability_zone': "az1", 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
# admin context
mock_check_support.return_value = True
# current status is dependent on argument: test_status.

@ -488,7 +488,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5)
@ -524,7 +525,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=1)
# Create a backup with metadata
@ -564,7 +566,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5, status='in-use')
@ -595,7 +598,8 @@ class BackupsAPITestCase(test.TestCase):
def test_create_backup_inuse_force(self, _mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5, status='in-use')
backup = utils.create_backup(self.context, volume.id,
@ -635,7 +639,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5, status='available')
@ -770,7 +775,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5)
snapshot = None
@ -819,7 +825,8 @@ class BackupsAPITestCase(test.TestCase):
self, _mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5)
@ -973,7 +980,8 @@ class BackupsAPITestCase(test.TestCase):
self, _mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'fake_az', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5, status='available')
@ -1009,22 +1017,27 @@ class BackupsAPITestCase(test.TestCase):
empty_service = []
# service host not match with volume's host
host_not_match = [{'availability_zone': 'fake_az', 'host': alt_host,
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
# service az not match with volume's az
az_not_match = [{'availability_zone': 'strange_az', 'host': testhost,
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'}]
# service disabled
disabled_service = []
# dead service that last reported at 20th century
dead_service = [{'availability_zone': 'fake_az', 'host': alt_host,
'disabled': 0, 'updated_at': '1989-04-16 02:55:44'}]
'disabled': 0, 'updated_at': '1989-04-16 02:55:44',
'uuid': '6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'}]
# first service's host not match but second one works.
multi_services = [{'availability_zone': 'fake_az', 'host': alt_host,
'disabled': 0, 'updated_at': timeutils.utcnow()},
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': '18417850-2ca9-43d1-9619-ae16bfb0f655'},
{'availability_zone': 'fake_az', 'host': testhost,
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'f838f35c-4035-464f-9792-ce60e390c13d'}]
# Setup mock to run through the following service cases
_mock_service_get_all.side_effect = [empty_service,
@ -1075,11 +1088,14 @@ class BackupsAPITestCase(test.TestCase):
def test_get_available_backup_service(self, _mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost1',
'disabled': 0, 'updated_at': timeutils.utcnow()},
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'},
{'availability_zone': 'az2', 'host': 'testhost2',
'disabled': 0, 'updated_at': timeutils.utcnow()},
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'},
{'availability_zone': 'az2', 'host': 'testhost3',
'disabled': 0, 'updated_at': timeutils.utcnow()}, ]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': '6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'}, ]
actual_host = self.backup_api._get_available_backup_service_host(
None, 'az1')
self.assertEqual('testhost1', actual_host)
@ -1095,9 +1111,11 @@ class BackupsAPITestCase(test.TestCase):
self, _mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost1',
'disabled': 0, 'updated_at': timeutils.utcnow()},
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'},
{'availability_zone': 'az2', 'host': 'testhost2',
'disabled': 0, 'updated_at': timeutils.utcnow()}, ]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'}, ]
self.override_config('backup_use_same_host', True)
actual_host = self.backup_api._get_available_backup_service_host(
None, 'az1')
@ -1113,7 +1131,8 @@ class BackupsAPITestCase(test.TestCase):
def test_delete_backup_available(self, _mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
backup = utils.create_backup(self.context,
status=fields.BackupStatus.AVAILABLE,
availability_zone='az1', host='testhost')
@ -1136,7 +1155,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
backup = utils.create_backup(self.context,
status=fields.BackupStatus.AVAILABLE,
availability_zone='az1', host='testhost')
@ -1164,7 +1184,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
backup = utils.create_backup(self.context,
status=fields.BackupStatus.ERROR,
availability_zone='az1', host='testhost')
@ -1222,7 +1243,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
volume = utils.create_volume(self.context, size=5)
backup = utils.create_backup(self.context, volume.id,
status=fields.BackupStatus.AVAILABLE)
@ -1253,7 +1275,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost',
'disabled': 0, 'updated_at': '1775-04-19 05:00:00'}]
'disabled': 0, 'updated_at': '1775-04-19 05:00:00',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
backup = utils.create_backup(self.context, status='available')
req = webob.Request.blank('/v2/%s/backups/%s' % (
fake.PROJECT_ID, backup.id))
@ -1351,7 +1374,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
_mock_volume_api_create.side_effect = fake_volume_api_create
backup = utils.create_backup(self.context, size=5,
@ -1386,7 +1410,8 @@ class BackupsAPITestCase(test.TestCase):
_mock_volume_api_create.side_effect = fake_volume_api_create
_mock_service_get_all.return_value = [
{'availability_zone': 'az1', 'host': 'testhost',
'disabled': 0, 'updated_at': timeutils.utcnow()}]
'disabled': 0, 'updated_at': timeutils.utcnow(),
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
backup = utils.create_backup(self.context, size=5,
status=fields.BackupStatus.AVAILABLE,

@ -70,7 +70,9 @@ class CapabilitiesAPITest(test.TestCase):
@mock.patch('cinder.volume.rpcapi.VolumeAPI.get_capabilities',
rpcapi_get_capabilities)
def test_capabilities_summary(self, mock_services):
mock_services.return_value = [{'name': 'fake', 'host': 'fake_host'}]
mock_services.return_value = [
{'name': 'fake', 'host': 'fake_host',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
req = fakes.HTTPRequest.blank('/fake/capabilities/fake')
req.environ['cinder.context'] = self.ctxt
res = self.controller.show(req, 'fake')
@ -113,7 +115,9 @@ class CapabilitiesAPITest(test.TestCase):
@mock.patch('cinder.volume.rpcapi.VolumeAPI.get_capabilities')
def test_get_capabilities_rpc_timeout(self, mock_rpc, mock_services):
mock_rpc.side_effect = oslo_messaging.MessagingTimeout
mock_services.return_value = [{'name': 'fake'}]
mock_services.return_value = [
{'name': 'fake',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
req = fakes.HTTPRequest.blank('/fake/capabilities/fake')
req.environ['cinder.context'] = self.ctxt

@ -31,37 +31,46 @@ curr_time = datetime.datetime(2013, 7, 3, 0, 0, 1)
SERVICE_LIST = [
{'created_at': created_time, 'updated_at': curr_time,
'host': 'test.host.1', 'topic': 'cinder-volume', 'disabled': 0,
'availability_zone': 'cinder'},
'availability_zone': 'cinder',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'},
{'created_at': created_time, 'updated_at': curr_time,
'host': 'test.host.1', 'topic': 'cinder-volume', 'disabled': 0,
'availability_zone': 'cinder'},
'availability_zone': 'cinder',
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'},
{'created_at': created_time, 'updated_at': curr_time,
'host': 'test.host.1', 'topic': 'cinder-volume', 'disabled': 0,
'availability_zone': 'cinder'},
'availability_zone': 'cinder',
'uuid': '6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'},
{'created_at': created_time, 'updated_at': curr_time,
'host': 'test.host.1', 'topic': 'cinder-volume', 'disabled': 0,
'availability_zone': 'cinder'},
'availability_zone': 'cinder',
'uuid': '18417850-2ca9-43d1-9619-ae16bfb0f655'},
{'created_at': created_time, 'updated_at': None,
'host': 'test.host.1', 'topic': 'cinder-volume', 'disabled': 0,
'availability_zone': 'cinder'},
'availability_zone': 'cinder',
'uuid': 'f838f35c-4035-464f-9792-ce60e390c13d'},
]
LIST_RESPONSE = [{'service-status': 'available', 'service': 'cinder-volume',
'zone': 'cinder', 'service-state': 'enabled',
'host_name': 'test.host.1', 'last-update': curr_time},
'host_name': 'test.host.1', 'last-update': curr_time,
},
{'service-status': 'available', 'service': 'cinder-volume',
'zone': 'cinder', 'service-state': 'enabled',
'host_name': 'test.host.1', 'last-update': curr_time},
'host_name': 'test.host.1', 'last-update': curr_time,
},
{'service-status': 'available', 'service': 'cinder-volume',
'zone': 'cinder', 'service-state': 'enabled',
'host_name': 'test.host.1', 'last-update': curr_time},
'host_name': 'test.host.1', 'last-update': curr_time,
},
{'service-status': 'available', 'service': 'cinder-volume',
'zone': 'cinder', 'service-state': 'enabled',
'host_name': 'test.host.1', 'last-update': curr_time},
'host_name': 'test.host.1', 'last-update': curr_time,
},
{'service-status': 'unavailable', 'service': 'cinder-volume',
'zone': 'cinder', 'service-state': 'enabled',
'host_name': 'test.host.1', 'last-update': None},
]
'host_name': 'test.host.1', 'last-update': None,
}, ]
def stub_utcnow(with_timezone=False):

@ -47,7 +47,8 @@ fake_services_list = [
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'created_at': datetime.datetime(2012, 9, 18, 2, 46, 27),
'disabled_reason': 'test1',
'modified_at': ''},
'modified_at': '',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'},
{'binary': 'cinder-volume',
'host': 'host1',
'cluster_name': None,
@ -57,7 +58,8 @@ fake_services_list = [
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 5),
'created_at': datetime.datetime(2012, 9, 18, 2, 46, 27),
'disabled_reason': 'test2',
'modified_at': ''},
'modified_at': '',
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'},
{'binary': 'cinder-scheduler',
'host': 'host2',
'cluster_name': 'cluster1',
@ -67,7 +69,8 @@ fake_services_list = [
'updated_at': datetime.datetime(2012, 9, 19, 6, 55, 34),
'created_at': datetime.datetime(2012, 9, 18, 2, 46, 28),
'disabled_reason': '',
'modified_at': ''},
'modified_at': '',
'uuid': '6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'},
{'binary': 'cinder-volume',
'host': 'host2',
'cluster_name': 'cluster1',
@ -77,7 +80,8 @@ fake_services_list = [
'updated_at': datetime.datetime(2012, 9, 18, 8, 3, 38),
'created_at': datetime.datetime(2012, 9, 18, 2, 46, 28),
'disabled_reason': 'test4',
'modified_at': ''},
'modified_at': '',
'uuid': '18417850-2ca9-43d1-9619-ae16bfb0f655'},
{'binary': 'cinder-volume',
'host': 'host2',
'cluster_name': 'cluster2',
@ -87,7 +91,8 @@ fake_services_list = [
'updated_at': datetime.datetime(2012, 9, 18, 8, 3, 38),
'created_at': datetime.datetime(2012, 9, 18, 2, 46, 28),
'disabled_reason': 'test5',
'modified_at': datetime.datetime(2012, 10, 29, 13, 42, 5)},
'modified_at': datetime.datetime(2012, 10, 29, 13, 42, 5),
'uuid': 'f838f35c-4035-464f-9792-ce60e390c13d'},
{'binary': 'cinder-volume',
'host': 'host2',
'cluster_name': 'cluster2',
@ -97,7 +102,8 @@ fake_services_list = [
'updated_at': datetime.datetime(2012, 9, 18, 8, 3, 38),
'created_at': datetime.datetime(2012, 9, 18, 2, 46, 28),
'disabled_reason': '',
'modified_at': datetime.datetime(2012, 9, 18, 8, 1, 38)},
'modified_at': datetime.datetime(2012, 9, 18, 8, 1, 38),
'uuid': 'f2825a00-cc2f-493d-9635-003e01db8b3d'},
{'binary': 'cinder-scheduler',
'host': 'host2',
'cluster_name': None,
@ -107,7 +113,8 @@ fake_services_list = [
'updated_at': None,
'created_at': datetime.datetime(2012, 9, 18, 2, 46, 28),
'disabled_reason': '',
'modified_at': None},
'modified_at': None,
'uuid': '35fcf841-1974-4944-a798-1fb6d0a44972'},
]

@ -62,9 +62,11 @@ def service_get(context, service_id, backend_match_level=None, host=None,
check for existence of a host, so the content returned doesn't matter.
"""
if host == 'host_ok':
return {'disabled': False}
return {'disabled': False,
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}
if host == 'host_disabled':
return {'disabled': True}
return {'disabled': True,
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'}
raise exception.ServiceNotFound(service_id=host)
# Some of the tests check that volume types are correctly validated during a

@ -223,11 +223,13 @@ def fake_snapshot_update(self, context, *args, **param):
def fake_service_get_all(*args, **kwargs):
return [{'availability_zone': "zone1:host1", "disabled": 0}]
return [{'availability_zone': "zone1:host1", "disabled": 0,
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
def fake_service_get_all_by_topic(context, topic, disabled=None):
return [{'availability_zone': "zone1:host1", "disabled": 0}]
return [{'availability_zone': "zone1:host1", "disabled": 0,
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'}]
def fake_snapshot_get(self, context, snapshot_id):

@ -43,7 +43,7 @@ object_data = {
'QualityOfServiceSpecs': '1.0-0b212e0a86ee99092229874e03207fe8',
'QualityOfServiceSpecsList': '1.0-15ecf022a68ddbb8c2a6739cfc9f8f5e',
'RequestSpec': '1.1-b0bd1a28d191d75648901fa853e8a733',
'Service': '1.5-dfa465098dd9017bad825cab55eacc93',
'Service': '1.6-e881b6b324151dd861e09cdfffcdaccd',
'ServiceList': '1.1-15ecf022a68ddbb8c2a6739cfc9f8f5e',
'Snapshot': '1.5-ac1cdbd5b89588f6a8f44afdf6b8b201',
'SnapshotList': '1.0-15ecf022a68ddbb8c2a6739cfc9f8f5e',
@ -101,6 +101,12 @@ class TestObjectVersions(test.TestCase):
# db model and object match.
def _check_table_matched(db_model, cls):
for column in db_model.__table__.columns:
# NOTE(jdg): Model and Object don't match intentionally here
if (column.name in cls.fields and
(column.name == 'uuid' and name == 'Service')):
continue
# NOTE(xyang): Skip the comparison of the colume name
# group_type_id in table Group because group_type_id
# is in the object Group but it is stored in a different

@ -47,7 +47,8 @@ class FakeHostManager(host_manager.HostManager):
'reserved_percentage': 10,
'volume_backend_name': 'lvm1',
'timestamp': UTC_NOW,
'multiattach': True},
'multiattach': True,
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'},
'host2': {'total_capacity_gb': 2048,
'free_capacity_gb': 300,
'allocated_capacity_gb': 1748,
@ -57,7 +58,8 @@ class FakeHostManager(host_manager.HostManager):
'thick_provisioning_support': False,
'reserved_percentage': 10,
'volume_backend_name': 'lvm2',
'timestamp': UTC_NOW},
'timestamp': UTC_NOW,
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'},
'host3': {'total_capacity_gb': 512,
'free_capacity_gb': 256,
'allocated_capacity_gb': 256,
@ -67,7 +69,8 @@ class FakeHostManager(host_manager.HostManager):
'thick_provisioning_support': True,
'reserved_percentage': 0,
'volume_backend_name': 'lvm3',
'timestamp': UTC_NOW},
'timestamp': UTC_NOW,
'uuid': '6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'},
'host4': {'total_capacity_gb': 2048,
'free_capacity_gb': 200,
'allocated_capacity_gb': 1848,
@ -78,7 +81,8 @@ class FakeHostManager(host_manager.HostManager):
'reserved_percentage': 5,
'volume_backend_name': 'lvm4',
'timestamp': UTC_NOW,
'consistent_group_snapshot_enabled': True},
'consistent_group_snapshot_enabled': True,
'uuid': '18417850-2ca9-43d1-9619-ae16bfb0f655'},
'host5': {'total_capacity_gb': 'infinite',
'free_capacity_gb': 'unknown',
'allocated_capacity_gb': 1548,
@ -87,7 +91,8 @@ class FakeHostManager(host_manager.HostManager):
'thin_provisioning_support': True,
'thick_provisioning_support': False,
'reserved_percentage': 5,
'timestamp': UTC_NOW},
'timestamp': UTC_NOW,
'uuid': 'f838f35c-4035-464f-9792-ce60e390c13d'},
}
@ -150,15 +155,20 @@ class FakeNovaClient(object):
def mock_host_manager_db_calls(mock_obj, disabled=None):
services = [
dict(id=1, host='host1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'),
dict(id=2, host='host2', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='4200b32b-0bf9-436c-86b2-0675f6ac218e'),
dict(id=3, host='host3', topic='volume', disabled=False,
availability_zone='zone2', updated_at=timeutils.utcnow()),
availability_zone='zone2', updated_at=timeutils.utcnow(),
uuid='4200b32b-0bf9-436c-86b2-0675f6ac218e'),
dict(id=4, host='host4', topic='volume', disabled=False,
availability_zone='zone3', updated_at=timeutils.utcnow()),
availability_zone='zone3', updated_at=timeutils.utcnow(),
uuid='18417850-2ca9-43d1-9619-ae16bfb0f655'),
dict(id=5, host='host5', topic='volume', disabled=False,
availability_zone='zone3', updated_at=timeutils.utcnow()),
availability_zone='zone3', updated_at=timeutils.utcnow(),
uuid='f838f35c-4035-464f-9792-ce60e390c13d'),
]
if disabled is None:
mock_obj.return_value = services

@ -502,11 +502,14 @@ class HostManagerTestCase(test.TestCase):
_mock_service_is_up.return_value = True
services = [
dict(id=1, host='host1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'),
dict(id=2, host='host2', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='4200b32b-0bf9-436c-86b2-0675f6ac218e'),
dict(id=3, host='host3', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'),
]
_mock_service_get_all.return_value = services
# Create host_manager again to let db.service_get_all mock run
@ -553,7 +556,8 @@ class HostManagerTestCase(test.TestCase):
services = [
# This is the first call to utcnow()
dict(id=1, host='host1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7',)
]
mocked_service_states = {
@ -659,19 +663,23 @@ class HostManagerTestCase(test.TestCase):
dict(id=1, host='host1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow(),
binary=None, deleted=False, created_at=None, modified_at=None,
report_count=0, deleted_at=None, disabled_reason=None),
report_count=0, deleted_at=None, disabled_reason=None,
uuid='a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'),
dict(id=2, host='host2', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow(),
binary=None, deleted=False, created_at=None, modified_at=None,
report_count=0, deleted_at=None, disabled_reason=None),
report_count=0, deleted_at=None, disabled_reason=None,
uuid='4200b32b-0bf9-436c-86b2-0675f6ac218e'),
dict(id=3, host='host3', topic='volume', disabled=False,
availability_zone='zone2', updated_at=timeutils.utcnow(),
binary=None, deleted=False, created_at=None, modified_at=None,
report_count=0, deleted_at=None, disabled_reason=None),
report_count=0, deleted_at=None, disabled_reason=None,
uuid='6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'),
dict(id=4, host='host4', topic='volume', disabled=False,
availability_zone='zone3', updated_at=timeutils.utcnow(),
binary=None, deleted=False, created_at=None, modified_at=None,
report_count=0, deleted_at=None, disabled_reason=None),
report_count=0, deleted_at=None, disabled_reason=None,
uuid='18417850-2ca9-43d1-9619-ae16bfb0f655'),
]
service_objs = []
@ -759,11 +767,14 @@ class HostManagerTestCase(test.TestCase):
services = [
dict(id=1, host='host1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'),
dict(id=2, host='host2@back1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='4200b32b-0bf9-436c-86b2-0675f6ac218e'),
dict(id=3, host='host2@back2', topic='volume', disabled=False,
availability_zone='zone2', updated_at=timeutils.utcnow()),
availability_zone='zone2', updated_at=timeutils.utcnow(),
uuid='6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'),
]
mocked_service_states = {
@ -982,9 +993,11 @@ class HostManagerTestCase(test.TestCase):
services = [
dict(id=1, host='host1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'),
dict(id=2, host='host2@back1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow())
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='4200b32b-0bf9-436c-86b2-0675f6ac218e')
]
mocked_service_states = {
@ -1074,9 +1087,11 @@ class HostManagerTestCase(test.TestCase):
services = [
dict(id=1, host='host1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow()),
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'),
dict(id=2, host='host2@back1', topic='volume', disabled=False,
availability_zone='zone1', updated_at=timeutils.utcnow())
availability_zone='zone1', updated_at=timeutils.utcnow(),
uuid='4200b32b-0bf9-436c-86b2-0675f6ac218e')
]
mocked_service_states = {

@ -335,8 +335,10 @@ class TestCinderManageCmd(test.TestCase):
@mock.patch('cinder.context.get_admin_context')
def test_host_commands_list(self, get_admin_context, service_get_all):
get_admin_context.return_value = mock.sentinel.ctxt
service_get_all.return_value = [{'host': 'fake-host',
'availability_zone': 'fake-az'}]
service_get_all.return_value = [
{'host': 'fake-host',
'availability_zone': 'fake-az',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
with mock.patch('sys.stdout', new=six.StringIO()) as fake_out:
expected_out = ("%(host)-25s\t%(zone)-15s\n" %
@ -356,10 +358,13 @@ class TestCinderManageCmd(test.TestCase):
def test_host_commands_list_with_zone(self, get_admin_context,
service_get_all):
get_admin_context.return_value = mock.sentinel.ctxt
service_get_all.return_value = [{'host': 'fake-host',
'availability_zone': 'fake-az1'},
{'host': 'fake-host',
'availability_zone': 'fake-az2'}]
service_get_all.return_value = [
{'host': 'fake-host',
'availability_zone': 'fake-az1',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'},
{'host': 'fake-host',
'availability_zone': 'fake-az2',
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'}]
with mock.patch('sys.stdout', new=six.StringIO()) as fake_out:
expected_out = ("%(host)-25s\t%(zone)-15s\n" %
@ -692,7 +697,8 @@ class TestCinderManageCmd(test.TestCase):
'disabled': False,
'rpc_current_version': '1.1',
'object_current_version': '1.1',
'cluster_name': 'my_cluster'}
'cluster_name': 'my_cluster',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}
for binary in ('volume', 'scheduler', 'backup'):
service['binary'] = 'cinder-%s' % binary
self._test_service_commands_list(service)
@ -704,7 +710,8 @@ class TestCinderManageCmd(test.TestCase):
'updated_at': None,
'disabled': False,
'rpc_current_version': '1.1',
'object_current_version': '1.1'}
'object_current_version': '1.1',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}
for binary in ('volume', 'scheduler', 'backup'):
service['binary'] = 'cinder-%s' % binary
self._test_service_commands_list(service)
@ -965,7 +972,10 @@ class TestCinderManageCmd(test.TestCase):
self.assertEqual(2, exit)
@mock.patch('cinder.db.service_destroy')
@mock.patch('cinder.db.service_get', return_value = {'id': '12'})
@mock.patch(
'cinder.db.service_get',
return_value = {'id': '12',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'})
def test_remove_service_success(self, mock_get_by_args,
mock_service_destroy):
service_commands = cinder_manage.ServiceCommands()

@ -162,6 +162,54 @@ class DBAPIServiceTestCase(BaseTest):
"""Unit tests for cinder.db.api.service_*."""
def test_service_uuid_migrations(self):
# Force create one entry with no UUID
sqlalchemy_api.service_create(self.ctxt, {
'host': 'host1',
'binary': 'cinder-volume',
'topic': 'volume', })
# Create another one with a valid UUID
sqlalchemy_api.service_create(self.ctxt, {
'host': 'host2',
'binary': 'cinder-volume',
'topic': 'volume',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'})
# Run the migration and verify that we updated 1 entry
total, updated = db.service_uuids_online_data_migration(
self.ctxt, 10)
self.assertEqual(1, total)
self.assertEqual(1, updated)
def test_service_uuid_migrations_with_limit(self):
sqlalchemy_api.service_create(self.ctxt, {
'host': 'host1',
'binary': 'cinder-volume',
'topic': 'volume', })
sqlalchemy_api.service_create(self.ctxt, {
'host': 'host2',
'binary': 'cinder-volume',
'topic': 'volume', })
sqlalchemy_api.service_create(self.ctxt, {
'host': 'host3',
'binary': 'cinder-volume',
'topic': 'volume', })
# Run the migration and verify that we updated 1 entry
total, updated = db.service_uuids_online_data_migration(
self.ctxt, 2)
self.assertEqual(3, total)
self.assertEqual(2, updated)
# Now get the rest, intentionally setting max > what we should have
total, updated = db.service_uuids_online_data_migration(
self.ctxt, 2)
self.assertEqual(1, total)
self.assertEqual(1, updated)
def test_service_create(self):
# Add a cluster value to the service
values = {'cluster_name': 'cluster'}

@ -147,7 +147,8 @@ class ServiceTestCase(test.TestCase):
'topic': self.topic,
'report_count': 0,
'availability_zone': 'nova',
'id': 1}
'id': 1,
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}
self.ctxt = context.get_admin_context()
def _check_app(self, app, cluster=None, cluster_exists=None,

@ -29,7 +29,8 @@ class AvailabilityZoneTestCase(base.BaseVolumeTestCase):
super(AvailabilityZoneTestCase, self).setUp()
self.get_all = self.patch(
'cinder.db.service_get_all', autospec=True,
return_value = [{'availability_zone': 'a', 'disabled': False}])
return_value=[{'availability_zone': 'a', 'disabled': False,
'uuid': 'f838f35c-4035-464f-9792-ce60e390c13d'}])
def test_list_availability_zones_cached(self):
azs = self.volume_api.list_availability_zones(enable_cache=True)
@ -80,10 +81,12 @@ class AvailabilityZoneTestCase(base.BaseVolumeTestCase):
{
'availability_zone': 'a',
'disabled': False,
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824',
},
{
'availability_zone': 'b',
'disabled': False,
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e',
},
]
azs = self.volume_api.list_availability_zones(enable_cache=True)
@ -99,10 +102,14 @@ class AvailabilityZoneTestCase(base.BaseVolumeTestCase):
return obj['name']
self.get_all.return_value = [
{'availability_zone': 'ping', 'disabled': 0},
{'availability_zone': 'ping', 'disabled': 1},
{'availability_zone': 'pong', 'disabled': 0},
{'availability_zone': 'pung', 'disabled': 1},
{'availability_zone': 'ping', 'disabled': 0,
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'},
{'availability_zone': 'ping', 'disabled': 1,
'uuid': '4200b32b-0bf9-436c-86b2-0675f6ac218e'},
{'availability_zone': 'pong', 'disabled': 0,
'uuid': '6d91e7f5-ca17-4e3b-bf4f-19ca77166dd7'},
{'availability_zone': 'pung', 'disabled': 1,
'uuid': '18417850-2ca9-43d1-9619-ae16bfb0f655'},
]
volume_api = cinder.volume.api.API()

@ -1083,7 +1083,9 @@ class VolumeTestCase(base.BaseVolumeTestCase):
with mock.patch('cinder.db.service_get_all') as mock_get_service, \
mock.patch.object(volume_api,
'list_availability_zones') as mock_get_azs:
mock_get_service.return_value = [{'host': 'foo'}]
mock_get_service.return_value = [
{'host': 'foo',
'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}]
mock_get_azs.return_value = {}
volume_api.create(self.context,
size=1,