Merge "Add 2.55 schema & update flavor API in flavors_client"
This commit is contained in:
commit
e4f4d8bee1
@ -354,6 +354,10 @@ Microversion tests implemented in Tempest
|
||||
|
||||
.. _2.48: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id43
|
||||
|
||||
* `2.55`_
|
||||
|
||||
.. _2.55: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id49
|
||||
|
||||
* `2.60`_
|
||||
|
||||
.. _2.60: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id54
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add update flavor API to compute flavors_client library.
|
43
tempest/api/compute/admin/test_flavors_microversions.py
Normal file
43
tempest/api/compute/admin/test_flavors_microversions.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright 2018 NEC Corporation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
from tempest.api.compute import base
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
|
||||
class FlavorsV255TestJSON(base.BaseV2ComputeAdminTest):
|
||||
min_microversion = '2.55'
|
||||
max_microversion = 'latest'
|
||||
|
||||
# NOTE(gmann): This class tests the flavors APIs
|
||||
# response schema for the 2.55 microversion.
|
||||
|
||||
@decorators.idempotent_id('61976b25-488d-41dc-9dcb-cb9693a7b075')
|
||||
def test_crud_flavor(self):
|
||||
flavor_id = data_utils.rand_int_id(start=1000)
|
||||
# Checking create API response schema
|
||||
new_flavor_id = self.create_flavor(ram=512,
|
||||
vcpus=1,
|
||||
disk=10,
|
||||
id=flavor_id)['id']
|
||||
# Checking show API response schema
|
||||
self.flavors_client.show_flavor(new_flavor_id)['flavor']
|
||||
# Checking update API response schema
|
||||
self.admin_flavors_client.update_flavor(new_flavor_id,
|
||||
description='new')['flavor']
|
||||
# Checking list details API response schema
|
||||
self.flavors_client.list_flavors(detail=True)['flavors']
|
||||
# Checking list API response schema
|
||||
self.flavors_client.list_flavors()['flavors']
|
@ -86,7 +86,7 @@ unset_flavor_extra_specs = {
|
||||
'status_code': [200]
|
||||
}
|
||||
|
||||
create_get_flavor_details = {
|
||||
create_update_get_flavor_details = {
|
||||
'status_code': [200],
|
||||
'response_body': {
|
||||
'type': 'object',
|
||||
|
112
tempest/lib/api_schema/response/compute/v2_55/flavors.py
Normal file
112
tempest/lib/api_schema/response/compute/v2_55/flavors.py
Normal file
@ -0,0 +1,112 @@
|
||||
# Copyright 2018 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
|
||||
|
||||
# Note(gmann): This is schema for microversion 2.55 which includes the
|
||||
# following changes:
|
||||
# Add new PUT API
|
||||
# Adds a ``description`` field to the following APIs response:
|
||||
# - ``GET /flavors``
|
||||
# - ``GET /flavors/detail``
|
||||
# - ``GET /flavors/{flavor_id}``
|
||||
# - ``POST /flavors``
|
||||
|
||||
flavor_description = {
|
||||
'type': ['string', 'null'],
|
||||
'minLength': 0, 'maxLength': 65535
|
||||
}
|
||||
|
||||
list_flavors = {
|
||||
'status_code': [200],
|
||||
'response_body': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'flavors': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': {'type': 'string'},
|
||||
'links': parameter_types.links,
|
||||
'id': {'type': 'string'},
|
||||
'description': flavor_description
|
||||
},
|
||||
'additionalProperties': False,
|
||||
'required': ['name', 'links', 'id', 'description']
|
||||
}
|
||||
},
|
||||
'flavors_links': parameter_types.links
|
||||
},
|
||||
'additionalProperties': False,
|
||||
# NOTE(gmann): flavors_links attribute is not necessary
|
||||
# to be present always So it is not 'required'.
|
||||
'required': ['flavors']
|
||||
}
|
||||
}
|
||||
|
||||
common_flavor_info = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': {'type': 'string'},
|
||||
'links': parameter_types.links,
|
||||
'ram': {'type': 'integer'},
|
||||
'vcpus': {'type': 'integer'},
|
||||
# 'swap' attributes comes as integer value but if it is empty
|
||||
# it comes as "". So defining type of as string and integer.
|
||||
'swap': {'type': ['integer', 'string']},
|
||||
'disk': {'type': 'integer'},
|
||||
'id': {'type': 'string'},
|
||||
'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
|
||||
'os-flavor-access:is_public': {'type': 'boolean'},
|
||||
'rxtx_factor': {'type': 'number'},
|
||||
'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'},
|
||||
'description': flavor_description
|
||||
},
|
||||
'additionalProperties': False,
|
||||
# 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and
|
||||
# 'OS-FLV-EXT-DATA' are API extensions. So they are not 'required'.
|
||||
'required': ['name', 'links', 'ram', 'vcpus', 'swap', 'disk', 'id',
|
||||
'description']
|
||||
}
|
||||
|
||||
list_flavors_details = {
|
||||
'status_code': [200],
|
||||
'response_body': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'flavors': {
|
||||
'type': 'array',
|
||||
'items': common_flavor_info
|
||||
},
|
||||
# NOTE(gmann): flavors_links attribute is not necessary
|
||||
# to be present always So it is not 'required'.
|
||||
'flavors_links': parameter_types.links
|
||||
},
|
||||
'additionalProperties': False,
|
||||
'required': ['flavors']
|
||||
}
|
||||
}
|
||||
|
||||
create_update_get_flavor_details = {
|
||||
'status_code': [200],
|
||||
'response_body': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'flavor': common_flavor_info
|
||||
},
|
||||
'additionalProperties': False,
|
||||
'required': ['flavor']
|
||||
}
|
||||
}
|
@ -21,12 +21,18 @@ from tempest.lib.api_schema.response.compute.v2_1 import flavors_access \
|
||||
as schema_access
|
||||
from tempest.lib.api_schema.response.compute.v2_1 import flavors_extra_specs \
|
||||
as schema_extra_specs
|
||||
from tempest.lib.api_schema.response.compute.v2_55 import flavors \
|
||||
as schemav255
|
||||
from tempest.lib.common import rest_client
|
||||
from tempest.lib.services.compute import base_compute_client
|
||||
|
||||
|
||||
class FlavorsClient(base_compute_client.BaseComputeClient):
|
||||
|
||||
schema_versions_info = [
|
||||
{'min': None, 'max': '2.54', 'schema': schema},
|
||||
{'min': '2.55', 'max': None, 'schema': schemav255}]
|
||||
|
||||
def list_flavors(self, detail=False, **params):
|
||||
"""Lists flavors.
|
||||
|
||||
@ -36,11 +42,12 @@ class FlavorsClient(base_compute_client.BaseComputeClient):
|
||||
https://developer.openstack.org/api-ref/compute/#list-flavors-with-details
|
||||
"""
|
||||
url = 'flavors'
|
||||
_schema = schema.list_flavors
|
||||
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
if detail:
|
||||
url += '/detail'
|
||||
_schema = schema.list_flavors_details
|
||||
else:
|
||||
_schema = schema.list_flavors
|
||||
if params:
|
||||
url += '?%s' % urllib.urlencode(params)
|
||||
|
||||
@ -58,7 +65,9 @@ class FlavorsClient(base_compute_client.BaseComputeClient):
|
||||
"""
|
||||
resp, body = self.get("flavors/%s" % flavor_id)
|
||||
body = json.loads(body)
|
||||
self.validate_response(schema.create_get_flavor_details, resp, body)
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
self.validate_response(schema.create_update_get_flavor_details,
|
||||
resp, body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
def create_flavor(self, **kwargs):
|
||||
@ -77,7 +86,25 @@ class FlavorsClient(base_compute_client.BaseComputeClient):
|
||||
resp, body = self.post('flavors', post_body)
|
||||
|
||||
body = json.loads(body)
|
||||
self.validate_response(schema.create_get_flavor_details, resp, body)
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
self.validate_response(schema.create_update_get_flavor_details,
|
||||
resp, body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
def update_flavor(self, flavor_id, **kwargs):
|
||||
"""Uodate the flavor or instance type.
|
||||
|
||||
For a full list of available parameters, please refer to the official
|
||||
API reference:
|
||||
https://developer.openstack.org/api-ref/compute/#update-flavor-description
|
||||
"""
|
||||
put_body = json.dumps({'flavor': kwargs})
|
||||
resp, body = self.put("flavors/%s" % flavor_id, put_body)
|
||||
|
||||
body = json.loads(body)
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
self.validate_response(schema.create_update_get_flavor_details,
|
||||
resp, body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
def delete_flavor(self, flavor_id):
|
||||
|
@ -17,6 +17,7 @@ import copy
|
||||
import fixtures
|
||||
from oslo_serialization import jsonutils as json
|
||||
|
||||
from tempest.api.compute import api_microversion_fixture
|
||||
from tempest.lib.services.compute import flavors_client
|
||||
from tempest.tests.lib import fake_auth_provider
|
||||
from tempest.tests.lib import fake_http
|
||||
@ -39,6 +40,21 @@ class TestFlavorsClient(base.BaseServiceTest):
|
||||
"vcpus": 1
|
||||
}
|
||||
|
||||
FAKE_FLAVOR_UPDATE = {
|
||||
"disk": 1,
|
||||
"id": "1",
|
||||
"links": [{
|
||||
"href": "http://openstack.example.com/v2/openstack/flavors/1",
|
||||
"rel": "self"}, {
|
||||
"href": "http://openstack.example.com/openstack/flavors/1",
|
||||
"rel": "bookmark"}],
|
||||
"name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 1,
|
||||
"vcpus": 1,
|
||||
"description": 'new'
|
||||
}
|
||||
|
||||
EXTRA_SPECS = {"extra_specs": {
|
||||
"key1": "value1",
|
||||
"key2": "value2"}
|
||||
@ -106,6 +122,25 @@ class TestFlavorsClient(base.BaseServiceTest):
|
||||
def test_create_flavor__byte_body(self):
|
||||
self._test_create_flavor(bytes_body=True)
|
||||
|
||||
def _test_update_flavor(self, bytes_body=False):
|
||||
self.useFixture(api_microversion_fixture.APIMicroversionFixture(
|
||||
'2.55'))
|
||||
expected = {"flavor": TestFlavorsClient.FAKE_FLAVOR_UPDATE}
|
||||
request = {"flavor": {"description": "updated description"}}
|
||||
self.check_service_client_function(
|
||||
self.client.update_flavor,
|
||||
'tempest.lib.common.rest_client.RestClient.put',
|
||||
expected,
|
||||
bytes_body,
|
||||
flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
|
||||
**request)
|
||||
|
||||
def test_update_flavor_str_body(self):
|
||||
self._test_update_flavor(bytes_body=False)
|
||||
|
||||
def test_update_flavor__byte_body(self):
|
||||
self._test_update_flavor(bytes_body=True)
|
||||
|
||||
def test_delete_flavor(self):
|
||||
self.check_service_client_function(
|
||||
self.client.delete_flavor,
|
||||
|
Loading…
Reference in New Issue
Block a user