placement/placement/tests/functional/gabbits/allocation-candidates-root-...

292 lines
14 KiB
YAML

# Tests of allocation candidates API with root_required
fixtures:
- NUMANetworkFixture
defaults:
request_headers:
x-auth-token: admin
accept: application/json
openstack-api-version: placement 1.35
tests:
- name: root_required before microversion
GET: /allocation_candidates?resources=VCPU:1&root_required=HW_CPU_X86_AVX2
request_headers:
openstack-api-version: placement 1.34
status: 400
response_strings:
- Invalid query string parameters
- "'root_required' does not match any of the regexes"
- name: conflicting required and forbidden
GET: /allocation_candidates?resources=VCPU:1&root_required=HW_CPU_X86_AVX2,HW_CPU_X86_SSE,!HW_CPU_X86_AVX2
status: 400
response_strings:
- "Conflicting required and forbidden traits found in root_required: HW_CPU_X86_AVX2"
response_json_paths:
errors[0].code: placement.query.bad_value
- name: nonexistent required
GET: /allocation_candidates?resources=VCPU:1&root_required=CUSTOM_NO_EXIST,HW_CPU_X86_SSE,!HW_CPU_X86_AVX
status: 400
response_strings:
- "No such trait(s): CUSTOM_NO_EXIST"
- name: nonexistent forbidden
GET: /allocation_candidates?resources=VCPU:1&root_required=!CUSTOM_NO_EXIST,HW_CPU_X86_SSE,!HW_CPU_X86_AVX
status: 400
response_strings:
- "No such trait(s): CUSTOM_NO_EXIST"
- name: multiple root_required is an error
GET: /allocation_candidates?resources=VCPU:1&root_required=MISC_SHARES_VIA_AGGREGATE&root_required=!HW_NUMA_ROOT
status: 400
response_strings:
- Query parameter 'root_required' may be specified only once.
response_json_paths:
errors[0].code: placement.query.duplicate_key
- name: no hits for a required trait that is on children in one tree and absent from the other
GET: /allocation_candidates?resources=VCPU:1&root_required=HW_NUMA_ROOT
status: 200
response_json_paths:
# No root has HW_NUMA_ROOT
$.allocation_requests.`len`: 0
- name: required trait on a sharing root
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=MISC_SHARES_VIA_AGGREGATE
status: 200
response_json_paths:
# MISC_SHARES is on the sharing root, but not on any of the anchor roots
$.allocation_requests.`len`: 0
- name: root_required trait on children
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=HW_NUMA_ROOT
status: 200
response_json_paths:
# HW_NUMA_ROOT is on child providers, not on any root
$.allocation_requests.`len`: 0
- name: required trait not on any provider
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=HW_CPU_X86_AVX2
status: 200
response_json_paths:
# HW_CPU_X86_AVX2 isn't anywhere in the env.
$.allocation_requests.`len`: 0
- name: limit to multiattach-capable unsuffixed no sharing
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024&root_required=COMPUTE_VOLUME_MULTI_ATTACH
status: 200
response_json_paths:
# We only get results from cn1 because only it has MULTI_ATTACH
# We get candidates where VCPU and MEMORY_MB are provided by the same or
# alternate NUMA roots.
$.allocation_requests.`len`: 4
$.allocation_requests..allocations["$ENVIRON['NUMA0_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['NUMA0_UUID']"].resources.MEMORY_MB: [1024, 1024]
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.MEMORY_MB: [1024, 1024]
- name: limit to multiattach-capable separate granular no isolate no sharing
GET: /allocation_candidates?resources1=VCPU:1&resources2=MEMORY_MB:1024&group_policy=none&root_required=COMPUTE_VOLUME_MULTI_ATTACH
status: 200
response_json_paths:
# Same as above
$.allocation_requests.`len`: 4
# Prove we didn't break provider summaries
$.provider_summaries["$ENVIRON['NUMA0_UUID']"].resources[VCPU][capacity]: 4
$.provider_summaries["$ENVIRON['NUMA1_UUID']"].resources[MEMORY_MB][capacity]: 2048
- name: limit to multiattach-capable separate granular isolate no sharing
GET: /allocation_candidates?resources1=VCPU:1&resources2=MEMORY_MB:1024&group_policy=isolate&root_required=COMPUTE_VOLUME_MULTI_ATTACH
status: 200
response_json_paths:
# Now we (perhaps unrealistically) only get candidates where VCPU and
# MEMORY_MB are on alternate NUMA roots.
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['NUMA0_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['NUMA0_UUID']"].resources.MEMORY_MB: 1024
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.MEMORY_MB: 1024
- name: limit to multiattach-capable unsuffixed sharing
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=COMPUTE_VOLUME_MULTI_ATTACH
status: 200
response_json_paths:
# We only get results from cn1 because only it has MULTI_ATTACH
# We get candidates where VCPU and MEMORY_MB are provided by the same or
# alternate NUMA roots. DISK_GB is always provided by the sharing provider.
$.allocation_requests.`len`: 4
$.provider_summaries["$ENVIRON['NUMA0_UUID']"].traits:
- HW_NUMA_ROOT
$.provider_summaries["$ENVIRON['NUMA1_UUID']"].traits:
- HW_NUMA_ROOT
- CUSTOM_FOO
- name: limit to multiattach-capable granular sharing
GET: /allocation_candidates?resources1=VCPU:1,MEMORY_MB:1024&resources2=DISK_GB:100&&group_policy=none&root_required=COMPUTE_VOLUME_MULTI_ATTACH
status: 200
response_json_paths:
# We only get results from cn1 because only it has MULTI_ATTACH
# We only get candidates where VCPU and MEMORY_MB are provided by the same
# NUMA root, because requested in the same suffixed group. DISK_GB is
# always provided by the sharing provider.
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['NUMA0_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['NUMA0_UUID']"].resources.MEMORY_MB: 1024
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.MEMORY_MB: 1024
- name: trait exists on root and child in separate trees case 1 unsuffixed required
GET: /allocation_candidates?resources=VCPU:1,DISK_GB:100&required=CUSTOM_FOO
status: 200
response_json_paths:
# We get a candidates from cn2 and cn2+ss1 because cn2 has all the
# resources and the trait.
# We get a candidate from numa1+ss1 because (even in the unsuffixed group)
# regular `required` is tied to the resource in that group.
$.allocation_requests.`len`: 3
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: [100, 100]
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 100
- name: trait exists on root and child in separate trees case 2 unsuffixed root_required
GET: /allocation_candidates?resources=VCPU:1,DISK_GB:100&root_required=CUSTOM_FOO
status: 200
response_json_paths:
# We only get candidates from cn2 and cn2+ss1 because only cn2 has FOO on
# the root
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: 100
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 100
- name: trait exists on root and child in separate trees case 3 suffixed required
GET: /allocation_candidates?resources1=VCPU:1&required1=CUSTOM_FOO&resources2=DISK_GB:100&group_policy=none
status: 200
response_json_paths:
# We get a candidates from cn2 because has all the resources and the trait;
# and from cn2+ss1 because group_policy=none and the required trait is on
# the group with the VCPU.
# We get a candidate from numa1+ss1 because the required trait is on the
# group with the VCPU.
$.allocation_requests.`len`: 3
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: [100, 100]
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 100
- name: trait exists on root and child in separate trees case 4 suffixed root_required
GET: /allocation_candidates?resources1=VCPU:1&resources2=DISK_GB:100&group_policy=none&root_required=CUSTOM_FOO
status: 200
response_json_paths:
# We only get candidates from cn2 and cn2+ss1 because only cn2 has FOO on
# the root
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: 100
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 100
- name: no filtering for a forbidden trait that is on children in one tree and absent from the other
GET: /allocation_candidates?resources=VCPU:3&root_required=!HW_NUMA_ROOT
status: 200
response_json_paths:
# No root has HW_NUMA_ROOT, so we hit all providers of VCPU with adequate capacity
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: 3
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: 3
- name: forbidden trait on a sharing root
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=!MISC_SHARES_VIA_AGGREGATE
status: 200
response_json_paths:
# This does not filter out candidates including the sharing provider, of
# which there are five (four from the combinations of VCPU+MEMORY_MB on cn1
# because non-isolated; one using VCPU+MEMORY_MB from cn2). The sixth is
# where cn2 provides all the resources.
$.allocation_requests.`len`: 6
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: [100, 100, 100, 100, 100]
- name: combine required with irrelevant forbidden
# This time the irrelevant forbidden is on a child provider
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=CUSTOM_FOO,!HW_NUMA_ROOT
status: 200
response_json_paths:
# This is as above, but filtered to the candidates involving cn2, which has
# CUSTOM_FOO on the root.
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.MEMORY_MB: [1024, 1024]
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 100
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: 100
- name: redundant required and forbidden
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=CUSTOM_FOO,!COMPUTE_VOLUME_MULTI_ATTACH
status: 200
response_json_paths:
# Same result as above. The forbidden multi-attach and the required foo are
# both doing the same thing.
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: [1, 1]
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.MEMORY_MB: [1024, 1024]
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.DISK_GB: 100
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: 100
- name: forbiddens cancel each other
GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&root_required=!CUSTOM_FOO,!COMPUTE_VOLUME_MULTI_ATTACH
status: 200
response_json_paths:
# !foo gets rid of cn2; !multi-attach gets rid of cn1.
$.allocation_requests.`len`: 0
- name: isolate foo granular sharing
GET: /allocation_candidates?resources1=VCPU:1,MEMORY_MB:1024&resources2=DISK_GB:100&&group_policy=none&root_required=!CUSTOM_FOO
status: 200
response_json_paths:
# We only get results from cn1 because cn2 has the forbidden foo trait.
# We only get candidates where VCPU and MEMORY_MB are provided by the same
# NUMA root, because requested in the same suffixed group. DISK_GB is
# always provided by the sharing provider.
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['NUMA0_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: 1
$.allocation_requests..allocations["$ENVIRON['SS1_UUID']"].resources.DISK_GB: [100, 100]
- name: unsuffixed required and root_required same trait
GET: /allocation_candidates?resources=VCPU:1&required=CUSTOM_FOO&root_required=CUSTOM_FOO
status: 200
response_json_paths:
# required=FOO would have limited us to getting VCPU from numa1 and cn2
# BUT root_required=FOO should further restrict us to just cn2
$.allocation_requests.`len`: 1
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: 1
- name: granular required and root_required same trait
GET: /allocation_candidates?resources1=VCPU:1&required1=CUSTOM_FOO&root_required=CUSTOM_FOO
status: 200
response_json_paths:
# same as above
$.allocation_requests.`len`: 1
$.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: 1
- name: required positive and root_required negative same trait
GET: /allocation_candidates?resources1=VCPU:1&required1=CUSTOM_FOO&root_required=!CUSTOM_FOO
status: 200
response_json_paths:
# Both numa1 and cn2 match required1=FOO, but since we're forbidding FOO on
# the root, we should only get numa1
$.allocation_requests.`len`: 1
$.allocation_requests..allocations["$ENVIRON['NUMA1_UUID']"].resources.VCPU: 1
- name: required negative and root_required positive same trait
GET: /allocation_candidates?resources1=VCPU:1&required1=!CUSTOM_FOO&root_required=CUSTOM_FOO
status: 200
response_json_paths:
# The only provider of VCPU that doesn't have FOO is numa0. But numa0 is on
# cn1, which doesn't have the required FOO on the root.
$.allocation_requests.`len`: 0