From 6fc00d34651858308c5b08fdabe8a0b9ce663e26 Mon Sep 17 00:00:00 2001 From: Kravchenko Pavel Date: Tue, 8 Jan 2013 22:54:14 +0200 Subject: Adds to manager init_host validation for instances location While the compute was down the instances running on it could be evacuated to another host. The method checks that instance host identical to current host. Otherwise destroying it. part of blueprint rebuild-for-ha DocImpact Change-Id: Ic90df2b2887ee203e6d8261084e3f97773c5d81c Co-authored-by: Oshrit Feder --- nova/tests/compute/test_compute.py | 143 +++++++++++++++++++++++++++++++ nova/tests/compute/test_compute_utils.py | 94 ++++++++++++++++++++ 2 files changed, 237 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index dabb8bb89..5cdc3dd27 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -3110,6 +3110,149 @@ class ComputeTestCase(BaseTestCase): self.assertEqual(timeouts.count(10), 10) self.assertTrue(None in timeouts) + def test_init_host_with_evacuated_instances_uuid_list(self): + # creating testdata + c = context.get_admin_context() + + # instances in central db + instances = [ + # those are still related to this host + jsonutils.to_primitive(self._create_fake_instance( + {'host': self.compute.host})), + jsonutils.to_primitive(self._create_fake_instance( + {'host': self.compute.host})), + jsonutils.to_primitive(self._create_fake_instance( + {'host': self.compute.host})) + ] + + # those are already been evacuated to other host + evacuated_instance = self._create_fake_instance({'host': 'otherhost'}) + + # creating mocks + self.mox.StubOutWithMock(self.compute.driver, 'init_host') + + self.compute.driver.init_host(host=self.compute.host) + + def fake_get_admin_context(): + return c + + def fake_all(*args, **kwargs): + pass + + def fake_list_instance_uuids(): + return [ + # those are still related to this host + instances[0]['uuid'], + instances[1]['uuid'], + instances[2]['uuid'], + # and this one already been evacuated to other host + evacuated_instance['uuid'] + ] + + def fake_destroy(instance, nw, bdi, destroyDisks): + self.assertFalse(destroyDisks) + self.assertEqual(instance['uuid'], evacuated_instance['uuid']) + + self.stubs.Set(nova.context, + 'get_admin_context', + fake_get_admin_context) + self.stubs.Set(self.compute.driver, 'filter_defer_apply_on', fake_all) + self.stubs.Set(self.compute.driver, + 'list_instance_uuids', + fake_list_instance_uuids) + self.stubs.Set(self.compute, '_get_instance_nw_info', fake_all) + self.stubs.Set(self.compute, '_get_instance_volume_block_device_info', + fake_all) + self.stubs.Set(self.compute.driver, 'destroy', fake_destroy) + self.stubs.Set(self.compute, '_legacy_nw_info', fake_all) + self.stubs.Set(self.compute, '_init_instance', fake_all) + + self.stubs.Set(self.compute.driver, 'filter_defer_apply_off', fake_all) + self.stubs.Set(self.compute, '_report_driver_status', fake_all) + self.stubs.Set(self.compute, 'publish_service_capabilities', fake_all) + # start test + self.mox.ReplayAll() + self.compute.init_host() + + db.instance_destroy(c, evacuated_instance['uuid']) + for instance in instances: + db.instance_destroy(c, instance['uuid']) + + def test_init_host_with_evacuated_instances_names_list(self): + # creating testdata + c = context.get_admin_context() + + # instances in central db + instances = [ + # those are still related to this host + jsonutils.to_primitive(self._create_fake_instance( + {'host': self.compute.host})), + jsonutils.to_primitive(self._create_fake_instance( + {'host': self.compute.host})), + jsonutils.to_primitive(self._create_fake_instance( + {'host': self.compute.host})) + ] + + # those are already been evacuated to other host + evacuated_instance = self._create_fake_instance({'host': 'otherhost'}) + + # creating mocks + self.mox.StubOutWithMock(self.compute.driver, 'init_host') + + self.compute.driver.init_host(host=self.compute.host) + + def fake_get_admin_context(): + return c + + def fake_all(*args, **kwargs): + pass + + def fake_list_instances(): + return [ + # those are still related to this host + CONF.instance_name_template % instances[0]['id'], + CONF.instance_name_template % instances[1]['id'], + CONF.instance_name_template % instances[2]['id'], + # and this one already been evacuated to other host + CONF.instance_name_template % evacuated_instance['id'] + ] + + def fake_list_instance_uuids(): + raise NotImplementedError() + + def fake_destroy(instance, nw, bdi, destroyDisks): + self.assertFalse(destroyDisks) + self.assertEqual(instance['uuid'], evacuated_instance['uuid']) + + self.stubs.Set(nova.context, + 'get_admin_context', + fake_get_admin_context) + self.stubs.Set(self.compute.driver, 'filter_defer_apply_on', fake_all) + self.stubs.Set(self.compute.driver, + 'list_instances', + fake_list_instances) + self.stubs.Set(self.compute.driver, + 'list_instance_uuids', + fake_list_instance_uuids) + + self.stubs.Set(self.compute, '_get_instance_nw_info', fake_all) + self.stubs.Set(self.compute, '_get_instance_volume_block_device_info', + fake_all) + self.stubs.Set(self.compute.driver, 'destroy', fake_destroy) + self.stubs.Set(self.compute, '_legacy_nw_info', fake_all) + self.stubs.Set(self.compute, '_init_instance', fake_all) + + self.stubs.Set(self.compute.driver, 'filter_defer_apply_off', fake_all) + self.stubs.Set(self.compute, '_report_driver_status', fake_all) + self.stubs.Set(self.compute, 'publish_service_capabilities', fake_all) + # start test + self.mox.ReplayAll() + self.compute.init_host() + + db.instance_destroy(c, evacuated_instance['uuid']) + for instance in instances: + db.instance_destroy(c, instance['uuid']) + class ComputeAPITestCase(BaseTestCase): diff --git a/nova/tests/compute/test_compute_utils.py b/nova/tests/compute/test_compute_utils.py index 5acc1cc53..bdd42d4f1 100644 --- a/nova/tests/compute/test_compute_utils.py +++ b/nova/tests/compute/test_compute_utils.py @@ -390,3 +390,97 @@ class MetadataToDictTestCase(test.TestCase): def test_metadata_to_dict_empty(self): self.assertEqual(compute_utils.metadata_to_dict([]), {}) + + +class ParseDecimalIDTestCase(test.TestCase): + + def setUp(self): + super(ParseDecimalIDTestCase, self).setUp() + self.context = context.RequestContext('fake', 'fake') + + self.templates = [ + CONF.instance_name_template, + 'instance-%08x', + 'instance-%08o', + 'instance-%08d', + 'instance-%04x', + 'instance-%04o', + 'instance-%04d', + 'instance-%x', + 'instance-%o', + 'instance-%d', + 'james-%07x-bond', + 'james-%07o-bond', + 'james-%07d-bond', + 'xxxx%xxxx', + 'oooo%oooo', + 'dddd%dddd', + '%02x', + '%02o', + '%02d', + '%x', + '%o', + '%d', + '%07x-bond', + '%07o-bond', + '%07d-bond', + '123%xxxx', + '123%oooo', + '123%dddd', + '007%02x', + '007%02o', + '007%02d', + '42%x', + '42%o', + '42%d', + '700%07x007', + '700%07o007', + '700%07d007'] + + self.ids = [ + 1, + 5, + 10, + 42, + 90, + 100, + 256, + 500, + 1000, + 2500, + 19294, + 100500, + 21093404 + ] + + def _validate_id(self, template, name): + return compute_utils.parse_decimal_id(template, name) + + def test_name_template_based(self): + for template in self.templates: + for id in self.ids: + self.assertEqual(id, self._validate_id(template, + template % id)) + + def test_name_not_template_based(self): + + for template in self.templates: + for id in self.ids: + name = template % id + + self.assertEqual(-1, self._validate_id(template, + 'n%s' % name)) + self.assertEqual(-1, self._validate_id(template, + '%sw' % name)) + self.assertEqual(-1, self._validate_id(template, + 'reg%s' % name)) + self.assertEqual(-1, self._validate_id(template, + '%sex' % name)) + self.assertEqual(-1, self._validate_id(template, '%s%s%s' % ( + name[:1], + 'abr', + name[-1:]))) + self.assertEqual(-1, self._validate_id(template, '%s%s%s' % ( + name[:1], + 'qwer23456ert', + name[-1:]))) -- cgit