Merge "os-xenapi: fix CI to fit the change that glance-api use uwsgi"
This commit is contained in:
commit
a6a612295a
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue