summaryrefslogtreecommitdiffstats
path: root/nova/tests
diff options
context:
space:
mode:
authorBrian Waldon <brian.waldon@rackspace.com>2011-08-02 19:03:33 +0000
committerTarmac <>2011-08-02 19:03:33 +0000
commit65ba8bda43aa79080f6fec9c396f412c294718b8 (patch)
treead3a289dae895fa73734261253c08df0300be956 /nova/tests
parentcf7eefab9e7891d449b115c0c50c4b76ae45743f (diff)
parentb65c7e2378d8344d1948fe4cf0dde66ef34b7204 (diff)
Moves image creation from POST /images to POST /servers/<id>/action
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/api/openstack/test_images.py256
-rw-r--r--nova/tests/api/openstack/test_servers.py275
2 files changed, 274 insertions, 257 deletions
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 8c5ad7f8d..942c0b333 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -1042,82 +1042,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
response = req.get_response(fakes.wsgi_app())
self.assertEqual(400, response.status_int)
- def test_create_backup_no_name(self):
- """Name is also required for backups"""
- body = dict(image=dict(serverId='123', image_type='backup',
- backup_type='daily', rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_backup_with_rotation_and_backup_type(self):
- """The happy path for creating backups
-
- Creating a backup is an admin-only operation, as opposed to snapshots
- which are available to anybody.
- """
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', image_type='backup',
- name='Backup 1',
- backup_type='daily', rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
-
- def test_create_backup_no_rotation(self):
- """Rotation is required for backup requests"""
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', name='daily',
- image_type='backup', backup_type='daily'))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_backup_no_backup_type(self):
- """Backup Type (daily or weekly) is required for backup requests"""
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', name='daily',
- image_type='backup', rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_with_invalid_image_type(self):
- """Valid image_types are snapshot | daily | weekly"""
- # FIXME(sirp): teardown needed?
- FLAGS.allow_admin_api = True
-
- # FIXME(sirp): should the fact that backups are admin_only be a FLAG
- body = dict(image=dict(serverId='123', image_type='monthly',
- rotation=1))
- req = webob.Request.blank('/v1.0/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
def test_create_image_no_server_id(self):
body = dict(image=dict(name='Snapshot 1'))
@@ -1128,113 +1052,6 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
response = req.get_response(fakes.wsgi_app())
self.assertEqual(400, response.status_int)
- def test_create_image_v1_1(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"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
-
- def test_create_image_v1_1_actual_server_ref(self):
-
- serverRef = 'http://localhost/v1.1/servers/1'
- serverBookmark = 'http://localhost/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
- result = json.loads(response.body)
- expected = {
- 'id': 1,
- 'links': [
- {
- 'rel': 'self',
- 'href': serverRef,
- },
- {
- 'rel': 'bookmark',
- 'href': serverBookmark,
- },
- ]
- }
- self.assertEqual(result['image']['server'], expected)
-
- def test_create_image_v1_1_actual_server_ref_port(self):
-
- serverRef = 'http://localhost:8774/v1.1/servers/1'
- serverBookmark = 'http://localhost:8774/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(200, response.status_int)
- result = json.loads(response.body)
- expected = {
- 'id': 1,
- 'links': [
- {
- 'rel': 'self',
- 'href': serverRef,
- },
- {
- 'rel': 'bookmark',
- 'href': serverBookmark,
- },
- ]
- }
- self.assertEqual(result['image']['server'], expected)
-
- def test_create_image_v1_1_server_ref_bad_hostname(self):
-
- serverRef = 'http://asdf/v1.1/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_v1_1_no_server_ref(self):
-
- body = dict(image=dict(name='Snapshot 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_v1_1_server_ref_missing_version(self):
-
- serverRef = 'http://localhost/servers/1'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
- def test_create_image_v1_1_server_ref_missing_id(self):
-
- serverRef = 'http://localhost/v1.1/servers'
- body = dict(image=dict(serverRef=serverRef, name='Backup 1'))
- req = webob.Request.blank('/v1.1/images')
- req.method = 'POST'
- req.body = json.dumps(body)
- req.headers["content-type"] = "application/json"
- response = req.get_response(fakes.wsgi_app())
- self.assertEqual(400, response.status_int)
-
@classmethod
def _make_image_fixtures(cls):
image_id = 123
@@ -1713,76 +1530,3 @@ class ImageXMLSerializationTest(test.TestCase):
""".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,
- 'status': 'SAVING',
- '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, 'create')
- 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="SAVING"
- 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()))
-
- self.assertEqual(expected.toxml(), actual.toxml())
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index 14ce42837..1871cac96 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -260,6 +260,17 @@ class ServersTest(test.TestCase):
self.stubs.Set(nova.compute.API, "get_diagnostics", fake_compute_api)
self.stubs.Set(nova.compute.API, "get_actions", fake_compute_api)
+ fakes.stub_out_glance(self.stubs)
+ fakes.stub_out_compute_api_snapshot(self.stubs)
+ service_class = 'nova.image.glance.GlanceImageService'
+ self.service = utils.import_object(service_class)
+ self.context = context.RequestContext(1, None)
+ self.service.delete_all()
+ self.sent_to_glance = {}
+ fakes.stub_out_glance_add_image(self.stubs, self.sent_to_glance)
+
+ self.allow_admin = FLAGS.allow_admin_api
+
self.webreq = common.webob_factory('/v1.0/servers')
def test_get_server_by_id(self):
@@ -2346,6 +2357,268 @@ class ServersTest(test.TestCase):
res_dict = json.loads(res.body)
self.assertEqual(res_dict['server']['status'], 'SHUTOFF')
+ def test_create_image_v1_1(self):
+ body = {
+ 'createImage': {
+ 'name': 'Snapshot 1',
+ },
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ location = response.headers['Location']
+ self.assertEqual('http://localhost/v1.1/images/123', location)
+
+ def test_create_image_v1_1_with_metadata(self):
+ body = {
+ 'createImage': {
+ 'name': 'Snapshot 1',
+ 'metadata': {'key': 'asdf'},
+ },
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ location = response.headers['Location']
+ self.assertEqual('http://localhost/v1.1/images/123', location)
+
+ def test_create_image_v1_1_no_name(self):
+ body = {
+ 'createImage': {},
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_image_v1_1_bad_metadata(self):
+ body = {
+ 'createImage': {
+ 'name': 'geoff',
+ 'metadata': 'henry',
+ },
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup(self):
+ """The happy path for creating backups"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ self.assertTrue(response.headers['Location'])
+
+ def test_create_backup_v1_1(self):
+ """The happy path for creating backups through v1.1 api"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ self.assertTrue(response.headers['Location'])
+
+ def test_create_backup_admin_api_off(self):
+ """The happy path for creating backups"""
+ FLAGS.allow_admin_api = False
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(501, response.status_int)
+
+ def test_create_backup_with_metadata(self):
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ 'metadata': {'123': 'asdf'},
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(202, response.status_int)
+ self.assertTrue(response.headers['Location'])
+
+ def test_create_backup_no_name(self):
+ """Name is required for backups"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'backup_type': 'daily',
+ 'rotation': 1,
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup_no_rotation(self):
+ """Rotation is required for backup requests"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'backup_type': 'daily',
+ },
+ }
+
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup_no_backup_type(self):
+ """Backup Type (daily or weekly) is required for backup requests"""
+ FLAGS.allow_admin_api = True
+
+ body = {
+ 'createBackup': {
+ 'name': 'Backup 1',
+ 'rotation': 1,
+ },
+ }
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+ def test_create_backup_bad_entity(self):
+ FLAGS.allow_admin_api = True
+
+ body = {'createBackup': 'go'}
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
+
+class TestServerActionXMLDeserializer(test.TestCase):
+
+ def setUp(self):
+ self.deserializer = create_instance_helper.ServerXMLDeserializer()
+
+ def tearDown(self):
+ pass
+
+ def test_create_image(self):
+ serial_request = """
+<createImage xmlns="http://docs.openstack.org/compute/api/v1.1"
+ name="new-server-test"/>"""
+ request = self.deserializer.deserialize(serial_request, 'action')
+ expected = {
+ "createImage": {
+ "name": "new-server-test",
+ "metadata": {},
+ },
+ }
+ self.assertEquals(request['body'], expected)
+
+ def test_create_image_with_metadata(self):
+ serial_request = """
+<createImage xmlns="http://docs.openstack.org/compute/api/v1.1"
+ name="new-server-test">
+ <metadata>
+ <meta key="key1">value1</meta>
+ </metadata>
+</createImage>"""
+ request = self.deserializer.deserialize(serial_request, 'action')
+ expected = {
+ "createImage": {
+ "name": "new-server-test",
+ "metadata": {"key1": "value1"},
+ },
+ }
+ self.assertEquals(request['body'], expected)
+
+ def test_create_backup_with_metadata(self):
+ serial_request = """
+<createBackup xmlns="http://docs.openstack.org/compute/api/v1.1"
+ name="new-server-test"
+ rotation="12"
+ backup_type="daily">
+ <metadata>
+ <meta key="key1">value1</meta>
+ </metadata>
+</createBackup>"""
+ request = self.deserializer.deserialize(serial_request, 'action')
+ expected = {
+ "createBackup": {
+ "name": "new-server-test",
+ "rotation": "12",
+ "backup_type": "daily",
+ "metadata": {"key1": "value1"},
+ },
+ }
+ self.assertEquals(request['body'], expected)
+
class TestServerCreateRequestXMLDeserializerV10(unittest.TestCase):
@@ -2815,7 +3088,7 @@ class TestServerCreateRequestXMLDeserializerV11(unittest.TestCase):
self.assertEquals(request['body'], expected)
-class TextAddressesXMLSerialization(test.TestCase):
+class TestAddressesXMLSerialization(test.TestCase):
serializer = nova.api.openstack.ips.IPXMLSerializer()