631 lines
28 KiB
Python
631 lines
28 KiB
Python
# Copyright 2013 IBM Corp.
|
|
#
|
|
# 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.
|
|
|
|
import copy
|
|
|
|
import mock
|
|
import netaddr
|
|
from oslo_serialization import jsonutils
|
|
from oslo_utils.fixture import uuidsentinel
|
|
from oslo_utils import timeutils
|
|
from oslo_versionedobjects import base as ovo_base
|
|
from oslo_versionedobjects import exception as ovo_exc
|
|
|
|
from nova.db import api as db
|
|
from nova import exception
|
|
from nova import objects
|
|
from nova.objects import base
|
|
from nova.objects import compute_node
|
|
from nova.objects import hv_spec
|
|
from nova.objects import service
|
|
from nova.tests.unit import fake_pci_device_pools
|
|
from nova.tests.unit.objects import test_objects
|
|
|
|
|
|
NOW = timeutils.utcnow().replace(microsecond=0)
|
|
fake_stats = {'num_foo': '10'}
|
|
fake_stats_db_format = jsonutils.dumps(fake_stats)
|
|
# host_ip is coerced from a string to an IPAddress
|
|
# but needs to be converted to a string for the database format
|
|
fake_host_ip = '127.0.0.1'
|
|
fake_numa_topology = objects.NUMATopology(
|
|
cells=[objects.NUMACell(id=0, cpuset=set([1, 2]), memory=512,
|
|
cpu_usage=0, memory_usage=0,
|
|
mempages=[], pinned_cpus=set([]),
|
|
siblings=[set([1]), set([2])]),
|
|
objects.NUMACell(id=1, cpuset=set([3, 4]), memory=512,
|
|
cpu_usage=0, memory_usage=0,
|
|
mempages=[], pinned_cpus=set([]),
|
|
siblings=[set([3]), set([4])])])
|
|
fake_numa_topology_db_format = fake_numa_topology._to_json()
|
|
fake_supported_instances = [('x86_64', 'kvm', 'hvm')]
|
|
fake_hv_spec = hv_spec.HVSpec(arch=fake_supported_instances[0][0],
|
|
hv_type=fake_supported_instances[0][1],
|
|
vm_mode=fake_supported_instances[0][2])
|
|
fake_supported_hv_specs = [fake_hv_spec]
|
|
# for backward compatibility, each supported instance object
|
|
# is stored as a list in the database
|
|
fake_supported_hv_specs_db_format = jsonutils.dumps([fake_hv_spec.to_list()])
|
|
fake_pci = jsonutils.dumps(fake_pci_device_pools.fake_pool_list_primitive)
|
|
fake_compute_node = {
|
|
'created_at': NOW,
|
|
'updated_at': None,
|
|
'deleted_at': None,
|
|
'deleted': False,
|
|
'id': 123,
|
|
'uuid': uuidsentinel.fake_compute_node,
|
|
'service_id': None,
|
|
'host': 'fake',
|
|
'vcpus': 4,
|
|
'memory_mb': 4096,
|
|
'local_gb': 1024,
|
|
'vcpus_used': 2,
|
|
'memory_mb_used': 2048,
|
|
'local_gb_used': 512,
|
|
'hypervisor_type': 'Hyper-Dan-VM-ware',
|
|
'hypervisor_version': 1001,
|
|
'hypervisor_hostname': 'vm.danplanet.com',
|
|
'free_ram_mb': 1024,
|
|
'free_disk_gb': 256,
|
|
'current_workload': 100,
|
|
'running_vms': 2013,
|
|
'cpu_info': 'Schmintel i786',
|
|
'disk_available_least': 256,
|
|
'metrics': '',
|
|
'stats': fake_stats_db_format,
|
|
'host_ip': fake_host_ip,
|
|
'numa_topology': fake_numa_topology_db_format,
|
|
'supported_instances': fake_supported_hv_specs_db_format,
|
|
'pci_stats': fake_pci,
|
|
'cpu_allocation_ratio': 16.0,
|
|
'ram_allocation_ratio': 1.5,
|
|
'disk_allocation_ratio': 1.0,
|
|
'mapped': 0,
|
|
}
|
|
# FIXME(sbauza) : For compatibility checking, to be removed once we are sure
|
|
# that all computes are running latest DB version with host field in it.
|
|
fake_old_compute_node = fake_compute_node.copy()
|
|
del fake_old_compute_node['host']
|
|
# resources are passed from the virt drivers and copied into the compute_node
|
|
fake_resources = {
|
|
'vcpus': 2,
|
|
'memory_mb': 1024,
|
|
'local_gb': 10,
|
|
'cpu_info': 'fake-info',
|
|
'vcpus_used': 1,
|
|
'memory_mb_used': 512,
|
|
'local_gb_used': 4,
|
|
'numa_topology': fake_numa_topology_db_format,
|
|
'hypervisor_type': 'fake-type',
|
|
'hypervisor_version': 1,
|
|
'hypervisor_hostname': 'fake-host',
|
|
'disk_available_least': 256,
|
|
'host_ip': fake_host_ip,
|
|
'supported_instances': fake_supported_instances
|
|
}
|
|
fake_compute_with_resources = objects.ComputeNode(
|
|
vcpus=fake_resources['vcpus'],
|
|
memory_mb=fake_resources['memory_mb'],
|
|
local_gb=fake_resources['local_gb'],
|
|
cpu_info=fake_resources['cpu_info'],
|
|
vcpus_used=fake_resources['vcpus_used'],
|
|
memory_mb_used=fake_resources['memory_mb_used'],
|
|
local_gb_used =fake_resources['local_gb_used'],
|
|
numa_topology=fake_resources['numa_topology'],
|
|
hypervisor_type=fake_resources['hypervisor_type'],
|
|
hypervisor_version=fake_resources['hypervisor_version'],
|
|
hypervisor_hostname=fake_resources['hypervisor_hostname'],
|
|
disk_available_least=fake_resources['disk_available_least'],
|
|
host_ip=netaddr.IPAddress(fake_resources['host_ip']),
|
|
supported_hv_specs=fake_supported_hv_specs,
|
|
)
|
|
|
|
|
|
class _TestComputeNodeObject(object):
|
|
def supported_hv_specs_comparator(self, expected, obj_val):
|
|
obj_val = [inst.to_list() for inst in obj_val]
|
|
self.assertJsonEqual(expected, obj_val)
|
|
|
|
def pci_device_pools_comparator(self, expected, obj_val):
|
|
if obj_val is not None:
|
|
obj_val = obj_val.obj_to_primitive()
|
|
self.assertJsonEqual(expected, obj_val)
|
|
else:
|
|
self.assertEqual(expected, obj_val)
|
|
|
|
def comparators(self):
|
|
return {'stats': self.assertJsonEqual,
|
|
'host_ip': self.str_comparator,
|
|
'supported_hv_specs': self.supported_hv_specs_comparator,
|
|
'pci_device_pools': self.pci_device_pools_comparator,
|
|
}
|
|
|
|
def subs(self):
|
|
return {'supported_hv_specs': 'supported_instances',
|
|
'pci_device_pools': 'pci_stats'}
|
|
|
|
@mock.patch.object(db, 'compute_node_get')
|
|
def test_get_by_id(self, get_mock):
|
|
get_mock.return_value = fake_compute_node
|
|
compute = compute_node.ComputeNode.get_by_id(self.context, 123)
|
|
self.compare_obj(compute, fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
self.assertNotIn('uuid', compute.obj_what_changed())
|
|
get_mock.assert_called_once_with(self.context, 123)
|
|
|
|
@mock.patch.object(compute_node.ComputeNodeList, 'get_all_by_uuids')
|
|
def test_get_by_uuid(self, get_all_by_uuids):
|
|
fake_node = copy.copy(fake_compute_node)
|
|
fake_node['stats'] = None
|
|
get_all_by_uuids.return_value = objects.ComputeNodeList(
|
|
objects=[objects.ComputeNode(**fake_node)])
|
|
compute = compute_node.ComputeNode.get_by_uuid(
|
|
self.context, uuidsentinel.fake_compute_node)
|
|
self.assertEqual(uuidsentinel.fake_compute_node, compute.uuid)
|
|
get_all_by_uuids.assert_called_once_with(
|
|
self.context, [uuidsentinel.fake_compute_node])
|
|
|
|
@mock.patch.object(compute_node.ComputeNodeList, 'get_all_by_uuids')
|
|
def test_get_by_uuid_not_found(self, get_all_by_uuids):
|
|
get_all_by_uuids.return_value = objects.ComputeNodeList()
|
|
self.assertRaises(exception.ComputeHostNotFound,
|
|
compute_node.ComputeNode.get_by_uuid,
|
|
self.context, uuidsentinel.fake_compute_node)
|
|
get_all_by_uuids.assert_called_once_with(
|
|
self.context, [uuidsentinel.fake_compute_node])
|
|
|
|
@mock.patch.object(db, 'compute_node_get')
|
|
def test_get_without_mapped(self, get_mock):
|
|
fake_node = copy.copy(fake_compute_node)
|
|
fake_node['mapped'] = None
|
|
get_mock.return_value = fake_node
|
|
compute = compute_node.ComputeNode.get_by_id(self.context, 123)
|
|
self.compare_obj(compute, fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
self.assertIn('mapped', compute)
|
|
self.assertEqual(0, compute.mapped)
|
|
|
|
@mock.patch.object(objects.Service, 'get_by_id')
|
|
@mock.patch.object(db, 'compute_node_get')
|
|
def test_get_by_id_with_host_field_not_in_db(self, mock_cn_get,
|
|
mock_obj_svc_get):
|
|
fake_compute_node_with_svc_id = fake_compute_node.copy()
|
|
fake_compute_node_with_svc_id['service_id'] = 123
|
|
fake_compute_node_with_no_host = fake_compute_node_with_svc_id.copy()
|
|
host = fake_compute_node_with_no_host.pop('host')
|
|
fake_service = service.Service(id=123)
|
|
fake_service.host = host
|
|
|
|
mock_cn_get.return_value = fake_compute_node_with_no_host
|
|
mock_obj_svc_get.return_value = fake_service
|
|
|
|
compute = compute_node.ComputeNode.get_by_id(self.context, 123)
|
|
self.compare_obj(compute, fake_compute_node_with_svc_id,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
@mock.patch.object(db, 'compute_nodes_get_by_service_id')
|
|
def test_get_by_service_id(self, get_mock):
|
|
get_mock.return_value = [fake_compute_node]
|
|
compute = compute_node.ComputeNode.get_by_service_id(self.context, 456)
|
|
self.compare_obj(compute, fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
get_mock.assert_called_once_with(self.context, 456)
|
|
|
|
@mock.patch.object(db, 'compute_node_get_by_host_and_nodename')
|
|
def test_get_by_host_and_nodename(self, cn_get_by_h_and_n):
|
|
cn_get_by_h_and_n.return_value = fake_compute_node
|
|
|
|
compute = compute_node.ComputeNode.get_by_host_and_nodename(
|
|
self.context, 'fake', 'vm.danplanet.com')
|
|
self.compare_obj(compute, fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
@mock.patch('nova.db.api.compute_node_get_all_by_host')
|
|
def test_get_first_node_by_host_for_old_compat(
|
|
self, cn_get_all_by_host):
|
|
another_node = fake_compute_node.copy()
|
|
another_node['hypervisor_hostname'] = 'neverland'
|
|
cn_get_all_by_host.return_value = [fake_compute_node, another_node]
|
|
|
|
compute = (
|
|
compute_node.ComputeNode.get_first_node_by_host_for_old_compat(
|
|
self.context, 'fake')
|
|
)
|
|
self.compare_obj(compute, fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
@mock.patch('nova.objects.ComputeNodeList.get_all_by_host')
|
|
def test_get_first_node_by_host_for_old_compat_not_found(
|
|
self, cn_get_all_by_host):
|
|
cn_get_all_by_host.side_effect = exception.ComputeHostNotFound(
|
|
host='fake')
|
|
|
|
self.assertRaises(
|
|
exception.ComputeHostNotFound,
|
|
compute_node.ComputeNode.get_first_node_by_host_for_old_compat,
|
|
self.context, 'fake')
|
|
|
|
@mock.patch.object(db, 'compute_node_create')
|
|
@mock.patch('nova.db.api.compute_node_get', return_value=fake_compute_node)
|
|
def test_create(self, mock_get, mock_create):
|
|
mock_create.return_value = fake_compute_node
|
|
compute = compute_node.ComputeNode(context=self.context)
|
|
compute.service_id = 456
|
|
compute.uuid = uuidsentinel.fake_compute_node
|
|
compute.stats = fake_stats
|
|
# NOTE (pmurray): host_ip is coerced to an IPAddress
|
|
compute.host_ip = fake_host_ip
|
|
compute.supported_hv_specs = fake_supported_hv_specs
|
|
with mock.patch('oslo_utils.uuidutils.generate_uuid') as mock_gu:
|
|
compute.create()
|
|
self.assertFalse(mock_gu.called)
|
|
self.compare_obj(compute, fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
param_dict = {
|
|
'service_id': 456,
|
|
'stats': fake_stats_db_format,
|
|
'host_ip': fake_host_ip,
|
|
'supported_instances': fake_supported_hv_specs_db_format,
|
|
'uuid': uuidsentinel.fake_compute_node
|
|
}
|
|
mock_create.assert_called_once_with(self.context, param_dict)
|
|
|
|
@mock.patch('nova.db.api.compute_node_create')
|
|
@mock.patch('oslo_utils.uuidutils.generate_uuid')
|
|
@mock.patch('nova.db.api.compute_node_get', return_value=fake_compute_node)
|
|
def test_create_allocates_uuid(self, mock_get, mock_gu, mock_create):
|
|
mock_create.return_value = fake_compute_node
|
|
mock_gu.return_value = fake_compute_node['uuid']
|
|
obj = objects.ComputeNode(context=self.context)
|
|
obj.create()
|
|
mock_gu.assert_called_once_with()
|
|
mock_create.assert_called_once_with(
|
|
self.context, {'uuid': fake_compute_node['uuid']})
|
|
|
|
@mock.patch('nova.db.api.compute_node_create')
|
|
@mock.patch('nova.db.api.compute_node_get', return_value=fake_compute_node)
|
|
def test_recreate_fails(self, mock_get, mock_create):
|
|
mock_create.return_value = fake_compute_node
|
|
compute = compute_node.ComputeNode(context=self.context)
|
|
compute.service_id = 456
|
|
compute.uuid = uuidsentinel.fake_compute_node
|
|
compute.create()
|
|
self.assertRaises(exception.ObjectActionError, compute.create)
|
|
param_dict = {'service_id': 456,
|
|
'uuid': uuidsentinel.fake_compute_node}
|
|
mock_create.assert_called_once_with(self.context, param_dict)
|
|
|
|
@mock.patch.object(db, 'compute_node_update')
|
|
@mock.patch('nova.db.api.compute_node_get', return_value=fake_compute_node)
|
|
def test_save(self, mock_get, mock_update):
|
|
mock_update.return_value = fake_compute_node
|
|
compute = compute_node.ComputeNode(context=self.context)
|
|
compute.id = 123
|
|
compute.vcpus_used = 3
|
|
compute.stats = fake_stats
|
|
compute.uuid = uuidsentinel.fake_compute_node
|
|
# NOTE (pmurray): host_ip is coerced to an IPAddress
|
|
compute.host_ip = fake_host_ip
|
|
compute.supported_hv_specs = fake_supported_hv_specs
|
|
compute.save()
|
|
self.compare_obj(compute, fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
param_dict = {
|
|
'vcpus_used': 3,
|
|
'stats': fake_stats_db_format,
|
|
'host_ip': fake_host_ip,
|
|
'supported_instances': fake_supported_hv_specs_db_format,
|
|
'uuid': uuidsentinel.fake_compute_node,
|
|
}
|
|
mock_update.assert_called_once_with(self.context, 123, param_dict)
|
|
|
|
@mock.patch('nova.db.api.compute_node_update')
|
|
def test_save_pci_device_pools_empty(self, mock_update):
|
|
fake_pci = jsonutils.dumps(
|
|
objects.PciDevicePoolList(objects=[]).obj_to_primitive())
|
|
compute_dict = fake_compute_node.copy()
|
|
compute_dict['pci_stats'] = fake_pci
|
|
mock_update.return_value = compute_dict
|
|
|
|
compute = compute_node.ComputeNode(context=self.context)
|
|
compute.id = 123
|
|
compute.pci_device_pools = objects.PciDevicePoolList(objects=[])
|
|
compute.save()
|
|
self.compare_obj(compute, compute_dict,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
mock_update.assert_called_once_with(
|
|
self.context, 123, {'pci_stats': fake_pci})
|
|
|
|
@mock.patch('nova.db.api.compute_node_update')
|
|
def test_save_pci_device_pools_null(self, mock_update):
|
|
compute_dict = fake_compute_node.copy()
|
|
compute_dict['pci_stats'] = None
|
|
mock_update.return_value = compute_dict
|
|
|
|
compute = compute_node.ComputeNode(context=self.context)
|
|
compute.id = 123
|
|
compute.pci_device_pools = None
|
|
compute.save()
|
|
self.compare_obj(compute, compute_dict,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
mock_update.assert_called_once_with(
|
|
self.context, 123, {'pci_stats': None})
|
|
|
|
@mock.patch.object(db, 'compute_node_create',
|
|
return_value=fake_compute_node)
|
|
@mock.patch.object(db, 'compute_node_get',
|
|
return_value=fake_compute_node)
|
|
def test_set_id_failure(self, mock_get, db_mock):
|
|
compute = compute_node.ComputeNode(context=self.context,
|
|
uuid=fake_compute_node['uuid'])
|
|
compute.create()
|
|
self.assertRaises(ovo_exc.ReadOnlyFieldError, setattr,
|
|
compute, 'id', 124)
|
|
|
|
@mock.patch.object(db, 'compute_node_delete')
|
|
def test_destroy(self, mock_delete):
|
|
compute = compute_node.ComputeNode(context=self.context)
|
|
compute.id = 123
|
|
compute.destroy()
|
|
mock_delete.assert_called_once_with(self.context, 123)
|
|
|
|
@mock.patch.object(db, 'compute_node_get_all')
|
|
def test_get_all(self, mock_get_all):
|
|
mock_get_all.return_value = [fake_compute_node]
|
|
computes = compute_node.ComputeNodeList.get_all(self.context)
|
|
self.assertEqual(1, len(computes))
|
|
self.compare_obj(computes[0], fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
mock_get_all.assert_called_once_with(self.context)
|
|
|
|
@mock.patch.object(db, 'compute_node_search_by_hypervisor')
|
|
def test_get_by_hypervisor(self, mock_search):
|
|
mock_search.return_value = [fake_compute_node]
|
|
computes = compute_node.ComputeNodeList.get_by_hypervisor(self.context,
|
|
'hyper')
|
|
self.assertEqual(1, len(computes))
|
|
self.compare_obj(computes[0], fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
mock_search.assert_called_once_with(self.context, 'hyper')
|
|
|
|
@mock.patch('nova.db.api.compute_node_get_all_by_pagination',
|
|
return_value=[fake_compute_node])
|
|
def test_get_by_pagination(self, fake_get_by_pagination):
|
|
computes = compute_node.ComputeNodeList.get_by_pagination(
|
|
self.context, limit=1, marker=1)
|
|
self.assertEqual(1, len(computes))
|
|
self.compare_obj(computes[0], fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
@mock.patch('nova.db.api.compute_nodes_get_by_service_id')
|
|
def test__get_by_service(self, cn_get_by_svc_id):
|
|
cn_get_by_svc_id.return_value = [fake_compute_node]
|
|
computes = compute_node.ComputeNodeList._get_by_service(self.context,
|
|
123)
|
|
self.assertEqual(1, len(computes))
|
|
self.compare_obj(computes[0], fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
@mock.patch('nova.db.api.compute_node_get_all_by_host')
|
|
def test_get_all_by_host(self, cn_get_all_by_host):
|
|
cn_get_all_by_host.return_value = [fake_compute_node]
|
|
computes = compute_node.ComputeNodeList.get_all_by_host(self.context,
|
|
'fake')
|
|
self.assertEqual(1, len(computes))
|
|
self.compare_obj(computes[0], fake_compute_node,
|
|
subs=self.subs(),
|
|
comparators=self.comparators())
|
|
|
|
def test_compat_numa_topology(self):
|
|
compute = compute_node.ComputeNode()
|
|
versions = ovo_base.obj_tree_get_versions('ComputeNode')
|
|
primitive = compute.obj_to_primitive(target_version='1.4',
|
|
version_manifest=versions)
|
|
self.assertNotIn('numa_topology', primitive)
|
|
|
|
def test_compat_supported_hv_specs(self):
|
|
compute = compute_node.ComputeNode()
|
|
compute.supported_hv_specs = fake_supported_hv_specs
|
|
versions = ovo_base.obj_tree_get_versions('ComputeNode')
|
|
primitive = compute.obj_to_primitive(target_version='1.5',
|
|
version_manifest=versions)
|
|
self.assertNotIn('supported_hv_specs', primitive)
|
|
|
|
def test_compat_host(self):
|
|
compute = compute_node.ComputeNode()
|
|
primitive = compute.obj_to_primitive(target_version='1.6')
|
|
self.assertNotIn('host', primitive)
|
|
|
|
def test_compat_pci_device_pools(self):
|
|
compute = compute_node.ComputeNode()
|
|
compute.pci_device_pools = fake_pci_device_pools.fake_pool_list
|
|
versions = ovo_base.obj_tree_get_versions('ComputeNode')
|
|
primitive = compute.obj_to_primitive(target_version='1.8',
|
|
version_manifest=versions)
|
|
self.assertNotIn('pci_device_pools', primitive)
|
|
|
|
@mock.patch('nova.objects.Service.get_by_compute_host')
|
|
def test_compat_service_id(self, mock_get):
|
|
mock_get.return_value = objects.Service(id=1)
|
|
compute = objects.ComputeNode(host='fake-host', service_id=None)
|
|
primitive = compute.obj_to_primitive(target_version='1.12')
|
|
self.assertEqual(1, primitive['nova_object.data']['service_id'])
|
|
|
|
@mock.patch('nova.objects.Service.get_by_compute_host')
|
|
def test_compat_service_id_compute_host_not_found(self, mock_get):
|
|
mock_get.side_effect = exception.ComputeHostNotFound(host='fake-host')
|
|
compute = objects.ComputeNode(host='fake-host', service_id=None)
|
|
primitive = compute.obj_to_primitive(target_version='1.12')
|
|
self.assertEqual(-1, primitive['nova_object.data']['service_id'])
|
|
|
|
def test_update_from_virt_driver(self):
|
|
# copy in case the update has a side effect
|
|
resources = copy.deepcopy(fake_resources)
|
|
# Emulate the ironic driver which adds a uuid field.
|
|
resources['uuid'] = uuidsentinel.node_uuid
|
|
compute = compute_node.ComputeNode()
|
|
compute.update_from_virt_driver(resources)
|
|
expected = fake_compute_with_resources.obj_clone()
|
|
expected.uuid = uuidsentinel.node_uuid
|
|
self.assertTrue(base.obj_equal_prims(expected, compute))
|
|
|
|
def test_update_from_virt_driver_uuid_already_set(self):
|
|
"""Tests update_from_virt_driver where the compute node object already
|
|
has a uuid value so the uuid from the virt driver is ignored.
|
|
"""
|
|
# copy in case the update has a side effect
|
|
resources = copy.deepcopy(fake_resources)
|
|
# Emulate the ironic driver which adds a uuid field.
|
|
resources['uuid'] = uuidsentinel.node_uuid
|
|
compute = compute_node.ComputeNode(uuid=uuidsentinel.something_else)
|
|
compute.update_from_virt_driver(resources)
|
|
expected = fake_compute_with_resources.obj_clone()
|
|
expected.uuid = uuidsentinel.something_else
|
|
self.assertTrue(base.obj_equal_prims(expected, compute))
|
|
|
|
def test_update_from_virt_driver_missing_field(self):
|
|
# NOTE(pmurray): update_from_virt_driver does not require
|
|
# all fields to be present in resources. Validation of the
|
|
# resources data structure would be done in a different method.
|
|
resources = copy.deepcopy(fake_resources)
|
|
del resources['vcpus']
|
|
compute = compute_node.ComputeNode()
|
|
compute.update_from_virt_driver(resources)
|
|
expected = fake_compute_with_resources.obj_clone()
|
|
del expected.vcpus
|
|
self.assertTrue(base.obj_equal_prims(expected, compute))
|
|
|
|
def test_update_from_virt_driver_extra_field(self):
|
|
# copy in case the update has a side effect
|
|
resources = copy.deepcopy(fake_resources)
|
|
resources['extra_field'] = 'nonsense'
|
|
compute = compute_node.ComputeNode()
|
|
compute.update_from_virt_driver(resources)
|
|
expected = fake_compute_with_resources
|
|
self.assertTrue(base.obj_equal_prims(expected, compute))
|
|
|
|
def test_update_from_virt_driver_bad_value(self):
|
|
# copy in case the update has a side effect
|
|
resources = copy.deepcopy(fake_resources)
|
|
resources['vcpus'] = 'nonsense'
|
|
compute = compute_node.ComputeNode()
|
|
self.assertRaises(ValueError,
|
|
compute.update_from_virt_driver, resources)
|
|
|
|
def test_compat_allocation_ratios(self):
|
|
compute = compute_node.ComputeNode()
|
|
primitive = compute.obj_to_primitive(target_version='1.13')
|
|
self.assertNotIn('cpu_allocation_ratio', primitive)
|
|
self.assertNotIn('ram_allocation_ratio', primitive)
|
|
|
|
def test_compat_disk_allocation_ratio(self):
|
|
compute = compute_node.ComputeNode()
|
|
primitive = compute.obj_to_primitive(target_version='1.15')
|
|
self.assertNotIn('disk_allocation_ratio', primitive)
|
|
|
|
def test_compat_allocation_ratios_old_compute(self):
|
|
self.flags(cpu_allocation_ratio=2.0, ram_allocation_ratio=3.0,
|
|
disk_allocation_ratio=0.9)
|
|
compute_dict = fake_compute_node.copy()
|
|
# old computes don't provide allocation ratios to the table
|
|
compute_dict['cpu_allocation_ratio'] = None
|
|
compute_dict['ram_allocation_ratio'] = None
|
|
compute_dict['disk_allocation_ratio'] = None
|
|
cls = objects.ComputeNode
|
|
compute = cls._from_db_object(self.context, cls(), compute_dict)
|
|
|
|
self.assertEqual(2.0, compute.cpu_allocation_ratio)
|
|
self.assertEqual(3.0, compute.ram_allocation_ratio)
|
|
self.assertEqual(0.9, compute.disk_allocation_ratio)
|
|
|
|
def test_compat_allocation_ratios_zero_conf(self):
|
|
self.flags(cpu_allocation_ratio=0.0, ram_allocation_ratio=0.0,
|
|
disk_allocation_ratio=0.0)
|
|
compute_dict = fake_compute_node.copy()
|
|
# the computes provide allocation ratios None
|
|
compute_dict['cpu_allocation_ratio'] = None
|
|
compute_dict['ram_allocation_ratio'] = None
|
|
compute_dict['disk_allocation_ratio'] = None
|
|
cls = objects.ComputeNode
|
|
compute = cls._from_db_object(self.context, cls(), compute_dict)
|
|
|
|
self.assertEqual(16.0, compute.cpu_allocation_ratio)
|
|
self.assertEqual(1.5, compute.ram_allocation_ratio)
|
|
self.assertEqual(1.0, compute.disk_allocation_ratio)
|
|
|
|
def test_compat_allocation_ratios_None_conf_zero_values(self):
|
|
# the CONF.x_allocation_ratio is None by default
|
|
compute_dict = fake_compute_node.copy()
|
|
# the computes provide allocation ratios 0.0
|
|
compute_dict['cpu_allocation_ratio'] = 0.0
|
|
compute_dict['ram_allocation_ratio'] = 0.0
|
|
compute_dict['disk_allocation_ratio'] = 0.0
|
|
cls = objects.ComputeNode
|
|
compute = cls._from_db_object(self.context, cls(), compute_dict)
|
|
|
|
self.assertEqual(16.0, compute.cpu_allocation_ratio)
|
|
self.assertEqual(1.5, compute.ram_allocation_ratio)
|
|
self.assertEqual(1.0, compute.disk_allocation_ratio)
|
|
|
|
def test_compat_allocation_ratios_None_conf_None_values(self):
|
|
# the CONF.x_allocation_ratio is None by default
|
|
compute_dict = fake_compute_node.copy()
|
|
# # the computes provide allocation ratios None
|
|
compute_dict['cpu_allocation_ratio'] = None
|
|
compute_dict['ram_allocation_ratio'] = None
|
|
compute_dict['disk_allocation_ratio'] = None
|
|
cls = objects.ComputeNode
|
|
compute = cls._from_db_object(self.context, cls(), compute_dict)
|
|
|
|
self.assertEqual(16.0, compute.cpu_allocation_ratio)
|
|
self.assertEqual(1.5, compute.ram_allocation_ratio)
|
|
self.assertEqual(1.0, compute.disk_allocation_ratio)
|
|
|
|
def test_get_all_by_not_mapped(self):
|
|
for mapped in (1, 0, 1, 3):
|
|
compute = fake_compute_with_resources.obj_clone()
|
|
compute._context = self.context
|
|
compute.mapped = mapped
|
|
compute.create()
|
|
nodes = compute_node.ComputeNodeList.get_all_by_not_mapped(
|
|
self.context, 2)
|
|
self.assertEqual(3, len(nodes))
|
|
self.assertEqual([0, 1, 1], sorted([x.mapped for x in nodes]))
|
|
|
|
|
|
class TestComputeNodeObject(test_objects._LocalTest,
|
|
_TestComputeNodeObject):
|
|
pass
|
|
|
|
|
|
class TestRemoteComputeNodeObject(test_objects._RemoteTest,
|
|
_TestComputeNodeObject):
|
|
pass
|