From 0ed15fd0a44520470323b3e1a4925dbe76650530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20J=C3=B3zefczyk?= Date: Thu, 16 Nov 2017 14:49:42 +0100 Subject: Update resources once in update_available_resource This change ensures that resources are updated only once per update_available_resource() call. Compute resources were previously updated during host object initialization and at the end of update_available_resource(). It could cause inconsistencies in resource tracking between compute host and DB for couple of second when final _update() at the end of update_available_resource() is being called. For example: nova-api shows that host uses 10GB of RAM, but in fact its 12GB because DB doesn't have resources that belongs to shutdown instance. Because of that fact nova-scheduler (CachingScheduler) could choose (based on imcomplete information) host which is already full. For more informations please see realted bug: #1729621 Conflicts: nova/tests/unit/compute/test_resource_tracker.py NOTE: The conflict is due to the backporting order of this patch and I9fa1d509a3de405d6246fb8670612c65c10cc93b to pike has changed. This caused the conflict in first place, and also modification needed in test_compute_node_create_fail_retry_works(), which is now exactly the same as it was originally implemented in queens by the patch mentioned above. Change-Id: I120a98cc4c11772f24099081ef3ac44a50daf71d Closes-Bug: #1729621 (cherry picked from commit c9b74bcfa09d11c2046ce1bfb6dd8463b3a2f3b0) (cherry picked from commit 36d93675d9a6bf903ed64c216243c74a639a2087) --- nova/compute/resource_tracker.py | 3 --- nova/tests/unit/compute/test_resource_tracker.py | 23 +++++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py index 4ffafd3a34..adf26260c3 100644 --- a/nova/compute/resource_tracker.py +++ b/nova/compute/resource_tracker.py @@ -583,7 +583,6 @@ class ResourceTracker(object): cn = self.compute_nodes[nodename] self._copy_resources(cn, resources) self._setup_pci_tracker(context, cn, resources) - self._update(context, cn) return # now try to get the compute node record from the @@ -593,7 +592,6 @@ class ResourceTracker(object): self.compute_nodes[nodename] = cn self._copy_resources(cn, resources) self._setup_pci_tracker(context, cn, resources) - self._update(context, cn) return if self._check_for_nodes_rebalance(context, resources, nodename): @@ -616,7 +614,6 @@ class ResourceTracker(object): {'host': self.host, 'node': nodename, 'uuid': cn.uuid}) self._setup_pci_tracker(context, cn, resources) - self._update(context, cn) def _setup_pci_tracker(self, context, compute_node, resources): if not self.pci_tracker: diff --git a/nova/tests/unit/compute/test_resource_tracker.py b/nova/tests/unit/compute/test_resource_tracker.py index 4d440f17ca..9e9534b9cd 100644 --- a/nova/tests/unit/compute/test_resource_tracker.py +++ b/nova/tests/unit/compute/test_resource_tracker.py @@ -568,6 +568,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() @mock.patch('nova.objects.InstancePCIRequests.get_by_instance', return_value=objects.InstancePCIRequests(requests=[])) @@ -608,6 +609,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() @mock.patch('nova.objects.InstancePCIRequests.get_by_instance', return_value=objects.InstancePCIRequests(requests=[])) @@ -655,6 +657,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() @mock.patch('nova.objects.InstancePCIRequests.get_by_instance', return_value=objects.InstancePCIRequests(requests=[])) @@ -718,6 +721,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() @mock.patch('nova.objects.InstancePCIRequests.get_by_instance', return_value=objects.InstancePCIRequests(requests=[])) @@ -780,6 +784,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() @mock.patch('nova.objects.InstancePCIRequests.get_by_instance', return_value=objects.InstancePCIRequests(requests=[])) @@ -839,6 +844,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() @mock.patch('nova.objects.InstancePCIRequests.get_by_instance', return_value=objects.InstancePCIRequests(requests=[])) @@ -894,6 +900,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() @mock.patch('nova.objects.InstancePCIRequests.get_by_instance', return_value=objects.InstancePCIRequests(requests=[])) @@ -962,6 +969,7 @@ class TestUpdateAvailableResources(BaseTestCase): actual_resources = update_mock.call_args[0][1] self.assertTrue(obj_base.obj_equal_prims(expected_resources, actual_resources)) + update_mock.assert_called_once() class TestInitComputeNode(BaseTestCase): @@ -987,7 +995,7 @@ class TestInitComputeNode(BaseTestCase): self.assertFalse(get_mock.called) self.assertFalse(create_mock.called) self.assertTrue(pci_mock.called) - self.assertTrue(update_mock.called) + self.assertFalse(update_mock.called) @mock.patch('nova.objects.PciDeviceList.get_by_compute_node', return_value=objects.PciDeviceList()) @@ -1011,7 +1019,7 @@ class TestInitComputeNode(BaseTestCase): get_mock.assert_called_once_with(mock.sentinel.ctx, _HOSTNAME, _NODENAME) self.assertFalse(create_mock.called) - self.assertTrue(update_mock.called) + self.assertFalse(update_mock.called) @mock.patch('nova.objects.ComputeNodeList.get_by_hypervisor') @mock.patch('nova.objects.PciDeviceList.get_by_compute_node', @@ -1165,7 +1173,7 @@ class TestInitComputeNode(BaseTestCase): create_mock.assert_called_once_with() self.assertTrue(obj_base.obj_equal_prims(expected_compute, cn)) setup_pci.assert_called_once_with(mock.sentinel.ctx, cn, resources) - self.assertTrue(update_mock.called) + self.assertFalse(update_mock.called) @mock.patch('nova.compute.resource_tracker.ResourceTracker.' '_setup_pci_tracker') @@ -1195,11 +1203,8 @@ class TestInitComputeNode(BaseTestCase): _cn.uuid = uuids.cn_uuid return original_copy_resources(_cn, _resources) - with test.nested( - mock.patch.object(self.rt, '_copy_resources', - fake_copy_resources), - mock.patch.object(self.rt, '_update') - ) as (mock_copy_resources, mock_update): + with mock.patch.object(self.rt, '_copy_resources', + fake_copy_resources): self.rt._init_compute_node(ctxt, resources) self.assertIn(_NODENAME, self.rt.compute_nodes) mock_get.assert_has_calls([mock.call( @@ -1207,8 +1212,6 @@ class TestInitComputeNode(BaseTestCase): self.assertEqual(2, mock_create.call_count) mock_setup_pci.assert_called_once_with( ctxt, test.MatchType(objects.ComputeNode), resources) - mock_update.assert_called_once_with( - ctxt, self.rt.compute_nodes[_NODENAME]) @mock.patch('nova.objects.ComputeNodeList.get_by_hypervisor') @mock.patch('nova.objects.ComputeNode.create') -- cgit v1.2.1