summaryrefslogtreecommitdiffstats
path: root/nova/tests
diff options
context:
space:
mode:
authorTrey Morris <trey.morris@rackspace.com>2011-06-30 14:20:59 -0500
committerTrey Morris <trey.morris@rackspace.com>2011-06-30 14:20:59 -0500
commitfa8f7421f48a3bd1f6b01b2ff3cc754c24e0a424 (patch)
treea1cbb2835c9c8bd6ea9866115d4fb22c8b1b0aae /nova/tests
parent46c321d044d6a2db44a22466624a1e7dc71d5935 (diff)
parentc7ee39c3d00fdc799850b308fefd08f482edb5e5 (diff)
trunk merge with migration renumbering
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/api/__init__.py19
-rw-r--r--nova/tests/api/openstack/__init__.py3
-rw-r--r--nova/tests/api/openstack/test_image_metadata.py222
-rw-r--r--nova/tests/api/openstack/test_images.py483
-rw-r--r--nova/tests/api/openstack/test_zones.py10
-rw-r--r--nova/tests/image/__init__.py3
-rw-r--r--nova/tests/integrated/__init__.py2
-rw-r--r--nova/tests/scheduler/__init__.py19
-rw-r--r--nova/tests/scheduler/test_least_cost_scheduler.py11
-rw-r--r--nova/tests/scheduler/test_scheduler.py4
-rw-r--r--nova/tests/scheduler/test_zone_aware_scheduler.py87
-rw-r--r--nova/tests/test_compute.py14
-rw-r--r--nova/tests/test_utils.py13
13 files changed, 690 insertions, 200 deletions
diff --git a/nova/tests/api/__init__.py b/nova/tests/api/__init__.py
index e69de29bb..6dab802f2 100644
--- a/nova/tests/api/__init__.py
+++ b/nova/tests/api/__init__.py
@@ -0,0 +1,19 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 Openstack LLC.
+# 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.
+
+# NOTE(vish): this forces the fixtures from tests/__init.py:setup() to work
+from nova.tests import *
diff --git a/nova/tests/api/openstack/__init__.py b/nova/tests/api/openstack/__init__.py
index bac7181f7..bfb424afe 100644
--- a/nova/tests/api/openstack/__init__.py
+++ b/nova/tests/api/openstack/__init__.py
@@ -15,6 +15,9 @@
# License for the specific language governing permissions and limitations
# under the License.
+# NOTE(vish): this forces the fixtures from tests/__init.py:setup() to work
+from nova.tests import *
+
import webob.dec
from nova import test
diff --git a/nova/tests/api/openstack/test_image_metadata.py b/nova/tests/api/openstack/test_image_metadata.py
index 730af3665..d9fb61e2a 100644
--- a/nova/tests/api/openstack/test_image_metadata.py
+++ b/nova/tests/api/openstack/test_image_metadata.py
@@ -24,6 +24,7 @@ import xml.dom.minidom as minidom
from nova import flags
from nova.api import openstack
+from nova import test
from nova.tests.api.openstack import fakes
import nova.wsgi
@@ -31,7 +32,7 @@ import nova.wsgi
FLAGS = flags.FLAGS
-class ImageMetaDataTest(unittest.TestCase):
+class ImageMetaDataTest(test.TestCase):
IMAGE_FIXTURES = [
{'status': 'active',
@@ -112,30 +113,6 @@ class ImageMetaDataTest(unittest.TestCase):
for (key, value) in res_dict['metadata'].items():
self.assertEqual(value, res_dict['metadata'][key])
- def test_index_xml(self):
- serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
- fixture = {
- 'metadata': {
- 'one': 'two',
- 'three': 'four',
- },
- }
- output = serializer.index(fixture)
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
- <meta key="three">
- four
- </meta>
- <meta key="one">
- two
- </meta>
- </metadata>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
-
def test_show(self):
req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1'
@@ -146,24 +123,6 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual(len(res_dict['meta']), 1)
self.assertEqual('value1', res_dict['meta']['key1'])
- def test_show_xml(self):
- serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
- fixture = {
- 'meta': {
- 'one': 'two',
- },
- }
- output = serializer.show(fixture)
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
- two
- </meta>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
-
def test_show_not_found(self):
req = webob.Request.blank('/v1.1/images/1/meta/key9')
req.environ['api.version'] = '1.1'
@@ -185,34 +144,6 @@ class ImageMetaDataTest(unittest.TestCase):
self.assertEqual('value2', res_dict['metadata']['key2'])
self.assertEqual(1, len(res_dict))
- def test_create_xml(self):
- serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
- fixture = {
- 'metadata': {
- 'key9': 'value9',
- 'key2': 'value2',
- 'key1': 'value1',
- },
- }
- output = serializer.create(fixture)
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
- <meta key="key2">
- value2
- </meta>
- <meta key="key9">
- value9
- </meta>
- <meta key="key1">
- value1
- </meta>
- </metadata>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
-
def test_update_item(self):
req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1'
@@ -235,24 +166,6 @@ class ImageMetaDataTest(unittest.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(400, res.status_int)
- def test_update_item_xml(self):
- serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
- fixture = {
- 'meta': {
- 'one': 'two',
- },
- }
- output = serializer.update(fixture)
- actual = minidom.parseString(output.replace(" ", ""))
-
- expected = minidom.parseString("""
- <meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
- two
- </meta>
- """.replace(" ", ""))
-
- self.assertEqual(expected.toxml(), actual.toxml())
-
def test_update_item_too_many_keys(self):
req = webob.Request.blank('/v1.1/images/1/meta/key1')
req.environ['api.version'] = '1.1'
@@ -306,3 +219,134 @@ class ImageMetaDataTest(unittest.TestCase):
req.headers["content-type"] = "application/json"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(400, res.status_int)
+
+
+class ImageMetadataXMLSerializationTest(test.TestCase):
+
+ def test_index_xml(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ fixture = {
+ 'metadata': {
+ 'one': 'two',
+ 'three': 'four',
+ },
+ }
+ output = serializer.serialize(fixture, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <meta key="three">
+ four
+ </meta>
+ <meta key="one">
+ two
+ </meta>
+ </metadata>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index_xml_null(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ fixture = {
+ 'metadata': {
+ None: None,
+ },
+ }
+ output = serializer.serialize(fixture, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <meta key="None">
+ None
+ </meta>
+ </metadata>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index_xml_unicode(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ fixture = {
+ 'metadata': {
+ u'three': u'Jos\xe9',
+ },
+ }
+ output = serializer.serialize(fixture, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString(u"""
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <meta key="three">
+ Jos\xe9
+ </meta>
+ </metadata>
+ """.encode("UTF-8").replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_show_xml(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ fixture = {
+ 'meta': {
+ 'one': 'two',
+ },
+ }
+ output = serializer.serialize(fixture, 'show')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
+ two
+ </meta>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_update_item_xml(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ fixture = {
+ 'meta': {
+ 'one': 'two',
+ },
+ }
+ output = serializer.serialize(fixture, 'update')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <meta xmlns="http://docs.openstack.org/compute/api/v1.1" key="one">
+ two
+ </meta>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_create_xml(self):
+ serializer = openstack.image_metadata.ImageMetadataXMLSerializer()
+ fixture = {
+ 'metadata': {
+ 'key9': 'value9',
+ 'key2': 'value2',
+ 'key1': 'value1',
+ },
+ }
+ output = serializer.serialize(fixture, 'create')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected = minidom.parseString("""
+ <metadata xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <meta key="key2">
+ value2
+ </meta>
+ <meta key="key9">
+ value9
+ </meta>
+ <meta key="key1">
+ value1
+ </meta>
+ </metadata>
+ """.replace(" ", ""))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index e11e1c046..1e046531c 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -394,20 +394,25 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
self.assertEqual(expected_image, actual_image)
def test_get_image_v1_1(self):
- request = webob.Request.blank('/v1.1/images/123')
+ request = webob.Request.blank('/v1.1/images/124')
response = request.get_response(fakes.wsgi_app())
actual_image = json.loads(response.body)
- href = "http://localhost/v1.1/images/123"
+ href = "http://localhost/v1.1/images/124"
expected_image = {
"image": {
- "id": 123,
- "name": "public image",
+ "id": 124,
+ "name": "queued snapshot",
+ "serverRef": "http://localhost/v1.1/servers/42",
"updated": self.NOW_API_FORMAT,
"created": self.NOW_API_FORMAT,
- "status": "ACTIVE",
+ "status": "QUEUED",
+ "metadata": {
+ "instance_ref": "http://localhost/v1.1/servers/42",
+ "user_id": "1",
+ },
"links": [{
"rel": "self",
"href": href,
@@ -465,34 +470,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
self.assertEqual(expected_image.toxml(), actual_image.toxml())
- def test_get_image_v1_1_xml(self):
- request = webob.Request.blank('/v1.1/images/123')
- request.accept = "application/xml"
- response = request.get_response(fakes.wsgi_app())
-
- actual_image = minidom.parseString(response.body.replace(" ", ""))
-
- expected_href = "http://localhost/v1.1/images/123"
- expected_now = self.NOW_API_FORMAT
- expected_image = minidom.parseString("""
- <image id="123"
- name="public image"
- updated="%(expected_now)s"
- created="%(expected_now)s"
- status="ACTIVE"
- xmlns="http://docs.openstack.org/compute/api/v1.1">
- <links>
- <link href="%(expected_href)s" rel="self"/>
- <link href="%(expected_href)s" rel="bookmark"
- type="application/json" />
- <link href="%(expected_href)s" rel="bookmark"
- type="application/xml" />
- </links>
- </image>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected_image.toxml(), actual_image.toxml())
-
def test_get_image_404_json(self):
request = webob.Request.blank('/v1.0/images/NonExistantImage')
response = request.get_response(fakes.wsgi_app())
@@ -665,6 +642,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
expected = [{
'id': 123,
'name': 'public image',
+ 'metadata': {},
'updated': self.NOW_API_FORMAT,
'created': self.NOW_API_FORMAT,
'status': 'ACTIVE',
@@ -686,7 +664,11 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
{
'id': 124,
'name': 'queued snapshot',
- 'serverRef': "http://localhost:8774/v1.1/servers/42",
+ 'metadata': {
+ u'instance_ref': u'http://localhost/v1.1/servers/42',
+ u'user_id': u'1',
+ },
+ 'serverRef': "http://localhost/v1.1/servers/42",
'updated': self.NOW_API_FORMAT,
'created': self.NOW_API_FORMAT,
'status': 'QUEUED',
@@ -708,7 +690,11 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
{
'id': 125,
'name': 'saving snapshot',
- 'serverRef': "http://localhost:8774/v1.1/servers/42",
+ 'metadata': {
+ u'instance_ref': u'http://localhost/v1.1/servers/42',
+ u'user_id': u'1',
+ },
+ 'serverRef': "http://localhost/v1.1/servers/42",
'updated': self.NOW_API_FORMAT,
'created': self.NOW_API_FORMAT,
'status': 'SAVING',
@@ -731,7 +717,11 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
{
'id': 126,
'name': 'active snapshot',
- 'serverRef': "http://localhost:8774/v1.1/servers/42",
+ 'metadata': {
+ u'instance_ref': u'http://localhost/v1.1/servers/42',
+ u'user_id': u'1',
+ },
+ 'serverRef': "http://localhost/v1.1/servers/42",
'updated': self.NOW_API_FORMAT,
'created': self.NOW_API_FORMAT,
'status': 'ACTIVE',
@@ -753,7 +743,11 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
{
'id': 127,
'name': 'killed snapshot',
- 'serverRef': "http://localhost:8774/v1.1/servers/42",
+ 'metadata': {
+ u'instance_ref': u'http://localhost/v1.1/servers/42',
+ u'user_id': u'1',
+ },
+ 'serverRef': "http://localhost/v1.1/servers/42",
'updated': self.NOW_API_FORMAT,
'created': self.NOW_API_FORMAT,
'status': 'FAILED',
@@ -775,6 +769,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
{
'id': 129,
'name': None,
+ 'metadata': {},
'updated': self.NOW_API_FORMAT,
'created': self.NOW_API_FORMAT,
'status': 'ACTIVE',
@@ -1108,39 +1103,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
response = req.get_response(fakes.wsgi_app())
self.assertEqual(400, response.status_int)
- def test_create_image_v1_1_xml_serialization(self):
-
- body = dict(image=dict(serverRef='123', name='Snapshot 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- req.headers["accept"] = "application/xml"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
- resp_xml = minidom.parseString(response.body.replace(" ", ""))
- expected_href = "http://localhost/v1.1/images/123"
- expected_image = minidom.parseString("""
- <image
- created="None"
- id="123"
- name="Snapshot 1"
- serverRef="http://localhost/v1.1/servers/123"
- status="ACTIVE"
- updated="None"
- xmlns="http://docs.openstack.org/compute/api/v1.1">
- <links>
- <link href="%(expected_href)s" rel="self"/>
- <link href="%(expected_href)s" rel="bookmark"
- type="application/json" />
- <link href="%(expected_href)s" rel="bookmark"
- type="application/xml" />
- </links>
- </image>
- """.replace(" ", "") % (locals()))
-
- self.assertEqual(expected_image.toxml(), resp_xml.toxml())
-
def test_create_image_v1_1_no_server_ref(self):
body = dict(image=dict(name='Snapshot 1'))
@@ -1171,7 +1133,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
image_id += 1
# Snapshot for User 1
- server_ref = 'http://localhost:8774/v1.1/servers/42'
+ server_ref = 'http://localhost/v1.1/servers/42'
snapshot_properties = {'instance_ref': server_ref, 'user_id': '1'}
for status in ('queued', 'saving', 'active', 'killed'):
add_fixture(id=image_id, name='%s snapshot' % status,
@@ -1193,3 +1155,382 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
image_id += 1
return fixtures
+
+
+class ImageXMLSerializationTest(test.TestCase):
+
+ TIMESTAMP = "2010-10-11T10:30:22Z"
+ SERVER_HREF = 'http://localhost/v1.1/servers/123'
+ IMAGE_HREF = 'http://localhost/v1.1/images/%s'
+
+ def test_show(self):
+ serializer = images.ImageXMLSerializer()
+
+ fixture = {
+ 'image': {
+ 'id': 1,
+ 'name': 'Image1',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'status': 'ACTIVE',
+ 'metadata': {
+ 'key1': 'value1',
+ },
+ 'links': [
+ {
+ 'href': self.IMAGE_HREF % (1,),
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+ },
+ }
+
+ output = serializer.serialize(fixture, 'show')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected_server_href = self.SERVER_HREF
+ expected_href = self.IMAGE_HREF % (1, )
+ expected_now = self.TIMESTAMP
+ expected = minidom.parseString("""
+ <image id="1"
+ name="Image1"
+ serverRef="%(expected_server_href)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="ACTIVE"
+ xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <links>
+ <link href="%(expected_href)s" rel="bookmark"
+ type="application/json" />
+ </links>
+ <metadata>
+ <meta key="key1">
+ value1
+ </meta>
+ </metadata>
+ </image>
+ """.replace(" ", "") % (locals()))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_show_zero_metadata(self):
+ serializer = images.ImageXMLSerializer()
+
+ fixture = {
+ 'image': {
+ 'id': 1,
+ 'name': 'Image1',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'status': 'ACTIVE',
+ 'metadata': {},
+ 'links': [
+ {
+ 'href': self.IMAGE_HREF % (1,),
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+ },
+ }
+
+ output = serializer.serialize(fixture, 'show')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected_server_href = self.SERVER_HREF
+ expected_href = self.IMAGE_HREF % (1, )
+ expected_now = self.TIMESTAMP
+ expected = minidom.parseString("""
+ <image id="1"
+ name="Image1"
+ serverRef="%(expected_server_href)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="ACTIVE"
+ xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <links>
+ <link href="%(expected_href)s" rel="bookmark"
+ type="application/json" />
+ </links>
+ <metadata />
+ </image>
+ """.replace(" ", "") % (locals()))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_show_image_no_metadata_key(self):
+ serializer = images.ImageXMLSerializer()
+
+ fixture = {
+ 'image': {
+ 'id': 1,
+ 'name': 'Image1',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'status': 'ACTIVE',
+ 'links': [
+ {
+ 'href': self.IMAGE_HREF % (1,),
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+
+ },
+ }
+
+ output = serializer.serialize(fixture, 'show')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected_server_href = self.SERVER_HREF
+ expected_href = self.IMAGE_HREF % (1, )
+ expected_now = self.TIMESTAMP
+ expected = minidom.parseString("""
+ <image id="1"
+ name="Image1"
+ serverRef="%(expected_server_href)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="ACTIVE"
+ xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <links>
+ <link href="%(expected_href)s" rel="bookmark"
+ type="application/json" />
+ </links>
+ <metadata />
+ </image>
+ """.replace(" ", "") % (locals()))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index(self):
+ serializer = images.ImageXMLSerializer()
+
+ fixtures = {
+ 'images': [
+ {
+ 'id': 1,
+ 'name': 'Image1',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'status': 'ACTIVE',
+ 'links': [
+ {
+ 'href': 'http://localhost/v1.1/images/1',
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+ },
+ {
+ 'id': 2,
+ 'name': 'queued image',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'status': 'QUEUED',
+ 'links': [
+ {
+ 'href': 'http://localhost/v1.1/images/2',
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+ },
+ ],
+ }
+
+ output = serializer.serialize(fixtures, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected_serverRef = self.SERVER_HREF
+ expected_now = self.TIMESTAMP
+ expected = minidom.parseString("""
+ <images xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <image id="1"
+ name="Image1"
+ serverRef="%(expected_serverRef)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="ACTIVE">
+ <links>
+ <link href="http://localhost/v1.1/images/1" rel="bookmark"
+ type="application/json" />
+ </links>
+ </image>
+ <image id="2"
+ name="queued image"
+ serverRef="%(expected_serverRef)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="QUEUED">
+ <links>
+ <link href="http://localhost/v1.1/images/2" rel="bookmark"
+ type="application/json" />
+ </links>
+ </image>
+ </images>
+ """.replace(" ", "") % (locals()))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_index_zero_images(self):
+ serializer = images.ImageXMLSerializer()
+
+ fixtures = {
+ 'images': [],
+ }
+
+ output = serializer.serialize(fixtures, 'index')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected_serverRef = self.SERVER_HREF
+ expected_now = self.TIMESTAMP
+ expected = minidom.parseString("""
+ <images xmlns="http://docs.openstack.org/compute/api/v1.1" />
+ """.replace(" ", "") % (locals()))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_detail(self):
+ serializer = images.ImageXMLSerializer()
+
+ fixtures = {
+ 'images': [
+ {
+ 'id': 1,
+ 'name': 'Image1',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'status': 'ACTIVE',
+ 'metadata': {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ },
+ 'links': [
+ {
+ 'href': 'http://localhost/v1.1/images/1',
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+ },
+ {
+ 'id': 2,
+ 'name': 'queued image',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'metadata': {},
+ 'status': 'QUEUED',
+ 'links': [
+ {
+ 'href': 'http://localhost/v1.1/images/2',
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+ },
+ ],
+ }
+
+ output = serializer.serialize(fixtures, 'detail')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected_serverRef = self.SERVER_HREF
+ expected_now = self.TIMESTAMP
+ expected = minidom.parseString("""
+ <images xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <image id="1"
+ name="Image1"
+ serverRef="%(expected_serverRef)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="ACTIVE">
+ <links>
+ <link href="http://localhost/v1.1/images/1" rel="bookmark"
+ type="application/json" />
+ </links>
+ <metadata>
+ <meta key="key2">
+ value2
+ </meta>
+ <meta key="key1">
+ value1
+ </meta>
+ </metadata>
+ </image>
+ <image id="2"
+ name="queued image"
+ serverRef="%(expected_serverRef)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="QUEUED">
+ <links>
+ <link href="http://localhost/v1.1/images/2" rel="bookmark"
+ type="application/json" />
+ </links>
+ <metadata />
+ </image>
+ </images>
+ """.replace(" ", "") % (locals()))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
+
+ def test_create(self):
+ serializer = images.ImageXMLSerializer()
+
+ fixture = {
+ 'image': {
+ 'id': 1,
+ 'name': 'Image1',
+ 'created': self.TIMESTAMP,
+ 'updated': self.TIMESTAMP,
+ 'serverRef': self.SERVER_HREF,
+ 'status': 'ACTIVE',
+ 'metadata': {
+ 'key1': 'value1',
+ },
+ 'links': [
+ {
+ 'href': self.IMAGE_HREF % (1,),
+ 'rel': 'bookmark',
+ 'type': 'application/json',
+ },
+ ],
+ },
+ }
+
+ output = serializer.serialize(fixture, 'create')
+ actual = minidom.parseString(output.replace(" ", ""))
+
+ expected_server_href = self.SERVER_HREF
+ expected_href = self.IMAGE_HREF % (1, )
+ expected_now = self.TIMESTAMP
+ expected = minidom.parseString("""
+ <image id="1"
+ name="Image1"
+ serverRef="%(expected_server_href)s"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="ACTIVE"
+ xmlns="http://docs.openstack.org/compute/api/v1.1">
+ <links>
+ <link href="%(expected_href)s" rel="bookmark"
+ type="application/json" />
+ </links>
+ <metadata>
+ <meta key="key1">
+ value1
+ </meta>
+ </metadata>
+ </image>
+ """.replace(" ", "") % (locals()))
+
+ self.assertEqual(expected.toxml(), actual.toxml())
diff --git a/nova/tests/api/openstack/test_zones.py b/nova/tests/api/openstack/test_zones.py
index 098577e4c..6a6e13d93 100644
--- a/nova/tests/api/openstack/test_zones.py
+++ b/nova/tests/api/openstack/test_zones.py
@@ -34,7 +34,7 @@ FLAGS.verbose = True
def zone_get(context, zone_id):
return dict(id=1, api_url='http://example.com', username='bob',
- password='xxx')
+ password='xxx', weight_scale=1.0, weight_offset=0.0)
def zone_create(context, values):
@@ -57,9 +57,9 @@ def zone_delete(context, zone_id):
def zone_get_all_scheduler(*args):
return [
dict(id=1, api_url='http://example.com', username='bob',
- password='xxx'),
+ password='xxx', weight_scale=1.0, weight_offset=0.0),
dict(id=2, api_url='http://example.org', username='alice',
- password='qwerty'),
+ password='qwerty', weight_scale=1.0, weight_offset=0.0),
]
@@ -70,9 +70,9 @@ def zone_get_all_scheduler_empty(*args):
def zone_get_all_db(context):
return [
dict(id=1, api_url='http://example.com', username='bob',
- password='xxx'),
+ password='xxx', weight_scale=1.0, weight_offset=0.0),
dict(id=2, api_url='http://example.org', username='alice',
- password='qwerty'),
+ password='qwerty', weight_scale=1.0, weight_offset=0.0),
]
diff --git a/nova/tests/image/__init__.py b/nova/tests/image/__init__.py
index b94e2e54e..6dab802f2 100644
--- a/nova/tests/image/__init__.py
+++ b/nova/tests/image/__init__.py
@@ -14,3 +14,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
+
+# NOTE(vish): this forces the fixtures from tests/__init.py:setup() to work
+from nova.tests import *
diff --git a/nova/tests/integrated/__init__.py b/nova/tests/integrated/__init__.py
index 10e0a91d7..430af8754 100644
--- a/nova/tests/integrated/__init__.py
+++ b/nova/tests/integrated/__init__.py
@@ -18,3 +18,5 @@
:mod:`integrated` -- Tests whole systems, using mock services where needed
=================================
"""
+# NOTE(vish): this forces the fixtures from tests/__init.py:setup() to work
+from nova.tests import *
diff --git a/nova/tests/scheduler/__init__.py b/nova/tests/scheduler/__init__.py
index e69de29bb..6dab802f2 100644
--- a/nova/tests/scheduler/__init__.py
+++ b/nova/tests/scheduler/__init__.py
@@ -0,0 +1,19 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 Openstack LLC.
+# 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.
+
+# NOTE(vish): this forces the fixtures from tests/__init.py:setup() to work
+from nova.tests import *
diff --git a/nova/tests/scheduler/test_least_cost_scheduler.py b/nova/tests/scheduler/test_least_cost_scheduler.py
index 9a5318aee..49791053e 100644
--- a/nova/tests/scheduler/test_least_cost_scheduler.py
+++ b/nova/tests/scheduler/test_least_cost_scheduler.py
@@ -122,15 +122,16 @@ class LeastCostSchedulerTestCase(test.TestCase):
for hostname, caps in hosts]
self.assertWeights(expected, num, request_spec, hosts)
- def test_fill_first_cost_fn(self):
+ def test_compute_fill_first_cost_fn(self):
FLAGS.least_cost_scheduler_cost_functions = [
- 'nova.scheduler.least_cost.fill_first_cost_fn',
+ 'nova.scheduler.least_cost.compute_fill_first_cost_fn',
]
- FLAGS.fill_first_cost_fn_weight = 1
+ FLAGS.compute_fill_first_cost_fn_weight = 1
num = 1
- request_spec = {}
- hosts = self.sched.filter_hosts(num, request_spec)
+ instance_type = {'memory_mb': 1024}
+ request_spec = {'instance_type': instance_type}
+ hosts = self.sched.filter_hosts('compute', request_spec, None)
expected = []
for idx, (hostname, caps) in enumerate(hosts):
diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py
index 94d1212c8..daea826fd 100644
--- a/nova/tests/scheduler/test_scheduler.py
+++ b/nova/tests/scheduler/test_scheduler.py
@@ -1073,7 +1073,7 @@ class DynamicNovaClientTest(test.TestCase):
self.assertEquals(api._issue_novaclient_command(
FakeNovaClient(FakeServerCollection()),
- zone, "servers", "find", "name").b, 22)
+ zone, "servers", "find", name="test").b, 22)
self.assertEquals(api._issue_novaclient_command(
FakeNovaClient(FakeServerCollection()),
@@ -1087,7 +1087,7 @@ class DynamicNovaClientTest(test.TestCase):
self.assertEquals(api._issue_novaclient_command(
FakeNovaClient(FakeEmptyServerCollection()),
- zone, "servers", "find", "name"), None)
+ zone, "servers", "find", name="test"), None)
self.assertEquals(api._issue_novaclient_command(
FakeNovaClient(FakeEmptyServerCollection()),
diff --git a/nova/tests/scheduler/test_zone_aware_scheduler.py b/nova/tests/scheduler/test_zone_aware_scheduler.py
index 37c6488cc..5950f4551 100644
--- a/nova/tests/scheduler/test_zone_aware_scheduler.py
+++ b/nova/tests/scheduler/test_zone_aware_scheduler.py
@@ -16,6 +16,8 @@
Tests For Zone Aware Scheduler.
"""
+import nova.db
+
from nova import exception
from nova import test
from nova.scheduler import driver
@@ -55,29 +57,21 @@ def fake_zone_manager_service_states(num_hosts):
class FakeZoneAwareScheduler(zone_aware_scheduler.ZoneAwareScheduler):
- def filter_hosts(self, num, specs):
- # NOTE(sirp): this is returning [(hostname, services)]
- return self.zone_manager.service_states.items()
-
- def weigh_hosts(self, num, specs, hosts):
- fake_weight = 99
- weighted = []
- for hostname, caps in hosts:
- weighted.append(dict(weight=fake_weight, name=hostname))
- return weighted
+ # No need to stub anything at the moment
+ pass
class FakeZoneManager(zone_manager.ZoneManager):
def __init__(self):
self.service_states = {
'host1': {
- 'compute': {'ram': 1000},
+ 'compute': {'host_memory_free': 1073741824},
},
'host2': {
- 'compute': {'ram': 2000},
+ 'compute': {'host_memory_free': 2147483648},
},
'host3': {
- 'compute': {'ram': 3000},
+ 'compute': {'host_memory_free': 3221225472},
},
}
@@ -87,7 +81,7 @@ class FakeEmptyZoneManager(zone_manager.ZoneManager):
self.service_states = {}
-def fake_empty_call_zone_method(context, method, specs):
+def fake_empty_call_zone_method(context, method, specs, zones):
return []
@@ -106,7 +100,7 @@ def fake_ask_child_zone_to_create_instance(context, zone_info,
was_called = True
-def fake_provision_resource_locally(context, item, instance_id, kwargs):
+def fake_provision_resource_locally(context, build_plan, request_spec, kwargs):
global was_called
was_called = True
@@ -126,7 +120,7 @@ def fake_decrypt_blob_returns_child_info(blob):
'child_blob': True} # values aren't important. Keys are.
-def fake_call_zone_method(context, method, specs):
+def fake_call_zone_method(context, method, specs, zones):
return [
('zone1', [
dict(weight=1, blob='AAAAAAA'),
@@ -149,28 +143,67 @@ def fake_call_zone_method(context, method, specs):
]
+def fake_zone_get_all(context):
+ return [
+ dict(id=1, api_url='zone1',
+ username='admin', password='password',
+ weight_offset=0.0, weight_scale=1.0),
+ dict(id=2, api_url='zone2',
+ username='admin', password='password',
+ weight_offset=1000.0, weight_scale=1.0),
+ dict(id=3, api_url='zone3',
+ username='admin', password='password',
+ weight_offset=0.0, weight_scale=1000.0),
+ ]
+
+
class ZoneAwareSchedulerTestCase(test.TestCase):
"""Test case for Zone Aware Scheduler."""
def test_zone_aware_scheduler(self):
"""
- Create a nested set of FakeZones, ensure that a select call returns the
- appropriate build plan.
+ Create a nested set of FakeZones, try to build multiple instances
+ and ensure that a select call returns the appropriate build plan.
"""
sched = FakeZoneAwareScheduler()
self.stubs.Set(sched, '_call_zone_method', fake_call_zone_method)
+ self.stubs.Set(nova.db, 'zone_get_all', fake_zone_get_all)
zm = FakeZoneManager()
sched.set_zone_manager(zm)
fake_context = {}
- build_plan = sched.select(fake_context, {})
-
- self.assertEqual(15, len(build_plan))
-
- hostnames = [plan_item['name']
- for plan_item in build_plan if 'name' in plan_item]
- self.assertEqual(3, len(hostnames))
+ build_plan = sched.select(fake_context,
+ {'instance_type': {'memory_mb': 512},
+ 'num_instances': 4})
+
+ # 4 from local zones, 12 from remotes
+ self.assertEqual(16, len(build_plan))
+
+ hostnames = [plan_item['hostname']
+ for plan_item in build_plan if 'hostname' in plan_item]
+ # 4 local hosts
+ self.assertEqual(4, len(hostnames))
+
+ def test_adjust_child_weights(self):
+ """Make sure the weights returned by child zones are
+ properly adjusted based on the scale/offset in the zone
+ db entries.
+ """
+ sched = FakeZoneAwareScheduler()
+ child_results = fake_call_zone_method(None, None, None, None)
+ zones = fake_zone_get_all(None)
+ sched._adjust_child_weights(child_results, zones)
+ scaled = [130000, 131000, 132000, 3000]
+ for zone, results in child_results:
+ for item in results:
+ w = item['weight']
+ if zone == 'zone1': # No change
+ self.assertTrue(w < 1000.0)
+ if zone == 'zone2': # Offset +1000
+ self.assertTrue(w >= 1000.0 and w < 2000)
+ if zone == 'zone3': # Scale x1000
+ self.assertEqual(scaled.pop(0), w)
def test_empty_zone_aware_scheduler(self):
"""
@@ -178,6 +211,7 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
"""
sched = FakeZoneAwareScheduler()
self.stubs.Set(sched, '_call_zone_method', fake_empty_call_zone_method)
+ self.stubs.Set(nova.db, 'zone_get_all', fake_zone_get_all)
zm = FakeEmptyZoneManager()
sched.set_zone_manager(zm)
@@ -185,8 +219,7 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
fake_context = {}
self.assertRaises(driver.NoValidHost, sched.schedule_run_instance,
fake_context, 1,
- dict(host_filter=None,
- request_spec={'instance_type': {}}))
+ dict(host_filter=None, instance_type={}))
def test_schedule_do_not_schedule_with_hint(self):
"""
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 730dc6a2a..45cd2f764 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -130,7 +130,7 @@ class ComputeTestCase(test.TestCase):
instance_ref = models.Instance()
instance_ref['id'] = 1
instance_ref['volumes'] = [vol1, vol2]
- instance_ref['hostname'] = 'i-00000001'
+ instance_ref['hostname'] = 'hostname-1'
instance_ref['host'] = 'dummy'
return instance_ref
@@ -162,6 +162,18 @@ class ComputeTestCase(test.TestCase):
db.security_group_destroy(self.context, group['id'])
db.instance_destroy(self.context, ref[0]['id'])
+ def test_default_hostname_generator(self):
+ cases = [(None, 'server_1'), ('Hello, Server!', 'hello_server'),
+ ('<}\x1fh\x10e\x08l\x02l\x05o\x12!{>', 'hello')]
+ for display_name, hostname in cases:
+ ref = self.compute_api.create(self.context,
+ instance_types.get_default_instance_type(), None,
+ display_name=display_name)
+ try:
+ self.assertEqual(ref[0]['hostname'], hostname)
+ finally:
+ db.instance_destroy(self.context, ref[0]['id'])
+
def test_destroy_instance_disassociates_security_groups(self):
"""Make sure destroying disassociates security groups"""
group = self._create_group()
diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py
index 3a3f914e4..0c359e981 100644
--- a/nova/tests/test_utils.py
+++ b/nova/tests/test_utils.py
@@ -276,6 +276,19 @@ class GenericUtilsTestCase(test.TestCase):
result = utils.parse_server_string('www.exa:mple.com:8443')
self.assertEqual(('', ''), result)
+ def test_bool_from_str(self):
+ self.assertTrue(utils.bool_from_str('1'))
+ self.assertTrue(utils.bool_from_str('2'))
+ self.assertTrue(utils.bool_from_str('-1'))
+ self.assertTrue(utils.bool_from_str('true'))
+ self.assertTrue(utils.bool_from_str('True'))
+ self.assertTrue(utils.bool_from_str('tRuE'))
+ self.assertFalse(utils.bool_from_str('False'))
+ self.assertFalse(utils.bool_from_str('false'))
+ self.assertFalse(utils.bool_from_str('0'))
+ self.assertFalse(utils.bool_from_str(None))
+ self.assertFalse(utils.bool_from_str('junk'))
+
class IsUUIDLikeTestCase(test.TestCase):
def assertUUIDLike(self, val, expected):