placement/placement/tests/functional/gabbits/granular.yaml

545 lines
22 KiB
YAML

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Tests for granular resource requests
fixtures:
# See the layout diagram in this fixture's docstring in ../fixtures.py
- GranularFixture
defaults:
request_headers:
x-auth-token: admin
content-type: application/json
accept: application/json
openstack-api-version: placement 1.25
tests:
- name: different groups hit with group_policy=none
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1
resources2: MEMORY_MB:1024
group_policy: none
status: 200
response_json_paths:
$.allocation_requests.`len`: 3
$.provider_summaries.`len`: 3
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources:
VCPU: 1
MEMORY_MB: 1024
$.allocation_requests..allocations["$ENVIRON['CN_MIDDLE']"].resources:
VCPU: 1
MEMORY_MB: 1024
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources:
VCPU: 1
MEMORY_MB: 1024
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources:
VCPU:
capacity: 8
used: 0
MEMORY_MB:
capacity: 4096
used: 0
$.provider_summaries["$ENVIRON['CN_MIDDLE']"].resources:
VCPU:
capacity: 8
used: 0
MEMORY_MB:
capacity: 4096
used: 0
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources:
VCPU:
capacity: 8
used: 0
MEMORY_MB:
capacity: 4096
used: 0
- name: different groups miss with group_policy=isolate
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1
resources2: MEMORY_MB:1024
group_policy: isolate
status: 200
response_json_paths:
# We asked for VCPU and MEMORY_MB to be satisfied by *different*
# providers, because they're in separate numbered request groups and
# group_policy=isolate. Since there are no sharing providers of these
# resources, we get no results.
$.allocation_requests.`len`: 0
$.provider_summaries.`len`: 0
- name: multiple group_policy picks the first one
# NOTE(efried): gabbi query_parameters doesn't preserve param order
GET: /allocation_candidates?resources1=VCPU:1&resources2=MEMORY_MB:1024&group_policy=isolate&group_policy=none
status: 200
response_json_paths:
$.allocation_requests.`len`: 0
$.provider_summaries.`len`: 0
- name: resources combine
GET: /allocation_candidates
query_parameters:
resources: VCPU:3,MEMORY_MB:512
resources1: VCPU:1,MEMORY_MB:1024
resources2: VCPU:2
group_policy: none
status: 200
response_json_paths:
$.allocation_requests.`len`: 3
$.provider_summaries.`len`: 3
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources:
VCPU: 6
MEMORY_MB: 1536
$.allocation_requests..allocations["$ENVIRON['CN_MIDDLE']"].resources:
VCPU: 6
MEMORY_MB: 1536
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources:
VCPU: 6
MEMORY_MB: 1536
- name: group policy not required with only one numbered group
GET: /allocation_candidates?resources=VCPU:1&resources1=MEMORY_MB:2048
status: 200
response_json_paths:
$.allocation_requests.`len`: 3
$.provider_summaries.`len`: 3
- name: disk sharing isolated
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1,MEMORY_MB:1024
resources2: DISK_GB:100
group_policy: isolate
status: 200
response_json_paths:
# Here we've asked for VCPU and MEMORY_MB to be satisfied by the same
# provider - all three of our non-sharing providers can do that - and
# the DISK_GB to be satisfied by a *different* provider than the VCPU and
# MEMORY_MB. So we'll get all permutations where cn_* provide VCPU and
# MEMORY_MB and shr_disk_* provide the DISK_GB; but *no* results where
# DISK_GB is provided by the cn_*s themselves.
$.allocation_requests.`len`: 5
$.provider_summaries.`len`: 5
- name: disk sharing non-isolated
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1,MEMORY_MB:1024
resources2: DISK_GB:100
group_policy: none
status: 200
response_json_paths:
$.allocation_requests.`len`: 7
$.provider_summaries.`len`: 5
- name: disk alone
GET: /allocation_candidates
query_parameters:
resources1: DISK_GB:800
status: 200
response_json_paths:
$.allocation_requests.`len`: 2
$.provider_summaries.`len`: 2
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB]: 800
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB]: 800
- name: disk alone non-granular
GET: /allocation_candidates
query_parameters:
resources: DISK_GB:800
status: 200
response_json_paths:
$.allocation_requests.`len`: 2
$.provider_summaries.`len`: 2
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB]: 800
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB]: 800
- name: isolated ssd
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1,MEMORY_MB:1024
resources2: DISK_GB:100
required2: CUSTOM_DISK_SSD
group_policy: isolate
status: 200
response_json_paths:
# We get candidates [cn_left + shr_disk_1] and [cn_middle + shr_disk_1]
# We don't get [cn_right + shr_disk_1] because they're not associated via aggregate.
# We don't get [cn_left/middle + shr_disk_2] because shr_disk_2 doesn't have the SSD trait
# We don't get [cn_left] or [cn_right] even though they have SSD disk because we asked to isolate
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources:
VCPU: 1
MEMORY_MB: 1024
$.allocation_requests..allocations["$ENVIRON['CN_MIDDLE']"].resources:
VCPU: 1
MEMORY_MB: 1024
# shr_disk_1 satisfies the disk for both allocation requests
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB]: [100, 100]
$.provider_summaries.`len`: 3
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources:
VCPU:
capacity: 8
used: 0
MEMORY_MB:
capacity: 4096
used: 0
DISK_GB:
capacity: 500
used: 0
$.provider_summaries["$ENVIRON['CN_MIDDLE']"].resources:
VCPU:
capacity: 8
used: 0
MEMORY_MB:
capacity: 4096
used: 0
$.provider_summaries["$ENVIRON['SHR_DISK_1']"].resources:
DISK_GB:
capacity: 1000
used: 0
- name: no isolation, forbid ssd
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1
resources2: DISK_GB:100
required2: "!CUSTOM_DISK_SSD"
group_policy: none
status: 200
response_json_paths:
# The permutations we *don't* get are:
# cn_right by itself because it has SSD
# - anything involving shr_disk_1 because it has SSD
$.allocation_requests.`len`: 4
# We get two allocation requests involving cn_left - one where it
# satisfies the disk itself and one where shr_disk_2 provides it
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[VCPU]: [1, 1]
# We get one for [cn_middle + shr_disk_2] - it doesn't have disk to provide for itself
$.allocation_requests..allocations["$ENVIRON['CN_MIDDLE']"].resources[VCPU]: 1
# We get one for [cn_right + shr_disk_2] - cn_right can't provide its own
# disk due to the forbidden SSD trait.
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[VCPU]: 1
# shr_disk_2 satisfies the disk for three out of the four allocation
# requests (all except the one where cn_left provides for itself)
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB]: [100, 100, 100]
# Validate that we got the correct four providers in the summaries
$.provider_summaries.`len`: 4
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_MIDDLE']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB][capacity]: 1000
- name: member_of filters
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1
resources2: DISK_GB:100
member_of2: $ENVIRON['AGGC']
group_policy: none
status: 200
response_json_paths:
$.allocation_requests.`len`: 1
$.allocation_requests[0].allocations["$ENVIRON['CN_RIGHT']"].resources:
VCPU: 1
DISK_GB: 100
$.provider_summaries.`len`: 1
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[DISK_GB][capacity]: 500
- name: required, forbidden, member_of in
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1
required1: "!HW_CPU_X86_SSE"
resources2: DISK_GB:100
required2: CUSTOM_DISK_SSD
member_of2: in:$ENVIRON['AGGA'],$ENVIRON['AGGC']
group_policy: none
status: 200
response_json_paths:
# cn_middle won't appear (forbidden SSE trait)
# shr_disk_2 won't appear (required SSD trait is absent)
# [cn_left] won't be in the results (required SSD trait is absent)
# So we'll get:
# [cn_left, shr_disk_1]
# [cn_right]
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB]: 100
$.provider_summaries.`len`: 3
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[DISK_GB][capacity]: 500
$.provider_summaries["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB][capacity]: 1000
- name: required, forbidden, member_of in long suffix
desc: same as above, but using complex suffixes
GET: /allocation_candidates
query_parameters:
resources_compute: VCPU:1
required_compute: "!HW_CPU_X86_SSE"
resources_disk: DISK_GB:100
required_disk: CUSTOM_DISK_SSD
member_of_disk: in:$ENVIRON['AGGA'],$ENVIRON['AGGC']
group_policy: none
request_headers:
openstack-api-version: placement 1.33
status: 200
response_json_paths:
$.allocation_requests.`len`: 2
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB]: 100
$.provider_summaries.`len`: 3
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[DISK_GB][capacity]: 500
$.provider_summaries["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB][capacity]: 1000
- name: multiple member_of
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1
resources2: DISK_GB:100
member_of2:
- in:$ENVIRON['AGGB'],$ENVIRON['AGGC']
- $ENVIRON['AGGA']
group_policy: isolate
status: 200
response_json_paths:
# The member_of2 specifications say that the DISK_GB resource must come
# from a provider that's in aggA and also in (aggB and/or aggC). Only
# shr_disk_2 qualifies; so we'll get results anchored at cn_middle and
# cn_right. But note that we'll also get a result anchored at cn_left:
# it doesn't meet the member_of criteria, but it doesn't need to, since
# it's not providing the DISK_GB resource.
$.allocation_requests.`len`: 3
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['CN_MIDDLE']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB]: [100, 100, 100]
$.provider_summaries.`len`: 4
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_MIDDLE']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB][capacity]: 1000
- name: multiple disks, multiple networks
GET: /allocation_candidates
query_parameters:
resources1: VCPU:1
resources2: VGPU:1
required2: HW_GPU_API_DXVA
resources3: MEMORY_MB:1024
resources4: DISK_GB:100
required4: CUSTOM_DISK_SSD
resources5: DISK_GB:50
required5: "!CUSTOM_DISK_SSD"
resources6: SRIOV_NET_VF:1,CUSTOM_NET_MBPS:1000
resources7: SRIOV_NET_VF:2,CUSTOM_NET_MBPS:2000
group_policy: none
# Breaking it down:
# => These could come from cn_left, cn_middle, or cn_right
# ?resources1=VCPU:1
# &resources3=MEMORY_MB:1024
# => But this limits us to cn_left and cn_right
# &resources2=VGPU:1&required2=HW_GPU_API_DXVA
# => Since we're not isolating, this SSD can come from cn_right or shr_disk_1
# &resources4=DISK_GB:100&required4=CUSTOM_DISK_SSD
# => This non-SSD can come from cn_left or shr_disk_2
# &resources5=DISK_GB:50&required5=!CUSTOM_DISK_SSD
# => These VFs and bandwidth can come from cn_left or shr_net. Since cn_left
# can't be an anchor for shr_net, these will always combine.
# &resources6=SRIOV_NET_VF:1,CUSTOM_NET_MBPS:1000
# &resources7=SRIOV_NET_VF:2,CUSTOM_NET_MBPS:2000
# => If we didn't do this, the separated VCPU/MEMORY_MB/VGPU resources would
# cause us to get no results
# &group_policy=none
status: 200
response_json_paths:
# We have two permutations involving cn_left.
# - One where the non-SSD is satisfied by cn_left itself
# [cn_left(VCPU:1, MEMORY_MB:1024, VGPU:1, DISK_GB:50, SRIOV_NET_VF:3, CUSTOM_NET_MBPS:3000),
# shr_disk_1(DISK_GB:100)]
# - And one where the non-SSD is satisfied by shr_disk_2
# [cn_left(VCPU:1, MEMORY_MB:1024, VGPU:1, SRIOV_NET_VF:3, CUSTOM_NET_MBPS:3000),
# shr_disk_1(DISK_GB:100),
# shr_disk_2(DISK_GB: 50)]
# There's only one result involving cn_right.
# - We must satisfy the SSD from cn_right and the non-SSD from shr_disk_2
# - We must satisfy the network stuff from shr_net
# [cn_right(VCPU:1, MEMORY_MB:1024, VGPU:1, DISK_GB:100),
# shr_disk_2(DISK_GB:50),
# shr_net(SRIOV_NET_VF:3, CUSTOM_NET_MBPS:3000)]
$.allocation_requests.`len`: 3
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[VCPU]: [1, 1]
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[MEMORY_MB]: [1024, 1024]
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[VGPU]: [1, 1]
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[SRIOV_NET_VF]: [3, 3]
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[CUSTOM_NET_MBPS]: [3000, 3000]
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[DISK_GB]: 50
# These come from the cn_left results
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB]: [100, 100]
# One of these comes from the second cn_left result, the other from the cn_right result
$.allocation_requests..allocations["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB]: [50, 50]
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[VCPU]: 1
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[MEMORY_MB]: 1024
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[VGPU]: 1
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[DISK_GB]: 100
$.allocation_requests..allocations["$ENVIRON['SHR_NET']"].resources[SRIOV_NET_VF]: 3
$.allocation_requests..allocations["$ENVIRON['SHR_NET']"].resources[CUSTOM_NET_MBPS]: 3000
# Just make sure we got the correct four providers in the summaries
$.provider_summaries.`len`: 5
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['SHR_DISK_1']"].resources[DISK_GB][capacity]: 1000
$.provider_summaries["$ENVIRON['SHR_DISK_2']"].resources[DISK_GB][capacity]: 1000
$.provider_summaries["$ENVIRON['SHR_NET']"].resources[SRIOV_NET_VF][capacity]: 16
- name: combining request groups exceeds capacity
GET: /allocation_candidates
query_parameters:
resources: VCPU:2,MEMORY_MB:2048,SRIOV_NET_VF:1,CUSTOM_NET_MBPS:2000
resources1: SRIOV_NET_VF:1,CUSTOM_NET_MBPS:3000
status: 200
response_json_paths:
# CUSTOM_NET_MBPS of 2000 + 3000 = 5000 is too much for cn_left, but
# shr_net can accommodate it.
$.allocation_requests.`len`: 1
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[VCPU]: 2
$.allocation_requests..allocations["$ENVIRON['CN_RIGHT']"].resources[MEMORY_MB]: 2048
$.allocation_requests..allocations["$ENVIRON['SHR_NET']"].resources[SRIOV_NET_VF]: 2
$.allocation_requests..allocations["$ENVIRON['SHR_NET']"].resources[CUSTOM_NET_MBPS]: 5000
$.provider_summaries.`len`: 2
$.provider_summaries["$ENVIRON['CN_RIGHT']"].resources[VCPU][capacity]: 8
$.provider_summaries["$ENVIRON['SHR_NET']"].resources[CUSTOM_NET_MBPS][capacity]: 40000
- name: combining request groups exceeds max_unit
GET: /allocation_candidates
query_parameters:
resources: VGPU:1
resources1: VGPU:1
resources2: VGPU:1
group_policy: none
status: 200
response_json_paths:
# VGPU of 1 + 1 + 1 = 3 exceeds max_unit on cn_right, but cn_left can handle it.
$.allocation_requests.`len`: 1
$.allocation_requests..allocations["$ENVIRON['CN_LEFT']"].resources[VGPU]: 3
$.provider_summaries.`len`: 1
$.provider_summaries["$ENVIRON['CN_LEFT']"].resources[VGPU][capacity]: 8
#################
# Error scenarios
#################
- name: numbered resources bad microversion
GET: /allocation_candidates?resources=MEMORY_MB:1024&resources1=VCPU:1
request_headers:
openstack-api-version: placement 1.24
status: 400
response_strings:
- Invalid query string parameters
- "'resources1' was unexpected"
- name: numbered traits bad microversion
GET: /allocation_candidates?resources=MEMORY_MB:1024&required2=HW_CPU_X86_AVX2
request_headers:
openstack-api-version: placement 1.24
status: 400
response_strings:
- Invalid query string parameters
- "'required2' was unexpected"
- name: numbered member_of bad microversion
GET: /allocation_candidates?resources=MEMORY_MB:1024&member_of3=$ENVIRON['AGGB']
request_headers:
openstack-api-version: placement 1.24
status: 400
response_strings:
- Invalid query string parameters
- "'member_of3' was unexpected"
- name: group_policy bad microversion
GET: /allocation_candidates?resources=VCPU:1&group_policy=isolate
request_headers:
openstack-api-version: placement 1.24
status: 400
response_strings:
- Invalid query string parameters
- "'group_policy' was unexpected"
- name: bogus numbering
GET: /allocation_candidates?resources01=VCPU:1
status: 400
response_strings:
- Invalid query string parameters
- "'resources01' does not match any of the regexes"
- name: bogus suffix
desc: this is bogus because of unsupported character
GET: /allocation_candidates?resources1@=VCPU:1
request_headers:
openstack-api-version: placement 1.33
status: 400
response_strings:
- Invalid query string parameters
- "'resources1@' does not match any of the regexes"
- "^member_of([a-zA-Z0-9_-]{1,64})?$"
- name: bogus length
desc: 65 character suffix is too long
GET: /allocation_candidates?resources_0123456701234567012345670123456701234567012345670123456701234567=VCPU:1
request_headers:
openstack-api-version: placement 1.33
status: 400
response_strings:
- Invalid query string parameters
- "'resources_0123456701234567012345670123456701234567012345670123456701234567' does not match any of the regexes"
- "^member_of([a-zA-Z0-9_-]{1,64})?$"
- name: invalid group_policy value
GET: /allocation_candidates?resources=VCPU:1&group_policy=bogus
status: 400
response_strings:
- Invalid query string parameters
- "'bogus' is not one of ['none', 'isolate']"
- name: group_policy required when more than one numbered group
GET: /allocation_candidates?resources1=VCPU:1&resources2=VCPU:1
status: 400
response_strings:
- The \"group_policy\" parameter is required when specifying more than one \"resources{N}\" parameter.
- name: orphaned traits keys
GET: /allocation_candidates?required=FOO&required1=BAR
status: 400
response_strings:
- 'Found the following orphaned traits keys: required, required1'
- name: orphaned member_of keys
GET: /allocation_candidates?member_of=$ENVIRON['AGGA']&member_of3=$ENVIRON['AGGC']
status: 400
response_strings:
- 'Found the following orphaned member_of keys: member_of, member_of3'
- name: at least one request group required
GET: /allocation_candidates?group_policy=isolate
status: 400
response_strings:
- At least one request group (`resources` or `resources{$S}`) is required.