nova/nova/tests/functional/compute/test_cache_image.py

103 lines
4.2 KiB
Python

# 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.
from oslo_utils.fixture import uuidsentinel as uuids
from nova import context
from nova import objects
from nova import test
from nova.tests import fixtures
class ImageCacheTest(test.TestCase):
NUMBER_OF_CELLS = 2
def setUp(self):
super(ImageCacheTest, self).setUp()
self.flags(compute_driver='fake.FakeDriverWithCaching')
self.notifier = self.useFixture(fixtures.NotificationFixture(self))
self.context = context.get_admin_context()
self.conductor = self.start_service('conductor')
self.compute1 = self.start_service('compute', host='compute1')
self.compute2 = self.start_service('compute', host='compute2')
self.compute3 = self.start_service('compute', host='compute3',
cell_name='cell2')
self.compute4 = self.start_service('compute', host='compute4',
cell_name='cell2')
self.compute5 = self.start_service('compute', host='compute5',
cell_name='cell2')
cell2 = self.cell_mappings['cell2']
with context.target_cell(self.context, cell2) as cctxt:
srv = objects.Service.get_by_compute_host(cctxt, 'compute5')
srv.forced_down = True
srv.save()
def test_cache_image(self):
"""Test caching images by injecting the request directly to
the conductor service and making sure it fans out and calls
the expected nodes.
"""
aggregate = objects.Aggregate(name='test',
uuid=uuids.aggregate,
id=1,
hosts=['compute1', 'compute3',
'compute4', 'compute5'])
self.conductor.compute_task_mgr.cache_images(
self.context, aggregate, ['an-image'])
# NOTE(danms): We expect only three image cache attempts because
# compute5 is marked as forced-down and compute2 is not in the
# requested aggregate.
for host in ['compute1', 'compute3', 'compute4']:
mgr = getattr(self, host)
self.assertEqual(set(['an-image']), mgr.driver.cached_images)
for host in ['compute2', 'compute5']:
mgr = getattr(self, host)
self.assertEqual(set(), mgr.driver.cached_images)
self.notifier.wait_for_versioned_notifications(
'aggregate.cache_images.start')
progress = self.notifier.wait_for_versioned_notifications(
'aggregate.cache_images.progress', n_events=4)
self.assertEqual(4, len(progress), progress)
for notification in progress:
payload = notification['payload']['nova_object.data']
if payload['host'] == 'compute5':
self.assertEqual(['an-image'], payload['images_failed'])
self.assertEqual([], payload['images_cached'])
else:
self.assertEqual(['an-image'], payload['images_cached'])
self.assertEqual([], payload['images_failed'])
self.assertLessEqual(payload['index'], 4)
self.assertGreater(payload['index'], 0)
self.assertEqual(4, payload['total'])
self.assertIn('conductor', notification['publisher_id'])
self.notifier.wait_for_versioned_notifications(
'aggregate.cache_images.end')
logtext = self.stdlog.logger.output
self.assertIn(
'3 cached, 0 existing, 0 errors, 0 unsupported, 1 skipped',
logtext)
self.assertNotIn(
'Image pre-cache operation for image an-image failed',
logtext)