diff options
author | John L. Villalovos <john.l.villalovos@intel.com> | 2015-09-28 11:36:37 -0700 |
---|---|---|
committer | John L. Villalovos <openstack.org@sodarock.com> | 2015-09-28 21:27:01 +0000 |
commit | f350d87af82ba8e33c19fb03eeb67625027838db (patch) | |
tree | 21b2b058ad13c7e1a9897c26a82fa2d99be8ecae /ironic/tests/unit/common/test_glance_service.py | |
parent | efb8b2abb67ae8810cd59cb5879b33060e1051b4 (diff) | |
download | ironic-f350d87af82ba8e33c19fb03eeb67625027838db.tar.gz |
Prepare for functional testing
Prepare for functional testing by creating two new directories:
* ironic/tests/unit
* ironic/tests/functional
Move all files currently in ironic/tests/* to ironic/tests/unit/
Update imports from 'ironic.tests.YYY' to 'ironic.tests.unit.YYY'
Fix any PEP8 issues due to longer lines
Partial-Bug: #1491670
Change-Id: I1166f20adf8c84b2042b62e348926502a4851e08
Diffstat (limited to 'ironic/tests/unit/common/test_glance_service.py')
-rw-r--r-- | ironic/tests/unit/common/test_glance_service.py | 860 |
1 files changed, 860 insertions, 0 deletions
diff --git a/ironic/tests/unit/common/test_glance_service.py b/ironic/tests/unit/common/test_glance_service.py new file mode 100644 index 000000000..881b86eaa --- /dev/null +++ b/ironic/tests/unit/common/test_glance_service.py @@ -0,0 +1,860 @@ +# Copyright 2013 Hewlett-Packard Development Company, L.P. +# 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 datetime +import filecmp +import os +import tempfile +import time + +from glanceclient import exc as glance_exc +import mock +from oslo_config import cfg +from oslo_context import context +from oslo_serialization import jsonutils +import testtools + +from ironic.common import exception +from ironic.common.glance_service import base_image_service +from ironic.common.glance_service import service_utils +from ironic.common import image_service as service +from ironic.tests.unit import base +from ironic.tests.unit import stubs + + +CONF = cfg.CONF + + +class NullWriter(object): + """Used to test ImageService.get which takes a writer object.""" + + def write(self, *arg, **kwargs): + pass + + +class TestGlanceSerializer(testtools.TestCase): + def test_serialize(self): + metadata = {'name': 'image1', + 'is_public': True, + 'foo': 'bar', + 'properties': { + 'prop1': 'propvalue1', + 'mappings': [ + {'virtual': 'aaa', + 'device': 'bbb'}, + {'virtual': 'xxx', + 'device': 'yyy'}], + 'block_device_mapping': [ + {'virtual_device': 'fake', + 'device_name': '/dev/fake'}, + {'virtual_device': 'ephemeral0', + 'device_name': '/dev/fake0'}]}} + + converted_expected = { + 'name': 'image1', + 'is_public': True, + 'foo': 'bar', + 'properties': {'prop1': 'propvalue1'} + } + converted = service_utils._convert(metadata, 'to') + self.assertEqual(metadata, + service_utils._convert(converted, 'from')) + # Fields that rely on dict ordering can't be compared as text + mappings = jsonutils.loads(converted['properties'] + .pop('mappings')) + self.assertEqual([{"device": "bbb", "virtual": "aaa"}, + {"device": "yyy", "virtual": "xxx"}], + mappings) + bd_mapping = jsonutils.loads(converted['properties'] + .pop('block_device_mapping')) + self.assertEqual([{"virtual_device": "fake", + "device_name": "/dev/fake"}, + {"virtual_device": "ephemeral0", + "device_name": "/dev/fake0"}], + bd_mapping) + # Compare the remaining + self.assertEqual(converted_expected, converted) + + +class TestGlanceImageService(base.TestCase): + NOW_GLANCE_OLD_FORMAT = "2010-10-11T10:30:22" + NOW_GLANCE_FORMAT = "2010-10-11T10:30:22.000000" + + NOW_DATETIME = datetime.datetime(2010, 10, 11, 10, 30, 22) + + def setUp(self): + super(TestGlanceImageService, self).setUp() + client = stubs.StubGlanceClient() + self.context = context.RequestContext(auth_token=True) + self.context.user_id = 'fake' + self.context.project_id = 'fake' + self.service = service.GlanceImageService(client, 1, self.context) + + self.config(glance_host='localhost', group='glance') + try: + self.config(auth_strategy='keystone', group='glance') + except Exception: + opts = [ + cfg.StrOpt('auth_strategy', default='keystone'), + ] + CONF.register_opts(opts) + + return + + @staticmethod + def _make_fixture(**kwargs): + fixture = {'name': None, + 'properties': {}, + 'status': None, + 'is_public': None} + fixture.update(kwargs) + return fixture + + @property + def endpoint(self): + # For glanceclient versions >= 0.13, the endpoint is located + # under http_client (blueprint common-client-library-2) + # I5addc38eb2e2dd0be91b566fda7c0d81787ffa75 + # Test both options to keep backward compatibility + if getattr(self.service.client, 'endpoint', None): + endpoint = self.service.client.endpoint + else: + endpoint = self.service.client.http_client.endpoint + return endpoint + + def _make_datetime_fixture(self): + return self._make_fixture(created_at=self.NOW_GLANCE_FORMAT, + updated_at=self.NOW_GLANCE_FORMAT, + deleted_at=self.NOW_GLANCE_FORMAT) + + def test_create_with_instance_id(self): + # Ensure instance_id is persisted as an image-property. + fixture = {'name': 'test image', + 'is_public': False, + 'properties': {'instance_id': '42', 'user_id': 'fake'}} + image_id = self.service.create(fixture)['id'] + image_meta = self.service.show(image_id) + expected = { + 'id': image_id, + 'name': 'test image', + 'is_public': False, + 'size': None, + 'min_disk': None, + 'min_ram': None, + 'disk_format': None, + 'container_format': None, + 'checksum': None, + 'created_at': self.NOW_DATETIME, + 'updated_at': self.NOW_DATETIME, + 'deleted_at': None, + 'deleted': None, + 'status': None, + 'properties': {'instance_id': '42', 'user_id': 'fake'}, + 'owner': None, + } + + self.assertDictEqual(expected, image_meta) + + image_metas = self.service.detail() + self.assertDictEqual(expected, image_metas[0]) + + def test_create_without_instance_id(self): + """Test creating an image without an instance ID. + + Ensure we can create an image without having to specify an + instance_id. Public images are an example of an image not tied to an + instance. + """ + fixture = {'name': 'test image', 'is_public': False} + image_id = self.service.create(fixture)['id'] + + expected = { + 'id': image_id, + 'name': 'test image', + 'is_public': False, + 'size': None, + 'min_disk': None, + 'min_ram': None, + 'disk_format': None, + 'container_format': None, + 'checksum': None, + 'created_at': self.NOW_DATETIME, + 'updated_at': self.NOW_DATETIME, + 'deleted_at': None, + 'deleted': None, + 'status': None, + 'properties': {}, + 'owner': None, + } + actual = self.service.show(image_id) + self.assertDictEqual(expected, actual) + + def test_create(self): + fixture = self._make_fixture(name='test image') + num_images = len(self.service.detail()) + image_id = self.service.create(fixture)['id'] + + self.assertIsNotNone(image_id) + self.assertEqual( + num_images + 1, len(self.service.detail())) + + def test_create_and_show_non_existing_image(self): + fixture = self._make_fixture(name='test image') + image_id = self.service.create(fixture)['id'] + + self.assertIsNotNone(image_id) + self.assertRaises(exception.ImageNotFound, + self.service.show, + 'bad image id') + + def test_detail_private_image(self): + fixture = self._make_fixture(name='test image') + fixture['is_public'] = False + properties = {'owner_id': 'proj1'} + fixture['properties'] = properties + + self.service.create(fixture)['id'] + + proj = self.context.project_id + self.context.project_id = 'proj1' + + image_metas = self.service.detail() + + self.context.project_id = proj + + self.assertEqual(1, len(image_metas)) + self.assertEqual('test image', image_metas[0]['name']) + self.assertEqual(False, image_metas[0]['is_public']) + + def test_detail_marker(self): + fixtures = [] + ids = [] + for i in range(10): + fixture = self._make_fixture(name='TestImage %d' % (i)) + fixtures.append(fixture) + ids.append(self.service.create(fixture)['id']) + + image_metas = self.service.detail(marker=ids[1]) + self.assertEqual(8, len(image_metas)) + i = 2 + for meta in image_metas: + expected = { + 'id': ids[i], + 'status': None, + 'is_public': None, + 'name': 'TestImage %d' % (i), + 'properties': {}, + 'size': None, + 'min_disk': None, + 'min_ram': None, + 'disk_format': None, + 'container_format': None, + 'checksum': None, + 'created_at': self.NOW_DATETIME, + 'updated_at': self.NOW_DATETIME, + 'deleted_at': None, + 'deleted': None, + 'owner': None, + } + + self.assertDictEqual(expected, meta) + i = i + 1 + + def test_detail_limit(self): + fixtures = [] + ids = [] + for i in range(10): + fixture = self._make_fixture(name='TestImage %d' % (i)) + fixtures.append(fixture) + ids.append(self.service.create(fixture)['id']) + + image_metas = self.service.detail(limit=5) + self.assertEqual(5, len(image_metas)) + + def test_detail_default_limit(self): + fixtures = [] + ids = [] + for i in range(10): + fixture = self._make_fixture(name='TestImage %d' % (i)) + fixtures.append(fixture) + ids.append(self.service.create(fixture)['id']) + + image_metas = self.service.detail() + for i, meta in enumerate(image_metas): + self.assertEqual(meta['name'], 'TestImage %d' % (i)) + + def test_detail_marker_and_limit(self): + fixtures = [] + ids = [] + for i in range(10): + fixture = self._make_fixture(name='TestImage %d' % (i)) + fixtures.append(fixture) + ids.append(self.service.create(fixture)['id']) + + image_metas = self.service.detail(marker=ids[3], limit=5) + self.assertEqual(5, len(image_metas)) + i = 4 + for meta in image_metas: + expected = { + 'id': ids[i], + 'status': None, + 'is_public': None, + 'name': 'TestImage %d' % (i), + 'properties': {}, + 'size': None, + 'min_disk': None, + 'min_ram': None, + 'disk_format': None, + 'container_format': None, + 'checksum': None, + 'created_at': self.NOW_DATETIME, + 'updated_at': self.NOW_DATETIME, + 'deleted_at': None, + 'deleted': None, + 'owner': None, + } + self.assertDictEqual(expected, meta) + i = i + 1 + + def test_detail_invalid_marker(self): + fixtures = [] + ids = [] + for i in range(10): + fixture = self._make_fixture(name='TestImage %d' % (i)) + fixtures.append(fixture) + ids.append(self.service.create(fixture)['id']) + + self.assertRaises(exception.Invalid, self.service.detail, + marker='invalidmarker') + + def test_update(self): + fixture = self._make_fixture(name='test image') + image = self.service.create(fixture) + image_id = image['id'] + fixture['name'] = 'new image name' + self.service.update(image_id, fixture) + + new_image_data = self.service.show(image_id) + self.assertEqual('new image name', new_image_data['name']) + + def test_delete(self): + fixture1 = self._make_fixture(name='test image 1') + fixture2 = self._make_fixture(name='test image 2') + fixtures = [fixture1, fixture2] + + num_images = len(self.service.detail()) + self.assertEqual(0, num_images) + + ids = [] + for fixture in fixtures: + new_id = self.service.create(fixture)['id'] + ids.append(new_id) + + num_images = len(self.service.detail()) + self.assertEqual(2, num_images) + + self.service.delete(ids[0]) + # When you delete an image from glance, it sets the status to DELETED + # and doesn't actually remove the image. + + # Check the image is still there. + num_images = len(self.service.detail()) + self.assertEqual(2, num_images) + + # Check the image is marked as deleted. + num_images = len([x for x in self.service.detail() + if not x['deleted']]) + self.assertEqual(1, num_images) + + def test_show_passes_through_to_client(self): + fixture = self._make_fixture(name='image1', is_public=True) + image_id = self.service.create(fixture)['id'] + + image_meta = self.service.show(image_id) + expected = { + 'id': image_id, + 'name': 'image1', + 'is_public': True, + 'size': None, + 'min_disk': None, + 'min_ram': None, + 'disk_format': None, + 'container_format': None, + 'checksum': None, + 'created_at': self.NOW_DATETIME, + 'updated_at': self.NOW_DATETIME, + 'deleted_at': None, + 'deleted': None, + 'status': None, + 'properties': {}, + 'owner': None, + } + self.assertEqual(expected, image_meta) + + def test_show_raises_when_no_authtoken_in_the_context(self): + fixture = self._make_fixture(name='image1', + is_public=False, + properties={'one': 'two'}) + image_id = self.service.create(fixture)['id'] + self.context.auth_token = False + self.assertRaises(exception.ImageNotFound, + self.service.show, + image_id) + + def test_detail_passes_through_to_client(self): + fixture = self._make_fixture(name='image10', is_public=True) + image_id = self.service.create(fixture)['id'] + image_metas = self.service.detail() + expected = [ + { + 'id': image_id, + 'name': 'image10', + 'is_public': True, + 'size': None, + 'min_disk': None, + 'min_ram': None, + 'disk_format': None, + 'container_format': None, + 'checksum': None, + 'created_at': self.NOW_DATETIME, + 'updated_at': self.NOW_DATETIME, + 'deleted_at': None, + 'deleted': None, + 'status': None, + 'properties': {}, + 'owner': None, + }, + ] + self.assertEqual(expected, image_metas) + + def test_show_makes_datetimes(self): + fixture = self._make_datetime_fixture() + image_id = self.service.create(fixture)['id'] + image_meta = self.service.show(image_id) + self.assertEqual(self.NOW_DATETIME, image_meta['created_at']) + self.assertEqual(self.NOW_DATETIME, image_meta['updated_at']) + + def test_detail_makes_datetimes(self): + fixture = self._make_datetime_fixture() + self.service.create(fixture) + image_meta = self.service.detail()[0] + self.assertEqual(self.NOW_DATETIME, image_meta['created_at']) + self.assertEqual(self.NOW_DATETIME, image_meta['updated_at']) + + @mock.patch.object(time, 'sleep', autospec=True) + def test_download_with_retries(self, mock_sleep): + tries = [0] + + class MyGlanceStubClient(stubs.StubGlanceClient): + """A client that fails the first time, then succeeds.""" + def get(self, image_id): + if tries[0] == 0: + tries[0] = 1 + raise glance_exc.ServiceUnavailable('') + else: + return {} + + stub_client = MyGlanceStubClient() + stub_context = context.RequestContext(auth_token=True) + stub_context.user_id = 'fake' + stub_context.project_id = 'fake' + stub_service = service.GlanceImageService(stub_client, 1, stub_context) + image_id = 1 # doesn't matter + writer = NullWriter() + + # When retries are disabled, we should get an exception + self.config(glance_num_retries=0, group='glance') + self.assertRaises(exception.GlanceConnectionFailed, + stub_service.download, image_id, writer) + + # Now lets enable retries. No exception should happen now. + tries = [0] + self.config(glance_num_retries=1, group='glance') + stub_service.download(image_id, writer) + self.assertTrue(mock_sleep.called) + + def test_download_file_url(self): + # NOTE: only in v2 API + class MyGlanceStubClient(stubs.StubGlanceClient): + + """A client that returns a file url.""" + + (outfd, s_tmpfname) = tempfile.mkstemp(prefix='directURLsrc') + outf = os.fdopen(outfd, 'wb') + inf = open('/dev/urandom', 'rb') + for i in range(10): + _data = inf.read(1024) + outf.write(_data) + outf.close() + + def get(self, image_id): + return type('GlanceTestDirectUrlMeta', (object,), + {'direct_url': 'file://%s' + self.s_tmpfname}) + + stub_context = context.RequestContext(auth_token=True) + stub_context.user_id = 'fake' + stub_context.project_id = 'fake' + stub_client = MyGlanceStubClient() + (outfd, tmpfname) = tempfile.mkstemp(prefix='directURLdst') + writer = os.fdopen(outfd, 'w') + + stub_service = service.GlanceImageService(stub_client, + context=stub_context, + version=2) + image_id = 1 # doesn't matter + + self.config(allowed_direct_url_schemes=['file'], group='glance') + stub_service.download(image_id, writer) + writer.close() + + # compare the two files + rc = filecmp.cmp(tmpfname, stub_client.s_tmpfname) + self.assertTrue(rc, "The file %s and %s should be the same" % + (tmpfname, stub_client.s_tmpfname)) + os.remove(stub_client.s_tmpfname) + os.remove(tmpfname) + + def test_client_forbidden_converts_to_imagenotauthed(self): + class MyGlanceStubClient(stubs.StubGlanceClient): + """A client that raises a Forbidden exception.""" + def get(self, image_id): + raise glance_exc.Forbidden(image_id) + + stub_client = MyGlanceStubClient() + stub_context = context.RequestContext(auth_token=True) + stub_context.user_id = 'fake' + stub_context.project_id = 'fake' + stub_service = service.GlanceImageService(stub_client, 1, stub_context) + image_id = 1 # doesn't matter + writer = NullWriter() + self.assertRaises(exception.ImageNotAuthorized, stub_service.download, + image_id, writer) + + def test_client_httpforbidden_converts_to_imagenotauthed(self): + class MyGlanceStubClient(stubs.StubGlanceClient): + """A client that raises a HTTPForbidden exception.""" + def get(self, image_id): + raise glance_exc.HTTPForbidden(image_id) + + stub_client = MyGlanceStubClient() + stub_context = context.RequestContext(auth_token=True) + stub_context.user_id = 'fake' + stub_context.project_id = 'fake' + stub_service = service.GlanceImageService(stub_client, 1, stub_context) + image_id = 1 # doesn't matter + writer = NullWriter() + self.assertRaises(exception.ImageNotAuthorized, stub_service.download, + image_id, writer) + + def test_client_notfound_converts_to_imagenotfound(self): + class MyGlanceStubClient(stubs.StubGlanceClient): + """A client that raises a NotFound exception.""" + def get(self, image_id): + raise glance_exc.NotFound(image_id) + + stub_client = MyGlanceStubClient() + stub_context = context.RequestContext(auth_token=True) + stub_context.user_id = 'fake' + stub_context.project_id = 'fake' + stub_service = service.GlanceImageService(stub_client, 1, stub_context) + image_id = 1 # doesn't matter + writer = NullWriter() + self.assertRaises(exception.ImageNotFound, stub_service.download, + image_id, writer) + + def test_client_httpnotfound_converts_to_imagenotfound(self): + class MyGlanceStubClient(stubs.StubGlanceClient): + """A client that raises a HTTPNotFound exception.""" + def get(self, image_id): + raise glance_exc.HTTPNotFound(image_id) + + stub_client = MyGlanceStubClient() + stub_context = context.RequestContext(auth_token=True) + stub_context.user_id = 'fake' + stub_context.project_id = 'fake' + stub_service = service.GlanceImageService(stub_client, 1, stub_context) + image_id = 1 # doesn't matter + writer = NullWriter() + self.assertRaises(exception.ImageNotFound, stub_service.download, + image_id, writer) + + def test_check_image_service_client_set(self): + def func(self): + return True + + self.service.client = True + + wrapped_func = base_image_service.check_image_service(func) + self.assertTrue(wrapped_func(self.service)) + + def test_check_image_service__no_client_set_http(self): + def func(service, *args, **kwargs): + return (self.endpoint, args, kwargs) + + self.service.client = None + params = {'image_href': 'http://123.123.123.123:9292/image_uuid'} + self.config(auth_strategy='keystone', group='glance') + wrapped_func = base_image_service.check_image_service(func) + self.assertEqual(('http://123.123.123.123:9292', (), params), + wrapped_func(self.service, **params)) + + def test_get_image_service__no_client_set_https(self): + def func(service, *args, **kwargs): + return (self.endpoint, args, kwargs) + + self.service.client = None + params = {'image_href': 'https://123.123.123.123:9292/image_uuid'} + self.config(auth_strategy='keystone', group='glance') + wrapped_func = base_image_service.check_image_service(func) + + self.assertEqual(('https://123.123.123.123:9292', (), params), + wrapped_func(self.service, **params)) + + +def _create_failing_glance_client(info): + class MyGlanceStubClient(stubs.StubGlanceClient): + """A client that fails the first time, then succeeds.""" + def get(self, image_id): + info['num_calls'] += 1 + if info['num_calls'] == 1: + raise glance_exc.ServiceUnavailable('') + return {} + + return MyGlanceStubClient() + + +class TestGlanceSwiftTempURL(base.TestCase): + def setUp(self): + super(TestGlanceSwiftTempURL, self).setUp() + client = stubs.StubGlanceClient() + self.context = context.RequestContext() + self.context.auth_token = 'fake' + self.service = service.GlanceImageService(client, 2, self.context) + self.config(swift_temp_url_key='correcthorsebatterystaple', + group='glance') + self.config(swift_endpoint_url='https://swift.example.com', + group='glance') + self.config(swift_account='AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30', + group='glance') + self.config(swift_api_version='v1', + group='glance') + self.config(swift_container='glance', + group='glance') + self.config(swift_temp_url_duration=1200, + group='glance') + self.config(swift_store_multiple_containers_seed=0, + group='glance') + self.config() + self.fake_image = { + 'id': '757274c4-2856-4bd2-bb20-9a4a231e187b' + } + + @mock.patch('swiftclient.utils.generate_temp_url', autospec=True) + def test_swift_temp_url(self, tempurl_mock): + + path = ('/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30' + '/glance' + '/757274c4-2856-4bd2-bb20-9a4a231e187b') + tempurl_mock.return_value = ( + path + '?temp_url_sig=hmacsig&temp_url_expires=1400001200') + + self.service._validate_temp_url_config = mock.Mock() + + temp_url = self.service.swift_temp_url(image_info=self.fake_image) + + self.assertEqual(CONF.glance.swift_endpoint_url + + tempurl_mock.return_value, + temp_url) + tempurl_mock.assert_called_with( + path=path, + seconds=CONF.glance.swift_temp_url_duration, + key=CONF.glance.swift_temp_url_key, + method='GET') + + @mock.patch('swiftclient.utils.generate_temp_url', autospec=True) + def test_swift_temp_url_multiple_containers(self, tempurl_mock): + + self.config(swift_store_multiple_containers_seed=8, + group='glance') + + path = ('/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30' + '/glance_757274c4' + '/757274c4-2856-4bd2-bb20-9a4a231e187b') + tempurl_mock.return_value = ( + path + '?temp_url_sig=hmacsig&temp_url_expires=1400001200') + + self.service._validate_temp_url_config = mock.Mock() + + temp_url = self.service.swift_temp_url(image_info=self.fake_image) + + self.assertEqual(CONF.glance.swift_endpoint_url + + tempurl_mock.return_value, + temp_url) + tempurl_mock.assert_called_with( + path=path, + seconds=CONF.glance.swift_temp_url_duration, + key=CONF.glance.swift_temp_url_key, + method='GET') + + def test_swift_temp_url_url_bad_no_info(self): + self.assertRaises(exception.ImageUnacceptable, + self.service.swift_temp_url, + image_info={}) + + def test__validate_temp_url_config(self): + self.service._validate_temp_url_config() + + def test__validate_temp_url_key_exception(self): + self.config(swift_temp_url_key=None, group='glance') + self.assertRaises(exception.MissingParameterValue, + self.service._validate_temp_url_config) + + def test__validate_temp_url_endpoint_config_exception(self): + self.config(swift_endpoint_url=None, group='glance') + self.assertRaises(exception.MissingParameterValue, + self.service._validate_temp_url_config) + + def test__validate_temp_url_account_exception(self): + self.config(swift_account=None, group='glance') + self.assertRaises(exception.MissingParameterValue, + self.service._validate_temp_url_config) + + def test__validate_temp_url_endpoint_negative_duration(self): + self.config(swift_temp_url_duration=-1, + group='glance') + self.assertRaises(exception.InvalidParameterValue, + self.service._validate_temp_url_config) + + def test__validate_temp_url_multiple_containers(self): + self.config(swift_store_multiple_containers_seed=-1, + group='glance') + self.assertRaises(exception.InvalidParameterValue, + self.service._validate_temp_url_config) + self.config(swift_store_multiple_containers_seed=None, + group='glance') + self.assertRaises(exception.InvalidParameterValue, + self.service._validate_temp_url_config) + self.config(swift_store_multiple_containers_seed=33, + group='glance') + self.assertRaises(exception.InvalidParameterValue, + self.service._validate_temp_url_config) + + +class TestGlanceUrl(base.TestCase): + + def test_generate_glance_http_url(self): + self.config(glance_host="127.0.0.1", group='glance') + generated_url = service_utils.generate_glance_url() + http_url = "http://%s:%d" % (CONF.glance.glance_host, + CONF.glance.glance_port) + self.assertEqual(http_url, generated_url) + + def test_generate_glance_https_url(self): + self.config(glance_protocol="https", group='glance') + self.config(glance_host="127.0.0.1", group='glance') + generated_url = service_utils.generate_glance_url() + https_url = "https://%s:%d" % (CONF.glance.glance_host, + CONF.glance.glance_port) + self.assertEqual(https_url, generated_url) + + +class TestServiceUtils(base.TestCase): + + def test_parse_image_ref_no_ssl(self): + image_href = u'http://127.0.0.1:9292/image_path/'\ + u'image_\u00F9\u00FA\u00EE\u0111' + parsed_href = service_utils.parse_image_ref(image_href) + self.assertEqual((u'image_\u00F9\u00FA\u00EE\u0111', + '127.0.0.1', 9292, False), parsed_href) + + def test_parse_image_ref_ssl(self): + image_href = 'https://127.0.0.1:9292/image_path/'\ + u'image_\u00F9\u00FA\u00EE\u0111' + parsed_href = service_utils.parse_image_ref(image_href) + self.assertEqual((u'image_\u00F9\u00FA\u00EE\u0111', + '127.0.0.1', 9292, True), parsed_href) + + def test_generate_image_url(self): + image_href = u'image_\u00F9\u00FA\u00EE\u0111' + self.config(glance_host='123.123.123.123', group='glance') + self.config(glance_port=1234, group='glance') + self.config(glance_protocol='https', group='glance') + generated_url = service_utils.generate_image_url(image_href) + self.assertEqual('https://123.123.123.123:1234/images/' + u'image_\u00F9\u00FA\u00EE\u0111', + generated_url) + + def test_is_glance_image(self): + image_href = u'uui\u0111' + self.assertFalse(service_utils.is_glance_image(image_href)) + image_href = u'733d1c44-a2ea-414b-aca7-69decf20d810' + self.assertTrue(service_utils.is_glance_image(image_href)) + image_href = u'glance://uui\u0111' + self.assertTrue(service_utils.is_glance_image(image_href)) + image_href = 'http://aaa/bbb' + self.assertFalse(service_utils.is_glance_image(image_href)) + image_href = None + self.assertFalse(service_utils.is_glance_image(image_href)) + + def test_is_image_href_ordinary_file_name_true(self): + image = u"\u0111eploy.iso" + result = service_utils.is_image_href_ordinary_file_name(image) + self.assertTrue(result) + + def test_is_image_href_ordinary_file_name_false(self): + for image in ('733d1c44-a2ea-414b-aca7-69decf20d810', + u'glance://\u0111eploy_iso', + u'http://\u0111eploy_iso', + u'https://\u0111eploy_iso', + u'file://\u0111eploy_iso',): + result = service_utils.is_image_href_ordinary_file_name(image) + self.assertFalse(result) + + +class TestGlanceAPIServers(base.TestCase): + + def setUp(self): + super(TestGlanceAPIServers, self).setUp() + service_utils._GLANCE_API_SERVER = None + + def test__get_api_servers_default(self): + host, port, use_ssl = service_utils._get_api_server() + self.assertEqual(CONF.glance.glance_host, host) + self.assertEqual(CONF.glance.glance_port, port) + self.assertEqual(CONF.glance.glance_protocol == 'https', use_ssl) + + def test__get_api_servers_one(self): + CONF.set_override('glance_api_servers', ['https://10.0.0.1:9293'], + 'glance') + s1 = service_utils._get_api_server() + s2 = service_utils._get_api_server() + self.assertEqual(('10.0.0.1', 9293, True), s1) + + # Only one server, should always get the same one + self.assertEqual(s1, s2) + + def test__get_api_servers_two(self): + CONF.set_override('glance_api_servers', + ['http://10.0.0.1:9293', 'http://10.0.0.2:9294'], + 'glance') + s1 = service_utils._get_api_server() + s2 = service_utils._get_api_server() + s3 = service_utils._get_api_server() + + self.assertNotEqual(s1, s2) + + # 2 servers, so cycles to the first again + self.assertEqual(s1, s3) |