From 9ac0b51736fb11641c0983e701e8b90f9467043a Mon Sep 17 00:00:00 2001 From: Mikyung Kang Date: Thu, 13 Dec 2012 02:56:56 +0900 Subject: [PATCH] New Baremetal provisioning framework. This is a minimal patch for the new baremetal driver. With this driver, nova compute registers multiple entries of baremetal nodes. It periodically updates the capabilities of the multiple baremetal nodes and reports it as a list of capabilities. It does not include Tilera or PXE back-ends, which will be provided by subsequent patches. It also does not include VIF or volume components. Part 4 of 7: blueprint general-bare-metal-provisioning-framework. Change-Id: I55617a8da52d20d4df727b8bbde8e5f72d3bf130 Co-authored-by: Mikyung Kang Co-authored-by: David Kang Co-authored-by: Ken Igarashi Co-authored-by: Arata Notsu Co-authored-by: Chris Krelle Co-authored-by: Devananda van der Veen --- nova/tests/baremetal/__init__.py | 2 +- nova/tests/baremetal/db/__init__.py | 1 + nova/tests/baremetal/db/test_bm_interface.py | 17 -- nova/tests/baremetal/db/utils.py | 1 - nova/tests/baremetal/test_driver.py | 173 +++++++++++++++++++ 5 files changed, 175 insertions(+), 19 deletions(-) create mode 100644 nova/tests/baremetal/test_driver.py diff --git a/nova/tests/baremetal/__init__.py b/nova/tests/baremetal/__init__.py index eef64faeb..f15d84efc 100644 --- a/nova/tests/baremetal/__init__.py +++ b/nova/tests/baremetal/__init__.py @@ -12,4 +12,4 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -from nova.tests import * +from nova.tests.baremetal import * diff --git a/nova/tests/baremetal/db/__init__.py b/nova/tests/baremetal/db/__init__.py index 19071662c..543dfc1ae 100644 --- a/nova/tests/baremetal/db/__init__.py +++ b/nova/tests/baremetal/db/__init__.py @@ -12,3 +12,4 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from nova.tests.baremetal.db import * diff --git a/nova/tests/baremetal/db/test_bm_interface.py b/nova/tests/baremetal/db/test_bm_interface.py index 9f051ac9b..a9168bff6 100644 --- a/nova/tests/baremetal/db/test_bm_interface.py +++ b/nova/tests/baremetal/db/test_bm_interface.py @@ -35,20 +35,3 @@ class BareMetalInterfaceTestCase(base.BMDBTestCase): pif2_id = db.bm_interface_create(self.context, 2, '11:11:11:11:11:11', '0x2', 2) self.assertTrue(pif2_id is not None) - - def test_unique_vif_uuid(self): - pif1_id = db.bm_interface_create(self.context, 1, '11:11:11:11:11:11', - '0x1', 1) - pif2_id = db.bm_interface_create(self.context, 2, '22:22:22:22:22:22', - '0x2', 2) - db.bm_interface_set_vif_uuid(self.context, pif1_id, 'AAAA') - self.assertRaises(exception.NovaException, - db.bm_interface_set_vif_uuid, - self.context, pif2_id, 'AAAA') - - def test_vif_not_found(self): - pif_id = db.bm_interface_create(self.context, 1, '11:11:11:11:11:11', - '0x1', 1) - self.assertRaises(exception.NovaException, - db.bm_interface_set_vif_uuid, - self.context, pif_id + 1, 'AAAA') diff --git a/nova/tests/baremetal/db/utils.py b/nova/tests/baremetal/db/utils.py index 800305402..034f2f25a 100644 --- a/nova/tests/baremetal/db/utils.py +++ b/nova/tests/baremetal/db/utils.py @@ -60,7 +60,6 @@ def new_bm_interface(**kwargs): x.address = kwargs.pop('address', None) x.datapath_id = kwargs.pop('datapath_id', None) x.port_no = kwargs.pop('port_no', None) - x.vif_uuid = kwargs.pop('vif_uuid', None) if len(kwargs) > 0: raise test.TestingException("unknown field: %s" % ','.join(kwargs.keys())) diff --git a/nova/tests/baremetal/test_driver.py b/nova/tests/baremetal/test_driver.py new file mode 100644 index 000000000..117520e94 --- /dev/null +++ b/nova/tests/baremetal/test_driver.py @@ -0,0 +1,173 @@ +# Copyright (c) 2012 NTT DOCOMO, INC. +# Copyright (c) 2011 University of Southern California / ISI +# 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 baremetal driver. +""" + +import mox + +from nova import exception +from nova.openstack.common import cfg +from nova import test +from nova.tests.baremetal.db import base +from nova.tests.baremetal.db import 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.virt.baremetal import baremetal_states +from nova.virt.baremetal import db +from nova.virt.baremetal import driver as bm_driver +from nova.virt.firewall import NoopFirewallDriver + + +CONF = cfg.CONF + + +FakeFirewallDriver = NoopFirewallDriver + + +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( + baremetal_sql_connection='sqlite:///:memory:', + baremetal_driver='nova.virt.baremetal.fake.Fake', + power_manager='nova.virt.baremetal.fake.FakePowerManager', + firewall_driver=class_path(FakeFirewallDriver), + instance_type_extra_specs=['cpu_arch:test'], + host=NODE['service_host'], +) + + +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): + + def setUp(self): + super(BaremetalDriverSpawnTestCase, self).setUp() + self.flags(**COMMON_FLAGS) + fake_image.stub_out_image_service(self.stubs) + + self.node = _create_baremetal_stuff() + self.node_id = self.node['id'] + + 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): + + def setUp(self): + super(BaremetalDriverTestCase, self).setUp() + self.driver_module = 'nova.virt.baremetal.BareMetalDriver' + self.flags(**COMMON_FLAGS) + self.node = _create_baremetal_stuff() + self.node_id = self.node['id'] + fake_image.stub_out_image_service(self.stubs) + 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._firewall_driver, FakeFirewallDriver)) + + 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['baremetal_driver'], + 'nova.virt.baremetal.fake.Fake')