From 02cea6a46ff0dc0bd71312b6cbc1af683208843d Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 14 Jun 2018 10:44:01 +0100 Subject: [PATCH] objects: Add NUMATopologyLimits.network_metadata We need some way to pass the metadata about requested networks back from nova-scheduler to nova-compute for using during claiming. This satisfies that requirement. Part of blueprint numa-aware-vswitches Change-Id: I3f62b2770dc2df70636f3cefa9144fde3c97ce42 --- nova/objects/numa.py | 13 +++++-- nova/tests/unit/objects/test_numa.py | 17 +++++++++ nova/tests/unit/objects/test_objects.py | 2 +- nova/tests/unit/objects/test_selection.py | 42 +++++++++++++---------- 4 files changed, 53 insertions(+), 21 deletions(-) diff --git a/nova/objects/numa.py b/nova/objects/numa.py index be8613ea6221..e3400796cb14 100644 --- a/nova/objects/numa.py +++ b/nova/objects/numa.py @@ -254,9 +254,18 @@ class NUMATopology(base.NovaObject): @base.NovaObjectRegistry.register class NUMATopologyLimits(base.NovaObject): # Version 1.0: Initial version - VERSION = '1.0' + # Version 1.1: Add network_metadata field + VERSION = '1.1' fields = { 'cpu_allocation_ratio': fields.FloatField(), 'ram_allocation_ratio': fields.FloatField(), - } + 'network_metadata': fields.ObjectField('NetworkMetadata'), + } + + def obj_make_compatible(self, primitive, target_version): + super(NUMATopologyLimits, self).obj_make_compatible(primitive, + target_version) + target_version = versionutils.convert_version_to_tuple(target_version) + if target_version < (1, 1): + primitive.pop('network_metadata', None) diff --git a/nova/tests/unit/objects/test_numa.py b/nova/tests/unit/objects/test_numa.py index 06b4c6aa1f4f..935496f23c28 100644 --- a/nova/tests/unit/objects/test_numa.py +++ b/nova/tests/unit/objects/test_numa.py @@ -271,6 +271,23 @@ class _TestNUMA(object): size_kb=1024, total=64, used=32) self.assertEqual(32, p.free) + def test_numa_topology_limits_obj_make_compatible(self): + network_meta = objects.NetworkMetadata( + physnets=set(['foo', 'bar']), tunneled=True) + limits = objects.NUMATopologyLimits( + cpu_allocation_ratio=1.0, + ram_allocation_ratio=1.0, + network_metadata=network_meta) + + versions = ovo_base.obj_tree_get_versions('NUMATopologyLimits') + primitive = limits.obj_to_primitive(target_version='1.1', + version_manifest=versions) + self.assertIn('network_metadata', primitive['nova_object.data']) + + primitive = limits.obj_to_primitive(target_version='1.0', + version_manifest=versions) + self.assertNotIn('network_metadata', primitive['nova_object.data']) + class TestNUMA(test_objects._LocalTest, _TestNUMA): diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py index 3703d4fc7ee1..a58ab042c7e9 100644 --- a/nova/tests/unit/objects/test_objects.py +++ b/nova/tests/unit/objects/test_objects.py @@ -1127,7 +1127,7 @@ object_data = { 'NUMACell': '1.3-64b5fec7c51c0a85760c56b42dd307a5', 'NUMAPagesTopology': '1.1-edab9fa2dc43c117a38d600be54b4542', 'NUMATopology': '1.2-c63fad38be73b6afd04715c9c1b29220', - 'NUMATopologyLimits': '1.0-9463e0edd40f64765ae518a539b9dfd2', + 'NUMATopologyLimits': '1.1-4235c5da7a76c7e36075f0cd2f5cf922', 'Network': '1.2-a977ab383aa462a479b2fae8211a5dde', 'NetworkInterfaceMetadata': '1.2-6f3d480b40fe339067b1c0dd4d656716', 'NetworkList': '1.2-69eca910d8fa035dfecd8ba10877ee59', diff --git a/nova/tests/unit/objects/test_selection.py b/nova/tests/unit/objects/test_selection.py index c774c95d97e2..afef9c1a6778 100644 --- a/nova/tests/unit/objects/test_selection.py +++ b/nova/tests/unit/objects/test_selection.py @@ -91,8 +91,11 @@ class _TestSelectionObject(object): """Tests that to_dict() method properly converts a Selection object to the corresponding dict. """ + fake_network_metadata = objects.NetworkMetadata( + physnets=set(['foo', 'bar']), tunneled=True) fake_numa_limit = objects.numa.NUMATopologyLimits( - cpu_allocation_ratio=1.0, ram_allocation_ratio=1.0) + cpu_allocation_ratio=1.0, ram_allocation_ratio=1.0, + network_metadata=fake_network_metadata) fake_limit = {"memory_mb": 1024, "disk_gb": 100, "vcpus": 2, "numa_topology": fake_numa_limit} fake_limit_obj = objects.SchedulerLimits.from_dict(fake_limit) @@ -100,24 +103,27 @@ class _TestSelectionObject(object): nodename="fakenode", compute_node_uuid=uuids.host, cell_uuid=uuids.cell, limits=fake_limit_obj, allocation_request="fake", allocation_request_version="99.9") - expected = { - 'host': 'fakehost', - 'nodename': 'fakenode', - 'limits': { - 'disk_gb': 100, - 'memory_mb': 1024, - 'numa_topology': { - 'nova_object.changes': [ - 'cpu_allocation_ratio', - 'ram_allocation_ratio'], - 'nova_object.data': { - 'cpu_allocation_ratio': 1.0, - 'ram_allocation_ratio': 1.0}, - 'nova_object.name': 'NUMATopologyLimits', - 'nova_object.namespace': 'nova', - 'nova_object.version': '1.0'}}} + result = sel_obj.to_dict() - self.assertDictEqual(expected, result) + + self.assertEqual(['host', 'limits', 'nodename'], sorted(result.keys())) + self.assertEqual('fakehost', result['host']) + self.assertEqual('fakenode', result['nodename']) + + limits = result['limits'] + self.assertEqual(['disk_gb', 'memory_mb', 'numa_topology'], + sorted(limits.keys())) + self.assertEqual(100, limits['disk_gb']) + self.assertEqual(1024, limits['memory_mb']) + + numa_topology = limits['numa_topology']['nova_object.data'] + self.assertEqual(1.0, numa_topology['cpu_allocation_ratio']) + self.assertEqual(1.0, numa_topology['ram_allocation_ratio']) + + network_meta = numa_topology['network_metadata']['nova_object.data'] + # sets are unordered so we need to convert to a list + self.assertEqual(['bar', 'foo'], sorted(network_meta['physnets'])) + self.assertTrue(network_meta['tunneled']) def test_selection_obj_to_dict_no_numa(self): """Tests that to_dict() method properly converts a