# Tests of allocation candidates API

fixtures:
    - NonSharedStorageFixture

defaults:
    request_headers:
        x-auth-token: admin
        content-type: application/json
        accept: application/json
        openstack-api-version: placement 1.24

tests:

- name: get bad member_of microversion
  GET: /allocation_candidates?resources=VCPU:1&member_of=in:$ENVIRON['AGGA_UUID'],$ENVIRON['AGGB_UUID']
  request_headers:
      openstack-api-version: placement 1.18
  status: 400
  response_strings:
      - Invalid query string parameters
      - "'member_of' was unexpected"

- name: get allocation candidates invalid member_of value
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=INVALID_UUID
  status: 400
  response_strings:
      - Expected 'member_of' parameter to contain valid UUID(s).

- name: get allocation candidates no 'in:' for multiple member_of
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=$ENVIRON['AGGA_UUID'],$ENVIRON['AGGB_UUID']
  status: 400
  response_strings:
      - Multiple values for 'member_of' must be prefixed with the 'in:' or '!in:' keyword using the valid microversion.

- name: get allocation candidates multiple member_of with 'in:' but invalid values
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=in:$ENVIRON['AGGA_UUID'],INVALID_UUID
  status: 400
  response_strings:
      - Expected 'member_of' parameter to contain valid UUID(s).

- name: get allocation candidates multiple member_of with 'in:' but no aggregates
  GET: /allocation_candidates?&member_of=in:&resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100
  status: 400
  response_strings:
      - Expected 'member_of' parameter to contain valid UUID(s).

- name: get allocation candidates with no match for member_of
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=$ENVIRON['AGGA_UUID']
  status: 200
  response_json_paths:
      $.allocation_requests.`len`: 0

- name: get compute node 1 state
  GET: /resource_providers/$ENVIRON['CN1_UUID']

- name: associate the first compute node with aggA
  PUT: /resource_providers/$ENVIRON['CN1_UUID']/aggregates
  data:
      aggregates:
        - $ENVIRON['AGGA_UUID']
      resource_provider_generation: $HISTORY['get compute node 1 state'].$RESPONSE['$.generation']
  status: 200

- name: verify that the member_of call now returns 1 allocation_candidate
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=in:$ENVIRON['AGGA_UUID'],$ENVIRON['AGGB_UUID']
  status: 200
  response_json_paths:
      $.allocation_requests.`len`: 1

- name: get compute node 2 state
  GET: /resource_providers/$ENVIRON['CN2_UUID']

- name: associate the second compute node with aggB
  PUT: /resource_providers/$ENVIRON['CN2_UUID']/aggregates
  data:
      aggregates:
        - $ENVIRON['AGGB_UUID']
      resource_provider_generation: $HISTORY['get compute node 2 state'].$RESPONSE['$.generation']
  status: 200

- name: verify that the member_of call now returns both RPs
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=in:$ENVIRON['AGGA_UUID'],$ENVIRON['AGGB_UUID']
  status: 200
  response_json_paths:
      $.allocation_requests.`len`: 2

- name: verify that aggC still returns no RPs
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=$ENVIRON['AGGC_UUID']
  status: 200
  response_json_paths:
      $.allocation_requests.`len`: 0

- name: get current compute node 1 state
  GET: /resource_providers/$ENVIRON['CN1_UUID']

- name: now associate the first compute node with both aggA and aggC
  PUT: /resource_providers/$ENVIRON['CN1_UUID']/aggregates
  data:
      aggregates:
        - $ENVIRON['AGGA_UUID']
        - $ENVIRON['AGGC_UUID']
      resource_provider_generation: $HISTORY['get current compute node 1 state'].$RESPONSE['$.generation']

- name: verify that the member_of call for aggs A and B still returns 2 allocation_candidates
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=in:$ENVIRON['AGGA_UUID'],$ENVIRON['AGGB_UUID']
  status: 200
  response_json_paths:
      $.allocation_requests.`len`: 2
  status: 200

- name: verify microversion fail for multiple member_of params
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=$ENVIRON['AGGA_UUID']&member_of=$ENVIRON['AGGB_UUID']
  request_headers:
      openstack-api-version: placement 1.23
  status: 400
  response_strings:
      - 'Multiple member_of parameters are not supported'
  response_json_paths:
      $.errors[0].title: Bad Request

- name: verify that no RP is associated with BOTH aggA and aggB
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=$ENVIRON['AGGA_UUID']&member_of=$ENVIRON['AGGB_UUID']
  status: 200
  response_json_paths:
      $.allocation_requests.`len`: 0

- name: associate the second compute node with aggA and aggB
  PUT: /resource_providers/$ENVIRON['CN2_UUID']/aggregates
  data:
      aggregates:
        - $ENVIRON['AGGA_UUID']
        - $ENVIRON['AGGB_UUID']
      resource_provider_generation: $HISTORY['associate the second compute node with aggB'].$RESPONSE['$.resource_provider_generation']
  status: 200

- name: verify that second RP is associated with BOTH aggA and aggB
  GET: /allocation_candidates?resources=VCPU:1,MEMORY_MB:1024,DISK_GB:100&member_of=$ENVIRON['AGGA_UUID']&member_of=$ENVIRON['AGGB_UUID']
  status: 200
  response_json_paths:
      $.allocation_requests.`len`: 1

# Tests for negative aggregate membership from microversion 1.32
# Now the aggregation map is as below
# {
#  CN1: [AGGA, AGGC],
#  CN2: [AGGA, AGGB],
#  CN3: []
# }
- name: negative agg error on old microversion with ! prefix
  GET: /allocation_candidates?resources=VCPU:1&member_of=!$ENVIRON['AGGA_UUID']
  status: 400
  request_headers:
    openstack-api-version: placement 1.31
  response_strings:
      - "Forbidden member_of parameters are not supported in the specified microversion"

- name: negative agg error on old microversion with !in prefix
  GET: /allocation_candidates?resources=VCPU:1&member_of=!in:$ENVIRON['AGGA_UUID']
  status: 400
  request_headers:
    openstack-api-version: placement 1.31
  response_strings:
      - "Forbidden member_of parameters are not supported in the specified microversion"

- name: negative agg error on orphaned queryparam
  GET: /allocation_candidates?member_of=!$ENVIRON['AGGA_UUID']
  status: 400
  request_headers:
    openstack-api-version: placement 1.32
  response_strings:
      - "All member_of parameters must be associated with resources"

- name: negative agg error on invalid agg
  GET: /allocation_candidates?resources=VCPU:1&member_of=!(^o^)
  status: 400
  request_headers:
    openstack-api-version: placement 1.32
  response_strings:
      - "Invalid query string parameters: Expected 'member_of' parameter to contain valid UUID(s)."

- name: negative agg error on invalid usage of in prefix
  GET: /allocation_candidates?resources=VCPU:1&member_of=in:$ENVIRON['AGGA_UUID'],!$ENVIRON['AGGB_UUID']
  status: 400
  request_headers:
    openstack-api-version: placement 1.32
  response_strings:
      - "Invalid query string parameters: Expected 'member_of' parameter to contain valid UUID(s)."

- name: negative agg
  GET: /allocation_candidates?resources=VCPU:1&member_of=!$ENVIRON['AGGC_UUID']
  status: 200
  request_headers:
    openstack-api-version: placement 1.32
  response_json_paths:
    # CN1 is excluded
    $.allocation_requests.`len`: 2
    $.provider_summaries.`len`: 2
    $.allocation_requests..allocations["$ENVIRON['CN2_UUID']"].resources.VCPU: 1
    $.allocation_requests..allocations["$ENVIRON['CN3_UUID']"].resources.VCPU: 1

- name: negative agg multiple
  GET: /allocation_candidates?resources=VCPU:1&member_of=!in:$ENVIRON['AGGB_UUID'],$ENVIRON['AGGC_UUID']
  status: 200
  request_headers:
    openstack-api-version: placement 1.32
  response_json_paths:
    # Both CN1 and CN2 are excluded
    $.allocation_requests.`len`: 1
    $.provider_summaries.`len`: 1
    $.allocation_requests..allocations["$ENVIRON['CN3_UUID']"].resources.VCPU: 1

- name: negative agg with positive agg
  GET: /allocation_candidates?resources=VCPU:1&member_of=!$ENVIRON['AGGB_UUID']&member_of=$ENVIRON['AGGC_UUID']
  status: 200
  request_headers:
    openstack-api-version: placement 1.32
  response_json_paths:
    # Only CN1 is returned
    $.allocation_requests.`len`: 1
    $.provider_summaries.`len`: 1
    $.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: 1

- name: negative agg multiple with positive agg
  GET: /allocation_candidates?resources=VCPU:1&member_of=!in:$ENVIRON['AGGB_UUID'],$ENVIRON['AGGC_UUID']&member_of=$ENVIRON['AGGA_UUID']
  status: 200
  request_headers:
    openstack-api-version: placement 1.32
  response_json_paths:
    # no rp is returned
    $.allocation_requests.`len`: 0
    $.provider_summaries.`len`: 0

# This request is equivalent to the one in "negative agg with positive agg"
- name: negative agg with the same agg on positive get rp
  GET: /allocation_candidates?resources=VCPU:1&member_of=!$ENVIRON['AGGB_UUID']&member_of=in:$ENVIRON['AGGB_UUID'],$ENVIRON['AGGC_UUID']
  status: 200
  request_headers:
    openstack-api-version: placement 1.32
  response_json_paths:
    $.allocation_requests.`len`: 1
    $.provider_summaries.`len`: 1
    $.allocation_requests..allocations["$ENVIRON['CN1_UUID']"].resources.VCPU: 1

- name: negative agg with the same agg on positive no rp
  GET: /allocation_candidates?resources=VCPU:1&member_of=!$ENVIRON['AGGB_UUID']&member_of=$ENVIRON['AGGB_UUID']
  status: 200
  request_headers:
    openstack-api-version: placement 1.32
  response_json_paths:
    # no rp is returned
    $.allocation_requests.`len`: 0
    $.provider_summaries.`len`: 0
