nova/nova/tests/unit/objects/test_selection.py

199 lines
8.8 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_serialization import jsonutils
from oslo_utils.fixture import uuidsentinel as uuids
from nova import conf
from nova import objects
from nova.objects import numa
from nova.scheduler import host_manager
from nova.tests.unit.objects import test_objects
CONF = conf.CONF
fake_numa_limit1 = numa.NUMATopologyLimits(cpu_allocation_ratio=1.0,
ram_allocation_ratio=1.0)
fake_limit1 = {"memory_mb": 1024, "disk_gb": 100, "vcpus": 2,
"numa_topology": fake_numa_limit1}
fake_limit_obj1 = objects.SchedulerLimits.from_dict(fake_limit1)
fake_host1 = {
"uuid": uuids.host1,
"host": "host1",
"nodename": "node1",
"cell_uuid": uuids.cell,
"limits": fake_limit1,
}
fake_host_state1 = host_manager.HostState("host1", "node1", uuids.cell)
fake_host_state1.uuid = uuids.host1
fake_host_state1.limits = fake_limit1.copy()
fake_alloc1 = {"allocations": [
{"resource_provider": {"uuid": uuids.host1},
"resources": {"VCPU": 1,
"MEMORY_MB": 1024,
"DISK_GB": 100}
}]}
fake_alloc_version = "1.23"
class _TestSelectionObject(object):
def test_create_with_values(self):
json_alloc = jsonutils.dumps(fake_alloc1)
dest = objects.Selection(service_host="host", nodename="node",
compute_node_uuid=uuids.host1, cell_uuid=uuids.cell,
limits=fake_limit_obj1, allocation_request=json_alloc,
allocation_request_version=fake_alloc_version)
self.assertEqual("host", dest.service_host)
self.assertEqual(uuids.host1, dest.compute_node_uuid)
self.assertEqual("node", dest.nodename)
self.assertEqual(uuids.cell, dest.cell_uuid)
self.assertEqual(fake_limit_obj1, dest.limits)
self.assertEqual(json_alloc, dest.allocation_request)
self.assertEqual(fake_alloc_version, dest.allocation_request_version)
def test_passing_dict_allocation_fails(self):
self.assertRaises(ValueError, objects.Selection, service_host="host",
compute_node_uuid=uuids.host, nodename="node",
cell_uuid=uuids.cell, allocation_request=fake_alloc1,
allocation_request_version=fake_alloc_version)
def test_passing_numeric_allocation_version_converts(self):
json_alloc = jsonutils.dumps(fake_alloc1)
dest = objects.Selection(service_host="host",
compute_node_uuid=uuids.host, nodename="node",
cell_uuid=uuids.cell, allocation_request=json_alloc,
allocation_request_version=1.23)
self.assertEqual("1.23", dest.allocation_request_version)
def test_from_host_state(self):
dest = objects.Selection.from_host_state(fake_host_state1, fake_alloc1,
fake_alloc_version)
self.assertEqual(dest.service_host, fake_host_state1.host)
expected_alloc = jsonutils.dumps(fake_alloc1)
self.assertEqual(dest.allocation_request, expected_alloc)
self.assertEqual(dest.allocation_request_version, fake_alloc_version)
def test_from_host_state_no_alloc_info(self):
dest = objects.Selection.from_host_state(fake_host_state1)
self.assertEqual(dest.service_host, fake_host_state1.host)
expected_alloc = jsonutils.dumps(None)
self.assertEqual(expected_alloc, dest.allocation_request)
self.assertIsNone(dest.allocation_request_version)
def test_selection_obj_to_dict(self):
"""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,
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)
sel_obj = objects.Selection(service_host="fakehost",
nodename="fakenode", compute_node_uuid=uuids.host,
cell_uuid=uuids.cell, limits=fake_limit_obj,
allocation_request="fake", allocation_request_version="99.9")
result = sel_obj.to_dict()
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
Selection object to the corresponding dict when the numa_topology field
is None.
"""
fake_limit = {"memory_mb": 1024, "disk_gb": 100, "vcpus": 2,
"numa_topology": None}
fake_limit_obj = objects.SchedulerLimits.from_dict(fake_limit)
sel_obj = objects.Selection(service_host="fakehost",
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}}
result = sel_obj.to_dict()
self.assertDictEqual(expected, result)
class TestSelectionObject(test_objects._LocalTest,
_TestSelectionObject):
# NOTE(mriedem): The tests below are for methods which are not remotable
# so they can go in the local-only test class rather than the mixin above.
def test_obj_make_compatible(self):
selection = objects.Selection(service_host='host1',
availability_zone='zone1')
primitive = selection.obj_to_primitive(
target_version='1.1')['nova_object.data']
self.assertIn('availability_zone', primitive)
primitive = selection.obj_to_primitive(
target_version='1.0')['nova_object.data']
self.assertNotIn('availability_zone', primitive)
self.assertIn('service_host', primitive)
def test_from_host_state_az_via_aggregate_metadata(self):
"""Tests the scenario that the host is in multiple aggregates and
one has the availability_zone aggregate metadata key which is used
on the selection object.
"""
host_state = host_manager.HostState('host', 'node', uuids.cell_uuid)
host_state.uuid = uuids.compute_node_uuid
host_state.limits = {}
host_state.aggregates = [
objects.Aggregate(metadata={'foo': 'bar'}),
objects.Aggregate(metadata={'availability_zone': 'zone1'})
]
selection = objects.Selection.from_host_state(host_state)
self.assertEqual('zone1', selection.availability_zone)
def test_from_host_state_az_via_config(self):
"""Tests the scenario that the host is not in an aggregate with the
availability_zone metadata key so the AZ comes from config.
"""
host_state = host_manager.HostState('host', 'node', uuids.cell_uuid)
host_state.uuid = uuids.compute_node_uuid
host_state.limits = {}
host_state.aggregates = []
selection = objects.Selection.from_host_state(host_state)
self.assertEqual(CONF.default_availability_zone,
selection.availability_zone)
class TestRemoteSelectionObject(test_objects._RemoteTest,
_TestSelectionObject):
pass