diff options
Diffstat (limited to 'nova/tests/test_imagecache.py')
-rw-r--r-- | nova/tests/test_imagecache.py | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/nova/tests/test_imagecache.py b/nova/tests/test_imagecache.py new file mode 100644 index 000000000..dee937bd2 --- /dev/null +++ b/nova/tests/test_imagecache.py @@ -0,0 +1,243 @@ +#!/usr/bin/python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# 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 hashlib +import os +import shutil +import tempfile +import time + +from nova import test + +from nova import db +from nova import flags +from nova import log as logging +from nova.virt.libvirt import imagecache +from nova.virt.libvirt import utils as virtutils + + +flags.DECLARE('instances_path', 'nova.compute.manager') +FLAGS = flags.FLAGS + +LOG = logging.getLogger('nova.tests.test_imagecache') + + +class ImageCacheManagerTestCase(test.TestCase): + + def test_read_stored_checksum_missing(self): + self.stubs.Set(os.path, 'exists', lambda x: False) + + csum = imagecache.read_stored_checksum('/tmp/foo') + self.assertEquals(csum, None) + + def test_read_stored_checksum(self): + try: + dirname = tempfile.mkdtemp() + fname = os.path.join(dirname, 'aaa') + + csum_input = 'fdghkfhkgjjksfdgjksjkghsdf' + f = open('%s.sha1' % fname, 'w') + f.write('%s\n' % csum_input) + f.close() + + csum_output = imagecache.read_stored_checksum(fname) + + self.assertEquals(csum_input, csum_output) + + finally: + shutil.rmtree(dirname) + + def test_list_base_images(self): + listing = ['00000001', + 'ephemeral_0_20_None', + 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm', + 'e09c675c2d1cfac32dae3c2d83689c8c94bc693b_sm', + 'e97222e91fc4241f49a7f520d1dcf446751129b3', + '00000004'] + + self.stubs.Set(os, 'listdir', lambda x: listing) + 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) + + self.assertEquals(len(image_cache_manager.unexplained_images), 3) + + expected = os.path.join(base_dir, + 'e97222e91fc4241f49a7f520d1dcf446751129b3') + self.assertTrue(expected in image_cache_manager.unexplained_images) + + unexpected = os.path.join(base_dir, '00000004') + self.assertFalse(unexpected in image_cache_manager.unexplained_images) + + for ent in image_cache_manager.unexplained_images: + self.assertTrue(ent.startswith(base_dir)) + + def test_list_running_instances(self): + self.stubs.Set(db, 'instance_get_all', + lambda x: [{'image_ref': 'image-1', + 'host': FLAGS.host, + 'name': 'inst-1'}, + {'image_ref': 'image-2', + 'host': FLAGS.host, + 'name': 'inst-2'}, + {'image_ref': 'image-2', + 'host': 'remotehost', + 'name': 'inst-3'}]) + + image_cache_manager = imagecache.ImageCacheManager() + + # The argument here should be a context, but its mocked out + image_cache_manager._list_running_instances(None) + + self.assertEqual(len(image_cache_manager.used_images), 2) + self.assertTrue(image_cache_manager.used_images['image-1'] == + (1, 0, ['inst-1'])) + self.assertTrue(image_cache_manager.used_images['image-2'] == + (1, 1, ['inst-2', 'inst-3'])) + + self.assertEqual(len(image_cache_manager.image_popularity), 2) + self.assertEqual(image_cache_manager.image_popularity['image-1'], 1) + self.assertEqual(image_cache_manager.image_popularity['image-2'], 2) + + def test_list_backing_images(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(virtutils, 'get_disk_backing_file', + lambda x: 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') + + found = os.path.join(FLAGS.instances_path, '_base', + 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') + + image_cache_manager = imagecache.ImageCacheManager() + image_cache_manager.unexplained_images = [found] + + inuse_images = image_cache_manager._list_backing_images() + + self.assertEquals(inuse_images, [found]) + self.assertEquals(len(image_cache_manager.unexplained_images), 0) + + 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): + self.stubs.Set(os.path, 'exists', + lambda x: x.endswith('549867354867_sm')) + + 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)) + + base_file = os.path.join(base_dir, fingerprint + '_sm') + self.assertTrue(res == [(base_file, True)]) + + def test_find_base_file_both(self): + self.stubs.Set(os.path, 'exists', lambda x: True) + + 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)) + + base_file1 = os.path.join(base_dir, fingerprint) + base_file2 = os.path.join(base_dir, fingerprint + '_sm') + self.assertTrue(res == [(base_file1, False), (base_file2, True)]) + + def test_verify_checksum(self): + testdata = ('OpenStack Software delivers a massively scalable cloud ' + 'operating system.') + img = {'container_format': 'ami', 'id': '42'} + + try: + dirname = tempfile.mkdtemp() + fname = os.path.join(dirname, 'aaa') + + f = open(fname, 'w') + f.write(testdata) + f.close() + + # Checksum is valid + f = open('%s.sha1' % fname, 'w') + csum = hashlib.sha1() + csum.update(testdata) + f.write(csum.hexdigest()) + f.close() + + image_cache_manager = imagecache.ImageCacheManager() + res = image_cache_manager._verify_checksum(img, fname) + self.assertTrue(res) + + # Checksum is invalid + f = open('%s.sha1' % fname, 'w') + f.write('banana') + f.close() + + image_cache_manager = imagecache.ImageCacheManager() + res = image_cache_manager._verify_checksum(img, fname) + self.assertFalse(res) + + # Checksum file missing + os.remove('%s.sha1' % fname) + image_cache_manager = imagecache.ImageCacheManager() + res = image_cache_manager._verify_checksum(img, fname) + self.assertEquals(res, None) + + finally: + shutil.rmtree(dirname) + + def test_remove_base_file(self): + try: + dirname = tempfile.mkdtemp() + fname = os.path.join(dirname, 'aaa') + + f = open(fname, 'w') + f.write('data') + f.close() + + f = open('%s.sha1' % fname, 'w') + f.close() + + image_cache_manager = imagecache.ImageCacheManager() + image_cache_manager._remove_base_file(fname) + + # Files are initially too new to delete + self.assertTrue(os.path.exists(fname)) + self.assertTrue(os.path.exists('%s.sha1' % fname)) + + # Old files get cleaned up though + os.utime(fname, (-1, time.time() - 100000)) + image_cache_manager._remove_base_file(fname) + + self.assertFalse(os.path.exists(fname)) + self.assertFalse(os.path.exists('%s.sha1' % fname)) + + finally: + shutil.rmtree(dirname) |