diff options
Diffstat (limited to 'ironic/tests/unit/drivers/ilo/test_inspect.py')
-rw-r--r-- | ironic/tests/unit/drivers/ilo/test_inspect.py | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/ironic/tests/unit/drivers/ilo/test_inspect.py b/ironic/tests/unit/drivers/ilo/test_inspect.py new file mode 100644 index 000000000..94ddbdd45 --- /dev/null +++ b/ironic/tests/unit/drivers/ilo/test_inspect.py @@ -0,0 +1,365 @@ +# Copyright 2014 Hewlett-Packard Development Company, L.P. +# +# 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. + + +"""Test class for Management Interface used by iLO modules.""" + +import mock +from oslo_config import cfg +import six + +from ironic.common import exception +from ironic.common import states +from ironic.common import utils +from ironic.conductor import task_manager +from ironic.conductor import utils as conductor_utils +from ironic.db import api as dbapi +from ironic.drivers.modules.ilo import common as ilo_common +from ironic.drivers.modules.ilo import inspect as ilo_inspect +from ironic.drivers.modules.ilo import power as ilo_power +from ironic.tests.unit.conductor import utils as mgr_utils +from ironic.tests.unit.db import base as db_base +from ironic.tests.unit.db import utils as db_utils +from ironic.tests.unit.objects import utils as obj_utils + + +INFO_DICT = db_utils.get_test_ilo_info() +CONF = cfg.CONF + + +class IloInspectTestCase(db_base.DbTestCase): + + def setUp(self): + super(IloInspectTestCase, self).setUp() + mgr_utils.mock_the_extension_manager(driver="fake_ilo") + self.node = obj_utils.create_test_node( + self.context, driver='fake_ilo', driver_info=INFO_DICT) + + def test_get_properties(self): + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + properties = ilo_common.REQUIRED_PROPERTIES.copy() + self.assertEqual(properties, + task.driver.inspect.get_properties()) + + @mock.patch.object(ilo_common, 'parse_driver_info', spec_set=True, + autospec=True) + def test_validate(self, driver_info_mock): + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + task.driver.inspect.validate(task) + driver_info_mock.assert_called_once_with(task.node) + + @mock.patch.object(ilo_inspect, '_get_capabilities', spec_set=True, + autospec=True) + @mock.patch.object(ilo_inspect, '_create_ports_if_not_exist', + spec_set=True, autospec=True) + @mock.patch.object(ilo_inspect, '_get_essential_properties', spec_set=True, + autospec=True) + @mock.patch.object(ilo_power.IloPower, 'get_power_state', spec_set=True, + autospec=True) + @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True, + autospec=True) + def test_inspect_essential_ok(self, get_ilo_object_mock, + power_mock, + get_essential_mock, + create_port_mock, + get_capabilities_mock): + ilo_object_mock = get_ilo_object_mock.return_value + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + capabilities = '' + result = {'properties': properties, 'macs': macs} + get_essential_mock.return_value = result + get_capabilities_mock.return_value = capabilities + power_mock.return_value = states.POWER_ON + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + task.driver.inspect.inspect_hardware(task) + self.assertEqual(properties, task.node.properties) + power_mock.assert_called_once_with(mock.ANY, task) + get_essential_mock.assert_called_once_with(task.node, + ilo_object_mock) + get_capabilities_mock.assert_called_once_with(task.node, + ilo_object_mock) + create_port_mock.assert_called_once_with(task.node, macs) + + @mock.patch.object(ilo_inspect, '_get_capabilities', spec_set=True, + autospec=True) + @mock.patch.object(ilo_inspect, '_create_ports_if_not_exist', + spec_set=True, autospec=True) + @mock.patch.object(ilo_inspect, '_get_essential_properties', spec_set=True, + autospec=True) + @mock.patch.object(conductor_utils, 'node_power_action', spec_set=True, + autospec=True) + @mock.patch.object(ilo_power.IloPower, 'get_power_state', spec_set=True, + autospec=True) + @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True, + autospec=True) + def test_inspect_essential_ok_power_off(self, get_ilo_object_mock, + power_mock, + set_power_mock, + get_essential_mock, + create_port_mock, + get_capabilities_mock): + ilo_object_mock = get_ilo_object_mock.return_value + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + capabilities = '' + result = {'properties': properties, 'macs': macs} + get_essential_mock.return_value = result + get_capabilities_mock.return_value = capabilities + power_mock.return_value = states.POWER_OFF + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + task.driver.inspect.inspect_hardware(task) + self.assertEqual(properties, task.node.properties) + power_mock.assert_called_once_with(mock.ANY, task) + set_power_mock.assert_any_call(task, states.POWER_ON) + get_essential_mock.assert_called_once_with(task.node, + ilo_object_mock) + get_capabilities_mock.assert_called_once_with(task.node, + ilo_object_mock) + create_port_mock.assert_called_once_with(task.node, macs) + + @mock.patch.object(ilo_inspect, '_get_capabilities', spec_set=True, + autospec=True) + @mock.patch.object(ilo_inspect, '_create_ports_if_not_exist', + spec_set=True, autospec=True) + @mock.patch.object(ilo_inspect, '_get_essential_properties', spec_set=True, + autospec=True) + @mock.patch.object(ilo_power.IloPower, 'get_power_state', spec_set=True, + autospec=True) + @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True, + autospec=True) + def test_inspect_essential_capabilities_ok(self, get_ilo_object_mock, + power_mock, + get_essential_mock, + create_port_mock, + get_capabilities_mock): + ilo_object_mock = get_ilo_object_mock.return_value + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + capability_str = 'BootMode:uefi' + capabilities = {'BootMode': 'uefi'} + result = {'properties': properties, 'macs': macs} + get_essential_mock.return_value = result + get_capabilities_mock.return_value = capabilities + power_mock.return_value = states.POWER_ON + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + task.driver.inspect.inspect_hardware(task) + expected_properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64', + 'capabilities': capability_str} + self.assertEqual(expected_properties, task.node.properties) + power_mock.assert_called_once_with(mock.ANY, task) + get_essential_mock.assert_called_once_with(task.node, + ilo_object_mock) + get_capabilities_mock.assert_called_once_with(task.node, + ilo_object_mock) + create_port_mock.assert_called_once_with(task.node, macs) + + @mock.patch.object(ilo_inspect, '_get_capabilities', spec_set=True, + autospec=True) + @mock.patch.object(ilo_inspect, '_create_ports_if_not_exist', + spec_set=True, autospec=True) + @mock.patch.object(ilo_inspect, '_get_essential_properties', spec_set=True, + autospec=True) + @mock.patch.object(ilo_power.IloPower, 'get_power_state', spec_set=True, + autospec=True) + @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True, + autospec=True) + def test_inspect_essential_capabilities_exist_ok(self, get_ilo_object_mock, + power_mock, + get_essential_mock, + create_port_mock, + get_capabilities_mock): + ilo_object_mock = get_ilo_object_mock.return_value + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64', + 'somekey': 'somevalue'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + result = {'properties': properties, 'macs': macs} + capabilities = {'BootMode': 'uefi'} + get_essential_mock.return_value = result + get_capabilities_mock.return_value = capabilities + power_mock.return_value = states.POWER_ON + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + task.node.properties = {'capabilities': 'foo:bar'} + expected_capabilities = ('BootMode:uefi,' + 'foo:bar') + set1 = set(expected_capabilities.split(',')) + task.driver.inspect.inspect_hardware(task) + end_capabilities = task.node.properties['capabilities'] + set2 = set(end_capabilities.split(',')) + self.assertEqual(set1, set2) + expected_properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64', + 'capabilities': end_capabilities} + power_mock.assert_called_once_with(mock.ANY, task) + self.assertEqual(task.node.properties, expected_properties) + get_essential_mock.assert_called_once_with(task.node, + ilo_object_mock) + get_capabilities_mock.assert_called_once_with(task.node, + ilo_object_mock) + create_port_mock.assert_called_once_with(task.node, macs) + + +class TestInspectPrivateMethods(db_base.DbTestCase): + + def setUp(self): + super(TestInspectPrivateMethods, self).setUp() + mgr_utils.mock_the_extension_manager(driver="fake_ilo") + self.node = obj_utils.create_test_node( + self.context, driver='fake_ilo', driver_info=INFO_DICT) + + @mock.patch.object(ilo_inspect.LOG, 'info', spec_set=True, autospec=True) + @mock.patch.object(dbapi, 'get_instance', spec_set=True, autospec=True) + def test__create_ports_if_not_exist(self, instance_mock, log_mock): + db_obj = instance_mock.return_value + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + node_id = self.node.id + port_dict1 = {'address': 'aa:aa:aa:aa:aa:aa', 'node_id': node_id} + port_dict2 = {'address': 'bb:bb:bb:bb:bb:bb', 'node_id': node_id} + ilo_inspect._create_ports_if_not_exist(self.node, macs) + instance_mock.assert_called_once_with() + self.assertTrue(log_mock.called) + db_obj.create_port.assert_any_call(port_dict1) + db_obj.create_port.assert_any_call(port_dict2) + + @mock.patch.object(ilo_inspect.LOG, 'warn', spec_set=True, autospec=True) + @mock.patch.object(dbapi, 'get_instance', spec_set=True, autospec=True) + def test__create_ports_if_not_exist_mac_exception(self, + instance_mock, + log_mock): + dbapi_mock = instance_mock.return_value + dbapi_mock.create_port.side_effect = exception.MACAlreadyExists('f') + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + ilo_inspect._create_ports_if_not_exist(self.node, macs) + instance_mock.assert_called_once_with() + self.assertTrue(log_mock.called) + + def test__get_essential_properties_ok(self): + ilo_mock = mock.MagicMock(spec=['get_essential_properties']) + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + result = {'properties': properties, 'macs': macs} + ilo_mock.get_essential_properties.return_value = result + actual_result = ilo_inspect._get_essential_properties(self.node, + ilo_mock) + self.assertEqual(result, actual_result) + + def test__get_essential_properties_fail(self): + ilo_mock = mock.MagicMock( + spec=['get_additional_capabilities', 'get_essential_properties']) + # Missing key: cpu_arch + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa', 'Port 2': 'bb:bb:bb:bb:bb:bb'} + result = {'properties': properties, 'macs': macs} + ilo_mock.get_essential_properties.return_value = result + result = self.assertRaises(exception.HardwareInspectionFailure, + ilo_inspect._get_essential_properties, + self.node, + ilo_mock) + self.assertEqual( + six.text_type(result), + ("Failed to inspect hardware. Reason: Server didn't return the " + "key(s): cpu_arch")) + + def test__get_essential_properties_fail_invalid_format(self): + ilo_mock = mock.MagicMock( + spec=['get_additional_capabilities', 'get_essential_properties']) + # Not a dict + properties = ['memory_mb', '512', 'local_gb', '10', + 'cpus', '1'] + macs = ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb'] + capabilities = '' + result = {'properties': properties, 'macs': macs} + ilo_mock.get_essential_properties.return_value = result + ilo_mock.get_additional_capabilities.return_value = capabilities + self.assertRaises(exception.HardwareInspectionFailure, + ilo_inspect._get_essential_properties, + self.node, ilo_mock) + + def test__get_essential_properties_fail_mac_invalid_format(self): + ilo_mock = mock.MagicMock(spec=['get_essential_properties']) + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64'} + # Not a dict + macs = 'aa:aa:aa:aa:aa:aa' + result = {'properties': properties, 'macs': macs} + ilo_mock.get_essential_properties.return_value = result + self.assertRaises(exception.HardwareInspectionFailure, + ilo_inspect._get_essential_properties, + self.node, ilo_mock) + + def test__get_essential_properties_hardware_port_empty(self): + ilo_mock = mock.MagicMock( + spec=['get_additional_capabilities', 'get_essential_properties']) + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64'} + # Not a dictionary + macs = None + result = {'properties': properties, 'macs': macs} + capabilities = '' + ilo_mock.get_essential_properties.return_value = result + ilo_mock.get_additional_capabilities.return_value = capabilities + self.assertRaises(exception.HardwareInspectionFailure, + ilo_inspect._get_essential_properties, + self.node, ilo_mock) + + def test__get_essential_properties_hardware_port_not_dict(self): + ilo_mock = mock.MagicMock(spec=['get_essential_properties']) + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1', 'cpu_arch': 'x86_64'} + # Not a dict + macs = 'aa:bb:cc:dd:ee:ff' + result = {'properties': properties, 'macs': macs} + ilo_mock.get_essential_properties.return_value = result + result = self.assertRaises( + exception.HardwareInspectionFailure, + ilo_inspect._get_essential_properties, self.node, ilo_mock) + + @mock.patch.object(utils, 'get_updated_capabilities', spec_set=True, + autospec=True) + def test__get_capabilities_ok(self, capability_mock): + ilo_mock = mock.MagicMock(spec=['get_server_capabilities']) + capabilities = {'ilo_firmware_version': 'xyz'} + ilo_mock.get_server_capabilities.return_value = capabilities + cap = ilo_inspect._get_capabilities(self.node, ilo_mock) + self.assertEqual(cap, capabilities) + + def test__validate_ok(self): + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '2', 'cpu_arch': 'x86_arch'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa'} + data = {'properties': properties, 'macs': macs} + valid_keys = ilo_inspect.IloInspect.ESSENTIAL_PROPERTIES + ilo_inspect._validate(self.node, data) + self.assertEqual(sorted(set(properties)), sorted(valid_keys)) + + def test__validate_essential_keys_fail_missing_key(self): + properties = {'memory_mb': '512', 'local_gb': '10', + 'cpus': '1'} + macs = {'Port 1': 'aa:aa:aa:aa:aa:aa'} + data = {'properties': properties, 'macs': macs} + self.assertRaises(exception.HardwareInspectionFailure, + ilo_inspect._validate, self.node, data) |