summaryrefslogtreecommitdiffstats
path: root/nova/tests
diff options
context:
space:
mode:
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/api/ec2/test_cloud.py4
-rw-r--r--nova/tests/api/openstack/common.py22
-rw-r--r--nova/tests/api/openstack/contrib/test_createserverext.py4
-rw-r--r--nova/tests/api/openstack/contrib/test_rescue.py23
-rw-r--r--nova/tests/api/openstack/contrib/test_volumes.py77
-rw-r--r--nova/tests/api/openstack/test_api.py25
-rw-r--r--nova/tests/api/openstack/test_common.py176
-rw-r--r--nova/tests/api/openstack/test_extensions.py1
-rw-r--r--nova/tests/api/openstack/test_flavors.py259
-rw-r--r--nova/tests/api/openstack/test_images.py454
-rw-r--r--nova/tests/api/openstack/test_limits.py104
-rw-r--r--nova/tests/api/openstack/test_server_actions.py3
-rw-r--r--nova/tests/api/openstack/test_servers.py325
-rw-r--r--nova/tests/api/openstack/test_versions.py604
-rw-r--r--nova/tests/api/openstack/test_wsgi.py57
-rw-r--r--nova/tests/db/fakes.py4
-rw-r--r--nova/tests/fake_network.py30
-rw-r--r--nova/tests/integrated/test_xml.py12
-rw-r--r--nova/tests/test_libvirt.py142
-rw-r--r--nova/tests/test_xenapi.py3
-rw-r--r--nova/tests/vmwareapi/stubs.py2
21 files changed, 1374 insertions, 957 deletions
diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py
index 7fe353b3d..7bdae0552 100644
--- a/nova/tests/api/ec2/test_cloud.py
+++ b/nova/tests/api/ec2/test_cloud.py
@@ -1540,7 +1540,9 @@ class CloudTestCase(test.TestCase):
'ephemeral0': '/dev/sdb',
'swap': '/dev/sdc',
'ephemeral1': '/dev/sdd',
- 'ephemeral2': '/dev/sd3'}
+ 'ephemeral2': '/dev/sd3',
+ 'ebs0': '/dev/sdh',
+ 'ebs1': '/dev/sdi'}
self.assertEqual(self.cloud._format_instance_mapping(ctxt,
instance_ref0),
diff --git a/nova/tests/api/openstack/common.py b/nova/tests/api/openstack/common.py
index 74bb8729a..19515ca67 100644
--- a/nova/tests/api/openstack/common.py
+++ b/nova/tests/api/openstack/common.py
@@ -34,3 +34,25 @@ def webob_factory(url):
req.body = json.dumps(body)
return req
return web_request
+
+
+def compare_links(actual, expected):
+ """Compare xml atom links."""
+
+ return compare_tree_to_dict(actual, expected, ('rel', 'href', 'type'))
+
+
+def compare_media_types(actual, expected):
+ """Compare xml media types."""
+
+ return compare_tree_to_dict(actual, expected, ('base', 'type'))
+
+
+def compare_tree_to_dict(actual, expected, keys):
+ """Compare parts of lxml.etree objects to dicts."""
+
+ for elem, data in zip(actual, expected):
+ for key in keys:
+ if elem.get(key) != data.get(key):
+ return False
+ return True
diff --git a/nova/tests/api/openstack/contrib/test_createserverext.py b/nova/tests/api/openstack/contrib/test_createserverext.py
index 24f756d5b..1ab2062e9 100644
--- a/nova/tests/api/openstack/contrib/test_createserverext.py
+++ b/nova/tests/api/openstack/contrib/test_createserverext.py
@@ -49,10 +49,14 @@ INSTANCE = {
"id": 1,
"display_name": "test_server",
"uuid": FAKE_UUID,
+ "user_id": 'fake_user_id',
+ "tenant_id": 'fake_tenant_id',
"created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
"updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
"security_groups": [{"id": 1, "name": "test"}],
"progress": 0
+ "image_ref": 'http://foo.com/123',
+ "instance_type": {"flavorid": '124'},
}
diff --git a/nova/tests/api/openstack/contrib/test_rescue.py b/nova/tests/api/openstack/contrib/test_rescue.py
index f8126d461..403bcfd4c 100644
--- a/nova/tests/api/openstack/contrib/test_rescue.py
+++ b/nova/tests/api/openstack/contrib/test_rescue.py
@@ -16,11 +16,14 @@ import json
import webob
from nova import compute
+from nova import flags
from nova import test
from nova.tests.api.openstack import fakes
+FLAGS = flags.FLAGS
-def rescue(self, context, instance_id):
+
+def rescue(self, context, instance_id, rescue_password=None):
pass
@@ -34,7 +37,19 @@ class RescueTest(test.TestCase):
self.stubs.Set(compute.api.API, "rescue", rescue)
self.stubs.Set(compute.api.API, "unrescue", unrescue)
- def test_rescue(self):
+ def test_rescue_with_preset_password(self):
+ body = {"rescue": {"adminPass": "AABBCC112233"}}
+ req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
+ req.method = "POST"
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ resp = req.get_response(fakes.wsgi_app())
+ self.assertEqual(resp.status_int, 200)
+ resp_json = json.loads(resp.body)
+ self.assertEqual("AABBCC112233", resp_json['adminPass'])
+
+ def test_rescue_generates_password(self):
body = dict(rescue=None)
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
req.method = "POST"
@@ -43,6 +58,8 @@ class RescueTest(test.TestCase):
resp = req.get_response(fakes.wsgi_app())
self.assertEqual(resp.status_int, 200)
+ resp_json = json.loads(resp.body)
+ self.assertEqual(FLAGS.password_length, len(resp_json['adminPass']))
def test_unrescue(self):
body = dict(unrescue=None)
@@ -52,4 +69,4 @@ class RescueTest(test.TestCase):
req.headers["content-type"] = "application/json"
resp = req.get_response(fakes.wsgi_app())
- self.assertEqual(resp.status_int, 200)
+ self.assertEqual(resp.status_int, 202)
diff --git a/nova/tests/api/openstack/contrib/test_volumes.py b/nova/tests/api/openstack/contrib/test_volumes.py
new file mode 100644
index 000000000..52b65f5e1
--- /dev/null
+++ b/nova/tests/api/openstack/contrib/test_volumes.py
@@ -0,0 +1,77 @@
+# Copyright 2011 Josh Durgin
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import datetime
+import json
+import webob
+
+import nova
+from nova import context
+from nova import flags
+from nova import test
+from nova.api.openstack.contrib.volumes import BootFromVolumeController
+from nova.compute import instance_types
+from nova.tests.api.openstack import fakes
+from nova.tests.api.openstack.test_servers import fake_gen_uuid
+
+
+FLAGS = flags.FLAGS
+
+
+def fake_compute_api_create(cls, context, instance_type, image_href, **kwargs):
+ inst_type = instance_types.get_instance_type_by_flavor_id(2)
+ return [{'id': 1,
+ 'display_name': 'test_server',
+ 'uuid': fake_gen_uuid(),
+ 'instance_type': dict(inst_type),
+ 'access_ip_v4': '1.2.3.4',
+ 'access_ip_v6': 'fead::1234',
+ 'image_ref': 3,
+ 'user_id': 'fake',
+ 'project_id': 'fake',
+ 'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0),
+ 'updated_at': datetime.datetime(2010, 11, 11, 11, 0, 0),
+ }]
+
+
+class BootFromVolumeTest(test.TestCase):
+
+ def setUp(self):
+ super(BootFromVolumeTest, self).setUp()
+ self.stubs.Set(nova.compute.API, 'create', fake_compute_api_create)
+
+ def test_create_root_volume(self):
+ body = dict(server=dict(
+ name='test_server', imageRef=3,
+ flavorRef=2, min_count=1, max_count=1,
+ block_device_mapping=[dict(
+ volume_id=1,
+ device_name='/dev/vda',
+ virtual='root',
+ delete_on_termination=False,
+ )]
+ ))
+ req = webob.Request.blank('/v1.1/fake/os-volumes_boot')
+ req.method = 'POST'
+ 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(1, server['id'])
+ self.assertEqual(2, int(server['flavor']['id']))
+ self.assertEqual(u'test_server', server['name'])
+ self.assertEqual(3, int(server['image']['id']))
+ self.assertEqual(FLAGS.password_length, len(server['adminPass']))
diff --git a/nova/tests/api/openstack/test_api.py b/nova/tests/api/openstack/test_api.py
index 7321c329f..b7a0b01ef 100644
--- a/nova/tests/api/openstack/test_api.py
+++ b/nova/tests/api/openstack/test_api.py
@@ -20,6 +20,7 @@ import json
import webob.exc
import webob.dec
+from lxml import etree
from webob import Request
from nova import test
@@ -52,6 +53,30 @@ class APITest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
+ def test_vendor_content_type_json(self):
+ ctype = 'application/vnd.openstack.compute+json'
+
+ req = webob.Request.blank('/')
+ req.headers['Accept'] = ctype
+
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 200)
+ self.assertEqual(res.content_type, ctype)
+
+ body = json.loads(res.body)
+
+ def test_vendor_content_type_xml(self):
+ ctype = 'application/vnd.openstack.compute+xml'
+
+ req = webob.Request.blank('/')
+ req.headers['Accept'] = ctype
+
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 200)
+ self.assertEqual(res.content_type, ctype)
+
+ body = etree.XML(res.body)
+
def test_exceptions_are_converted_to_faults(self):
@webob.dec.wsgify
diff --git a/nova/tests/api/openstack/test_common.py b/nova/tests/api/openstack/test_common.py
index b422bc4d1..1628ad1c8 100644
--- a/nova/tests/api/openstack/test_common.py
+++ b/nova/tests/api/openstack/test_common.py
@@ -19,6 +19,7 @@
Test suites for 'common' code used throughout the OpenStack HTTP API.
"""
+from lxml import etree
import webob.exc
import xml.dom.minidom as minidom
@@ -26,6 +27,11 @@ from webob import Request
from nova import test
from nova.api.openstack import common
+from nova.api.openstack import xmlutil
+
+
+NS = "{http://docs.openstack.org/compute/api/v1.1}"
+ATOMNS = "{http://www.w3.org/2005/Atom}"
class LimiterTest(test.TestCase):
@@ -237,21 +243,41 @@ class MiscFunctionsTest(test.TestCase):
common.remove_version_from_href,
fixture)
- def test_get_id_from_href(self):
+ def test_get_id_from_href_with_int_url(self):
fixture = 'http://www.testsite.com/dir/45'
actual = common.get_id_from_href(fixture)
- expected = 45
+ expected = '45'
self.assertEqual(actual, expected)
- def test_get_id_from_href_bad_request(self):
- fixture = 'http://45'
- self.assertRaises(ValueError,
- common.get_id_from_href,
- fixture)
+ def test_get_id_from_href_with_int(self):
+ fixture = '45'
+ actual = common.get_id_from_href(fixture)
+ expected = '45'
+ self.assertEqual(actual, expected)
+
+ def test_get_id_from_href_with_int_url_query(self):
+ fixture = 'http://www.testsite.com/dir/45?asdf=jkl'
+ actual = common.get_id_from_href(fixture)
+ expected = '45'
+ self.assertEqual(actual, expected)
- def test_get_id_from_href_int(self):
- fixture = 1
- self.assertEqual(fixture, common.get_id_from_href(fixture))
+ def test_get_id_from_href_with_uuid_url(self):
+ fixture = 'http://www.testsite.com/dir/abc123'
+ actual = common.get_id_from_href(fixture)
+ expected = "abc123"
+ self.assertEqual(actual, expected)
+
+ def test_get_id_from_href_with_uuid_url_query(self):
+ fixture = 'http://www.testsite.com/dir/abc123?asdf=jkl'
+ actual = common.get_id_from_href(fixture)
+ expected = "abc123"
+ self.assertEqual(actual, expected)
+
+ def test_get_id_from_href_with_uuid(self):
+ fixture = 'abc123'
+ actual = common.get_id_from_href(fixture)
+ expected = 'abc123'
+ self.assertEqual(actual, expected)
def test_get_version_from_href(self):
fixture = 'http://www.testsite.com/v1.1/images'
@@ -314,7 +340,7 @@ class MetadataXMLDeserializationTest(test.TestCase):
class MetadataXMLSerializationTest(test.TestCase):
- def test_index(self):
+ def test_xml_declaration(self):
serializer = common.MetadataXMLSerializer()
fixture = {
'metadata': {
@@ -322,17 +348,31 @@ class MetadataXMLSerializationTest(test.TestCase):
'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(" ", "").replace("\n", ""))
+ output = serializer.serialize(fixture, 'index')
+ print output
+ has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
+ self.assertTrue(has_dec)
- self.assertEqual(expected.toxml(), actual.toxml())
+ def test_index(self):
+ serializer = common.MetadataXMLSerializer()
+ fixture = {
+ 'metadata': {
+ 'one': 'two',
+ 'three': 'four',
+ },
+ }
+ output = serializer.serialize(fixture, 'index')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'metadata')
+ metadata_dict = fixture['metadata']
+ metadata_elems = root.findall('{0}meta'.format(NS))
+ self.assertEqual(len(metadata_elems), 2)
+ for i, metadata_elem in enumerate(metadata_elems):
+ (meta_key, meta_value) = metadata_dict.items()[i]
+ self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
+ self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
def test_index_null(self):
serializer = common.MetadataXMLSerializer()
@@ -342,15 +382,16 @@ class MetadataXMLSerializationTest(test.TestCase):
},
}
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(" ", "").replace("\n", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'metadata')
+ metadata_dict = fixture['metadata']
+ metadata_elems = root.findall('{0}meta'.format(NS))
+ self.assertEqual(len(metadata_elems), 1)
+ for i, metadata_elem in enumerate(metadata_elems):
+ (meta_key, meta_value) = metadata_dict.items()[i]
+ self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
+ self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
def test_index_unicode(self):
serializer = common.MetadataXMLSerializer()
@@ -360,15 +401,16 @@ class MetadataXMLSerializationTest(test.TestCase):
},
}
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(" ", "").replace("\n", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'metadata')
+ metadata_dict = fixture['metadata']
+ metadata_elems = root.findall('{0}meta'.format(NS))
+ self.assertEqual(len(metadata_elems), 1)
+ for i, metadata_elem in enumerate(metadata_elems):
+ (meta_key, meta_value) = metadata_dict.items()[i]
+ self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
+ self.assertEqual(metadata_elem.text.strip(), meta_value)
def test_show(self):
serializer = common.MetadataXMLSerializer()
@@ -378,14 +420,12 @@ class MetadataXMLSerializationTest(test.TestCase):
},
}
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(" ", "").replace("\n", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ meta_dict = fixture['meta']
+ (meta_key, meta_value) = meta_dict.items()[0]
+ self.assertEqual(str(root.get('key')), str(meta_key))
+ self.assertEqual(root.text.strip(), meta_value)
def test_update_all(self):
serializer = common.MetadataXMLSerializer()
@@ -396,16 +436,16 @@ class MetadataXMLSerializationTest(test.TestCase):
},
}
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(" ", "").replace("\n", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'metadata')
+ metadata_dict = fixture['metadata']
+ metadata_elems = root.findall('{0}meta'.format(NS))
+ self.assertEqual(len(metadata_elems), 2)
+ for i, metadata_elem in enumerate(metadata_elems):
+ (meta_key, meta_value) = metadata_dict.items()[i]
+ self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
+ self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
def test_update_item(self):
serializer = common.MetadataXMLSerializer()
@@ -415,14 +455,12 @@ class MetadataXMLSerializationTest(test.TestCase):
},
}
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(" ", "").replace("\n", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ meta_dict = fixture['meta']
+ (meta_key, meta_value) = meta_dict.items()[0]
+ self.assertEqual(str(root.get('key')), str(meta_key))
+ self.assertEqual(root.text.strip(), meta_value)
def test_create(self):
serializer = common.MetadataXMLSerializer()
@@ -434,6 +472,16 @@ class MetadataXMLSerializationTest(test.TestCase):
},
}
output = serializer.serialize(fixture, 'create')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'metadata')
+ metadata_dict = fixture['metadata']
+ metadata_elems = root.findall('{0}meta'.format(NS))
+ self.assertEqual(len(metadata_elems), 3)
+ for i, metadata_elem in enumerate(metadata_elems):
+ (meta_key, meta_value) = metadata_dict.items()[i]
+ self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
+ self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
actual = minidom.parseString(output.replace(" ", ""))
expected = minidom.parseString("""
diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py
index 31443242b..44f4eb055 100644
--- a/nova/tests/api/openstack/test_extensions.py
+++ b/nova/tests/api/openstack/test_extensions.py
@@ -87,6 +87,7 @@ class ExtensionControllerTest(test.TestCase):
self.ext_list = [
"Createserverext",
"FlavorExtraSpecs",
+ "FlavorExtraData",
"Floating_ips",
"Fox In Socks",
"Hosts",
diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py
index 812bece42..348042bfe 100644
--- a/nova/tests/api/openstack/test_flavors.py
+++ b/nova/tests/api/openstack/test_flavors.py
@@ -17,16 +17,21 @@
import json
import webob
-import xml.dom.minidom as minidom
+from lxml import etree
from nova.api.openstack import flavors
import nova.db.api
from nova import exception
from nova import test
+from nova.api.openstack import xmlutil
from nova.tests.api.openstack import fakes
from nova import wsgi
+NS = "{http://docs.openstack.org/compute/api/v1.1}"
+ATOMNS = "{http://www.w3.org/2005/Atom}"
+
+
def stub_flavor(flavorid, name, memory_mb="256", local_gb="10"):
return {
"flavorid": str(flavorid),
@@ -107,12 +112,20 @@ class FlavorsTest(test.TestCase):
"name": "flavor 1",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
},
{
"id": "2",
"name": "flavor 2",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
},
]
self.assertEqual(flavors, expected)
@@ -127,6 +140,10 @@ class FlavorsTest(test.TestCase):
"name": "flavor 12",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
}
self.assertEqual(flavor, expected)
@@ -149,6 +166,10 @@ class FlavorsTest(test.TestCase):
"name": "flavor 12",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -216,6 +237,10 @@ class FlavorsTest(test.TestCase):
"name": "flavor 1",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -232,6 +257,10 @@ class FlavorsTest(test.TestCase):
"name": "flavor 2",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -262,15 +291,50 @@ class FlavorsTest(test.TestCase):
class FlavorsXMLSerializationTest(test.TestCase):
+ def test_xml_declaration(self):
+ serializer = flavors.FlavorXMLSerializer()
+
+ fixture = {
+ "flavor": {
+ "id": "12",
+ "name": "asdf",
+ "ram": "256",
+ "disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
+ "links": [
+ {
+ "rel": "self",
+ "href": "http://localhost/v1.1/fake/flavors/12",
+ },
+ {
+ "rel": "bookmark",
+ "href": "http://localhost/fake/flavors/12",
+ },
+ ],
+ },
+ }
+
+ output = serializer.serialize(fixture, 'show')
+ print output
+ has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
+ self.assertTrue(has_dec)
+
def test_show(self):
serializer = flavors.FlavorXMLSerializer()
- input = {
+ fixture = {
"flavor": {
"id": "12",
"name": "asdf",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -284,34 +348,34 @@ class FlavorsXMLSerializationTest(test.TestCase):
},
}
- output = serializer.serialize(input, 'show')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <flavor xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom"
- id="12"
- name="asdf"
- ram="256"
- disk="10">
- <atom:link href="http://localhost/v1.1/fake/flavors/12"
- rel="self"/>
- <atom:link href="http://localhost/fake/flavors/12"
- rel="bookmark"/>
- </flavor>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ output = serializer.serialize(fixture, 'show')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'flavor')
+ flavor_dict = fixture['flavor']
+
+ for key in ['name', 'id', 'ram', 'disk']:
+ self.assertEqual(root.get(key), str(flavor_dict[key]))
+
+ link_nodes = root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(flavor_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_show_handles_integers(self):
serializer = flavors.FlavorXMLSerializer()
- input = {
+ fixture = {
"flavor": {
"id": 12,
"name": "asdf",
"ram": 256,
"disk": 10,
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -325,35 +389,35 @@ class FlavorsXMLSerializationTest(test.TestCase):
},
}
- output = serializer.serialize(input, 'show')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <flavor xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom"
- id="12"
- name="asdf"
- ram="256"
- disk="10">
- <atom:link href="http://localhost/v1.1/fake/flavors/12"
- rel="self"/>
- <atom:link href="http://localhost/fake/flavors/12"
- rel="bookmark"/>
- </flavor>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ output = serializer.serialize(fixture, 'show')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'flavor')
+ flavor_dict = fixture['flavor']
+
+ for key in ['name', 'id', 'ram', 'disk']:
+ self.assertEqual(root.get(key), str(flavor_dict[key]))
+
+ link_nodes = root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(flavor_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_detail(self):
serializer = flavors.FlavorXMLSerializer()
- input = {
+ fixture = {
"flavors": [
{
"id": "23",
"name": "flavor 23",
"ram": "512",
"disk": "20",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -369,6 +433,10 @@ class FlavorsXMLSerializationTest(test.TestCase):
"name": "flavor 13",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -383,45 +451,38 @@ class FlavorsXMLSerializationTest(test.TestCase):
],
}
- output = serializer.serialize(input, 'detail')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <flavors xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom">
- <flavor id="23"
- name="flavor 23"
- ram="512"
- disk="20">
- <atom:link href="http://localhost/v1.1/fake/flavors/23"
- rel="self"/>
- <atom:link href="http://localhost/fake/flavors/23"
- rel="bookmark"/>
- </flavor>
- <flavor id="13"
- name="flavor 13"
- ram="256"
- disk="10">
- <atom:link href="http://localhost/v1.1/fake/flavors/13"
- rel="self"/>
- <atom:link href="http://localhost/fake/flavors/13"
- rel="bookmark"/>
- </flavor>
- </flavors>
- """.replace(" ", "") % locals())
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ output = serializer.serialize(fixture, 'detail')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'flavors')
+ flavor_elems = root.findall('{0}flavor'.format(NS))
+ self.assertEqual(len(flavor_elems), 2)
+ for i, flavor_elem in enumerate(flavor_elems):
+ flavor_dict = fixture['flavors'][i]
+
+ for key in ['name', 'id', 'ram', 'disk']:
+ self.assertEqual(flavor_elem.get(key), str(flavor_dict[key]))
+
+ link_nodes = flavor_elem.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(flavor_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_index(self):
serializer = flavors.FlavorXMLSerializer()
- input = {
+ fixture = {
"flavors": [
{
"id": "23",
"name": "flavor 23",
"ram": "512",
"disk": "20",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -437,6 +498,10 @@ class FlavorsXMLSerializationTest(test.TestCase):
"name": "flavor 13",
"ram": "256",
"disk": "10",
+ "rxtx_cap": "",
+ "rxtx_quota": "",
+ "swap": "",
+ "vcpus": "",
"links": [
{
"rel": "self",
@@ -451,42 +516,34 @@ class FlavorsXMLSerializationTest(test.TestCase):
],
}
- output = serializer.serialize(input, 'index')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <flavors xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom">
- <flavor id="23" name="flavor 23">
- <atom:link href="http://localhost/v1.1/fake/flavors/23"
- rel="self"/>
- <atom:link href="http://localhost/fake/flavors/23"
- rel="bookmark"/>
- </flavor>
- <flavor id="13" name="flavor 13">
- <atom:link href="http://localhost/v1.1/fake/flavors/13"
- rel="self"/>
- <atom:link href="http://localhost/fake/flavors/13"
- rel="bookmark"/>
- </flavor>
- </flavors>
- """.replace(" ", "") % locals())
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ output = serializer.serialize(fixture, 'index')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'flavors_index')
+ flavor_elems = root.findall('{0}flavor'.format(NS))
+ self.assertEqual(len(flavor_elems), 2)
+ for i, flavor_elem in enumerate(flavor_elems):
+ flavor_dict = fixture['flavors'][i]
+
+ for key in ['name', 'id']:
+ self.assertEqual(flavor_elem.get(key), str(flavor_dict[key]))
+
+ link_nodes = flavor_elem.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(flavor_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_index_empty(self):
serializer = flavors.FlavorXMLSerializer()
- input = {
+ fixture = {
"flavors": [],
}
- output = serializer.serialize(input, 'index')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <flavors xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom" />
- """.replace(" ", "") % locals())
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ output = serializer.serialize(fixture, 'index')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'flavors_index')
+ flavor_elems = root.findall('{0}flavor'.format(NS))
+ self.assertEqual(len(flavor_elems), 0)
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 7759b52ef..e5fd4764a 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -24,6 +24,7 @@ import copy
import json
import xml.dom.minidom as minidom
+from lxml import etree
import mox
import stubout
import webob
@@ -31,10 +32,13 @@ import webob
from nova import context
import nova.api.openstack
from nova.api.openstack import images
+from nova.api.openstack import xmlutil
from nova import test
from nova.tests.api.openstack import fakes
+NS = "{http://docs.openstack.org/compute/api/v1.1}"
+ATOMNS = "{http://www.w3.org/2005/Atom}"
NOW_API_FORMAT = "2010-10-11T10:30:22Z"
@@ -73,14 +77,14 @@ class ImagesTest(test.TestCase):
response_dict = json.loads(response.body)
response_list = response_dict["images"]
- expected = [{'id': '123', 'name': 'public image'},
- {'id': '124', 'name': 'queued snapshot'},
- {'id': '125', 'name': 'saving snapshot'},
- {'id': '126', 'name': 'active snapshot'},
- {'id': '127', 'name': 'killed snapshot'},
- {'id': '128', 'name': 'deleted snapshot'},
- {'id': '129', 'name': 'pending_delete snapshot'},
- {'id': '130', 'name': None}]
+ expected = [{'id': 123, 'name': 'public image'},
+ {'id': 124, 'name': 'queued snapshot'},
+ {'id': 125, 'name': 'saving snapshot'},
+ {'id': 126, 'name': 'active snapshot'},
+ {'id': 127, 'name': 'killed snapshot'},
+ {'id': 128, 'name': 'deleted snapshot'},
+ {'id': 129, 'name': 'pending_delete snapshot'},
+ {'id': 130, 'name': None}]
self.assertDictListMatch(response_list, expected)
@@ -95,7 +99,7 @@ class ImagesTest(test.TestCase):
expected_image = {
"image": {
- "id": "123",
+ "id": 123,
"name": "public image",
"updated": NOW_API_FORMAT,
"created": NOW_API_FORMAT,
@@ -127,7 +131,7 @@ class ImagesTest(test.TestCase):
"status": "SAVING",
"progress": 0,
'server': {
- 'id': 42,
+ 'id': '42',
"links": [{
"rel": "self",
"href": server_href,
@@ -220,12 +224,10 @@ class ImagesTest(test.TestCase):
expected = minidom.parseString("""
<itemNotFound code="404"
- xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
- <message>
- Image not found.
- </message>
+ xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
+ <message>Image not found.</message>
</itemNotFound>
- """.replace(" ", ""))
+ """.replace(" ", "").replace("\n", ""))
actual = minidom.parseString(response.body.replace(" ", ""))
@@ -257,12 +259,10 @@ class ImagesTest(test.TestCase):
# because the element hasn't changed definition
expected = minidom.parseString("""
<itemNotFound code="404"
- xmlns="http://docs.openstack.org/compute/api/v1.1">
- <message>
- Image not found.
- </message>
+ xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <message>Image not found.</message>
</itemNotFound>
- """.replace(" ", ""))
+ """.replace(" ", "").replace("\n", ""))
actual = minidom.parseString(response.body.replace(" ", ""))
@@ -402,7 +402,7 @@ class ImagesTest(test.TestCase):
response_list = response_dict["images"]
expected = [{
- 'id': '123',
+ 'id': 123,
'name': 'public image',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -410,7 +410,7 @@ class ImagesTest(test.TestCase):
'progress': 100,
},
{
- 'id': '124',
+ 'id': 124,
'name': 'queued snapshot',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -418,7 +418,7 @@ class ImagesTest(test.TestCase):
'progress': 0,
},
{
- 'id': '125',
+ 'id': 125,
'name': 'saving snapshot',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -426,7 +426,7 @@ class ImagesTest(test.TestCase):
'progress': 0,
},
{
- 'id': '126',
+ 'id': 126,
'name': 'active snapshot',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -434,7 +434,7 @@ class ImagesTest(test.TestCase):
'progress': 100,
},
{
- 'id': '127',
+ 'id': 127,
'name': 'killed snapshot',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -442,7 +442,7 @@ class ImagesTest(test.TestCase):
'progress': 0,
},
{
- 'id': '128',
+ 'id': 128,
'name': 'deleted snapshot',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -450,7 +450,7 @@ class ImagesTest(test.TestCase):
'progress': 0,
},
{
- 'id': '129',
+ 'id': 129,
'name': 'pending_delete snapshot',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -458,7 +458,7 @@ class ImagesTest(test.TestCase):
'progress': 0,
},
{
- 'id': '130',
+ 'id': 130,
'name': None,
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT,
@@ -507,7 +507,7 @@ class ImagesTest(test.TestCase):
'status': 'SAVING',
'progress': 0,
'server': {
- 'id': 42,
+ 'id': '42',
"links": [{
"rel": "self",
"href": server_href,
@@ -538,7 +538,7 @@ class ImagesTest(test.TestCase):
'status': 'SAVING',
'progress': 0,
'server': {
- 'id': 42,
+ 'id': '42',
"links": [{
"rel": "self",
"href": server_href,
@@ -569,7 +569,7 @@ class ImagesTest(test.TestCase):
'status': 'ACTIVE',
'progress': 100,
'server': {
- 'id': 42,
+ 'id': '42',
"links": [{
"rel": "self",
"href": server_href,
@@ -600,7 +600,7 @@ class ImagesTest(test.TestCase):
'status': 'ERROR',
'progress': 0,
'server': {
- 'id': 42,
+ 'id': '42',
"links": [{
"rel": "self",
"href": server_href,
@@ -631,7 +631,7 @@ class ImagesTest(test.TestCase):
'status': 'DELETED',
'progress': 0,
'server': {
- 'id': 42,
+ 'id': '42',
"links": [{
"rel": "self",
"href": server_href,
@@ -662,7 +662,7 @@ class ImagesTest(test.TestCase):
'status': 'DELETED',
'progress': 0,
'server': {
- 'id': 42,
+ 'id': '42',
"links": [{
"rel": "self",
"href": server_href,
@@ -910,7 +910,7 @@ class ImagesTest(test.TestCase):
app = fakes.wsgi_app(fake_auth_context=self._get_fake_context())
res = req.get_response(app)
image_meta = json.loads(res.body)['image']
- expected = {'id': '123', 'name': 'public image',
+ expected = {'id': 123, 'name': 'public image',
'updated': NOW_API_FORMAT,
'created': NOW_API_FORMAT, 'status': 'ACTIVE',
'progress': 100}
@@ -972,7 +972,7 @@ class ImageXMLSerializationTest(test.TestCase):
IMAGE_HREF = 'http://localhost/v1.1/fake/images/%s'
IMAGE_BOOKMARK = 'http://localhost/fake/images/%s'
- def test_show(self):
+ def test_xml_declaration(self):
serializer = images.ImageXMLSerializer()
fixture = {
@@ -984,7 +984,7 @@ class ImageXMLSerializationTest(test.TestCase):
'status': 'ACTIVE',
'progress': 80,
'server': {
- 'id': 1,
+ 'id': '1',
'links': [
{
'href': self.SERVER_HREF,
@@ -1013,37 +1013,80 @@ class ImageXMLSerializationTest(test.TestCase):
}
output = serializer.serialize(fixture, 'show')
- actual = minidom.parseString(output.replace(" ", ""))
+ print output
+ has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
+ self.assertTrue(has_dec)
- expected_server_href = self.SERVER_HREF
- expected_server_bookmark = self.SERVER_BOOKMARK
- expected_href = self.IMAGE_HREF % 1
- expected_bookmark = self.IMAGE_BOOKMARK % 1
- expected_now = self.TIMESTAMP
- expected = minidom.parseString("""
- <image id="1"
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom"
- name="Image1"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="ACTIVE"
- progress="80">
- <server id="1">
- <atom:link rel="self" href="%(expected_server_href)s"/>
- <atom:link rel="bookmark" href="%(expected_server_bookmark)s"/>
- </server>
- <metadata>
- <meta key="key1">
- value1
- </meta>
- </metadata>
- <atom:link href="%(expected_href)s" rel="self"/>
- <atom:link href="%(expected_bookmark)s" rel="bookmark"/>
- </image>
- """.replace(" ", "") % (locals()))
+ def test_show(self):
+ serializer = images.ImageXMLSerializer()
- self.assertEqual(expected.toxml(), actual.toxml())
+ fixture = {
+ 'image': {
+ 'id': 1,
+ 'name': 'Image1',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'status': 'ACTIVE',
+ 'progress': 80,
+ 'server': {
+ 'id': '1',
+ 'links': [
+ {
+ 'href': self.SERVER_HREF,
+ 'rel': 'self',
+ },
+ {
+ 'href': self.SERVER_BOOKMARK,
+ 'rel': 'bookmark',
+ },
+ ],
+ },
+ 'metadata': {
+ 'key1': 'value1',
+ },
+ 'links': [
+ {
+ 'href': self.IMAGE_HREF % 1,
+ 'rel': 'self',
+ },
+ {
+ 'href': self.IMAGE_BOOKMARK % 1,
+ 'rel': 'bookmark',
+ },
+ ],
+ },
+ }
+
+ output = serializer.serialize(fixture, 'show')
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'image')
+ image_dict = fixture['image']
+
+ for key in ['name', 'id', 'updated', 'created', 'status', 'progress']:
+ self.assertEqual(root.get(key), str(image_dict[key]))
+
+ link_nodes = root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
+
+ metadata_root = root.find('{0}metadata'.format(NS))
+ metadata_elems = metadata_root.findall('{0}meta'.format(NS))
+ self.assertEqual(len(metadata_elems), 1)
+ for i, metadata_elem in enumerate(metadata_elems):
+ (meta_key, meta_value) = image_dict['metadata'].items()[i]
+ self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
+ self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
+
+ server_root = root.find('{0}server'.format(NS))
+ self.assertEqual(server_root.get('id'), image_dict['server']['id'])
+ link_nodes = server_root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['server']['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_show_zero_metadata(self):
serializer = images.ImageXMLSerializer()
@@ -1056,7 +1099,7 @@ class ImageXMLSerializationTest(test.TestCase):
'updated': self.TIMESTAMP,
'status': 'ACTIVE',
'server': {
- 'id': 1,
+ 'id': '1',
'links': [
{
'href': self.SERVER_HREF,
@@ -1083,31 +1126,31 @@ class ImageXMLSerializationTest(test.TestCase):
}
output = serializer.serialize(fixture, 'show')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected_server_href = self.SERVER_HREF
- expected_server_bookmark = self.SERVER_BOOKMARK
- expected_href = self.IMAGE_HREF % 1
- expected_bookmark = self.IMAGE_BOOKMARK % 1
- expected_now = self.TIMESTAMP
- expected = minidom.parseString("""
- <image id="1"
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom"
- name="Image1"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="ACTIVE">
- <server id="1">
- <atom:link rel="self" href="%(expected_server_href)s"/>
- <atom:link rel="bookmark" href="%(expected_server_bookmark)s"/>
- </server>
- <atom:link href="%(expected_href)s" rel="self"/>
- <atom:link href="%(expected_bookmark)s" rel="bookmark"/>
- </image>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'image')
+ image_dict = fixture['image']
+
+ for key in ['name', 'id', 'updated', 'created', 'status']:
+ self.assertEqual(root.get(key), str(image_dict[key]))
+
+ link_nodes = root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
+
+ metadata_root = root.find('{0}metadata'.format(NS))
+ meta_nodes = root.findall('{0}meta'.format(ATOMNS))
+ self.assertEqual(len(meta_nodes), 0)
+
+ server_root = root.find('{0}server'.format(NS))
+ self.assertEqual(server_root.get('id'), image_dict['server']['id'])
+ link_nodes = server_root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['server']['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_show_image_no_metadata_key(self):
serializer = images.ImageXMLSerializer()
@@ -1120,7 +1163,7 @@ class ImageXMLSerializationTest(test.TestCase):
'updated': self.TIMESTAMP,
'status': 'ACTIVE',
'server': {
- 'id': 1,
+ 'id': '1',
'links': [
{
'href': self.SERVER_HREF,
@@ -1146,31 +1189,31 @@ class ImageXMLSerializationTest(test.TestCase):
}
output = serializer.serialize(fixture, 'show')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected_server_href = self.SERVER_HREF
- expected_server_bookmark = self.SERVER_BOOKMARK
- expected_href = self.IMAGE_HREF % 1
- expected_bookmark = self.IMAGE_BOOKMARK % 1
- expected_now = self.TIMESTAMP
- expected = minidom.parseString("""
- <image id="1"
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom"
- name="Image1"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="ACTIVE">
- <server id="1">
- <atom:link rel="self" href="%(expected_server_href)s"/>
- <atom:link rel="bookmark" href="%(expected_server_bookmark)s"/>
- </server>
- <atom:link href="%(expected_href)s" rel="self"/>
- <atom:link href="%(expected_bookmark)s" rel="bookmark"/>
- </image>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'image')
+ image_dict = fixture['image']
+
+ for key in ['name', 'id', 'updated', 'created', 'status']:
+ self.assertEqual(root.get(key), str(image_dict[key]))
+
+ link_nodes = root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
+
+ metadata_root = root.find('{0}metadata'.format(NS))
+ meta_nodes = root.findall('{0}meta'.format(ATOMNS))
+ self.assertEqual(len(meta_nodes), 0)
+
+ server_root = root.find('{0}server'.format(NS))
+ self.assertEqual(server_root.get('id'), image_dict['server']['id'])
+ link_nodes = server_root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['server']['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_show_no_server(self):
serializer = images.ImageXMLSerializer()
@@ -1199,30 +1242,30 @@ class ImageXMLSerializationTest(test.TestCase):
}
output = serializer.serialize(fixture, 'show')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected_href = self.IMAGE_HREF % 1
- expected_bookmark = self.IMAGE_BOOKMARK % 1
- expected_now = self.TIMESTAMP
- expected = minidom.parseString("""
- <image id="1"
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom"
- name="Image1"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="ACTIVE">
- <metadata>
- <meta key="key1">
- value1
- </meta>
- </metadata>
- <atom:link href="%(expected_href)s" rel="self"/>
- <atom:link href="%(expected_bookmark)s" rel="bookmark"/>
- </image>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'image')
+ image_dict = fixture['image']
+
+ for key in ['name', 'id', 'updated', 'created', 'status']:
+ self.assertEqual(root.get(key), str(image_dict[key]))
+
+ link_nodes = root.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
+
+ metadata_root = root.find('{0}metadata'.format(NS))
+ metadata_elems = metadata_root.findall('{0}meta'.format(NS))
+ self.assertEqual(len(metadata_elems), 1)
+ for i, metadata_elem in enumerate(metadata_elems):
+ (meta_key, meta_value) = image_dict['metadata'].items()[i]
+ self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
+ self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
+
+ server_root = root.find('{0}server'.format(NS))
+ self.assertEqual(server_root, None)
def test_index(self):
serializer = images.ImageXMLSerializer()
@@ -1237,6 +1280,10 @@ class ImageXMLSerializationTest(test.TestCase):
'href': self.IMAGE_HREF % 1,
'rel': 'self',
},
+ {
+ 'href': self.IMAGE_BOOKMARK % 1,
+ 'rel': 'bookmark',
+ },
],
},
{
@@ -1247,35 +1294,32 @@ class ImageXMLSerializationTest(test.TestCase):
'href': self.IMAGE_HREF % 2,
'rel': 'self',
},
+ {
+ 'href': self.IMAGE_BOOKMARK % 2,
+ 'rel': 'bookmark',
+ },
],
},
]
}
output = serializer.serialize(fixture, 'index')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected_server_href = self.SERVER_HREF
- expected_server_bookmark = self.SERVER_BOOKMARK
- expected_href = self.IMAGE_HREF % 1
- expected_bookmark = self.IMAGE_BOOKMARK % 1
- expected_href_two = self.IMAGE_HREF % 2
- expected_bookmark_two = self.IMAGE_BOOKMARK % 2
- expected_now = self.TIMESTAMP
- expected = minidom.parseString("""
- <images
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom">
- <image id="1" name="Image1">
- <atom:link href="%(expected_href)s" rel="self"/>
- </image>
- <image id="2" name="Image2">
- <atom:link href="%(expected_href_two)s" rel="self"/>
- </image>
- </images>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'images_index')
+ image_elems = root.findall('{0}image'.format(NS))
+ self.assertEqual(len(image_elems), 2)
+ for i, image_elem in enumerate(image_elems):
+ image_dict = fixture['images'][i]
+
+ for key in ['name', 'id']:
+ self.assertEqual(image_elem.get(key), str(image_dict[key]))
+
+ link_nodes = image_elem.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
def test_index_zero_images(self):
serializer = images.ImageXMLSerializer()
@@ -1285,15 +1329,11 @@ class ImageXMLSerializationTest(test.TestCase):
}
output = serializer.serialize(fixtures, 'index')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <images
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom" />
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'images_index')
+ image_elems = root.findall('{0}image'.format(NS))
+ self.assertEqual(len(image_elems), 0)
def test_detail(self):
serializer = images.ImageXMLSerializer()
@@ -1307,7 +1347,7 @@ class ImageXMLSerializationTest(test.TestCase):
'updated': self.TIMESTAMP,
'status': 'ACTIVE',
'server': {
- 'id': 1,
+ 'id': '1',
'links': [
{
'href': self.SERVER_HREF,
@@ -1331,7 +1371,7 @@ class ImageXMLSerializationTest(test.TestCase):
],
},
{
- 'id': 2,
+ 'id': '2',
'name': 'Image2',
'created': self.TIMESTAMP,
'updated': self.TIMESTAMP,
@@ -1355,46 +1395,22 @@ class ImageXMLSerializationTest(test.TestCase):
}
output = serializer.serialize(fixture, 'detail')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected_server_href = self.SERVER_HREF
- expected_server_bookmark = self.SERVER_BOOKMARK
- expected_href = self.IMAGE_HREF % 1
- expected_bookmark = self.IMAGE_BOOKMARK % 1
- expected_href_two = self.IMAGE_HREF % 2
- expected_bookmark_two = self.IMAGE_BOOKMARK % 2
- expected_now = self.TIMESTAMP
- expected = minidom.parseString("""
- <images
- xmlns="http://docs.openstack.org/compute/api/v1.1"
- xmlns:atom="http://www.w3.org/2005/Atom">
- <image id="1"
- name="Image1"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="ACTIVE">
- <server id="1">
- <atom:link rel="self" href="%(expected_server_href)s"/>
- <atom:link rel="bookmark" href="%(expected_server_bookmark)s"/>
- </server>
- <atom:link href="%(expected_href)s" rel="self"/>
- <atom:link href="%(expected_bookmark)s" rel="bookmark"/>
- </image>
- <image id="2"
- name="Image2"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="SAVING"
- progress="80">
- <metadata>
- <meta key="key1">
- value1
- </meta>
- </metadata>
- <atom:link href="%(expected_href_two)s" rel="self"/>
- <atom:link href="%(expected_bookmark_two)s" rel="bookmark"/>
- </image>
- </images>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'images')
+ image_elems = root.findall('{0}image'.format(NS))
+ self.assertEqual(len(image_elems), 2)
+ for i, image_elem in enumerate(image_elems):
+ image_dict = fixture['images'][i]
+
+ for key in ['name', 'id', 'updated', 'created', 'status']:
+ self.assertEqual(image_elem.get(key), str(image_dict[key]))
+
+ link_nodes = image_elem.findall('{0}link'.format(ATOMNS))
+ self.assertEqual(len(link_nodes), 2)
+ for i, link in enumerate(image_dict['links']):
+ for key, value in link.items():
+ self.assertEqual(link_nodes[i].get(key), value)
+
+ metadata_root = image_elem.find('{0}metadata'.format(NS))
+ metadata_elems = metadata_root.findall('{0}meta'.format(NS))
diff --git a/nova/tests/api/openstack/test_limits.py b/nova/tests/api/openstack/test_limits.py
index 801b06230..6f0210c27 100644
--- a/nova/tests/api/openstack/test_limits.py
+++ b/nova/tests/api/openstack/test_limits.py
@@ -19,6 +19,7 @@ Tests dealing with HTTP rate-limiting.
import httplib
import json
+from lxml import etree
import StringIO
import stubout
import time
@@ -29,6 +30,7 @@ from xml.dom import minidom
import nova.context
from nova.api.openstack import limits
from nova.api.openstack import views
+from nova.api.openstack import xmlutil
from nova import test
@@ -39,6 +41,10 @@ TEST_LIMITS = [
limits.Limit("PUT", "*", "", 10, limits.PER_MINUTE),
limits.Limit("PUT", "/servers", "^/servers", 5, limits.PER_MINUTE),
]
+NS = {
+ 'atom': 'http://www.w3.org/2005/Atom',
+ 'ns': 'http://docs.openstack.org/compute/api/v1.1'
+}
class BaseLimitTestSuite(unittest.TestCase):
@@ -168,12 +174,11 @@ class LimitsControllerV10Test(BaseLimitTestSuite):
response = request.get_response(self.controller)
expected = minidom.parseString("""
- <limits
- xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
+ <limits xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
<rate/>
<absolute/>
</limits>
- """.replace(" ", ""))
+ """.replace(" ", "").replace("\n", ""))
body = minidom.parseString(response.body.replace(" ", ""))
@@ -186,17 +191,16 @@ class LimitsControllerV10Test(BaseLimitTestSuite):
response = request.get_response(self.controller)
expected = minidom.parseString("""
- <limits
- xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
+ <limits xmlns="http://docs.rackspacecloud.com/servers/api/v1.0">
<rate>
<limit URI="*" regex=".*" remaining="10" resetTime="0"
- unit="MINUTE" value="10" verb="GET"/>
+ unit="MINUTE" value="10" verb="GET"/>
<limit URI="*" regex=".*" remaining="5" resetTime="0"
- unit="HOUR" value="5" verb="POST"/>
+ unit="HOUR" value="5" verb="POST"/>
</rate>
<absolute/>
</limits>
- """.replace(" ", ""))
+ """.replace(" ", "").replace("\n", ""))
body = minidom.parseString(response.body.replace(" ", ""))
self.assertEqual(expected.toxml(), body.toxml())
@@ -980,9 +984,22 @@ class LimitsXMLSerializationTest(test.TestCase):
def tearDown(self):
pass
- def test_index(self):
+ def test_xml_declaration(self):
serializer = limits.LimitsXMLSerializer()
+
fixture = {"limits": {
+ "rate": [],
+ "absolute": {}}}
+
+ output = serializer.serialize(fixture, 'index')
+ print output
+ has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
+ self.assertTrue(has_dec)
+
+ def test_index(self):
+ serializer = limits.LimitsXMLSerializer()
+ fixture = {
+ "limits": {
"rate": [{
"uri": "*",
"regex": ".*",
@@ -1006,32 +1023,32 @@ class LimitsXMLSerializationTest(test.TestCase):
"maxPersonalitySize": 10240}}}
output = serializer.serialize(fixture, 'index')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <limits xmlns="http://docs.openstack.org/compute/api/v1.1">
- <rates>
- <rate uri="*" regex=".*">
- <limit value="10" verb="POST" remaining="2"
- unit="MINUTE"
- next-available="2011-12-15T22:42:45Z"/>
- </rate>
- <rate uri="*/servers" regex="^/servers">
- <limit value="50" verb="POST" remaining="10"
- unit="DAY"
- next-available="2011-12-15T22:42:45Z"/>
- </rate>
- </rates>
- <absolute>
- <limit name="maxServerMeta" value="1"/>
- <limit name="maxPersonality" value="5"/>
- <limit name="maxImageMeta" value="1"/>
- <limit name="maxPersonalitySize" value="10240"/>
- </absolute>
- </limits>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'limits')
+
+ #verify absolute limits
+ absolutes = root.xpath('ns:absolute/ns:limit', namespaces=NS)
+ self.assertEqual(len(absolutes), 4)
+ for limit in absolutes:
+ name = limit.get('name')
+ value = limit.get('value')
+ self.assertEqual(value, str(fixture['limits']['absolute'][name]))
+
+ #verify rate limits
+ rates = root.xpath('ns:rates/ns:rate', namespaces=NS)
+ self.assertEqual(len(rates), 2)
+ for i, rate in enumerate(rates):
+ for key in ['uri', 'regex']:
+ self.assertEqual(rate.get(key),
+ str(fixture['limits']['rate'][i][key]))
+ rate_limits = rate.xpath('ns:limit', namespaces=NS)
+ self.assertEqual(len(rate_limits), 1)
+ for j, limit in enumerate(rate_limits):
+ for key in ['verb', 'value', 'remaining', 'unit',
+ 'next-available']:
+ self.assertEqual(limit.get(key),
+ str(fixture['limits']['rate'][i]['limit'][j][key]))
def test_index_no_limits(self):
serializer = limits.LimitsXMLSerializer()
@@ -1041,13 +1058,14 @@ class LimitsXMLSerializationTest(test.TestCase):
"absolute": {}}}
output = serializer.serialize(fixture, 'index')
- actual = minidom.parseString(output.replace(" ", ""))
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'limits')
- expected = minidom.parseString("""
- <limits xmlns="http://docs.openstack.org/compute/api/v1.1">
- <rates />
- <absolute />
- </limits>
- """.replace(" ", ""))
+ #verify absolute limits
+ absolutes = root.xpath('ns:absolute/ns:limit', namespaces=NS)
+ self.assertEqual(len(absolutes), 0)
- self.assertEqual(expected.toxml(), actual.toxml())
+ #verify rate limits
+ rates = root.xpath('ns:rates/ns:rate', namespaces=NS)
+ self.assertEqual(len(rates), 0)
diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py
index f6e45e9c7..251b5d126 100644
--- a/nova/tests/api/openstack/test_server_actions.py
+++ b/nova/tests/api/openstack/test_server_actions.py
@@ -623,7 +623,8 @@ class ServerActionsTestV11(test.TestCase):
self.assertEqual(res.status_int, 202)
body = json.loads(res.body)
self.assertEqual(body['server']['image']['id'], '2')
- self.assertEqual(len(body['server']['adminPass']), 16)
+ self.assertEqual(len(body['server']['adminPass']),
+ FLAGS.password_length)
def test_server_rebuild_rejected_when_building(self):
body = {
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index f654bf209..f7e08118f 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -28,6 +28,7 @@ import webob
from nova import context
from nova import db
from nova import exception
+from nova import flags
from nova import test
from nova import utils
import nova.api.openstack
@@ -49,9 +50,14 @@ from nova.tests.api.openstack import common
from nova.tests.api.openstack import fakes
+FLAGS = flags.FLAGS
FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
NS = "{http://docs.openstack.org/compute/api/v1.1}"
ATOMNS = "{http://www.w3.org/2005/Atom}"
+XPATH_NS = {
+ 'atom': 'http://www.w3.org/2005/Atom',
+ 'ns': 'http://docs.openstack.org/compute/api/v1.1'
+}
def fake_gen_uuid():
@@ -413,12 +419,7 @@ class ServersTest(test.TestCase):
def test_get_server_by_id_v1_1_xml(self):
image_bookmark = "http://localhost/fake/images/10"
- flavor_ref = "http://localhost/v1.1/fake/flavors/1"
- flavor_id = "1"
flavor_bookmark = "http://localhost/fake/flavors/1"
- server_href = "http://localhost/v1.1/fake/servers/1"
- server_bookmark = "http://localhost/fake/servers/1"
-
public_ip = '192.168.0.3'
private_ip = '172.19.0.1'
interfaces = [
@@ -442,50 +443,88 @@ class ServersTest(test.TestCase):
req = webob.Request.blank('/v1.1/fake/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"
- userId="fake"
- tenantId="fake"
- 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"
- accessIPv4=""
- accessIPv6=""
- 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())
+ output = res.body
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'server')
+
+ expected = {
+ 'id': 1,
+ 'uuid': FAKE_UUID,
+ 'user_id': 'fake',
+ 'tenant_id': 'fake',
+ 'updated': '2010-11-11T11:00:00Z',
+ 'created': '2010-10-10T12:00:00Z',
+ 'progress': 0,
+ 'name': 'server1',
+ 'status': 'BUILD',
+ 'accessIPv4': '',
+ 'accessIPv6': '',
+ 'hostId': '',
+ 'key_name': '',
+ 'image': {
+ 'id': '10',
+ 'links': [{'rel': 'bookmark', 'href': image_bookmark}],
+ },
+ 'flavor': {
+ 'id': '1',
+ 'links': [{'rel': 'bookmark', 'href': flavor_bookmark}],
+ },
+ 'addresses': {
+ 'public': [{'version': 4, 'addr': public_ip}],
+ 'private': [{'version': 4, 'addr': private_ip}],
+ },
+ 'metadata': {'seq': '1'},
+ 'config_drive': None,
+ 'links': [
+ {
+ 'rel': 'self',
+ 'href': 'http://localhost/v1.1/fake/servers/1',
+ },
+ {
+ 'rel': 'bookmark',
+ 'href': 'http://localhost/fake/servers/1',
+ },
+ ],
+ }
+
+ self.assertTrue(root.xpath('/ns:server', namespaces=XPATH_NS))
+ for key in ['id', 'uuid', 'created', 'progress', 'name', 'status',
+ 'accessIPv4', 'accessIPv6', 'hostId']:
+ self.assertEqual(root.get(key), str(expected[key]))
+ self.assertEqual(root.get('userId'), str(expected['user_id']))
+ self.assertEqual(root.get('tenantId'), str(expected['tenant_id']))
+
+ (image,) = root.xpath('ns:image', namespaces=XPATH_NS)
+ self.assertEqual(image.get('id'), str(expected['image']['id']))
+
+ links = root.xpath('ns:image/atom:link', namespaces=XPATH_NS)
+ self.assertTrue(common.compare_links(links,
+ expected['image']['links']))
+
+ (flavor,) = root.xpath('ns:flavor', namespaces=XPATH_NS)
+ self.assertEqual(flavor.get('id'), str(expected['flavor']['id']))
+
+ (meta,) = root.xpath('ns:metadata/ns:meta', namespaces=XPATH_NS)
+ self.assertEqual(meta.get('key'), 'seq')
+ self.assertEqual(meta.text, '1')
+
+ (pub_network, priv_network) = root.xpath('ns:addresses/ns:network',
+ namespaces=XPATH_NS)
+ self.assertEqual(pub_network.get('id'), 'public')
+ (pub_ip,) = pub_network.xpath('ns:ip', namespaces=XPATH_NS)
+ (priv_ip,) = priv_network.xpath('ns:ip', namespaces=XPATH_NS)
+ self.assertEqual(pub_ip.get('version'),
+ str(expected['addresses']['public'][0]['version']))
+ self.assertEqual(pub_ip.get('addr'),
+ str(expected['addresses']['public'][0]['addr']))
+ self.assertEqual(priv_ip.get('version'),
+ str(expected['addresses']['private'][0]['version']))
+ self.assertEqual(priv_ip.get('addr'),
+ str(expected['addresses']['private'][0]['addr']))
+
+ links = root.xpath('atom:link', namespaces=XPATH_NS)
+ self.assertTrue(common.compare_links(links, expected['links']))
def test_get_server_with_active_status_by_id_v1_1(self):
image_bookmark = "http://localhost/fake/images/10"
@@ -1541,7 +1580,7 @@ class ServersTest(test.TestCase):
self.assertEqual(res.status_int, 202)
server = json.loads(res.body)['server']
- self.assertEqual(16, len(server['adminPass']))
+ self.assertEqual(FLAGS.password_length, len(server['adminPass']))
self.assertEqual('server_test', server['name'])
self.assertEqual(1, server['id'])
self.assertEqual(2, server['flavorId'])
@@ -1742,7 +1781,7 @@ class ServersTest(test.TestCase):
self.assertEqual(res.status_int, 202)
server = json.loads(res.body)['server']
- self.assertEqual(16, len(server['adminPass']))
+ self.assertEqual(FLAGS.password_length, len(server['adminPass']))
self.assertEqual(1, server['id'])
self.assertEqual(0, server['progress'])
self.assertEqual('server_test', server['name'])
@@ -1802,7 +1841,7 @@ class ServersTest(test.TestCase):
self.assertEqual(res.status_int, 202)
server = json.loads(res.body)['server']
- self.assertEqual(16, len(server['adminPass']))
+ self.assertEqual(FLAGS.password_length, len(server['adminPass']))
self.assertEqual(1, server['id'])
self.assertEqual("BUILD", server["status"])
self.assertEqual(0, server['progress'])
@@ -2513,9 +2552,8 @@ class ServersTest(test.TestCase):
self.assertEqual(res.status, '202 Accepted')
self.assertEqual(self.server_delete_called, True)
- def test_rescue_accepted(self):
+ def test_rescue_generates_password(self):
self.flags(allow_admin_api=True)
- body = {}
self.called = False
@@ -2530,7 +2568,33 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(self.called, True)
- self.assertEqual(res.status_int, 202)
+ self.assertEqual(res.status_int, 200)
+ res_body = json.loads(res.body)
+ self.assertTrue('adminPass' in res_body)
+ self.assertEqual(FLAGS.password_length, len(res_body['adminPass']))
+
+ def test_rescue_with_preset_password(self):
+ self.flags(allow_admin_api=True)
+
+ self.called = False
+
+ def rescue_mock(*args, **kwargs):
+ self.called = True
+
+ self.stubs.Set(nova.compute.api.API, 'rescue', rescue_mock)
+ req = webob.Request.blank('/v1.0/servers/1/rescue')
+ req.method = 'POST'
+ body = {"rescue": {"adminPass": "AABBCC112233"}}
+ req.body = json.dumps(body)
+ req.content_type = 'application/json'
+
+ res = req.get_response(fakes.wsgi_app())
+
+ self.assertEqual(self.called, True)
+ self.assertEqual(res.status_int, 200)
+ res_body = json.loads(res.body)
+ self.assertTrue('adminPass' in res_body)
+ self.assertEqual('AABBCC112233', res_body['adminPass'])
def test_rescue_raises_handled(self):
self.flags(allow_admin_api=True)
@@ -3288,7 +3352,7 @@ class TestAddressesXMLSerialization(test.TestCase):
serializer = nova.api.openstack.ips.IPXMLSerializer()
- def test_show(self):
+ def test_xml_declaration(self):
fixture = {
'network_2': [
{'addr': '192.168.0.1', 'version': 4},
@@ -3296,17 +3360,29 @@ class TestAddressesXMLSerialization(test.TestCase):
],
}
output = self.serializer.serialize(fixture, 'show')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <network xmlns="http://docs.openstack.org/compute/api/v1.1"
- id="network_2">
- <ip version="4" addr="192.168.0.1"/>
- <ip version="6" addr="fe80::beef"/>
- </network>
- """.replace(" ", ""))
+ print output
+ has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
+ self.assertTrue(has_dec)
- self.assertEqual(expected.toxml(), actual.toxml())
+ def test_show(self):
+ fixture = {
+ 'network_2': [
+ {'addr': '192.168.0.1', 'version': 4},
+ {'addr': 'fe80::beef', 'version': 6},
+ ],
+ }
+ output = self.serializer.serialize(fixture, 'show')
+ print output
+ root = etree.XML(output)
+ network = fixture['network_2']
+ self.assertEqual(str(root.get('id')), 'network_2')
+ ip_elems = root.findall('{0}ip'.format(NS))
+ for z, ip_elem in enumerate(ip_elems):
+ ip = network[z]
+ self.assertEqual(str(ip_elem.get('version')),
+ str(ip['version']))
+ self.assertEqual(str(ip_elem.get('addr')),
+ str(ip['addr']))
def test_index(self):
fixture = {
@@ -3322,22 +3398,22 @@ class TestAddressesXMLSerialization(test.TestCase):
},
}
output = self.serializer.serialize(fixture, 'index')
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <addresses xmlns="http://docs.openstack.org/compute/api/v1.1">
- <network id="network_2">
- <ip version="4" addr="192.168.0.1"/>
- <ip version="6" addr="fe80::beef"/>
- </network>
- <network id="network_1">
- <ip version="4" addr="192.168.0.3"/>
- <ip version="4" addr="192.168.0.5"/>
- </network>
- </addresses>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
+ print output
+ root = etree.XML(output)
+ xmlutil.validate_schema(root, 'addresses')
+ addresses_dict = fixture['addresses']
+ network_elems = root.findall('{0}network'.format(NS))
+ self.assertEqual(len(network_elems), 2)
+ for i, network_elem in enumerate(network_elems):
+ network = addresses_dict.items()[i]
+ self.assertEqual(str(network_elem.get('id')), str(network[0]))
+ ip_elems = network_elem.findall('{0}ip'.format(NS))
+ for z, ip_elem in enumerate(ip_elems):
+ ip = network[1][z]
+ self.assertEqual(str(ip_elem.get('version')),
+ str(ip['version']))
+ self.assertEqual(str(ip_elem.get('addr')),
+ str(ip['addr']))
class TestServerInstanceCreation(test.TestCase):
@@ -3575,7 +3651,8 @@ class TestServerInstanceCreation(test.TestCase):
self.assertEquals(response.status_int, 202)
response = json.loads(response.body)
self.assertTrue('adminPass' in response['server'])
- self.assertEqual(16, len(response['server']['adminPass']))
+ self.assertEqual(FLAGS.password_length,
+ len(response['server']['adminPass']))
def test_create_instance_admin_pass_xml(self):
request, response, dummy = \
@@ -3584,7 +3661,8 @@ class TestServerInstanceCreation(test.TestCase):
dom = minidom.parseString(response.body)
server = dom.childNodes[0]
self.assertEquals(server.nodeName, 'server')
- self.assertEqual(16, len(server.getAttribute('adminPass')))
+ self.assertEqual(FLAGS.password_length,
+ len(server.getAttribute('adminPass')))
class TestGetKernelRamdiskFromImage(test.TestCase):
@@ -4064,6 +4142,85 @@ class ServerXMLSerializationTest(test.TestCase):
self.maxDiff = None
test.TestCase.setUp(self)
+ def test_xml_declaration(self):
+ serializer = servers.ServerXMLSerializer()
+
+ fixture = {
+ "server": {
+ 'id': 1,
+ 'uuid': FAKE_UUID,
+ 'user_id': 'fake_user_id',
+ 'tenant_id': 'fake_tenant_id',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ "progress": 0,
+ "name": "test_server",
+ "status": "BUILD",
+ "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
+ "accessIPv4": "1.2.3.4",
+ "accessIPv6": "fead::1234",
+ "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')
+ print output
+ has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
+ self.assertTrue(has_dec)
+
def test_show(self):
serializer = servers.ServerXMLSerializer()
diff --git a/nova/tests/api/openstack/test_versions.py b/nova/tests/api/openstack/test_versions.py
index 1269f13c9..f69dbd316 100644
--- a/nova/tests/api/openstack/test_versions.py
+++ b/nova/tests/api/openstack/test_versions.py
@@ -15,19 +15,24 @@
# License for the specific language governing permissions and limitations
# under the License.
+import feedparser
import json
import stubout
import webob
-import xml.etree.ElementTree
-
+from lxml import etree
from nova import context
from nova import test
-from nova.tests.api.openstack import fakes
from nova.api.openstack import versions
from nova.api.openstack import views
from nova.api.openstack import wsgi
+from nova.tests.api.openstack import common
+from nova.tests.api.openstack import fakes
+NS = {
+ 'atom': 'http://www.w3.org/2005/Atom',
+ 'ns': 'http://docs.openstack.org/compute/api/v1.1'
+}
VERSIONS = {
"v1.0": {
"id": "v1.0",
@@ -113,23 +118,23 @@ class VersionsTest(test.TestCase):
versions = json.loads(res.body)["versions"]
expected = [
{
- "id": "v1.1",
- "status": "CURRENT",
+ "id": "v1.0",
+ "status": "DEPRECATED",
"updated": "2011-01-21T11:33:21Z",
"links": [
{
"rel": "self",
- "href": "http://localhost/v1.1/",
+ "href": "http://localhost/v1.0/",
}],
},
{
- "id": "v1.0",
- "status": "DEPRECATED",
+ "id": "v1.1",
+ "status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"links": [
{
"rel": "self",
- "href": "http://localhost/v1.0/",
+ "href": "http://localhost/v1.1/",
}],
},
]
@@ -233,48 +238,20 @@ class VersionsTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
self.assertEqual(res.content_type, "application/xml")
- root = xml.etree.ElementTree.XML(res.body)
- self.assertEqual(root.tag.split('}')[1], "version")
- self.assertEqual(root.tag.split('}')[0].strip('{'), wsgi.XMLNS_V11)
- children = list(root)
- media_types = children[0]
- media_type_nodes = list(media_types)
- links = (children[1], children[2], children[3])
-
- self.assertEqual(media_types.tag.split('}')[1], 'media-types')
- for media_node in media_type_nodes:
- self.assertEqual(media_node.tag.split('}')[1], 'media-type')
-
- expected = """
- <version id="v1.0" status="DEPRECATED"
- updated="2011-01-21T11:33:21Z"
- xmlns="%s"
- xmlns:atom="http://www.w3.org/2005/Atom">
-
- <media-types>
- <media-type base="application/xml"
- type="application/vnd.openstack.compute-v1.0+xml"/>
- <media-type base="application/json"
- type="application/vnd.openstack.compute-v1.0+json"/>
- </media-types>
-
- <atom:link href="http://localhost/v1.0/"
- rel="self"/>
-
- <atom:link href="http://docs.rackspacecloud.com/servers/
- api/v1.0/cs-devguide-20110125.pdf"
- rel="describedby"
- type="application/pdf"/>
-
- <atom:link href="http://docs.rackspacecloud.com/servers/
- api/v1.0/application.wadl"
- rel="describedby"
- type="application/vnd.sun.wadl+xml"/>
- </version>""".replace(" ", "").replace("\n", "") % wsgi.XMLNS_V11
-
- actual = res.body.replace(" ", "").replace("\n", "")
- self.assertEqual(expected, actual)
+ version = etree.XML(res.body)
+ expected = VERSIONS['v1.0']
+ self.assertTrue(version.xpath('/ns:version', namespaces=NS))
+ media_types = version.xpath('ns:media-types/ns:media-type',
+ namespaces=NS)
+ self.assertTrue(common.compare_media_types(media_types,
+ expected['media-types']))
+ for key in ['id', 'status', 'updated']:
+ self.assertEqual(version.get(key), expected[key])
+ links = version.xpath('atom:link', namespaces=NS)
+ self.assertTrue(common.compare_links(links,
+ [{'rel': 'self', 'href': 'http://localhost/v1.0/'}]
+ + expected['links']))
def test_get_version_1_1_detail_xml(self):
req = webob.Request.blank('/v1.1/')
@@ -282,35 +259,20 @@ class VersionsTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
self.assertEqual(res.content_type, "application/xml")
- expected = """
- <version id="v1.1" status="CURRENT"
- updated="2011-01-21T11:33:21Z"
- xmlns="%s"
- xmlns:atom="http://www.w3.org/2005/Atom">
-
- <media-types>
- <media-type base="application/xml"
- type="application/vnd.openstack.compute-v1.1+xml"/>
- <media-type base="application/json"
- type="application/vnd.openstack.compute-v1.1+json"/>
- </media-types>
-
- <atom:link href="http://localhost/v1.1/"
- rel="self"/>
-
- <atom:link href="http://docs.rackspacecloud.com/servers/
- api/v1.1/cs-devguide-20110125.pdf"
- rel="describedby"
- type="application/pdf"/>
-
- <atom:link href="http://docs.rackspacecloud.com/servers/
- api/v1.1/application.wadl"
- rel="describedby"
- type="application/vnd.sun.wadl+xml"/>
- </version>""".replace(" ", "").replace("\n", "") % wsgi.XMLNS_V11
-
- actual = res.body.replace(" ", "").replace("\n", "")
- self.assertEqual(expected, actual)
+
+ version = etree.XML(res.body)
+ expected = VERSIONS['v1.1']
+ self.assertTrue(version.xpath('/ns:version', namespaces=NS))
+ media_types = version.xpath('ns:media-types/ns:media-type',
+ namespaces=NS)
+ self.assertTrue(common.compare_media_types(media_types,
+ expected['media-types']))
+ for key in ['id', 'status', 'updated']:
+ self.assertEqual(version.get(key), expected[key])
+ links = version.xpath('atom:link', namespaces=NS)
+ self.assertTrue(common.compare_links(links,
+ [{'rel': 'self', 'href': 'http://localhost/v1.1/'}]
+ + expected['links']))
def test_get_version_list_xml(self):
req = webob.Request.blank('/')
@@ -319,21 +281,19 @@ class VersionsTest(test.TestCase):
self.assertEqual(res.status_int, 200)
self.assertEqual(res.content_type, "application/xml")
- expected = """
- <versions xmlns="%s" xmlns:atom="%s">
- <version id="v1.1" status="CURRENT" updated="2011-01-21T11:33:21Z">
- <atom:link href="http://localhost/v1.1/" rel="self"/>
- </version>
- <version id="v1.0" status="DEPRECATED"
- updated="2011-01-21T11:33:21Z">
- <atom:link href="http://localhost/v1.0/" rel="self"/>
- </version>
- </versions>""".replace(" ", "").replace("\n", "") % (wsgi.XMLNS_V11,
- wsgi.XMLNS_ATOM)
+ root = etree.XML(res.body)
+ self.assertTrue(root.xpath('/ns:versions', namespaces=NS))
+ versions = root.xpath('ns:version', namespaces=NS)
+ self.assertEqual(len(versions), 2)
- actual = res.body.replace(" ", "").replace("\n", "")
-
- self.assertEqual(expected, actual)
+ for i, v in enumerate(['v1.0', 'v1.1']):
+ version = versions[i]
+ expected = VERSIONS[v]
+ for key in ['id', 'status', 'updated']:
+ self.assertEqual(version.get(key), expected[key])
+ (link,) = version.xpath('atom:link', namespaces=NS)
+ self.assertTrue(common.compare_links(link,
+ [{'rel': 'self', 'href': 'http://localhost/%s/' % v}]))
def test_get_version_1_0_detail_atom(self):
req = webob.Request.blank('/v1.0/')
@@ -341,36 +301,38 @@ class VersionsTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
self.assertEqual("application/atom+xml", res.content_type)
- expected = """
- <feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">About This Version</title>
- <updated>2011-01-21T11:33:21Z</updated>
- <id>http://localhost/v1.0/</id>
- <author>
- <name>Rackspace</name>
- <uri>http://www.rackspace.com/</uri>
- </author>
- <link href="http://localhost/v1.0/" rel="self"/>
- <entry>
- <id>http://localhost/v1.0/</id>
- <title type="text">Version v1.0</title>
- <updated>2011-01-21T11:33:21Z</updated>
- <link href="http://localhost/v1.0/"
- rel="self"/>
- <link href="http://docs.rackspacecloud.com/servers/
- api/v1.0/cs-devguide-20110125.pdf"
- rel="describedby" type="application/pdf"/>
- <link href="http://docs.rackspacecloud.com/servers/
- api/v1.0/application.wadl"
- rel="describedby" type="application/vnd.sun.wadl+xml"/>
- <content type="text">
- Version v1.0 DEPRECATED (2011-01-21T11:33:21Z)
- </content>
- </entry>
- </feed>""".replace(" ", "").replace("\n", "")
-
- actual = res.body.replace(" ", "").replace("\n", "")
- self.assertEqual(expected, actual)
+
+ f = feedparser.parse(res.body)
+ self.assertEqual(f.feed.title, 'About This Version')
+ self.assertEqual(f.feed.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(f.feed.id, 'http://localhost/v1.0/')
+ self.assertEqual(f.feed.author, 'Rackspace')
+ self.assertEqual(f.feed.author_detail.href,
+ 'http://www.rackspace.com/')
+ self.assertEqual(f.feed.links[0]['href'], 'http://localhost/v1.0/')
+ self.assertEqual(f.feed.links[0]['rel'], 'self')
+
+ self.assertEqual(len(f.entries), 1)
+ entry = f.entries[0]
+ self.assertEqual(entry.id, 'http://localhost/v1.0/')
+ self.assertEqual(entry.title, 'Version v1.0')
+ self.assertEqual(entry.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(len(entry.content), 1)
+ self.assertEqual(entry.content[0].value,
+ 'Version v1.0 DEPRECATED (2011-01-21T11:33:21Z)')
+ self.assertEqual(len(entry.links), 3)
+ self.assertEqual(entry.links[0]['href'], 'http://localhost/v1.0/')
+ self.assertEqual(entry.links[0]['rel'], 'self')
+ self.assertEqual(entry.links[1], {
+ 'href': 'http://docs.rackspacecloud.com/servers/api/v1.0/'\
+ 'cs-devguide-20110125.pdf',
+ 'type': 'application/pdf',
+ 'rel': 'describedby'})
+ self.assertEqual(entry.links[2], {
+ 'href': 'http://docs.rackspacecloud.com/servers/api/v1.0/'\
+ 'application.wadl',
+ 'type': 'application/vnd.sun.wadl+xml',
+ 'rel': 'describedby'})
def test_get_version_1_1_detail_atom(self):
req = webob.Request.blank('/v1.1/')
@@ -378,36 +340,38 @@ class VersionsTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
self.assertEqual("application/atom+xml", res.content_type)
- expected = """
- <feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">About This Version</title>
- <updated>2011-01-21T11:33:21Z</updated>
- <id>http://localhost/v1.1/</id>
- <author>
- <name>Rackspace</name>
- <uri>http://www.rackspace.com/</uri>
- </author>
- <link href="http://localhost/v1.1/" rel="self"/>
- <entry>
- <id>http://localhost/v1.1/</id>
- <title type="text">Version v1.1</title>
- <updated>2011-01-21T11:33:21Z</updated>
- <link href="http://localhost/v1.1/"
- rel="self"/>
- <link href="http://docs.rackspacecloud.com/servers/
- api/v1.1/cs-devguide-20110125.pdf"
- rel="describedby" type="application/pdf"/>
- <link href="http://docs.rackspacecloud.com/servers/
- api/v1.1/application.wadl"
- rel="describedby" type="application/vnd.sun.wadl+xml"/>
- <content type="text">
- Version v1.1 CURRENT (2011-01-21T11:33:21Z)
- </content>
- </entry>
- </feed>""".replace(" ", "").replace("\n", "")
-
- actual = res.body.replace(" ", "").replace("\n", "")
- self.assertEqual(expected, actual)
+
+ f = feedparser.parse(res.body)
+ self.assertEqual(f.feed.title, 'About This Version')
+ self.assertEqual(f.feed.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(f.feed.id, 'http://localhost/v1.1/')
+ self.assertEqual(f.feed.author, 'Rackspace')
+ self.assertEqual(f.feed.author_detail.href,
+ 'http://www.rackspace.com/')
+ self.assertEqual(f.feed.links[0]['href'], 'http://localhost/v1.1/')
+ self.assertEqual(f.feed.links[0]['rel'], 'self')
+
+ self.assertEqual(len(f.entries), 1)
+ entry = f.entries[0]
+ self.assertEqual(entry.id, 'http://localhost/v1.1/')
+ self.assertEqual(entry.title, 'Version v1.1')
+ self.assertEqual(entry.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(len(entry.content), 1)
+ self.assertEqual(entry.content[0].value,
+ 'Version v1.1 CURRENT (2011-01-21T11:33:21Z)')
+ self.assertEqual(len(entry.links), 3)
+ self.assertEqual(entry.links[0]['href'], 'http://localhost/v1.1/')
+ self.assertEqual(entry.links[0]['rel'], 'self')
+ self.assertEqual(entry.links[1], {
+ 'href': 'http://docs.rackspacecloud.com/servers/api/v1.1/'\
+ 'cs-devguide-20110125.pdf',
+ 'type': 'application/pdf',
+ 'rel': 'describedby'})
+ self.assertEqual(entry.links[2], {
+ 'href': 'http://docs.rackspacecloud.com/servers/api/v1.1/'\
+ 'application.wadl',
+ 'type': 'application/vnd.sun.wadl+xml',
+ 'rel': 'describedby'})
def test_get_version_list_atom(self):
req = webob.Request.blank('/')
@@ -416,40 +380,37 @@ class VersionsTest(test.TestCase):
self.assertEqual(res.status_int, 200)
self.assertEqual(res.content_type, "application/atom+xml")
- expected = """
- <feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Available API Versions</title>
- <updated>2011-01-21T11:33:21Z</updated>
- <id>http://localhost/</id>
- <author>
- <name>Rackspace</name>
- <uri>http://www.rackspace.com/</uri>
- </author>
- <link href="http://localhost/" rel="self"/>
- <entry>
- <id>http://localhost/v1.1/</id>
- <title type="text">Version v1.1</title>
- <updated>2011-01-21T11:33:21Z</updated>
- <link href="http://localhost/v1.1/" rel="self"/>
- <content type="text">
- Version v1.1 CURRENT (2011-01-21T11:33:21Z)
- </content>
- </entry>
- <entry>
- <id>http://localhost/v1.0/</id>
- <title type="text">Version v1.0</title>
- <updated>2011-01-21T11:33:21Z</updated>
- <link href="http://localhost/v1.0/" rel="self"/>
- <content type="text">
- Version v1.0 DEPRECATED (2011-01-21T11:33:21Z)
- </content>
- </entry>
- </feed>
- """.replace(" ", "").replace("\n", "")
-
- actual = res.body.replace(" ", "").replace("\n", "")
-
- self.assertEqual(expected, actual)
+ f = feedparser.parse(res.body)
+ self.assertEqual(f.feed.title, 'Available API Versions')
+ self.assertEqual(f.feed.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(f.feed.id, 'http://localhost/')
+ self.assertEqual(f.feed.author, 'Rackspace')
+ self.assertEqual(f.feed.author_detail.href,
+ 'http://www.rackspace.com/')
+ self.assertEqual(f.feed.links[0]['href'], 'http://localhost/')
+ self.assertEqual(f.feed.links[0]['rel'], 'self')
+
+ self.assertEqual(len(f.entries), 2)
+ entry = f.entries[0]
+ self.assertEqual(entry.id, 'http://localhost/v1.0/')
+ self.assertEqual(entry.title, 'Version v1.0')
+ self.assertEqual(entry.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(len(entry.content), 1)
+ self.assertEqual(entry.content[0].value,
+ 'Version v1.0 DEPRECATED (2011-01-21T11:33:21Z)')
+ self.assertEqual(len(entry.links), 1)
+ self.assertEqual(entry.links[0]['href'], 'http://localhost/v1.0/')
+ self.assertEqual(entry.links[0]['rel'], 'self')
+ entry = f.entries[1]
+ self.assertEqual(entry.id, 'http://localhost/v1.1/')
+ self.assertEqual(entry.title, 'Version v1.1')
+ self.assertEqual(entry.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(len(entry.content), 1)
+ self.assertEqual(entry.content[0].value,
+ 'Version v1.1 CURRENT (2011-01-21T11:33:21Z)')
+ self.assertEqual(len(entry.links), 1)
+ self.assertEqual(entry.links[0]['href'], 'http://localhost/v1.1/')
+ self.assertEqual(entry.links[0]['rel'], 'self')
def test_multi_choice_image(self):
req = webob.Request.blank('/images/1')
@@ -511,28 +472,32 @@ class VersionsTest(test.TestCase):
self.assertEqual(res.status_int, 300)
self.assertEqual(res.content_type, "application/xml")
- expected = """
- <choices xmlns="%s" xmlns:atom="%s">
- <version id="v1.1" status="CURRENT">
- <media-types>
- <media-type base="application/xml"
- type="application/vnd.openstack.compute-v1.1+xml"/>
- <media-type base="application/json"
- type="application/vnd.openstack.compute-v1.1+json"/>
- </media-types>
- <atom:link href="http://localhost/v1.1/images/1" rel="self"/>
- </version>
- <version id="v1.0" status="DEPRECATED">
- <media-types>
- <media-type base="application/xml"
- type="application/vnd.openstack.compute-v1.0+xml"/>
- <media-type base="application/json"
- type="application/vnd.openstack.compute-v1.0+json"/>
- </media-types>
- <atom:link href="http://localhost/v1.0/images/1" rel="self"/>
- </version>
- </choices>""".replace(" ", "").replace("\n", "") % (wsgi.XMLNS_V11,
- wsgi.XMLNS_ATOM)
+ root = etree.XML(res.body)
+ self.assertTrue(root.xpath('/ns:choices', namespaces=NS))
+ versions = root.xpath('ns:version', namespaces=NS)
+ self.assertEqual(len(versions), 2)
+
+ version = versions[0]
+ self.assertEqual(version.get('id'), 'v1.1')
+ self.assertEqual(version.get('status'), 'CURRENT')
+ media_types = version.xpath('ns:media-types/ns:media-type',
+ namespaces=NS)
+ self.assertTrue(common.compare_media_types(media_types,
+ VERSIONS['v1.1']['media-types']))
+ links = version.xpath('atom:link', namespaces=NS)
+ self.assertTrue(common.compare_links(links,
+ [{'rel': 'self', 'href': 'http://localhost/v1.1/images/1'}]))
+
+ version = versions[1]
+ self.assertEqual(version.get('id'), 'v1.0')
+ self.assertEqual(version.get('status'), 'DEPRECATED')
+ media_types = version.xpath('ns:media-types/ns:media-type',
+ namespaces=NS)
+ self.assertTrue(common.compare_media_types(media_types,
+ VERSIONS['v1.0']['media-types']))
+ links = version.xpath('atom:link', namespaces=NS)
+ self.assertTrue(common.compare_links(links,
+ [{'rel': 'self', 'href': 'http://localhost/v1.0/images/1'}]))
def test_multi_choice_server_atom(self):
"""
@@ -665,22 +630,20 @@ class VersionsSerializerTests(test.TestCase):
serializer = versions.VersionsXMLSerializer()
response = serializer.index(versions_data)
- root = xml.etree.ElementTree.XML(response)
- self.assertEqual(root.tag.split('}')[1], "versions")
- self.assertEqual(root.tag.split('}')[0].strip('{'), wsgi.XMLNS_V11)
- version = list(root)[0]
- self.assertEqual(version.tag.split('}')[1], "version")
- self.assertEqual(version.get('id'),
- versions_data['versions'][0]['id'])
+ root = etree.XML(response)
+ self.assertTrue(root.xpath('/ns:versions', namespaces=NS))
+ version_elems = root.xpath('ns:version', namespaces=NS)
+ self.assertEqual(len(version_elems), 1)
+ version = version_elems[0]
+ self.assertEqual(version.get('id'), versions_data['versions'][0]['id'])
self.assertEqual(version.get('status'),
versions_data['versions'][0]['status'])
- link = list(version)[0]
-
- self.assertEqual(link.tag.split('}')[1], "link")
- self.assertEqual(link.tag.split('}')[0].strip('{'), wsgi.XMLNS_ATOM)
- for key, val in versions_data['versions'][0]['links'][0].items():
- self.assertEqual(link.get(key), val)
+ (link,) = version.xpath('atom:link', namespaces=NS)
+ self.assertTrue(common.compare_links(link, [{
+ 'rel': 'self',
+ 'href': 'http://test/2.7.1',
+ 'type': 'application/atom+xml'}]))
def test_versions_multi_xml_serializer(self):
versions_data = {
@@ -703,11 +666,9 @@ class VersionsSerializerTests(test.TestCase):
serializer = versions.VersionsXMLSerializer()
response = serializer.multi(versions_data)
- root = xml.etree.ElementTree.XML(response)
- self.assertEqual(root.tag.split('}')[1], "choices")
- self.assertEqual(root.tag.split('}')[0].strip('{'), wsgi.XMLNS_V11)
- version = list(root)[0]
- self.assertEqual(version.tag.split('}')[1], "version")
+ root = etree.XML(response)
+ self.assertTrue(root.xpath('/ns:choices', namespaces=NS))
+ (version,) = root.xpath('ns:version', namespaces=NS)
self.assertEqual(version.get('id'), versions_data['choices'][0]['id'])
self.assertEqual(version.get('status'),
versions_data['choices'][0]['status'])
@@ -716,19 +677,14 @@ class VersionsSerializerTests(test.TestCase):
media_type_nodes = list(media_types)
self.assertEqual(media_types.tag.split('}')[1], "media-types")
- set_types = versions_data['choices'][0]['media-types']
- for i, type in enumerate(set_types):
- node = media_type_nodes[i]
- self.assertEqual(node.tag.split('}')[1], "media-type")
- for key, val in set_types[i].items():
- self.assertEqual(node.get(key), val)
-
- link = list(version)[1]
+ media_types = version.xpath('ns:media-types/ns:media-type',
+ namespaces=NS)
+ self.assertTrue(common.compare_media_types(media_types,
+ versions_data['choices'][0]['media-types']))
- self.assertEqual(link.tag.split('}')[1], "link")
- self.assertEqual(link.tag.split('}')[0].strip('{'), wsgi.XMLNS_ATOM)
- for key, val in versions_data['choices'][0]['links'][0].items():
- self.assertEqual(link.get(key), val)
+ (link,) = version.xpath('atom:link', namespaces=NS)
+ self.assertTrue(common.compare_links(link,
+ versions_data['choices'][0]['links']))
def test_version_detail_xml_serializer(self):
version_data = {
@@ -770,7 +726,7 @@ class VersionsSerializerTests(test.TestCase):
serializer = versions.VersionsXMLSerializer()
response = serializer.show(version_data)
- root = xml.etree.ElementTree.XML(response)
+ root = etree.XML(response)
self.assertEqual(root.tag.split('}')[1], "version")
self.assertEqual(root.tag.split('}')[0].strip('{'), wsgi.XMLNS_V11)
@@ -811,59 +767,28 @@ class VersionsSerializerTests(test.TestCase):
serializer = versions.VersionsAtomSerializer()
response = serializer.index(versions_data)
-
- root = xml.etree.ElementTree.XML(response)
- self.assertEqual(root.tag.split('}')[1], "feed")
- self.assertEqual(root.tag.split('}')[0].strip('{'),
- "http://www.w3.org/2005/Atom")
-
- children = list(root)
- title = children[0]
- updated = children[1]
- id = children[2]
- author = children[3]
- link = children[4]
- entry = children[5]
-
- self.assertEqual(title.tag.split('}')[1], 'title')
- self.assertEqual(title.text, 'Available API Versions')
- self.assertEqual(updated.tag.split('}')[1], 'updated')
- self.assertEqual(updated.text, '2011-07-20T11:40:00Z')
- self.assertEqual(id.tag.split('}')[1], 'id')
- self.assertEqual(id.text, 'http://test/')
-
- self.assertEqual(author.tag.split('}')[1], 'author')
- author_name = list(author)[0]
- author_uri = list(author)[1]
- self.assertEqual(author_name.tag.split('}')[1], 'name')
- self.assertEqual(author_name.text, 'Rackspace')
- self.assertEqual(author_uri.tag.split('}')[1], 'uri')
- self.assertEqual(author_uri.text, 'http://www.rackspace.com/')
-
- self.assertEqual(link.get('href'), 'http://test/')
- self.assertEqual(link.get('rel'), 'self')
-
- self.assertEqual(entry.tag.split('}')[1], 'entry')
- entry_children = list(entry)
- entry_id = entry_children[0]
- entry_title = entry_children[1]
- entry_updated = entry_children[2]
- entry_link = entry_children[3]
- entry_content = entry_children[4]
- self.assertEqual(entry_id.tag.split('}')[1], "id")
- self.assertEqual(entry_id.text, "http://test/2.9.8")
- self.assertEqual(entry_title.tag.split('}')[1], "title")
- self.assertEqual(entry_title.get('type'), "text")
- self.assertEqual(entry_title.text, "Version 2.9.8")
- self.assertEqual(entry_updated.tag.split('}')[1], "updated")
- self.assertEqual(entry_updated.text, "2011-07-20T11:40:00Z")
- self.assertEqual(entry_link.tag.split('}')[1], "link")
- self.assertEqual(entry_link.get('href'), "http://test/2.9.8")
- self.assertEqual(entry_link.get('rel'), "self")
- self.assertEqual(entry_content.tag.split('}')[1], "content")
- self.assertEqual(entry_content.get('type'), "text")
- self.assertEqual(entry_content.text,
- "Version 2.9.8 CURRENT (2011-07-20T11:40:00Z)")
+ f = feedparser.parse(response)
+
+ self.assertEqual(f.feed.title, 'Available API Versions')
+ self.assertEqual(f.feed.updated, '2011-07-20T11:40:00Z')
+ self.assertEqual(f.feed.id, 'http://test/')
+ self.assertEqual(f.feed.author, 'Rackspace')
+ self.assertEqual(f.feed.author_detail.href,
+ 'http://www.rackspace.com/')
+ self.assertEqual(f.feed.links[0]['href'], 'http://test/')
+ self.assertEqual(f.feed.links[0]['rel'], 'self')
+
+ self.assertEqual(len(f.entries), 1)
+ entry = f.entries[0]
+ self.assertEqual(entry.id, 'http://test/2.9.8')
+ self.assertEqual(entry.title, 'Version 2.9.8')
+ self.assertEqual(entry.updated, '2011-07-20T11:40:00Z')
+ self.assertEqual(len(entry.content), 1)
+ self.assertEqual(entry.content[0].value,
+ 'Version 2.9.8 CURRENT (2011-07-20T11:40:00Z)')
+ self.assertEqual(len(entry.links), 1)
+ self.assertEqual(entry.links[0]['href'], 'http://test/2.9.8')
+ self.assertEqual(entry.links[0]['rel'], 'self')
def test_version_detail_atom_serializer(self):
versions_data = {
@@ -904,63 +829,36 @@ class VersionsSerializerTests(test.TestCase):
serializer = versions.VersionsAtomSerializer()
response = serializer.show(versions_data)
-
- root = xml.etree.ElementTree.XML(response)
- self.assertEqual(root.tag.split('}')[1], "feed")
- self.assertEqual(root.tag.split('}')[0].strip('{'),
- "http://www.w3.org/2005/Atom")
-
- children = list(root)
- title = children[0]
- updated = children[1]
- id = children[2]
- author = children[3]
- link = children[4]
- entry = children[5]
-
- self.assertEqual(root.tag.split('}')[1], 'feed')
- self.assertEqual(title.tag.split('}')[1], 'title')
- self.assertEqual(title.text, 'About This Version')
- self.assertEqual(updated.tag.split('}')[1], 'updated')
- self.assertEqual(updated.text, '2011-01-21T11:33:21Z')
- self.assertEqual(id.tag.split('}')[1], 'id')
- self.assertEqual(id.text, 'http://localhost/v1.1/')
-
- self.assertEqual(author.tag.split('}')[1], 'author')
- author_name = list(author)[0]
- author_uri = list(author)[1]
- self.assertEqual(author_name.tag.split('}')[1], 'name')
- self.assertEqual(author_name.text, 'Rackspace')
- self.assertEqual(author_uri.tag.split('}')[1], 'uri')
- self.assertEqual(author_uri.text, 'http://www.rackspace.com/')
-
- self.assertEqual(link.get('href'),
- 'http://localhost/v1.1/')
- self.assertEqual(link.get('rel'), 'self')
-
- self.assertEqual(entry.tag.split('}')[1], 'entry')
- entry_children = list(entry)
- entry_id = entry_children[0]
- entry_title = entry_children[1]
- entry_updated = entry_children[2]
- entry_links = (entry_children[3], entry_children[4], entry_children[5])
- entry_content = entry_children[6]
-
- self.assertEqual(entry_id.tag.split('}')[1], "id")
- self.assertEqual(entry_id.text,
- "http://localhost/v1.1/")
- self.assertEqual(entry_title.tag.split('}')[1], "title")
- self.assertEqual(entry_title.get('type'), "text")
- self.assertEqual(entry_title.text, "Version v1.1")
- self.assertEqual(entry_updated.tag.split('}')[1], "updated")
- self.assertEqual(entry_updated.text, "2011-01-21T11:33:21Z")
-
- for i, link in enumerate(versions_data["version"]["links"]):
- self.assertEqual(entry_links[i].tag.split('}')[1], "link")
- for key, val in versions_data["version"]["links"][i].items():
- self.assertEqual(entry_links[i].get(key), val)
-
- self.assertEqual(entry_content.tag.split('}')[1], "content")
- self.assertEqual(entry_content.get('type'), "text")
- self.assertEqual(entry_content.text,
- "Version v1.1 CURRENT (2011-01-21T11:33:21Z)")
+ f = feedparser.parse(response)
+
+ self.assertEqual(f.feed.title, 'About This Version')
+ self.assertEqual(f.feed.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(f.feed.id, 'http://localhost/v1.1/')
+ self.assertEqual(f.feed.author, 'Rackspace')
+ self.assertEqual(f.feed.author_detail.href,
+ 'http://www.rackspace.com/')
+ self.assertEqual(f.feed.links[0]['href'], 'http://localhost/v1.1/')
+ self.assertEqual(f.feed.links[0]['rel'], 'self')
+
+ self.assertEqual(len(f.entries), 1)
+ entry = f.entries[0]
+ self.assertEqual(entry.id, 'http://localhost/v1.1/')
+ self.assertEqual(entry.title, 'Version v1.1')
+ self.assertEqual(entry.updated, '2011-01-21T11:33:21Z')
+ self.assertEqual(len(entry.content), 1)
+ self.assertEqual(entry.content[0].value,
+ 'Version v1.1 CURRENT (2011-01-21T11:33:21Z)')
+ self.assertEqual(len(entry.links), 3)
+ self.assertEqual(entry.links[0]['href'], 'http://localhost/v1.1/')
+ self.assertEqual(entry.links[0]['rel'], 'self')
+ self.assertEqual(entry.links[1], {
+ 'rel': 'describedby',
+ 'type': 'application/pdf',
+ 'href': 'http://docs.rackspacecloud.com/'
+ 'servers/api/v1.1/cs-devguide-20110125.pdf'})
+ self.assertEqual(entry.links[2], {
+ 'rel': 'describedby',
+ 'type': 'application/vnd.sun.wadl+xml',
+ 'href': 'http://docs.rackspacecloud.com/'
+ 'servers/api/v1.1/application.wadl',
+ })
diff --git a/nova/tests/api/openstack/test_wsgi.py b/nova/tests/api/openstack/test_wsgi.py
index 6dea78d17..74b9ce853 100644
--- a/nova/tests/api/openstack/test_wsgi.py
+++ b/nova/tests/api/openstack/test_wsgi.py
@@ -27,17 +27,17 @@ class RequestTest(test.TestCase):
result = request.get_content_type()
self.assertEqual(result, "application/json")
- def test_content_type_from_accept_xml(self):
- request = wsgi.Request.blank('/tests/123')
- request.headers["Accept"] = "application/xml"
- result = request.best_match_content_type()
- self.assertEqual(result, "application/xml")
-
- request = wsgi.Request.blank('/tests/123')
- request.headers["Accept"] = "application/json"
- result = request.best_match_content_type()
- self.assertEqual(result, "application/json")
-
+ def test_content_type_from_accept(self):
+ for content_type in ('application/xml',
+ 'application/vnd.openstack.compute+xml',
+ 'application/json',
+ 'application/vnd.openstack.compute+json'):
+ request = wsgi.Request.blank('/tests/123')
+ request.headers["Accept"] = content_type
+ result = request.best_match_content_type()
+ self.assertEqual(result, content_type)
+
+ def test_content_type_from_accept_best(self):
request = wsgi.Request.blank('/tests/123')
request.headers["Accept"] = "application/xml, application/json"
result = request.best_match_content_type()
@@ -231,7 +231,7 @@ class ResponseSerializerTest(test.TestCase):
self.body_serializers = {
'application/json': JSONSerializer(),
- 'application/XML': XMLSerializer(),
+ 'application/xml': XMLSerializer(),
}
self.serializer = wsgi.ResponseSerializer(self.body_serializers,
@@ -250,15 +250,24 @@ class ResponseSerializerTest(test.TestCase):
self.serializer.get_body_serializer,
'application/unknown')
- def test_serialize_response(self):
- response = self.serializer.serialize({}, 'application/json')
- self.assertEqual(response.headers['Content-Type'], 'application/json')
- self.assertEqual(response.body, 'pew_json')
- self.assertEqual(response.status_int, 404)
+ def test_serialize_response_json(self):
+ for content_type in ('application/json',
+ 'application/vnd.openstack.compute+json'):
+ response = self.serializer.serialize({}, content_type)
+ self.assertEqual(response.headers['Content-Type'], content_type)
+ self.assertEqual(response.body, 'pew_json')
+ self.assertEqual(response.status_int, 404)
+
+ def test_serialize_response_xml(self):
+ for content_type in ('application/xml',
+ 'application/vnd.openstack.compute+xml'):
+ response = self.serializer.serialize({}, content_type)
+ self.assertEqual(response.headers['Content-Type'], content_type)
+ self.assertEqual(response.body, 'pew_xml')
+ self.assertEqual(response.status_int, 404)
def test_serialize_response_None(self):
response = self.serializer.serialize(None, 'application/json')
- print response
self.assertEqual(response.headers['Content-Type'], 'application/json')
self.assertEqual(response.body, '')
self.assertEqual(response.status_int, 404)
@@ -281,7 +290,7 @@ class RequestDeserializerTest(test.TestCase):
self.body_deserializers = {
'application/json': JSONDeserializer(),
- 'application/XML': XMLDeserializer(),
+ 'application/xml': XMLDeserializer(),
}
self.deserializer = wsgi.RequestDeserializer(self.body_deserializers)
@@ -290,8 +299,9 @@ class RequestDeserializerTest(test.TestCase):
pass
def test_get_deserializer(self):
- expected = self.deserializer.get_body_deserializer('application/json')
- self.assertEqual(expected, self.body_deserializers['application/json'])
+ ctype = 'application/json'
+ expected = self.deserializer.get_body_deserializer(ctype)
+ self.assertEqual(expected, self.body_deserializers[ctype])
def test_get_deserializer_unknown_content_type(self):
self.assertRaises(exception.InvalidContentType,
@@ -299,10 +309,11 @@ class RequestDeserializerTest(test.TestCase):
'application/unknown')
def test_get_expected_content_type(self):
+ ctype = 'application/json'
request = wsgi.Request.blank('/')
- request.headers['Accept'] = 'application/json'
+ request.headers['Accept'] = ctype
self.assertEqual(self.deserializer.get_expected_content_type(request),
- 'application/json')
+ ctype)
def test_get_action_args(self):
env = {
diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py
index 19028a451..cdbfba63a 100644
--- a/nova/tests/db/fakes.py
+++ b/nova/tests/db/fakes.py
@@ -125,10 +125,11 @@ def stub_out_db_network_api(stubs):
if ips[0]['fixed_ip']:
fixed_ip_address = ips[0]['fixed_ip']['address']
ips[0]['fixed_ip'] = None
+ ips[0]['host'] = None
return fixed_ip_address
def fake_floating_ip_fixed_ip_associate(context, floating_address,
- fixed_address):
+ fixed_address, host):
float = filter(lambda i: i['address'] == floating_address,
floating_ips)
fixed = filter(lambda i: i['address'] == fixed_address,
@@ -136,6 +137,7 @@ def stub_out_db_network_api(stubs):
if float and fixed:
float[0]['fixed_ip'] = fixed[0]
float[0]['fixed_ip_id'] = fixed[0]['id']
+ float[0]['host'] = host
def fake_floating_ip_get_all_by_host(context, host):
# TODO(jkoelker): Once we get the patches that remove host from
diff --git a/nova/tests/fake_network.py b/nova/tests/fake_network.py
index 1ecb99b31..142206755 100644
--- a/nova/tests/fake_network.py
+++ b/nova/tests/fake_network.py
@@ -25,6 +25,36 @@ HOST = "testhost"
FLAGS = flags.FLAGS
+class FakeIptablesFirewallDriver(object):
+ def __init__(self, **kwargs):
+ pass
+
+ def setattr(self, key, val):
+ self.__setattr__(key, val)
+
+ def apply_instance_filter(self, instance, network_info):
+ pass
+
+
+class FakeVIFDriver(object):
+
+ def __init__(self, **kwargs):
+ pass
+
+ def setattr(self, key, val):
+ self.__setattr__(key, val)
+
+ def plug(self, instance, network, mapping):
+ return {
+ 'id': 'fake',
+ 'bridge_name': 'fake',
+ 'mac_address': 'fake',
+ 'ip_address': 'fake',
+ 'dhcp_server': 'fake',
+ 'extra_params': 'fake',
+ }
+
+
class FakeModel(dict):
"""Represent a model from the db"""
def __init__(self, *args, **kwargs):
diff --git a/nova/tests/integrated/test_xml.py b/nova/tests/integrated/test_xml.py
index 74baaacc2..cf013da1d 100644
--- a/nova/tests/integrated/test_xml.py
+++ b/nova/tests/integrated/test_xml.py
@@ -15,6 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from lxml import etree
+
from nova.log import logging
from nova.tests.integrated import integrated_helpers
from nova.api.openstack import common
@@ -34,9 +36,8 @@ class XmlTests(integrated_helpers._IntegratedTestBase):
response = self.api.api_request('/limits', headers=headers)
data = response.read()
LOG.debug("data: %s" % data)
-
- prefix = '<limits xmlns="%s"' % common.XML_NS_V11
- self.assertTrue(data.startswith(prefix))
+ root = etree.XML(data)
+ self.assertEqual(root.nsmap.get(None), common.XML_NS_V11)
def test_namespace_servers(self):
"""/servers should have v1.1 namespace (has changed in 1.1)."""
@@ -46,6 +47,5 @@ class XmlTests(integrated_helpers._IntegratedTestBase):
response = self.api.api_request('/servers', headers=headers)
data = response.read()
LOG.debug("data: %s" % data)
-
- prefix = '<servers xmlns="%s"' % common.XML_NS_V11
- self.assertTrue(data.startswith(prefix))
+ root = etree.XML(data)
+ self.assertEqual(root.nsmap.get(None), common.XML_NS_V11)
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index 233ee14de..1924ae050 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -35,6 +35,7 @@ from nova import utils
from nova.api.ec2 import cloud
from nova.compute import power_state
from nova.compute import vm_states
+from nova.virt import driver
from nova.virt.libvirt import connection
from nova.virt.libvirt import firewall
from nova.tests import fake_network
@@ -51,6 +52,41 @@ def _concurrency(wait, done, target):
done.send()
+class FakeVirDomainSnapshot(object):
+
+ def __init__(self, dom=None):
+ self.dom = dom
+
+ def delete(self, flags):
+ pass
+
+
+class FakeVirtDomain(object):
+
+ def __init__(self, fake_xml=None):
+ if fake_xml:
+ self._fake_dom_xml = fake_xml
+ else:
+ self._fake_dom_xml = """
+ <domain type='kvm'>
+ <devices>
+ <disk type='file'>
+ <source file='filename'/>
+ </disk>
+ </devices>
+ </domain>
+ """
+
+ def snapshotCreateXML(self, *args):
+ return FakeVirDomainSnapshot(self)
+
+ def createWithFlags(self, launch_flags):
+ pass
+
+ def XMLDesc(self, *args):
+ return self._fake_dom_xml
+
+
class CacheConcurrencyTestCase(test.TestCase):
def setUp(self):
super(CacheConcurrencyTestCase, self).setUp()
@@ -152,70 +188,24 @@ class LibvirtConnTestCase(test.TestCase):
# A fake libvirt.virConnect
class FakeLibvirtConnection(object):
- pass
-
- # A fake connection.IptablesFirewallDriver
- class FakeIptablesFirewallDriver(object):
-
- def __init__(self, **kwargs):
- pass
-
- def setattr(self, key, val):
- self.__setattr__(key, val)
-
- # A fake VIF driver
- class FakeVIFDriver(object):
-
- def __init__(self, **kwargs):
- pass
-
- def setattr(self, key, val):
- self.__setattr__(key, val)
-
- def plug(self, instance, network, mapping):
- return {
- 'id': 'fake',
- 'bridge_name': 'fake',
- 'mac_address': 'fake',
- 'ip_address': 'fake',
- 'dhcp_server': 'fake',
- 'extra_params': 'fake',
- }
+ def defineXML(self, xml):
+ return FakeVirtDomain()
# Creating mocks
fake = FakeLibvirtConnection()
- fakeip = FakeIptablesFirewallDriver
- fakevif = FakeVIFDriver()
# Customizing above fake if necessary
for key, val in kwargs.items():
fake.__setattr__(key, val)
- # Inevitable mocks for connection.LibvirtConnection
- self.mox.StubOutWithMock(connection.utils, 'import_class')
- connection.utils.import_class(mox.IgnoreArg()).AndReturn(fakeip)
- self.mox.StubOutWithMock(connection.utils, 'import_object')
- connection.utils.import_object(mox.IgnoreArg()).AndReturn(fakevif)
+ self.flags(image_service='nova.image.fake.FakeImageService')
+ fw_driver = "nova.tests.fake_network.FakeIptablesFirewallDriver"
+ self.flags(firewall_driver=fw_driver)
+ self.flags(libvirt_vif_driver="nova.tests.fake_network.FakeVIFDriver")
+
self.mox.StubOutWithMock(connection.LibvirtConnection, '_conn')
connection.LibvirtConnection._conn = fake
def fake_lookup(self, instance_name):
-
- class FakeVirtDomain(object):
-
- def snapshotCreateXML(self, *args):
- return None
-
- def XMLDesc(self, *args):
- return """
- <domain type='kvm'>
- <devices>
- <disk type='file'>
- <source file='filename'/>
- </disk>
- </devices>
- </domain>
- """
-
return FakeVirtDomain()
def fake_execute(self, *args):
@@ -797,8 +787,6 @@ class LibvirtConnTestCase(test.TestCase):
shutil.rmtree(os.path.join(FLAGS.instances_path, instance.name))
shutil.rmtree(os.path.join(FLAGS.instances_path, '_base'))
- self.assertTrue(count)
-
def test_get_host_ip_addr(self):
conn = connection.LibvirtConnection(False)
ip = conn.get_host_ip_addr()
@@ -840,6 +828,50 @@ class LibvirtConnTestCase(test.TestCase):
_assert_volume_in_mapping('sdg', False)
_assert_volume_in_mapping('sdh1', False)
+ def test_reboot_signature(self):
+ """Test that libvirt driver method sig matches interface"""
+ def fake_reboot_with_correct_sig(ignore, instance,
+ network_info, reboot_type):
+ pass
+
+ def fake_destroy(instance, network_info, cleanup=False):
+ pass
+
+ def fake_plug_vifs(instance, network_info):
+ pass
+
+ def fake_create_new_domain(xml):
+ return
+
+ def fake_none(self, instance):
+ return
+
+ instance = db.instance_create(self.context, self.test_instance)
+ network_info = _fake_network_info(self.stubs, 1)
+
+ self.mox.StubOutWithMock(connection.LibvirtConnection, '_conn')
+ connection.LibvirtConnection._conn.lookupByName = self.fake_lookup
+
+ conn = connection.LibvirtConnection(False)
+ self.stubs.Set(conn, 'destroy', fake_destroy)
+ self.stubs.Set(conn, 'plug_vifs', fake_plug_vifs)
+ self.stubs.Set(conn.firewall_driver,
+ 'setup_basic_filtering',
+ fake_none)
+ self.stubs.Set(conn.firewall_driver,
+ 'prepare_instance_filter',
+ fake_none)
+ self.stubs.Set(conn, '_create_new_domain', fake_create_new_domain)
+ self.stubs.Set(conn.firewall_driver,
+ 'apply_instance_filter',
+ fake_none)
+
+ args = [instance, network_info, 'SOFT']
+ conn.reboot(*args)
+
+ compute_driver = driver.ComputeDriver()
+ self.assertRaises(NotImplementedError, compute_driver.reboot, *args)
+
class NWFilterFakes:
def __init__(self):
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index a8a03b56b..2cacd2364 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -364,7 +364,7 @@ class XenAPIVMTestCase(test.TestCase):
def _test_spawn(self, image_ref, kernel_id, ramdisk_id,
instance_type_id="3", os_type="linux",
- architecture="x86-64", instance_id=1,
+ hostname="test", architecture="x86-64", instance_id=1,
check_injection=False,
create_record=True, empty_dns=False):
stubs.stubout_loopingcall_start(self.stubs)
@@ -377,6 +377,7 @@ class XenAPIVMTestCase(test.TestCase):
'ramdisk_id': ramdisk_id,
'instance_type_id': instance_type_id,
'os_type': os_type,
+ 'hostname': hostname,
'architecture': architecture}
instance = db.instance_create(self.context, instance_values)
else:
diff --git a/nova/tests/vmwareapi/stubs.py b/nova/tests/vmwareapi/stubs.py
index 0ed5e9b68..7de10e612 100644
--- a/nova/tests/vmwareapi/stubs.py
+++ b/nova/tests/vmwareapi/stubs.py
@@ -47,7 +47,5 @@ def set_stubs(stubs):
stubs.Set(vmware_images, 'upload_image', fake.fake_upload_image)
stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object",
fake_get_vim_object)
- stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object",
- fake_get_vim_object)
stubs.Set(vmwareapi_conn.VMWareAPISession, "_is_vim_object",
fake_is_vim_object)