def test_resource_request_from_image_props_append_request(self): props = {'trait:CUSTOM_MAGIC': 'required'} image_meta_props = objects.ImageMetaProps.from_dict(props) existing_req = utils.ResourceRequest() existing_req._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, required_traits={ 'HW_CPU_X86_AVX', }) # Build up a ResourceRequest from the inside to compare against. expected = utils.ResourceRequest() expected._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, required_traits={ # In addition to information already contained in the existing # resource request, we add the traits from image properties 'HW_CPU_X86_AVX', 'CUSTOM_MAGIC', }) self.assertResourceRequestsEqual( expected, utils.ResourceRequest.from_image_props(image_meta_props, req=existing_req))
def test_member_of_multiple_aggs_numbered(self): """Numbered resources with multiple member_of query params.""" agg1_uuid = uuidsentinel.agg1 agg2_uuid = uuidsentinel.agg2 agg3_uuid = uuidsentinel.agg3 agg4_uuid = uuidsentinel.agg4 qs = ('resources1=VCPU:2' '&member_of1=%s' '&member_of1=%s' '&resources2=VCPU:2' '&member_of2=in:%s,%s' % (agg1_uuid, agg2_uuid, agg3_uuid, agg4_uuid)) expected = [ pl.RequestGroup(resources={ 'VCPU': 2, }, member_of=[set([agg1_uuid]), set([agg2_uuid])]), pl.RequestGroup(resources={ 'VCPU': 2, }, member_of=[ set([agg3_uuid, agg4_uuid]), ]), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs, version=(1, 24)))
def test_resource_request_from_extra_specs_append_request(self): extra_specs = { 'resources:VCPU': '2', 'resources:MEMORY_MB': '2048', 'trait:HW_CPU_X86_AVX': 'required', } existing_req = utils.ResourceRequest() existing_req._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, required_traits={ 'CUSTOM_MAGIC', }) # Build up a ResourceRequest from the inside to compare against. expected = utils.ResourceRequest() expected._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, required_traits={ # In addition to traits from extra spec, we get traits from a # previous existing resource request 'HW_CPU_X86_AVX', 'CUSTOM_MAGIC', }) self.assertResourceRequestsEqual( expected, utils.ResourceRequest.from_extra_specs(extra_specs, req=existing_req))
def test_numbered_only(self): # Crazy ordering and nonsequential numbers don't matter. # It's okay to have a 'resources' without a 'required'. # A trait that's repeated shows up in both spots. qs = ('resources1=VCPU:2,MEMORY_MB:2048' '&required42=CUSTOM_GOLD' '&resources99=DISK_GB:5' '&resources42=CUSTOM_MAGIC:123' '&required1=HW_CPU_X86_VMX,CUSTOM_GOLD') expected = [ pl.RequestGroup( resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, required_traits={ 'HW_CPU_X86_VMX', 'CUSTOM_GOLD', }, ), pl.RequestGroup( resources={ 'CUSTOM_MAGIC': 123, }, required_traits={ 'CUSTOM_GOLD', }, ), pl.RequestGroup(resources={ 'DISK_GB': 5, }, ), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs))
def test_get_resources_from_request_spec_granular(self): flavor = objects.Flavor( vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=0, swap=0, extra_specs={ 'resources1:VGPU': '1', 'resources1:VGPU_DISPLAY_HEAD': '2', # Replace 'resources3:VCPU': '2', # Stay separate (don't sum) 'resources42:SRIOV_NET_VF': '1', 'resources24:SRIOV_NET_VF': '2', # Ignore 'some:bogus': 'value', # Custom in the unnumbered group (merge with DISK_GB) 'resources:CUSTOM_THING': '123', # Traits make it through 'trait3:CUSTOM_SILVER': 'required', 'trait3:CUSTOM_GOLD': 'required', # Delete standard 'resources86:MEMORY_MB': '0', # Standard and custom zeroes don't make it through 'resources:IPV4_ADDRESS': '0', 'resources:CUSTOM_FOO': '0', # Bogus values don't make it through 'resources1:MEMORY_MB': 'bogus' }) expected_resources = utils.ResourceRequest() expected_resources._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'DISK_GB': 10, 'CUSTOM_THING': 123, }) expected_resources._rg_by_id['1'] = plib.RequestGroup( resources={ 'VGPU': 1, 'VGPU_DISPLAY_HEAD': 2, }) expected_resources._rg_by_id['3'] = plib.RequestGroup( resources={ 'VCPU': 2, }, required_traits={ 'CUSTOM_GOLD', 'CUSTOM_SILVER', }) expected_resources._rg_by_id['24'] = plib.RequestGroup(resources={ 'SRIOV_NET_VF': 2, }, ) expected_resources._rg_by_id['42'] = plib.RequestGroup( resources={ 'SRIOV_NET_VF': 1, }) self._test_resources_from_request_spec(flavor, expected_resources)
def test_numbered_and_unnumbered(self): qs = ('resources=VCPU:3,MEMORY_MB:4096,DISK_GB:10' '&required=HW_CPU_X86_VMX,CUSTOM_MEM_FLASH,STORAGE_DISK_SSD' '&resources1=SRIOV_NET_VF:2' '&required1=CUSTOM_PHYSNET_PRIVATE' '&resources2=SRIOV_NET_VF:1,NET_INGRESS_BYTES_SEC:20000' ',NET_EGRESS_BYTES_SEC:10000' '&required2=CUSTOM_SWITCH_BIG,CUSTOM_PHYSNET_PROD' '&resources3=CUSTOM_MAGIC:123') expected = [ pl.RequestGroup( use_same_provider=False, resources={ 'VCPU': 3, 'MEMORY_MB': 4096, 'DISK_GB': 10, }, required_traits={ 'HW_CPU_X86_VMX', 'CUSTOM_MEM_FLASH', 'STORAGE_DISK_SSD', }, ), pl.RequestGroup( resources={ 'SRIOV_NET_VF': 2, }, required_traits={ 'CUSTOM_PHYSNET_PRIVATE', }, ), pl.RequestGroup( resources={ 'SRIOV_NET_VF': 1, 'NET_INGRESS_BYTES_SEC': 20000, 'NET_EGRESS_BYTES_SEC': 10000, }, required_traits={ 'CUSTOM_SWITCH_BIG', 'CUSTOM_PHYSNET_PROD', }, ), pl.RequestGroup( resources={ 'CUSTOM_MAGIC': 123, }, ), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs))
def test_forbidden_one_group(self): """When forbidden are allowed this will parse, but otherwise will indicate an invalid trait. """ qs = ('resources=VCPU:2,MEMORY_MB:2048' '&required=CUSTOM_PHYSNET1,!CUSTOM_SWITCH_BIG') expected_forbidden = [ pl.RequestGroup(use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, required_traits={ 'CUSTOM_PHYSNET1', }, forbidden_traits={ 'CUSTOM_SWITCH_BIG', }), ] expected_message = ( "Invalid query string parameters: Expected 'required' parameter " "value of the form: HW_CPU_X86_VMX,CUSTOM_MAGIC. Got: " "CUSTOM_PHYSNET1,!CUSTOM_SWITCH_BIG") exc = self.assertRaises(webob.exc.HTTPBadRequest, self.do_parse, qs) self.assertEqual(expected_message, six.text_type(exc)) self.assertRequestGroupsEqual(expected_forbidden, self.do_parse(qs, version=(1, 22)))
def test_all_sharing_providers(self): ss1 = self._create_provider('ss1', uuids.agg1) _set_traits(ss1, "MISC_SHARES_VIA_AGGREGATE") _add_inventory(ss1, fields.ResourceClass.IPV4_ADDRESS, 24) _add_inventory(ss1, fields.ResourceClass.SRIOV_NET_VF, 16) _add_inventory(ss1, fields.ResourceClass.DISK_GB, 1600) ss2 = self._create_provider('ss2', uuids.agg1) _set_traits(ss2, "MISC_SHARES_VIA_AGGREGATE") _add_inventory(ss2, fields.ResourceClass.DISK_GB, 1600) alloc_cands = self._get_allocation_candidates(requests=[ placement_lib.RequestGroup( use_same_provider=False, resources={ 'IPV4_ADDRESS': 2, 'SRIOV_NET_VF': 1, 'DISK_GB': 1500, } )] ) # We expect two candidates: one that gets all the resources from ss1; # and one that gets the DISK_GB from ss2 and the rest from ss1: expected = [ [('ss1', fields.ResourceClass.IPV4_ADDRESS, 2), ('ss1', fields.ResourceClass.SRIOV_NET_VF, 1), ('ss1', fields.ResourceClass.DISK_GB, 1500)], [('ss1', fields.ResourceClass.IPV4_ADDRESS, 2), ('ss1', fields.ResourceClass.SRIOV_NET_VF, 1), ('ss2', fields.ResourceClass.DISK_GB, 1500)], ] self._validate_allocation_requests(expected, alloc_cands)
def test_resources_from_request_spec_flavor_and_image_traits(self): image = self._get_image_with_traits() flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0, extra_specs={ 'trait:CUSTOM_FLAVOR_TRAIT': 'required', 'trait:CUSTOM_IMAGE_TRAIT2': 'required' }) expected_resources = utils.ResourceRequest() expected_resources._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 1, 'MEMORY_MB': 1024, 'DISK_GB': 15, }, required_traits={ # trait:CUSTOM_IMAGE_TRAIT2 is defined in both extra_specs and # image metadata. We get a union of both. 'CUSTOM_IMAGE_TRAIT1', 'CUSTOM_IMAGE_TRAIT2', 'CUSTOM_FLAVOR_TRAIT', }) self._test_resources_from_request_spec(expected_resources, flavor, image)
def test_unknown_traits(self): missing = set(['UNKNOWN_TRAIT']) requests = [placement_lib.RequestGroup( use_same_provider=False, resources=self.requested_resources, required_traits=missing)] self.assertRaises(ValueError, rp_obj.AllocationCandidates.get_by_requests, self.ctx, requests)
def test_resource_request_from_image_props(self): props = {'trait:CUSTOM_TRUSTED': 'required'} image_meta_props = objects.ImageMetaProps.from_dict(props) # Build up a ResourceRequest from the inside to compare against. expected = utils.ResourceRequest() expected._rg_by_id[None] = plib.RequestGroup(use_same_provider=False, required_traits={ 'CUSTOM_TRUSTED', }) self.assertResourceRequestsEqual( expected, utils.ResourceRequest.from_image_props(image_meta_props))
def test_common_rc_traits_split(self): """Validate filters when traits are split across cn and shared RPs.""" # NOTE(efried): This test case only applies to the scenario where we're # requesting resources via the RequestGroup where # use_same_provider=False cn = self._create_provider('cn', uuids.agg1) _add_inventory(cn, fields.ResourceClass.VCPU, 24) _add_inventory(cn, fields.ResourceClass.MEMORY_MB, 2048) _add_inventory(cn, fields.ResourceClass.DISK_GB, 1600) # The compute node's disk is SSD _set_traits(cn, 'HW_CPU_X86_SSE', 'STORAGE_DISK_SSD') ss = self._create_provider('ss', uuids.agg1) _add_inventory(ss, fields.ResourceClass.DISK_GB, 1600) # The shared storage's disk is RAID _set_traits(ss, 'MISC_SHARES_VIA_AGGREGATE', 'CUSTOM_RAID') alloc_cands = rp_obj.AllocationCandidates.get_by_requests( self.ctx, [ placement_lib.RequestGroup( use_same_provider=False, resources=self.requested_resources, required_traits=set(['HW_CPU_X86_SSE', 'STORAGE_DISK_SSD', 'CUSTOM_RAID']) ) ] ) # TODO(efried): Okay, bear with me here: # TODO(efried): Bug #1724633: we'd *like* to get no candidates, because # there's no single DISK_GB resource with both STORAGE_DISK_SSD and # CUSTOM_RAID traits. So this is the ideal expected value: # expected = [] # TODO(efried): But under the design as currently conceived, we would # get the cn + ss candidate, because that combination satisfies both # traits: # expected = [ # [('cn', fields.ResourceClass.VCPU, 1), # ('cn', fields.ResourceClass.MEMORY_MB, 64), # ('ss', fields.ResourceClass.DISK_GB, 1500)], # ] # TODO(efried): However, until https://review.openstack.org/#/c/479766/ # lands, the traits are ignored, so this behaves just like # test_common_rc above, which is subject to bug #1724613: expected = [ [('cn', fields.ResourceClass.VCPU, 1), ('cn', fields.ResourceClass.MEMORY_MB, 64), ('cn', fields.ResourceClass.DISK_GB, 1500)], ] self._validate_allocation_requests(expected, alloc_cands)
def test_forbidden_separate_groups_no_conflict(self): qs = ('resources1=CUSTOM_MAGIC:1&required1=CUSTOM_PHYSNET1' '&resources2=CUSTOM_MAGIC:1&required2=!CUSTOM_PHYSNET1') expected = [ pl.RequestGroup(use_same_provider=True, resources={ 'CUSTOM_MAGIC': 1, }, required_traits={ 'CUSTOM_PHYSNET1', }), pl.RequestGroup(use_same_provider=True, resources={ 'CUSTOM_MAGIC': 1, }, forbidden_traits={ 'CUSTOM_PHYSNET1', }), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs, version=(1, 22)))
def test_member_of_single_agg(self): """Unnumbered resources with one member_of query param.""" agg1_uuid = uuidsentinel.agg1 qs = ('resources=VCPU:2,MEMORY_MB:2048' '&member_of=%s' % agg1_uuid) expected = [ pl.RequestGroup(use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, member_of=[set([agg1_uuid])]), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs))
def test_resources_from_request_spec_with_no_disk(self): flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=0, ephemeral_gb=0, swap=0) expected_resources = utils.ResourceRequest() expected_resources._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 1, 'MEMORY_MB': 1024, }) self._test_resources_from_request_spec(flavor, expected_resources)
def test_all_sharing_providers(self): ss1 = self._create_provider('ss1', uuids.agg1) _set_traits(ss1, "MISC_SHARES_VIA_AGGREGATE") _add_inventory(ss1, fields.ResourceClass.IPV4_ADDRESS, 24) _add_inventory(ss1, fields.ResourceClass.SRIOV_NET_VF, 16) _add_inventory(ss1, fields.ResourceClass.DISK_GB, 1600) ss2 = self._create_provider('ss2', uuids.agg1) _set_traits(ss2, "MISC_SHARES_VIA_AGGREGATE") _add_inventory(ss2, fields.ResourceClass.DISK_GB, 1600) alloc_cands = self._get_allocation_candidates(requests=[ placement_lib.RequestGroup( use_same_provider=False, resources={ 'IPV4_ADDRESS': 2, 'SRIOV_NET_VF': 1, 'DISK_GB': 1500, } )] ) # TODO(efried): Bug https://bugs.launchpad.net/nova/+bug/1730730 # We expect two candidates: one that gets all the resources from ss1; # and one that gets the DISK_GB from ss2 and the rest from ss1: # expected = [ # [('ss1', fields.ResourceClass.IPV4_ADDRESS, 2), # ('ss1', fields.ResourceClass.SRIOV_NET_VF, 1), # ('ss1', fields.ResourceClass.DISK_GB, 1500)], # [('ss1', fields.ResourceClass.IPV4_ADDRESS, 2), # ('ss1', fields.ResourceClass.SRIOV_NET_VF, 1), # ('ss2', fields.ResourceClass.DISK_GB, 1500)], # ] # But here's what we're actually seeing: # One with all the resources coming from ss1 expected = [ [('ss1', fields.ResourceClass.IPV4_ADDRESS, 2), ('ss1', fields.ResourceClass.SRIOV_NET_VF, 1), ('ss1', fields.ResourceClass.DISK_GB, 1500)], # One with the DISK_GB coming from ss2 and IPV4_ADDRESS coming from ss1 [('ss1', fields.ResourceClass.IPV4_ADDRESS, 2), ('ss2', fields.ResourceClass.DISK_GB, 1500)], # One with the DISK_GB coming from ss2 and SRIOV_NET_VF coming from ss1 [('ss1', fields.ResourceClass.SRIOV_NET_VF, 1), ('ss2', fields.ResourceClass.DISK_GB, 1500)], # Of special brokenness are those last two, which don't even have all # of the requested resources: ] self._validate_allocation_requests(expected, alloc_cands)
def test_forbidden_two_groups(self): qs = ('resources=VCPU:2,MEMORY_MB:2048&resources1=CUSTOM_MAGIC:1' '&required1=CUSTOM_PHYSNET1,!CUSTOM_PHYSNET2') expected = [ pl.RequestGroup( use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, ), pl.RequestGroup(resources={ 'CUSTOM_MAGIC': 1, }, required_traits={ 'CUSTOM_PHYSNET1', }, forbidden_traits={ 'CUSTOM_PHYSNET2', }), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs, version=(1, 22)))
def test_unnumbered_resources_only(self): """Validate the bit that can be used for 1.10 and earlier.""" qs = 'resources=VCPU:2,MEMORY_MB:2048,DISK_GB:5,CUSTOM_MAGIC:123' expected = [ pl.RequestGroup( use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, 'DISK_GB': 5, 'CUSTOM_MAGIC': 123, }, ), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs))
def test_resources_from_request_spec_flavor_only(self): flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0) expected_resources = utils.ResourceRequest() expected_resources._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 1, 'MEMORY_MB': 1024, 'DISK_GB': 15, }) self._test_resources_from_request_spec(expected_resources, flavor)
def test_get_resources_from_request_spec_remove_flavor_amounts(self): flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0, extra_specs={ "resources:VCPU": 0, "resources:DISK_GB": 0 }) expected_resources = utils.ResourceRequest() expected_resources._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ "MEMORY_MB": 1024, }) self._test_resources_from_request_spec(flavor, expected_resources)
def test_get_resources_from_request_spec_custom_resource_class(self): flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0, extra_specs={"resources:CUSTOM_TEST_CLASS": 1}) expected_resources = utils.ResourceRequest() expected_resources._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ "VCPU": 1, "MEMORY_MB": 1024, "DISK_GB": 15, "CUSTOM_TEST_CLASS": 1, }) self._test_resources_from_request_spec(flavor, expected_resources)
def test_stringification(self): grp = pl.RequestGroup( resources={ 'VCPU': 2, 'CUSTOM_MAGIC': 1, }, required_traits={ 'CUSTOM_VNIC_TYPE_NORMAL', 'CUSTOM_PHYSNET1', }, forbidden_traits={'CUSTOM_PHYSNET2', 'CUSTOM_VNIC_TYPE_DIRECT'}, member_of=[['baz'], ['foo', 'bar']]) self.assertEqual( 'RequestGroup(use_same_provider=True, ' 'resources={CUSTOM_MAGIC:1, VCPU:2}, ' 'traits=[CUSTOM_PHYSNET1, CUSTOM_VNIC_TYPE_NORMAL, ' '!CUSTOM_PHYSNET2, !CUSTOM_VNIC_TYPE_DIRECT], ' 'aggregates=[[baz], [foo, bar]])', str(grp))
def test_unnumbered_only(self): """Unnumbered resources & traits - no numbered groupings.""" qs = ('resources=VCPU:2,MEMORY_MB:2048' '&required=HW_CPU_X86_VMX,CUSTOM_GOLD') expected = [ pl.RequestGroup( use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, required_traits={ 'HW_CPU_X86_VMX', 'CUSTOM_GOLD', }, ), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs))
def test_member_of_multiple_aggs(self): """Unnumbered resources with multiple member_of query params.""" agg1_uuid = uuidsentinel.agg1 agg2_uuid = uuidsentinel.agg2 qs = ('resources=VCPU:2,MEMORY_MB:2048' '&member_of=%s' '&member_of=%s' % (agg1_uuid, agg2_uuid)) expected = [ pl.RequestGroup(use_same_provider=False, resources={ 'VCPU': 2, 'MEMORY_MB': 2048, }, member_of=[set([agg1_uuid]), set([agg2_uuid])]), ] self.assertRequestGroupsEqual(expected, self.do_parse(qs, version=(1, 24)))
def test_process_no_force_hosts_or_force_nodes(self): flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=15, ephemeral_gb=0, swap=0) expected = utils.ResourceRequest() expected._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 1, 'MEMORY_MB': 1024, 'DISK_GB': 15, }, ) rr = self._test_resources_from_request_spec(expected, flavor) expected_querystring = ( 'limit=1000&' 'resources=DISK_GB%3A15%2CMEMORY_MB%3A1024%2CVCPU%3A1') self.assertEqual(expected_querystring, rr.to_querystring())
def test_get_resources_from_request_spec_vgpu(self): flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=0, swap=0, extra_specs={ "resources:VGPU": 1, "resources:VGPU_DISPLAY_HEAD": 1 }) expected_resources = utils.ResourceRequest() expected_resources._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ "VCPU": 1, "MEMORY_MB": 1024, "DISK_GB": 10, "VGPU": 1, "VGPU_DISPLAY_HEAD": 1, }) self._test_resources_from_request_spec(flavor, expected_resources)
def test_process_use_force_hosts(self): flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=15, ephemeral_gb=0, swap=0) fake_spec = objects.RequestSpec(flavor=flavor, force_hosts=['test']) expected = utils.ResourceRequest() expected._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 1, 'MEMORY_MB': 1024, 'DISK_GB': 15, }, ) expected._limit = None resources = utils.resources_from_request_spec(fake_spec) self.assertResourceRequestsEqual(expected, resources) expected_querystring = ( 'resources=DISK_GB%3A15%2CMEMORY_MB%3A1024%2CVCPU%3A1') self.assertEqual(expected_querystring, resources.to_querystring())
def test_resources_from_request_spec_no_limit_based_on_hint(self, hints): """Tests that there is no limit applied to the GET /allocation_candidates query string if a given scheduler hint is in the request spec. """ flavor = objects.Flavor(vcpus=1, memory_mb=1024, root_gb=15, ephemeral_gb=0, swap=0) fake_spec = objects.RequestSpec(flavor=flavor, scheduler_hints=hints) expected = utils.ResourceRequest() expected._rg_by_id[None] = plib.RequestGroup( use_same_provider=False, resources={ 'VCPU': 1, 'MEMORY_MB': 1024, 'DISK_GB': 15, }, ) expected._limit = None resources = utils.resources_from_request_spec(fake_spec) self.assertResourceRequestsEqual(expected, resources)
def get_request_group(self, ident): if ident not in self._rg_by_id: rq_grp = placement_lib.RequestGroup(use_same_provider=bool(ident)) self._rg_by_id[ident] = rq_grp return self._rg_by_id[ident]
def get_request_group(suffix): if suffix not in by_suffix: rq_grp = placement_lib.RequestGroup(use_same_provider=bool(suffix)) by_suffix[suffix] = rq_grp return by_suffix[suffix]