summaryrefslogtreecommitdiffstats
path: root/nova/tests
diff options
context:
space:
mode:
authorSalvatore Orlando <salvatore.orlando@eu.citrix.com>2011-04-06 14:28:05 +0100
committerSalvatore Orlando <salvatore.orlando@eu.citrix.com>2011-04-06 14:28:05 +0100
commite68174e419e105e174ce9f8b221e0ef201fa1990 (patch)
treef2ec46a474d7db41ea03ef144c5e387f403f8b74 /nova/tests
parent574980cf15f63c08d4d7d6ac4a406149cfb8bcaf (diff)
parentc0a8904508edb0687b588d40a7bd181d0393884f (diff)
Improved unit tests
Fixed docstring formatting Merged with trunk
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/api/openstack/test_faults.py122
-rw-r--r--nova/tests/api/openstack/test_images.py57
-rw-r--r--nova/tests/api/openstack/test_servers.py207
-rw-r--r--nova/tests/api/openstack/test_versions.py26
-rw-r--r--nova/tests/test_cloud.py33
-rw-r--r--nova/tests/test_xenapi.py41
-rw-r--r--nova/tests/xenapi/stubs.py14
7 files changed, 440 insertions, 60 deletions
diff --git a/nova/tests/api/openstack/test_faults.py b/nova/tests/api/openstack/test_faults.py
index 7667753f4..9746e8168 100644
--- a/nova/tests/api/openstack/test_faults.py
+++ b/nova/tests/api/openstack/test_faults.py
@@ -15,6 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import json
+
import webob
import webob.dec
import webob.exc
@@ -24,35 +26,115 @@ from nova.api.openstack import faults
class TestFaults(test.TestCase):
+ """Tests covering `nova.api.openstack.faults:Fault` class."""
- def test_fault_parts(self):
- req = webob.Request.blank('/.xml')
- f = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram'))
- resp = req.get_response(f)
+ def _prepare_xml(self, xml_string):
+ """Remove characters from string which hinder XML equality testing."""
+ xml_string = xml_string.replace(" ", "")
+ xml_string = xml_string.replace("\n", "")
+ xml_string = xml_string.replace("\t", "")
+ return xml_string
- first_two_words = resp.body.strip().split()[:2]
- self.assertEqual(first_two_words, ['<badRequest', 'code="400">'])
- body_without_spaces = ''.join(resp.body.split())
- self.assertTrue('<message>scram</message>' in body_without_spaces)
+ def test_400_fault_xml(self):
+ """Test fault serialized to XML via file-extension and/or header."""
+ requests = [
+ webob.Request.blank('/.xml'),
+ webob.Request.blank('/', headers={"Accept": "application/xml"}),
+ ]
- def test_retry_header(self):
- req = webob.Request.blank('/.xml')
- exc = webob.exc.HTTPRequestEntityTooLarge(explanation='sorry',
- headers={'Retry-After': 4})
- f = faults.Fault(exc)
- resp = req.get_response(f)
- first_two_words = resp.body.strip().split()[:2]
- self.assertEqual(first_two_words, ['<overLimit', 'code="413">'])
- body_sans_spaces = ''.join(resp.body.split())
- self.assertTrue('<message>sorry</message>' in body_sans_spaces)
- self.assertTrue('<retryAfter>4</retryAfter>' in body_sans_spaces)
- self.assertEqual(resp.headers['Retry-After'], 4)
+ for request in requests:
+ fault = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram'))
+ response = request.get_response(fault)
+
+ expected = self._prepare_xml("""
+ <badRequest code="400">
+ <message>scram</message>
+ </badRequest>
+ """)
+ actual = self._prepare_xml(response.body)
+
+ self.assertEqual(response.content_type, "application/xml")
+ self.assertEqual(expected, actual)
+
+ def test_400_fault_json(self):
+ """Test fault serialized to JSON via file-extension and/or header."""
+ requests = [
+ webob.Request.blank('/.json'),
+ webob.Request.blank('/', headers={"Accept": "application/json"}),
+ ]
+
+ for request in requests:
+ fault = faults.Fault(webob.exc.HTTPBadRequest(explanation='scram'))
+ response = request.get_response(fault)
+
+ expected = {
+ "badRequest": {
+ "message": "scram",
+ "code": 400,
+ },
+ }
+ actual = json.loads(response.body)
+
+ self.assertEqual(response.content_type, "application/json")
+ self.assertEqual(expected, actual)
+
+ def test_413_fault_xml(self):
+ requests = [
+ webob.Request.blank('/.xml'),
+ webob.Request.blank('/', headers={"Accept": "application/xml"}),
+ ]
+
+ for request in requests:
+ exc = webob.exc.HTTPRequestEntityTooLarge
+ fault = faults.Fault(exc(explanation='sorry',
+ headers={'Retry-After': 4}))
+ response = request.get_response(fault)
+
+ expected = self._prepare_xml("""
+ <overLimit code="413">
+ <message>sorry</message>
+ <retryAfter>4</retryAfter>
+ </overLimit>
+ """)
+ actual = self._prepare_xml(response.body)
+
+ self.assertEqual(expected, actual)
+ self.assertEqual(response.content_type, "application/xml")
+ self.assertEqual(response.headers['Retry-After'], 4)
+
+ def test_413_fault_json(self):
+ """Test fault serialized to JSON via file-extension and/or header."""
+ requests = [
+ webob.Request.blank('/.json'),
+ webob.Request.blank('/', headers={"Accept": "application/json"}),
+ ]
+
+ for request in requests:
+ exc = webob.exc.HTTPRequestEntityTooLarge
+ fault = faults.Fault(exc(explanation='sorry',
+ headers={'Retry-After': 4}))
+ response = request.get_response(fault)
+
+ expected = {
+ "overLimit": {
+ "message": "sorry",
+ "code": 413,
+ "retryAfter": 4,
+ },
+ }
+ actual = json.loads(response.body)
+
+ self.assertEqual(response.content_type, "application/json")
+ self.assertEqual(expected, actual)
def test_raise(self):
+ """Ensure the ability to raise `Fault`s in WSGI-ified methods."""
@webob.dec.wsgify
def raiser(req):
raise faults.Fault(webob.exc.HTTPNotFound(explanation='whut?'))
+
req = webob.Request.blank('/.xml')
resp = req.get_response(raiser)
+ self.assertEqual(resp.content_type, "application/xml")
self.assertEqual(resp.status_int, 404)
self.assertTrue('whut?' in resp.body)
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 57e447dce..69cc3116d 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -263,7 +263,8 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
{'id': 124, 'name': 'queued backup'},
{'id': 125, 'name': 'saving backup'},
{'id': 126, 'name': 'active backup'},
- {'id': 127, 'name': 'killed backup'}]
+ {'id': 127, 'name': 'killed backup'},
+ {'id': 129, 'name': None}]
self.assertDictListMatch(response_list, expected)
@@ -339,6 +340,24 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
self.assertEqual(expected_image.toxml(), actual_image.toxml())
+ def test_get_image_xml_no_name(self):
+ request = webob.Request.blank('/v1.0/images/129')
+ request.accept = "application/xml"
+ response = request.get_response(fakes.wsgi_app())
+
+ actual_image = minidom.parseString(response.body.replace(" ", ""))
+
+ expected_now = self.NOW_API_FORMAT
+ expected_image = minidom.parseString("""
+ <image id="129"
+ name="None"
+ updated="%(expected_now)s"
+ created="%(expected_now)s"
+ status="ACTIVE" />
+ """ % (locals()))
+
+ 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"
@@ -516,6 +535,13 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
'updated': self.NOW_API_FORMAT,
'created': self.NOW_API_FORMAT,
'status': 'FAILED',
+ },
+ {
+ 'id': 129,
+ 'name': None,
+ 'updated': self.NOW_API_FORMAT,
+ 'created': self.NOW_API_FORMAT,
+ 'status': 'ACTIVE',
}]
self.assertDictListMatch(expected, response_list)
@@ -635,7 +661,29 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
"type": "application/xml",
"href": "http://localhost/v1.1/images/127",
}],
- }]
+ },
+ {
+ 'id': 129,
+ 'name': None,
+ 'updated': self.NOW_API_FORMAT,
+ 'created': self.NOW_API_FORMAT,
+ 'status': 'ACTIVE',
+ "links": [{
+ "rel": "self",
+ "href": "http://localhost/v1.1/images/129",
+ },
+ {
+ "rel": "bookmark",
+ "type": "application/json",
+ "href": "http://localhost/v1.1/images/129",
+ },
+ {
+ "rel": "bookmark",
+ "type": "application/xml",
+ "href": "http://localhost/v1.1/images/129",
+ }],
+ },
+ ]
self.assertDictListMatch(expected, response_list)
@@ -694,4 +742,9 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
status='active', properties=other_backup_properties)
image_id += 1
+ # Image without a name
+ add_fixture(id=image_id, is_public=True, status='active',
+ properties={})
+ image_id += 1
+
return fixtures
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index 989385a8c..313676e72 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -377,7 +377,6 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
server = json.loads(res.body)['server']
- self.assertEqual('serv', server['adminPass'][:4])
self.assertEqual(16, len(server['adminPass']))
self.assertEqual('server_test', server['name'])
self.assertEqual(1, server['id'])
@@ -392,6 +391,74 @@ class ServersTest(test.TestCase):
fakes.stub_out_key_pair_funcs(self.stubs, have_key_pair=False)
self._test_create_instance_helper()
+ def test_create_instance_no_name(self):
+ self._setup_for_create_instance()
+
+ body = {
+ 'server': {
+ 'imageId': 3,
+ 'flavorId': 1,
+ 'metadata': {
+ 'hello': 'world',
+ 'open': 'stack',
+ },
+ 'personality': {},
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers')
+ 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, 400)
+
+ def test_create_instance_nonstring_name(self):
+ self._setup_for_create_instance()
+
+ body = {
+ 'server': {
+ 'name': 12,
+ 'imageId': 3,
+ 'flavorId': 1,
+ 'metadata': {
+ 'hello': 'world',
+ 'open': 'stack',
+ },
+ 'personality': {},
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers')
+ 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, 400)
+
+ def test_create_instance_whitespace_name(self):
+ self._setup_for_create_instance()
+
+ body = {
+ 'server': {
+ 'name': ' ',
+ 'imageId': 3,
+ 'flavorId': 1,
+ 'metadata': {
+ 'hello': 'world',
+ 'open': 'stack',
+ },
+ 'personality': {},
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers')
+ 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, 400)
+
def test_create_instance_v11(self):
self._setup_for_create_instance()
@@ -418,7 +485,6 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
server = json.loads(res.body)['server']
- self.assertEqual('serv', server['adminPass'][:4])
self.assertEqual(16, len(server['adminPass']))
self.assertEqual('server_test', server['name'])
self.assertEqual(1, server['id'])
@@ -448,39 +514,82 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 422)
- def test_update_bad_params(self):
+ def test_update_nonstring_name(self):
+ """ Confirm that update is filtering params """
+ inst_dict = dict(name=12, adminPass='bacon')
+ self.body = json.dumps(dict(server=inst_dict))
+
+ req = webob.Request.blank('/v1.0/servers/1')
+ req.method = 'PUT'
+ req.content_type = "application/json"
+ req.body = self.body
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
+ def test_update_whitespace_name(self):
""" Confirm that update is filtering params """
- inst_dict = dict(cat='leopard', name='server_test', adminPass='bacon')
+ inst_dict = dict(name=' ', adminPass='bacon')
+ self.body = json.dumps(dict(server=inst_dict))
+
+ req = webob.Request.blank('/v1.0/servers/1')
+ req.method = 'PUT'
+ req.content_type = "application/json"
+ req.body = self.body
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
+ def test_update_null_name(self):
+ """ Confirm that update is filtering params """
+ inst_dict = dict(name='', adminPass='bacon')
+ self.body = json.dumps(dict(server=inst_dict))
+
+ req = webob.Request.blank('/v1.0/servers/1')
+ req.method = 'PUT'
+ req.content_type = "application/json"
+ req.body = self.body
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
+ def test_update_server_v10(self):
+ inst_dict = dict(name='server_test', adminPass='bacon')
self.body = json.dumps(dict(server=inst_dict))
def server_update(context, id, params):
- self.update_called = True
- filtered_dict = dict(name='server_test', admin_pass='bacon')
+ filtered_dict = dict(
+ display_name='server_test',
+ admin_pass='bacon',
+ )
self.assertEqual(params, filtered_dict)
+ return filtered_dict
self.stubs.Set(nova.db.api, 'instance_update',
server_update)
req = webob.Request.blank('/v1.0/servers/1')
req.method = 'PUT'
+ req.content_type = "application/json"
req.body = self.body
- req.get_response(fakes.wsgi_app())
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 204)
- def test_update_server(self):
+ def test_update_server_adminPass_ignored_v11(self):
inst_dict = dict(name='server_test', adminPass='bacon')
self.body = json.dumps(dict(server=inst_dict))
def server_update(context, id, params):
- filtered_dict = dict(name='server_test', admin_pass='bacon')
+ filtered_dict = dict(display_name='server_test')
self.assertEqual(params, filtered_dict)
+ return filtered_dict
self.stubs.Set(nova.db.api, 'instance_update',
server_update)
- req = webob.Request.blank('/v1.0/servers/1')
+ req = webob.Request.blank('/v1.1/servers/1')
req.method = 'PUT'
+ req.content_type = "application/json"
req.body = self.body
- req.get_response(fakes.wsgi_app())
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 204)
def test_create_backup_schedules(self):
req = webob.Request.blank('/v1.0/servers/1/backup_schedule')
@@ -520,6 +629,7 @@ class ServersTest(test.TestCase):
self.assertEqual(s['name'], 'server%d' % i)
self.assertEqual(s['imageId'], '10')
self.assertEqual(s['flavorId'], '1')
+ self.assertEqual(s['status'], 'BUILD')
self.assertEqual(s['metadata']['seq'], i)
def test_get_all_server_details_v1_1(self):
@@ -533,6 +643,7 @@ class ServersTest(test.TestCase):
self.assertEqual(s['name'], 'server%d' % i)
self.assertEqual(s['imageRef'], 'http://localhost/v1.1/images/10')
self.assertEqual(s['flavorRef'], 'http://localhost/v1.1/flavors/1')
+ self.assertEqual(s['status'], 'BUILD')
self.assertEqual(s['metadata']['seq'], i)
def test_get_all_server_details_with_host(self):
@@ -653,6 +764,74 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 404)
+ def test_server_change_password(self):
+ body = {'changePassword': {'adminPass': '1234pass'}}
+ req = webob.Request.blank('/v1.0/servers/1/action')
+ req.method = 'POST'
+ req.content_type = 'application/json'
+ req.body = json.dumps(body)
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 501)
+
+ def test_server_change_password_v1_1(self):
+
+ class MockSetAdminPassword(object):
+ def __init__(self):
+ self.instance_id = None
+ self.password = None
+
+ def __call__(self, context, instance_id, password):
+ self.instance_id = instance_id
+ self.password = password
+
+ mock_method = MockSetAdminPassword()
+ self.stubs.Set(nova.compute.api.API, 'set_admin_password', mock_method)
+ body = {'changePassword': {'adminPass': '1234pass'}}
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.content_type = 'application/json'
+ req.body = json.dumps(body)
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 202)
+ self.assertEqual(mock_method.instance_id, '1')
+ self.assertEqual(mock_method.password, '1234pass')
+
+ def test_server_change_password_bad_request_v1_1(self):
+ body = {'changePassword': {'pass': '12345'}}
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.content_type = 'application/json'
+ req.body = json.dumps(body)
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
+ def test_server_change_password_empty_string_v1_1(self):
+ body = {'changePassword': {'adminPass': ''}}
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.content_type = 'application/json'
+ req.body = json.dumps(body)
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
+ def test_server_change_password_none_v1_1(self):
+ body = {'changePassword': {'adminPass': None}}
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.content_type = 'application/json'
+ req.body = json.dumps(body)
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
+ def test_server_change_password_not_a_string_v1_1(self):
+ body = {'changePassword': {'adminPass': 1234}}
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.content_type = 'application/json'
+ req.body = json.dumps(body)
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 400)
+
def test_server_reboot(self):
body = dict(server=dict(
name='server_test', imageId=2, flavorId=2, metadata={},
@@ -738,7 +917,7 @@ class ServersTest(test.TestCase):
fake_migration_get)
res = req.get_response(fakes.wsgi_app())
body = json.loads(res.body)
- self.assertEqual(body['server']['status'], 'resize-confirm')
+ self.assertEqual(body['server']['status'], 'RESIZE-CONFIRM')
def test_confirm_resize_server(self):
req = self.webreq('/1/action', 'POST', dict(confirmResize=None))
@@ -1315,7 +1494,7 @@ class TestServerInstanceCreation(test.TestCase):
self.assertEquals(response.status_int, 200)
response = json.loads(response.body)
self.assertTrue('adminPass' in response['server'])
- self.assertTrue(response['server']['adminPass'].startswith('fake'))
+ self.assertEqual(16, len(response['server']['adminPass']))
def test_create_instance_admin_pass_xml(self):
request, response, dummy = \
@@ -1324,7 +1503,7 @@ class TestServerInstanceCreation(test.TestCase):
dom = minidom.parseString(response.body)
server = dom.childNodes[0]
self.assertEquals(server.nodeName, 'server')
- self.assertTrue(server.getAttribute('adminPass').startswith('fake'))
+ self.assertEqual(16, len(server.getAttribute('adminPass')))
class TestGetKernelRamdiskFromImage(test.TestCase):
diff --git a/nova/tests/api/openstack/test_versions.py b/nova/tests/api/openstack/test_versions.py
index ebb59a9a6..2640a4ddb 100644
--- a/nova/tests/api/openstack/test_versions.py
+++ b/nova/tests/api/openstack/test_versions.py
@@ -34,8 +34,10 @@ class VersionsTest(test.TestCase):
def test_get_version_list(self):
req = webob.Request.blank('/')
+ req.accept = "application/json"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
+ self.assertEqual(res.content_type, "application/json")
versions = json.loads(res.body)["versions"]
expected = [
{
@@ -61,6 +63,30 @@ class VersionsTest(test.TestCase):
]
self.assertEqual(versions, expected)
+ def test_get_version_list_xml(self):
+ req = webob.Request.blank('/')
+ req.accept = "application/xml"
+ res = req.get_response(fakes.wsgi_app())
+ self.assertEqual(res.status_int, 200)
+ self.assertEqual(res.content_type, "application/xml")
+
+ expected = """<versions>
+ <version id="v1.1" status="CURRENT">
+ <links>
+ <link href="http://localhost/v1.1" rel="self"/>
+ </links>
+ </version>
+ <version id="v1.0" status="DEPRECATED">
+ <links>
+ <link href="http://localhost/v1.0" rel="self"/>
+ </links>
+ </version>
+ </versions>""".replace(" ", "").replace("\n", "")
+
+ actual = res.body.replace(" ", "").replace("\n", "")
+
+ self.assertEqual(expected, actual)
+
def test_view_builder(self):
base_url = "http://example.org/"
diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py
index 00803d0ad..5cb969979 100644
--- a/nova/tests/test_cloud.py
+++ b/nova/tests/test_cloud.py
@@ -41,6 +41,7 @@ from nova.compute import power_state
from nova.api.ec2 import cloud
from nova.api.ec2 import ec2utils
from nova.image import local
+from nova.exception import NotFound
FLAGS = flags.FLAGS
@@ -71,7 +72,8 @@ class CloudTestCase(test.TestCase):
host = self.network.get_network_host(self.context.elevated())
def fake_show(meh, context, id):
- return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}}
+ return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
+ 'type': 'machine'}}
self.stubs.Set(local.LocalImageService, 'show', fake_show)
self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show)
@@ -216,6 +218,35 @@ class CloudTestCase(test.TestCase):
db.service_destroy(self.context, comp1['id'])
db.service_destroy(self.context, comp2['id'])
+ def test_describe_images(self):
+ describe_images = self.cloud.describe_images
+
+ def fake_detail(meh, context):
+ return [{'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
+ 'type': 'machine'}}]
+
+ def fake_show_none(meh, context, id):
+ raise NotFound
+
+ self.stubs.Set(local.LocalImageService, 'detail', fake_detail)
+ # list all
+ result1 = describe_images(self.context)
+ result1 = result1['imagesSet'][0]
+ self.assertEqual(result1['imageId'], 'ami-00000001')
+ # provided a valid image_id
+ result2 = describe_images(self.context, ['ami-00000001'])
+ self.assertEqual(1, len(result2['imagesSet']))
+ # provide more than 1 valid image_id
+ result3 = describe_images(self.context, ['ami-00000001',
+ 'ami-00000002'])
+ self.assertEqual(2, len(result3['imagesSet']))
+ # provide an non-existing image_id
+ self.stubs.UnsetAll()
+ self.stubs.Set(local.LocalImageService, 'show', fake_show_none)
+ self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show_none)
+ self.assertRaises(NotFound, describe_images,
+ self.context, ['ami-fake'])
+
def test_console_output(self):
instance_type = FLAGS.default_instance_type
max_count = 1
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 01d46b21d..3cdbd681a 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -188,7 +188,7 @@ class XenAPIVMTestCase(test.TestCase):
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
stubs.stubout_get_this_vm_uuid(self.stubs)
stubs.stubout_stream_disk(self.stubs)
- stubs.stubout_is_vdi_pv(self.stubs)
+ stubs.stubout_determine_is_pv_objectstore(self.stubs)
self.stubs.Set(VMOps, 'reset_network', reset_network)
stubs.stub_out_vm_methods(self.stubs)
glance_stubs.stubout_glance_client(self.stubs,
@@ -327,18 +327,17 @@ class XenAPIVMTestCase(test.TestCase):
self.assertEquals(self.vm['HVM_boot_params'], {})
self.assertEquals(self.vm['HVM_boot_policy'], '')
- def _check_no_unbound_vdi(self):
+ def _list_vdis(self):
url = FLAGS.xenapi_connection_url
username = FLAGS.xenapi_connection_username
password = FLAGS.xenapi_connection_password
session = xenapi_conn.XenAPISession(url, username, password)
- vdi_refs = session.call_xenapi('VDI.get_all')
- for vdi_ref in vdi_refs:
- vdi_rec = session.call_xenapi('VDI.get_record', vdi_ref)
- if 'VBDs' in vdi_rec:
- self.assertEquals(vdi_rec['VBDs'], {})
- else:
- self.fail('Found unexpected unbound VDI:%s' % vdi_rec['uuid'])
+ return session.call_xenapi('VDI.get_all')
+
+ def _check_vdis(self, start_list, end_list):
+ for vdi_ref in end_list:
+ if not vdi_ref in start_list:
+ self.fail('Found unexpected VDI:%s' % vdi_ref)
def _test_spawn(self, image_id, kernel_id, ramdisk_id,
instance_type="m1.large", os_type="linux",
@@ -365,28 +364,32 @@ class XenAPIVMTestCase(test.TestCase):
1, 2, 3, "m1.xlarge")
def test_spawn_fail_cleanup_1(self):
+ """Simulates an error while downloading an image.
+ Verifies that VDIs created are properly cleaned up.
+
"""
- Simulates an error while downloading image
- Verifies VDI create are properly cleaned up.
- """
+ vdi_recs_start = self._list_vdis()
FLAGS.xenapi_image_service = 'glance'
stubs.stubout_fetch_image_glance_disk(self.stubs)
self.assertRaises(xenapi_fake.Failure,
self._test_spawn, 1, 2, 3)
- # ensure there is no VDI without a VBD
- self._check_no_unbound_vdi()
+ # no new VDI should be found
+ vdi_recs_end = self._list_vdis()
+ self._check_vdis(vdi_recs_start, vdi_recs_end)
def test_spawn_fail_cleanup_2(self):
+ """Simulates an error while creating VM record. It
+ verifies that VDIs created are properly cleaned up.
+
"""
- Simulates an error while creating VM record. It
- verifies that VDI created are properly cleaned up.
- """
+ vdi_recs_start = self._list_vdis()
FLAGS.xenapi_image_service = 'glance'
stubs.stubout_create_vm(self.stubs)
self.assertRaises(xenapi_fake.Failure,
self._test_spawn, 1, 2, 3)
- # ensure there is no VDI without a VBD
- self._check_no_unbound_vdi()
+ # no new VDI should be found
+ vdi_recs_end = self._list_vdis()
+ self._check_vdis(vdi_recs_start, vdi_recs_end)
def test_spawn_raw_objectstore(self):
FLAGS.xenapi_image_service = 'objectstore'
diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py
index 62457ea16..8b34f7cd4 100644
--- a/nova/tests/xenapi/stubs.py
+++ b/nova/tests/xenapi/stubs.py
@@ -132,10 +132,13 @@ def stubout_stream_disk(stubs):
stubs.Set(vm_utils, '_stream_disk', f)
-def stubout_is_vdi_pv(stubs):
- def f(_1):
+def stubout_determine_is_pv_objectstore(stubs):
+ """Assumes VMs never have PV kernels"""
+
+ @classmethod
+ def f(cls, *args):
return False
- stubs.Set(vm_utils, '_is_vdi_pv', f)
+ stubs.Set(vm_utils.VMHelper, '_determine_is_pv_objectstore', f)
def stubout_lookup_image(stubs):
@@ -176,7 +179,10 @@ class FakeSessionForVMTests(fake.SessionBase):
def __init__(self, uri):
super(FakeSessionForVMTests, self).__init__(uri)
- def host_call_plugin(self, _1, _2, _3, _4, _5):
+ def host_call_plugin(self, _1, _2, plugin, fn, args):
+ # copy_kernel_vdi returns nothing
+ if fn == 'copy_kernel_vdi':
+ return
sr_ref = fake.get_all('SR')[0]
vdi_ref = fake.create_vdi('', False, sr_ref, False)
vdi_rec = fake.get_record('VDI', vdi_ref)