Merge "Convert ironic virt driver to update_provider_tree"
This commit is contained in:
commit
697eeae50c
|
@ -912,19 +912,6 @@ class ResourceTracker(object):
|
||||||
self.scheduler_client.update_compute_node(context,
|
self.scheduler_client.update_compute_node(context,
|
||||||
compute_node)
|
compute_node)
|
||||||
|
|
||||||
try:
|
|
||||||
traits = self.driver.get_traits(nodename)
|
|
||||||
except NotImplementedError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# NOTE(mgoddard): set_traits_for_provider does not refresh the
|
|
||||||
# provider tree in the report client, so we rely on the above
|
|
||||||
# call to set_inventory_for_provider or update_compute_node to
|
|
||||||
# ensure that the resource provider exists in the tree and has
|
|
||||||
# had its cached traits refreshed.
|
|
||||||
self.reportclient.set_traits_for_provider(
|
|
||||||
context, compute_node.uuid, traits)
|
|
||||||
|
|
||||||
if self.pci_tracker:
|
if self.pci_tracker:
|
||||||
self.pci_tracker.save(context)
|
self.pci_tracker.save(context)
|
||||||
|
|
||||||
|
|
|
@ -1714,24 +1714,6 @@ class ProviderTreeTests(integrated_helpers.ProviderUsageBaseTestCase):
|
||||||
self.assertNotIn('FOO', traits)
|
self.assertNotIn('FOO', traits)
|
||||||
|
|
||||||
|
|
||||||
class TraitsTrackingTests(integrated_helpers.ProviderUsageBaseTestCase):
|
|
||||||
compute_driver = 'fake.SmallFakeDriver'
|
|
||||||
|
|
||||||
@mock.patch.object(fake.SmallFakeDriver, 'get_traits')
|
|
||||||
def test_resource_provider_traits(self, mock_traits):
|
|
||||||
traits = ['CUSTOM_FOO', 'HW_CPU_X86_VMX']
|
|
||||||
mock_traits.return_value = traits
|
|
||||||
|
|
||||||
self.assertNotIn('CUSTOM_FOO', self._get_all_traits())
|
|
||||||
self.assertEqual([], self._get_all_providers())
|
|
||||||
|
|
||||||
self.compute = self._start_compute(host='host1')
|
|
||||||
|
|
||||||
rp_uuid = self._get_provider_uuid_by_host('host1')
|
|
||||||
self.assertEqual(traits, sorted(self._get_provider_traits(rp_uuid)))
|
|
||||||
self.assertIn('CUSTOM_FOO', self._get_all_traits())
|
|
||||||
|
|
||||||
|
|
||||||
class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase):
|
class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase):
|
||||||
"""Tests moving servers while checking the resource allocations and usages
|
"""Tests moving servers while checking the resource allocations and usages
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,6 @@ def setup_rt(hostname, virt_resources=_VIRT_DRIVER_AVAIL_RESOURCES,
|
||||||
virt_resources = copy.deepcopy(virt_resources)
|
virt_resources = copy.deepcopy(virt_resources)
|
||||||
vd.get_available_resource.return_value = virt_resources
|
vd.get_available_resource.return_value = virt_resources
|
||||||
vd.get_inventory.side_effect = NotImplementedError
|
vd.get_inventory.side_effect = NotImplementedError
|
||||||
vd.get_traits.side_effect = NotImplementedError
|
|
||||||
vd.update_provider_tree.side_effect = NotImplementedError
|
vd.update_provider_tree.side_effect = NotImplementedError
|
||||||
vd.get_host_ip_addr.return_value = _NODENAME
|
vd.get_host_ip_addr.return_value = _NODENAME
|
||||||
vd.estimate_instance_overhead.side_effect = estimate_overhead
|
vd.estimate_instance_overhead.side_effect = estimate_overhead
|
||||||
|
@ -1209,7 +1208,6 @@ class TestUpdateComputeNode(BaseTestCase):
|
||||||
self.driver_mock.get_inventory.assert_called_once_with(_NODENAME)
|
self.driver_mock.get_inventory.assert_called_once_with(_NODENAME)
|
||||||
ucn_mock = self.sched_client_mock.update_compute_node
|
ucn_mock = self.sched_client_mock.update_compute_node
|
||||||
ucn_mock.assert_called_once_with(mock.sentinel.ctx, new_compute)
|
ucn_mock.assert_called_once_with(mock.sentinel.ctx, new_compute)
|
||||||
self.driver_mock.get_traits.assert_called_once_with(_NODENAME)
|
|
||||||
|
|
||||||
@mock.patch('nova.objects.ComputeNode.save')
|
@mock.patch('nova.objects.ComputeNode.save')
|
||||||
def test_existing_compute_node_updated_diff_updated_at(self, save_mock):
|
def test_existing_compute_node_updated_diff_updated_at(self, save_mock):
|
||||||
|
@ -1258,7 +1256,6 @@ class TestUpdateComputeNode(BaseTestCase):
|
||||||
self.assertFalse(norm_mock.called)
|
self.assertFalse(norm_mock.called)
|
||||||
ucn_mock = self.sched_client_mock.update_compute_node
|
ucn_mock = self.sched_client_mock.update_compute_node
|
||||||
ucn_mock.assert_called_once_with(mock.sentinel.ctx, new_compute)
|
ucn_mock.assert_called_once_with(mock.sentinel.ctx, new_compute)
|
||||||
self.driver_mock.get_traits.assert_called_once_with(_NODENAME)
|
|
||||||
|
|
||||||
@mock.patch('nova.compute.resource_tracker.'
|
@mock.patch('nova.compute.resource_tracker.'
|
||||||
'_normalize_inventory_from_cn_obj')
|
'_normalize_inventory_from_cn_obj')
|
||||||
|
@ -1274,7 +1271,7 @@ class TestUpdateComputeNode(BaseTestCase):
|
||||||
"""
|
"""
|
||||||
self._setup_rt()
|
self._setup_rt()
|
||||||
|
|
||||||
# Emulate a driver that has implemented the new get_inventory() virt
|
# Emulate a driver that has implemented the newish get_inventory() virt
|
||||||
# driver method
|
# driver method
|
||||||
self.driver_mock.get_inventory.side_effect = [mock.sentinel.inv_data]
|
self.driver_mock.get_inventory.side_effect = [mock.sentinel.inv_data]
|
||||||
|
|
||||||
|
@ -1297,35 +1294,6 @@ class TestUpdateComputeNode(BaseTestCase):
|
||||||
mock.sentinel.inv_data,
|
mock.sentinel.inv_data,
|
||||||
)
|
)
|
||||||
self.assertFalse(ucn_mock.called)
|
self.assertFalse(ucn_mock.called)
|
||||||
self.driver_mock.get_traits.assert_called_once_with(_NODENAME)
|
|
||||||
|
|
||||||
def test_existing_node_get_traits_implemented(self):
|
|
||||||
"""The get_traits() virt driver method is only implemented for some
|
|
||||||
virt drivers. This method returns traits information for a
|
|
||||||
node/provider, and if this method doesn't raise a NotImplementedError,
|
|
||||||
this triggers _update() to call the set_traits_for_provider() method of
|
|
||||||
the reporting client.
|
|
||||||
"""
|
|
||||||
self._setup_rt()
|
|
||||||
rc = self.rt.reportclient
|
|
||||||
rc.set_traits_for_provider = mock.MagicMock()
|
|
||||||
|
|
||||||
# Emulate a driver that has implemented the new get_traits() virt
|
|
||||||
# driver method
|
|
||||||
self.driver_mock.get_traits.side_effect = [mock.sentinel.traits]
|
|
||||||
|
|
||||||
orig_compute = _COMPUTE_NODE_FIXTURES[0].obj_clone()
|
|
||||||
self.rt.compute_nodes[_NODENAME] = orig_compute
|
|
||||||
self.rt.old_resources[_NODENAME] = orig_compute
|
|
||||||
new_compute = orig_compute.obj_clone()
|
|
||||||
|
|
||||||
self.rt._update(mock.sentinel.ctx, new_compute)
|
|
||||||
rc.set_traits_for_provider.assert_called_once_with(
|
|
||||||
mock.sentinel.ctx,
|
|
||||||
new_compute.uuid,
|
|
||||||
mock.sentinel.traits,
|
|
||||||
)
|
|
||||||
self.driver_mock.get_traits.assert_called_once_with(_NODENAME)
|
|
||||||
|
|
||||||
@mock.patch('nova.objects.ComputeNode.save')
|
@mock.patch('nova.objects.ComputeNode.save')
|
||||||
def test_existing_node_update_provider_tree_implemented(self, save_mock):
|
def test_existing_node_update_provider_tree_implemented(self, save_mock):
|
||||||
|
|
|
@ -27,6 +27,7 @@ from tooz import hashring as hash_ring
|
||||||
from nova.api.metadata import base as instance_metadata
|
from nova.api.metadata import base as instance_metadata
|
||||||
from nova import block_device
|
from nova import block_device
|
||||||
from nova.compute import power_state as nova_states
|
from nova.compute import power_state as nova_states
|
||||||
|
from nova.compute import provider_tree
|
||||||
from nova.compute import task_states
|
from nova.compute import task_states
|
||||||
from nova.compute import vm_states
|
from nova.compute import vm_states
|
||||||
from nova.console import type as console_type
|
from nova.console import type as console_type
|
||||||
|
@ -119,6 +120,9 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
self.ctx = nova_context.get_admin_context()
|
self.ctx = nova_context.get_admin_context()
|
||||||
self.instance_uuid = uuidutils.generate_uuid()
|
self.instance_uuid = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
self.ptree = provider_tree.ProviderTree()
|
||||||
|
self.ptree.new_root(mock.sentinel.nodename, mock.sentinel.nodename)
|
||||||
|
|
||||||
# mock retries configs to avoid sleeps and make tests run quicker
|
# mock retries configs to avoid sleeps and make tests run quicker
|
||||||
CONF.set_default('api_max_retries', default=1, group='ironic')
|
CONF.set_default('api_max_retries', default=1, group='ironic')
|
||||||
CONF.set_default('api_retry_interval', default=0, group='ironic')
|
CONF.set_default('api_retry_interval', default=0, group='ironic')
|
||||||
|
@ -709,8 +713,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'_node_resources_unavailable', return_value=False)
|
'_node_resources_unavailable', return_value=False)
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||||
def test_get_inventory_no_rc(self, mock_nfc, mock_nr, mock_res_unavail,
|
def test_update_provider_tree_no_rc(self, mock_nfc, mock_nr,
|
||||||
mock_res_used):
|
mock_res_unavail, mock_res_used):
|
||||||
"""Ensure that when node.resource_class is missing, that we return the
|
"""Ensure that when node.resource_class is missing, that we return the
|
||||||
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory.
|
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory.
|
||||||
"""
|
"""
|
||||||
|
@ -724,7 +728,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'resource_class': None,
|
'resource_class': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
result = self.driver.get_inventory(mock.sentinel.nodename)
|
self.driver.update_provider_tree(self.ptree, mock.sentinel.nodename)
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
fields.ResourceClass.VCPU: {
|
fields.ResourceClass.VCPU: {
|
||||||
|
@ -756,6 +760,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
result = self.ptree.data(mock.sentinel.nodename).inventory
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
@mock.patch.object(ironic_driver.IronicDriver,
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
@ -764,8 +769,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'_node_resources_unavailable', return_value=False)
|
'_node_resources_unavailable', return_value=False)
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||||
def test_get_inventory_with_rc(self, mock_nfc, mock_nr, mock_res_unavail,
|
def test_update_provider_tree_with_rc(self, mock_nfc, mock_nr,
|
||||||
mock_res_used):
|
mock_res_unavail, mock_res_used):
|
||||||
"""Ensure that when node.resource_class is present, that we return the
|
"""Ensure that when node.resource_class is present, that we return the
|
||||||
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory in addition
|
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory in addition
|
||||||
to the custom resource class inventory record.
|
to the custom resource class inventory record.
|
||||||
|
@ -780,7 +785,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'resource_class': 'iron-nfv',
|
'resource_class': 'iron-nfv',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = self.driver.get_inventory(mock.sentinel.nodename)
|
self.driver.update_provider_tree(self.ptree, mock.sentinel.nodename)
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
fields.ResourceClass.VCPU: {
|
fields.ResourceClass.VCPU: {
|
||||||
|
@ -820,6 +825,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
result = self.ptree.data(mock.sentinel.nodename).inventory
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
@mock.patch.object(ironic_driver.IronicDriver,
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
@ -828,8 +834,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'_node_resources_unavailable', return_value=False)
|
'_node_resources_unavailable', return_value=False)
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||||
def test_get_inventory_only_rc(self, mock_nfc, mock_nr, mock_res_unavail,
|
def test_update_provider_tree_only_rc(self, mock_nfc, mock_nr,
|
||||||
mock_res_used):
|
mock_res_unavail, mock_res_used):
|
||||||
"""Ensure that when node.resource_class is present, that we return the
|
"""Ensure that when node.resource_class is present, that we return the
|
||||||
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory in addition
|
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory in addition
|
||||||
to the custom resource class inventory record.
|
to the custom resource class inventory record.
|
||||||
|
@ -844,7 +850,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'resource_class': 'iron-nfv',
|
'resource_class': 'iron-nfv',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = self.driver.get_inventory(mock.sentinel.nodename)
|
self.driver.update_provider_tree(self.ptree, mock.sentinel.nodename)
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
'CUSTOM_IRON_NFV': {
|
'CUSTOM_IRON_NFV': {
|
||||||
|
@ -860,6 +866,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
result = self.ptree.data(mock.sentinel.nodename).inventory
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
@mock.patch.object(ironic_driver.IronicDriver,
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
@ -868,8 +875,9 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'_node_resources_unavailable', return_value=False)
|
'_node_resources_unavailable', return_value=False)
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||||
def test_get_inventory_with_rc_occupied(self, mock_nfc, mock_nr,
|
def test_update_provider_tree_with_rc_occupied(self, mock_nfc, mock_nr,
|
||||||
mock_res_unavail, mock_res_used):
|
mock_res_unavail,
|
||||||
|
mock_res_used):
|
||||||
"""Ensure that when a node is used, we report the inventory matching
|
"""Ensure that when a node is used, we report the inventory matching
|
||||||
the consumed resources.
|
the consumed resources.
|
||||||
"""
|
"""
|
||||||
|
@ -883,7 +891,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
'resource_class': 'iron-nfv',
|
'resource_class': 'iron-nfv',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = self.driver.get_inventory(mock.sentinel.nodename)
|
self.driver.update_provider_tree(self.ptree, mock.sentinel.nodename)
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
fields.ResourceClass.VCPU: {
|
fields.ResourceClass.VCPU: {
|
||||||
|
@ -923,6 +931,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||||
self.assertFalse(mock_res_unavail.called)
|
self.assertFalse(mock_res_unavail.called)
|
||||||
|
result = self.ptree.data(mock.sentinel.nodename).inventory
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
@mock.patch.object(ironic_driver.IronicDriver,
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
@ -930,37 +939,80 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
||||||
@mock.patch.object(ironic_driver.IronicDriver,
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
'_node_resources_unavailable', return_value=True)
|
'_node_resources_unavailable', return_value=True)
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||||
def test_get_inventory_disabled_node(self, mock_nfc, mock_res_unavail,
|
def test_update_provider_tree_disabled_node(self, mock_nfc,
|
||||||
mock_res_used):
|
mock_res_unavail,
|
||||||
"""Ensure that when a node is disabled, that get_inventory() returns
|
mock_res_used):
|
||||||
an empty dict.
|
"""Ensure that when a node is disabled, that update_provider_tree()
|
||||||
|
sets inventory to an empty dict.
|
||||||
"""
|
"""
|
||||||
result = self.driver.get_inventory(mock.sentinel.nodename)
|
self.driver.update_provider_tree(self.ptree, mock.sentinel.nodename)
|
||||||
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
result = self.ptree.data(mock.sentinel.nodename).inventory
|
||||||
self.assertEqual({}, result)
|
self.assertEqual({}, result)
|
||||||
|
|
||||||
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
'_node_resources_used', return_value=True)
|
||||||
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
'_node_resources_unavailable', return_value=False)
|
||||||
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||||
def test_get_traits_no_traits(self, mock_nfc):
|
def test_update_provider_tree_no_traits(self, mock_nfc, mock_nr,
|
||||||
"""Ensure that when the node has no traits, we return no traits."""
|
mock_res_unavail, mock_res_used):
|
||||||
node = _get_cached_node()
|
"""Ensure that when the node has no traits, we set no traits."""
|
||||||
mock_nfc.return_value = node
|
mock_nr.return_value = {
|
||||||
result = self.driver.get_traits(node.uuid)
|
'vcpus': 24,
|
||||||
|
'vcpus_used': 24,
|
||||||
|
'memory_mb': 1024,
|
||||||
|
'memory_mb_used': 1024,
|
||||||
|
'local_gb': 100,
|
||||||
|
'local_gb_used': 100,
|
||||||
|
'resource_class': 'iron-nfv',
|
||||||
|
}
|
||||||
|
|
||||||
mock_nfc.assert_called_once_with(node.uuid)
|
mock_nfc.return_value = _get_cached_node(uuid=mock.sentinel.nodename)
|
||||||
self.assertEqual([], result)
|
|
||||||
|
|
||||||
|
self.driver.update_provider_tree(self.ptree, mock.sentinel.nodename)
|
||||||
|
|
||||||
|
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||||
|
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
self.assertFalse(mock_res_unavail.called)
|
||||||
|
result = self.ptree.data(mock.sentinel.nodename).traits
|
||||||
|
self.assertEqual(set(), result)
|
||||||
|
|
||||||
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
'_node_resources_used', return_value=True)
|
||||||
|
@mock.patch.object(ironic_driver.IronicDriver,
|
||||||
|
'_node_resources_unavailable', return_value=False)
|
||||||
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||||
def test_get_traits_with_traits(self, mock_nfc):
|
def test_update_provider_tree_with_traits(self, mock_nfc, mock_nr,
|
||||||
"""Ensure that when the node has traits, we return the traits."""
|
mock_res_unavail, mock_res_used):
|
||||||
node = _get_cached_node(traits=['trait1', 'trait2'])
|
"""Ensure that when the node has traits, we set the traits."""
|
||||||
mock_nfc.return_value = node
|
mock_nr.return_value = {
|
||||||
result = self.driver.get_traits(node.uuid)
|
'vcpus': 24,
|
||||||
|
'vcpus_used': 24,
|
||||||
|
'memory_mb': 1024,
|
||||||
|
'memory_mb_used': 1024,
|
||||||
|
'local_gb': 100,
|
||||||
|
'local_gb_used': 100,
|
||||||
|
'resource_class': 'iron-nfv',
|
||||||
|
}
|
||||||
|
|
||||||
expected = ['trait1', 'trait2']
|
traits = ['trait1', 'trait2']
|
||||||
mock_nfc.assert_called_once_with(node.uuid)
|
mock_nfc.return_value = _get_cached_node(
|
||||||
self.assertEqual(expected, result)
|
uuid=mock.sentinel.nodename, traits=traits)
|
||||||
|
|
||||||
|
self.driver.update_provider_tree(self.ptree, mock.sentinel.nodename)
|
||||||
|
|
||||||
|
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||||
|
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||||
|
self.assertFalse(mock_res_unavail.called)
|
||||||
|
result = self.ptree.data(mock.sentinel.nodename).traits
|
||||||
|
self.assertEqual(set(traits), result)
|
||||||
|
|
||||||
@mock.patch.object(FAKE_CLIENT.node, 'get')
|
@mock.patch.object(FAKE_CLIENT.node, 'get')
|
||||||
@mock.patch.object(FAKE_CLIENT.node, 'list')
|
@mock.patch.object(FAKE_CLIENT.node, 'list')
|
||||||
|
|
|
@ -883,17 +883,6 @@ class ComputeDriver(object):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_traits(self, nodename):
|
|
||||||
"""Get the traits for a given node.
|
|
||||||
|
|
||||||
Any custom traits returned are not required to exist in the placement
|
|
||||||
service - the caller will ensure their existence.
|
|
||||||
|
|
||||||
:param nodename: the name of the node.
|
|
||||||
:returns: an iterable of string trait names for the supplied node.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def get_available_resource(self, nodename):
|
def get_available_resource(self, nodename):
|
||||||
"""Retrieve resource information.
|
"""Retrieve resource information.
|
||||||
|
|
||||||
|
|
|
@ -734,9 +734,21 @@ class IronicDriver(virt_driver.ComputeDriver):
|
||||||
|
|
||||||
return node_uuids
|
return node_uuids
|
||||||
|
|
||||||
def get_inventory(self, nodename):
|
def update_provider_tree(self, provider_tree, nodename):
|
||||||
"""Return a dict, keyed by resource class, of inventory information for
|
"""Update a ProviderTree object with current resource provider and
|
||||||
the supplied node.
|
inventory information.
|
||||||
|
|
||||||
|
:param nova.compute.provider_tree.ProviderTree provider_tree:
|
||||||
|
A nova.compute.provider_tree.ProviderTree object representing all
|
||||||
|
the providers in the tree associated with the compute node, and any
|
||||||
|
sharing providers (those with the ``MISC_SHARES_VIA_AGGREGATE``
|
||||||
|
trait) associated via aggregate with any of those providers (but
|
||||||
|
not *their* tree- or aggregate-associated providers), as currently
|
||||||
|
known by placement.
|
||||||
|
:param nodename:
|
||||||
|
String name of the compute node (i.e.
|
||||||
|
ComputeNode.hypervisor_hostname) for which the caller is requesting
|
||||||
|
updated provider information.
|
||||||
"""
|
"""
|
||||||
# nodename is the ironic node's UUID.
|
# nodename is the ironic node's UUID.
|
||||||
node = self._node_from_cache(nodename)
|
node = self._node_from_cache(nodename)
|
||||||
|
@ -788,19 +800,10 @@ class IronicDriver(virt_driver.ComputeDriver):
|
||||||
'allocation_ratio': 1.0,
|
'allocation_ratio': 1.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
provider_tree.update_inventory(nodename, result)
|
||||||
|
# TODO(efried): *Unset* traits that are "owned" by ironic virt but not
|
||||||
def get_traits(self, nodename):
|
# set on the node object.
|
||||||
"""Get the traits for a given node.
|
provider_tree.add_traits(nodename, *node.traits)
|
||||||
|
|
||||||
Any custom traits returned are not required to exist in the placement
|
|
||||||
service - the caller will ensure their existence.
|
|
||||||
|
|
||||||
:param nodename: the UUID of the node.
|
|
||||||
:returns: an iterable of string trait names for the supplied node.
|
|
||||||
"""
|
|
||||||
node = self._node_from_cache(nodename)
|
|
||||||
return list(node.traits)
|
|
||||||
|
|
||||||
def get_available_resource(self, nodename):
|
def get_available_resource(self, nodename):
|
||||||
"""Retrieve resource information.
|
"""Retrieve resource information.
|
||||||
|
|
Loading…
Reference in New Issue