Merge "Transfer RequestLevelParams from ports to scheduling"
This commit is contained in:
commit
982d459c65
@ -1064,7 +1064,7 @@ class API:
|
|||||||
result = self.network_api.create_resource_requests(
|
result = self.network_api.create_resource_requests(
|
||||||
context, requested_networks, pci_request_info,
|
context, requested_networks, pci_request_info,
|
||||||
affinity_policy=pci_numa_affinity_policy)
|
affinity_policy=pci_numa_affinity_policy)
|
||||||
network_metadata, port_resource_requests = result
|
network_metadata, port_resource_requests, req_lvl_params = result
|
||||||
|
|
||||||
self._check_support_vnic_accelerator(context, requested_networks)
|
self._check_support_vnic_accelerator(context, requested_networks)
|
||||||
|
|
||||||
@ -1104,7 +1104,9 @@ class API:
|
|||||||
'pci_requests': pci_request_info,
|
'pci_requests': pci_request_info,
|
||||||
'numa_topology': numa_topology,
|
'numa_topology': numa_topology,
|
||||||
'system_metadata': system_metadata,
|
'system_metadata': system_metadata,
|
||||||
'port_resource_requests': port_resource_requests}
|
'port_resource_requests': port_resource_requests,
|
||||||
|
'request_level_params': req_lvl_params,
|
||||||
|
}
|
||||||
|
|
||||||
options_from_image = self._inherit_properties_from_image(
|
options_from_image = self._inherit_properties_from_image(
|
||||||
boot_meta, auto_disk_config)
|
boot_meta, auto_disk_config)
|
||||||
@ -1296,6 +1298,7 @@ class API:
|
|||||||
security_groups = security_group_api.populate_security_groups(
|
security_groups = security_group_api.populate_security_groups(
|
||||||
security_groups)
|
security_groups)
|
||||||
port_resource_requests = base_options.pop('port_resource_requests')
|
port_resource_requests = base_options.pop('port_resource_requests')
|
||||||
|
req_lvl_params = base_options.pop('request_level_params')
|
||||||
instances_to_build = []
|
instances_to_build = []
|
||||||
# We could be iterating over several instances with several BDMs per
|
# We could be iterating over several instances with several BDMs per
|
||||||
# instance and those BDMs could be using a lot of the same images so
|
# instance and those BDMs could be using a lot of the same images so
|
||||||
@ -1325,13 +1328,15 @@ class API:
|
|||||||
# RequestSpec before the instance is created.
|
# RequestSpec before the instance is created.
|
||||||
instance_uuid = uuidutils.generate_uuid()
|
instance_uuid = uuidutils.generate_uuid()
|
||||||
# Store the RequestSpec that will be used for scheduling.
|
# Store the RequestSpec that will be used for scheduling.
|
||||||
req_spec = objects.RequestSpec.from_components(context,
|
req_spec = objects.RequestSpec.from_components(
|
||||||
|
context,
|
||||||
instance_uuid, boot_meta, flavor,
|
instance_uuid, boot_meta, flavor,
|
||||||
base_options['numa_topology'],
|
base_options['numa_topology'],
|
||||||
base_options['pci_requests'], filter_properties,
|
base_options['pci_requests'], filter_properties,
|
||||||
instance_group, base_options['availability_zone'],
|
instance_group, base_options['availability_zone'],
|
||||||
security_groups=security_groups,
|
security_groups=security_groups,
|
||||||
port_resource_requests=port_resource_requests)
|
port_resource_requests=port_resource_requests,
|
||||||
|
request_level_params=req_lvl_params)
|
||||||
|
|
||||||
if block_device_mapping:
|
if block_device_mapping:
|
||||||
# Record whether or not we are a BFV instance
|
# Record whether or not we are a BFV instance
|
||||||
|
@ -7627,6 +7627,7 @@ class ComputeManager(manager.Manager):
|
|||||||
instance: 'objects.Instance',
|
instance: 'objects.Instance',
|
||||||
pci_reqs: 'objects.InstancePCIRequests',
|
pci_reqs: 'objects.InstancePCIRequests',
|
||||||
request_groups: ty.List['objects.RequestGroup'],
|
request_groups: ty.List['objects.RequestGroup'],
|
||||||
|
request_level_params: 'objects.RequestLevelParams',
|
||||||
) -> ty.Tuple[ty.Optional[ty.Dict[str, ty.List[str]]],
|
) -> ty.Tuple[ty.Optional[ty.Dict[str, ty.List[str]]],
|
||||||
ty.Optional[ty.Dict[str, ty.Dict[str, ty.Dict[str, int]]]]]:
|
ty.Optional[ty.Dict[str, ty.Dict[str, ty.Dict[str, int]]]]]:
|
||||||
"""Allocate resources for the request in placement
|
"""Allocate resources for the request in placement
|
||||||
@ -7638,6 +7639,8 @@ class ComputeManager(manager.Manager):
|
|||||||
needed PCI devices
|
needed PCI devices
|
||||||
:param request_groups: A list of RequestGroup objects describing the
|
:param request_groups: A list of RequestGroup objects describing the
|
||||||
resources the port requests from placement
|
resources the port requests from placement
|
||||||
|
:param request_level_params: A RequestLevelParams object describing the
|
||||||
|
non group specific request of the port.
|
||||||
:raises InterfaceAttachResourceAllocationFailed: if we failed to
|
:raises InterfaceAttachResourceAllocationFailed: if we failed to
|
||||||
allocate resource in placement for the request
|
allocate resource in placement for the request
|
||||||
:returns: A tuple of provider mappings and allocated resources or
|
:returns: A tuple of provider mappings and allocated resources or
|
||||||
@ -7666,7 +7669,8 @@ class ComputeManager(manager.Manager):
|
|||||||
# NOTE(gibi): when support is added for attaching a cyborg based
|
# NOTE(gibi): when support is added for attaching a cyborg based
|
||||||
# smart NIC the ResourceRequest could be extended to handle multiple
|
# smart NIC the ResourceRequest could be extended to handle multiple
|
||||||
# request groups.
|
# request groups.
|
||||||
rr = scheduler_utils.ResourceRequest.from_request_group(request_group)
|
rr = scheduler_utils.ResourceRequest.from_request_group(
|
||||||
|
request_group, request_level_params)
|
||||||
res = self.reportclient.get_allocation_candidates(context, rr)
|
res = self.reportclient.get_allocation_candidates(context, rr)
|
||||||
alloc_reqs, provider_sums, version = res
|
alloc_reqs, provider_sums, version = res
|
||||||
|
|
||||||
@ -7789,12 +7793,17 @@ class ComputeManager(manager.Manager):
|
|||||||
instance.flavor, instance.image_meta)
|
instance.flavor, instance.image_meta)
|
||||||
pci_reqs = objects.InstancePCIRequests(
|
pci_reqs = objects.InstancePCIRequests(
|
||||||
requests=[], instance_uuid=instance.uuid)
|
requests=[], instance_uuid=instance.uuid)
|
||||||
_, request_groups = self.network_api.create_resource_requests(
|
_, request_groups, req_lvl_params = (
|
||||||
context, requested_networks, pci_reqs,
|
self.network_api.create_resource_requests(
|
||||||
affinity_policy=pci_numa_affinity_policy)
|
context,
|
||||||
|
requested_networks,
|
||||||
|
pci_reqs,
|
||||||
|
affinity_policy=pci_numa_affinity_policy
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
result = self._allocate_port_resource_for_instance(
|
result = self._allocate_port_resource_for_instance(
|
||||||
context, instance, pci_reqs, request_groups)
|
context, instance, pci_reqs, request_groups, req_lvl_params)
|
||||||
provider_mappings, resources = result
|
provider_mappings, resources = result
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -2050,13 +2050,15 @@ class API:
|
|||||||
:type affinity_policy: nova.objects.fields.PCINUMAAffinityPolicy
|
:type affinity_policy: nova.objects.fields.PCINUMAAffinityPolicy
|
||||||
:raises ExtendedResourceRequestNotSupported: if the
|
:raises ExtendedResourceRequestNotSupported: if the
|
||||||
extended-resource-request Neutron API extension is enabled.
|
extended-resource-request Neutron API extension is enabled.
|
||||||
:returns: A tuple with an instance of ``objects.NetworkMetadata`` for
|
|
||||||
use by the scheduler or None and a list of RequestGroup
|
:returns: A three tuple with an instance of ``objects.NetworkMetadata``
|
||||||
objects representing the resource needs of each requested
|
for use by the scheduler or None, a list of RequestGroup
|
||||||
port
|
objects representing the resource needs of each requested port and
|
||||||
|
a RequestLevelParam object that contains global scheduling
|
||||||
|
instructions not specific to any of the RequestGroups
|
||||||
"""
|
"""
|
||||||
if not requested_networks or requested_networks.no_allocate:
|
if not requested_networks or requested_networks.no_allocate:
|
||||||
return None, []
|
return None, [], None
|
||||||
|
|
||||||
if not self.support_create_with_resource_request(context):
|
if not self.support_create_with_resource_request(context):
|
||||||
raise exception.ExtendedResourceRequestNotSupported()
|
raise exception.ExtendedResourceRequestNotSupported()
|
||||||
@ -2068,6 +2070,7 @@ class API:
|
|||||||
has_extended_resource_request_extension = (
|
has_extended_resource_request_extension = (
|
||||||
self._has_extended_resource_request_extension(context, neutron))
|
self._has_extended_resource_request_extension(context, neutron))
|
||||||
resource_requests = []
|
resource_requests = []
|
||||||
|
request_level_params = objects.RequestLevelParams()
|
||||||
|
|
||||||
for request_net in requested_networks:
|
for request_net in requested_networks:
|
||||||
physnet = None
|
physnet = None
|
||||||
@ -2122,6 +2125,9 @@ class API:
|
|||||||
objects.RequestGroup.from_extended_port_request(
|
objects.RequestGroup.from_extended_port_request(
|
||||||
context=None,
|
context=None,
|
||||||
port_resource_request=resource_request))
|
port_resource_request=resource_request))
|
||||||
|
request_level_params.extend_with(
|
||||||
|
objects.RequestLevelParams.from_port_request(
|
||||||
|
port_resource_request=resource_request))
|
||||||
else:
|
else:
|
||||||
# keep supporting the old format of the
|
# keep supporting the old format of the
|
||||||
# resource_request
|
# resource_request
|
||||||
@ -2183,8 +2189,11 @@ class API:
|
|||||||
# Add pci_request_id into the requested network
|
# Add pci_request_id into the requested network
|
||||||
request_net.pci_request_id = pci_request_id
|
request_net.pci_request_id = pci_request_id
|
||||||
|
|
||||||
return (objects.NetworkMetadata(physnets=physnets, tunneled=tunneled),
|
return (
|
||||||
resource_requests)
|
objects.NetworkMetadata(physnets=physnets, tunneled=tunneled),
|
||||||
|
resource_requests,
|
||||||
|
request_level_params
|
||||||
|
)
|
||||||
|
|
||||||
def _can_auto_allocate_network(self, context, neutron):
|
def _can_auto_allocate_network(self, context, neutron):
|
||||||
"""Helper method to determine if we can auto-allocate networks
|
"""Helper method to determine if we can auto-allocate networks
|
||||||
|
@ -474,10 +474,12 @@ class RequestSpec(base.NovaObject):
|
|||||||
return filt_props
|
return filt_props
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_components(cls, context, instance_uuid, image, flavor,
|
def from_components(
|
||||||
|
cls, context, instance_uuid, image, flavor,
|
||||||
numa_topology, pci_requests, filter_properties, instance_group,
|
numa_topology, pci_requests, filter_properties, instance_group,
|
||||||
availability_zone, security_groups=None, project_id=None,
|
availability_zone, security_groups=None, project_id=None,
|
||||||
user_id=None, port_resource_requests=None):
|
user_id=None, port_resource_requests=None, request_level_params=None
|
||||||
|
):
|
||||||
"""Returns a new RequestSpec object hydrated by various components.
|
"""Returns a new RequestSpec object hydrated by various components.
|
||||||
|
|
||||||
This helper is useful in creating the RequestSpec from the various
|
This helper is useful in creating the RequestSpec from the various
|
||||||
@ -503,6 +505,7 @@ class RequestSpec(base.NovaObject):
|
|||||||
:param port_resource_requests: a list of RequestGroup objects
|
:param port_resource_requests: a list of RequestGroup objects
|
||||||
representing the resource needs of the
|
representing the resource needs of the
|
||||||
neutron ports
|
neutron ports
|
||||||
|
:param request_level_params: a RequestLevelParams object
|
||||||
"""
|
"""
|
||||||
spec_obj = cls(context)
|
spec_obj = cls(context)
|
||||||
spec_obj.num_instances = 1
|
spec_obj.num_instances = 1
|
||||||
@ -536,10 +539,11 @@ class RequestSpec(base.NovaObject):
|
|||||||
if port_resource_requests:
|
if port_resource_requests:
|
||||||
spec_obj.requested_resources.extend(port_resource_requests)
|
spec_obj.requested_resources.extend(port_resource_requests)
|
||||||
|
|
||||||
# NOTE(efried): We don't need to handle request_level_params here yet
|
# NOTE(gibi): later the scheduler adds more request level params but
|
||||||
# because they're set dynamically by the scheduler. That could change
|
# never overrides existing ones so we can initialize them here.
|
||||||
# in the future.
|
if request_level_params is None:
|
||||||
# TODO(gibi): handle same_subtree here coming from the neutron ports
|
request_level_params = objects.RequestLevelParams()
|
||||||
|
spec_obj.request_level_params = request_level_params
|
||||||
|
|
||||||
# NOTE(sbauza): Default the other fields that are not part of the
|
# NOTE(sbauza): Default the other fields that are not part of the
|
||||||
# original contract
|
# original contract
|
||||||
|
@ -202,9 +202,13 @@ class ResourceRequest(object):
|
|||||||
def from_request_group(
|
def from_request_group(
|
||||||
cls,
|
cls,
|
||||||
request_group: 'objects.RequestGroup',
|
request_group: 'objects.RequestGroup',
|
||||||
|
request_level_params: 'objects.RequestLevelParams',
|
||||||
) -> 'ResourceRequest':
|
) -> 'ResourceRequest':
|
||||||
"""Create a new instance of ResourceRequest from a RequestGroup."""
|
"""Create a new instance of ResourceRequest from a RequestGroup."""
|
||||||
res_req = cls()
|
res_req = cls()
|
||||||
|
res_req._root_required = request_level_params.root_required
|
||||||
|
res_req._root_forbidden = request_level_params.root_forbidden
|
||||||
|
res_req._same_subtree = request_level_params.same_subtree
|
||||||
res_req._add_request_group(request_group)
|
res_req._add_request_group(request_group)
|
||||||
res_req.strip_zeros()
|
res_req.strip_zeros()
|
||||||
return res_req
|
return res_req
|
||||||
|
@ -184,7 +184,7 @@ def stub_out_nw_api(test, cls=None, private=None, publics=None):
|
|||||||
def create_resource_requests(
|
def create_resource_requests(
|
||||||
self, context, requested_networks,
|
self, context, requested_networks,
|
||||||
pci_requests=None, affinity_policy=None):
|
pci_requests=None, affinity_policy=None):
|
||||||
return None, []
|
return None, [], objects.RequestLevelParams()
|
||||||
|
|
||||||
if cls is None:
|
if cls is None:
|
||||||
cls = Fake
|
cls = Fake
|
||||||
|
@ -226,9 +226,11 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
objects=[objects.NetworkRequest(address=address,
|
objects=[objects.NetworkRequest(address=address,
|
||||||
port_id=port)])
|
port_id=port)])
|
||||||
|
|
||||||
with mock.patch.object(self.compute_api.network_api,
|
with mock.patch.object(
|
||||||
|
self.compute_api.network_api,
|
||||||
'create_resource_requests',
|
'create_resource_requests',
|
||||||
return_value=(None, [])):
|
return_value=(None, [], mock.sentinel.req_lvl_params)
|
||||||
|
):
|
||||||
self.compute_api.create(self.context, flavor, 'image_id',
|
self.compute_api.create(self.context, flavor, 'image_id',
|
||||||
requested_networks=requested_networks,
|
requested_networks=requested_networks,
|
||||||
max_count=None)
|
max_count=None)
|
||||||
@ -4891,7 +4893,10 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
'user_data': None,
|
'user_data': None,
|
||||||
'numa_topology': None,
|
'numa_topology': None,
|
||||||
'pci_requests': None,
|
'pci_requests': None,
|
||||||
'port_resource_requests': None}
|
'port_resource_requests': None,
|
||||||
|
'request_level_params':
|
||||||
|
objects.RequestLevelParams(),
|
||||||
|
}
|
||||||
security_groups = {}
|
security_groups = {}
|
||||||
block_device_mapping = objects.BlockDeviceMappingList(
|
block_device_mapping = objects.BlockDeviceMappingList(
|
||||||
objects=[objects.BlockDeviceMapping(
|
objects=[objects.BlockDeviceMapping(
|
||||||
@ -5062,10 +5067,12 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
'properties': {'mappings': []},
|
'properties': {'mappings': []},
|
||||||
'status': 'fake-status',
|
'status': 'fake-status',
|
||||||
'location': 'far-away'}
|
'location': 'far-away'}
|
||||||
|
numa_topology = objects.InstanceNUMATopology()
|
||||||
|
pci_requests = objects.InstancePCIRequests()
|
||||||
base_options = {'image_ref': 'fake-ref',
|
base_options = {'image_ref': 'fake-ref',
|
||||||
'display_name': 'fake-name',
|
'display_name': 'fake-name',
|
||||||
'project_id': 'fake-project',
|
'project_id': 'fake-project',
|
||||||
'availability_zone': None,
|
'availability_zone': 'fake-az',
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
'access_ip_v4': None,
|
'access_ip_v4': None,
|
||||||
'access_ip_v6': None,
|
'access_ip_v6': None,
|
||||||
@ -5076,9 +5083,13 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
'ramdisk_id': None,
|
'ramdisk_id': None,
|
||||||
'root_device_name': None,
|
'root_device_name': None,
|
||||||
'user_data': None,
|
'user_data': None,
|
||||||
'numa_topology': None,
|
'numa_topology': numa_topology,
|
||||||
'pci_requests': None,
|
'pci_requests': pci_requests,
|
||||||
'port_resource_requests': None}
|
'port_resource_requests':
|
||||||
|
mock.sentinel.resource_reqs,
|
||||||
|
'request_level_params':
|
||||||
|
mock.sentinel.req_lvl_params,
|
||||||
|
}
|
||||||
security_groups = {}
|
security_groups = {}
|
||||||
block_device_mappings = objects.BlockDeviceMappingList(
|
block_device_mappings = objects.BlockDeviceMappingList(
|
||||||
objects=[objects.BlockDeviceMapping(
|
objects=[objects.BlockDeviceMapping(
|
||||||
@ -5115,6 +5126,18 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
block_device_mappings, {}, mock_get_volumes.return_value,
|
block_device_mappings, {}, mock_get_volumes.return_value,
|
||||||
False)] * max_count)
|
False)] * max_count)
|
||||||
|
|
||||||
|
mock_req_spec_from_components.assert_has_calls(
|
||||||
|
[
|
||||||
|
mock.call(
|
||||||
|
ctxt, mock.ANY, boot_meta, flavor, numa_topology,
|
||||||
|
pci_requests, filter_properties, instance_group,
|
||||||
|
'fake-az', security_groups=mock.ANY,
|
||||||
|
port_resource_requests=mock.sentinel.resource_reqs,
|
||||||
|
request_level_params=mock.sentinel.req_lvl_params
|
||||||
|
),
|
||||||
|
] * 2
|
||||||
|
)
|
||||||
|
|
||||||
for rs, br, im in instances_to_build:
|
for rs, br, im in instances_to_build:
|
||||||
self.assertIsInstance(br.instance, objects.Instance)
|
self.assertIsInstance(br.instance, objects.Instance)
|
||||||
self.assertTrue(uuidutils.is_uuid_like(br.instance.uuid))
|
self.assertTrue(uuidutils.is_uuid_like(br.instance.uuid))
|
||||||
@ -5168,7 +5191,10 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
'user_data': None,
|
'user_data': None,
|
||||||
'numa_topology': None,
|
'numa_topology': None,
|
||||||
'pci_requests': None,
|
'pci_requests': None,
|
||||||
'port_resource_requests': None}
|
'port_resource_requests': None,
|
||||||
|
'request_level_params':
|
||||||
|
objects.RequestLevelParams(),
|
||||||
|
}
|
||||||
security_groups = {}
|
security_groups = {}
|
||||||
block_device_mapping = objects.BlockDeviceMappingList(
|
block_device_mapping = objects.BlockDeviceMappingList(
|
||||||
objects=[objects.BlockDeviceMapping(
|
objects=[objects.BlockDeviceMapping(
|
||||||
@ -5265,7 +5291,11 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
'user_data': None,
|
'user_data': None,
|
||||||
'numa_topology': None,
|
'numa_topology': None,
|
||||||
'pci_requests': None,
|
'pci_requests': None,
|
||||||
'port_resource_requests': None}
|
'port_resource_requests': None,
|
||||||
|
'request_level_params':
|
||||||
|
objects.RequestLevelParams(),
|
||||||
|
}
|
||||||
|
|
||||||
security_groups = {}
|
security_groups = {}
|
||||||
block_device_mapping = objects.BlockDeviceMappingList(
|
block_device_mapping = objects.BlockDeviceMappingList(
|
||||||
objects=[objects.BlockDeviceMapping(
|
objects=[objects.BlockDeviceMapping(
|
||||||
@ -5331,7 +5361,9 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
mock_objects.RequestSpec.from_components.assert_called_once_with(
|
mock_objects.RequestSpec.from_components.assert_called_once_with(
|
||||||
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY,
|
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY,
|
||||||
mock.ANY, mock.ANY, mock.ANY,
|
mock.ANY, mock.ANY, mock.ANY,
|
||||||
security_groups=secgroups, port_resource_requests=mock.ANY)
|
security_groups=secgroups, port_resource_requests=mock.ANY,
|
||||||
|
request_level_params=mock.ANY
|
||||||
|
)
|
||||||
test()
|
test()
|
||||||
|
|
||||||
def _test_rescue(self, vm_state=vm_states.ACTIVE, rescue_password=None,
|
def _test_rescue(self, vm_state=vm_states.ACTIVE, rescue_password=None,
|
||||||
|
@ -8703,11 +8703,13 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
objects=[objects.NetworkRequest(port_id=uuids.port_instance)])
|
objects=[objects.NetworkRequest(port_id=uuids.port_instance)])
|
||||||
|
|
||||||
with test.nested(
|
with test.nested(
|
||||||
mock.patch.object(self.compute_api.compute_task_api,
|
mock.patch.object(
|
||||||
|
self.compute_api.compute_task_api,
|
||||||
'schedule_and_build_instances'),
|
'schedule_and_build_instances'),
|
||||||
mock.patch.object(self.compute_api.network_api,
|
mock.patch.object(
|
||||||
|
self.compute_api.network_api,
|
||||||
'create_resource_requests',
|
'create_resource_requests',
|
||||||
return_value=(None, [])),
|
return_value=(None, [], objects.RequestLevelParams())),
|
||||||
) as (mock_sbi, _mock_create_resreqs):
|
) as (mock_sbi, _mock_create_resreqs):
|
||||||
self.compute_api.create(
|
self.compute_api.create(
|
||||||
self.context,
|
self.context,
|
||||||
@ -10206,7 +10208,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
"_claim_pci_device_for_interface_attach",
|
"_claim_pci_device_for_interface_attach",
|
||||||
return_value=None)
|
return_value=None)
|
||||||
) as (cap, mock_lock, mock_create_resource_req, mock_claim_pci):
|
) as (cap, mock_lock, mock_create_resource_req, mock_claim_pci):
|
||||||
mock_create_resource_req.return_value = (None, [])
|
mock_create_resource_req.return_value = (
|
||||||
|
None, [], mock.sentinel.req_lvl_params)
|
||||||
vif = self.compute.attach_interface(self.context,
|
vif = self.compute.attach_interface(self.context,
|
||||||
instance,
|
instance,
|
||||||
network_id,
|
network_id,
|
||||||
@ -10266,7 +10269,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
mock_allocate_res
|
mock_allocate_res
|
||||||
):
|
):
|
||||||
request_groups = [objects.RequestGroup]
|
request_groups = [objects.RequestGroup]
|
||||||
mock_create_resource_req.return_value = (None, request_groups)
|
mock_create_resource_req.return_value = (
|
||||||
|
None, request_groups, mock.sentinel.req_lvl_params)
|
||||||
mock_allocate_res.return_value = (
|
mock_allocate_res.return_value = (
|
||||||
mock.sentinel.provider_mappings, mock.sentinel.resources)
|
mock.sentinel.provider_mappings, mock.sentinel.resources)
|
||||||
vif = self.compute.attach_interface(
|
vif = self.compute.attach_interface(
|
||||||
@ -10311,7 +10315,9 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
# as this port has resource request we need to call
|
# as this port has resource request we need to call
|
||||||
# _allocate_port_resource_for_instance for it
|
# _allocate_port_resource_for_instance for it
|
||||||
mock_allocate_res.assert_called_once_with(
|
mock_allocate_res.assert_called_once_with(
|
||||||
self.context, instance, pci_reqs, request_groups)
|
self.context, instance, pci_reqs, request_groups,
|
||||||
|
mock.sentinel.req_lvl_params
|
||||||
|
)
|
||||||
|
|
||||||
@mock.patch.object(compute_utils, 'notify_about_instance_action')
|
@mock.patch.object(compute_utils, 'notify_about_instance_action')
|
||||||
def test_attach_sriov_interface(self, mock_notify):
|
def test_attach_sriov_interface(self, mock_notify):
|
||||||
@ -10348,7 +10354,7 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
# Simulate that the requested port is an SRIOV port
|
# Simulate that the requested port is an SRIOV port
|
||||||
pci_requests.requests.append(pci_req)
|
pci_requests.requests.append(pci_req)
|
||||||
# without resource request
|
# without resource request
|
||||||
return None, []
|
return None, [], mock.sentinel.req_lvl_params
|
||||||
|
|
||||||
mock_create_resource_req.side_effect = create_resource_req
|
mock_create_resource_req.side_effect = create_resource_req
|
||||||
|
|
||||||
@ -10424,7 +10430,7 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
# Simulate that the requested port is an SRIOV port
|
# Simulate that the requested port is an SRIOV port
|
||||||
pci_requests.requests.append(pci_req)
|
pci_requests.requests.append(pci_req)
|
||||||
# with resource request
|
# with resource request
|
||||||
return None, request_groups
|
return None, request_groups, mock.sentinel.req_lvl_params
|
||||||
|
|
||||||
mock_create_resource_req.side_effect = create_resource_req
|
mock_create_resource_req.side_effect = create_resource_req
|
||||||
|
|
||||||
@ -10475,9 +10481,11 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
self.assertIn(pci_device, instance.pci_devices.objects)
|
self.assertIn(pci_device, instance.pci_devices.objects)
|
||||||
|
|
||||||
# ensure that we called _allocate_port_resource_for_instance as it has
|
# ensure that we called _allocate_port_resource_for_instance as it has
|
||||||
# resource reques
|
# resource request
|
||||||
mock_allocate_res.assert_called_once_with(
|
mock_allocate_res.assert_called_once_with(
|
||||||
self.context, instance, pci_reqs, request_groups)
|
self.context, instance, pci_reqs, request_groups,
|
||||||
|
mock.sentinel.req_lvl_params
|
||||||
|
)
|
||||||
|
|
||||||
@mock.patch.object(compute_utils, 'notify_about_instance_action')
|
@mock.patch.object(compute_utils, 'notify_about_instance_action')
|
||||||
def test_interface_tagged_attach(self, mock_notify):
|
def test_interface_tagged_attach(self, mock_notify):
|
||||||
@ -10498,7 +10506,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
'_claim_pci_device_for_interface_attach',
|
'_claim_pci_device_for_interface_attach',
|
||||||
return_value=None)
|
return_value=None)
|
||||||
) as (mock_capabilities, mock_create_resource_req, mock_claim_pci):
|
) as (mock_capabilities, mock_create_resource_req, mock_claim_pci):
|
||||||
mock_create_resource_req.return_value = (None, [])
|
mock_create_resource_req.return_value = (
|
||||||
|
None, [], mock.sentinel.req_lvl_params)
|
||||||
vif = self.compute.attach_interface(self.context,
|
vif = self.compute.attach_interface(self.context,
|
||||||
instance,
|
instance,
|
||||||
network_id,
|
network_id,
|
||||||
@ -10574,7 +10583,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
) as (mock_notify, mock_attach, mock_allocate, mock_deallocate,
|
) as (mock_notify, mock_attach, mock_allocate, mock_deallocate,
|
||||||
mock_dict, mock_create_resource_req, mock_claim_pci):
|
mock_dict, mock_create_resource_req, mock_claim_pci):
|
||||||
|
|
||||||
mock_create_resource_req.return_value = (None, [])
|
mock_create_resource_req.return_value = (
|
||||||
|
None, [], mock.sentinel.req_lvl_params)
|
||||||
mock_allocate.return_value = nwinfo
|
mock_allocate.return_value = nwinfo
|
||||||
mock_attach.side_effect = exception.NovaException("attach_failed")
|
mock_attach.side_effect = exception.NovaException("attach_failed")
|
||||||
self.assertRaises(exception.InterfaceAttachFailed,
|
self.assertRaises(exception.InterfaceAttachFailed,
|
||||||
@ -10652,7 +10662,7 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
pci_requests=None, affinity_policy=None):
|
pci_requests=None, affinity_policy=None):
|
||||||
# Simulate that the requested port is an SRIOV port
|
# Simulate that the requested port is an SRIOV port
|
||||||
pci_requests.requests.append(pci_req)
|
pci_requests.requests.append(pci_req)
|
||||||
return None, []
|
return None, [], mock.sentinel.req_lvl_params
|
||||||
|
|
||||||
mock_create_resource_req.side_effect = create_resource_req
|
mock_create_resource_req.side_effect = create_resource_req
|
||||||
mock_allocate.return_value = nwinfo
|
mock_allocate.return_value = nwinfo
|
||||||
@ -10727,7 +10737,7 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
pci_requests=None, affinity_policy=None):
|
pci_requests=None, affinity_policy=None):
|
||||||
# Simulate that the requested port is an SRIOV port
|
# Simulate that the requested port is an SRIOV port
|
||||||
pci_requests.requests.append(pci_req)
|
pci_requests.requests.append(pci_req)
|
||||||
return None, request_groups
|
return None, request_groups, mock.sentinel.req_lvl_params
|
||||||
|
|
||||||
mock_create_resource_req.side_effect = create_resource_req
|
mock_create_resource_req.side_effect = create_resource_req
|
||||||
mock_allocate_res.return_value = (
|
mock_allocate_res.return_value = (
|
||||||
@ -10752,7 +10762,12 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
self.assertNotIn(pci_req, instance.pci_requests.requests)
|
self.assertNotIn(pci_req, instance.pci_requests.requests)
|
||||||
|
|
||||||
mock_allocate_res.assert_called_once_with(
|
mock_allocate_res.assert_called_once_with(
|
||||||
self.context, instance, pci_reqs, request_groups)
|
self.context,
|
||||||
|
instance,
|
||||||
|
pci_reqs,
|
||||||
|
request_groups,
|
||||||
|
mock.sentinel.req_lvl_params
|
||||||
|
)
|
||||||
mock_remove_res.assert_called_once_with(
|
mock_remove_res.assert_called_once_with(
|
||||||
self.context, instance.uuid, mock.sentinel.resources)
|
self.context, instance.uuid, mock.sentinel.resources)
|
||||||
|
|
||||||
@ -10764,6 +10779,10 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
resources={"CUSTOM_FOO": 13},
|
resources={"CUSTOM_FOO": 13},
|
||||||
requester_id=uuids.requester_id)
|
requester_id=uuids.requester_id)
|
||||||
]
|
]
|
||||||
|
req_lvl_params = objects.RequestLevelParams(
|
||||||
|
root_required={"CUSTOM_BLUE"},
|
||||||
|
same_subtree=[[uuids.group1, uuids.group2]]
|
||||||
|
)
|
||||||
|
|
||||||
with test.nested(
|
with test.nested(
|
||||||
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
||||||
@ -10792,7 +10811,9 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
alloc_reqs, mock.sentinel.provider_sums, mock.sentinel.version)
|
alloc_reqs, mock.sentinel.provider_sums, mock.sentinel.version)
|
||||||
|
|
||||||
res = self.compute._allocate_port_resource_for_instance(
|
res = self.compute._allocate_port_resource_for_instance(
|
||||||
self.context, instance, pci_reqs, request_groups)
|
self.context, instance, pci_reqs, request_groups,
|
||||||
|
req_lvl_params
|
||||||
|
)
|
||||||
provider_mappings, resources = res
|
provider_mappings, resources = res
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -10808,6 +10829,11 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
request_groups[0].requester_id)
|
request_groups[0].requester_id)
|
||||||
self.assertEqual(request_groups[0], actual_rg)
|
self.assertEqual(request_groups[0], actual_rg)
|
||||||
self.assertEqual(uuids.compute_node, actual_rg.in_tree)
|
self.assertEqual(uuids.compute_node, actual_rg.in_tree)
|
||||||
|
self.assertEqual({"CUSTOM_BLUE"}, resource_request._root_required)
|
||||||
|
self.assertEqual(
|
||||||
|
[[uuids.group1, uuids.group2]],
|
||||||
|
resource_request._same_subtree
|
||||||
|
)
|
||||||
mock_add_res.assert_called_once_with(
|
mock_add_res.assert_called_once_with(
|
||||||
self.context, instance.uuid, mock.sentinel.resources)
|
self.context, instance.uuid, mock.sentinel.resources)
|
||||||
mock_update_pci.assert_called_once_with(
|
mock_update_pci.assert_called_once_with(
|
||||||
@ -10822,6 +10848,10 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
resources={"CUSTOM_FOO": 13},
|
resources={"CUSTOM_FOO": 13},
|
||||||
requester_id=uuids.requester_id)
|
requester_id=uuids.requester_id)
|
||||||
]
|
]
|
||||||
|
req_lvl_params = objects.RequestLevelParams(
|
||||||
|
root_required={"CUSTOM_BLUE"},
|
||||||
|
same_subtree=[[uuids.group1, uuids.group2]]
|
||||||
|
)
|
||||||
|
|
||||||
with test.nested(
|
with test.nested(
|
||||||
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
||||||
@ -10847,7 +10877,9 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
exception.InterfaceAttachResourceAllocationFailed,
|
exception.InterfaceAttachResourceAllocationFailed,
|
||||||
self.compute._allocate_port_resource_for_instance,
|
self.compute._allocate_port_resource_for_instance,
|
||||||
self.context, instance, pci_reqs, request_groups)
|
self.context, instance, pci_reqs, request_groups,
|
||||||
|
req_lvl_params,
|
||||||
|
)
|
||||||
|
|
||||||
mock_get_nodename.assert_called_once_with(
|
mock_get_nodename.assert_called_once_with(
|
||||||
self.context, instance.node)
|
self.context, instance.node)
|
||||||
@ -10862,6 +10894,10 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
resources={"CUSTOM_FOO": 13},
|
resources={"CUSTOM_FOO": 13},
|
||||||
requester_id=uuids.requester_id)
|
requester_id=uuids.requester_id)
|
||||||
]
|
]
|
||||||
|
req_lvl_params = objects.RequestLevelParams(
|
||||||
|
root_required={"CUSTOM_BLUE"},
|
||||||
|
same_subtree=[[uuids.group1, uuids.group2]]
|
||||||
|
)
|
||||||
|
|
||||||
with test.nested(
|
with test.nested(
|
||||||
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
||||||
@ -10896,7 +10932,9 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
exception.InterfaceAttachResourceAllocationFailed,
|
exception.InterfaceAttachResourceAllocationFailed,
|
||||||
self.compute._allocate_port_resource_for_instance,
|
self.compute._allocate_port_resource_for_instance,
|
||||||
self.context, instance, pci_reqs, request_groups)
|
self.context, instance, pci_reqs, request_groups,
|
||||||
|
req_lvl_params
|
||||||
|
)
|
||||||
|
|
||||||
mock_get_nodename.assert_called_once_with(
|
mock_get_nodename.assert_called_once_with(
|
||||||
self.context, instance.node)
|
self.context, instance.node)
|
||||||
@ -10907,6 +10945,11 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
request_groups[0].requester_id)
|
request_groups[0].requester_id)
|
||||||
self.assertEqual(request_groups[0], actual_rg)
|
self.assertEqual(request_groups[0], actual_rg)
|
||||||
self.assertEqual(uuids.compute_node, actual_rg.in_tree)
|
self.assertEqual(uuids.compute_node, actual_rg.in_tree)
|
||||||
|
self.assertEqual({"CUSTOM_BLUE"}, resource_request._root_required)
|
||||||
|
self.assertEqual(
|
||||||
|
[[uuids.group1, uuids.group2]],
|
||||||
|
resource_request._same_subtree
|
||||||
|
)
|
||||||
mock_add_res.assert_called_once_with(
|
mock_add_res.assert_called_once_with(
|
||||||
self.context, instance.uuid, mock.sentinel.resources)
|
self.context, instance.uuid, mock.sentinel.resources)
|
||||||
|
|
||||||
@ -10918,6 +10961,10 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
resources={"CUSTOM_FOO": 13},
|
resources={"CUSTOM_FOO": 13},
|
||||||
requester_id=uuids.requester_id)
|
requester_id=uuids.requester_id)
|
||||||
]
|
]
|
||||||
|
req_lvl_params = objects.RequestLevelParams(
|
||||||
|
root_required={"CUSTOM_BLUE"},
|
||||||
|
same_subtree=[[uuids.group1, uuids.group2]]
|
||||||
|
)
|
||||||
|
|
||||||
with test.nested(
|
with test.nested(
|
||||||
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
mock.patch.object(objects.ComputeNode, 'get_by_nodename'),
|
||||||
@ -10954,7 +11001,9 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
exception.AmbiguousResourceProviderForPCIRequest,
|
exception.AmbiguousResourceProviderForPCIRequest,
|
||||||
self.compute._allocate_port_resource_for_instance,
|
self.compute._allocate_port_resource_for_instance,
|
||||||
self.context, instance, pci_reqs, request_groups)
|
self.context, instance, pci_reqs, request_groups,
|
||||||
|
req_lvl_params
|
||||||
|
)
|
||||||
|
|
||||||
mock_get_nodename.assert_called_once_with(
|
mock_get_nodename.assert_called_once_with(
|
||||||
self.context, instance.node)
|
self.context, instance.node)
|
||||||
@ -10965,6 +11014,11 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
request_groups[0].requester_id)
|
request_groups[0].requester_id)
|
||||||
self.assertEqual(request_groups[0], actual_rg)
|
self.assertEqual(request_groups[0], actual_rg)
|
||||||
self.assertEqual(uuids.compute_node, actual_rg.in_tree)
|
self.assertEqual(uuids.compute_node, actual_rg.in_tree)
|
||||||
|
self.assertEqual({"CUSTOM_BLUE"}, resource_request._root_required)
|
||||||
|
self.assertEqual(
|
||||||
|
[[uuids.group1, uuids.group2]],
|
||||||
|
resource_request._same_subtree
|
||||||
|
)
|
||||||
mock_add_res.assert_called_once_with(
|
mock_add_res.assert_called_once_with(
|
||||||
self.context, instance.uuid, mock.sentinel.resources)
|
self.context, instance.uuid, mock.sentinel.resources)
|
||||||
mock_update_pci.assert_called_once_with(
|
mock_update_pci.assert_called_once_with(
|
||||||
|
@ -2627,7 +2627,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
def do_test(
|
def do_test(
|
||||||
update, meth, add_fault, notify, event, mock_claim_pci,
|
update, meth, add_fault, notify, event, mock_claim_pci,
|
||||||
mock_create_resource_req):
|
mock_create_resource_req):
|
||||||
mock_create_resource_req.return_value = None, []
|
mock_create_resource_req.return_value = (
|
||||||
|
None, [], mock.sentinel.req_lvl_params)
|
||||||
self.assertRaises(exception.InterfaceAttachFailed,
|
self.assertRaises(exception.InterfaceAttachFailed,
|
||||||
self.compute.attach_interface,
|
self.compute.attach_interface,
|
||||||
self.context, f_instance, uuids.network_id,
|
self.context, f_instance, uuids.network_id,
|
||||||
|
@ -5789,7 +5789,7 @@ class TestAPI(TestAPIBase):
|
|||||||
|
|
||||||
result = api.create_resource_requests(
|
result = api.create_resource_requests(
|
||||||
self.context, requested_networks, pci_requests)
|
self.context, requested_networks, pci_requests)
|
||||||
network_metadata, port_resource_requests = result
|
network_metadata, port_resource_requests, _ = result
|
||||||
|
|
||||||
self.assertFalse(mock_get_client.called)
|
self.assertFalse(mock_get_client.called)
|
||||||
self.assertIsNone(network_metadata)
|
self.assertIsNone(network_metadata)
|
||||||
@ -5816,7 +5816,7 @@ class TestAPI(TestAPIBase):
|
|||||||
|
|
||||||
result = api.create_resource_requests(
|
result = api.create_resource_requests(
|
||||||
self.context, requested_networks, pci_requests)
|
self.context, requested_networks, pci_requests)
|
||||||
network_metadata, port_resource_requests = result
|
network_metadata, port_resource_requests, _ = result
|
||||||
|
|
||||||
mock_get_physnet_tunneled_info.assert_not_called()
|
mock_get_physnet_tunneled_info.assert_not_called()
|
||||||
self.assertEqual(set(), network_metadata.physnets)
|
self.assertEqual(set(), network_metadata.physnets)
|
||||||
@ -5875,7 +5875,7 @@ class TestAPI(TestAPIBase):
|
|||||||
|
|
||||||
result = api.create_resource_requests(
|
result = api.create_resource_requests(
|
||||||
self.context, requested_networks, pci_requests)
|
self.context, requested_networks, pci_requests)
|
||||||
network_metadata, port_resource_requests = result
|
network_metadata, port_resource_requests, _ = result
|
||||||
|
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
mock.sentinel.request_group1,
|
mock.sentinel.request_group1,
|
||||||
@ -5982,7 +5982,7 @@ class TestAPI(TestAPIBase):
|
|||||||
result = self.api.create_resource_requests(
|
result = self.api.create_resource_requests(
|
||||||
self.context, requested_networks, pci_requests=None)
|
self.context, requested_networks, pci_requests=None)
|
||||||
|
|
||||||
network_metadata, port_resource_requests = result
|
network_metadata, port_resource_requests, _ = result
|
||||||
mock_get_dp_group.assert_called_once_with('smat_nic')
|
mock_get_dp_group.assert_called_once_with('smat_nic')
|
||||||
mock_get_physnet_tunneled_info.assert_called_once_with(
|
mock_get_physnet_tunneled_info.assert_called_once_with(
|
||||||
self.context, mock.ANY, 'netN')
|
self.context, mock.ANY, 'netN')
|
||||||
@ -6046,6 +6046,12 @@ class TestAPI(TestAPIBase):
|
|||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
neutronapi.API, '_has_extended_resource_request_extension',
|
neutronapi.API, '_has_extended_resource_request_extension',
|
||||||
return_value=True)
|
return_value=True)
|
||||||
|
@mock.patch(
|
||||||
|
'nova.objects.request_spec.RequestLevelParams.extend_with'
|
||||||
|
)
|
||||||
|
@mock.patch(
|
||||||
|
'nova.objects.request_spec.RequestLevelParams.from_port_request'
|
||||||
|
)
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'nova.objects.request_spec.RequestGroup.from_extended_port_request')
|
'nova.objects.request_spec.RequestGroup.from_extended_port_request')
|
||||||
@mock.patch.object(neutronapi.API, '_get_physnet_tunneled_info')
|
@mock.patch.object(neutronapi.API, '_get_physnet_tunneled_info')
|
||||||
@ -6054,6 +6060,7 @@ class TestAPI(TestAPIBase):
|
|||||||
def test_create_resource_request_extended(
|
def test_create_resource_request_extended(
|
||||||
self, getclient, mock_get_port_vnic_info,
|
self, getclient, mock_get_port_vnic_info,
|
||||||
mock_get_physnet_tunneled_info, mock_from_port_request,
|
mock_get_physnet_tunneled_info, mock_from_port_request,
|
||||||
|
mock_req_lvl_param, mock_extened_req_lvl_param,
|
||||||
mock_has_extended_res_req
|
mock_has_extended_res_req
|
||||||
):
|
):
|
||||||
requested_networks = objects.NetworkRequestList(
|
requested_networks = objects.NetworkRequestList(
|
||||||
@ -6088,10 +6095,15 @@ class TestAPI(TestAPIBase):
|
|||||||
mock.sentinel.port2_request_group2,
|
mock.sentinel.port2_request_group2,
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
# also both port1 and port2 has same subtree params
|
||||||
|
mock_req_lvl_param.side_effect = [
|
||||||
|
mock.sentinel.port1_req_lvl_param,
|
||||||
|
mock.sentinel.port2_req_lvl_param,
|
||||||
|
]
|
||||||
|
|
||||||
result = api.create_resource_requests(
|
result = api.create_resource_requests(
|
||||||
self.context, requested_networks, pci_requests)
|
self.context, requested_networks, pci_requests)
|
||||||
network_metadata, port_resource_requests = result
|
network_metadata, port_resource_requests, req_lvl_param = result
|
||||||
|
|
||||||
# assert that all the request groups are collected from both ports
|
# assert that all the request groups are collected from both ports
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -6102,6 +6114,23 @@ class TestAPI(TestAPIBase):
|
|||||||
mock.sentinel.port2_request_group2,
|
mock.sentinel.port2_request_group2,
|
||||||
],
|
],
|
||||||
port_resource_requests)
|
port_resource_requests)
|
||||||
|
# the same subtree requests are combined from the two ports
|
||||||
|
mock_req_lvl_param.assert_has_calls(
|
||||||
|
[
|
||||||
|
mock.call(
|
||||||
|
port_resource_request=mock.sentinel.resource_request1),
|
||||||
|
mock.call(
|
||||||
|
port_resource_request=mock.sentinel.resource_request2),
|
||||||
|
]
|
||||||
|
|
||||||
|
)
|
||||||
|
mock_extened_req_lvl_param.assert_has_calls(
|
||||||
|
[
|
||||||
|
mock.call(mock.sentinel.port1_req_lvl_param),
|
||||||
|
mock.call(mock.sentinel.port2_req_lvl_param),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.assertIsInstance(req_lvl_param, objects.RequestLevelParams)
|
||||||
|
|
||||||
mock_from_port_request.assert_has_calls([
|
mock_from_port_request.assert_has_calls([
|
||||||
mock.call(
|
mock.call(
|
||||||
|
@ -412,13 +412,17 @@ class _TestRequestSpecObject(object):
|
|||||||
filter_properties = {'fake': 'property'}
|
filter_properties = {'fake': 'property'}
|
||||||
|
|
||||||
rg = request_spec.RequestGroup()
|
rg = request_spec.RequestGroup()
|
||||||
|
req_lvl_params = request_spec.RequestLevelParams()
|
||||||
|
|
||||||
spec = objects.RequestSpec.from_components(ctxt, instance.uuid, image,
|
spec = objects.RequestSpec.from_components(
|
||||||
|
ctxt, instance.uuid, image,
|
||||||
flavor, instance.numa_topology, instance.pci_requests,
|
flavor, instance.numa_topology, instance.pci_requests,
|
||||||
filter_properties, None, instance.availability_zone,
|
filter_properties, None, instance.availability_zone,
|
||||||
port_resource_requests=[rg])
|
port_resource_requests=[rg], request_level_params=req_lvl_params
|
||||||
|
)
|
||||||
|
|
||||||
self.assertListEqual([rg], spec.requested_resources)
|
self.assertListEqual([rg], spec.requested_resources)
|
||||||
|
self.assertEqual(req_lvl_params, spec.request_level_params)
|
||||||
|
|
||||||
def test_get_scheduler_hint(self):
|
def test_get_scheduler_hint(self):
|
||||||
spec_obj = objects.RequestSpec(scheduler_hints={'foo_single': ['1'],
|
spec_obj = objects.RequestSpec(scheduler_hints={'foo_single': ['1'],
|
||||||
|
@ -1369,8 +1369,13 @@ class TestUtils(TestUtilsBase):
|
|||||||
"CUSTOM_VNIC_TYPE_NORMAL"]
|
"CUSTOM_VNIC_TYPE_NORMAL"]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
req_lvl_params = objects.RequestLevelParams(
|
||||||
|
root_required={"CUSTOM_BLUE"},
|
||||||
|
root_forbidden={"CUSTOM_DIRTY"},
|
||||||
|
same_subtree=[[uuids.group1]],
|
||||||
|
)
|
||||||
|
|
||||||
rr = utils.ResourceRequest.from_request_group(rg)
|
rr = utils.ResourceRequest.from_request_group(rg, req_lvl_params)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
f'limit=1000&'
|
f'limit=1000&'
|
||||||
@ -1379,7 +1384,9 @@ class TestUtils(TestUtilsBase):
|
|||||||
f'CUSTOM_VNIC_TYPE_NORMAL&'
|
f'CUSTOM_VNIC_TYPE_NORMAL&'
|
||||||
f'resources{uuids.port_id}='
|
f'resources{uuids.port_id}='
|
||||||
f'NET_BW_EGR_KILOBIT_PER_SEC%3A1000%2C'
|
f'NET_BW_EGR_KILOBIT_PER_SEC%3A1000%2C'
|
||||||
f'NET_BW_IGR_KILOBIT_PER_SEC%3A1000',
|
f'NET_BW_IGR_KILOBIT_PER_SEC%3A1000&'
|
||||||
|
f'root_required=CUSTOM_BLUE%2C%21CUSTOM_DIRTY&'
|
||||||
|
f'same_subtree={uuids.group1}',
|
||||||
rr.to_querystring())
|
rr.to_querystring())
|
||||||
|
|
||||||
def test_resource_request_add_group_inserts_the_group(self):
|
def test_resource_request_add_group_inserts_the_group(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user