From 9d1ecf82152d64f96b6c4509f6e1d7cbac789b1e Mon Sep 17 00:00:00 2001 From: Zhi Yan Liu Date: Mon, 15 Dec 2014 22:34:28 +0800 Subject: [PATCH] Removes http-requests to glance/example.com in glance test This patch changes the references of glance test cases from glance.com and example.com to local fake http server. This change also fixed two test cases[0][1] which could broken by next glance_store release due to merged change [2] in http store driver changed return value when internal 404 NotFound happend on remote image access/query. [0] glance.tests.unit.v1.test_api.TestGlanceAPI. test_add_copy_from_image_authorized_upload_image_authorized [1] glance.tests.functional.v1.test_copy_to_file.TestCopyToFile. test_copy_from_http_nonexistent [2] https://github.com/openstack/glance_store/commit/53cb5c345faa88d76b79d73e3ac4bd15da9ff8a9 Closes bug 1298918 Change-Id: Ie80483e600e16e02240488e083293538e5512f35 Signed-off-by: Zhi Yan Liu --- .../tests/functional/v1/test_copy_to_file.py | 62 ++++++++++--------- glance/tests/functional/v2/test_images.py | 44 ++----------- glance/tests/unit/v1/test_api.py | 29 ++++++--- glance/tests/utils.py | 36 +++++++++++ 4 files changed, 94 insertions(+), 77 deletions(-) diff --git a/glance/tests/functional/v1/test_copy_to_file.py b/glance/tests/functional/v1/test_copy_to_file.py index 3bc2681e81..993a9b236c 100644 --- a/glance/tests/functional/v1/test_copy_to_file.py +++ b/glance/tests/functional/v1/test_copy_to_file.py @@ -177,43 +177,45 @@ class TestCopyToFile(functional.FunctionalTest): path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers) - self.assertEqual(201, response.status, content) - data = jsonutils.loads(content) + if response.status == 201: + data = jsonutils.loads(content) - copy_image_id = data['image']['id'] - self.assertEqual('queued', data['image']['status'], content) + copy_image_id = data['image']['id'] + self.assertEqual('queued', data['image']['status'], content) - path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, - copy_image_id) + path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, + copy_image_id) - def _await_status(expected_status): - for i in xrange(100): - time.sleep(0.01) - http = httplib2.Http() - response, content = http.request(path, 'HEAD') - self.assertEqual(200, response.status) - if response['x-image-meta-status'] == expected_status: - return - self.fail('unexpected image status %s' % - response['x-image-meta-status']) + def _await_status(expected_status): + for i in xrange(100): + time.sleep(0.01) + http = httplib2.Http() + response, content = http.request(path, 'HEAD') + self.assertEqual(200, response.status) + if response['x-image-meta-status'] == expected_status: + return + self.fail('unexpected image status %s' % + response['x-image-meta-status']) - _await_status('active' if exists else 'killed') + _await_status('active' if exists else 'killed') - # GET image and make sure image content is as expected - http = httplib2.Http() - response, content = http.request(path, 'GET') - self.assertEqual(200 if exists else 404, response.status) + # GET image and make sure image content is as expected + http = httplib2.Http() + response, content = http.request(path, 'GET') + self.assertEqual(200 if exists else 404, response.status) - if exists: - self.assertEqual(str(FIVE_KB), response['content-length']) - self.assertEqual("*" * FIVE_KB, content) - self.assertEqual(hashlib.md5("*" * FIVE_KB).hexdigest(), - hashlib.md5(content).hexdigest()) + if exists: + self.assertEqual(str(FIVE_KB), response['content-length']) + self.assertEqual("*" * FIVE_KB, content) + self.assertEqual(hashlib.md5("*" * FIVE_KB).hexdigest(), + hashlib.md5(content).hexdigest()) - # DELETE copied image - http = httplib2.Http() - response, content = http.request(path, 'DELETE') - self.assertEqual(200, response.status) + # DELETE copied image + http = httplib2.Http() + response, content = http.request(path, 'DELETE') + self.assertEqual(200, response.status) + else: + self.assertEqual(400, response.status, content) self.stop_servers() diff --git a/glance/tests/functional/v2/test_images.py b/glance/tests/functional/v2/test_images.py index d5628c98ce..0f3447f902 100644 --- a/glance/tests/functional/v2/test_images.py +++ b/glance/tests/functional/v2/test_images.py @@ -13,7 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -import BaseHTTPServer import os import signal import uuid @@ -23,6 +22,7 @@ import requests import six from glance.tests import functional +from glance.tests import utils as test_utils TENANT1 = str(uuid.uuid4()) @@ -31,42 +31,6 @@ TENANT3 = str(uuid.uuid4()) TENANT4 = str(uuid.uuid4()) -def get_handler_class(fixture): - class StaticHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): - def do_GET(self): - self.send_response(200) - self.send_header('Content-Length', str(len(fixture))) - self.end_headers() - self.wfile.write(fixture) - return - - def do_HEAD(self): - self.send_response(200) - self.send_header('Content-Length', str(len(fixture))) - self.end_headers() - return - - def log_message(self, *args, **kwargs): - # Override this method to prevent debug output from going - # to stderr during testing - return - - return StaticHTTPRequestHandler - - -def http_server(image_id, image_data): - server_address = ('127.0.0.1', 0) - handler_class = get_handler_class(image_data) - httpd = BaseHTTPServer.HTTPServer(server_address, handler_class) - port = httpd.socket.getsockname()[1] - - pid = os.fork() - if pid == 0: - httpd.serve_forever() - else: - return pid, port - - class TestImages(functional.FunctionalTest): def setUp(self): @@ -75,7 +39,8 @@ class TestImages(functional.FunctionalTest): self.api_server.deployment_flavor = 'noauth' self.api_server.data_api = 'glance.db.sqlalchemy.api' for i in range(3): - ret = http_server("foo_image_id%d" % i, "foo_image%d" % i) + ret = test_utils.start_http_server("foo_image_id%d" % i, + "foo_image%d" % i) setattr(self, 'http_server%d_pid' % i, ret[0]) setattr(self, 'http_port%d' % i, ret[1]) @@ -2420,7 +2385,8 @@ class TestImageLocationSelectionStrategy(functional.FunctionalTest): self.cleanup() self.api_server.deployment_flavor = 'noauth' for i in range(3): - ret = http_server("foo_image_id%d" % i, "foo_image%d" % i) + ret = test_utils.start_http_server("foo_image_id%d" % i, + "foo_image%d" % i) setattr(self, 'http_server%d_pid' % i, ret[0]) setattr(self, 'http_port%d' % i, ret[1]) diff --git a/glance/tests/unit/v1/test_api.py b/glance/tests/unit/v1/test_api.py index 5ddae5543f..18630d7d00 100644 --- a/glance/tests/unit/v1/test_api.py +++ b/glance/tests/unit/v1/test_api.py @@ -19,6 +19,8 @@ import contextlib import copy import datetime import hashlib +import os +import signal import uuid import glance_store as store @@ -95,11 +97,15 @@ class TestGlanceAPI(base.IsolatedUnitTest): self.create_fixtures() # Used to store/track image status changes for post-analysis self.image_status = [] + ret = test_utils.start_http_server("foo_image_id", "foo_image") + self.http_server_pid, self.http_port = ret def tearDown(self): """Clear the test environment""" super(TestGlanceAPI, self).tearDown() self.destroy_fixtures() + if self.http_server_pid is not None: + os.kill(self.http_server_pid, signal.SIGKILL) def create_fixtures(self): for fixture in self.FIXTURES: @@ -134,6 +140,9 @@ class TestGlanceAPI(base.IsolatedUnitTest): self.assertEqual(format_value, res_body['disk_format']) self.assertEqual(format_value, res_body['container_format']) + def _http_loc_url(self, path): + return 'http://127.0.0.1:%d%s' % (self.http_port, path) + def test_defaulted_amazon_format(self): for key in ('x-image-meta-disk-format', 'x-image-meta-container-format'): @@ -472,7 +481,7 @@ class TestGlanceAPI(base.IsolatedUnitTest): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', - 'x-image-meta-location': 'http://example.com/image.tar.gz', + 'x-image-meta-location': self._http_loc_url('/image.tar.gz'), 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'bare', } @@ -495,7 +504,7 @@ class TestGlanceAPI(base.IsolatedUnitTest): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'X' * 256, - 'x-image-meta-location': 'http://example.com/image.tar.gz', + 'x-image-meta-location': self._http_loc_url('/image.tar.gz'), 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'bare', } @@ -829,7 +838,8 @@ class TestGlanceAPI(base.IsolatedUnitTest): req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' - req.headers['x-image-meta-location'] = 'http://example.com/images/123' + url = self._http_loc_url('/images/123') + req.headers['x-image-meta-location'] = url res = req.get_response(self.api) self.assertEqual(400, res.status_int) @@ -894,9 +904,10 @@ class TestGlanceAPI(base.IsolatedUnitTest): def test_add_copy_from_image_unauthorized(self): rules = {"add_image": '@', "copy_from": '!'} self.set_policy_rules(rules) + url = self._http_loc_url('/i.ovf') fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', - 'x-glance-api-copy-from': 'http://glance.com/i.ovf', + 'x-glance-api-copy-from': url, 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} @@ -913,9 +924,10 @@ class TestGlanceAPI(base.IsolatedUnitTest): def test_add_copy_from_upload_image_unauthorized(self): rules = {"add_image": '@', "copy_from": '@', "upload_image": '!'} self.set_policy_rules(rules) + url = self._http_loc_url('/i.ovf') fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', - 'x-glance-api-copy-from': 'http://glance.com/i.ovf', + 'x-glance-api-copy-from': url, 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} @@ -931,9 +943,10 @@ class TestGlanceAPI(base.IsolatedUnitTest): def test_add_copy_from_image_authorized_upload_image_authorized(self): rules = {"add_image": '@', "copy_from": '@', "upload_image": '@'} self.set_policy_rules(rules) + url = self._http_loc_url('/i.ovf') fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', - 'x-glance-api-copy-from': 'http://glance.com/i.ovf', + 'x-glance-api-copy-from': url, 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} @@ -1193,7 +1206,7 @@ class TestGlanceAPI(base.IsolatedUnitTest): req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' - req.headers['x-glance-api-copy-from'] = 'http://glance.com/i.ovf' + req.headers['x-glance-api-copy-from'] = self._http_loc_url('/i.ovf') res = req.get_response(self.api) self.assertEqual(403, res.status_int) @@ -1219,7 +1232,7 @@ class TestGlanceAPI(base.IsolatedUnitTest): req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' - req.headers['x-glance-api-copy-from'] = 'http://glance.com/i.ovf' + req.headers['x-glance-api-copy-from'] = self._http_loc_url('/i.ovf') res = req.get_response(self.api) self.assertEqual(403, res.status_int) diff --git a/glance/tests/utils.py b/glance/tests/utils.py index 0c537b3a97..37b3e98575 100644 --- a/glance/tests/utils.py +++ b/glance/tests/utils.py @@ -15,6 +15,7 @@ """Common utilities used in testing""" +import BaseHTTPServer import errno import functools import os @@ -413,6 +414,41 @@ def minimal_add_command(port, name, suffix='', public=True): " name=%s %s" % (port, visibility, name, suffix)) +def start_http_server(image_id, image_data): + def _get_http_handler_class(fixture): + class StaticHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + def do_GET(self): + self.send_response(200) + self.send_header('Content-Length', str(len(fixture))) + self.end_headers() + self.wfile.write(fixture) + return + + def do_HEAD(self): + self.send_response(200) + self.send_header('Content-Length', str(len(fixture))) + self.end_headers() + return + + def log_message(self, *args, **kwargs): + # Override this method to prevent debug output from going + # to stderr during testing + return + + return StaticHTTPRequestHandler + + server_address = ('127.0.0.1', 0) + handler_class = _get_http_handler_class(image_data) + httpd = BaseHTTPServer.HTTPServer(server_address, handler_class) + port = httpd.socket.getsockname()[1] + + pid = os.fork() + if pid == 0: + httpd.serve_forever() + else: + return pid, port + + class RegistryAPIMixIn(object): def create_fixtures(self):