os-xenapi: fix CI to fit the change that glance-api use uwsgi
Need change xenapi code to fit the change that glance-api switched to uwsgi and add back the glance relative tests. Use urlparser to get the suffix of the endepoint to build the http url. Using it in glance service request in order to specify glance service Change-Id: I5abdba24dc77c165100ba7d20cc731ce6076a4c7
This commit is contained in:
@@ -297,7 +297,7 @@ def _upload_tarball_by_url_v1(staging_path, image_id, glance_endpoint,
|
||||
conn.close()
|
||||
|
||||
|
||||
def _update_image_meta_v2(conn, image_id, extra_headers, properties):
|
||||
def _update_image_meta_v2(conn, extra_headers, properties, patch_path):
|
||||
# NOTE(sirp): There is some confusion around OVF. Here's a summary
|
||||
# of where we currently stand:
|
||||
# 1. OVF as a container format is misnamed. We really should be
|
||||
@@ -321,8 +321,8 @@ def _update_image_meta_v2(conn, image_id, extra_headers, properties):
|
||||
"op": "add"}
|
||||
body.append(prop)
|
||||
body = json.dumps(body)
|
||||
conn.request('PATCH', '/v2/images/%s' % image_id,
|
||||
body=body, headers=headers)
|
||||
|
||||
conn.request('PATCH', patch_path, body=body, headers=headers)
|
||||
resp = conn.getresponse()
|
||||
resp.read()
|
||||
|
||||
@@ -364,9 +364,17 @@ def _upload_tarball_by_url_v2(staging_path, image_id, glance_endpoint,
|
||||
raise RetryableError(error)
|
||||
|
||||
try:
|
||||
_update_image_meta_v2(conn, image_id, extra_headers, properties)
|
||||
mgt_url = "%(glance_endpoint)s/v2/images/%(image_id)s" % {
|
||||
'glance_endpoint': glance_endpoint,
|
||||
'image_id': image_id}
|
||||
mgt_parts = urlparse(mgt_url)
|
||||
mgt_path = mgt_parts[2]
|
||||
|
||||
validate_image_status_before_upload_v2(conn, url, extra_headers)
|
||||
_update_image_meta_v2(conn, image_id, extra_headers, properties,
|
||||
mgt_path)
|
||||
|
||||
validate_image_status_before_upload_v2(conn, url, extra_headers,
|
||||
mgt_path)
|
||||
|
||||
try:
|
||||
conn.connect()
|
||||
@@ -537,7 +545,8 @@ def validate_image_status_before_upload_v1(conn, url, extra_headers):
|
||||
'image_status': image_status})
|
||||
|
||||
|
||||
def validate_image_status_before_upload_v2(conn, url, extra_headers):
|
||||
def validate_image_status_before_upload_v2(conn, url, extra_headers,
|
||||
get_path):
|
||||
try:
|
||||
parts = urlparse(url)
|
||||
path = parts[2]
|
||||
@@ -548,8 +557,7 @@ def validate_image_status_before_upload_v2(conn, url, extra_headers):
|
||||
# it is not 'active' and send back a 409. Hence, the data will be
|
||||
# unnecessarily buffered by Glance. This wastes time and bandwidth.
|
||||
# LP bug #1202785
|
||||
|
||||
conn.request('GET', '/v2/images/%s' % image_id, headers=extra_headers)
|
||||
conn.request('GET', get_path, headers=extra_headers)
|
||||
get_resp = conn.getresponse()
|
||||
except Exception, error: # noqa
|
||||
logging.exception('Failed to GET the image %(image_id)s while '
|
||||
|
||||
@@ -333,6 +333,7 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
expected_url = "%(glance_endpoint)s/v2/images/%(image_id)s/file" % {
|
||||
'glance_endpoint': fake_endpoint,
|
||||
'image_id': 'fake_image_id'}
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance._upload_tarball_by_url_v2(
|
||||
'fake_staging_path', 'fake_image_id', fake_endpoint,
|
||||
@@ -341,7 +342,8 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
self.assertTrue(mock_HTTPConn.called)
|
||||
mock_validate_image.assert_called_with(fake_conn,
|
||||
expected_url,
|
||||
fake_extra_headers)
|
||||
fake_extra_headers,
|
||||
expected_wsgi_path)
|
||||
self.assertTrue(mock_update_image_meta.called)
|
||||
self.assertTrue(mock_create_tarball.called)
|
||||
self.assertTrue(
|
||||
@@ -369,6 +371,7 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
expected_url = "%(glance_endpoint)s/v2/images/%(image_id)s/file" % {
|
||||
'glance_endpoint': fake_endpoint,
|
||||
'image_id': 'fake_image_id'}
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance._upload_tarball_by_url_v2(
|
||||
'fake_staging_path', 'fake_image_id', fake_endpoint,
|
||||
@@ -378,12 +381,89 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
self.assertTrue(mock_update_image_meta.called)
|
||||
mock_validate_image.assert_called_with(fake_conn,
|
||||
expected_url,
|
||||
fake_extra_headers)
|
||||
fake_extra_headers,
|
||||
expected_wsgi_path)
|
||||
self.assertTrue(mock_create_tarball.called)
|
||||
self.assertTrue(
|
||||
mock_HTTPSConn.return_value.getresponse.called)
|
||||
self.assertFalse(mock_check_resp_status.called)
|
||||
|
||||
def test_upload_tarball_by_url_v2_with_api_endpoint(self):
|
||||
fake_conn = mock.Mock()
|
||||
mock_Conn = self.mock_patch_object(
|
||||
self.glance, '_create_connection', fake_conn)
|
||||
mock_validate_image = self.mock_patch_object(
|
||||
self.glance, 'validate_image_status_before_upload_v2')
|
||||
mock_create_tarball = self.mock_patch_object(
|
||||
self.glance.utils, 'create_tarball')
|
||||
mock_check_resp_status = self.mock_patch_object(
|
||||
self.glance, 'check_resp_status_and_retry')
|
||||
mock_update_image_meta = self.mock_patch_object(
|
||||
self.glance, '_update_image_meta_v2')
|
||||
self.glance._create_connection().getresponse = mock.Mock()
|
||||
self.glance._create_connection().getresponse().status = \
|
||||
httplib.NO_CONTENT
|
||||
fake_extra_headers = {}
|
||||
fake_properties = {}
|
||||
fake_endpoint = 'https://fake_netloc:fake_port'
|
||||
expected_url = "%(glance_endpoint)s/v2/images/%(image_id)s/file" % {
|
||||
'glance_endpoint': fake_endpoint,
|
||||
'image_id': 'fake_image_id'}
|
||||
expected_api_path = '/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance._upload_tarball_by_url_v2(
|
||||
'fake_staging_path', 'fake_image_id', fake_endpoint,
|
||||
fake_extra_headers, fake_properties)
|
||||
|
||||
self.assertTrue(mock_Conn.called)
|
||||
self.assertTrue(mock_update_image_meta.called)
|
||||
mock_validate_image.assert_called_with(fake_conn,
|
||||
expected_url,
|
||||
fake_extra_headers,
|
||||
expected_api_path)
|
||||
self.assertTrue(mock_create_tarball.called)
|
||||
self.assertTrue(
|
||||
mock_Conn.return_value.getresponse.called)
|
||||
self.assertFalse(mock_check_resp_status.called)
|
||||
|
||||
def test_upload_tarball_by_url_v2_with_wsgi_endpoint(self):
|
||||
fake_conn = mock.Mock()
|
||||
mock_Conn = self.mock_patch_object(
|
||||
self.glance, '_create_connection', fake_conn)
|
||||
mock_validate_image = self.mock_patch_object(
|
||||
self.glance, 'validate_image_status_before_upload_v2')
|
||||
mock_create_tarball = self.mock_patch_object(
|
||||
self.glance.utils, 'create_tarball')
|
||||
mock_check_resp_status = self.mock_patch_object(
|
||||
self.glance, 'check_resp_status_and_retry')
|
||||
mock_update_image_meta = self.mock_patch_object(
|
||||
self.glance, '_update_image_meta_v2')
|
||||
self.glance._create_connection().getresponse = mock.Mock()
|
||||
self.glance._create_connection().getresponse().status = \
|
||||
httplib.NO_CONTENT
|
||||
fake_extra_headers = {}
|
||||
fake_properties = {}
|
||||
fake_endpoint = 'https://fake_netloc/fake_path'
|
||||
expected_url = "%(glance_endpoint)s/v2/images/%(image_id)s/file" % {
|
||||
'glance_endpoint': fake_endpoint,
|
||||
'image_id': 'fake_image_id'}
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance._upload_tarball_by_url_v2(
|
||||
'fake_staging_path', 'fake_image_id', fake_endpoint,
|
||||
fake_extra_headers, fake_properties)
|
||||
|
||||
self.assertTrue(mock_Conn.called)
|
||||
self.assertTrue(mock_update_image_meta.called)
|
||||
mock_validate_image.assert_called_with(fake_conn,
|
||||
expected_url,
|
||||
fake_extra_headers,
|
||||
expected_wsgi_path)
|
||||
self.assertTrue(mock_create_tarball.called)
|
||||
self.assertTrue(
|
||||
mock_Conn.return_value.getresponse.called)
|
||||
self.assertFalse(mock_check_resp_status.called)
|
||||
|
||||
def test_upload_tarball_by_url_https_failed_retry_v2(self):
|
||||
fake_conn = mock.Mock()
|
||||
mock_HTTPSConn = self.mock_patch_object(
|
||||
@@ -405,6 +485,7 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
expected_url = "%(glance_endpoint)s/v2/images/%(image_id)s/file" % {
|
||||
'glance_endpoint': fake_endpoint,
|
||||
'image_id': 'fake_image_id'}
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance._upload_tarball_by_url_v2(
|
||||
'fake_staging_path', 'fake_image_id', fake_endpoint,
|
||||
@@ -414,13 +495,14 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
self.assertTrue(mock_update_image_meta.called)
|
||||
mock_validate_image.assert_called_with(fake_conn,
|
||||
expected_url,
|
||||
fake_extra_headers)
|
||||
fake_extra_headers,
|
||||
expected_wsgi_path)
|
||||
self.assertTrue(mock_create_tarball.called)
|
||||
self.assertTrue(
|
||||
mock_HTTPSConn.return_value.getresponse.called)
|
||||
self.assertTrue(mock_check_resp_status.called)
|
||||
|
||||
def test_update_image_meta_ok_v2(self):
|
||||
def test_update_image_meta_ok_v2_using_api_service(self):
|
||||
fake_conn = mock.Mock()
|
||||
fake_extra_headers = {'fake_type': 'fake_content'}
|
||||
fake_properties = {'fake_path': True}
|
||||
@@ -438,15 +520,45 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
fake_headers.update(**fake_extra_headers)
|
||||
fake_conn.getresponse.return_value = mock.Mock()
|
||||
fake_conn.getresponse().status = httplib.OK
|
||||
expected_api_path = '/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance._update_image_meta_v2(fake_conn, 'fake_image_id',
|
||||
fake_extra_headers, fake_properties)
|
||||
self.glance._update_image_meta_v2(fake_conn, fake_extra_headers,
|
||||
fake_properties, expected_api_path)
|
||||
fake_conn.request.assert_called_with('PATCH',
|
||||
'/v2/images/%s' % 'fake_image_id',
|
||||
body=fake_body_json,
|
||||
headers=fake_headers)
|
||||
fake_conn.getresponse.assert_called()
|
||||
|
||||
def test_update_image_meta_ok_v2_using_uwsgi_service(self):
|
||||
fake_conn = mock.Mock()
|
||||
fake_extra_headers = {'fake_type': 'fake_content'}
|
||||
fake_properties = {'fake_path': True}
|
||||
new_fake_properties = {'path': '/fake-path',
|
||||
'value': "True",
|
||||
'op': 'add'}
|
||||
fake_body = [
|
||||
{"path": "/container_format", "value": "ovf", "op": "add"},
|
||||
{"path": "/disk_format", "value": "vhd", "op": "add"},
|
||||
{"path": "/visibility", "value": "private", "op": "add"}]
|
||||
fake_body.append(new_fake_properties)
|
||||
fake_body_json = json.dumps(fake_body)
|
||||
fake_headers = {
|
||||
'Content-Type': 'application/openstack-images-v2.1-json-patch'}
|
||||
fake_headers.update(**fake_extra_headers)
|
||||
fake_conn.getresponse.return_value = mock.Mock()
|
||||
fake_conn.getresponse().status = httplib.OK
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance._update_image_meta_v2(fake_conn, fake_extra_headers,
|
||||
fake_properties, expected_wsgi_path)
|
||||
fake_conn.request.assert_called_with('PATCH',
|
||||
'/fake_path/v2/images/%s' %
|
||||
'fake_image_id',
|
||||
body=fake_body_json,
|
||||
headers=fake_headers)
|
||||
fake_conn.getresponse.assert_called()
|
||||
|
||||
def test_check_resp_status_and_retry_plugin_error(self):
|
||||
mock_resp_badrequest = mock.Mock()
|
||||
mock_resp_badrequest.status = httplib.BAD_REQUEST
|
||||
@@ -579,7 +691,30 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
mock_head_resp, fake_image_id, fake_url)
|
||||
mock_conn.request.assert_called_once()
|
||||
|
||||
def test_validate_image_status_before_upload_ok_v2(self):
|
||||
def test_validate_image_status_before_upload_ok_v2_using_api_service(self):
|
||||
mock_conn = mock.Mock()
|
||||
fake_url = 'http://fake_host:fake_port/fake_path/fake_image_id'
|
||||
mock_check_resp_status_and_retry = self.mock_patch_object(
|
||||
self.glance, 'check_resp_status_and_retry')
|
||||
mock_head_resp = mock.Mock()
|
||||
mock_head_resp.status = httplib.OK
|
||||
mock_head_resp.read.return_value = '{"status": "queued"}'
|
||||
mock_conn.getresponse.return_value = mock_head_resp
|
||||
fake_extra_headers = mock.Mock()
|
||||
expected_api_path = '/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance.validate_image_status_before_upload_v2(
|
||||
mock_conn, fake_url, fake_extra_headers, expected_api_path)
|
||||
|
||||
self.assertTrue(mock_conn.getresponse.called)
|
||||
self.assertEqual(
|
||||
mock_head_resp.read.call_count, 2)
|
||||
self.assertFalse(mock_check_resp_status_and_retry.called)
|
||||
mock_conn.request.assert_called_with('GET',
|
||||
'/v2/images/fake_image_id',
|
||||
headers=fake_extra_headers)
|
||||
|
||||
def test_validate_image_status_before_upload_ok_v2_using_uwsgi(self):
|
||||
mock_conn = mock.Mock()
|
||||
fake_url = 'http://fake_host/fake_path/fake_image_id'
|
||||
mock_check_resp_status_and_retry = self.mock_patch_object(
|
||||
@@ -589,14 +724,19 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
mock_head_resp.read.return_value = '{"status": "queued"}'
|
||||
mock_conn.getresponse.return_value = mock_head_resp
|
||||
|
||||
fake_extra_headers = mock.Mock()
|
||||
fake_patch_path = 'fake_patch_path'
|
||||
|
||||
self.glance.validate_image_status_before_upload_v2(
|
||||
mock_conn, fake_url, extra_headers=mock.Mock())
|
||||
mock_conn, fake_url, fake_extra_headers, fake_patch_path)
|
||||
|
||||
self.assertTrue(mock_conn.getresponse.called)
|
||||
self.assertEqual(
|
||||
mock_head_resp.read.call_count, 2)
|
||||
self.assertFalse(mock_check_resp_status_and_retry.called)
|
||||
mock_conn.request.assert_called_once()
|
||||
mock_conn.request.assert_called_with('GET',
|
||||
'fake_patch_path',
|
||||
headers=fake_extra_headers)
|
||||
|
||||
def test_validate_image_status_before_upload_get_image_failed_v2(self):
|
||||
mock_conn = mock.Mock()
|
||||
@@ -605,10 +745,11 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
mock_head_resp = mock.Mock()
|
||||
mock_head_resp.status = httplib.OK
|
||||
mock_conn.getresponse.return_value = mock_head_resp
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.assertRaises(self.glance.RetryableError,
|
||||
self.glance.validate_image_status_before_upload_v2,
|
||||
mock_conn, fake_url, extra_headers=mock.Mock())
|
||||
mock_conn, fake_url, mock.Mock(), expected_wsgi_path)
|
||||
mock_conn.request.assert_called_once()
|
||||
mock_head_resp.read.assert_not_called()
|
||||
mock_conn.getresponse.assert_not_called()
|
||||
@@ -620,9 +761,10 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
mock_head_resp = mock.Mock()
|
||||
mock_head_resp.status = httplib.BAD_REQUEST
|
||||
mock_conn.getresponse.return_value = mock_head_resp
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.glance.validate_image_status_before_upload_v2(
|
||||
mock_conn, fake_url, extra_headers=mock.Mock())
|
||||
mock_conn, fake_url, mock.Mock(), expected_wsgi_path)
|
||||
mock_conn.request.assert_called_once()
|
||||
mock_conn.getresponse.assert_called_once()
|
||||
mock_head_resp.read.assert_called_once()
|
||||
@@ -635,10 +777,11 @@ class GlanceTestCase(plugin_test.PluginTestBase):
|
||||
mock_head_resp.status = httplib.OK
|
||||
mock_head_resp.read.return_value = '{"status": "not-queued"}'
|
||||
mock_conn.getresponse.return_value = mock_head_resp
|
||||
expected_wsgi_path = '/fake_path/v2/images/%s' % 'fake_image_id'
|
||||
|
||||
self.assertRaises(self.glance.PluginError,
|
||||
self.glance.validate_image_status_before_upload_v2,
|
||||
mock_conn, fake_url, extra_headers=mock.Mock())
|
||||
mock_conn, fake_url, mock.Mock(), expected_wsgi_path)
|
||||
mock_conn.request.assert_called_once()
|
||||
mock_head_resp.read.assert_called_once()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user