292 lines
14 KiB
YAML
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
|