updating images metadata resource
This commit is contained in:
@@ -164,10 +164,17 @@ class APIRouterV11(APIRouter):
|
||||
|
||||
def _setup_routes(self, mapper):
|
||||
super(APIRouterV11, self)._setup_routes(mapper, '1.1')
|
||||
mapper.resource("image_meta", "meta",
|
||||
controller=image_metadata.create_resource(),
|
||||
image_metadata_controller = image_metadata.create_resource()
|
||||
mapper.resource("image_meta", "metadata",
|
||||
controller=image_metadata_controller,
|
||||
parent_resource=dict(member_name='image',
|
||||
collection_name='images'))
|
||||
mapper.connect("image_meta", controller=image_metadata_controller,
|
||||
action='update_collection', condition={"method":['PUT']})
|
||||
mapper.connect("metadata", "/images/{image_id}/metadata",
|
||||
controller=image_metadata_controller,
|
||||
action='update_all',
|
||||
conditions={"method":['PUT',]})
|
||||
|
||||
mapper.resource("server_meta", "meta",
|
||||
controller=server_metadata.create_resource(),
|
||||
|
||||
@@ -282,7 +282,7 @@ class CreateInstanceHelper(object):
|
||||
return password
|
||||
|
||||
|
||||
class ServerXMLDeserializer(wsgi.XMLDeserializer):
|
||||
class ServerXMLDeserializer(wsgi.MetadataXMLDeserializer):
|
||||
"""
|
||||
Deserializer to handle xml-formatted server create requests.
|
||||
|
||||
@@ -299,11 +299,12 @@ class ServerXMLDeserializer(wsgi.XMLDeserializer):
|
||||
def _extract_server(self, node):
|
||||
"""Marshal the server attribute of a parsed request"""
|
||||
server = {}
|
||||
server_node = self._find_first_child_named(node, 'server')
|
||||
server_node = self.find_first_child_named(node, 'server')
|
||||
for attr in ["name", "imageId", "flavorId", "imageRef", "flavorRef"]:
|
||||
if server_node.getAttribute(attr):
|
||||
server[attr] = server_node.getAttribute(attr)
|
||||
metadata = self._extract_metadata(server_node)
|
||||
metadata_node = self.find_first_child_named(server_node, "metadata")
|
||||
metadata = self.extract_metadata(metadata_node)
|
||||
if metadata is not None:
|
||||
server["metadata"] = metadata
|
||||
personality = self._extract_personality(server_node)
|
||||
@@ -311,49 +312,17 @@ class ServerXMLDeserializer(wsgi.XMLDeserializer):
|
||||
server["personality"] = personality
|
||||
return server
|
||||
|
||||
def _extract_metadata(self, server_node):
|
||||
"""Marshal the metadata attribute of a parsed request"""
|
||||
metadata_node = self._find_first_child_named(server_node, "metadata")
|
||||
if metadata_node is None:
|
||||
return None
|
||||
metadata = {}
|
||||
for meta_node in self._find_children_named(metadata_node, "meta"):
|
||||
key = meta_node.getAttribute("key")
|
||||
metadata[key] = self._extract_text(meta_node)
|
||||
return metadata
|
||||
|
||||
def _extract_personality(self, server_node):
|
||||
"""Marshal the personality attribute of a parsed request"""
|
||||
personality_node = \
|
||||
self._find_first_child_named(server_node, "personality")
|
||||
self.find_first_child_named(server_node, "personality")
|
||||
if personality_node is None:
|
||||
return None
|
||||
personality = []
|
||||
for file_node in self._find_children_named(personality_node, "file"):
|
||||
for file_node in self.find_children_named(personality_node, "file"):
|
||||
item = {}
|
||||
if file_node.hasAttribute("path"):
|
||||
item["path"] = file_node.getAttribute("path")
|
||||
item["contents"] = self._extract_text(file_node)
|
||||
item["contents"] = self.extract_text(file_node)
|
||||
personality.append(item)
|
||||
return personality
|
||||
|
||||
def _find_first_child_named(self, parent, name):
|
||||
"""Search a nodes children for the first child with a given name"""
|
||||
for node in parent.childNodes:
|
||||
if node.nodeName == name:
|
||||
return node
|
||||
return None
|
||||
|
||||
def _find_children_named(self, parent, name):
|
||||
"""Return all of a nodes children who have the given name"""
|
||||
for node in parent.childNodes:
|
||||
if node.nodeName == name:
|
||||
yield node
|
||||
|
||||
def _extract_text(self, node):
|
||||
"""Get the text field contained by the given node"""
|
||||
if len(node.childNodes) == 1:
|
||||
child = node.childNodes[0]
|
||||
if child.nodeType == child.TEXT_NODE:
|
||||
return child.nodeValue
|
||||
return ""
|
||||
|
||||
@@ -96,8 +96,16 @@ class Controller(object):
|
||||
self._check_quota_limit(context, metadata)
|
||||
img['properties'] = metadata
|
||||
self.image_service.update(context, image_id, img, None)
|
||||
return dict(meta=meta)
|
||||
|
||||
return req.body
|
||||
def update_all(self, req, image_id, body):
|
||||
context = req.environ['nova.context']
|
||||
img = self.image_service.show(context, image_id)
|
||||
metadata = body.get('metadata', {})
|
||||
self._check_quota_limit(context, metadata)
|
||||
img['properties'] = metadata
|
||||
self.image_service.update(context, image_id, img, None)
|
||||
return dict(metadata=metadata)
|
||||
|
||||
def delete(self, req, image_id, id):
|
||||
context = req.environ['nova.context']
|
||||
@@ -110,6 +118,32 @@ class Controller(object):
|
||||
self.image_service.update(context, image_id, img, None)
|
||||
|
||||
|
||||
class ImageMetadataXMLDeserializer(wsgi.MetadataXMLDeserializer):
|
||||
|
||||
def _extract_metadata_container(self, datastring):
|
||||
dom = minidom.parseString(datastring)
|
||||
metadata_node = self.find_first_child_named(dom, "metadata")
|
||||
metadata = self.extract_metadata(metadata_node)
|
||||
return {'body': {'metadata': metadata}}
|
||||
|
||||
def create(self, datastring):
|
||||
return self._extract_metadata_container(datastring)
|
||||
|
||||
def update_all(self, datastring):
|
||||
return self._extract_metadata_container(datastring)
|
||||
|
||||
def update(self, datastring):
|
||||
dom = minidom.parseString(datastring)
|
||||
metadata_item = self.extract_metadata(dom)
|
||||
return {'body': {'meta': metadata_item}}
|
||||
|
||||
|
||||
class HeadersSerializer(wsgi.ResponseHeadersSerializer):
|
||||
|
||||
def delete(self, response, data):
|
||||
response.status_int = 204
|
||||
|
||||
|
||||
class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
|
||||
def __init__(self, xmlns=wsgi.XMLNS_V11):
|
||||
super(ImageMetadataXMLSerializer, self).__init__(xmlns=xmlns)
|
||||
@@ -143,6 +177,9 @@ class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
|
||||
def create(self, metadata_dict):
|
||||
return self._meta_list_to_xml_string(metadata_dict)
|
||||
|
||||
def update_all(self, metadata_dict):
|
||||
return self._meta_list_to_xml_string(metadata_dict)
|
||||
|
||||
def _meta_item_to_xml_string(self, meta_item_dict):
|
||||
xml_doc = minidom.Document()
|
||||
item_key, item_value = meta_item_dict.items()[0]
|
||||
@@ -157,11 +194,21 @@ class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
|
||||
def update(self, meta_item_dict):
|
||||
return self._meta_item_to_xml_string(meta_item_dict['meta'])
|
||||
|
||||
def default(self, *args, **kwargs):
|
||||
return ''
|
||||
|
||||
|
||||
def create_resource():
|
||||
headers_serializer = HeadersSerializer()
|
||||
|
||||
body_deserializers = {
|
||||
'application/xml': ImageMetadataXMLDeserializer(),
|
||||
}
|
||||
|
||||
body_serializers = {
|
||||
'application/xml': ImageMetadataXMLSerializer(),
|
||||
}
|
||||
serializer = wsgi.ResponseSerializer(body_serializers)
|
||||
serializer = wsgi.ResponseSerializer(body_serializers, headers_serializer)
|
||||
deserializer = wsgi.RequestDeserializer(body_deserializers)
|
||||
|
||||
return wsgi.Resource(Controller(), serializer=serializer)
|
||||
return wsgi.Resource(Controller(), deserializer, serializer)
|
||||
|
||||
@@ -135,10 +135,44 @@ class XMLDeserializer(TextDeserializer):
|
||||
listnames)
|
||||
return result
|
||||
|
||||
def find_first_child_named(self, parent, name):
|
||||
"""Search a nodes children for the first child with a given name"""
|
||||
for node in parent.childNodes:
|
||||
if node.nodeName == name:
|
||||
return node
|
||||
return None
|
||||
|
||||
def find_children_named(self, parent, name):
|
||||
"""Return all of a nodes children who have the given name"""
|
||||
for node in parent.childNodes:
|
||||
if node.nodeName == name:
|
||||
yield node
|
||||
|
||||
def extract_text(self, node):
|
||||
"""Get the text field contained by the given node"""
|
||||
if len(node.childNodes) == 1:
|
||||
child = node.childNodes[0]
|
||||
if child.nodeType == child.TEXT_NODE:
|
||||
return child.nodeValue
|
||||
return ""
|
||||
|
||||
def default(self, datastring):
|
||||
return {'body': self._from_xml(datastring)}
|
||||
|
||||
|
||||
class MetadataXMLDeserializer(XMLDeserializer):
|
||||
|
||||
def extract_metadata(self, metadata_node):
|
||||
"""Marshal the metadata attribute of a parsed request"""
|
||||
if metadata_node is None:
|
||||
return None
|
||||
metadata = {}
|
||||
for meta_node in self.find_children_named(metadata_node, "meta"):
|
||||
key = meta_node.getAttribute("key")
|
||||
metadata[key] = self.extract_text(meta_node)
|
||||
return metadata
|
||||
|
||||
|
||||
class RequestHeadersDeserializer(ActionDispatcher):
|
||||
"""Default request headers deserializer"""
|
||||
|
||||
@@ -395,9 +429,10 @@ class ResponseSerializer(object):
|
||||
self.headers_serializer.serialize(response, data, action)
|
||||
|
||||
def serialize_body(self, response, data, content_type, action):
|
||||
response.headers['Content-Type'] = content_type
|
||||
serializer = self.get_body_serializer(content_type)
|
||||
response.body = serializer.serialize(data, action)
|
||||
if data is not None:
|
||||
response.headers['Content-Type'] = content_type
|
||||
serializer = self.get_body_serializer(content_type)
|
||||
response.body = serializer.serialize(data, action)
|
||||
|
||||
def get_body_serializer(self, content_type):
|
||||
try:
|
||||
@@ -443,7 +478,7 @@ class Resource(wsgi.Application):
|
||||
action, args, accept = self.deserializer.deserialize(request)
|
||||
except exception.InvalidContentType:
|
||||
msg = _("Unsupported Content-Type")
|
||||
return webob.exc.HTTPBadRequest(explanation=msg)
|
||||
return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
|
||||
except exception.MalformedRequestBody:
|
||||
msg = _("Malformed request body")
|
||||
return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
|
||||
@@ -452,13 +487,10 @@ class Resource(wsgi.Application):
|
||||
action_result = self.dispatch(request, action, args)
|
||||
except webob.exc.HTTPException as ex:
|
||||
LOG.info(_("HTTP exception thrown: %s"), unicode(ex))
|
||||
action_result = faults.Fault(ex)
|
||||
return faults.Fault(ex)
|
||||
|
||||
#TODO(bcwaldon): find a more elegant way to pass through non-dict types
|
||||
if type(action_result) is dict or action_result is None:
|
||||
response = self.serializer.serialize(action_result,
|
||||
accept,
|
||||
action=action)
|
||||
if isinstance(action_result, dict) or action_result is None:
|
||||
response = self.serializer.serialize(action_result, accept, action)
|
||||
else:
|
||||
response = action_result
|
||||
|
||||
|
||||
@@ -103,8 +103,7 @@ class ImageMetaDataTest(test.TestCase):
|
||||
super(ImageMetaDataTest, self).tearDown()
|
||||
|
||||
def test_index(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/meta')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
res_dict = json.loads(res.body)
|
||||
self.assertEqual(200, res.status_int)
|
||||
@@ -114,8 +113,7 @@ class ImageMetaDataTest(test.TestCase):
|
||||
self.assertEqual(value, res_dict['metadata'][key])
|
||||
|
||||
def test_show(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/meta/key1')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata/key1')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
res_dict = json.loads(res.body)
|
||||
self.assertEqual(200, res.status_int)
|
||||
@@ -124,42 +122,66 @@ class ImageMetaDataTest(test.TestCase):
|
||||
self.assertEqual('value1', res_dict['meta']['key1'])
|
||||
|
||||
def test_show_not_found(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/meta/key9')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata/key9')
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(404, res.status_int)
|
||||
|
||||
def test_create(self):
|
||||
req = webob.Request.blank('/v1.1/images/2/meta')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/2/metadata')
|
||||
req.method = 'POST'
|
||||
req.body = '{"metadata": {"key9": "value9"}}'
|
||||
req.headers["content-type"] = "application/json"
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
res_dict = json.loads(res.body)
|
||||
|
||||
self.assertEqual(200, res.status_int)
|
||||
self.assertEqual('value9', res_dict['metadata']['key9'])
|
||||
# other items should not be modified
|
||||
self.assertEqual('value1', res_dict['metadata']['key1'])
|
||||
self.assertEqual('value2', res_dict['metadata']['key2'])
|
||||
self.assertEqual(1, len(res_dict))
|
||||
actual_output = json.loads(res.body)
|
||||
|
||||
expected_output = {
|
||||
'metadata': {
|
||||
'key1': 'value1',
|
||||
'key2': 'value2',
|
||||
'key9': 'value9',
|
||||
},
|
||||
}
|
||||
|
||||
self.assertEqual(expected_output, actual_output)
|
||||
|
||||
def test_update_all(self):
|
||||
req = webob.Request.blank('/v1.1/images/2/metadata')
|
||||
req.method = 'PUT'
|
||||
req.body = '{"metadata": {"key9": "value9"}}'
|
||||
req.headers["content-type"] = "application/json"
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
|
||||
self.assertEqual(200, res.status_int)
|
||||
actual_output = json.loads(res.body)
|
||||
|
||||
expected_output = {
|
||||
'metadata': {
|
||||
'key9': 'value9',
|
||||
},
|
||||
}
|
||||
|
||||
self.assertEqual(expected_output, actual_output)
|
||||
|
||||
def test_update_item(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/meta/key1')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata/key1')
|
||||
req.method = 'PUT'
|
||||
req.body = '{"meta": {"key1": "zz"}}'
|
||||
req.headers["content-type"] = "application/json"
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
|
||||
self.assertEqual(200, res.status_int)
|
||||
res_dict = json.loads(res.body)
|
||||
self.assertTrue('meta' in res_dict)
|
||||
self.assertEqual(len(res_dict['meta']), 1)
|
||||
self.assertEqual('zz', res_dict['meta']['key1'])
|
||||
actual_output = json.loads(res.body)
|
||||
expected_output = {
|
||||
'meta': {
|
||||
'key1': 'zz',
|
||||
},
|
||||
}
|
||||
self.assertEqual(actual_output, expected_output)
|
||||
|
||||
def test_update_item_bad_body(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/meta/key1')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata/key1')
|
||||
req.method = 'PUT'
|
||||
req.body = '{"key1": "zz"}'
|
||||
req.headers["content-type"] = "application/json"
|
||||
@@ -167,8 +189,7 @@ class ImageMetaDataTest(test.TestCase):
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
def test_update_item_too_many_keys(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/meta/key1')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata/key1')
|
||||
req.method = 'PUT'
|
||||
req.body = '{"meta": {"key1": "value1", "key2": "value2"}}'
|
||||
req.headers["content-type"] = "application/json"
|
||||
@@ -176,24 +197,38 @@ class ImageMetaDataTest(test.TestCase):
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
def test_update_item_body_uri_mismatch(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/meta/bad')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata/bad')
|
||||
req.method = 'PUT'
|
||||
req.body = '{"meta": {"key1": "value1"}}'
|
||||
req.headers["content-type"] = "application/json"
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
def test_update_item_xml(self):
|
||||
req = webob.Request.blank('/v1.1/images/1/metadata/key1')
|
||||
req.method = 'PUT'
|
||||
req.body = '<meta key="key1">five</meta>'
|
||||
req.headers["content-type"] = "application/xml"
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
|
||||
self.assertEqual(200, res.status_int)
|
||||
actual_output = json.loads(res.body)
|
||||
expected_output = {
|
||||
'meta': {
|
||||
'key1': 'five',
|
||||
},
|
||||
}
|
||||
self.assertEqual(actual_output, expected_output)
|
||||
|
||||
def test_delete(self):
|
||||
req = webob.Request.blank('/v1.1/images/2/meta/key1')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/2/metadata/key1')
|
||||
req.method = 'DELETE'
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(200, res.status_int)
|
||||
self.assertEqual(204, res.status_int)
|
||||
self.assertEqual('', res.body)
|
||||
|
||||
def test_delete_not_found(self):
|
||||
req = webob.Request.blank('/v1.1/images/2/meta/blah')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/2/metadata/blah')
|
||||
req.method = 'DELETE'
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(404, res.status_int)
|
||||
@@ -203,8 +238,7 @@ class ImageMetaDataTest(test.TestCase):
|
||||
for num in range(FLAGS.quota_metadata_items + 1):
|
||||
data['metadata']['key%i' % num] = "blah"
|
||||
json_string = str(data).replace("\'", "\"")
|
||||
req = webob.Request.blank('/v1.1/images/2/meta')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/2/metadata')
|
||||
req.method = 'POST'
|
||||
req.body = json_string
|
||||
req.headers["content-type"] = "application/json"
|
||||
@@ -212,8 +246,7 @@ class ImageMetaDataTest(test.TestCase):
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
def test_too_many_metadata_items_on_put(self):
|
||||
req = webob.Request.blank('/v1.1/images/3/meta/blah')
|
||||
req.environ['api.version'] = '1.1'
|
||||
req = webob.Request.blank('/v1.1/images/3/metadata/blah')
|
||||
req.method = 'PUT'
|
||||
req.body = '{"meta": {"blah": "blah"}}'
|
||||
req.headers["content-type"] = "application/json"
|
||||
@@ -221,9 +254,49 @@ class ImageMetaDataTest(test.TestCase):
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
|
||||
class ImageMetadataXMLDeserializationTest(test.TestCase):
|
||||
|
||||
deserializer = openstack.image_metadata.ImageMetadataXMLDeserializer()
|
||||
|
||||
def test_create(self):
|
||||
request_body = """
|
||||
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
|
||||
<meta key='123'>asdf</meta>
|
||||
<meta key='567'>jkl;</meta>
|
||||
</metadata>"""
|
||||
output = self.deserializer.deserialize(request_body, 'create')
|
||||
expected = {"body": {"metadata": {"123": "asdf", "567": "jkl;"}}}
|
||||
self.assertEquals(output, expected)
|
||||
|
||||
def test_create_empty(self):
|
||||
request_body = """
|
||||
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1"/>"""
|
||||
output = self.deserializer.deserialize(request_body, 'create')
|
||||
expected = {"body": {"metadata": {}}}
|
||||
self.assertEquals(output, expected)
|
||||
|
||||
def test_update_all(self):
|
||||
request_body = """
|
||||
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
|
||||
<meta key='123'>asdf</meta>
|
||||
<meta key='567'>jkl;</meta>
|
||||
</metadata>"""
|
||||
output = self.deserializer.deserialize(request_body, 'update_all')
|
||||
expected = {"body": {"metadata": {"123": "asdf", "567": "jkl;"}}}
|
||||
self.assertEquals(output, expected)
|
||||
|
||||
def test_update(self):
|
||||
request_body = """
|
||||
<meta xmlns="http://docs.openstack.org/compute/api/v1.1"
|
||||
key='123'>asdf</meta>"""
|
||||
output = self.deserializer.deserialize(request_body, 'update')
|
||||
expected = {"body": {"meta": {"123": "asdf"}}}
|
||||
self.assertEquals(output, expected)
|
||||
|
||||
|
||||
class ImageMetadataXMLSerializationTest(test.TestCase):
|
||||
|
||||
def test_index_xml(self):
|
||||
def test_index(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
@@ -247,7 +320,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_index_xml_null(self):
|
||||
def test_index_null(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
@@ -267,7 +340,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_index_xml_unicode(self):
|
||||
def test_index_unicode(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
@@ -287,7 +360,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_show_xml(self):
|
||||
def test_show(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
fixture = {
|
||||
'meta': {
|
||||
@@ -305,7 +378,31 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_update_item_xml(self):
|
||||
def test_update_all(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
'key6': 'value6',
|
||||
'key4': 'value4',
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'update_all')
|
||||
actual = minidom.parseString(output.replace(" ", ""))
|
||||
|
||||
expected = minidom.parseString("""
|
||||
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
|
||||
<meta key="key6">
|
||||
value6
|
||||
</meta>
|
||||
<meta key="key4">
|
||||
value4
|
||||
</meta>
|
||||
</metadata>
|
||||
""".replace(" ", ""))
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_update_item(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
fixture = {
|
||||
'meta': {
|
||||
@@ -323,7 +420,7 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_create_xml(self):
|
||||
def test_create(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
@@ -350,3 +447,8 @@ class ImageMetadataXMLSerializationTest(test.TestCase):
|
||||
""".replace(" ", ""))
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_delete(self):
|
||||
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
|
||||
output = serializer.serialize(None, 'delete')
|
||||
self.assertEqual(output, '')
|
||||
|
||||
Reference in New Issue
Block a user