diff options
Diffstat (limited to 'nova/tests/virt/libvirt/test_imagecache.py')
-rw-r--r-- | nova/tests/virt/libvirt/test_imagecache.py | 887 |
1 files changed, 0 insertions, 887 deletions
diff --git a/nova/tests/virt/libvirt/test_imagecache.py b/nova/tests/virt/libvirt/test_imagecache.py deleted file mode 100644 index a2eb4a1c67..0000000000 --- a/nova/tests/virt/libvirt/test_imagecache.py +++ /dev/null @@ -1,887 +0,0 @@ -# Copyright 2012 Michael Still and Canonical Inc -# 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 contextlib -import cStringIO -import hashlib -import os -import time - -from oslo.concurrency import processutils -from oslo.config import cfg -from oslo.serialization import jsonutils -from oslo.utils import importutils - -from nova import conductor -from nova import db -from nova.openstack.common import log as logging -from nova import test -from nova.tests import fake_instance -from nova import utils -from nova.virt.libvirt import imagecache -from nova.virt.libvirt import utils as libvirt_utils - -CONF = cfg.CONF -CONF.import_opt('compute_manager', 'nova.service') -CONF.import_opt('host', 'nova.netconf') - - -@contextlib.contextmanager -def intercept_log_messages(): - try: - mylog = logging.getLogger('nova') - stream = cStringIO.StringIO() - handler = logging.logging.StreamHandler(stream) - handler.setFormatter(logging.ContextFormatter()) - mylog.logger.addHandler(handler) - yield stream - finally: - mylog.logger.removeHandler(handler) - - -class ImageCacheManagerTestCase(test.NoDBTestCase): - - def setUp(self): - super(ImageCacheManagerTestCase, self).setUp() - self.stock_instance_names = set(['instance-00000001', - 'instance-00000002', - 'instance-00000003', - 'banana-42-hamster']) - - def test_read_stored_checksum_missing(self): - self.stubs.Set(os.path, 'exists', lambda x: False) - csum = imagecache.read_stored_checksum('/tmp/foo', timestamped=False) - self.assertIsNone(csum) - - def test_read_stored_checksum(self): - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - - csum_input = '{"sha1": "fdghkfhkgjjksfdgjksjkghsdf"}\n' - fname = os.path.join(tmpdir, 'aaa') - info_fname = imagecache.get_info_filename(fname) - f = open(info_fname, 'w') - f.write(csum_input) - f.close() - - csum_output = imagecache.read_stored_checksum(fname, - timestamped=False) - self.assertEqual(csum_input.rstrip(), - '{"sha1": "%s"}' % csum_output) - - def test_read_stored_checksum_legacy_essex(self): - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - - fname = os.path.join(tmpdir, 'aaa') - old_fname = fname + '.sha1' - f = open(old_fname, 'w') - f.write('fdghkfhkgjjksfdgjksjkghsdf') - f.close() - - csum_output = imagecache.read_stored_checksum(fname, - timestamped=False) - self.assertEqual(csum_output, 'fdghkfhkgjjksfdgjksjkghsdf') - self.assertFalse(os.path.exists(old_fname)) - info_fname = imagecache.get_info_filename(fname) - self.assertTrue(os.path.exists(info_fname)) - - def test_list_base_images(self): - listing = ['00000001', - 'ephemeral_0_20_None', - '17d1b00b81642842e514494a78e804e9a511637c_5368709120.info', - '00000004'] - images = ['e97222e91fc4241f49a7f520d1dcf446751129b3_sm', - 'e09c675c2d1cfac32dae3c2d83689c8c94bc693b_sm', - 'e97222e91fc4241f49a7f520d1dcf446751129b3', - '17d1b00b81642842e514494a78e804e9a511637c', - '17d1b00b81642842e514494a78e804e9a511637c_5368709120', - '17d1b00b81642842e514494a78e804e9a511637c_10737418240'] - listing.extend(images) - - self.stubs.Set(os, 'listdir', lambda x: listing) - self.stubs.Set(os.path, 'isfile', lambda x: True) - - base_dir = '/var/lib/nova/instances/_base' - self.flags(instances_path='/var/lib/nova/instances') - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager._list_base_images(base_dir) - - sanitized = [] - for ent in image_cache_manager.unexplained_images: - sanitized.append(ent.replace(base_dir + '/', '')) - - self.assertEqual(sorted(sanitized), sorted(images)) - - expected = os.path.join(base_dir, - 'e97222e91fc4241f49a7f520d1dcf446751129b3') - self.assertIn(expected, image_cache_manager.unexplained_images) - - expected = os.path.join(base_dir, - '17d1b00b81642842e514494a78e804e9a511637c_' - '10737418240') - self.assertIn(expected, image_cache_manager.unexplained_images) - - unexpected = os.path.join(base_dir, '00000004') - self.assertNotIn(unexpected, image_cache_manager.unexplained_images) - - for ent in image_cache_manager.unexplained_images: - self.assertTrue(ent.startswith(base_dir)) - - self.assertEqual(len(image_cache_manager.originals), 2) - - expected = os.path.join(base_dir, - '17d1b00b81642842e514494a78e804e9a511637c') - self.assertIn(expected, image_cache_manager.originals) - - unexpected = os.path.join(base_dir, - '17d1b00b81642842e514494a78e804e9a511637c_' - '10737418240') - self.assertNotIn(unexpected, image_cache_manager.originals) - - def test_list_backing_images_small(self): - self.stubs.Set(os, 'listdir', - lambda x: ['_base', 'instance-00000001', - 'instance-00000002', 'instance-00000003']) - self.stubs.Set(os.path, 'exists', - lambda x: x.find('instance-') != -1) - self.stubs.Set(libvirt_utils, 'get_disk_backing_file', - lambda x: 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - - found = os.path.join(CONF.instances_path, - CONF.image_cache_subdirectory_name, - 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [found] - image_cache_manager.instance_names = self.stock_instance_names - - inuse_images = image_cache_manager._list_backing_images() - - self.assertEqual(inuse_images, [found]) - self.assertEqual(len(image_cache_manager.unexplained_images), 0) - - def test_list_backing_images_resized(self): - self.stubs.Set(os, 'listdir', - lambda x: ['_base', 'instance-00000001', - 'instance-00000002', 'instance-00000003']) - self.stubs.Set(os.path, 'exists', - lambda x: x.find('instance-') != -1) - self.stubs.Set(libvirt_utils, 'get_disk_backing_file', - lambda x: ('e97222e91fc4241f49a7f520d1dcf446751129b3_' - '10737418240')) - - found = os.path.join(CONF.instances_path, - CONF.image_cache_subdirectory_name, - 'e97222e91fc4241f49a7f520d1dcf446751129b3_' - '10737418240') - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [found] - image_cache_manager.instance_names = self.stock_instance_names - - inuse_images = image_cache_manager._list_backing_images() - - self.assertEqual(inuse_images, [found]) - self.assertEqual(len(image_cache_manager.unexplained_images), 0) - - def test_list_backing_images_instancename(self): - self.stubs.Set(os, 'listdir', - lambda x: ['_base', 'banana-42-hamster']) - self.stubs.Set(os.path, 'exists', - lambda x: x.find('banana-42-hamster') != -1) - self.stubs.Set(libvirt_utils, 'get_disk_backing_file', - lambda x: 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - - found = os.path.join(CONF.instances_path, - CONF.image_cache_subdirectory_name, - 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [found] - image_cache_manager.instance_names = self.stock_instance_names - - inuse_images = image_cache_manager._list_backing_images() - - self.assertEqual(inuse_images, [found]) - self.assertEqual(len(image_cache_manager.unexplained_images), 0) - - def test_list_backing_images_disk_notexist(self): - self.stubs.Set(os, 'listdir', - lambda x: ['_base', 'banana-42-hamster']) - self.stubs.Set(os.path, 'exists', - lambda x: x.find('banana-42-hamster') != -1) - - def fake_get_disk(disk_path): - raise processutils.ProcessExecutionError() - - self.stubs.Set(libvirt_utils, 'get_disk_backing_file', fake_get_disk) - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [] - image_cache_manager.instance_names = self.stock_instance_names - - self.assertRaises(processutils.ProcessExecutionError, - image_cache_manager._list_backing_images) - - def test_find_base_file_nothing(self): - self.stubs.Set(os.path, 'exists', lambda x: False) - - base_dir = '/var/lib/nova/instances/_base' - fingerprint = '549867354867' - image_cache_manager = imagecache.ImageCacheManager() - res = list(image_cache_manager._find_base_file(base_dir, fingerprint)) - - self.assertEqual(0, len(res)) - - def test_find_base_file_small(self): - fingerprint = '968dd6cc49e01aaa044ed11c0cce733e0fa44a6a' - self.stubs.Set(os.path, 'exists', - lambda x: x.endswith('%s_sm' % fingerprint)) - - base_dir = '/var/lib/nova/instances/_base' - image_cache_manager = imagecache.ImageCacheManager() - res = list(image_cache_manager._find_base_file(base_dir, fingerprint)) - - base_file = os.path.join(base_dir, fingerprint + '_sm') - self.assertEqual(res, [(base_file, True, False)]) - - def test_find_base_file_resized(self): - fingerprint = '968dd6cc49e01aaa044ed11c0cce733e0fa44a6a' - listing = ['00000001', - 'ephemeral_0_20_None', - '968dd6cc49e01aaa044ed11c0cce733e0fa44a6a_10737418240', - '00000004'] - - self.stubs.Set(os, 'listdir', lambda x: listing) - self.stubs.Set(os.path, 'exists', - lambda x: x.endswith('%s_10737418240' % fingerprint)) - self.stubs.Set(os.path, 'isfile', lambda x: True) - - base_dir = '/var/lib/nova/instances/_base' - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager._list_base_images(base_dir) - res = list(image_cache_manager._find_base_file(base_dir, fingerprint)) - - base_file = os.path.join(base_dir, fingerprint + '_10737418240') - self.assertEqual(res, [(base_file, False, True)]) - - def test_find_base_file_all(self): - fingerprint = '968dd6cc49e01aaa044ed11c0cce733e0fa44a6a' - listing = ['00000001', - 'ephemeral_0_20_None', - '968dd6cc49e01aaa044ed11c0cce733e0fa44a6a_sm', - '968dd6cc49e01aaa044ed11c0cce733e0fa44a6a_10737418240', - '00000004'] - - self.stubs.Set(os, 'listdir', lambda x: listing) - self.stubs.Set(os.path, 'exists', lambda x: True) - self.stubs.Set(os.path, 'isfile', lambda x: True) - - base_dir = '/var/lib/nova/instances/_base' - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager._list_base_images(base_dir) - res = list(image_cache_manager._find_base_file(base_dir, fingerprint)) - - base_file1 = os.path.join(base_dir, fingerprint) - base_file2 = os.path.join(base_dir, fingerprint + '_sm') - base_file3 = os.path.join(base_dir, fingerprint + '_10737418240') - self.assertEqual(res, [(base_file1, False, False), - (base_file2, True, False), - (base_file3, False, True)]) - - @contextlib.contextmanager - def _make_base_file(self, checksum=True): - """Make a base file for testing.""" - - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - fname = os.path.join(tmpdir, 'aaa') - - base_file = open(fname, 'w') - base_file.write('data') - base_file.close() - base_file = open(fname, 'r') - - if checksum: - imagecache.write_stored_checksum(fname) - - base_file.close() - yield fname - - def test_remove_base_file(self): - with self._make_base_file() as fname: - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager._remove_base_file(fname) - info_fname = imagecache.get_info_filename(fname) - - # Files are initially too new to delete - self.assertTrue(os.path.exists(fname)) - self.assertTrue(os.path.exists(info_fname)) - - # Old files get cleaned up though - os.utime(fname, (-1, time.time() - 3601)) - image_cache_manager._remove_base_file(fname) - - self.assertFalse(os.path.exists(fname)) - self.assertFalse(os.path.exists(info_fname)) - - def test_remove_base_file_original(self): - with self._make_base_file() as fname: - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.originals = [fname] - image_cache_manager._remove_base_file(fname) - info_fname = imagecache.get_info_filename(fname) - - # Files are initially too new to delete - self.assertTrue(os.path.exists(fname)) - self.assertTrue(os.path.exists(info_fname)) - - # This file should stay longer than a resized image - os.utime(fname, (-1, time.time() - 3601)) - image_cache_manager._remove_base_file(fname) - - self.assertTrue(os.path.exists(fname)) - self.assertTrue(os.path.exists(info_fname)) - - # Originals don't stay forever though - os.utime(fname, (-1, time.time() - 3600 * 25)) - image_cache_manager._remove_base_file(fname) - - self.assertFalse(os.path.exists(fname)) - self.assertFalse(os.path.exists(info_fname)) - - def test_remove_base_file_dne(self): - # This test is solely to execute the "does not exist" code path. We - # don't expect the method being tested to do anything in this case. - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - - fname = os.path.join(tmpdir, 'aaa') - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager._remove_base_file(fname) - - def test_remove_base_file_oserror(self): - with intercept_log_messages() as stream: - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - - fname = os.path.join(tmpdir, 'aaa') - - os.mkdir(fname) - os.utime(fname, (-1, time.time() - 3601)) - - # This will raise an OSError because of file permissions - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager._remove_base_file(fname) - - self.assertTrue(os.path.exists(fname)) - self.assertNotEqual(stream.getvalue().find('Failed to remove'), - -1) - - def test_handle_base_image_unused(self): - img = '123' - - with self._make_base_file() as fname: - os.utime(fname, (-1, time.time() - 3601)) - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [fname] - image_cache_manager._handle_base_image(img, fname) - - self.assertEqual(image_cache_manager.unexplained_images, []) - self.assertEqual(image_cache_manager.removable_base_files, - [fname]) - self.assertEqual(image_cache_manager.corrupt_base_files, []) - - def test_handle_base_image_used(self): - self.stubs.Set(libvirt_utils, 'chown', lambda x, y: None) - img = '123' - - with self._make_base_file() as fname: - os.utime(fname, (-1, time.time() - 3601)) - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [fname] - image_cache_manager.used_images = {'123': (1, 0, ['banana-42'])} - image_cache_manager._handle_base_image(img, fname) - - self.assertEqual(image_cache_manager.unexplained_images, []) - self.assertEqual(image_cache_manager.removable_base_files, []) - self.assertEqual(image_cache_manager.corrupt_base_files, []) - - def test_handle_base_image_used_remotely(self): - self.stubs.Set(libvirt_utils, 'chown', lambda x, y: None) - img = '123' - - with self._make_base_file() as fname: - os.utime(fname, (-1, time.time() - 3601)) - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [fname] - image_cache_manager.used_images = {'123': (0, 1, ['banana-42'])} - image_cache_manager._handle_base_image(img, fname) - - self.assertEqual(image_cache_manager.unexplained_images, []) - self.assertEqual(image_cache_manager.removable_base_files, []) - self.assertEqual(image_cache_manager.corrupt_base_files, []) - - def test_handle_base_image_absent(self): - img = '123' - - with intercept_log_messages() as stream: - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.used_images = {'123': (1, 0, ['banana-42'])} - image_cache_manager._handle_base_image(img, None) - - self.assertEqual(image_cache_manager.unexplained_images, []) - self.assertEqual(image_cache_manager.removable_base_files, []) - self.assertEqual(image_cache_manager.corrupt_base_files, []) - self.assertNotEqual(stream.getvalue().find('an absent base file'), - -1) - - def test_handle_base_image_used_missing(self): - img = '123' - - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - - fname = os.path.join(tmpdir, 'aaa') - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [fname] - image_cache_manager.used_images = {'123': (1, 0, ['banana-42'])} - image_cache_manager._handle_base_image(img, fname) - - self.assertEqual(image_cache_manager.unexplained_images, []) - self.assertEqual(image_cache_manager.removable_base_files, []) - self.assertEqual(image_cache_manager.corrupt_base_files, []) - - def test_handle_base_image_checksum_fails(self): - self.flags(checksum_base_images=True, group='libvirt') - self.stubs.Set(libvirt_utils, 'chown', lambda x, y: None) - - img = '123' - - with self._make_base_file() as fname: - with open(fname, 'w') as f: - f.write('banana') - - d = {'sha1': '21323454'} - with open('%s.info' % fname, 'w') as f: - f.write(jsonutils.dumps(d)) - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.unexplained_images = [fname] - image_cache_manager.used_images = {'123': (1, 0, ['banana-42'])} - image_cache_manager._handle_base_image(img, fname) - - self.assertEqual(image_cache_manager.unexplained_images, []) - self.assertEqual(image_cache_manager.removable_base_files, []) - self.assertEqual(image_cache_manager.corrupt_base_files, - [fname]) - - def test_verify_base_images(self): - hashed_1 = '356a192b7913b04c54574d18c28d46e6395428ab' - hashed_21 = '472b07b9fcf2c2451e8781e944bf5f77cd8457c8' - hashed_22 = '12c6fc06c99a462375eeb3f43dfd832b08ca9e17' - hashed_42 = '92cfceb39d57d914ed8b14d0e37643de0797ae56' - - self.flags(instances_path='/instance_path', - image_cache_subdirectory_name='_base') - - base_file_list = ['00000001', - 'ephemeral_0_20_None', - 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm', - 'e09c675c2d1cfac32dae3c2d83689c8c94bc693b_sm', - hashed_42, - hashed_1, - hashed_21, - hashed_22, - '%s_5368709120' % hashed_1, - '%s_10737418240' % hashed_1, - '00000004'] - - def fq_path(path): - return os.path.join('/instance_path/_base/', path) - - # Fake base directory existence - orig_exists = os.path.exists - - def exists(path): - # The python coverage tool got angry with my overly broad mocks - if not path.startswith('/instance_path'): - return orig_exists(path) - - if path in ['/instance_path', - '/instance_path/_base', - '/instance_path/instance-1/disk', - '/instance_path/instance-2/disk', - '/instance_path/instance-3/disk', - '/instance_path/_base/%s.info' % hashed_42]: - return True - - for p in base_file_list: - if path == fq_path(p): - return True - if path == fq_path(p) + '.info': - return False - - if path in ['/instance_path/_base/%s_sm' % i for i in [hashed_1, - hashed_21, - hashed_22, - hashed_42]]: - return False - - self.fail('Unexpected path existence check: %s' % path) - - self.stubs.Set(os.path, 'exists', lambda x: exists(x)) - - self.stubs.Set(libvirt_utils, 'chown', lambda x, y: None) - - # We need to stub utime as well - self.stubs.Set(os, 'utime', lambda x, y: None) - - # Fake up some instances in the instances directory - orig_listdir = os.listdir - - def listdir(path): - # The python coverage tool got angry with my overly broad mocks - if not path.startswith('/instance_path'): - return orig_listdir(path) - - if path == '/instance_path': - return ['instance-1', 'instance-2', 'instance-3', '_base'] - - if path == '/instance_path/_base': - return base_file_list - - self.fail('Unexpected directory listed: %s' % path) - - self.stubs.Set(os, 'listdir', lambda x: listdir(x)) - - # Fake isfile for these faked images in _base - orig_isfile = os.path.isfile - - def isfile(path): - # The python coverage tool got angry with my overly broad mocks - if not path.startswith('/instance_path'): - return orig_isfile(path) - - for p in base_file_list: - if path == fq_path(p): - return True - - self.fail('Unexpected isfile call: %s' % path) - - self.stubs.Set(os.path, 'isfile', lambda x: isfile(x)) - - # Fake the database call which lists running instances - instances = [{'image_ref': '1', - 'host': CONF.host, - 'name': 'instance-1', - 'uuid': '123', - 'vm_state': '', - 'task_state': ''}, - {'image_ref': '1', - 'kernel_id': '21', - 'ramdisk_id': '22', - 'host': CONF.host, - 'name': 'instance-2', - 'uuid': '456', - 'vm_state': '', - 'task_state': ''}] - all_instances = [fake_instance.fake_instance_obj(None, **instance) - for instance in instances] - image_cache_manager = imagecache.ImageCacheManager() - - # Fake the utils call which finds the backing image - def get_disk_backing_file(path): - if path in ['/instance_path/instance-1/disk', - '/instance_path/instance-2/disk']: - return fq_path('%s_5368709120' % hashed_1) - self.fail('Unexpected backing file lookup: %s' % path) - - self.stubs.Set(libvirt_utils, 'get_disk_backing_file', - lambda x: get_disk_backing_file(x)) - - # Fake out verifying checksums, as that is tested elsewhere - self.stubs.Set(image_cache_manager, '_verify_checksum', - lambda x, y: True) - - # Fake getmtime as well - orig_getmtime = os.path.getmtime - - def getmtime(path): - if not path.startswith('/instance_path'): - return orig_getmtime(path) - - return 1000000 - - self.stubs.Set(os.path, 'getmtime', lambda x: getmtime(x)) - - # Make sure we don't accidentally remove a real file - orig_remove = os.remove - - def remove(path): - if not path.startswith('/instance_path'): - return orig_remove(path) - - # Don't try to remove fake files - return - - self.stubs.Set(os, 'remove', lambda x: remove(x)) - - # And finally we can make the call we're actually testing... - # The argument here should be a context, but it is mocked out - image_cache_manager.update(None, all_instances) - - # Verify - active = [fq_path(hashed_1), fq_path('%s_5368709120' % hashed_1), - fq_path(hashed_21), fq_path(hashed_22)] - for act in active: - self.assertIn(act, image_cache_manager.active_base_files) - self.assertEqual(len(image_cache_manager.active_base_files), - len(active)) - - for rem in [fq_path('e97222e91fc4241f49a7f520d1dcf446751129b3_sm'), - fq_path('e09c675c2d1cfac32dae3c2d83689c8c94bc693b_sm'), - fq_path(hashed_42), - fq_path('%s_10737418240' % hashed_1)]: - self.assertIn(rem, image_cache_manager.removable_base_files) - - # Ensure there are no "corrupt" images as well - self.assertEqual(len(image_cache_manager.corrupt_base_files), 0) - - def test_verify_base_images_no_base(self): - self.flags(instances_path='/tmp/no/such/dir/name/please') - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.update(None, []) - - def test_is_valid_info_file(self): - hashed = 'e97222e91fc4241f49a7f520d1dcf446751129b3' - - self.flags(instances_path='/tmp/no/such/dir/name/please') - self.flags(image_info_filename_pattern=('$instances_path/_base/' - '%(image)s.info'), - group='libvirt') - base_filename = os.path.join(CONF.instances_path, '_base', hashed) - - is_valid_info_file = imagecache.is_valid_info_file - self.assertFalse(is_valid_info_file('banana')) - self.assertFalse(is_valid_info_file( - os.path.join(CONF.instances_path, '_base', '00000001'))) - self.assertFalse(is_valid_info_file(base_filename)) - self.assertFalse(is_valid_info_file(base_filename + '.sha1')) - self.assertTrue(is_valid_info_file(base_filename + '.info')) - - def test_configured_checksum_path(self): - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - - # Ensure there is a base directory - os.mkdir(os.path.join(tmpdir, '_base')) - - # Fake the database call which lists running instances - instances = [{'image_ref': '1', - 'host': CONF.host, - 'name': 'instance-1', - 'uuid': '123', - 'vm_state': '', - 'task_state': ''}, - {'image_ref': '1', - 'host': CONF.host, - 'name': 'instance-2', - 'uuid': '456', - 'vm_state': '', - 'task_state': ''}] - - all_instances = [] - for instance in instances: - all_instances.append(fake_instance.fake_instance_obj( - None, **instance)) - - def touch(filename): - f = open(filename, 'w') - f.write('Touched') - f.close() - - old = time.time() - (25 * 3600) - hashed = 'e97222e91fc4241f49a7f520d1dcf446751129b3' - base_filename = os.path.join(tmpdir, hashed) - touch(base_filename) - touch(base_filename + '.info') - os.utime(base_filename + '.info', (old, old)) - touch(base_filename + '.info') - os.utime(base_filename + '.info', (old, old)) - - image_cache_manager = imagecache.ImageCacheManager() - image_cache_manager.update(None, all_instances) - - self.assertTrue(os.path.exists(base_filename)) - self.assertTrue(os.path.exists(base_filename + '.info')) - - def test_compute_manager(self): - was = {'called': False} - - def fake_get_all_by_filters(context, *args, **kwargs): - was['called'] = True - instances = [] - for x in xrange(2): - instances.append(fake_instance.fake_db_instance( - image_ref='1', - uuid=x, - name=x, - vm_state='', - task_state='')) - return instances - - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - - self.stubs.Set(db, 'instance_get_all_by_filters', - fake_get_all_by_filters) - compute = importutils.import_object(CONF.compute_manager) - self.flags(use_local=True, group='conductor') - compute.conductor_api = conductor.API() - compute._run_image_cache_manager_pass(None) - self.assertTrue(was['called']) - - -class VerifyChecksumTestCase(test.NoDBTestCase): - - def setUp(self): - super(VerifyChecksumTestCase, self).setUp() - self.img = {'container_format': 'ami', 'id': '42'} - self.flags(checksum_base_images=True, group='libvirt') - - def _make_checksum(self, tmpdir): - testdata = ('OpenStack Software delivers a massively scalable cloud ' - 'operating system.') - - fname = os.path.join(tmpdir, 'aaa') - info_fname = imagecache.get_info_filename(fname) - - with open(fname, 'w') as f: - f.write(testdata) - - return fname, info_fname, testdata - - def _write_file(self, info_fname, info_attr, testdata): - f = open(info_fname, 'w') - if info_attr == "csum valid": - csum = hashlib.sha1() - csum.update(testdata) - f.write('{"sha1": "%s"}\n' % csum.hexdigest()) - elif info_attr == "csum invalid, not json": - f.write('banana') - else: - f.write('{"sha1": "banana"}') - f.close() - - def _check_body(self, tmpdir, info_attr): - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - fname, info_fname, testdata = self._make_checksum(tmpdir) - self._write_file(info_fname, info_attr, testdata) - image_cache_manager = imagecache.ImageCacheManager() - return image_cache_manager, fname - - def test_verify_checksum(self): - with utils.tempdir() as tmpdir: - image_cache_manager, fname = self._check_body(tmpdir, "csum valid") - res = image_cache_manager._verify_checksum(self.img, fname) - self.assertTrue(res) - - def test_verify_checksum_disabled(self): - self.flags(checksum_base_images=False, group='libvirt') - with utils.tempdir() as tmpdir: - image_cache_manager, fname = self._check_body(tmpdir, "csum valid") - res = image_cache_manager._verify_checksum(self.img, fname) - self.assertIsNone(res) - - def test_verify_checksum_invalid_json(self): - with intercept_log_messages() as stream: - with utils.tempdir() as tmpdir: - image_cache_manager, fname = ( - self._check_body(tmpdir, "csum invalid, not json")) - res = image_cache_manager._verify_checksum( - self.img, fname, create_if_missing=False) - self.assertFalse(res) - log = stream.getvalue() - - # NOTE(mikal): this is a skip not a fail because the file is - # present, but is not in valid json format and therefore is - # skipped. - self.assertNotEqual(log.find('image verification skipped'), -1) - - def test_verify_checksum_invalid_repaired(self): - with utils.tempdir() as tmpdir: - image_cache_manager, fname = ( - self._check_body(tmpdir, "csum invalid, not json")) - res = image_cache_manager._verify_checksum( - self.img, fname, create_if_missing=True) - self.assertIsNone(res) - - def test_verify_checksum_invalid(self): - with intercept_log_messages() as stream: - with utils.tempdir() as tmpdir: - image_cache_manager, fname = ( - self._check_body(tmpdir, "csum invalid, valid json")) - res = image_cache_manager._verify_checksum(self.img, fname) - self.assertFalse(res) - log = stream.getvalue() - self.assertNotEqual(log.find('image verification failed'), -1) - - def test_verify_checksum_file_missing(self): - with utils.tempdir() as tmpdir: - self.flags(instances_path=tmpdir) - self.flags(image_info_filename_pattern=('$instances_path/' - '%(image)s.info'), - group='libvirt') - fname, info_fname, testdata = self._make_checksum(tmpdir) - - image_cache_manager = imagecache.ImageCacheManager() - res = image_cache_manager._verify_checksum('aaa', fname) - self.assertIsNone(res) - - # Checksum requests for a file with no checksum now have the - # side effect of creating the checksum - self.assertTrue(os.path.exists(info_fname)) |