blob: 80dbc1d84c0a0efcaffaf35478920b40aaf423dd [file] [log] [blame]
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +00001# Copyright 2015 NEC Corporation. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
chenke4beff292019-04-11 14:02:57 +080015import six
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000016import testtools
17
Ghanshyam1f47cf92016-02-25 04:57:18 +090018from tempest.lib.common import api_version_request
19from tempest.lib import exceptions
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000020
21
Ghanshyam05049dd2016-02-12 17:44:48 +090022LATEST_MICROVERSION = 'latest'
23
24
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000025class BaseMicroversionTest(object):
26 """Mixin class for API microversion test class."""
27
28 # NOTE: Basically, each microversion is small API change and we
29 # can use the same tests for most microversions in most cases.
30 # So it is nice to define the test class as possible to run
31 # for all microversions. We need to define microversion range
32 # (min_microversion, max_microversion) on each test class if necessary.
33 min_microversion = None
Ghanshyam05049dd2016-02-12 17:44:48 +090034 max_microversion = LATEST_MICROVERSION
Lee Yarwood4b95d4b2020-01-15 10:49:54 +000035 volume_min_microversion = None
36 volume_max_microversion = LATEST_MICROVERSION
37 placement_min_microversion = None
38 placement_max_microversion = LATEST_MICROVERSION
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000039
40
41def check_skip_with_microversion(test_min_version, test_max_version,
42 cfg_min_version, cfg_max_version):
Ghanshyam1f47cf92016-02-25 04:57:18 +090043 """Checks API microversions range and returns whether test needs to be skip
44
45 Compare the test and configured microversion range and returns
46 whether test microversion range is out of configured one.
47 This method can be used to skip the test based on configured and test
48 microversion range.
49
50 :param test_min_version: Test Minimum Microversion
51 :param test_max_version: Test Maximum Microversion
52 :param cfg_min_version: Configured Minimum Microversion
53 :param cfg_max_version: Configured Maximum Microversion
54 :returns: boolean
55 """
56
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000057 min_version = api_version_request.APIVersionRequest(test_min_version)
58 max_version = api_version_request.APIVersionRequest(test_max_version)
59 config_min_version = api_version_request.APIVersionRequest(cfg_min_version)
60 config_max_version = api_version_request.APIVersionRequest(cfg_max_version)
61 if ((min_version > max_version) or
afazekas40fcb9b2019-03-08 11:25:11 +010062 (config_min_version > config_max_version)):
Ghanshyamd2e7a0a2016-02-02 10:53:33 +090063 msg = ("Test Class versions [%s - %s]. "
64 "Configuration versions [%s - %s]."
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000065 % (min_version.get_string(),
66 max_version.get_string(),
67 config_min_version.get_string(),
68 config_max_version.get_string()))
Ghanshyamd2e7a0a2016-02-02 10:53:33 +090069 raise exceptions.InvalidAPIVersionRange(msg)
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000070
71 # NOTE: Select tests which are in range of configuration like
72 # config min config max
73 # ----------------+--------------------------+----------------
74 # ...don't-select|
75 # ...select... ...select... ...select...
76 # |don't-select...
77 # ......................select............................
78 if (max_version < config_min_version or
79 config_max_version < min_version):
80 msg = ("The microversion range[%s - %s] of this test is out of the "
april4567efe2015-12-30 22:32:45 +080081 "configuration range[%s - %s]."
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000082 % (min_version.get_string(),
83 max_version.get_string(),
84 config_min_version.get_string(),
85 config_max_version.get_string()))
86 raise testtools.TestCase.skipException(msg)
ghanshyam4e2be342015-11-27 18:07:46 +090087
88
89def select_request_microversion(test_min_version, cfg_min_version):
ghanshyamc3b0b8b2016-03-16 11:58:34 +090090 """Select microversion from test and configuration min version.
Ghanshyam1f47cf92016-02-25 04:57:18 +090091
92 Compare requested microversion and return the maximum
93 microversion out of those.
94
95 :param test_min_version: Test Minimum Microversion
96 :param cfg_min_version: Configured Minimum Microversion
97 :returns: Selected microversion string
98 """
99
ghanshyam4e2be342015-11-27 18:07:46 +0900100 test_version = api_version_request.APIVersionRequest(test_min_version)
101 cfg_version = api_version_request.APIVersionRequest(cfg_min_version)
102 max_version = cfg_version if cfg_version >= test_version else test_version
103 return max_version.get_string()
Ghanshyambbdb33b2016-01-08 11:51:07 +0900104
105
106def assert_version_header_matches_request(api_microversion_header_name,
107 api_microversion,
108 response_header):
ghanshyamc3b0b8b2016-03-16 11:58:34 +0900109 """Checks API microversion in response header
Ghanshyambbdb33b2016-01-08 11:51:07 +0900110
111 Verify whether microversion is present in response header
112 and with specified 'api_microversion' value.
113
Ghanshyam1f47cf92016-02-25 04:57:18 +0900114 :param api_microversion_header_name: Microversion header name
Ghanshyambbdb33b2016-01-08 11:51:07 +0900115 Example- "X-OpenStack-Nova-API-Version"
chenke4beff292019-04-11 14:02:57 +0800116 :param api_microversion: Microversion number like "2.10", type str.
Ghanshyam1f47cf92016-02-25 04:57:18 +0900117 :param response_header: Response header where microversion is
Ghanshyambbdb33b2016-01-08 11:51:07 +0900118 expected to be present.
119 """
chenke4beff292019-04-11 14:02:57 +0800120 if not isinstance(api_microversion, six.string_types):
121 raise TypeError('api_microversion must be a string')
Ghanshyambbdb33b2016-01-08 11:51:07 +0900122 api_microversion_header_name = api_microversion_header_name.lower()
123 if (api_microversion_header_name not in response_header or
124 api_microversion != response_header[api_microversion_header_name]):
125 msg = ("Microversion header '%s' with value '%s' does not match in "
126 "response - %s. " % (api_microversion_header_name,
127 api_microversion,
128 response_header))
129 raise exceptions.InvalidHTTPResponseHeader(msg)
Felipe Monteiro9ff5c282017-06-21 21:05:07 +0100130
131
132def compare_version_header_to_response(api_microversion_header_name,
133 api_microversion,
134 response_header,
135 operation='eq'):
136 """Compares API microversion in response header to ``api_microversion``.
137
138 Compare the ``api_microversion`` value in response header if microversion
139 header is present in response, otherwise return false.
140
141 To make this function work for APIs which do not return microversion
142 header in response (example compute v2.0), this function does *not* raise
143 InvalidHTTPResponseHeader.
144
145 :param api_microversion_header_name: Microversion header name. Example:
146 'Openstack-Api-Version'.
147 :param api_microversion: Microversion number. Example:
148
149 * '2.10' for the old-style header name, 'X-OpenStack-Nova-API-Version'
150 * 'Compute 2.10' for the new-style header name, 'Openstack-Api-Version'
151
152 :param response_header: Response header where microversion is
153 expected to be present.
154 :param operation: The boolean operation to use to compare the
155 ``api_microversion`` to the microversion in ``response_header``.
156 Can be 'lt', 'eq', 'gt', 'le', 'ne', 'ge'. Default is 'eq'. The
157 operation type should be based on the order of the arguments:
158 ``api_microversion`` <operation> ``response_header`` microversion.
159 :returns: True if the comparison is logically true, else False if the
160 comparison is logically false or if ``api_microversion_header_name`` is
161 missing in the ``response_header``.
162 :raises InvalidParam: If the operation is not lt, eq, gt, le, ne or ge.
163 """
164 api_microversion_header_name = api_microversion_header_name.lower()
165 if api_microversion_header_name not in response_header:
166 return False
167
168 op = getattr(api_version_request.APIVersionRequest,
169 '__%s__' % operation, None)
170
171 if op is None:
172 msg = ("Operation %s is invalid. Valid options include: lt, eq, gt, "
173 "le, ne, ge." % operation)
Felipe Monteiro9ff5c282017-06-21 21:05:07 +0100174 raise exceptions.InvalidParam(invalid_param=msg)
175
176 # Remove "volume" from "volume <microversion>", for example, so that the
177 # microversion can be converted to `APIVersionRequest`.
178 api_version = api_microversion.split(' ')[-1]
179 resp_version = response_header[api_microversion_header_name].split(' ')[-1]
180 if not op(
181 api_version_request.APIVersionRequest(api_version),
182 api_version_request.APIVersionRequest(resp_version)):
183 return False
184
185 return True