blob: d29362d976d58f743549ff78c5d9e585c9539626 [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
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000035
36
37def check_skip_with_microversion(test_min_version, test_max_version,
38 cfg_min_version, cfg_max_version):
Ghanshyam1f47cf92016-02-25 04:57:18 +090039 """Checks API microversions range and returns whether test needs to be skip
40
41 Compare the test and configured microversion range and returns
42 whether test microversion range is out of configured one.
43 This method can be used to skip the test based on configured and test
44 microversion range.
45
46 :param test_min_version: Test Minimum Microversion
47 :param test_max_version: Test Maximum Microversion
48 :param cfg_min_version: Configured Minimum Microversion
49 :param cfg_max_version: Configured Maximum Microversion
50 :returns: boolean
51 """
52
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000053 min_version = api_version_request.APIVersionRequest(test_min_version)
54 max_version = api_version_request.APIVersionRequest(test_max_version)
55 config_min_version = api_version_request.APIVersionRequest(cfg_min_version)
56 config_max_version = api_version_request.APIVersionRequest(cfg_max_version)
57 if ((min_version > max_version) or
afazekas40fcb9b2019-03-08 11:25:11 +010058 (config_min_version > config_max_version)):
Ghanshyamd2e7a0a2016-02-02 10:53:33 +090059 msg = ("Test Class versions [%s - %s]. "
60 "Configuration versions [%s - %s]."
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000061 % (min_version.get_string(),
62 max_version.get_string(),
63 config_min_version.get_string(),
64 config_max_version.get_string()))
Ghanshyamd2e7a0a2016-02-02 10:53:33 +090065 raise exceptions.InvalidAPIVersionRange(msg)
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000066
67 # NOTE: Select tests which are in range of configuration like
68 # config min config max
69 # ----------------+--------------------------+----------------
70 # ...don't-select|
71 # ...select... ...select... ...select...
72 # |don't-select...
73 # ......................select............................
74 if (max_version < config_min_version or
75 config_max_version < min_version):
76 msg = ("The microversion range[%s - %s] of this test is out of the "
april4567efe2015-12-30 22:32:45 +080077 "configuration range[%s - %s]."
Ken'ichi Ohmichi4d237e72015-11-05 06:32:33 +000078 % (min_version.get_string(),
79 max_version.get_string(),
80 config_min_version.get_string(),
81 config_max_version.get_string()))
82 raise testtools.TestCase.skipException(msg)
ghanshyam4e2be342015-11-27 18:07:46 +090083
84
85def select_request_microversion(test_min_version, cfg_min_version):
ghanshyamc3b0b8b2016-03-16 11:58:34 +090086 """Select microversion from test and configuration min version.
Ghanshyam1f47cf92016-02-25 04:57:18 +090087
88 Compare requested microversion and return the maximum
89 microversion out of those.
90
91 :param test_min_version: Test Minimum Microversion
92 :param cfg_min_version: Configured Minimum Microversion
93 :returns: Selected microversion string
94 """
95
ghanshyam4e2be342015-11-27 18:07:46 +090096 test_version = api_version_request.APIVersionRequest(test_min_version)
97 cfg_version = api_version_request.APIVersionRequest(cfg_min_version)
98 max_version = cfg_version if cfg_version >= test_version else test_version
99 return max_version.get_string()
Ghanshyambbdb33b2016-01-08 11:51:07 +0900100
101
102def assert_version_header_matches_request(api_microversion_header_name,
103 api_microversion,
104 response_header):
ghanshyamc3b0b8b2016-03-16 11:58:34 +0900105 """Checks API microversion in response header
Ghanshyambbdb33b2016-01-08 11:51:07 +0900106
107 Verify whether microversion is present in response header
108 and with specified 'api_microversion' value.
109
Ghanshyam1f47cf92016-02-25 04:57:18 +0900110 :param api_microversion_header_name: Microversion header name
Ghanshyambbdb33b2016-01-08 11:51:07 +0900111 Example- "X-OpenStack-Nova-API-Version"
chenke4beff292019-04-11 14:02:57 +0800112 :param api_microversion: Microversion number like "2.10", type str.
Ghanshyam1f47cf92016-02-25 04:57:18 +0900113 :param response_header: Response header where microversion is
Ghanshyambbdb33b2016-01-08 11:51:07 +0900114 expected to be present.
115 """
chenke4beff292019-04-11 14:02:57 +0800116 if not isinstance(api_microversion, six.string_types):
117 raise TypeError('api_microversion must be a string')
Ghanshyambbdb33b2016-01-08 11:51:07 +0900118 api_microversion_header_name = api_microversion_header_name.lower()
119 if (api_microversion_header_name not in response_header or
120 api_microversion != response_header[api_microversion_header_name]):
121 msg = ("Microversion header '%s' with value '%s' does not match in "
122 "response - %s. " % (api_microversion_header_name,
123 api_microversion,
124 response_header))
125 raise exceptions.InvalidHTTPResponseHeader(msg)
Felipe Monteiro9ff5c282017-06-21 21:05:07 +0100126
127
128def compare_version_header_to_response(api_microversion_header_name,
129 api_microversion,
130 response_header,
131 operation='eq'):
132 """Compares API microversion in response header to ``api_microversion``.
133
134 Compare the ``api_microversion`` value in response header if microversion
135 header is present in response, otherwise return false.
136
137 To make this function work for APIs which do not return microversion
138 header in response (example compute v2.0), this function does *not* raise
139 InvalidHTTPResponseHeader.
140
141 :param api_microversion_header_name: Microversion header name. Example:
142 'Openstack-Api-Version'.
143 :param api_microversion: Microversion number. Example:
144
145 * '2.10' for the old-style header name, 'X-OpenStack-Nova-API-Version'
146 * 'Compute 2.10' for the new-style header name, 'Openstack-Api-Version'
147
148 :param response_header: Response header where microversion is
149 expected to be present.
150 :param operation: The boolean operation to use to compare the
151 ``api_microversion`` to the microversion in ``response_header``.
152 Can be 'lt', 'eq', 'gt', 'le', 'ne', 'ge'. Default is 'eq'. The
153 operation type should be based on the order of the arguments:
154 ``api_microversion`` <operation> ``response_header`` microversion.
155 :returns: True if the comparison is logically true, else False if the
156 comparison is logically false or if ``api_microversion_header_name`` is
157 missing in the ``response_header``.
158 :raises InvalidParam: If the operation is not lt, eq, gt, le, ne or ge.
159 """
160 api_microversion_header_name = api_microversion_header_name.lower()
161 if api_microversion_header_name not in response_header:
162 return False
163
164 op = getattr(api_version_request.APIVersionRequest,
165 '__%s__' % operation, None)
166
167 if op is None:
168 msg = ("Operation %s is invalid. Valid options include: lt, eq, gt, "
169 "le, ne, ge." % operation)
Felipe Monteiro9ff5c282017-06-21 21:05:07 +0100170 raise exceptions.InvalidParam(invalid_param=msg)
171
172 # Remove "volume" from "volume <microversion>", for example, so that the
173 # microversion can be converted to `APIVersionRequest`.
174 api_version = api_microversion.split(' ')[-1]
175 resp_version = response_header[api_microversion_header_name].split(' ')[-1]
176 if not op(
177 api_version_request.APIVersionRequest(api_version),
178 api_version_request.APIVersionRequest(resp_version)):
179 return False
180
181 return True