Add functional recreate test for bug 1799727

This adds a functional test which recreates the
bug where config-driven reserved and allocation ratio
overrides are not being reflected in resource provider
inventory once initially set.

The reserved and allocation_ratio values set in the
FakeDriver.update_provider_tree method, added in change
I69d760aaf931d46f011cfd229b88f400837662e8, are removed
here otherwise they hard-code the values which get sent
to placement and ResourceTracker._normalize_inventory_from_cn_obj
won't update the reserved / ratios based on config. The
fake virt driver shouldn't really need to hard-code these
values since the RT will provide those based on config.

Conflicts:
      nova/virt/fake.py

NTOE(mriedem): The conflict is due to not having change
I69d760aaf931d46f011cfd229b88f400837662e8 in Rocky. Rather
than backport that change, this backport simply adds the
update_provider_tree method to the fake virt driver. The
other noticeable difference is the "allocations" kwarg is
ommitted since that was added in Stein with change
Ic062446e5c620c89aec3065b34bcdc6bf5966275.

Change-Id: Ie66d6f4c83a7d6fc64a64dbd752e427cee1356d0
Related-Bug: #1799727
(cherry picked from commit 45f36cebab)
This commit is contained in:
Matt Riedemann 2018-10-24 13:08:33 -04:00
parent ec0b1a491d
commit 57ca9288ce
2 changed files with 127 additions and 0 deletions

View File

@ -15,12 +15,14 @@ import mock
from nova.compute import power_state
from nova.compute import resource_tracker
from nova.compute import task_states
from nova.compute import utils as compute_utils
from nova.compute import vm_states
from nova import conf
from nova import context
from nova import objects
from nova import rc_fields as fields
from nova.tests import fixtures as nova_fixtures
from nova.tests.functional import integrated_helpers
from nova.tests.functional import test_report_client as test_base
from nova.tests import uuidsentinel as uuids
from nova.virt import driver as virt_driver
@ -477,3 +479,105 @@ class IronicResourceTrackerTest(test_base.SchedulerReportClientTestBase):
inst = self.instances[uuids.instance1]
with self.rt.instance_claim(self.ctx, inst, cn1_nodename):
_assert_stats()
class TestUpdateComputeNodeReservedAndAllocationRatio(
integrated_helpers.ProviderUsageBaseTestCase):
"""Tests reflecting reserved and allocation ratio inventory from
nova-compute to placement
"""
compute_driver = 'fake.FakeDriver'
@staticmethod
def _get_reserved_host_values_from_config():
return {
'VCPU': CONF.reserved_host_cpus,
'MEMORY_MB': CONF.reserved_host_memory_mb,
'DISK_GB': compute_utils.convert_mb_to_ceil_gb(
CONF.reserved_host_disk_mb)
}
def test_update_inventory_reserved_and_allocation_ratio_from_conf(self):
# Start a compute service which should create a corresponding resource
# provider in the placement service.
compute_service = self._start_compute('fake-host')
# Assert the compute node resource provider exists in placement with
# the default reserved and allocation ratio values from config.
rp_uuid = self._get_provider_uuid_by_host('fake-host')
inventories = self._get_provider_inventory(rp_uuid)
# The default allocation ratio config values are all 0.0 and get
# defaulted to real values in the ComputeNode object, so we need to
# check our defaults against what is in the ComputeNode object.
ctxt = context.get_admin_context()
# Note that the CellDatabases fixture usage means we don't need to
# target the context to cell1 even though the compute_nodes table is
# in the cell1 database.
cn = objects.ComputeNode.get_by_uuid(ctxt, rp_uuid)
ratios = {
'VCPU': cn.cpu_allocation_ratio,
'MEMORY_MB': cn.ram_allocation_ratio,
'DISK_GB': cn.disk_allocation_ratio
}
for rc, ratio in ratios.items():
self.assertIn(rc, inventories)
self.assertIn('allocation_ratio', inventories[rc])
self.assertEqual(ratio, inventories[rc]['allocation_ratio'],
'Unexpected allocation ratio for %s' % rc)
reserved = self._get_reserved_host_values_from_config()
for rc, res in reserved.items():
self.assertIn('reserved', inventories[rc])
self.assertEqual(res, inventories[rc]['reserved'],
'Unexpected reserved value for %s' % rc)
# Now change the configuration values, restart the compute service,
# and ensure the changes are reflected in the resource provider
# inventory records. We use 2.0 since disk_allocation_ratio defaults
# to 1.0.
self.flags(cpu_allocation_ratio=2.0)
self.flags(ram_allocation_ratio=2.0)
self.flags(disk_allocation_ratio=2.0)
self.flags(reserved_host_cpus=2)
self.flags(reserved_host_memory_mb=1024)
self.flags(reserved_host_disk_mb=8192)
self.restart_compute_service(compute_service)
# The ratios should now come from config overrides rather than the
# defaults in the ComputeNode object.
ratios = {
'VCPU': CONF.cpu_allocation_ratio,
'MEMORY_MB': CONF.ram_allocation_ratio,
'DISK_GB': CONF.disk_allocation_ratio
}
attr_map = {
'VCPU': 'cpu',
'MEMORY_MB': 'ram',
'DISK_GB': 'disk',
}
cn = objects.ComputeNode.get_by_uuid(ctxt, rp_uuid)
inventories = self._get_provider_inventory(rp_uuid)
for rc, ratio in ratios.items():
# Make sure the config is what we expect.
self.assertEqual(2.0, ratio,
'Unexpected config allocation ratio for %s' % rc)
# Make sure the values in the DB are updated.
self.assertEqual(
ratio, getattr(cn, '%s_allocation_ratio' % attr_map[rc]),
'Unexpected ComputeNode allocation ratio for %s' % rc)
# Make sure the values in placement are updated.
# FIXME(mriedem): The config-driven allocation ratio overrides
# are not reflected in placement until bug 1799727 is fixed.
self.assertNotEqual(ratio, inventories[rc]['allocation_ratio'],
'Unexpected resource provider inventory '
'allocation ratio for %s' % rc)
# The reserved host values should also come from config.
reserved = self._get_reserved_host_values_from_config()
for rc, res in reserved.items():
self.assertIn('reserved', inventories[rc])
# FIXME(mriedem): The config-driven reserved overrides
# are not reflected in placement until bug 1799727 is fixed.
self.assertNotEqual(res, inventories[rc]['reserved'],
'Unexpected resource provider inventory '
'reserved value for %s' % rc)

View File

@ -490,6 +490,29 @@ class FakeDriver(driver.ComputeDriver):
host_status['cpu_info'] = jsonutils.dumps(cpu_info)
return host_status
def update_provider_tree(self, provider_tree, nodename):
inventory = {
'VCPU': {
'total': self.vcpus,
'min_unit': 1,
'max_unit': self.vcpus,
'step_size': 1,
},
'MEMORY_MB': {
'total': self.memory_mb,
'min_unit': 1,
'max_unit': self.memory_mb,
'step_size': 1,
},
'DISK_GB': {
'total': self.local_gb,
'min_unit': 1,
'max_unit': self.local_gb,
'step_size': 1,
},
}
provider_tree.update_inventory(nodename, inventory)
def ensure_filtering_rules_for_instance(self, instance, network_info):
return