
A blocker migration was added in Train [1] to force deployments to make sure they have completed the services.uuid online migration (added in Pike). Now that we're in Ussuri we can drop that online data migration code. Note that InstanceListWithServicesTestCase is removed because the scenario is now invalid with the blocker DB migration. [1] I8927b8a4513dab242d34953d13dd2cc95393dc80 Change-Id: If77702f0c3212f904443f627037782f9ad7b3b55
570 lines
25 KiB
Python
570 lines
25 KiB
Python
# Copyright 2013 IBM Corp.
|
|
#
|
|
# 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_utils.fixture import uuidsentinel
|
|
from oslo_utils import timeutils
|
|
from oslo_versionedobjects import base as ovo_base
|
|
from oslo_versionedobjects import exception as ovo_exc
|
|
import six
|
|
|
|
from nova.compute import manager as compute_manager
|
|
from nova import context
|
|
from nova.db import api as db
|
|
from nova import exception
|
|
from nova import objects
|
|
from nova.objects import aggregate
|
|
from nova.objects import service
|
|
from nova import test
|
|
from nova.tests import fixtures
|
|
from nova.tests.unit.objects import test_compute_node
|
|
from nova.tests.unit.objects import test_objects
|
|
|
|
|
|
NOW = timeutils.utcnow().replace(microsecond=0)
|
|
|
|
|
|
def _fake_service(**kwargs):
|
|
fake_service = {
|
|
'created_at': NOW,
|
|
'updated_at': None,
|
|
'deleted_at': None,
|
|
'deleted': False,
|
|
'id': 123,
|
|
'uuid': uuidsentinel.service,
|
|
'host': 'fake-host',
|
|
'binary': 'nova-compute',
|
|
'topic': 'fake-service-topic',
|
|
'report_count': 1,
|
|
'forced_down': False,
|
|
'disabled': False,
|
|
'disabled_reason': None,
|
|
'last_seen_up': None,
|
|
'version': service.SERVICE_VERSION,
|
|
}
|
|
fake_service.update(kwargs)
|
|
return fake_service
|
|
|
|
|
|
fake_service = _fake_service()
|
|
|
|
OPTIONAL = ['availability_zone', 'compute_node']
|
|
|
|
|
|
class _TestServiceObject(object):
|
|
def supported_hv_specs_comparator(self, expected, obj_val):
|
|
obj_val = [inst.to_list() for inst in obj_val]
|
|
self.assertJsonEqual(expected, obj_val)
|
|
|
|
def pci_device_pools_comparator(self, expected, obj_val):
|
|
obj_val = obj_val.obj_to_primitive()
|
|
self.assertJsonEqual(expected, obj_val)
|
|
|
|
def comparators(self):
|
|
return {'stats': self.assertJsonEqual,
|
|
'host_ip': self.assertJsonEqual,
|
|
'supported_hv_specs': self.supported_hv_specs_comparator,
|
|
'pci_device_pools': self.pci_device_pools_comparator}
|
|
|
|
def subs(self):
|
|
return {'supported_hv_specs': 'supported_instances',
|
|
'pci_device_pools': 'pci_stats'}
|
|
|
|
def _test_query(self, db_method, obj_method, *args, **kwargs):
|
|
db_exception = kwargs.pop('db_exception', None)
|
|
if db_exception:
|
|
with mock.patch.object(db, db_method, side_effect=db_exception) \
|
|
as mock_db_method:
|
|
obj = getattr(service.Service, obj_method)(self.context, *args,
|
|
**kwargs)
|
|
self.assertIsNone(obj)
|
|
mock_db_method.assert_called_once_with(self.context, *args,
|
|
**kwargs)
|
|
else:
|
|
with mock.patch.object(db, db_method, return_value=fake_service) \
|
|
as mock_db_method:
|
|
obj = getattr(service.Service, obj_method)(self.context, *args,
|
|
**kwargs)
|
|
self.compare_obj(obj, fake_service, allow_missing=OPTIONAL)
|
|
mock_db_method.assert_called_once_with(self.context, *args,
|
|
**kwargs)
|
|
|
|
def test_get_by_id(self):
|
|
self._test_query('service_get', 'get_by_id', 123)
|
|
|
|
def test_get_by_uuid(self):
|
|
self._test_query('service_get_by_uuid', 'get_by_uuid',
|
|
uuidsentinel.service_uuid)
|
|
|
|
def test_get_by_host_and_topic(self):
|
|
self._test_query('service_get_by_host_and_topic',
|
|
'get_by_host_and_topic', 'fake-host', 'fake-topic')
|
|
|
|
def test_get_by_host_and_binary(self):
|
|
self._test_query('service_get_by_host_and_binary',
|
|
'get_by_host_and_binary', 'fake-host', 'fake-binary')
|
|
|
|
def test_get_by_host_and_binary_raises(self):
|
|
self._test_query('service_get_by_host_and_binary',
|
|
'get_by_host_and_binary', 'fake-host', 'fake-binary',
|
|
db_exception=exception.HostBinaryNotFound(
|
|
host='fake-host', binary='fake-binary'))
|
|
|
|
def test_get_by_compute_host(self):
|
|
self._test_query('service_get_by_compute_host', 'get_by_compute_host',
|
|
'fake-host')
|
|
|
|
def test_get_by_args(self):
|
|
self._test_query('service_get_by_host_and_binary', 'get_by_args',
|
|
'fake-host', 'fake-binary')
|
|
|
|
@mock.patch.object(db, 'service_create', return_value=fake_service)
|
|
def test_create(self, mock_service_create):
|
|
service_obj = service.Service(context=self.context)
|
|
service_obj.host = 'fake-host'
|
|
service_obj.uuid = uuidsentinel.service2
|
|
service_obj.create()
|
|
self.assertEqual(fake_service['id'], service_obj.id)
|
|
self.assertEqual(service.SERVICE_VERSION, service_obj.version)
|
|
mock_service_create.assert_called_once_with(
|
|
self.context, {'host': 'fake-host',
|
|
'uuid': uuidsentinel.service2,
|
|
'version': fake_service['version']})
|
|
|
|
@mock.patch('nova.objects.service.uuidutils.generate_uuid',
|
|
return_value=uuidsentinel.service3)
|
|
@mock.patch.object(db, 'service_create', return_value=fake_service)
|
|
def test_create_without_uuid_generates_one(
|
|
self, mock_service_create, generate_uuid):
|
|
service_obj = service.Service(context=self.context)
|
|
service_obj.create()
|
|
create_args = mock_service_create.call_args[0][1]
|
|
self.assertEqual(generate_uuid.return_value, create_args['uuid'])
|
|
|
|
@mock.patch.object(db, 'service_create', return_value=fake_service)
|
|
def test_recreate_fails(self, mock_service_create):
|
|
service_obj = service.Service(context=self.context)
|
|
service_obj.host = 'fake-host'
|
|
service_obj.create()
|
|
self.assertRaises(exception.ObjectActionError, service_obj.create)
|
|
mock_service_create(self.context, {'host': 'fake-host',
|
|
'version': fake_service['version']})
|
|
|
|
@mock.patch('nova.objects.Service._send_notification')
|
|
@mock.patch.object(db, 'service_update', return_value=fake_service)
|
|
def test_save(self, mock_service_update, mock_notify):
|
|
service_obj = service.Service(context=self.context)
|
|
service_obj.id = 123
|
|
service_obj.host = 'fake-host'
|
|
service_obj.save()
|
|
self.assertEqual(service.SERVICE_VERSION, service_obj.version)
|
|
mock_service_update.assert_called_once_with(
|
|
self.context, 123, {'host': 'fake-host',
|
|
'version': fake_service['version']})
|
|
|
|
@mock.patch.object(db, 'service_create',
|
|
return_value=fake_service)
|
|
def test_set_id_failure(self, db_mock):
|
|
service_obj = service.Service(context=self.context,
|
|
binary='nova-compute')
|
|
service_obj.create()
|
|
self.assertRaises(ovo_exc.ReadOnlyFieldError, setattr,
|
|
service_obj, 'id', 124)
|
|
|
|
@mock.patch('nova.objects.Service._send_notification')
|
|
@mock.patch.object(db, 'service_destroy')
|
|
def _test_destroy(self, mock_service_destroy, mock_notify):
|
|
service_obj = service.Service(context=self.context)
|
|
service_obj.id = 123
|
|
service_obj.destroy()
|
|
mock_service_destroy.assert_called_once_with(self.context, 123)
|
|
|
|
def test_destroy(self):
|
|
# The test harness needs db.service_destroy to work,
|
|
# so avoid leaving it broken here after we're done
|
|
orig_service_destroy = db.service_destroy
|
|
try:
|
|
self._test_destroy()
|
|
finally:
|
|
db.service_destroy = orig_service_destroy
|
|
|
|
@mock.patch.object(db, 'service_get_all_by_topic',
|
|
return_value=[fake_service])
|
|
def test_get_by_topic(self, mock_service_get):
|
|
services = service.ServiceList.get_by_topic(self.context, 'fake-topic')
|
|
self.assertEqual(1, len(services))
|
|
self.compare_obj(services[0], fake_service, allow_missing=OPTIONAL)
|
|
mock_service_get.assert_called_once_with(self.context, 'fake-topic')
|
|
|
|
@mock.patch('nova.db.api.service_get_all_by_binary')
|
|
def test_get_by_binary(self, mock_get):
|
|
mock_get.return_value = [fake_service]
|
|
services = service.ServiceList.get_by_binary(self.context,
|
|
'fake-binary')
|
|
self.assertEqual(1, len(services))
|
|
mock_get.assert_called_once_with(self.context,
|
|
'fake-binary',
|
|
include_disabled=False)
|
|
|
|
@mock.patch('nova.db.api.service_get_all_by_binary')
|
|
def test_get_by_binary_disabled(self, mock_get):
|
|
mock_get.return_value = [_fake_service(disabled=True)]
|
|
services = service.ServiceList.get_by_binary(self.context,
|
|
'fake-binary',
|
|
include_disabled=True)
|
|
self.assertEqual(1, len(services))
|
|
mock_get.assert_called_once_with(self.context,
|
|
'fake-binary',
|
|
include_disabled=True)
|
|
|
|
@mock.patch('nova.db.api.service_get_all_by_binary')
|
|
def test_get_by_binary_both(self, mock_get):
|
|
mock_get.return_value = [_fake_service(),
|
|
_fake_service(disabled=True)]
|
|
services = service.ServiceList.get_by_binary(self.context,
|
|
'fake-binary',
|
|
include_disabled=True)
|
|
self.assertEqual(2, len(services))
|
|
mock_get.assert_called_once_with(self.context,
|
|
'fake-binary',
|
|
include_disabled=True)
|
|
|
|
@mock.patch.object(db, 'service_get_all_by_host',
|
|
return_value=[fake_service])
|
|
def test_get_by_host(self, mock_service_get):
|
|
services = service.ServiceList.get_by_host(self.context, 'fake-host')
|
|
self.assertEqual(1, len(services))
|
|
self.compare_obj(services[0], fake_service, allow_missing=OPTIONAL)
|
|
mock_service_get.assert_called_once_with(self.context, 'fake-host')
|
|
|
|
@mock.patch.object(db, 'service_get_all', return_value=[fake_service])
|
|
def test_get_all(self, mock_get_all):
|
|
services = service.ServiceList.get_all(self.context, disabled=False)
|
|
self.assertEqual(1, len(services))
|
|
self.compare_obj(services[0], fake_service, allow_missing=OPTIONAL)
|
|
mock_get_all.assert_called_once_with(self.context, disabled=False)
|
|
|
|
@mock.patch.object(db, 'service_get_all')
|
|
@mock.patch.object(aggregate.AggregateList, 'get_by_metadata_key')
|
|
def test_get_all_with_az(self, mock_get_by_key, mock_get_all):
|
|
agg = aggregate.Aggregate(context=self.context)
|
|
agg.name = 'foo'
|
|
agg.metadata = {'availability_zone': 'test-az'}
|
|
agg.create()
|
|
agg.hosts = [fake_service['host']]
|
|
mock_get_by_key.return_value = [agg]
|
|
mock_get_all.return_value = [dict(fake_service, topic='compute')]
|
|
services = service.ServiceList.get_all(self.context, set_zones=True)
|
|
self.assertEqual(1, len(services))
|
|
self.assertEqual('test-az', services[0].availability_zone)
|
|
mock_get_all.assert_called_once_with(self.context, disabled=None)
|
|
mock_get_by_key.assert_called_once_with(self.context,
|
|
'availability_zone', hosts=set(agg.hosts))
|
|
|
|
@mock.patch.object(objects.ComputeNodeList, 'get_all_by_host')
|
|
def test_compute_node(self, mock_get):
|
|
fake_compute_node = objects.ComputeNode._from_db_object(
|
|
self.context, objects.ComputeNode(),
|
|
test_compute_node.fake_compute_node)
|
|
mock_get.return_value = [fake_compute_node]
|
|
service_obj = service.Service(id=123, host="fake-host",
|
|
binary="nova-compute")
|
|
service_obj._context = self.context
|
|
self.assertEqual(service_obj.compute_node,
|
|
fake_compute_node)
|
|
# Make sure it doesn't re-fetch this
|
|
service_obj.compute_node
|
|
mock_get.assert_called_once_with(self.context, 'fake-host')
|
|
|
|
@mock.patch.object(db, 'service_get_all_computes_by_hv_type')
|
|
def test_get_all_computes_by_hv_type(self, mock_get_all):
|
|
mock_get_all.return_value = [fake_service]
|
|
services = service.ServiceList.get_all_computes_by_hv_type(
|
|
self.context, 'hv-type')
|
|
self.assertEqual(1, len(services))
|
|
self.compare_obj(services[0], fake_service, allow_missing=OPTIONAL)
|
|
mock_get_all.assert_called_once_with(self.context, 'hv-type',
|
|
include_disabled=False)
|
|
|
|
def test_load_when_orphaned(self):
|
|
service_obj = service.Service()
|
|
service_obj.id = 123
|
|
self.assertRaises(exception.OrphanedObjectError,
|
|
getattr, service_obj, 'compute_node')
|
|
|
|
@mock.patch.object(objects.ComputeNodeList, 'get_all_by_host')
|
|
def test_obj_make_compatible_for_compute_node(self, get_all_by_host):
|
|
service_obj = objects.Service(context=self.context)
|
|
fake_service_dict = fake_service.copy()
|
|
fake_compute_obj = objects.ComputeNode(host=fake_service['host'],
|
|
service_id=fake_service['id'])
|
|
get_all_by_host.return_value = [fake_compute_obj]
|
|
|
|
versions = ovo_base.obj_tree_get_versions('Service')
|
|
versions['ComputeNode'] = '1.10'
|
|
service_obj.obj_make_compatible_from_manifest(fake_service_dict, '1.9',
|
|
versions)
|
|
self.assertEqual(
|
|
fake_compute_obj.obj_to_primitive(target_version='1.10',
|
|
version_manifest=versions),
|
|
fake_service_dict['compute_node'])
|
|
|
|
@mock.patch('nova.db.api.service_get_minimum_version')
|
|
def test_get_minimum_version_none(self, mock_get):
|
|
mock_get.return_value = None
|
|
self.assertEqual(0,
|
|
objects.Service.get_minimum_version(self.context,
|
|
'nova-compute'))
|
|
mock_get.assert_called_once_with(self.context, ['nova-compute'])
|
|
|
|
@mock.patch('nova.db.api.service_get_minimum_version')
|
|
def test_get_minimum_version(self, mock_get):
|
|
mock_get.return_value = {'nova-compute': 123}
|
|
self.assertEqual(123,
|
|
objects.Service.get_minimum_version(self.context,
|
|
'nova-compute'))
|
|
mock_get.assert_called_once_with(self.context, ['nova-compute'])
|
|
|
|
@mock.patch('nova.db.api.service_get_minimum_version')
|
|
@mock.patch('nova.objects.service.LOG')
|
|
def test_get_minimum_version_checks_binary(self, mock_log, mock_get):
|
|
mock_get.return_value = None
|
|
self.assertEqual(0,
|
|
objects.Service.get_minimum_version(self.context,
|
|
'nova-compute'))
|
|
self.assertFalse(mock_log.warning.called)
|
|
self.assertRaises(exception.ObjectActionError,
|
|
objects.Service.get_minimum_version,
|
|
self.context,
|
|
'compute')
|
|
self.assertTrue(mock_log.warning.called)
|
|
|
|
@mock.patch('nova.db.api.service_get_minimum_version')
|
|
def test_get_minimum_version_with_caching(self, mock_get):
|
|
objects.Service.enable_min_version_cache()
|
|
mock_get.return_value = {'nova-compute': 123}
|
|
self.assertEqual(123,
|
|
objects.Service.get_minimum_version(self.context,
|
|
'nova-compute'))
|
|
self.assertEqual({"nova-compute": 123},
|
|
objects.Service._MIN_VERSION_CACHE)
|
|
self.assertEqual(123,
|
|
objects.Service.get_minimum_version(self.context,
|
|
'nova-compute'))
|
|
mock_get.assert_called_once_with(self.context, ['nova-compute'])
|
|
objects.Service._SERVICE_VERSION_CACHING = False
|
|
objects.Service.clear_min_version_cache()
|
|
|
|
@mock.patch('nova.db.api.service_get_minimum_version')
|
|
def test_get_min_version_multiple_with_old(self, mock_gmv):
|
|
mock_gmv.return_value = {'nova-api': None,
|
|
'nova-scheduler': 2,
|
|
'nova-conductor': 3}
|
|
|
|
binaries = ['nova-api', 'nova-api', 'nova-conductor',
|
|
'nova-conductor', 'nova-api']
|
|
minimum = objects.Service.get_minimum_version_multi(self.context,
|
|
binaries)
|
|
self.assertEqual(0, minimum)
|
|
|
|
@mock.patch('nova.db.api.service_get_minimum_version')
|
|
def test_get_min_version_multiple(self, mock_gmv):
|
|
mock_gmv.return_value = {'nova-api': 1,
|
|
'nova-scheduler': 2,
|
|
'nova-conductor': 3}
|
|
|
|
binaries = ['nova-api', 'nova-api', 'nova-conductor',
|
|
'nova-conductor', 'nova-api']
|
|
minimum = objects.Service.get_minimum_version_multi(self.context,
|
|
binaries)
|
|
self.assertEqual(1, minimum)
|
|
|
|
@mock.patch('nova.objects.Service._send_notification')
|
|
@mock.patch('nova.db.api.service_get_minimum_version',
|
|
return_value={'nova-compute': 2})
|
|
def test_create_above_minimum(self, mock_get, mock_notify):
|
|
with mock.patch('nova.objects.service.SERVICE_VERSION',
|
|
new=3):
|
|
objects.Service(context=self.context,
|
|
binary='nova-compute').create()
|
|
|
|
@mock.patch('nova.objects.Service._send_notification')
|
|
@mock.patch('nova.db.api.service_get_minimum_version',
|
|
return_value={'nova-compute': 2})
|
|
def test_create_equal_to_minimum(self, mock_get, mock_notify):
|
|
with mock.patch('nova.objects.service.SERVICE_VERSION',
|
|
new=2):
|
|
objects.Service(context=self.context,
|
|
binary='nova-compute').create()
|
|
|
|
@mock.patch('nova.db.api.service_get_minimum_version',
|
|
return_value={'nova-compute': 2})
|
|
def test_create_below_minimum(self, mock_get):
|
|
with mock.patch('nova.objects.service.SERVICE_VERSION',
|
|
new=1):
|
|
self.assertRaises(exception.ServiceTooOld,
|
|
objects.Service(context=self.context,
|
|
binary='nova-compute',
|
|
).create)
|
|
|
|
@mock.patch('nova.objects.base.NovaObject'
|
|
'.obj_make_compatible_from_manifest', new=mock.Mock())
|
|
def test_obj_make_compatible_from_manifest_strips_uuid(self):
|
|
s = service.Service()
|
|
primitive = {'uuid': uuidsentinel.service}
|
|
s.obj_make_compatible_from_manifest(primitive, '1.20', mock.Mock())
|
|
self.assertNotIn('uuid', primitive)
|
|
|
|
|
|
class TestServiceObject(test_objects._LocalTest,
|
|
_TestServiceObject):
|
|
pass
|
|
|
|
|
|
class TestRemoteServiceObject(test_objects._RemoteTest,
|
|
_TestServiceObject):
|
|
pass
|
|
|
|
|
|
class TestServiceVersion(test.NoDBTestCase):
|
|
def setUp(self):
|
|
self.ctxt = context.get_admin_context()
|
|
super(TestServiceVersion, self).setUp()
|
|
|
|
def _collect_things(self):
|
|
data = {
|
|
'compute_rpc': compute_manager.ComputeManager.target.version,
|
|
}
|
|
return data
|
|
|
|
def test_version(self):
|
|
calculated = self._collect_things()
|
|
self.assertEqual(
|
|
len(service.SERVICE_VERSION_HISTORY), service.SERVICE_VERSION + 1,
|
|
'Service version %i has no history. Please update '
|
|
'nova.objects.service.SERVICE_VERSION_HISTORY '
|
|
'and add %s to it' % (service.SERVICE_VERSION, repr(calculated)))
|
|
current = service.SERVICE_VERSION_HISTORY[service.SERVICE_VERSION]
|
|
self.assertEqual(
|
|
current, calculated,
|
|
'Changes detected that require a SERVICE_VERSION change. Please '
|
|
'increment nova.objects.service.SERVICE_VERSION, and make sure it '
|
|
'is equal to nova.compute.manager.ComputeManager.target.version.')
|
|
|
|
def test_version_in_init(self):
|
|
self.assertRaises(exception.ObjectActionError,
|
|
objects.Service,
|
|
version=123)
|
|
|
|
def test_version_set_on_init(self):
|
|
self.assertEqual(service.SERVICE_VERSION,
|
|
objects.Service().version)
|
|
|
|
def test_version_loaded_from_db(self):
|
|
fake_version = fake_service['version'] + 1
|
|
fake_different_service = dict(fake_service)
|
|
fake_different_service['version'] = fake_version
|
|
obj = objects.Service()
|
|
obj._from_db_object(self.ctxt, obj, fake_different_service)
|
|
self.assertEqual(fake_version, obj.version)
|
|
|
|
|
|
class TestServiceVersionCells(test.TestCase):
|
|
|
|
def setUp(self):
|
|
self.context = context.get_admin_context()
|
|
super(TestServiceVersionCells, self).setUp()
|
|
|
|
def _setup_cells(self):
|
|
# NOTE(danms): Override the base class's cell setup so we can have two
|
|
self.cells = fixtures.CellDatabases()
|
|
self.cells.add_cell_database(uuidsentinel.cell1, default=True)
|
|
self.cells.add_cell_database(uuidsentinel.cell2)
|
|
self.useFixture(self.cells)
|
|
|
|
cm = objects.CellMapping(context=self.context,
|
|
uuid=uuidsentinel.cell1,
|
|
name='cell1',
|
|
transport_url='fake://nowhere/',
|
|
database_connection=uuidsentinel.cell1)
|
|
cm.create()
|
|
cm = objects.CellMapping(context=self.context,
|
|
uuid=uuidsentinel.cell2,
|
|
name='cell2',
|
|
transport_url='fake://nowhere/',
|
|
database_connection=uuidsentinel.cell2)
|
|
cm.create()
|
|
|
|
def _create_services(self, *versions):
|
|
cells = objects.CellMappingList.get_all(self.context)
|
|
index = 0
|
|
for version in versions:
|
|
service = objects.Service(context=self.context,
|
|
binary='nova-compute')
|
|
service.version = version
|
|
cell = cells[index % len(cells)]
|
|
with context.target_cell(self.context, cell):
|
|
service.create()
|
|
index += 1
|
|
|
|
@mock.patch('nova.objects.Service._send_notification')
|
|
@mock.patch('nova.objects.Service._check_minimum_version')
|
|
def test_version_all_cells(self, mock_check, mock_notify):
|
|
self._create_services(16, 16, 13, 16)
|
|
self.assertEqual(13, service.get_minimum_version_all_cells(
|
|
self.context, ['nova-compute']))
|
|
|
|
@mock.patch('nova.objects.service.LOG')
|
|
def test_get_minimum_version_checks_binary(self, mock_log):
|
|
ex = self.assertRaises(exception.ObjectActionError,
|
|
service.get_minimum_version_all_cells,
|
|
self.context, ['compute'])
|
|
self.assertIn('Invalid binary prefix', six.text_type(ex))
|
|
self.assertTrue(mock_log.warning.called)
|
|
|
|
@mock.patch('nova.context.scatter_gather_all_cells')
|
|
def test_version_all_cells_with_fail(self, mock_scatter):
|
|
mock_scatter.return_value = {
|
|
'foo': {'nova-compute': 13},
|
|
'bar': exception.ServiceNotFound(service_id='fake'),
|
|
}
|
|
self.assertEqual(13, service.get_minimum_version_all_cells(
|
|
self.context, ['nova-compute']))
|
|
self.assertRaises(exception.CellTimeout,
|
|
service.get_minimum_version_all_cells,
|
|
self.context, ['nova-compute'],
|
|
require_all=True)
|
|
|
|
@mock.patch('nova.context.scatter_gather_all_cells')
|
|
def test_version_all_cells_with_timeout(self, mock_scatter):
|
|
mock_scatter.return_value = {
|
|
'foo': {'nova-compute': 13},
|
|
'bar': context.did_not_respond_sentinel,
|
|
}
|
|
self.assertEqual(13, service.get_minimum_version_all_cells(
|
|
self.context, ['nova-compute']))
|
|
self.assertRaises(exception.CellTimeout,
|
|
service.get_minimum_version_all_cells,
|
|
self.context, ['nova-compute'],
|
|
require_all=True)
|
|
|
|
@mock.patch('nova.context.scatter_gather_all_cells')
|
|
def test_version_all_cells_exclude_zero_service(self, mock_scatter):
|
|
mock_scatter.return_value = {
|
|
'foo': {'nova-compute': 13},
|
|
'bar': {'nova-compute': 0},
|
|
}
|
|
self.assertEqual(13, service.get_minimum_version_all_cells(
|
|
self.context, ['nova-compute']))
|