placement: refactor instance translate function

Makes the _allocations() object method of the SchedulerReportingClient
into a simple module-level function called
_instance_to_allocations_dict(). This makes the function name match what
the returned result is and indicates what the function actually does.

Change-Id: I0da4393fe884f626bb306a251472590535aab331
This commit is contained in:
Jay Pipes 2016-09-20 15:10:15 -04:00
parent 310e4dcbd8
commit a6cfc685dd
2 changed files with 74 additions and 60 deletions

View File

@ -93,6 +93,25 @@ def _compute_node_to_inventory_dict(compute_node):
}
def _instance_to_allocations_dict(instance):
"""Given an `objects.Instance` object, return a dict, keyed by resource
class of the amount used by the instance.
:param instance: `objects.Instance` object to translate
"""
# NOTE(danms): Boot-from-volume instances consume no local disk
is_bfv = compute_utils.is_volume_backed_instance(instance._context,
instance)
disk = ((0 if is_bfv else instance.flavor.root_gb) +
instance.flavor.swap +
instance.flavor.ephemeral_gb)
return {
MEMORY_MB: instance.flavor.memory_mb,
VCPU: instance.flavor.vcpus,
DISK_GB: disk,
}
class SchedulerReportClient(object):
"""Client class for updating the scheduler."""
@ -348,19 +367,6 @@ class SchedulerReportClient(object):
compute_node.hypervisor_hostname)
self._update_inventory(compute_node)
def _allocations(self, instance):
# NOTE(danms): Boot-from-volume instances consume no local disk
is_bfv = compute_utils.is_volume_backed_instance(instance._context,
instance)
disk = ((0 if is_bfv else instance.flavor.root_gb) +
instance.flavor.swap +
instance.flavor.ephemeral_gb)
return {
MEMORY_MB: instance.flavor.memory_mb,
VCPU: instance.flavor.vcpus,
DISK_GB: disk,
}
def _get_allocations_for_instance(self, compute_node, instance):
url = '/allocations/%s' % instance.uuid
resp = self.get(url)
@ -377,7 +383,7 @@ class SchedulerReportClient(object):
def _allocate_for_instance(self, compute_node, instance):
url = '/allocations/%s' % instance.uuid
my_allocations = self._allocations(instance)
my_allocations = _instance_to_allocations_dict(instance)
current_allocations = self._get_allocations_for_instance(compute_node,
instance)
if current_allocations == my_allocations:

View File

@ -676,7 +676,7 @@ class TestInventory(SchedulerReportClientTestCase):
class TestAllocations(SchedulerReportClientTestCase):
@mock.patch('nova.compute.utils.is_volume_backed_instance')
def test_allocations(self, mock_vbi):
def test_instance_to_allocations_dict(self, mock_vbi):
mock_vbi.return_value = False
inst = objects.Instance(
uuid=uuids.inst,
@ -685,15 +685,16 @@ class TestAllocations(SchedulerReportClientTestCase):
ephemeral_gb=100,
memory_mb=1024,
vcpus=2))
result = report._instance_to_allocations_dict(inst)
expected = {
'MEMORY_MB': 1024,
'VCPU': 2,
'DISK_GB': 111,
}
self.assertEqual(expected, self.client._allocations(inst))
self.assertEqual(expected, result)
@mock.patch('nova.compute.utils.is_volume_backed_instance')
def test_allocations_boot_from_volume(self, mock_vbi):
def test_instance_to_allocations_dict_boot_from_volume(self, mock_vbi):
mock_vbi.return_value = True
inst = objects.Instance(
uuid=uuids.inst,
@ -702,38 +703,44 @@ class TestAllocations(SchedulerReportClientTestCase):
ephemeral_gb=100,
memory_mb=1024,
vcpus=2))
result = report._instance_to_allocations_dict(inst)
expected = {
'MEMORY_MB': 1024,
'VCPU': 2,
'DISK_GB': 101,
}
self.assertEqual(expected, self.client._allocations(inst))
self.assertEqual(expected, result)
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'put')
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'get')
def test_update_instance_allocation_new(self, mock_get, mock_put):
@mock.patch('nova.scheduler.client.report.'
'_instance_to_allocations_dict')
def test_update_instance_allocation_new(self, mock_a, mock_get,
mock_put):
cn = objects.ComputeNode(uuid=uuids.cn)
inst = objects.Instance(uuid=uuids.inst)
mock_get.return_value.json.return_value = {'allocations': {}}
with mock.patch.object(self.client, '_allocations') as mock_a:
expected = {
'allocations': [
{'resource_provider': {'uuid': cn.uuid},
'resources': mock_a.return_value}]
}
self.client.update_instance_allocation(cn, inst, 1)
mock_put.assert_called_once_with(
'/allocations/%s' % inst.uuid,
expected)
self.assertTrue(mock_get.called)
expected = {
'allocations': [
{'resource_provider': {'uuid': cn.uuid},
'resources': mock_a.return_value}]
}
self.client.update_instance_allocation(cn, inst, 1)
mock_put.assert_called_once_with(
'/allocations/%s' % inst.uuid,
expected)
self.assertTrue(mock_get.called)
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'put')
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'get')
def test_update_instance_allocation_existing(self, mock_get, mock_put):
@mock.patch('nova.scheduler.client.report.'
'_instance_to_allocations_dict')
def test_update_instance_allocation_existing(self, mock_a, mock_get,
mock_put):
cn = objects.ComputeNode(uuid=uuids.cn)
inst = objects.Instance(uuid=uuids.inst)
mock_get.return_value.json.return_value = {'allocations': {
@ -745,33 +752,33 @@ class TestAllocations(SchedulerReportClientTestCase):
}
}}
}
with mock.patch.object(self.client, '_allocations') as mock_a:
mock_a.return_value = {
'DISK_GB': 123,
'MEMORY_MB': 456,
}
self.client.update_instance_allocation(cn, inst, 1)
self.assertFalse(mock_put.called)
mock_get.assert_called_once_with(
'/allocations/%s' % inst.uuid)
mock_a.return_value = {
'DISK_GB': 123,
'MEMORY_MB': 456,
}
self.client.update_instance_allocation(cn, inst, 1)
self.assertFalse(mock_put.called)
mock_get.assert_called_once_with(
'/allocations/%s' % inst.uuid)
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'get')
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'put')
@mock.patch('nova.scheduler.client.report.'
'_instance_to_allocations_dict')
@mock.patch.object(report.LOG, 'warning')
def test_update_instance_allocation_new_failed(self, mock_warn, mock_put,
mock_get):
def test_update_instance_allocation_new_failed(self, mock_warn, mock_a,
mock_put, mock_get):
cn = objects.ComputeNode(uuid=uuids.cn)
inst = objects.Instance(uuid=uuids.inst)
with mock.patch.object(self.client, '_allocations'):
try:
mock_put.return_value.__nonzero__.return_value = False
except AttributeError:
# NOTE(danms): LOL @ py3
mock_put.return_value.__bool__.return_value = False
self.client.update_instance_allocation(cn, inst, 1)
self.assertTrue(mock_warn.called)
try:
mock_put.return_value.__nonzero__.return_value = False
except AttributeError:
# NOTE(danms): LOL @ py3
mock_put.return_value.__bool__.return_value = False
self.client.update_instance_allocation(cn, inst, 1)
self.assertTrue(mock_warn.called)
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'delete')
@ -801,8 +808,10 @@ class TestAllocations(SchedulerReportClientTestCase):
'delete')
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'get')
def test_remove_deleted_instances(
self, mock_get, mock_delete):
@mock.patch('nova.scheduler.client.report.'
'_instance_to_allocations_dict')
def test_remove_deleted_instances(self, mock_a, mock_get,
mock_delete):
cn = objects.ComputeNode(uuid=uuids.cn)
inst1 = objects.Instance(uuid=uuids.inst1)
inst2 = objects.Instance(uuid=uuids.inst2)
@ -822,11 +831,10 @@ class TestAllocations(SchedulerReportClientTestCase):
inst3 = {'uuid': 'foo'}
mock_delete.return_value = True
with mock.patch.object(self.client, '_allocations'):
self.client.remove_deleted_instances(cn, [inst3])
mock_get.assert_called_once_with(
'/resource_providers/%s/allocations' % cn.uuid)
expected_calls = [
mock.call('/allocations/%s' % inst1.uuid),
mock.call('/allocations/%s' % inst2.uuid)]
mock_delete.assert_has_calls(expected_calls, any_order=True)
self.client.remove_deleted_instances(cn, [inst3])
mock_get.assert_called_once_with(
'/resource_providers/%s/allocations' % cn.uuid)
expected_calls = [
mock.call('/allocations/%s' % inst1.uuid),
mock.call('/allocations/%s' % inst2.uuid)]
mock_delete.assert_has_calls(expected_calls, any_order=True)