# Tests of allocations API
#
# Note(cdent): Consumer ids are not validated against anything to
# confirm that they are associated with anything real. This is
# by design.


fixtures:
    - APIFixture

defaults:
    request_headers:
        x-auth-token: admin
        accept: application/json

tests:

- name: get allocations no consumer is 405
  GET: /allocations
  status: 405
  response_json_paths:
     $.errors[0].title: Method Not Allowed

- name: get allocations is empty dict
  GET: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  response_json_paths:
      $.allocations: {}

- name: put an allocation no resource provider
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resources:
              DISK_GB: 10
  status: 400
  response_json_paths:
     $.errors[0].title: Bad Request

- name: create the resource provider
  POST: /resource_providers
  request_headers:
      content-type: application/json
  data:
      name: $ENVIRON['RP_NAME']
      uuid: $ENVIRON['RP_UUID']
  status: 201

- name: put an allocation no data
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  status: 400
  response_json_paths:
      $.errors[0].title: Bad Request

- name: put an allocation empty list
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations: []
  status: 400
  response_strings:
      - "Failed validating 'minItems'"

- name: put an allocation violate schema
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                cow: 10
  status: 400
  response_json_paths:
     $.errors[0].title: Bad Request

- name: put an allocation no inventory
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                DISK_GB: 10
  status: 409
  response_json_paths:
     $.errors[0].title: Conflict

- name: post some inventory
  POST: /resource_providers/$ENVIRON['RP_UUID']/inventories
  request_headers:
      content-type: application/json
  data:
      resource_class: DISK_GB
      total: 2048
      min_unit: 10
      max_unit: 1024
  status: 201

- name: put an allocation with zero usage
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                DISK_GB: 0
  status: 400
  response_strings:
      - "JSON does not validate: 0 is less than the minimum of 1"
      - Failed validating 'minimum' in schema

- name: put an allocation with omitted usage
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
  status: 400
  response_strings:
      - Failed validating 'required' in schema


- name: put an allocation
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                DISK_GB: 10
  status: 204

- name: fail to delete that provider
  DELETE: /resource_providers/$ENVIRON['RP_UUID']
  request_headers:
      content-type: application/json
      # we need this microversion to get error codes in the response
      openstack-api-version: placement 1.23
  status: 409
  response_strings:
      - "Unable to delete resource provider $ENVIRON['RP_UUID']"
  response_json_paths:
      errors[0].code: placement.resource_provider.inuse


- name: put an allocation different consumer
  PUT: /allocations/39715579-2167-4c63-8247-301311cc6703
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                DISK_GB: 10
  status: 204

- name: check usages after another 10
  GET: /resource_providers/$ENVIRON['RP_UUID']/usages
  response_json_paths:
      $.usages.DISK_GB: 20

# NOTE(cdent): Contravening the spec, we decided that it is
# important to be able to update an existing allocation, so this
# should work but it is important to check the usage.
- name: put allocation again
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                DISK_GB: 12
  status: 204

- name: check usages after 12
  GET: /resource_providers/$ENVIRON['RP_UUID']/usages
  response_json_paths:
      $.usages.DISK_GB: 22

- name: put allocation bad resource class
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                COWS: 12
  status: 400
  response_strings:
      - Unable to allocate inventory for consumer
      - No such resource class COWS
  response_json_paths:
      $.errors[0].title: Bad Request

- name: delete allocation
  DELETE: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  status: 204

- name: delete allocation again
  DELETE: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  status: 404
  response_strings:
      - No allocations for consumer '599ffd2d-526a-4b2e-8683-f13ad25f9958'
  response_json_paths:
      $.errors[0].title: Not Found

- name: delete allocation of unknown consumer id
  DELETE: /allocations/da78521f-bf7e-4e6e-9901-3f79bd94d55d
  status: 404
  response_json_paths:
      $.errors[0].title: Not Found

- name: redo an allocation
  PUT: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                DISK_GB: 10
  status: 204

- name: add other inventory
  POST: /resource_providers/$ENVIRON['RP_UUID']/inventories
  request_headers:
      content-type: application/json
  data:
      resource_class: VCPU
      total: 32
      min_unit: 1
      max_unit: 8
  status: 201

- name: multiple allocations
  PUT: /allocations/833f0885-f78c-4788-bb2b-3607b0656be7
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: $ENVIRON['RP_UUID']
            resources:
                DISK_GB: 20
                VCPU: 4
  status: 204

- name: check usages
  GET: /resource_providers/$ENVIRON['RP_UUID']/usages
  response_json_paths:
      $.resource_provider_generation: 7
      $.usages.DISK_GB: 40

- name: check allocations for the resource provider
  GET: /resource_providers/$ENVIRON['RP_UUID']/allocations
  response_json_paths:
      $.resource_provider_generation: 7
      # allocations are keyed by consumer id, jsonpath-rw needs us
      # to quote the uuids or its parser gets confused that maybe
      # they are numbers on which math needs to be done.
      $.allocations['833f0885-f78c-4788-bb2b-3607b0656be7'].resources.DISK_GB: 20
      $.allocations['833f0885-f78c-4788-bb2b-3607b0656be7'].resources.VCPU: 4
      $.allocations['599ffd2d-526a-4b2e-8683-f13ad25f9958'].resources.DISK_GB: 10
      $.allocations['39715579-2167-4c63-8247-301311cc6703'].resources.DISK_GB: 10

- name: confirm 404 for allocations of bad resource provider
  GET: /resource_providers/cb8a3007-b93a-471f-9e1f-4d58355678bd/allocations
  status: 404
  response_json_paths:
      $.errors[0].title: Not Found

- name: check allocations by consumer id
  GET: /allocations/833f0885-f78c-4788-bb2b-3607b0656be7
  response_json_paths:
      $.allocations["$ENVIRON['RP_UUID']"].generation: 7
      $.allocations["$ENVIRON['RP_UUID']"].resources.DISK_GB: 20
      $.allocations["$ENVIRON['RP_UUID']"].resources.VCPU: 4

- name: check allocations by different consumer id
  GET: /allocations/599ffd2d-526a-4b2e-8683-f13ad25f9958
  response_json_paths:
      $.allocations["$ENVIRON['RP_UUID']"].generation: 7
      $.allocations["$ENVIRON['RP_UUID']"].resources.DISK_GB: 10

# create another two resource providers to test retrieving
# allocations
- name: create resource provider 1
  POST: /resource_providers
  request_headers:
      content-type: application/json
  data:
      name: rp1
      uuid: 9229b2fc-d556-4e38-9c18-443e4bc6ceae
  status: 201

- name: create resource provider 2
  POST: /resource_providers
  request_headers:
      content-type: application/json
  data:
      name: rp2
      uuid: fcfa516a-abbe-45d1-8152-d5225d82e596
  status: 201

- name: set inventory on rp1
  PUT: /resource_providers/9229b2fc-d556-4e38-9c18-443e4bc6ceae/inventories
  request_headers:
      content-type: application/json
  data:
      resource_provider_generation: 0
      inventories:
        VCPU:
          total: 32
          max_unit: 32
        DISK_GB:
          total: 10
          max_unit: 10

- name: set inventory on rp2
  PUT: /resource_providers/fcfa516a-abbe-45d1-8152-d5225d82e596/inventories
  request_headers:
      content-type: application/json
  data:
      resource_provider_generation: 0
      inventories:
        VCPU:
          total: 16
          max_unit: 16
        DISK_GB:
          total: 20
          max_unit: 20
  status: 200

- name: put allocations on both those providers one
  PUT: /allocations/1835b1c9-1c61-45af-9eb3-3e0e9f29487b
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: fcfa516a-abbe-45d1-8152-d5225d82e596
            resources:
                DISK_GB: 10
                VCPU: 8
          - resource_provider:
                uuid: 9229b2fc-d556-4e38-9c18-443e4bc6ceae
            resources:
                DISK_GB: 5
                VCPU: 16
  status: 204

- name: put allocations on both those providers two
  PUT: /allocations/75d0f5f7-75d9-458c-b204-f90ac91604ec
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: fcfa516a-abbe-45d1-8152-d5225d82e596
            resources:
                DISK_GB: 5
                VCPU: 4
          - resource_provider:
                uuid: 9229b2fc-d556-4e38-9c18-443e4bc6ceae
            resources:
                DISK_GB: 2
                VCPU: 8
  status: 204
  # These headers should not be present in any microversion on PUT
  # because there is no response body.
  response_forbidden_headers:
      - cache-control
      - last-modified

- name: get those allocations for consumer
  GET: /allocations/1835b1c9-1c61-45af-9eb3-3e0e9f29487b
  response_json_paths:
      $.allocations.['fcfa516a-abbe-45d1-8152-d5225d82e596'].generation: 3
      $.allocations.['fcfa516a-abbe-45d1-8152-d5225d82e596'].resources.DISK_GB: 10
      $.allocations.['fcfa516a-abbe-45d1-8152-d5225d82e596'].resources.VCPU: 8
      $.allocations.['9229b2fc-d556-4e38-9c18-443e4bc6ceae'].generation: 3
      $.allocations.['9229b2fc-d556-4e38-9c18-443e4bc6ceae'].resources.DISK_GB: 5
      $.allocations.['9229b2fc-d556-4e38-9c18-443e4bc6ceae'].resources.VCPU: 16

- name: get those allocations for resource provider
  GET: /resource_providers/fcfa516a-abbe-45d1-8152-d5225d82e596/allocations
  response_json_paths:
      $.resource_provider_generation: 3
      $.allocations.['75d0f5f7-75d9-458c-b204-f90ac91604ec'].resources.DISK_GB: 5
      $.allocations.['75d0f5f7-75d9-458c-b204-f90ac91604ec'].resources.VCPU: 4
      $.allocations.['1835b1c9-1c61-45af-9eb3-3e0e9f29487b'].resources.DISK_GB: 10
      $.allocations.['1835b1c9-1c61-45af-9eb3-3e0e9f29487b'].resources.VCPU: 8

- name: put allocations on existing consumer with dashless UUID
  PUT: /allocations/75d0f5f775d9458cb204f90ac91604ec
  request_headers:
      content-type: application/json
      # Consumer generation
      openstack-api-version: placement 1.28
  data:
      allocations:
          fcfa516a-abbe-45d1-8152-d5225d82e596:
            resources:
                DISK_GB: 1
                VCPU: 1
          9229b2fc-d556-4e38-9c18-443e4bc6ceae:
            resources:
                DISK_GB: 1
                VCPU: 1
      consumer_generation: 1
      project_id: 00000000-0000-0000-0000-000000000000
      user_id: 00000000-0000-0000-0000-000000000000
  status: 204

- name: get allocations on existing consumer with dashed UUID
  GET: /allocations/75d0f5f7-75d9-458c-b204-f90ac91604ec
  response_json_paths:
      $.allocations.['fcfa516a-abbe-45d1-8152-d5225d82e596'].generation: 4
      $.allocations.['fcfa516a-abbe-45d1-8152-d5225d82e596'].resources.DISK_GB: 1
      $.allocations.['fcfa516a-abbe-45d1-8152-d5225d82e596'].resources.VCPU: 1
      $.allocations.['9229b2fc-d556-4e38-9c18-443e4bc6ceae'].generation: 4
      $.allocations.['9229b2fc-d556-4e38-9c18-443e4bc6ceae'].resources.DISK_GB: 1
      $.allocations.['9229b2fc-d556-4e38-9c18-443e4bc6ceae'].resources.VCPU: 1

- name: put an allocation for a not existing resource provider
  PUT: /allocations/75d0f5f7-75d9-458c-b204-f90ac91604ec
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: be8b9cba-e7db-4a12-a386-99b4242167fe
            resources:
                DISK_GB: 5
                VCPU: 4
  status: 400
  response_strings:
      - Allocation for resource provider 'be8b9cba-e7db-4a12-a386-99b4242167fe' that does not exist
  response_json_paths:
      $.errors[0].title: Bad Request

- name: get allocations for resource provider with cache headers 1.15
  GET: /resource_providers/fcfa516a-abbe-45d1-8152-d5225d82e596/allocations
  request_headers:
      openstack-api-version: placement 1.15
  response_headers:
      cache-control: no-cache
      # Does last-modified look like a legit timestamp?
      last-modified:  /^\w+, \d+ \w+ \d{4} [\d:]+ GMT$/

- name: get allocations for resource provider without cache headers 1.14
  GET: /resource_providers/fcfa516a-abbe-45d1-8152-d5225d82e596/allocations
  request_headers:
      openstack-api-version: placement 1.14
  response_forbidden_headers:
      - cache-control
      - last-modified

- name: get allocations for consumer with cache headers 1.15
  GET: /allocations/1835b1c9-1c61-45af-9eb3-3e0e9f29487b
  request_headers:
      openstack-api-version: placement 1.15
  response_headers:
      cache-control: no-cache
      # Does last-modified look like a legit timestamp?
      last-modified:  /^\w+, \d+ \w+ \d{4} [\d:]+ GMT$/

- name: get allocations for consumer without cache headers 1.14
  GET: /allocations/1835b1c9-1c61-45af-9eb3-3e0e9f29487b
  request_headers:
      openstack-api-version: placement 1.14
  response_forbidden_headers:
      - cache-control
      - last-modified

- name: creating allocation with a non UUID consumer fails
  PUT: /allocations/not-a-uuid
  request_headers:
      content-type: application/json
  data:
      allocations:
          - resource_provider:
                uuid: fcfa516a-abbe-45d1-8152-d5225d82e596
            resources:
                DISK_GB: 1
                VCPU: 1
  status: 400
  response_strings:
      - Malformed consumer_uuid
