From 9de03e1b17ddc202532757bb221ee81f02f89bbe Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Mon, 17 Jun 2019 11:16:34 +0100 Subject: [PATCH] Uniquify allocation mappings When creating the allocation mappings output, use a set() not a list() so that any single resource provider only shows up once. The initial implementation (at Ie78ed7e050416d4ccb62697ba608131038bb4303) allowed a provider to show up multiple times if it contributed more than one class of inventory. This slipped through because of a missing test. A test that covers the issue is added.k Change-Id: If00f01534b7d0ec84ca8abaeef5b90a16cbcffc3 --- placement/handlers/allocation_candidate.py | 4 +-- .../allocation-candidates-mappings-numa.yaml | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/placement/handlers/allocation_candidate.py b/placement/handlers/allocation_candidate.py index 3bccf9dfd..4f439ed0f 100644 --- a/placement/handlers/allocation_candidate.py +++ b/placement/handlers/allocation_candidate.py @@ -70,10 +70,10 @@ def _transform_allocation_requests_dict(alloc_reqs, want_version): rp_resources = collections.defaultdict(lambda: dict(resources={})) # A dict to map request group suffixes to the providers that provided # solutions to that group. - mappings = collections.defaultdict(list) + mappings = collections.defaultdict(set) for rr in ar.resource_requests: suffix = rr.suffix - mappings[suffix].append(rr.resource_provider.uuid) + mappings[suffix].add(rr.resource_provider.uuid) res_dict = rp_resources[rr.resource_provider.uuid]['resources'] res_dict[rr.resource_class] = rr.amount result = dict(allocations=rp_resources) diff --git a/placement/tests/functional/gabbits/allocation-candidates-mappings-numa.yaml b/placement/tests/functional/gabbits/allocation-candidates-mappings-numa.yaml index 88ca011ae..aa40843d8 100644 --- a/placement/tests/functional/gabbits/allocation-candidates-mappings-numa.yaml +++ b/placement/tests/functional/gabbits/allocation-candidates-mappings-numa.yaml @@ -85,3 +85,28 @@ tests: $.allocation_requests[0].mappings[''][0]: /$ENVIRON['NUMA0_UUID']|$ENVIRON['NUMA1_UUID']/ $.allocation_requests[0].mappings._NET1[0]: $ENVIRON['ESN1_UUID'] $.allocation_requests[0].mappings._NET2[0]: $ENVIRON['ESN2_UUID'] + +# Confirm that a resource provider which providers two different classes +# of inventory only shows up in a mapping for any suffix once. +- name: granular two resources on one suffix + GET: /allocation_candidates + query_parameters: + required_NET1: CUSTOM_PHYSNET1 + resources_NET1: NET_BW_EGR_KILOBIT_PER_SEC:10 + required_NET2: CUSTOM_PHYSNET2 + resources_NET2: NET_BW_EGR_KILOBIT_PER_SEC:20 + resources_COMPUTE: VCPU:1,MEMORY_MB:1024 + group_policy: isolate + response_json_paths: + # two candidates, one for each NUMA node providing _COMPUTE + $.allocation_requests.`len`: 2 + $.provider_summaries.`len`: 12 + # 3 members of the mappings dict + $.allocation_requests[0].mappings.`len`: 3 + # One member of each list in the mappings + $.allocation_requests[0].mappings._COMPUTE.`len`: 1 + $.allocation_requests[0].mappings._NET1.`len`: 1 + $.allocation_requests[0].mappings._NET2.`len`: 1 + $.allocation_requests[0].mappings._COMPUTE[0]: /$ENVIRON['NUMA0_UUID']|$ENVIRON['NUMA1_UUID']/ + $.allocation_requests[0].mappings._NET1[0]: $ENVIRON['ESN1_UUID'] + $.allocation_requests[0].mappings._NET2[0]: $ENVIRON['ESN2_UUID']