From 6e269b1e0b9c768b0977be140c48cc5229564177 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Wed, 9 Mar 2011 11:12:24 +0000 Subject: Added unit tests for ensuring VDI are cleaned up upon spawn failures --- nova/tests/test_xenapi.py | 30 ++++++++++++++++++++++++++++++ nova/tests/xenapi/stubs.py | 23 +++++++++++++++++++++++ 2 files changed, 53 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 106c0bd6f..7e57dd7d4 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -251,6 +251,16 @@ class XenAPIVMTestCase(test.TestCase): # Check that the VM is running according to XenAPI. self.assertEquals(vm['power_state'], 'Running') + def _check_no_unbound_vdi(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) + self.assertEquals(vdi_rec['VBDs'], {}) + def _test_spawn(self, image_id, kernel_id, ramdisk_id, instance_type="m1.large"): stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests) @@ -275,6 +285,26 @@ class XenAPIVMTestCase(test.TestCase): self._test_spawn, 1, 2, 3, "m1.xlarge") + def test_spawn_fail_cleanup_1(self): + """Simulates an error while downloading image + Verifies VDI create are properly cleaned up""" + FLAGS.xenapi_image_service = 'glance' + stubs.stubout_fetch_image_glance_disk(self.stubs) + self.assertRaises(Exception, + self._test_spawn, 1, 2, 3) + #ensure there is no VDI without a VBD + self._check_no_unbound_vdi() + + def test_spawn_fail_cleanup_2(self): + """Simulates an error while creating VM record. + Verifies VDI create are properly cleaned up""" + FLAGS.xenapi_image_service = 'glance' + stubs.stubout_create_vm(self.stubs) + self.assertRaises(Exception, + self._test_spawn, 1, 2, 3) + #ensure there is no VDI without a VBD + self._check_no_unbound_vdi() + def test_spawn_raw_objectstore(self): FLAGS.xenapi_image_service = 'objectstore' self._test_spawn(1, None, None) diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 3de73d617..285cf2d53 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -136,6 +136,29 @@ def stubout_is_vdi_pv(stubs): stubs.Set(vm_utils, '_is_vdi_pv', f) +def stubout_lookup_image(stubs): + """Simulates a failure in lookup image""" + def f(_1, _2, _3, _4): + raise Exception("Test Exception raised by fake lookup_image") + stubs.Set(vm_utils, 'lookup_image', f) + + +def stubout_fetch_image_glance_disk(stubs): + """Simulates a failure in fetch image_glance_disk""" + def f(_1, _2, _3, _4, _5, _6): + raise Exception("Test Exception raised by " + + "fake fetch_image_glance_disk") + stubs.Set(vm_utils.VMHelper, '_fetch_image_glance_disk', f) + + +def stubout_create_vm(stubs): + """Simulates a failure in create_vm""" + def f(_1, _2, _3, _4, _5, _6): + raise Exception("Test Exception raised by " + + "fake create_vm") + stubs.Set(vm_utils.VMHelper, 'create_vm', f) + + class FakeSessionForVMTests(fake.SessionBase): """ Stubs out a XenAPISession for VM tests """ def __init__(self, uri): -- cgit From e2aed1036c0fb61a2924ffa28d66f87539d43ba1 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Mon, 14 Mar 2011 14:52:19 +0000 Subject: Fixed pep8 errors --- nova/tests/db/fakes.py | 2 +- nova/tests/test_xenapi.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py index 142f6b1c6..22a60e012 100644 --- a/nova/tests/db/fakes.py +++ b/nova/tests/db/fakes.py @@ -77,7 +77,7 @@ def stub_out_db_instance_api(stubs): 'mac_address': values['mac_address'], 'vcpus': type_data['vcpus'], 'local_gb': type_data['local_gb'], - 'os_type': values['os_type'] + 'os_type': values['os_type'], } return FakeModel(base_options) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 60ef39cbb..7119f3078 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -78,7 +78,7 @@ class XenAPIVolumeTestCase(test.TestCase): 'ramdisk_id': 3, 'instance_type': 'm1.large', 'mac_address': 'aa:bb:cc:dd:ee:ff', - 'os_type': 'linux' + 'os_type': 'linux', } def _create_volume(self, size='0'): @@ -328,7 +328,7 @@ class XenAPIVMTestCase(test.TestCase): 'ramdisk_id': ramdisk_id, 'instance_type': instance_type, 'mac_address': 'aa:bb:cc:dd:ee:ff', - 'os_type': os_type + 'os_type': os_type, } conn = xenapi_conn.get_connection(False) instance = db.instance_create(values) @@ -473,7 +473,7 @@ class XenAPIMigrateInstance(test.TestCase): 'ramdisk_id': None, 'instance_type': 'm1.large', 'mac_address': 'aa:bb:cc:dd:ee:ff', - 'os_type': 'linux' + 'os_type': 'linux', } stubs.stub_out_migration_methods(self.stubs) glance_stubs.stubout_glance_client(self.stubs, -- cgit From 7649a9af1fb04886a25124b92e6ba4f88c1fd0b0 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Thu, 17 Mar 2011 11:19:03 +0000 Subject: Improved exception handling: - catching appropriate errors (OSError, IOError, XenAPI.Failure) - reduced size of try blocks - moved exception handling code in separate method - verifing for appropriate exeception type in unit tests --- nova/tests/test_xenapi.py | 4 ++-- nova/tests/xenapi/stubs.py | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index a65aecf6b..8a8b13933 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -346,7 +346,7 @@ class XenAPIVMTestCase(test.TestCase): Verifies VDI create are properly cleaned up""" FLAGS.xenapi_image_service = 'glance' stubs.stubout_fetch_image_glance_disk(self.stubs) - self.assertRaises(Exception, + self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) #ensure there is no VDI without a VBD self._check_no_unbound_vdi() @@ -356,7 +356,7 @@ class XenAPIVMTestCase(test.TestCase): Verifies VDI create are properly cleaned up""" FLAGS.xenapi_image_service = 'glance' stubs.stubout_create_vm(self.stubs) - self.assertRaises(Exception, + self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) #ensure there is no VDI without a VBD self._check_no_unbound_vdi() diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 6d050db04..924cecf2c 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -146,17 +146,21 @@ def stubout_lookup_image(stubs): def stubout_fetch_image_glance_disk(stubs): """Simulates a failure in fetch image_glance_disk""" - def f(_1, _2, _3, _4, _5, _6): - raise Exception("Test Exception raised by " + - "fake fetch_image_glance_disk") + + @classmethod + def f(cls, *args): + raise fake.Failure("Test Exception raised by " + + "fake fetch_image_glance_disk") stubs.Set(vm_utils.VMHelper, '_fetch_image_glance_disk', f) def stubout_create_vm(stubs): """Simulates a failure in create_vm""" - def f(_1, _2, _3, _4, _5, _6): - raise Exception("Test Exception raised by " + - "fake create_vm") + + @classmethod + def f(cls, *args): + raise fake.Failure("Test Exception raised by " + + "fake create_vm") stubs.Set(vm_utils.VMHelper, 'create_vm', f) -- cgit From 381354babab58688458b2a6cdc463eb0a0fee461 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Mon, 28 Mar 2011 13:11:45 +0100 Subject: addressed reviewers' concerns --- nova/tests/test_xenapi.py | 35 +++++++++++++++++++---------------- nova/tests/xenapi/stubs.py | 6 +++--- 2 files changed, 22 insertions(+), 19 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 1c5a81f0d..feaced8ac 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -343,8 +343,10 @@ class XenAPIVMTestCase(test.TestCase): 1, 2, 3, "m1.xlarge") def test_spawn_fail_cleanup_1(self): - """Simulates an error while downloading image - Verifies VDI create are properly cleaned up""" + """ + Simulates an error while downloading image + Verifies VDI create are properly cleaned up. + """ FLAGS.xenapi_image_service = 'glance' stubs.stubout_fetch_image_glance_disk(self.stubs) self.assertRaises(xenapi_fake.Failure, @@ -353,8 +355,10 @@ class XenAPIVMTestCase(test.TestCase): self._check_no_unbound_vdi() def test_spawn_fail_cleanup_2(self): - """Simulates an error while creating VM record. - Verifies VDI create are properly cleaned up""" + """ + Simulates an error while creating VM record. It + verifies that VDI created are properly cleaned up. + """ FLAGS.xenapi_image_service = 'glance' stubs.stubout_create_vm(self.stubs) self.assertRaises(xenapi_fake.Failure, @@ -423,18 +427,17 @@ class XenAPIVMTestCase(test.TestCase): self.stubs.UnsetAll() def _create_instance(self): - """Creates and spawns a test instance""" - values = { - 'name': 1, - 'id': 1, - 'project_id': self.project.id, - 'user_id': self.user.id, - 'image_id': 1, - 'kernel_id': 2, - 'ramdisk_id': 3, - 'instance_type': 'm1.large', - 'mac_address': 'aa:bb:cc:dd:ee:ff', - 'os_type': 'linux'} + """Creates and spawns a test instance.""" + values = {'name': 1, + 'id': 1, + 'project_id': self.project.id, + 'user_id': self.user.id, + 'image_id': 1, + 'kernel_id': 2, + 'ramdisk_id': 3, + 'instance_type': 'm1.large', + 'mac_address': 'aa:bb:cc:dd:ee:ff', + 'os_type': 'linux'} instance = db.instance_create(values) self.conn.spawn(instance) return instance diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 709a8b6ff..b745205f5 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -138,14 +138,14 @@ def stubout_is_vdi_pv(stubs): def stubout_lookup_image(stubs): - """Simulates a failure in lookup image""" + """Simulates a failure in lookup image.""" def f(_1, _2, _3, _4): raise Exception("Test Exception raised by fake lookup_image") stubs.Set(vm_utils, 'lookup_image', f) def stubout_fetch_image_glance_disk(stubs): - """Simulates a failure in fetch image_glance_disk""" + """Simulates a failure in fetch image_glance_disk.""" @classmethod def f(cls, *args): @@ -155,7 +155,7 @@ def stubout_fetch_image_glance_disk(stubs): def stubout_create_vm(stubs): - """Simulates a failure in create_vm""" + """Simulates a failure in create_vm.""" @classmethod def f(cls, *args): -- cgit From e722689c7b82bbf895213c2ebf9afaf34f292662 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Wed, 15 Jun 2011 12:31:20 +0100 Subject: Fixing code to ensure unit tests for objectstore, vhd & snapshots pass --- nova/tests/test_xenapi.py | 12 ++++++++++++ nova/tests/xenapi/stubs.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 7b6ceeb37..cddade0ce 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -350,6 +350,18 @@ class XenAPIVMTestCase(test.TestCase): self.assertEquals(self.vm['HVM_boot_params'], {}) self.assertEquals(self.vm['HVM_boot_policy'], '') + 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) + 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_ref, kernel_id, ramdisk_id, instance_type_id="3", os_type="linux", instance_id=1, check_injection=False): diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 0ecf83187..91731ad01 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -151,7 +151,7 @@ class FakeSessionForVMTests(fake.SessionBase): def host_call_plugin(self, _1, _2, plugin, method, _5): # copy_kernel_vdi returns nothing - if fn == 'copy_kernel_vdi': + if method == 'copy_kernel_vdi': return sr_ref = fake.get_all('SR')[0] vdi_ref = fake.create_vdi('', False, sr_ref, False) -- cgit From 3f2c0521f1c8462380c68d5245b5754867738fa1 Mon Sep 17 00:00:00 2001 From: John Tran Date: Tue, 21 Jun 2011 18:14:31 -0700 Subject: ec2 api describe_security_groups allow group_id param , added tests for create/delete security group in test_cloud although also exists in test_api this tests directly the ec2 method. --- nova/tests/test_cloud.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 6327734f5..2bd5979e7 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -165,6 +165,15 @@ class CloudTestCase(test.TestCase): sec['name']) db.security_group_destroy(self.context, sec['id']) + def test_create_delete_security_group(self): + descript = 'test description' + create = self.cloud.create_security_group + result = create(self.context, 'testgrp', descript) + group_descript = result['securityGroupSet'][0]['groupDescription'] + self.assertEqual(descript, group_descript) + delete = self.cloud.delete_security_group + self.assertTrue(delete(self.context, 'testgrp')) + def test_describe_volumes(self): """Makes sure describe_volumes works and filters results.""" vol1 = db.volume_create(self.context, {}) -- cgit From d5206c7f41c435fd39c1bb9c0fd7ec53c9685f43 Mon Sep 17 00:00:00 2001 From: John Tran Date: Thu, 23 Jun 2011 11:31:22 -0700 Subject: altho security_group authorize & revoke tests already exist in test_api, adding some direct ec2 api method tests. added group_id param support to the pertinent security group methods --- nova/tests/test_cloud.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 2bd5979e7..8cbab09a9 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -165,6 +165,27 @@ class CloudTestCase(test.TestCase): sec['name']) db.security_group_destroy(self.context, sec['id']) + def test_describe_security_groups_by_id(self): + sec = db.security_group_create(self.context, + {'project_id': self.context.project_id, + 'name': 'test'}) + result = self.cloud.describe_security_groups(self.context, + group_id=[sec['id']]) + self.assertEqual(len(result['securityGroupInfo']), 1) + self.assertEqual( + result['securityGroupInfo'][0]['groupName'], + sec['name']) + default = db.security_group_get_by_name(self.context, + self.context.project_id, + 'default') + result = self.cloud.describe_security_groups(self.context, + group_id=[default['id']]) + self.assertEqual(len(result['securityGroupInfo']), 1) + self.assertEqual( + result['securityGroupInfo'][0]['groupName'], + 'default') + db.security_group_destroy(self.context, sec['id']) + def test_create_delete_security_group(self): descript = 'test description' create = self.cloud.create_security_group @@ -174,6 +195,56 @@ class CloudTestCase(test.TestCase): delete = self.cloud.delete_security_group self.assertTrue(delete(self.context, 'testgrp')) + def test_delete_security_group_by_id(self): + sec = db.security_group_create(self.context, + {'project_id': self.context.project_id, + 'name': 'test'}) + delete = self.cloud.delete_security_group + notfound = exception.SecurityGroupNotFound + self.assertRaises(notfound, delete, self.context, 'badname') + self.assertRaises(notfound, delete, self.context, group_id=999) + self.assertRaises(exception.ApiError, delete, self.context) + self.assertTrue(delete(self.context, group_id=sec['id'])) + + def test_authorize_revoke_security_group_ingress(self): + sec = db.security_group_create(self.context, + {'project_id': self.context.project_id, + 'name': 'test'}) + authz = self.cloud.authorize_security_group_ingress + self.assertRaises(exception.ApiError, authz, self.context, sec['name']) + kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} + # ApiError: Not enough parameters, need group_name or group_id + self.assertRaises(exception.ApiError, authz, self.context, **kwargs) + authz(self.context, group_name=sec['name'], **kwargs) + # ApiError: This rule already exists in group test + self.assertRaises(exception.ApiError, authz, self.context, + group_name=sec['name'], **kwargs) + revoke = self.cloud.revoke_security_group_ingress + # ApiError: Not enough parameters, need group_name or group_id + self.assertRaises(exception.ApiError, revoke, self.context, **kwargs) + self.assertTrue(revoke(self.context, group_name=sec['name'], **kwargs)) + + def test_authorize_revoke_security_group_ingress_by_id(self): + sec = db.security_group_create(self.context, + {'project_id': self.context.project_id, + 'name': 'test'}) + authz = self.cloud.authorize_security_group_ingress + kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} + self.assertRaises(exception.ApiError, authz, self.context, sec['name']) + authz(self.context, group_id=sec['id'], **kwargs) + # ApiError: This rule already exists in group test + self.assertRaises(exception.ApiError, authz, self.context, + group_id=sec['id'], **kwargs) + revoke = self.cloud.revoke_security_group_ingress + self.assertTrue(revoke(self.context, group_id=sec['id'], **kwargs)) + + def test_describe_volumes(self): + """Makes sure describe_volumes works and filters results.""" + vol1 = db.volume_create(self.context, {}) + vol2 = db.volume_create(self.context, {}) + result = self.cloud.describe_volumes(self.context) + self.assertEqual(len(result['volumeSet']), 2) + volume_id = ec2utils.id_to_ec2_id(vol2['id'], 'vol-%08x') def test_describe_volumes(self): """Makes sure describe_volumes works and filters results.""" vol1 = db.volume_create(self.context, {}) -- cgit From c2cc453a6912bc37e2e9a9c5f5a3c2830b61f5be Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Thu, 23 Jun 2011 16:55:45 -0400 Subject: added tests --- nova/tests/api/openstack/test_flavors.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index d1c62e454..34c627ce0 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -87,6 +87,20 @@ class FlavorsTest(test.TestCase): ] self.assertEqual(flavors, expected) + def test_get_empty_flavor_list_v1_0(self): + def _throw_NoInstanceTypesFound(self): + raise exception.NoInstanceTypesFound + + self.stubs.Set(nova.db.api, "instance_type_get_all", + _throw_NoInstanceTypesFound) + + req = webob.Request.blank('/v1.0/flavors') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + flavors = json.loads(res.body)["flavors"] + expected = [] + self.assertEqual(flavors, expected) + def test_get_flavor_list_detail_v1_0(self): req = webob.Request.blank('/v1.0/flavors/detail') res = req.get_response(fakes.wsgi_app()) @@ -261,3 +275,17 @@ class FlavorsTest(test.TestCase): }, ] self.assertEqual(flavor, expected) + + def test_get_empty_flavor_list_v1_1(self): + def _throw_NoInstanceTypesFound(self): + raise exception.NoInstanceTypesFound + + self.stubs.Set(nova.db.api, "instance_type_get_all", + _throw_NoInstanceTypesFound) + + req = webob.Request.blank('/v1.1/flavors') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + flavors = json.loads(res.body)["flavors"] + expected = [] + self.assertEqual(flavors, expected) -- cgit From 129da3c5206443acc117b33b440a05b064fd711e Mon Sep 17 00:00:00 2001 From: John Tran Date: Thu, 23 Jun 2011 15:57:57 -0700 Subject: removing erroneous block, must've been a copy and paste fat finger --- nova/tests/test_cloud.py | 7 ------- 1 file changed, 7 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 8cbab09a9..162eca333 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -238,13 +238,6 @@ class CloudTestCase(test.TestCase): revoke = self.cloud.revoke_security_group_ingress self.assertTrue(revoke(self.context, group_id=sec['id'], **kwargs)) - def test_describe_volumes(self): - """Makes sure describe_volumes works and filters results.""" - vol1 = db.volume_create(self.context, {}) - vol2 = db.volume_create(self.context, {}) - result = self.cloud.describe_volumes(self.context) - self.assertEqual(len(result['volumeSet']), 2) - volume_id = ec2utils.id_to_ec2_id(vol2['id'], 'vol-%08x') def test_describe_volumes(self): """Makes sure describe_volumes works and filters results.""" vol1 = db.volume_create(self.context, {}) -- cgit From d75e776815f2fc7710ba9d937985787b49a9947f Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Thu, 23 Jun 2011 22:21:10 -0400 Subject: pep8 --- nova/tests/api/openstack/test_flavors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 34c627ce0..3c4e70e1a 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -93,7 +93,7 @@ class FlavorsTest(test.TestCase): self.stubs.Set(nova.db.api, "instance_type_get_all", _throw_NoInstanceTypesFound) - + req = webob.Request.blank('/v1.0/flavors') res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) @@ -282,7 +282,7 @@ class FlavorsTest(test.TestCase): self.stubs.Set(nova.db.api, "instance_type_get_all", _throw_NoInstanceTypesFound) - + req = webob.Request.blank('/v1.1/flavors') res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) -- cgit From a8f485d148f2184253fcbd7ccdfa9de9bb0bb735 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Sat, 25 Jun 2011 17:50:39 -0700 Subject: add metadata tests --- nova/tests/test_metadata.py | 82 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 nova/tests/test_metadata.py (limited to 'nova/tests') diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py new file mode 100644 index 000000000..30b5b19a7 --- /dev/null +++ b/nova/tests/test_metadata.py @@ -0,0 +1,82 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# 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. + +"""Tests for the testing the metadata code.""" + +import base64 +import httplib + +from nova import test +from nova import wsgi +from nova.api.ec2 import metadatarequesthandler +from nova.db.sqlalchemy import api + + +class MetadataTestCase(test.TestCase): + """Test that metadata is returning proper values.""" + def setUp(self): + super(MetadataTestCase, self).setUp() + self.instance = ({'id': 1, + 'project_id': 'test', + 'key_name': None, + 'host': 'test', + 'launch_index': 1, + 'instance_type': 'm1.tiny', + 'reservation_id': 'r-xxxxxxxx', + 'user_data': '', + 'image_ref': 7, + 'hostname' : 'test'}) + + def instance_get(*args, **kwargs): + return self.instance + + def floating_get(*args, **kwargs): + return '99.99.99.99' + + self.conn = self.fake_connection() + self.stubs.Set(api, 'instance_get', instance_get) + self.stubs.Set(api, 'fixed_ip_get_instance', instance_get) + self.stubs.Set(api, 'instance_get_floating_address', floating_get) + + def real_connection(self): + router = metadatarequesthandler.MetadataRequestHandler() + service = wsgi.Server() + service.start(router, 16969) + return httplib.HTTPConnection('127.0.0.1', 16969) + + def fake_connection(self): + return metadatarequesthandler.MetadataRequestHandler.fake_connection() + + def request(self, relative_url): + self.conn.request('GET', relative_url) + return self.conn.getresponse().read() + + def test_base(self): + self.assertEqual(self.request('/'), 'meta-data/\nuser-data') + + def test_user_data(self): + self.instance['user_data'] = base64.b64encode('happy') + self.assertEqual(self.request('/user-data'), 'happy') + + def test_security_groups(self): + def sg_get(*args, **kwargs): + return [{'name': 'default'}, {'name': 'other'}] + self.stubs.Set(api, 'security_group_get_by_instance', sg_get) + self.assertEqual(self.request('/meta-data/security-groups'), + 'default\nother') + -- cgit From b86b14ac5a96332beedf10ca8da5787adfc6c308 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Sat, 25 Jun 2011 17:52:26 -0700 Subject: pep8 --- nova/tests/test_metadata.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index 30b5b19a7..1ef1fea86 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -40,7 +40,7 @@ class MetadataTestCase(test.TestCase): 'reservation_id': 'r-xxxxxxxx', 'user_data': '', 'image_ref': 7, - 'hostname' : 'test'}) + 'hostname': 'test'}) def instance_get(*args, **kwargs): return self.instance @@ -79,4 +79,3 @@ class MetadataTestCase(test.TestCase): self.stubs.Set(api, 'security_group_get_by_instance', sg_get) self.assertEqual(self.request('/meta-data/security-groups'), 'default\nother') - -- cgit From d1b904d5b7d4a277adc156d8ab576b37b7e190fc Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 27 Jun 2011 09:56:31 -0400 Subject: Use webob to test WSGI app --- nova/tests/test_metadata.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index 1ef1fea86..c7095914c 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -21,6 +21,8 @@ import base64 import httplib +import webob + from nova import test from nova import wsgi from nova.api.ec2 import metadatarequesthandler @@ -48,23 +50,15 @@ class MetadataTestCase(test.TestCase): def floating_get(*args, **kwargs): return '99.99.99.99' - self.conn = self.fake_connection() self.stubs.Set(api, 'instance_get', instance_get) self.stubs.Set(api, 'fixed_ip_get_instance', instance_get) self.stubs.Set(api, 'instance_get_floating_address', floating_get) - - def real_connection(self): - router = metadatarequesthandler.MetadataRequestHandler() - service = wsgi.Server() - service.start(router, 16969) - return httplib.HTTPConnection('127.0.0.1', 16969) - - def fake_connection(self): - return metadatarequesthandler.MetadataRequestHandler.fake_connection() + self.app = metadatarequesthandler.MetadataRequestHandler() def request(self, relative_url): - self.conn.request('GET', relative_url) - return self.conn.getresponse().read() + request = webob.Request.blank(relative_url) + request.remote_addr = "127.0.0.1" + return request.get_response(self.app).body def test_base(self): self.assertEqual(self.request('/'), 'meta-data/\nuser-data') -- cgit From ad19a9e762f735a33af710fb8bded3a086266587 Mon Sep 17 00:00:00 2001 From: Brian Lamar Date: Mon, 27 Jun 2011 09:58:17 -0400 Subject: Removed now un-needed fake_connection --- nova/tests/test_metadata.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/tests') diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index c7095914c..c862726ab 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -31,6 +31,7 @@ from nova.db.sqlalchemy import api class MetadataTestCase(test.TestCase): """Test that metadata is returning proper values.""" + def setUp(self): super(MetadataTestCase, self).setUp() self.instance = ({'id': 1, -- cgit From 73c49dd3497f46953d7fa9ac3f5caebcafa02023 Mon Sep 17 00:00:00 2001 From: John Tran Date: Mon, 27 Jun 2011 15:30:56 -0700 Subject: breaking up into individual tests for security_groups --- nova/tests/test_cloud.py | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 162eca333..5d117dcfa 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -207,22 +207,43 @@ class CloudTestCase(test.TestCase): self.assertTrue(delete(self.context, group_id=sec['id'])) def test_authorize_revoke_security_group_ingress(self): - sec = db.security_group_create(self.context, - {'project_id': self.context.project_id, - 'name': 'test'}) + kwargs = {'project_id': self.context.project_id, 'name': 'test'} + sec = db.security_group_create(self.context, kwargs) authz = self.cloud.authorize_security_group_ingress - self.assertRaises(exception.ApiError, authz, self.context, sec['name']) kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} - # ApiError: Not enough parameters, need group_name or group_id + authz(self.context, group_name=sec['name'], **kwargs) + revoke = self.cloud.revoke_security_group_ingress + self.assertTrue(revoke(self.context, group_name=sec['name'], **kwargs)) + + def test_authorize_security_group_ingress_missing_protocol_params(self): + kwargs = {'project_id': self.context.project_id, 'name': 'test'} + sec = db.security_group_create(self.context, kwargs) + authz = self.cloud.authorize_security_group_ingress + self.assertRaises(exception.ApiError, authz, self.context, sec['name']) + + def test_authorize_security_group_ingress_missing_group_name_or_id(self): + kwargs = {'project_id': self.context.project_id, 'name': 'test'} + sec = db.security_group_create(self.context, kwargs) + authz = self.cloud.authorize_security_group_ingress self.assertRaises(exception.ApiError, authz, self.context, **kwargs) + + def test_authorize_security_group_ingress_already_exists(self): + kwargs = {'project_id': self.context.project_id, 'name': 'test'} + sec = db.security_group_create(self.context, kwargs) + authz = self.cloud.authorize_security_group_ingress + kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} authz(self.context, group_name=sec['name'], **kwargs) - # ApiError: This rule already exists in group test self.assertRaises(exception.ApiError, authz, self.context, group_name=sec['name'], **kwargs) + + def test_revoke_security_group_ingress_missing_group_name_or_id(self): + kwargs = {'project_id': self.context.project_id, 'name': 'test'} + sec = db.security_group_create(self.context, kwargs) + authz = self.cloud.authorize_security_group_ingress + kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} + authz(self.context, group_name=sec['name'], **kwargs) revoke = self.cloud.revoke_security_group_ingress - # ApiError: Not enough parameters, need group_name or group_id self.assertRaises(exception.ApiError, revoke, self.context, **kwargs) - self.assertTrue(revoke(self.context, group_name=sec['name'], **kwargs)) def test_authorize_revoke_security_group_ingress_by_id(self): sec = db.security_group_create(self.context, @@ -230,11 +251,7 @@ class CloudTestCase(test.TestCase): 'name': 'test'}) authz = self.cloud.authorize_security_group_ingress kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} - self.assertRaises(exception.ApiError, authz, self.context, sec['name']) authz(self.context, group_id=sec['id'], **kwargs) - # ApiError: This rule already exists in group test - self.assertRaises(exception.ApiError, authz, self.context, - group_id=sec['id'], **kwargs) revoke = self.cloud.revoke_security_group_ingress self.assertTrue(revoke(self.context, group_id=sec['id'], **kwargs)) -- cgit From 5686488517f702bd4ba714edeea89ea1993ac220 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 29 Jun 2011 09:49:49 -0700 Subject: Allow a port name in the server ref for image create --- nova/tests/api/openstack/test_images.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index 446d68e9e..6c36f96a7 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -1011,6 +1011,19 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): result = json.loads(response.body) self.assertEqual(result['image']['serverRef'], serverRef) + def test_create_image_v1_1_actual_server_ref_port(self): + + serverRef = 'http://localhost:8774/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(200, response.status_int) + result = json.loads(response.body) + self.assertEqual(result['image']['serverRef'], serverRef) + def test_create_image_v1_1_server_ref_bad_hostname(self): serverRef = 'http://asdf/v1.1/servers/1' -- cgit From 81ea3d5fc47bed84c5f4bf722b02dfa58792e19e Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Wed, 29 Jun 2011 18:26:51 -0400 Subject: Updated v1.1 links in flavors to represent the curret spec --- nova/tests/api/openstack/test_flavors.py | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index d1c62e454..47e6a3fd3 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -146,12 +146,10 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", "href": "http://localhost/v1.1/flavors/12", }, { "rel": "bookmark", - "type": "application/xml", "href": "http://localhost/v1.1/flavors/12", }, ], @@ -175,12 +173,10 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", "href": "http://localhost/v1.1/flavors/1", }, { "rel": "bookmark", - "type": "application/xml", "href": "http://localhost/v1.1/flavors/1", }, ], @@ -195,12 +191,10 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", "href": "http://localhost/v1.1/flavors/2", }, { "rel": "bookmark", - "type": "application/xml", "href": "http://localhost/v1.1/flavors/2", }, ], @@ -227,12 +221,10 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", "href": "http://localhost/v1.1/flavors/1", }, { "rel": "bookmark", - "type": "application/xml", "href": "http://localhost/v1.1/flavors/1", }, ], @@ -249,12 +241,10 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", "href": "http://localhost/v1.1/flavors/2", }, { "rel": "bookmark", - "type": "application/xml", "href": "http://localhost/v1.1/flavors/2", }, ], -- cgit From c12861f6068ea18156ff9c395ed40791585032d7 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Thu, 30 Jun 2011 09:28:21 -0400 Subject: refactored instance type code --- nova/tests/api/openstack/test_flavors.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 3c4e70e1a..fba4d593a 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -88,11 +88,10 @@ class FlavorsTest(test.TestCase): self.assertEqual(flavors, expected) def test_get_empty_flavor_list_v1_0(self): - def _throw_NoInstanceTypesFound(self): - raise exception.NoInstanceTypesFound - + def _return_empty(self): + return {} self.stubs.Set(nova.db.api, "instance_type_get_all", - _throw_NoInstanceTypesFound) + _return_empty) req = webob.Request.blank('/v1.0/flavors') res = req.get_response(fakes.wsgi_app()) @@ -277,11 +276,10 @@ class FlavorsTest(test.TestCase): self.assertEqual(flavor, expected) def test_get_empty_flavor_list_v1_1(self): - def _throw_NoInstanceTypesFound(self): - raise exception.NoInstanceTypesFound - + def _return_empty(self): + return {} self.stubs.Set(nova.db.api, "instance_type_get_all", - _throw_NoInstanceTypesFound) + _return_empty) req = webob.Request.blank('/v1.1/flavors') res = req.get_response(fakes.wsgi_app()) -- cgit From 8133b9af105f7924f03b710b30cf4f0acb52f143 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Thu, 30 Jun 2011 10:29:31 -0400 Subject: refactored flavors viewbuilder --- nova/tests/api/openstack/test_flavors.py | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_flavors.py b/nova/tests/api/openstack/test_flavors.py index 47e6a3fd3..7b4bd12f3 100644 --- a/nova/tests/api/openstack/test_flavors.py +++ b/nova/tests/api/openstack/test_flavors.py @@ -146,11 +146,7 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/12", - }, - { - "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/12", + "href": "http://localhost/flavors/12", }, ], } @@ -173,11 +169,7 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/1", - }, - { - "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/1", + "href": "http://localhost/flavors/1", }, ], }, @@ -191,11 +183,7 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/2", - }, - { - "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/2", + "href": "http://localhost/flavors/2", }, ], }, @@ -221,11 +209,7 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/1", - }, - { - "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/1", + "href": "http://localhost/flavors/1", }, ], }, @@ -241,11 +225,7 @@ class FlavorsTest(test.TestCase): }, { "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/2", - }, - { - "rel": "bookmark", - "href": "http://localhost/v1.1/flavors/2", + "href": "http://localhost/flavors/2", }, ], }, -- cgit From 5f772ea10c22549a7149f608cfc2ff932878d6fe Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Thu, 30 Jun 2011 11:18:19 -0400 Subject: updated servers --- nova/tests/api/openstack/test_servers.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index b53c6c9be..110445935 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -290,13 +290,7 @@ class ServersTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/servers/1", - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/servers/1", + "href": "http://localhost/servers/1", }, ] @@ -514,13 +508,7 @@ class ServersTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/servers/%d" % (i,), - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/servers/%d" % (i,), + "href": "http://localhost/servers/%d" % (i,), }, ] -- cgit From 386e2a28f2d92dea30a726722b49e97e1c7ebba7 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Thu, 30 Jun 2011 11:29:45 -0400 Subject: updated images --- nova/tests/api/openstack/test_images.py | 78 ++++++--------------------------- 1 file changed, 14 insertions(+), 64 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py index e11e1c046..b864ae9f4 100644 --- a/nova/tests/api/openstack/test_images.py +++ b/nova/tests/api/openstack/test_images.py @@ -400,6 +400,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): actual_image = json.loads(response.body) href = "http://localhost/v1.1/images/123" + bookmark = "http://localhost/images/123" expected_image = { "image": { @@ -414,13 +415,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": href, - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": href, + "href": bookmark, }], }, } @@ -473,6 +468,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): actual_image = minidom.parseString(response.body.replace(" ", "")) expected_href = "http://localhost/v1.1/images/123" + expected_bookmark = "http://localhost/images/123" expected_now = self.NOW_API_FORMAT expected_image = minidom.parseString(""" - - + """.replace(" ", "") % (locals())) @@ -580,22 +573,17 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): continue href = "http://localhost/v1.1/images/%s" % image["id"] + bookmark = "http://localhost/images/%s" % image["id"] test_image = { "id": image["id"], "name": image["name"], "links": [{ "rel": "self", - "href": "http://localhost/v1.1/images/%s" % image["id"], - }, - { - "rel": "bookmark", - "type": "application/json", "href": href, }, { "rel": "bookmark", - "type": "application/xml", - "href": href, + "href": bookmark, }], } self.assertTrue(test_image in response_list) @@ -674,13 +662,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/images/123", - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/images/123", + "href": "http://localhost/images/123", }], }, { @@ -696,13 +678,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/images/124", - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/images/124", + "href": "http://localhost/images/124", }], }, { @@ -719,13 +695,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/images/125", - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/images/125", + "href": "http://localhost/images/125", }], }, { @@ -741,13 +711,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/images/126", - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/images/126", + "href": "http://localhost/images/126", }], }, { @@ -763,13 +727,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/images/127", - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/images/127", + "href": "http://localhost/images/127", }], }, { @@ -784,13 +742,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): }, { "rel": "bookmark", - "type": "application/json", - "href": "http://localhost/v1.1/images/129", - }, - { - "rel": "bookmark", - "type": "application/xml", - "href": "http://localhost/v1.1/images/129", + "href": "http://localhost/images/129", }], }, ] @@ -1120,6 +1072,7 @@ class ImageControllerWithGlanceServiceTest(test.TestCase): self.assertEqual(200, response.status_int) resp_xml = minidom.parseString(response.body.replace(" ", "")) expected_href = "http://localhost/v1.1/images/123" + expected_bookmark = "http://localhost/images/123" expected_image = minidom.parseString(""" - - + """.replace(" ", "") % (locals())) -- cgit From 2d1d6b3e5c3957490c7cb49b38e72ca3baf9f8b0 Mon Sep 17 00:00:00 2001 From: John Tran Date: Thu, 30 Jun 2011 17:52:33 -0700 Subject: refactored the security_group tests a bit and broke up a few of them into smaller tests --- nova/tests/test_cloud.py | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 5d117dcfa..18a14e3ea 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -200,11 +200,21 @@ class CloudTestCase(test.TestCase): {'project_id': self.context.project_id, 'name': 'test'}) delete = self.cloud.delete_security_group + self.assertTrue(delete(self.context, group_id=sec['id'])) + + def test_delete_security_group_with_bad_name(self): + delete = self.cloud.delete_security_group notfound = exception.SecurityGroupNotFound self.assertRaises(notfound, delete, self.context, 'badname') + + def test_delete_security_group_with_bad_group_id(self): + delete = self.cloud.delete_security_group + notfound = exception.SecurityGroupNotFound self.assertRaises(notfound, delete, self.context, group_id=999) + + def test_delete_security_group_no_params(self): + delete = self.cloud.delete_security_group self.assertRaises(exception.ApiError, delete, self.context) - self.assertTrue(delete(self.context, group_id=sec['id'])) def test_authorize_revoke_security_group_ingress(self): kwargs = {'project_id': self.context.project_id, 'name': 'test'} @@ -215,15 +225,25 @@ class CloudTestCase(test.TestCase): revoke = self.cloud.revoke_security_group_ingress self.assertTrue(revoke(self.context, group_name=sec['name'], **kwargs)) + def test_authorize_revoke_security_group_ingress_by_id(self): + sec = db.security_group_create(self.context, + {'project_id': self.context.project_id, + 'name': 'test'}) + authz = self.cloud.authorize_security_group_ingress + kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} + authz(self.context, group_id=sec['id'], **kwargs) + revoke = self.cloud.revoke_security_group_ingress + self.assertTrue(revoke(self.context, group_id=sec['id'], **kwargs)) + def test_authorize_security_group_ingress_missing_protocol_params(self): - kwargs = {'project_id': self.context.project_id, 'name': 'test'} - sec = db.security_group_create(self.context, kwargs) + sec = db.security_group_create(self.context, + {'project_id': self.context.project_id, + 'name': 'test'}) authz = self.cloud.authorize_security_group_ingress - self.assertRaises(exception.ApiError, authz, self.context, sec['name']) + self.assertRaises(exception.ApiError, authz, self.context, 'test') def test_authorize_security_group_ingress_missing_group_name_or_id(self): kwargs = {'project_id': self.context.project_id, 'name': 'test'} - sec = db.security_group_create(self.context, kwargs) authz = self.cloud.authorize_security_group_ingress self.assertRaises(exception.ApiError, authz, self.context, **kwargs) @@ -237,24 +257,10 @@ class CloudTestCase(test.TestCase): group_name=sec['name'], **kwargs) def test_revoke_security_group_ingress_missing_group_name_or_id(self): - kwargs = {'project_id': self.context.project_id, 'name': 'test'} - sec = db.security_group_create(self.context, kwargs) - authz = self.cloud.authorize_security_group_ingress kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} - authz(self.context, group_name=sec['name'], **kwargs) revoke = self.cloud.revoke_security_group_ingress self.assertRaises(exception.ApiError, revoke, self.context, **kwargs) - def test_authorize_revoke_security_group_ingress_by_id(self): - sec = db.security_group_create(self.context, - {'project_id': self.context.project_id, - 'name': 'test'}) - authz = self.cloud.authorize_security_group_ingress - kwargs = {'to_port': '999', 'from_port': '999', 'ip_protocol': 'tcp'} - authz(self.context, group_id=sec['id'], **kwargs) - revoke = self.cloud.revoke_security_group_ingress - self.assertTrue(revoke(self.context, group_id=sec['id'], **kwargs)) - def test_describe_volumes(self): """Makes sure describe_volumes works and filters results.""" vol1 = db.volume_create(self.context, {}) -- cgit From 79cefb47c00636d26b1736b65a3f801ab8258e36 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 1 Jul 2011 11:20:04 -0400 Subject: removing IPy import --- nova/tests/test_iptables_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_iptables_network.py b/nova/tests/test_iptables_network.py index 29b09ade2..918034269 100644 --- a/nova/tests/test_iptables_network.py +++ b/nova/tests/test_iptables_network.py @@ -16,7 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. """Unit Tests for network code.""" -import IPy + import os from nova import test -- cgit From 7307f17edeb284a6b2da076ffa16b2ef5c82a4f4 Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Mon, 4 Jul 2011 15:41:37 +0000 Subject: Added missing extension file and tests. Also modified the get_host_list() docstring to be more accurate about the return value. --- nova/tests/test_hosts.py | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 nova/tests/test_hosts.py (limited to 'nova/tests') diff --git a/nova/tests/test_hosts.py b/nova/tests/test_hosts.py new file mode 100644 index 000000000..9c3344873 --- /dev/null +++ b/nova/tests/test_hosts.py @@ -0,0 +1,101 @@ +# Copyright (c) 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. + +import stubout + +from nova import context +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova.api.openstack.contrib import hosts as os_hosts +from nova.scheduler import api as scheduler_api + + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.hosts') +# Simulate the hosts returned by the zone manager. +HOST_LIST = [ + {"host_name": "host_c1", "service": "compute"}, + {"host_name": "host_c2", "service": "compute"}, + {"host_name": "host_v1", "service": "volume"}, + {"host_name": "host_v2", "service": "volume"}] + + +def stub_get_host_list(req): + return HOST_LIST + + +def stub_set_host_enabled(context, host, enabled): + # We'll simulate success and failure by assuming + # that 'host_c1' always succeeds, and 'host_c2' + # always fails + fail = (host == "host_c2") + status = "enabled" if (enabled ^ fail) else "disabled" + return status + + +class FakeRequest(object): + environ = {"nova.context": context.get_admin_context()} + + +class HostTestCase(test.TestCase): + """Test Case for hosts.""" + + def setUp(self): + super(HostTestCase, self).setUp() + self.controller = os_hosts.HostController() + self.req = FakeRequest() + self.stubs.Set(scheduler_api, 'get_host_list', stub_get_host_list) + self.stubs.Set(self.controller.compute_api, 'set_host_enabled', + stub_set_host_enabled) + + def test_list_hosts(self): + """Verify that the compute hosts are returned.""" + hosts = os_hosts._list_hosts(self.req) + self.assertEqual(hosts, HOST_LIST) + + compute_hosts = os_hosts._list_hosts(self.req, "compute") + expected = [host for host in HOST_LIST + if host["service"] == "compute"] + self.assertEqual(compute_hosts, expected) + + def test_disable_host(self): + dis_body = {"status": "disable"} + result_c1 = self.controller.update(self.req, "host_c1", body=dis_body) + self.assertEqual(result_c1["status"], "disabled") + result_c2 = self.controller.update(self.req, "host_c2", body=dis_body) + self.assertEqual(result_c2["status"], "enabled") + + def test_enable_host(self): + en_body = {"status": "enable"} + result_c1 = self.controller.update(self.req, "host_c1", body=en_body) + self.assertEqual(result_c1["status"], "enabled") + result_c2 = self.controller.update(self.req, "host_c2", body=en_body) + self.assertEqual(result_c2["status"], "disabled") + + def test_bad_status_value(self): + bad_body = {"status": "bad"} + self.assertRaises(ValueError, self.controller.update, self.req, + "host_c1", body=bad_body) + + def test_bad_update_key(self): + bad_body = {"crazy": "bad"} + self.assertRaises(ValueError, self.controller.update, self.req, + "host_c1", body=bad_body) + + def test_bad_host(self): + self.assertRaises(exception.HostNotFound, self.controller.update, + self.req, "bogus_host_name", body={"status": "disable"}) -- cgit From 33ee3015e28e23e2d875d6467215fd7e0071f7e4 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Mon, 4 Jul 2011 17:02:50 +0100 Subject: Fixing weird error while running tests. Fix required patching nova/tests/___init__.py explictly importing nova.test --- nova/tests/test_xenapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 3302bd095..4cb7447d3 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -450,7 +450,7 @@ class XenAPIVMTestCase(test.TestCase): self._check_vdis(vdi_recs_start, vdi_recs_end) def test_spawn_fail_cleanup_2(self): - """Simulates an error while creating VM record. + """Simulates an error while creating VM record. It verifies that VDIs created are properly cleaned up. -- cgit From c2bb27363e5155adb9ba36844586d390ddd14de4 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 5 Jul 2011 12:16:35 -0700 Subject: fixed zone id check --- nova/tests/scheduler/test_zone_aware_scheduler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/scheduler/test_zone_aware_scheduler.py b/nova/tests/scheduler/test_zone_aware_scheduler.py index 5950f4551..d74b71fb6 100644 --- a/nova/tests/scheduler/test_zone_aware_scheduler.py +++ b/nova/tests/scheduler/test_zone_aware_scheduler.py @@ -122,19 +122,19 @@ def fake_decrypt_blob_returns_child_info(blob): def fake_call_zone_method(context, method, specs, zones): return [ - ('zone1', [ + (1, [ dict(weight=1, blob='AAAAAAA'), dict(weight=111, blob='BBBBBBB'), dict(weight=112, blob='CCCCCCC'), dict(weight=113, blob='DDDDDDD'), ]), - ('zone2', [ + (2, [ dict(weight=120, blob='EEEEEEE'), dict(weight=2, blob='FFFFFFF'), dict(weight=122, blob='GGGGGGG'), dict(weight=123, blob='HHHHHHH'), ]), - ('zone3', [ + (3, [ dict(weight=130, blob='IIIIIII'), dict(weight=131, blob='JJJJJJJ'), dict(weight=132, blob='KKKKKKK'), -- cgit From 6435ba27edea7e525305d349cafea3d08f5db2c6 Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Wed, 6 Jul 2011 16:53:08 +0000 Subject: Changed the exception type for invalid requests to webob.exc.HTTPBadRequest. --- nova/tests/test_hosts.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_hosts.py b/nova/tests/test_hosts.py index 9c3344873..c14ea349b 100644 --- a/nova/tests/test_hosts.py +++ b/nova/tests/test_hosts.py @@ -14,6 +14,7 @@ # under the License. import stubout +import webob.exc from nova import context from nova import exception @@ -88,12 +89,12 @@ class HostTestCase(test.TestCase): def test_bad_status_value(self): bad_body = {"status": "bad"} - self.assertRaises(ValueError, self.controller.update, self.req, + self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, self.req, "host_c1", body=bad_body) def test_bad_update_key(self): bad_body = {"crazy": "bad"} - self.assertRaises(ValueError, self.controller.update, self.req, + self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, self.req, "host_c1", body=bad_body) def test_bad_host(self): -- cgit From 9d29dc60d904f2c5037d03cead71933dc62777ff Mon Sep 17 00:00:00 2001 From: Ed Leafe Date: Wed, 6 Jul 2011 17:14:46 +0000 Subject: pep8 fixes --- nova/tests/test_hosts.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_hosts.py b/nova/tests/test_hosts.py index c14ea349b..548f81f8b 100644 --- a/nova/tests/test_hosts.py +++ b/nova/tests/test_hosts.py @@ -89,13 +89,13 @@ class HostTestCase(test.TestCase): def test_bad_status_value(self): bad_body = {"status": "bad"} - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, self.req, - "host_c1", body=bad_body) + self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, + self.req, "host_c1", body=bad_body) def test_bad_update_key(self): bad_body = {"crazy": "bad"} - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, self.req, - "host_c1", body=bad_body) + self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, + self.req, "host_c1", body=bad_body) def test_bad_host(self): self.assertRaises(exception.HostNotFound, self.controller.update, -- cgit From 7048530fb6083ab92fa6b7a2b5a73fc2bf30709f Mon Sep 17 00:00:00 2001 From: Devendra Modium Date: Thu, 7 Jul 2011 11:25:45 -0400 Subject: Comments Incorporated for Bug800759 --- nova/tests/test_zones.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py index e132809dc..f4661a328 100644 --- a/nova/tests/test_zones.py +++ b/nova/tests/test_zones.py @@ -198,3 +198,124 @@ class ZoneManagerTestCase(test.TestCase): self.assertEquals(zone_state.attempt, 3) self.assertFalse(zone_state.is_active) self.assertEquals(zone_state.name, None) + + def test_host_service_caps_stale(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + + # services just updated capabilities + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4)) + self.assertFalse(zm.host_service_caps_stale("host1", "svc1")) + self.assertFalse(zm.host_service_caps_stale("host1", "svc2")) + + # Both services became stale + time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time) + utils.set_time_override(time_future) + self.assertTrue(zm.host_service_caps_stale("host1", "svc1")) + self.assertTrue(zm.host_service_caps_stale("host1", "svc2")) + + # One service became stale + utils.clear_time_override() + caps = zm.service_states["host1"]["svc1"] + caps["timestamp"] = utils.utcnow() - \ + datetime.timedelta(seconds=expiry_time) + self.assertTrue(zm.host_service_caps_stale("host1", "svc1")) + self.assertFalse(zm.host_service_caps_stale("host1", "svc2")) + + def test_delete_expired_host_services(self): + zm = zone_manager.ZoneManager() + + # Delete one service in a host + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4)) + stale_host_services = {"host1": ["svc1"]} + zm.delete_expired_host_services(stale_host_services) + self.assertFalse("svc1" in zm.service_states["host1"]) + self.assertTrue("svc2" in zm.service_states["host1"]) + + # Delete all services in a host + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + stale_host_services = {"host1": ["svc1", "svc2"]} + zm.delete_expired_host_services(stale_host_services) + self.assertFalse("host1" in zm.service_states) + + # Delete one service per host + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) + stale_host_services = {"host1": ["svc1"], "host2": ["svc1"]} + zm.delete_expired_host_services(stale_host_services) + self.assertFalse("host1" in zm.service_states) + self.assertFalse("host2" in zm.service_states) + + def test_get_zone_capabilities(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + + # Service capabilities recent + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2))) + + # Service capabilities stale + time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time) + utils.set_time_override(time_future) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, {}) + + # Both host service capabilities recent + utils.clear_time_override() + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, dict(svc1_a=(1, 3), svc1_b=(2, 4))) + + # One host service capabilities become stale + serv_caps = zm.service_states["host1"]["svc1"] + serv_caps["timestamp"] = utils.utcnow() - \ + datetime.timedelta(seconds=expiry_time) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, dict(svc1_a=(3, 3), svc1_b=(4, 4))) + + # Multiple services per host + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) + zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8)) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, dict(svc1_a=(1, 3), svc1_b=(2, 4), + svc2_a=(5, 7), svc2_b=(6, 8))) + + # Two host services among four become stale + serv_caps_1 = zm.service_states["host1"]["svc2"] + serv_caps_1["timestamp"] = utils.utcnow() - \ + datetime.timedelta(seconds=expiry_time) + serv_caps_2 = zm.service_states["host2"]["svc1"] + serv_caps_2["timestamp"] = utils.utcnow() - \ + datetime.timedelta(seconds=expiry_time) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2), + svc2_a=(7, 7), svc2_b=(8, 8))) + + # Three host services among four become stale + zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) + zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) + serv_caps_1 = zm.service_states["host1"]["svc2"] + serv_caps_1["timestamp"] = utils.utcnow() - \ + datetime.timedelta(seconds=expiry_time) + serv_caps_2 = zm.service_states["host2"]["svc1"] + serv_caps_2["timestamp"] = utils.utcnow() - \ + datetime.timedelta(seconds=expiry_time) + serv_caps_3 = zm.service_states["host2"]["svc2"] + serv_caps_3["timestamp"] = utils.utcnow() - \ + datetime.timedelta(seconds=expiry_time) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2))) + + # All the host services become stale + zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) + zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) + zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8)) + utils.set_time_override(time_future) + caps = zm.get_zone_capabilities(None) + self.assertEquals(caps, {}) + -- cgit From 784c0a76967310843269d7f8be9df6bc292ff3c8 Mon Sep 17 00:00:00 2001 From: Devendra Modium Date: Thu, 7 Jul 2011 15:55:34 -0400 Subject: Comments for bugfix800759 and pep8 --- nova/tests/test_zones.py | 88 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 17 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py index f4661a328..a943fee27 100644 --- a/nova/tests/test_zones.py +++ b/nova/tests/test_zones.py @@ -199,31 +199,42 @@ class ZoneManagerTestCase(test.TestCase): self.assertFalse(zone_state.is_active) self.assertEquals(zone_state.name, None) - def test_host_service_caps_stale(self): + def test_host_service_caps_stale_no_stale_service(self): zm = zone_manager.ZoneManager() - expiry_time = (FLAGS.periodic_interval * 3) + 1 - # services just updated capabilities + # services just updated capabilities zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4)) self.assertFalse(zm.host_service_caps_stale("host1", "svc1")) self.assertFalse(zm.host_service_caps_stale("host1", "svc2")) + def test_host_service_caps_stale_all_stale_services(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + # Both services became stale + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4)) time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time) utils.set_time_override(time_future) self.assertTrue(zm.host_service_caps_stale("host1", "svc1")) self.assertTrue(zm.host_service_caps_stale("host1", "svc2")) + utils.clear_time_override() + + def test_host_service_caps_stale_one_stale_service(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 # One service became stale - utils.clear_time_override() + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4)) caps = zm.service_states["host1"]["svc1"] caps["timestamp"] = utils.utcnow() - \ datetime.timedelta(seconds=expiry_time) self.assertTrue(zm.host_service_caps_stale("host1", "svc1")) self.assertFalse(zm.host_service_caps_stale("host1", "svc2")) - - def test_delete_expired_host_services(self): + + def test_delete_expired_host_services_del_one_service(self): zm = zone_manager.ZoneManager() # Delete one service in a host @@ -234,12 +245,19 @@ class ZoneManagerTestCase(test.TestCase): self.assertFalse("svc1" in zm.service_states["host1"]) self.assertTrue("svc2" in zm.service_states["host1"]) + def test_delete_expired_host_services_del_all_hosts(self): + zm = zone_manager.ZoneManager() + # Delete all services in a host + zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4)) zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) stale_host_services = {"host1": ["svc1", "svc2"]} zm.delete_expired_host_services(stale_host_services) self.assertFalse("host1" in zm.service_states) + def test_delete_expired_host_services_del_one_service_per_host(self): + zm = zone_manager.ZoneManager() + # Delete one service per host zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) @@ -247,45 +265,70 @@ class ZoneManagerTestCase(test.TestCase): zm.delete_expired_host_services(stale_host_services) self.assertFalse("host1" in zm.service_states) self.assertFalse("host2" in zm.service_states) - - def test_get_zone_capabilities(self): + + def test_get_zone_capabilities_one_host(self): zm = zone_manager.ZoneManager() - expiry_time = (FLAGS.periodic_interval * 3) + 1 # Service capabilities recent zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) caps = zm.get_zone_capabilities(None) self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2))) + def test_get_zone_capabilities_expired_host(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + # Service capabilities stale + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time) utils.set_time_override(time_future) caps = zm.get_zone_capabilities(None) self.assertEquals(caps, {}) + utils.clear_time_override() + + def test_get_zone_capabilities_multiple_hosts(self): + zm = zone_manager.ZoneManager() # Both host service capabilities recent - utils.clear_time_override() zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) caps = zm.get_zone_capabilities(None) self.assertEquals(caps, dict(svc1_a=(1, 3), svc1_b=(2, 4))) + def test_get_zone_capabilities_one_stale_host(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + # One host service capabilities become stale + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) serv_caps = zm.service_states["host1"]["svc1"] serv_caps["timestamp"] = utils.utcnow() - \ datetime.timedelta(seconds=expiry_time) caps = zm.get_zone_capabilities(None) self.assertEquals(caps, dict(svc1_a=(3, 3), svc1_b=(4, 4))) - # Multiple services per host + def test_get_zone_capabilities_multiple_service_per_host(self): + zm = zone_manager.ZoneManager() + + # Multiple services per host zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8)) caps = zm.get_zone_capabilities(None) self.assertEquals(caps, dict(svc1_a=(1, 3), svc1_b=(2, 4), svc2_a=(5, 7), svc2_b=(6, 8))) - # Two host services among four become stale + def test_get_zone_capabilities_one_stale_service_per_host(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + + # Two host services among four become stale + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) + zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) + zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) + zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8)) serv_caps_1 = zm.service_states["host1"]["svc2"] serv_caps_1["timestamp"] = utils.utcnow() - \ datetime.timedelta(seconds=expiry_time) @@ -296,9 +339,15 @@ class ZoneManagerTestCase(test.TestCase): self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2), svc2_a=(7, 7), svc2_b=(8, 8))) - # Three host services among four become stale - zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) + def test_get_zone_capabilities_three_stale_host_services(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + + # Three host services among four become stale + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) + zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) + zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8)) serv_caps_1 = zm.service_states["host1"]["svc2"] serv_caps_1["timestamp"] = utils.utcnow() - \ datetime.timedelta(seconds=expiry_time) @@ -311,11 +360,16 @@ class ZoneManagerTestCase(test.TestCase): caps = zm.get_zone_capabilities(None) self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2))) - # All the host services become stale - zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) + def test_get_zone_capabilities_all_stale_host_services(self): + zm = zone_manager.ZoneManager() + expiry_time = (FLAGS.periodic_interval * 3) + 1 + + # All the host services become stale + zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2)) zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4)) + zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6)) zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8)) + time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time) utils.set_time_override(time_future) caps = zm.get_zone_capabilities(None) self.assertEquals(caps, {}) - -- cgit From 9f3a309eab3af46aa3f8ac2767b7edcdeb49e043 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Thu, 7 Jul 2011 16:46:55 -0500 Subject: unit test suite for the multinic extension --- .../api/openstack/contrib/test_multinic_xs.py | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 nova/tests/api/openstack/contrib/test_multinic_xs.py (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_multinic_xs.py b/nova/tests/api/openstack/contrib/test_multinic_xs.py new file mode 100644 index 000000000..e531435a0 --- /dev/null +++ b/nova/tests/api/openstack/contrib/test_multinic_xs.py @@ -0,0 +1,88 @@ +# Copyright 2011 Eldar Nugaev +# 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 json +import stubout +import webob + +from nova import compute +from nova import context +from nova import test +from nova.tests.api.openstack import fakes + + +last_add_fixed_ip = (None, None) + + +def compute_api_add_fixed_ip(self, context, instance_id, network_id): + global last_add_fixed_ip + + last_add_fixed_ip = (instance_id, network_id) + + +class FixedIpTest(test.TestCase): + def setUp(self): + super(FixedIpTest, self).setUp() + self.stubs = stubout.StubOutForTesting() + fakes.FakeAuthManager.reset_fake_data() + fakes.FakeAuthDatabase.data = {} + fakes.stub_out_networking(self.stubs) + fakes.stub_out_rate_limiting(self.stubs) + fakes.stub_out_auth(self.stubs) + self.stubs.Set(compute.api.API, "add_fixed_ip", + compute_api_add_fixed_ip) + self.context = context.get_admin_context() + + def tearDown(self): + self.stubs.UnsetAll() + super(FixedIpTest, self).tearDown() + + def test_add_fixed_ip(self): + global last_add_fixed_ip + last_add_fixed_ip = (None, None) + + body = dict(addFixedIp=dict(networkId='test_net')) + req = webob.Request.blank('/v1.1/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, 202) + self.assertNotEqual(last_add_fixed_ip, (None, None)) + + def test_add_fixed_ip_no_network(self): + global last_add_fixed_ip + last_add_fixed_ip = (None, None) + + body = dict(addFixedIp=dict()) + req = webob.Request.blank('/v1.1/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, 422) + self.assertEqual(last_add_fixed_ip, (None, None)) + + def test_remove_fixed_ip(self): + body = dict(removeFixedIp=dict(address='10.10.10.1')) + req = webob.Request.blank('/v1.1/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, 501) -- cgit From 2c3eeb5f9f5f78d9cb8fb3e37d5b5e1610d32499 Mon Sep 17 00:00:00 2001 From: John Tran Date: Thu, 7 Jul 2011 20:43:50 -0700 Subject: ec2 api _get_image method logic flaw that strips the hex16 digit off of the image name, and does a search against the db for it and ignores that it may not be the correct image, such as if doing a search for aki-0000009, yet that image name doesn't exist, it strips off aki- and looks for any image_id 0000009 and if there was an image match that happens to be an ami instead of aki, it will go ahead and deregister that. That behavior is unintended, so added logic to ensure that the original request image_id matches the type of image being returned from database by matching against container_format attr --- nova/tests/test_cloud.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index bf7a2b7ca..d71a03aff 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -67,7 +67,8 @@ class CloudTestCase(test.TestCase): host = self.network.host def fake_show(meh, context, id): - return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + return {'id': 1, 'container_format': 'ami', + 'properties': {'kernel_id': 1, 'ramdisk_id': 1, 'type': 'machine', 'image_state': 'available'}} self.stubs.Set(fake._FakeImageService, 'show', fake_show) @@ -418,7 +419,8 @@ class CloudTestCase(test.TestCase): describe_images = self.cloud.describe_images def fake_detail(meh, context): - return [{'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + return [{'id': 1, 'container_format': 'ami', + 'properties': {'kernel_id': 1, 'ramdisk_id': 1, 'type': 'machine'}}] def fake_show_none(meh, context, id): @@ -448,7 +450,8 @@ class CloudTestCase(test.TestCase): def fake_show(meh, context, id): return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, - 'type': 'machine'}, 'is_public': True} + 'type': 'machine'}, 'container_format': 'ami', + 'is_public': True} self.stubs.Set(fake._FakeImageService, 'show', fake_show) self.stubs.Set(fake._FakeImageService, 'show_by_name', fake_show) @@ -460,7 +463,8 @@ class CloudTestCase(test.TestCase): modify_image_attribute = self.cloud.modify_image_attribute def fake_show(meh, context, id): - return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + return {'id': 1, 'container_format': 'ami', + 'properties': {'kernel_id': 1, 'ramdisk_id': 1, 'type': 'machine'}, 'is_public': False} def fake_update(meh, context, image_id, metadata, data=None): @@ -494,6 +498,16 @@ class CloudTestCase(test.TestCase): self.assertRaises(exception.ImageNotFound, deregister_image, self.context, 'ami-bad001') + def test_deregister_image_wrong_container_type(self): + deregister_image = self.cloud.deregister_image + + def fake_delete(self, context, id): + return None + + self.stubs.Set(fake._FakeImageService, 'delete', fake_delete) + self.assertRaises(exception.NotFound, deregister_image, self.context, + 'aki-00000001') + def _run_instance(self, **kwargs): rv = self.cloud.run_instances(self.context, **kwargs) instance_id = rv['instancesSet'][0]['instanceId'] @@ -609,7 +623,7 @@ class CloudTestCase(test.TestCase): def fake_show_no_state(self, context, id): return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, - 'type': 'machine'}} + 'type': 'machine'}, 'container_format': 'ami'} self.stubs.UnsetAll() self.stubs.Set(fake._FakeImageService, 'show', fake_show_no_state) @@ -623,7 +637,8 @@ class CloudTestCase(test.TestCase): run_instances = self.cloud.run_instances def fake_show_decrypt(self, context, id): - return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + return {'id': 1, 'container_format': 'ami', + 'properties': {'kernel_id': 1, 'ramdisk_id': 1, 'type': 'machine', 'image_state': 'decrypting'}} self.stubs.UnsetAll() @@ -638,7 +653,8 @@ class CloudTestCase(test.TestCase): run_instances = self.cloud.run_instances def fake_show_stat_active(self, context, id): - return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1, + return {'id': 1, 'container_format': 'ami', + 'properties': {'kernel_id': 1, 'ramdisk_id': 1, 'type': 'machine'}, 'status': 'active'} self.stubs.Set(fake._FakeImageService, 'show', fake_show_stat_active) -- cgit From ce0bdf7de31dcee53ee5ccdc0cca57333c6b6bc1 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Fri, 8 Jul 2011 11:47:34 -0500 Subject: Added unit tests. --- nova/tests/api/openstack/test_servers.py | 17 +++++++++++++++++ nova/tests/test_compute.py | 8 ++++++++ 2 files changed, 25 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 0cb16b4c0..1f369c4c8 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -1557,6 +1557,23 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 400) + def test_migrate_server(self): + """This is basically the same as resize, only we provide the `migrate` + attribute in the body's dict. + """ + req = self.webreq('/1/action', 'POST', dict(migrate=None)) + + self.resize_called = False + + def resize_mock(*args): + self.resize_called = True + + self.stubs.Set(nova.compute.api.API, 'resize', resize_mock) + + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 202) + self.assertEqual(self.resize_called, True) + def test_shutdown_status(self): new_server = return_server_with_power_state(power_state.SHUTDOWN) self.stubs.Set(nova.db.api, 'instance_get', new_server) diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 45cd2f764..04bb194d5 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -532,6 +532,14 @@ class ComputeTestCase(test.TestCase): self.context, instance_id, 1) self.compute.terminate_instance(self.context, instance_id) + def test_migrate(self): + context = self.context.elevated() + instance_id = self._create_instance() + self.compute.run_instance(self.context, instance_id) + # Migrate simply calls resize() without a flavor_id. + self.compute_api.resize(context, instance_id, None) + self.compute.terminate_instance(context, instance_id) + def _setup_other_managers(self): self.volume_manager = utils.import_object(FLAGS.volume_manager) self.network_manager = utils.import_object(FLAGS.network_manager) -- cgit From 921fee22ff42852b1ee0d7f3d051b44d60afd975 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Fri, 8 Jul 2011 13:06:37 -0500 Subject: Add support for remove_fixed_ip() --- .../api/openstack/contrib/test_multinic_xs.py | 35 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_multinic_xs.py b/nova/tests/api/openstack/contrib/test_multinic_xs.py index e531435a0..b9f4456bb 100644 --- a/nova/tests/api/openstack/contrib/test_multinic_xs.py +++ b/nova/tests/api/openstack/contrib/test_multinic_xs.py @@ -1,4 +1,4 @@ -# Copyright 2011 Eldar Nugaev +# Copyright 2011 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -24,6 +24,7 @@ from nova.tests.api.openstack import fakes last_add_fixed_ip = (None, None) +last_remove_fixed_ip = (None, None) def compute_api_add_fixed_ip(self, context, instance_id, network_id): @@ -32,6 +33,12 @@ def compute_api_add_fixed_ip(self, context, instance_id, network_id): last_add_fixed_ip = (instance_id, network_id) +def compute_api_remove_fixed_ip(self, context, instance_id, address): + global last_remove_fixed_ip + + last_remove_fixed_ip = (instance_id, address) + + class FixedIpTest(test.TestCase): def setUp(self): super(FixedIpTest, self).setUp() @@ -43,6 +50,9 @@ class FixedIpTest(test.TestCase): fakes.stub_out_auth(self.stubs) self.stubs.Set(compute.api.API, "add_fixed_ip", compute_api_add_fixed_ip) + # TODO(Vek): Fails until remove_fixed_ip() added + # self.stubs.Set(compute.api.API, "remove_fixed_ip", + # compute_api_remove_fixed_ip) self.context = context.get_admin_context() def tearDown(self): @@ -61,7 +71,7 @@ class FixedIpTest(test.TestCase): resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 202) - self.assertNotEqual(last_add_fixed_ip, (None, None)) + self.assertEqual(last_add_fixed_ip, ('test_inst', 'test_net')) def test_add_fixed_ip_no_network(self): global last_add_fixed_ip @@ -78,6 +88,9 @@ class FixedIpTest(test.TestCase): self.assertEqual(last_add_fixed_ip, (None, None)) def test_remove_fixed_ip(self): + global last_remove_fixed_ip + last_remove_fixed_ip = (None, None) + body = dict(removeFixedIp=dict(address='10.10.10.1')) req = webob.Request.blank('/v1.1/servers/test_inst/action') req.method = 'POST' @@ -85,4 +98,20 @@ class FixedIpTest(test.TestCase): req.headers['content-type'] = 'application/json' resp = req.get_response(fakes.wsgi_app()) - self.assertEqual(resp.status_int, 501) + # TODO(Vek): Fails until remove_fixed_ip() added + self.assertEqual(resp.status_int, 202) + self.assertEqual(last_remove_fixed_ip, ('test_inst', '10.10.10.1')) + + def test_remove_fixed_ip_no_address(self): + global last_remove_fixed_ip + last_remove_fixed_ip = (None, None) + + body = dict(removeFixedIp=dict()) + req = webob.Request.blank('/v1.1/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, 422) + self.assertEqual(last_remove_fixed_ip, (None, None)) -- cgit From d2c628c0ecbae048fabaf60eff2afd4b8a9cd918 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Mon, 11 Jul 2011 10:18:17 -0500 Subject: Comment out these two asserts; Sandy will uncomment in his merge-prop --- nova/tests/api/openstack/contrib/test_multinic_xs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_multinic_xs.py b/nova/tests/api/openstack/contrib/test_multinic_xs.py index b9f4456bb..484cd1c17 100644 --- a/nova/tests/api/openstack/contrib/test_multinic_xs.py +++ b/nova/tests/api/openstack/contrib/test_multinic_xs.py @@ -99,8 +99,8 @@ class FixedIpTest(test.TestCase): resp = req.get_response(fakes.wsgi_app()) # TODO(Vek): Fails until remove_fixed_ip() added - self.assertEqual(resp.status_int, 202) - self.assertEqual(last_remove_fixed_ip, ('test_inst', '10.10.10.1')) + # self.assertEqual(resp.status_int, 202) + # self.assertEqual(last_remove_fixed_ip, ('test_inst', '10.10.10.1')) def test_remove_fixed_ip_no_address(self): global last_remove_fixed_ip -- cgit