From 0279d846abd20904fa5a1d357fac6727005a2943 Mon Sep 17 00:00:00 2001 From: Devananda van der Veen Date: Sat, 22 Dec 2012 16:35:58 -0800 Subject: Fix tests/baremetal/test_driver.py Unit tests for baremetal/driver.py were not functioning and were falsely reporting success due to inheriting from the wrong class. This lead to drift between the tests and the code over time. I decided it was easier to re-implement tests/baremetal/test_driver.py instead of trying to fix the drift. This gave me the chance to make the test class easier to extend. Additional tests will be added in the future, when I refactor driver.py:spawn(). This patch also has some minor variable name changes for baremetal/driver.py. blueprint general-bare-metal-provisioning-framework. Change-Id: I36ba5ed340b722b9a6e8d02d6d57d3c8d53b1eef --- nova/tests/baremetal/test_driver.py | 271 +++++++++++++++++------------------- nova/virt/baremetal/driver.py | 88 ++++++------ nova/virt/baremetal/fake.py | 37 ++++- 3 files changed, 207 insertions(+), 189 deletions(-) diff --git a/nova/tests/baremetal/test_driver.py b/nova/tests/baremetal/test_driver.py index b12336da0..d060d3a5d 100644 --- a/nova/tests/baremetal/test_driver.py +++ b/nova/tests/baremetal/test_driver.py @@ -1,3 +1,7 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# coding=utf-8 + +# Copyright 2012 Hewlett-Packard Development Company, L.P. # Copyright (c) 2012 NTT DOCOMO, INC. # Copyright (c) 2011 University of Southern California / ISI # All Rights Reserved. @@ -15,180 +19,161 @@ # under the License. """ -Tests for baremetal driver. +Tests for the base baremetal driver class. """ -from nova import exception +import mox + from nova.openstack.common import cfg -from nova.tests.baremetal.db import base -from nova.tests.baremetal.db import utils + +from nova import exception +from nova import test + +from nova.tests.baremetal.db import base as bm_db_base +from nova.tests.baremetal.db import utils as bm_db_utils from nova.tests.image import fake as fake_image -from nova.tests import test_virt_drivers -from nova.tests import utils as test_utils +from nova.tests import utils + from nova.virt.baremetal import baremetal_states from nova.virt.baremetal import db from nova.virt.baremetal import driver as bm_driver -from nova.virt.baremetal import volume_driver -from nova.virt.firewall import NoopFirewallDriver - +from nova.virt.baremetal import fake +from nova.virt import firewall CONF = cfg.CONF - -class FakeVifDriver(object): - - def plug(self, instance, vif): - pass - - def unplug(self, instance, vif): - pass - -FakeFirewallDriver = NoopFirewallDriver - - -class FakeVolumeDriver(volume_driver.VolumeDriver): - def __init__(self, virtapi): - super(FakeVolumeDriver, self).__init__(virtapi) - self._initiator = "testtesttest" - - -NODE = utils.new_bm_node(cpus=2, memory_mb=4096, service_host="host1") -NICS = [ - {'address': '01:23:45:67:89:01', 'datapath_id': '0x1', 'port_no': 1, }, - {'address': '01:23:45:67:89:02', 'datapath_id': '0x2', 'port_no': 2, }, - ] - - -def class_path(class_): - return class_.__module__ + '.' + class_.__name__ - - COMMON_FLAGS = dict( - firewall_driver=class_path(FakeFirewallDriver), + firewall_driver='nova.virt.baremetal.fake.FakeFirewallDriver', + host='test_host', ) BAREMETAL_FLAGS = dict( - driver='nova.virt.baremetal.fake.Fake', - host=NODE['service_host'], - instance_type_extra_specs=['cpu_arch:test'], + driver='nova.virt.baremetal.fake.FakeDriver', + instance_type_extra_specs=['cpu_arch:test', 'test_spec:test_value'], power_manager='nova.virt.baremetal.fake.FakePowerManager', - sql_connection='sqlite:///:memory:', - vif_driver=class_path(FakeVifDriver), - volume_driver=class_path(FakeVolumeDriver), + vif_driver='nova.virt.baremetal.fake.FakeVifDriver', + volume_driver='nova.virt.baremetal.fake.FakeVolumeDriver', group='baremetal', ) -def _create_baremetal_stuff(): - context = test_utils.get_test_admin_context() - node = db.bm_node_create(context, NODE) - for nic in NICS: - db.bm_interface_create(context, - node['id'], - nic['address'], - nic['datapath_id'], - nic['port_no']) - return node - - -class BaremetalDriverSpawnTestCase(base.Database): +class BareMetalDriverNoDBTestCase(test.TestCase): def setUp(self): - super(BaremetalDriverSpawnTestCase, self).setUp() + super(BareMetalDriverNoDBTestCase, self).setUp() self.flags(**COMMON_FLAGS) self.flags(**BAREMETAL_FLAGS) - fake_image.stub_out_image_service(self.stubs) + self.driver = bm_driver.BareMetalDriver(None) - self.node = _create_baremetal_stuff() - self.node_id = self.node['id'] + def test_validate_driver_loading(self): + self.assertTrue(isinstance(self.driver.driver, + fake.FakeDriver)) + self.assertTrue(isinstance(self.driver.vif_driver, + fake.FakeVifDriver)) + self.assertTrue(isinstance(self.driver.volume_driver, + fake.FakeVolumeDriver)) + self.assertTrue(isinstance(self.driver.firewall_driver, + fake.FakeFirewallDriver)) - self.context = test_utils.get_test_admin_context() - self.instance = test_utils.get_test_instance() - self.network_info = test_utils.get_test_network_info() - self.block_device_info = None - self.image_meta = test_utils.get_test_image_info(None, self.instance) - self.driver = bm_driver.BareMetalDriver(None) - self.kwargs = dict( - context=self.context, - instance=self.instance, - image_meta=self.image_meta, - injected_files=[('/foo', 'bar'), ('/abc', 'xyz')], - admin_password='testpass', - network_info=self.network_info, - block_device_info=self.block_device_info) - self.addCleanup(fake_image.FakeImageService_reset) - def test_ok(self): - self.instance['node'] = str(self.node_id) - self.driver.spawn(**self.kwargs) - node = db.bm_node_get(self.context, self.node_id) - self.assertEqual(node['instance_uuid'], self.instance['uuid']) - self.assertEqual(node['task_state'], baremetal_states.ACTIVE) - - def test_without_node(self): - self.assertRaises( - exception.NovaException, - self.driver.spawn, - **self.kwargs) - - def test_node_not_found(self): - self.instance['node'] = "123456789" - self.assertRaises( - exception.InstanceNotFound, - self.driver.spawn, - **self.kwargs) - - def test_node_in_use(self): - self.instance['node'] = str(self.node_id) - db.bm_node_update(self.context, self.node_id, - {'instance_uuid': 'something'}) - self.assertRaises( - exception.NovaException, - self.driver.spawn, - **self.kwargs) - - -class BaremetalDriverTestCase(test_virt_drivers._VirtDriverTestCase, - base.Database): +class BareMetalDriverWithDBTestCase(bm_db_base.BMDBTestCase): def setUp(self): - super(BaremetalDriverTestCase, self).setUp() - self.driver_module = 'nova.virt.baremetal.BareMetalDriver' + super(BareMetalDriverWithDBTestCase, self).setUp() self.flags(**COMMON_FLAGS) - self.node = _create_baremetal_stuff() - self.node_id = self.node['id'] + self.flags(**BAREMETAL_FLAGS) + fake_image.stub_out_image_service(self.stubs) + self.context = utils.get_test_admin_context() + self.driver = bm_driver.BareMetalDriver(None) + self.node_info = bm_db_utils.new_bm_node( + id=123, + service_host='test_host', + cpus=2, + memory_mb=2048, + ) + self.nic_info = [ + {'address': '01:23:45:67:89:01', 'datapath_id': '0x1', + 'port_no': 1}, + {'address': '01:23:45:67:89:02', 'datapath_id': '0x2', + 'port_no': 2}, + ] self.addCleanup(fake_image.FakeImageService_reset) - def _get_running_instance(self): - instance_ref = test_utils.get_test_instance() - instance_ref['node'] = str(self.node_id) - network_info = test_utils.get_test_network_info() - image_info = test_utils.get_test_image_info(None, instance_ref) - self.connection.spawn(self.ctxt, instance_ref, image_info, - [], 'herp', network_info=network_info) - return instance_ref, network_info - - def test_loading_baremetal_drivers(self): - from nova.virt.baremetal import fake - drv = bm_driver.BareMetalDriver(None) - self.assertTrue(isinstance(drv.baremetal_nodes, fake.Fake)) - self.assertTrue(isinstance(drv._vif_driver, FakeVifDriver)) - self.assertTrue(isinstance(drv._firewall_driver, FakeFirewallDriver)) - self.assertTrue(isinstance(drv._volume_driver, FakeVolumeDriver)) + def _create_node(self): + self.node = db.bm_node_create(self.context, self.node_info) + for nic in self.nic_info: + db.bm_interface_create( + self.context, + self.node['id'], + nic['address'], + nic['datapath_id'], + nic['port_no'], + ) + self.test_instance = utils.get_test_instance() + self.test_instance['node'] = self.node['id'] + self.spawn_params = dict( + admin_password='test_pass', + block_device_info=None, + context=self.context, + image_meta=utils.get_test_image_info(None, + self.test_instance), + injected_files=[('/fake/path', 'hello world')], + instance=self.test_instance, + network_info=utils.get_test_network_info(), + ) def test_get_host_stats(self): - self.flags(instance_type_extra_specs=['cpu_arch:x86_64', - 'x:123', - 'y:456', ]) - drv = bm_driver.BareMetalDriver(None) - cap_list = drv.get_host_stats() - self.assertTrue(isinstance(cap_list, list)) - self.assertEqual(len(cap_list), 1) - cap = cap_list[0] - self.assertEqual(cap['cpu_arch'], 'x86_64') - self.assertEqual(cap['x'], '123') - self.assertEqual(cap['y'], '456') - self.assertEqual(cap['hypervisor_type'], 'baremetal') - self.assertEqual(cap['driver'], - 'nova.virt.baremetal.fake.Fake') + self._create_node() + stats = self.driver.get_host_stats() + self.assertTrue(isinstance(stats, list)) + self.assertEqual(len(stats), 1) + stats = stats[0] + self.assertEqual(stats['cpu_arch'], 'test') + self.assertEqual(stats['test_spec'], 'test_value') + self.assertEqual(stats['hypervisor_type'], 'baremetal') + self.assertEqual(stats['hypervisor_hostname'], '123') + self.assertEqual(stats['host'], 'test_host') + self.assertEqual(stats['vcpus'], 2) + self.assertEqual(stats['host_memory_total'], 2048) + + def test_spawn_ok(self): + self._create_node() + self.driver.spawn(**self.spawn_params) + row = db.bm_node_get(self.context, self.node['id']) + self.assertEqual(row['task_state'], baremetal_states.ACTIVE) + + def test_spawn_node_in_use(self): + self._create_node() + db.bm_node_update(self.context, self.node['id'], + {'instance_uuid': '1234-5678'}) + + self.assertRaises(exception.NovaException, + self.driver.spawn, **self.spawn_params) + + row = db.bm_node_get(self.context, self.node['id']) + self.assertEqual(row['task_state'], None) + + def test_spawn_node_not_found(self): + self._create_node() + db.bm_node_update(self.context, self.node['id'], + {'id': 9876}) + + self.assertRaises(exception.InstanceNotFound, + self.driver.spawn, **self.spawn_params) + + row = db.bm_node_get(self.context, 9876) + self.assertEqual(row['task_state'], None) + + def test_spawn_fails(self): + self._create_node() + + self.mox.StubOutWithMock(fake.FakePowerManager, 'activate_node') + fake.FakePowerManager.activate_node().AndRaise(test.TestingException) + self.mox.ReplayAll() + + self.assertRaises(test.TestingException, + self.driver.spawn, **self.spawn_params) + + row = db.bm_node_get(self.context, self.node['id']) + self.assertEqual(row['task_state'], baremetal_states.ERROR) diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py index 120a36c3c..9c50c09dc 100644 --- a/nova/virt/baremetal/driver.py +++ b/nova/virt/baremetal/driver.py @@ -28,7 +28,7 @@ from nova.openstack.common import cfg from nova.openstack.common import importutils from nova.openstack.common import log as logging from nova.virt.baremetal import baremetal_states -from nova.virt.baremetal import db as bmdb +from nova.virt.baremetal import db from nova.virt import driver from nova.virt import firewall from nova.virt.libvirt import imagecache @@ -79,13 +79,13 @@ DEFAULT_FIREWALL_DRIVER = "%s.%s" % ( def _get_baremetal_nodes(context): - nodes = bmdb.bm_node_get_all(context, service_host=CONF.host) + nodes = db.bm_node_get_all(context, service_host=CONF.host) return nodes def _get_baremetal_node_by_instance_uuid(instance_uuid): ctx = nova_context.get_admin_context() - node = bmdb.bm_node_get_by_instance_uuid(ctx, instance_uuid) + node = db.bm_node_get_by_instance_uuid(ctx, instance_uuid) if node['service_host'] != CONF.host: LOG.error(_("Request for baremetal node %s " "sent to wrong service host") % instance_uuid) @@ -97,7 +97,7 @@ def _update_baremetal_state(context, node, instance, state): instance_uuid = None if instance: instance_uuid = instance['uuid'] - bmdb.bm_node_update(context, node['id'], + db.bm_node_update(context, node['id'], {'instance_uuid': instance_uuid, 'task_state': state, }) @@ -118,15 +118,15 @@ class BareMetalDriver(driver.ComputeDriver): def __init__(self, virtapi, read_only=False): super(BareMetalDriver, self).__init__(virtapi) - self.baremetal_nodes = importutils.import_object( + self.driver = importutils.import_object( CONF.baremetal.driver) - self._vif_driver = importutils.import_object( + self.vif_driver = importutils.import_object( CONF.baremetal.vif_driver) - self._firewall_driver = firewall.load_driver( + self.firewall_driver = firewall.load_driver( default=DEFAULT_FIREWALL_DRIVER) - self._volume_driver = importutils.import_object( + self.volume_driver = importutils.import_object( CONF.baremetal.volume_driver, virtapi) - self._image_cache_manager = imagecache.ImageCacheManager() + self.image_cache_manager = imagecache.ImageCacheManager() extra_specs = {} extra_specs["baremetal_driver"] = CONF.baremetal.driver @@ -139,9 +139,9 @@ class BareMetalDriver(driver.ComputeDriver): LOG.warning( _('cpu_arch is not found in instance_type_extra_specs')) extra_specs['cpu_arch'] = '' - self._extra_specs = extra_specs + self.extra_specs = extra_specs - self._supported_instances = [ + self.supported_instances = [ (extra_specs['cpu_arch'], 'baremetal', 'baremetal'), ] @@ -178,7 +178,7 @@ class BareMetalDriver(driver.ComputeDriver): if not nodename: raise exception.NovaException(_("Baremetal node id not supplied" " to driver")) - node = bmdb.bm_node_get(context, nodename) + node = db.bm_node_get(context, nodename) if node['instance_uuid']: raise exception.NovaException(_("Baremetal node %s already" " in use") % nodename) @@ -188,28 +188,28 @@ class BareMetalDriver(driver.ComputeDriver): _update_baremetal_state(context, node, instance, baremetal_states.BUILDING) - var = self.baremetal_nodes.define_vars(instance, network_info, + var = self.driver.define_vars(instance, network_info, block_device_info) self._plug_vifs(instance, network_info, context=context) - self._firewall_driver.setup_basic_filtering(instance, network_info) - self._firewall_driver.prepare_instance_filter(instance, + self.firewall_driver.setup_basic_filtering(instance, network_info) + self.firewall_driver.prepare_instance_filter(instance, network_info) - self.baremetal_nodes.create_image(var, context, image_meta, node, + self.driver.create_image(var, context, image_meta, node, instance, injected_files=injected_files, admin_password=admin_password) - self.baremetal_nodes.activate_bootloader(var, context, node, + self.driver.activate_bootloader(var, context, node, instance, image_meta) pm = get_power_manager(node) state = pm.activate_node() _update_baremetal_state(context, node, instance, state) - self.baremetal_nodes.activate_node(var, context, node, instance) - self._firewall_driver.apply_instance_filter(instance, network_info) + self.driver.activate_node(var, context, node, instance) + self.firewall_driver.apply_instance_filter(instance, network_info) block_device_mapping = driver.block_device_info_get_mapping( block_device_info) @@ -246,10 +246,10 @@ class BareMetalDriver(driver.ComputeDriver): % instance['uuid']) return - var = self.baremetal_nodes.define_vars(instance, network_info, + var = self.driver.define_vars(instance, network_info, block_device_info) - self.baremetal_nodes.deactivate_node(var, ctx, node, instance) + self.driver.deactivate_node(var, ctx, node, instance) pm = get_power_manager(node) @@ -267,12 +267,12 @@ class BareMetalDriver(driver.ComputeDriver): mountpoint = vol['mount_device'] self.detach_volume(connection_info, instance['name'], mountpoint) - self.baremetal_nodes.deactivate_bootloader(var, ctx, node, instance) + self.driver.deactivate_bootloader(var, ctx, node, instance) - self.baremetal_nodes.destroy_images(var, ctx, node, instance) + self.driver.destroy_images(var, ctx, node, instance) # stop firewall - self._firewall_driver.unfilter_instance(instance, + self.firewall_driver.unfilter_instance(instance, network_info=network_info) self._unplug_vifs(instance, network_info) @@ -292,15 +292,15 @@ class BareMetalDriver(driver.ComputeDriver): pm.activate_node() def get_volume_connector(self, instance): - return self._volume_driver.get_volume_connector(instance) + return self.volume_driver.get_volume_connector(instance) def attach_volume(self, connection_info, instance_name, mountpoint): - return self._volume_driver.attach_volume(connection_info, + return self.volume_driver.attach_volume(connection_info, instance_name, mountpoint) @exception.wrap_exception() def detach_volume(self, connection_info, instance_name, mountpoint): - return self._volume_driver.detach_volume(connection_info, + return self.volume_driver.detach_volume(connection_info, instance_name, mountpoint) def get_info(self, instance): @@ -319,15 +319,15 @@ class BareMetalDriver(driver.ComputeDriver): 'cpu_time': 0} def refresh_security_group_rules(self, security_group_id): - self._firewall_driver.refresh_security_group_rules(security_group_id) + self.firewall_driver.refresh_security_group_rules(security_group_id) return True def refresh_security_group_members(self, security_group_id): - self._firewall_driver.refresh_security_group_members(security_group_id) + self.firewall_driver.refresh_security_group_members(security_group_id) return True def refresh_provider_fw_rules(self): - self._firewall_driver.refresh_provider_fw_rules() + self.firewall_driver.refresh_provider_fw_rules() def _node_resource(self, node): vcpus_used = 0 @@ -356,27 +356,27 @@ class BareMetalDriver(driver.ComputeDriver): return dic def refresh_instance_security_rules(self, instance): - self._firewall_driver.refresh_instance_security_rules(instance) + self.firewall_driver.refresh_instance_security_rules(instance) def get_available_resource(self, nodename): context = nova_context.get_admin_context() - node = bmdb.bm_node_get(context, nodename) + node = db.bm_node_get(context, nodename) dic = self._node_resource(node) return dic def ensure_filtering_rules_for_instance(self, instance_ref, network_info): - self._firewall_driver.setup_basic_filtering(instance_ref, network_info) - self._firewall_driver.prepare_instance_filter(instance_ref, + self.firewall_driver.setup_basic_filtering(instance_ref, network_info) + self.firewall_driver.prepare_instance_filter(instance_ref, network_info) def unfilter_instance(self, instance_ref, network_info): - self._firewall_driver.unfilter_instance(instance_ref, + self.firewall_driver.unfilter_instance(instance_ref, network_info=network_info) def get_host_stats(self, refresh=False): caps = [] context = nova_context.get_admin_context() - nodes = bmdb.bm_node_get_all(context, + nodes = db.bm_node_get_all(context, service_host=CONF.host) for node in nodes: res = self._node_resource(node) @@ -393,8 +393,8 @@ class BareMetalDriver(driver.ComputeDriver): data['hypervisor_type'] = res['hypervisor_type'] data['hypervisor_version'] = res['hypervisor_version'] data['hypervisor_hostname'] = nodename - data['supported_instances'] = self._supported_instances - data.update(self._extra_specs) + data['supported_instances'] = self.supported_instances + data.update(self.extra_specs) data['host'] = CONF.host data['node'] = nodename # TODO(NTTdocomo): put node's extra specs here @@ -410,24 +410,24 @@ class BareMetalDriver(driver.ComputeDriver): context = nova_context.get_admin_context() node = _get_baremetal_node_by_instance_uuid(instance['uuid']) if node: - pifs = bmdb.bm_interface_get_all_by_bm_node_id(context, node['id']) + pifs = db.bm_interface_get_all_by_bm_node_id(context, node['id']) for pif in pifs: if pif['vif_uuid']: - bmdb.bm_interface_set_vif_uuid(context, pif['id'], None) + db.bm_interface_set_vif_uuid(context, pif['id'], None) for (network, mapping) in network_info: - self._vif_driver.plug(instance, (network, mapping)) + self.vif_driver.plug(instance, (network, mapping)) def _unplug_vifs(self, instance, network_info): for (network, mapping) in network_info: - self._vif_driver.unplug(instance, (network, mapping)) + self.vif_driver.unplug(instance, (network, mapping)) def manage_image_cache(self, context, all_instances): """Manage the local cache of images.""" - self._image_cache_manager.verify_base_images(context, all_instances) + self.image_cache_manager.verify_base_images(context, all_instances) def get_console_output(self, instance): node = _get_baremetal_node_by_instance_uuid(instance['uuid']) - return self.baremetal_nodes.get_console_output(node, instance) + return self.driver.get_console_output(node, instance) def get_available_nodes(self): context = nova_context.get_admin_context() diff --git a/nova/virt/baremetal/fake.py b/nova/virt/baremetal/fake.py index 9df964c39..920eb0c10 100644 --- a/nova/virt/baremetal/fake.py +++ b/nova/virt/baremetal/fake.py @@ -18,13 +18,14 @@ from nova.virt.baremetal import baremetal_states from nova.virt.baremetal import base +from nova.virt.firewall import NoopFirewallDriver def get_baremetal_nodes(): - return Fake() + return FakeDriver() -class Fake(base.NodeDriver): +class FakeDriver(base.NodeDriver): def define_vars(self, instance, network_info, block_device_info): return {} @@ -73,3 +74,35 @@ class FakePowerManager(base.PowerManager): def stop_console(self): pass + + +class FakeFirewallDriver(NoopFirewallDriver): + + def __init__(self): + super(FakeFirewallDriver, self).__init__() + + +class FakeVifDriver(object): + + def __init__(self): + super(FakeVifDriver, self).__init__() + + def plug(self, instance, vif): + pass + + def unplug(self, instance, vif): + pass + + +class FakeVolumeDriver(object): + + def __init__(self, virtapi): + super(FakeVolumeDriver, self).__init__() + self.virtapi = virtapi + self._initiator = "fake_initiator" + + def attach_volume(self, connection_info, instance_name, mountpoint): + pass + + def detach_volume(self, connection_info, instance_name, mountpoint): + pass -- cgit