merged trunk and fix time call

This commit is contained in:
Vishvananda Ishaya 2011-07-29 09:28:02 -07:00
commit 31657838ac
15 changed files with 1249 additions and 358 deletions

View File

@ -17,12 +17,14 @@
import re
from urlparse import urlparse
from xml.dom import minidom
import webob
from nova import exception
from nova import flags
from nova import log as logging
from nova.api.openstack import wsgi
LOG = logging.getLogger('nova.api.openstack.common')
@ -192,3 +194,83 @@ def get_version_from_href(href):
except IndexError:
version = '1.0'
return version
class MetadataXMLDeserializer(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 MetadataHeadersSerializer(wsgi.ResponseHeadersSerializer):
def delete(self, response, data):
response.status_int = 204
class MetadataXMLSerializer(wsgi.XMLDictSerializer):
def __init__(self, xmlns=wsgi.XMLNS_V11):
super(MetadataXMLSerializer, self).__init__(xmlns=xmlns)
def _meta_item_to_xml(self, doc, key, value):
node = doc.createElement('meta')
doc.appendChild(node)
node.setAttribute('key', '%s' % key)
text = doc.createTextNode('%s' % value)
node.appendChild(text)
return node
def meta_list_to_xml(self, xml_doc, meta_items):
container_node = xml_doc.createElement('metadata')
for (key, value) in meta_items:
item_node = self._meta_item_to_xml(xml_doc, key, value)
container_node.appendChild(item_node)
return container_node
def _meta_list_to_xml_string(self, metadata_dict):
xml_doc = minidom.Document()
items = metadata_dict['metadata'].items()
container_node = self.meta_list_to_xml(xml_doc, items)
xml_doc.appendChild(container_node)
self._add_xmlns(container_node)
return xml_doc.toprettyxml(indent=' ', encoding='UTF-8')
def index(self, metadata_dict):
return self._meta_list_to_xml_string(metadata_dict)
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]
item_node = self._meta_item_to_xml(xml_doc, item_key, item_value)
xml_doc.appendChild(item_node)
self._add_xmlns(item_node)
return xml_doc.toprettyxml(indent=' ', encoding='UTF-8')
def show(self, meta_item_dict):
return self._meta_item_to_xml_string(meta_item_dict['meta'])
def update(self, meta_item_dict):
return self._meta_item_to_xml_string(meta_item_dict['meta'])
def default(self, *args, **kwargs):
return ''

View File

@ -191,7 +191,7 @@ class CreateInstanceHelper(object):
Overrides normal behavior in the case of xml content
"""
if request.content_type == "application/xml":
deserializer = ServerCreateRequestXMLDeserializer()
deserializer = ServerXMLDeserializer()
return deserializer.deserialize(request.body)
else:
return self._deserialize(request.body, request.get_content_type())
@ -306,29 +306,29 @@ class ServerXMLDeserializer(wsgi.MetadataXMLDeserializer):
"""Marshal the server attribute of a parsed request"""
server = {}
server_node = self.find_first_child_named(node, 'server')
for attr in ["name", "imageId", "flavorId", "imageRef", "flavorRef"]:
attributes = ["name", "imageId", "flavorId", "imageRef",
"flavorRef", "adminPass"]
for attr in attributes:
if server_node.getAttribute(attr):
server[attr] = server_node.getAttribute(attr)
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)
if personality is not None:
server["personality"] = personality
server["metadata"] = self.extract_metadata(metadata_node)
server["personality"] = self._extract_personality(server_node)
return server
def _extract_personality(self, server_node):
"""Marshal the personality attribute of a parsed request"""
personality_node = \
self.find_first_child_named(server_node, "personality")
if personality_node is None:
return None
node = self.find_first_child_named(server_node, "personality")
personality = []
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)
personality.append(item)
if node is not None:
for file_node in self.find_children_named(node, "file"):
item = {}
if file_node.hasAttribute("path"):
item["path"] = file_node.getAttribute("path")
item["contents"] = self.extract_text(file_node)
personality.append(item)
return personality

View File

@ -16,12 +16,12 @@
# under the License.
from webob import exc
from xml.dom import minidom
from nova import flags
from nova import image
from nova import quota
from nova import utils
from nova.api.openstack import common
from nova.api.openstack import wsgi
@ -118,95 +118,15 @@ 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)
def _meta_item_to_xml(self, doc, key, value):
node = doc.createElement('meta')
doc.appendChild(node)
node.setAttribute('key', '%s' % key)
text = doc.createTextNode('%s' % value)
node.appendChild(text)
return node
def meta_list_to_xml(self, xml_doc, meta_items):
container_node = xml_doc.createElement('metadata')
for (key, value) in meta_items:
item_node = self._meta_item_to_xml(xml_doc, key, value)
container_node.appendChild(item_node)
return container_node
def _meta_list_to_xml_string(self, metadata_dict):
xml_doc = minidom.Document()
items = metadata_dict['metadata'].items()
container_node = self.meta_list_to_xml(xml_doc, items)
xml_doc.appendChild(container_node)
self._add_xmlns(container_node)
return xml_doc.toprettyxml(indent=' ', encoding='UTF-8')
def index(self, metadata_dict):
return self._meta_list_to_xml_string(metadata_dict)
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]
item_node = self._meta_item_to_xml(xml_doc, item_key, item_value)
xml_doc.appendChild(item_node)
self._add_xmlns(item_node)
return xml_doc.toprettyxml(indent=' ', encoding='UTF-8')
def show(self, meta_item_dict):
return self._meta_item_to_xml_string(meta_item_dict['meta'])
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()
headers_serializer = common.MetadataHeadersSerializer()
body_deserializers = {
'application/xml': ImageMetadataXMLDeserializer(),
'application/xml': common.MetadataXMLDeserializer(),
}
body_serializers = {
'application/xml': ImageMetadataXMLSerializer(),
'application/xml': common.MetadataXMLSerializer(),
}
serializer = wsgi.ResponseSerializer(body_serializers, headers_serializer)
deserializer = wsgi.RequestDeserializer(body_deserializers)

View File

@ -284,7 +284,7 @@ class ImageXMLSerializer(wsgi.XMLDictSerializer):
xmlns = wsgi.XMLNS_V11
def __init__(self):
self.metadata_serializer = image_metadata.ImageMetadataXMLSerializer()
self.metadata_serializer = common.MetadataXMLSerializer()
def _image_to_xml(self, xml_doc, image):
image_node = xml_doc.createElement('image')

View File

@ -18,6 +18,7 @@ import traceback
from webob import exc
import webob
from xml.dom import minidom
from nova import compute
from nova import db
@ -27,6 +28,7 @@ from nova import log as logging
from nova import utils
from nova.api.openstack import common
from nova.api.openstack import create_instance_helper as helper
from nova.api.openstack import ips
import nova.api.openstack.views.addresses
import nova.api.openstack.views.flavors
import nova.api.openstack.views.images
@ -480,11 +482,20 @@ class ControllerV11(Controller):
raise exc.HTTPNotFound()
def _image_ref_from_req_data(self, data):
return data['server']['imageRef']
try:
return data['server']['imageRef']
except (TypeError, KeyError):
msg = _("Missing imageRef attribute")
raise exc.HTTPBadRequest(explanation=msg)
def _flavor_id_from_req_data(self, data):
href = data['server']['flavorRef']
return common.get_id_from_href(href)
try:
flavor_ref = data['server']['flavorRef']
except (TypeError, KeyError):
msg = _("Missing flavorRef attribute")
raise exc.HTTPBadRequest(explanation=msg)
return common.get_id_from_href(flavor_ref)
def _build_view(self, req, instance, is_detail=False):
base_url = req.application_url
@ -599,6 +610,123 @@ class HeadersSerializer(wsgi.ResponseHeadersSerializer):
response.status_int = 204
class ServerXMLSerializer(wsgi.XMLDictSerializer):
xmlns = wsgi.XMLNS_V11
def __init__(self):
self.metadata_serializer = common.MetadataXMLSerializer()
self.addresses_serializer = ips.IPXMLSerializer()
def _create_basic_entity_node(self, xml_doc, id, links, name):
basic_node = xml_doc.createElement(name)
basic_node.setAttribute('id', str(id))
link_nodes = self._create_link_nodes(xml_doc, links)
for link_node in link_nodes:
basic_node.appendChild(link_node)
return basic_node
def _create_metadata_node(self, xml_doc, metadata):
return self.metadata_serializer.meta_list_to_xml(xml_doc, metadata)
def _create_addresses_node(self, xml_doc, addresses):
return self.addresses_serializer.networks_to_xml(xml_doc, addresses)
def _add_server_attributes(self, node, server):
node.setAttribute('id', str(server['id']))
node.setAttribute('uuid', str(server['uuid']))
node.setAttribute('hostId', str(server['hostId']))
node.setAttribute('name', server['name'])
node.setAttribute('created', str(server['created']))
node.setAttribute('updated', str(server['updated']))
node.setAttribute('status', server['status'])
if 'progress' in server:
node.setAttribute('progress', str(server['progress']))
def _server_to_xml(self, xml_doc, server):
server_node = xml_doc.createElement('server')
server_node.setAttribute('id', str(server['id']))
server_node.setAttribute('name', server['name'])
link_nodes = self._create_link_nodes(xml_doc,
server['links'])
for link_node in link_nodes:
server_node.appendChild(link_node)
return server_node
def _server_to_xml_detailed(self, xml_doc, server):
server_node = xml_doc.createElement('server')
self._add_server_attributes(server_node, server)
link_nodes = self._create_link_nodes(xml_doc,
server['links'])
for link_node in link_nodes:
server_node.appendChild(link_node)
if 'image' in server:
image_node = self._create_basic_entity_node(xml_doc,
server['image']['id'],
server['image']['links'],
'image')
server_node.appendChild(image_node)
if 'flavor' in server:
flavor_node = self._create_basic_entity_node(xml_doc,
server['flavor']['id'],
server['flavor']['links'],
'flavor')
server_node.appendChild(flavor_node)
metadata = server.get('metadata', {}).items()
if len(metadata) > 0:
metadata_node = self._create_metadata_node(xml_doc, metadata)
server_node.appendChild(metadata_node)
addresses_node = self._create_addresses_node(xml_doc,
server['addresses'])
server_node.appendChild(addresses_node)
return server_node
def _server_list_to_xml(self, xml_doc, servers, detailed):
container_node = xml_doc.createElement('servers')
if detailed:
server_to_xml = self._server_to_xml_detailed
else:
server_to_xml = self._server_to_xml
for server in servers:
item_node = server_to_xml(xml_doc, server)
container_node.appendChild(item_node)
return container_node
def index(self, servers_dict):
xml_doc = minidom.Document()
node = self._server_list_to_xml(xml_doc,
servers_dict['servers'],
detailed=False)
return self.to_xml_string(node, True)
def detail(self, servers_dict):
xml_doc = minidom.Document()
node = self._server_list_to_xml(xml_doc,
servers_dict['servers'],
detailed=True)
return self.to_xml_string(node, True)
def show(self, server_dict):
xml_doc = minidom.Document()
node = self._server_to_xml_detailed(xml_doc,
server_dict['server'])
return self.to_xml_string(node, True)
def create(self, server_dict):
xml_doc = minidom.Document()
node = self._server_to_xml_detailed(xml_doc,
server_dict['server'])
node.setAttribute('adminPass', server_dict['server']['adminPass'])
return self.to_xml_string(node, True)
def create_resource(version='1.0'):
controller = {
'1.0': ControllerV10,
@ -628,9 +756,13 @@ def create_resource(version='1.0'):
headers_serializer = HeadersSerializer()
xml_serializer = {
'1.0': wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V10),
'1.1': ServerXMLSerializer(),
}[version]
body_serializers = {
'application/xml': wsgi.XMLDictSerializer(metadata=metadata,
xmlns=xmlns),
'application/xml': xml_serializer,
}
body_deserializers = {

View File

@ -15,6 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import datetime
import hashlib
import os
@ -149,8 +150,8 @@ class ViewBuilderV11(ViewBuilder):
def _build_detail(self, inst):
response = super(ViewBuilderV11, self)._build_detail(inst)
response['server']['created'] = inst['created_at']
response['server']['updated'] = inst['updated_at']
response['server']['created'] = utils.isotime(inst['created_at'])
response['server']['updated'] = utils.isotime(inst['updated_at'])
if 'status' in response['server']:
if response['server']['status'] == "ACTIVE":
response['server']['progress'] = 100

View File

@ -165,12 +165,11 @@ 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)
if metadata_node is not None:
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

View File

@ -127,7 +127,7 @@ class DbDriver(object):
try:
project = db.project_create(context.get_admin_context(), values)
except exception.Duplicate:
except exception.DBError:
raise exception.ProjectExists(project=name)
for member in members:

View File

@ -343,7 +343,7 @@ DEFINE_string('lock_path', os.path.join(os.path.dirname(__file__), '../'),
'Directory for lock files')
DEFINE_string('logdir', None, 'output to a per-service log file in named '
'directory')
DEFINE_integer('logfile_mode', 0644, 'Default file mode of the logs.')
DEFINE_string('sqlite_db', 'nova.sqlite', 'file name for sqlite')
DEFINE_string('sql_connection',
'sqlite:///$state_path/$sqlite_db',

View File

@ -257,6 +257,7 @@ class NovaRootLogger(NovaLogger):
self.filelog = WatchedFileHandler(logpath)
self.addHandler(self.filelog)
self.logpath = logpath
os.chmod(self.logpath, FLAGS.logfile_mode)
else:
self.removeHandler(self.filelog)
self.addHandler(self.streamlog)

View File

@ -20,6 +20,7 @@ Test suites for 'common' code used throughout the OpenStack HTTP API.
"""
import webob.exc
import xml.dom.minidom as minidom
from webob import Request
@ -265,3 +266,203 @@ class MiscFunctionsTest(test.TestCase):
expected = '1.0'
actual = common.get_version_from_href(fixture)
self.assertEqual(actual, expected)
class MetadataXMLDeserializationTest(test.TestCase):
deserializer = common.MetadataXMLDeserializer()
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 MetadataXMLSerializationTest(test.TestCase):
def test_index(self):
serializer = common.MetadataXMLSerializer()
fixture = {
'metadata': {
'one': 'two',
'three': 'four',
},
}
output = serializer.serialize(fixture, 'index')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="three">
four
</meta>
<meta key="one">
two
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_index_null(self):
serializer = common.MetadataXMLSerializer()
fixture = {
'metadata': {
None: None,
},
}
output = serializer.serialize(fixture, 'index')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="None">
None
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_index_unicode(self):
serializer = common.MetadataXMLSerializer()
fixture = {
'metadata': {
u'three': u'Jos\xe9',
},
}
output = serializer.serialize(fixture, 'index')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString(u"""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="three">
Jos\xe9
</meta>
</metadata>
""".encode("UTF-8").replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_show(self):
serializer = common.MetadataXMLSerializer()
fixture = {
'meta': {
'one': 'two',
},
}
output = serializer.serialize(fixture, 'show')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
two
</meta>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_update_all(self):
serializer = common.MetadataXMLSerializer()
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 = common.MetadataXMLSerializer()
fixture = {
'meta': {
'one': 'two',
},
}
output = serializer.serialize(fixture, 'update')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
two
</meta>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_create(self):
serializer = common.MetadataXMLSerializer()
fixture = {
'metadata': {
'key9': 'value9',
'key2': 'value2',
'key1': 'value1',
},
}
output = serializer.serialize(fixture, 'create')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="key2">
value2
</meta>
<meta key="key9">
value9
</meta>
<meta key="key1">
value1
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_delete(self):
serializer = common.MetadataXMLSerializer()
output = serializer.serialize(None, 'delete')
self.assertEqual(output, '')

View File

@ -17,7 +17,6 @@
import json
import webob
import xml.dom.minidom as minidom
from nova import flags
@ -240,203 +239,3 @@ class ImageMetaDataTest(test.TestCase):
req.headers["content-type"] = "application/json"
res = req.get_response(fakes.wsgi_app())
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(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
'one': 'two',
'three': 'four',
},
}
output = serializer.serialize(fixture, 'index')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="three">
four
</meta>
<meta key="one">
two
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_index_null(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
None: None,
},
}
output = serializer.serialize(fixture, 'index')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="None">
None
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_index_unicode(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
u'three': u'Jos\xe9',
},
}
output = serializer.serialize(fixture, 'index')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString(u"""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="three">
Jos\xe9
</meta>
</metadata>
""".encode("UTF-8").replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_show(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'meta': {
'one': 'two',
},
}
output = serializer.serialize(fixture, 'show')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
two
</meta>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
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': {
'one': 'two',
},
}
output = serializer.serialize(fixture, 'update')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
two
</meta>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_create(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
fixture = {
'metadata': {
'key9': 'value9',
'key2': 'value2',
'key1': 'value1',
},
}
output = serializer.serialize(fixture, 'create')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
<meta key="key2">
value2
</meta>
<meta key="key9">
value9
</meta>
<meta key="key1">
value1
</meta>
</metadata>
""".replace(" ", ""))
self.assertEqual(expected.toxml(), actual.toxml())
def test_delete(self):
serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
output = serializer.serialize(None, 'delete')
self.assertEqual(output, '')

View File

@ -16,6 +16,7 @@
# under the License.
import base64
import datetime
import json
import unittest
from xml.dom import minidom
@ -171,8 +172,8 @@ def stub_instance(id, user_id='fake', project_id='fake', private_address=None,
instance = {
"id": int(id),
"created_at": "2010-10-10T12:00:00Z",
"updated_at": "2010-11-11T11:00:00Z",
"created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
"updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
"admin_pass": "",
"user_id": user_id,
"project_id": project_id,
@ -388,6 +389,78 @@ class ServersTest(test.TestCase):
self.assertDictMatch(res_dict, expected_server)
def test_get_server_by_id_v1_1_xml(self):
image_bookmark = "http://localhost/images/10"
flavor_ref = "http://localhost/v1.1/flavors/1"
flavor_id = "1"
flavor_bookmark = "http://localhost/flavors/1"
server_href = "http://localhost/v1.1/servers/1"
server_bookmark = "http://localhost/servers/1"
public_ip = '192.168.0.3'
private_ip = '172.19.0.1'
interfaces = [
{
'network': {'label': 'public'},
'fixed_ips': [
{'address': public_ip},
],
},
{
'network': {'label': 'private'},
'fixed_ips': [
{'address': private_ip},
],
},
]
new_return_server = return_server_with_attributes(
interfaces=interfaces)
self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
req = webob.Request.blank('/v1.1/servers/1')
req.headers['Accept'] = 'application/xml'
res = req.get_response(fakes.wsgi_app())
actual = minidom.parseString(res.body.replace(' ', ''))
expected_uuid = FAKE_UUID
expected_updated = "2010-11-11T11:00:00Z"
expected_created = "2010-10-10T12:00:00Z"
expected = minidom.parseString("""
<server id="1"
uuid="%(expected_uuid)s"
xmlns="http://docs.openstack.org/compute/api/v1.1"
xmlns:atom="http://www.w3.org/2005/Atom"
name="server1"
updated="%(expected_updated)s"
created="%(expected_created)s"
hostId=""
status="BUILD"
progress="0">
<atom:link href="%(server_href)s" rel="self"/>
<atom:link href="%(server_bookmark)s" rel="bookmark"/>
<image id="10">
<atom:link rel="bookmark" href="%(image_bookmark)s"/>
</image>
<flavor id="1">
<atom:link rel="bookmark" href="%(flavor_bookmark)s"/>
</flavor>
<metadata>
<meta key="seq">
1
</meta>
</metadata>
<addresses>
<network id="public">
<ip version="4" addr="%(public_ip)s"/>
</network>
<network id="private">
<ip version="4" addr="%(private_ip)s"/>
</network>
</addresses>
</server>
""".replace(" ", "") % (locals()))
self.assertEqual(expected.toxml(), actual.toxml())
def test_get_server_with_active_status_by_id_v1_1(self):
image_bookmark = "http://localhost/images/10"
flavor_ref = "http://localhost/v1.1/flavors/1"
@ -1039,8 +1112,8 @@ class ServersTest(test.TestCase):
'uuid': FAKE_UUID,
'instance_type': dict(inst_type),
'image_ref': image_ref,
'created_at': '2010-10-10T12:00:00Z',
'updated_at': '2010-11-11T11:00:00Z',
"created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
"updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
}
def server_update(context, id, params):
@ -1090,6 +1163,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
server = json.loads(res.body)['server']
self.assertEqual(16, len(server['adminPass']))
self.assertEqual('server_test', server['name'])
@ -1097,7 +1171,6 @@ class ServersTest(test.TestCase):
self.assertEqual(2, server['flavorId'])
self.assertEqual(3, server['imageId'])
self.assertEqual(FAKE_UUID, server['uuid'])
self.assertEqual(res.status_int, 200)
def test_create_instance(self):
self._test_create_instance_helper()
@ -1270,7 +1343,12 @@ class ServersTest(test.TestCase):
'hello': 'world',
'open': 'stack',
},
'personality': {},
'personality': [
{
"path": "/etc/banner.txt",
"contents": "MQ==",
},
],
},
}
@ -1284,11 +1362,11 @@ class ServersTest(test.TestCase):
self.assertEqual(res.status_int, 200)
server = json.loads(res.body)['server']
self.assertEqual(16, len(server['adminPass']))
self.assertEqual(1, server['id'])
self.assertEqual(0, server['progress'])
self.assertEqual('server_test', server['name'])
self.assertEqual(expected_flavor, server['flavor'])
self.assertEqual(expected_image, server['image'])
self.assertEqual(res.status_int, 200)
#self.assertEqual(1, server['id'])
def test_create_instance_v1_1_invalid_flavor_href(self):
self._setup_for_create_instance()
@ -1342,7 +1420,7 @@ class ServersTest(test.TestCase):
self._setup_for_create_instance()
image_id = "2"
flavor_ref = 'http://localhost/flavors/3'
flavor_ref = 'http://localhost/v1.1/flavors/3'
expected_flavor = {
"id": "3",
"links": [
@ -1376,10 +1454,10 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
server = json.loads(res.body)['server']
self.assertEqual(expected_flavor, server['flavor'])
self.assertEqual(expected_image, server['image'])
self.assertEqual(res.status_int, 200)
def test_create_instance_with_admin_pass_v1_0(self):
self._setup_for_create_instance()
@ -1402,7 +1480,7 @@ class ServersTest(test.TestCase):
self.assertNotEqual(res['server']['adminPass'],
body['server']['adminPass'])
def test_create_instance_with_admin_pass_v1_1(self):
def test_create_instance_v1_1_admin_pass(self):
self._setup_for_create_instance()
image_href = 'http://localhost/v1.1/images/2'
@ -1410,8 +1488,8 @@ class ServersTest(test.TestCase):
body = {
'server': {
'name': 'server_test',
'imageRef': image_href,
'flavorRef': flavor_ref,
'imageRef': 3,
'flavorRef': 3,
'adminPass': 'testpass',
},
}
@ -1421,19 +1499,18 @@ class ServersTest(test.TestCase):
req.body = json.dumps(body)
req.headers['content-type'] = "application/json"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
server = json.loads(res.body)['server']
self.assertEqual(server['adminPass'], body['server']['adminPass'])
def test_create_instance_with_empty_admin_pass_v1_1(self):
def test_create_instance_v1_1_admin_pass_empty(self):
self._setup_for_create_instance()
image_href = 'http://localhost/v1.1/images/2'
flavor_ref = 'http://localhost/v1.1/flavors/3'
body = {
'server': {
'name': 'server_test',
'imageRef': image_href,
'flavorRef': flavor_ref,
'imageRef': 3,
'flavorRef': 3,
'adminPass': '',
},
}
@ -2227,7 +2304,7 @@ class ServersTest(test.TestCase):
self.assertEqual(res_dict['server']['status'], 'SHUTOFF')
class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
class TestServerCreateRequestXMLDeserializerV10(unittest.TestCase):
def setUp(self):
self.deserializer = create_instance_helper.ServerXMLDeserializer()
@ -2241,6 +2318,8 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"name": "new-server-test",
"imageId": "1",
"flavorId": "1",
"metadata": {},
"personality": [],
}}
self.assertEquals(request['body'], expected)
@ -2256,6 +2335,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"imageId": "1",
"flavorId": "1",
"metadata": {},
"personality": [],
}}
self.assertEquals(request['body'], expected)
@ -2270,6 +2350,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"name": "new-server-test",
"imageId": "1",
"flavorId": "1",
"metadata": {},
"personality": [],
}}
self.assertEquals(request['body'], expected)
@ -2507,18 +2588,188 @@ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==""",
request = self.deserializer.deserialize(serial_request, 'create')
self.assertEqual(request['body'], expected)
def test_request_xmlser_with_flavor_image_href(self):
class TestServerCreateRequestXMLDeserializerV11(unittest.TestCase):
def setUp(self):
self.deserializer = create_instance_helper.ServerXMLDeserializer()
def test_minimal_request(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="http://localhost:8774/v1.1/images/1"
flavorRef="http://localhost:8774/v1.1/flavors/1">
</server>"""
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="1"
flavorRef="2"/>"""
request = self.deserializer.deserialize(serial_request, 'create')
self.assertEquals(request['body']["server"]["flavorRef"],
"http://localhost:8774/v1.1/flavors/1")
self.assertEquals(request['body']["server"]["imageRef"],
"http://localhost:8774/v1.1/images/1")
expected = {
"server": {
"name": "new-server-test",
"imageRef": "1",
"flavorRef": "2",
"metadata": {},
"personality": [],
},
}
self.assertEquals(request['body'], expected)
def test_admin_pass(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="1"
flavorRef="2"
adminPass="1234"/>"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {
"server": {
"name": "new-server-test",
"imageRef": "1",
"flavorRef": "2",
"adminPass": "1234",
"metadata": {},
"personality": [],
},
}
self.assertEquals(request['body'], expected)
def test_image_link(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="http://localhost:8774/v1.1/images/2"
flavorRef="3"/>"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {
"server": {
"name": "new-server-test",
"imageRef": "http://localhost:8774/v1.1/images/2",
"flavorRef": "3",
"metadata": {},
"personality": [],
},
}
self.assertEquals(request['body'], expected)
def test_flavor_link(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="1"
flavorRef="http://localhost:8774/v1.1/flavors/3"/>"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {
"server": {
"name": "new-server-test",
"imageRef": "1",
"flavorRef": "http://localhost:8774/v1.1/flavors/3",
"metadata": {},
"personality": [],
},
}
self.assertEquals(request['body'], expected)
def test_empty_metadata_personality(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="1"
flavorRef="2">
<metadata/>
<personality/>
</server>"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {
"server": {
"name": "new-server-test",
"imageRef": "1",
"flavorRef": "2",
"metadata": {},
"personality": [],
},
}
self.assertEquals(request['body'], expected)
def test_multiple_metadata_items(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="1"
flavorRef="2">
<metadata>
<meta key="one">two</meta>
<meta key="open">snack</meta>
</metadata>
</server>"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {
"server": {
"name": "new-server-test",
"imageRef": "1",
"flavorRef": "2",
"metadata": {"one": "two", "open": "snack"},
"personality": [],
},
}
self.assertEquals(request['body'], expected)
def test_multiple_personality_files(self):
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
name="new-server-test"
imageRef="1"
flavorRef="2">
<personality>
<file path="/etc/banner.txt">MQ==</file>
<file path="/etc/hosts">Mg==</file>
</personality>
</server>"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {
"server": {
"name": "new-server-test",
"imageRef": "1",
"flavorRef": "2",
"metadata": {},
"personality": [
{"path": "/etc/banner.txt", "contents": "MQ=="},
{"path": "/etc/hosts", "contents": "Mg=="},
],
},
}
self.assertEquals(request['body'], expected)
def test_spec_request(self):
image_bookmark_link = "http://servers.api.openstack.org/1234/" + \
"images/52415800-8b69-11e0-9b19-734f6f006e54"
serial_request = """
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
imageRef="%s"
flavorRef="52415800-8b69-11e0-9b19-734f1195ff37"
name="new-server-test">
<metadata>
<meta key="My Server Name">Apache1</meta>
</metadata>
<personality>
<file path="/etc/banner.txt">Mg==</file>
</personality>
</server>""" % (image_bookmark_link)
request = self.deserializer.deserialize(serial_request, 'create')
expected = {
"server": {
"name": "new-server-test",
"imageRef": "http://servers.api.openstack.org/1234/" + \
"images/52415800-8b69-11e0-9b19-734f6f006e54",
"flavorRef": "52415800-8b69-11e0-9b19-734f1195ff37",
"metadata": {"My Server Name": "Apache1"},
"personality": [
{
"path": "/etc/banner.txt",
"contents": "Mg==",
},
],
},
}
self.assertEquals(request['body'], expected)
class TextAddressesXMLSerialization(test.TestCase):
@ -2881,10 +3132,12 @@ class ServersViewBuilderV11Test(test.TestCase):
pass
def _get_instance(self):
created_at = datetime.datetime(2010, 10, 10, 12, 0, 0)
updated_at = datetime.datetime(2010, 11, 11, 11, 0, 0)
instance = {
"id": 1,
"created_at": "2010-10-10T12:00:00Z",
"updated_at": "2010-11-11T11:00:00Z",
"created_at": created_at,
"updated_at": updated_at,
"admin_pass": "",
"user_id": "",
"project_id": "",
@ -2932,7 +3185,7 @@ class ServersViewBuilderV11Test(test.TestCase):
address_builder,
flavor_builder,
image_builder,
base_url
base_url,
)
return view_builder
@ -3088,12 +3341,12 @@ class ServersViewBuilderV11Test(test.TestCase):
},
"flavor": {
"id": "1",
"links": [
{
"rel": "bookmark",
"href": flavor_bookmark,
},
],
"links": [
{
"rel": "bookmark",
"href": flavor_bookmark,
},
],
},
"addresses": {},
"metadata": {
@ -3115,3 +3368,505 @@ class ServersViewBuilderV11Test(test.TestCase):
output = self.view_builder.build(self.instance, True)
self.assertDictMatch(output, expected_server)
class ServerXMLSerializationTest(test.TestCase):
TIMESTAMP = "2010-10-11T10:30:22Z"
SERVER_HREF = 'http://localhost/v1.1/servers/123'
SERVER_BOOKMARK = 'http://localhost/servers/123'
IMAGE_BOOKMARK = 'http://localhost/images/5'
FLAVOR_BOOKMARK = 'http://localhost/flavors/1'
def setUp(self):
self.maxDiff = None
test.TestCase.setUp(self)
def test_show(self):
serializer = servers.ServerXMLSerializer()
fixture = {
"server": {
"id": 1,
"uuid": FAKE_UUID,
'created': self.TIMESTAMP,
'updated': self.TIMESTAMP,
"progress": 0,
"name": "test_server",
"status": "BUILD",
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
"image": {
"id": "5",
"links": [
{
"rel": "bookmark",
"href": self.IMAGE_BOOKMARK,
},
],
},
"flavor": {
"id": "1",
"links": [
{
"rel": "bookmark",
"href": self.FLAVOR_BOOKMARK,
},
],
},
"addresses": {
"network_one": [
{
"version": 4,
"addr": "67.23.10.138",
},
{
"version": 6,
"addr": "::babe:67.23.10.138",
},
],
"network_two": [
{
"version": 4,
"addr": "67.23.10.139",
},
{
"version": 6,
"addr": "::babe:67.23.10.139",
},
],
},
"metadata": {
"Open": "Stack",
"Number": "1",
},
'links': [
{
'href': self.SERVER_HREF,
'rel': 'self',
},
{
'href': self.SERVER_BOOKMARK,
'rel': 'bookmark',
},
],
}
}
output = serializer.serialize(fixture, 'show')
actual = minidom.parseString(output.replace(" ", ""))
expected_server_href = self.SERVER_HREF
expected_server_bookmark = self.SERVER_BOOKMARK
expected_image_bookmark = self.IMAGE_BOOKMARK
expected_flavor_bookmark = self.FLAVOR_BOOKMARK
expected_now = self.TIMESTAMP
expected_uuid = FAKE_UUID
expected = minidom.parseString("""
<server id="1"
uuid="%(expected_uuid)s"
xmlns="http://docs.openstack.org/compute/api/v1.1"
xmlns:atom="http://www.w3.org/2005/Atom"
name="test_server"
updated="%(expected_now)s"
created="%(expected_now)s"
hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
status="BUILD"
progress="0">
<atom:link href="%(expected_server_href)s" rel="self"/>
<atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
<image id="5">
<atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
</image>
<flavor id="1">
<atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
</flavor>
<metadata>
<meta key="Open">
Stack
</meta>
<meta key="Number">
1
</meta>
</metadata>
<addresses>
<network id="network_one">
<ip version="4" addr="67.23.10.138"/>
<ip version="6" addr="::babe:67.23.10.138"/>
</network>
<network id="network_two">
<ip version="4" addr="67.23.10.139"/>
<ip version="6" addr="::babe:67.23.10.139"/>
</network>
</addresses>
</server>
""".replace(" ", "") % (locals()))
self.assertEqual(expected.toxml(), actual.toxml())
def test_create(self):
serializer = servers.ServerXMLSerializer()
fixture = {
"server": {
"id": 1,
"uuid": FAKE_UUID,
'created': self.TIMESTAMP,
'updated': self.TIMESTAMP,
"progress": 0,
"name": "test_server",
"status": "BUILD",
"hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
"adminPass": "test_password",
"image": {
"id": "5",
"links": [
{
"rel": "bookmark",
"href": self.IMAGE_BOOKMARK,
},
],
},
"flavor": {
"id": "1",
"links": [
{
"rel": "bookmark",
"href": self.FLAVOR_BOOKMARK,
},
],
},
"addresses": {
"network_one": [
{
"version": 4,
"addr": "67.23.10.138",
},
{
"version": 6,
"addr": "::babe:67.23.10.138",
},
],
"network_two": [
{
"version": 4,
"addr": "67.23.10.139",
},
{
"version": 6,
"addr": "::babe:67.23.10.139",
},
],
},
"metadata": {
"Open": "Stack",
"Number": "1",
},
'links': [
{
'href': self.SERVER_HREF,
'rel': 'self',
},
{
'href': self.SERVER_BOOKMARK,
'rel': 'bookmark',
},
],
}
}
output = serializer.serialize(fixture, 'create')
actual = minidom.parseString(output.replace(" ", ""))
expected_server_href = self.SERVER_HREF
expected_server_bookmark = self.SERVER_BOOKMARK
expected_image_bookmark = self.IMAGE_BOOKMARK
expected_flavor_bookmark = self.FLAVOR_BOOKMARK
expected_now = self.TIMESTAMP
expected_uuid = FAKE_UUID
expected = minidom.parseString("""
<server id="1"
uuid="%(expected_uuid)s"
xmlns="http://docs.openstack.org/compute/api/v1.1"
xmlns:atom="http://www.w3.org/2005/Atom"
name="test_server"
updated="%(expected_now)s"
created="%(expected_now)s"
hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
status="BUILD"
adminPass="test_password"
progress="0">
<atom:link href="%(expected_server_href)s" rel="self"/>
<atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
<image id="5">
<atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
</image>
<flavor id="1">
<atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
</flavor>
<metadata>
<meta key="Open">
Stack
</meta>
<meta key="Number">
1
</meta>
</metadata>
<addresses>
<network id="network_one">
<ip version="4" addr="67.23.10.138"/>
<ip version="6" addr="::babe:67.23.10.138"/>
</network>
<network id="network_two">
<ip version="4" addr="67.23.10.139"/>
<ip version="6" addr="::babe:67.23.10.139"/>
</network>
</addresses>
</server>
""".replace(" ", "") % (locals()))
self.assertEqual(expected.toxml(), actual.toxml())
def test_index(self):
serializer = servers.ServerXMLSerializer()
expected_server_href = 'http://localhost/v1.1/servers/1'
expected_server_bookmark = 'http://localhost/servers/1'
expected_server_href_2 = 'http://localhost/v1.1/servers/2'
expected_server_bookmark_2 = 'http://localhost/servers/2'
fixture = {"servers": [
{
"id": 1,
"name": "test_server",
'links': [
{
'href': expected_server_href,
'rel': 'self',
},
{
'href': expected_server_bookmark,
'rel': 'bookmark',
},
],
},
{
"id": 2,
"name": "test_server_2",
'links': [
{
'href': expected_server_href_2,
'rel': 'self',
},
{
'href': expected_server_bookmark_2,
'rel': 'bookmark',
},
],
},
]}
output = serializer.serialize(fixture, 'index')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<servers xmlns="http://docs.openstack.org/compute/api/v1.1"
xmlns:atom="http://www.w3.org/2005/Atom">
<server id="1" name="test_server">
<atom:link href="%(expected_server_href)s" rel="self"/>
<atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
</server>
<server id="2" name="test_server_2">
<atom:link href="%(expected_server_href_2)s" rel="self"/>
<atom:link href="%(expected_server_bookmark_2)s" rel="bookmark"/>
</server>
</servers>
""".replace(" ", "") % (locals()))
self.assertEqual(expected.toxml(), actual.toxml())
def test_detail(self):
serializer = servers.ServerXMLSerializer()
expected_server_href = 'http://localhost/v1.1/servers/1'
expected_server_bookmark = 'http://localhost/servers/1'
expected_image_bookmark = self.IMAGE_BOOKMARK
expected_flavor_bookmark = self.FLAVOR_BOOKMARK
expected_now = self.TIMESTAMP
expected_uuid = FAKE_UUID
expected_server_href_2 = 'http://localhost/v1.1/servers/2'
expected_server_bookmark_2 = 'http://localhost/servers/2'
fixture = {"servers": [
{
"id": 1,
"uuid": FAKE_UUID,
'created': self.TIMESTAMP,
'updated': self.TIMESTAMP,
"progress": 0,
"name": "test_server",
"status": "BUILD",
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
"image": {
"id": "5",
"links": [
{
"rel": "bookmark",
"href": expected_image_bookmark,
},
],
},
"flavor": {
"id": "1",
"links": [
{
"rel": "bookmark",
"href": expected_flavor_bookmark,
},
],
},
"addresses": {
"network_one": [
{
"version": 4,
"addr": "67.23.10.138",
},
{
"version": 6,
"addr": "::babe:67.23.10.138",
},
],
},
"metadata": {
"Number": "1",
},
"links": [
{
"href": expected_server_href,
"rel": "self",
},
{
"href": expected_server_bookmark,
"rel": "bookmark",
},
],
},
{
"id": 2,
"uuid": FAKE_UUID,
'created': self.TIMESTAMP,
'updated': self.TIMESTAMP,
"progress": 100,
"name": "test_server_2",
"status": "ACTIVE",
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
"image": {
"id": "5",
"links": [
{
"rel": "bookmark",
"href": expected_image_bookmark,
},
],
},
"flavor": {
"id": "1",
"links": [
{
"rel": "bookmark",
"href": expected_flavor_bookmark,
},
],
},
"addresses": {
"network_one": [
{
"version": 4,
"addr": "67.23.10.138",
},
{
"version": 6,
"addr": "::babe:67.23.10.138",
},
],
},
"metadata": {
"Number": "2",
},
"links": [
{
"href": expected_server_href_2,
"rel": "self",
},
{
"href": expected_server_bookmark_2,
"rel": "bookmark",
},
],
},
]}
output = serializer.serialize(fixture, 'detail')
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
<servers xmlns="http://docs.openstack.org/compute/api/v1.1"
xmlns:atom="http://www.w3.org/2005/Atom">
<server id="1"
uuid="%(expected_uuid)s"
name="test_server"
updated="%(expected_now)s"
created="%(expected_now)s"
hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
status="BUILD"
progress="0">
<atom:link href="%(expected_server_href)s" rel="self"/>
<atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
<image id="5">
<atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
</image>
<flavor id="1">
<atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
</flavor>
<metadata>
<meta key="Number">
1
</meta>
</metadata>
<addresses>
<network id="network_one">
<ip version="4" addr="67.23.10.138"/>
<ip version="6" addr="::babe:67.23.10.138"/>
</network>
</addresses>
</server>
<server id="2"
uuid="%(expected_uuid)s"
name="test_server_2"
updated="%(expected_now)s"
created="%(expected_now)s"
hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
status="ACTIVE"
progress="100">
<atom:link href="%(expected_server_href_2)s" rel="self"/>
<atom:link href="%(expected_server_bookmark_2)s" rel="bookmark"/>
<image id="5">
<atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
</image>
<flavor id="1">
<atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
</flavor>
<metadata>
<meta key="Number">
2
</meta>
</metadata>
<addresses>
<network id="network_one">
<ip version="4" addr="67.23.10.138"/>
<ip version="6" addr="::babe:67.23.10.138"/>
</network>
</addresses>
</server>
</servers>
""".replace(" ", "") % (locals()))
self.assertEqual(expected.toxml(), actual.toxml())

View File

@ -305,5 +305,6 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
# Cleanup
self._delete_server(server_id)
if __name__ == "__main__":
unittest.main()

View File

@ -466,7 +466,7 @@ class VMOps(object):
self._session, instance, template_vdi_uuids, image_id)
finally:
if template_vm_ref:
self._destroy(instance, template_vm_ref, None,
self._destroy(instance, template_vm_ref,
shutdown=False, destroy_kernel_ramdisk=False)
logging.debug(_("Finished snapshot and upload for VM %s"), instance)
@ -848,7 +848,7 @@ class VMOps(object):
vm_ref = VMHelper.lookup(self._session, instance.name)
return self._destroy(instance, vm_ref, network_info, shutdown=True)
def _destroy(self, instance, vm_ref, network_info, shutdown=True,
def _destroy(self, instance, vm_ref, network_info=None, shutdown=True,
destroy_kernel_ramdisk=True):
"""Destroys VM instance by performing: