Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 1 | # 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 | |
| 15 | import testtools |
| 16 | |
Ghanshyam | 1f47cf9 | 2016-02-25 04:57:18 +0900 | [diff] [blame] | 17 | from tempest.lib.common import api_version_request |
| 18 | from tempest.lib import exceptions |
Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 19 | |
| 20 | |
Ghanshyam | 05049dd | 2016-02-12 17:44:48 +0900 | [diff] [blame] | 21 | LATEST_MICROVERSION = 'latest' |
| 22 | |
| 23 | |
Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 24 | class BaseMicroversionTest(object): |
| 25 | """Mixin class for API microversion test class.""" |
| 26 | |
| 27 | # NOTE: Basically, each microversion is small API change and we |
| 28 | # can use the same tests for most microversions in most cases. |
| 29 | # So it is nice to define the test class as possible to run |
| 30 | # for all microversions. We need to define microversion range |
| 31 | # (min_microversion, max_microversion) on each test class if necessary. |
| 32 | min_microversion = None |
Ghanshyam | 05049dd | 2016-02-12 17:44:48 +0900 | [diff] [blame] | 33 | max_microversion = LATEST_MICROVERSION |
Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 34 | |
| 35 | |
| 36 | def check_skip_with_microversion(test_min_version, test_max_version, |
| 37 | cfg_min_version, cfg_max_version): |
Ghanshyam | 1f47cf9 | 2016-02-25 04:57:18 +0900 | [diff] [blame] | 38 | """Checks API microversions range and returns whether test needs to be skip |
| 39 | |
| 40 | Compare the test and configured microversion range and returns |
| 41 | whether test microversion range is out of configured one. |
| 42 | This method can be used to skip the test based on configured and test |
| 43 | microversion range. |
| 44 | |
| 45 | :param test_min_version: Test Minimum Microversion |
| 46 | :param test_max_version: Test Maximum Microversion |
| 47 | :param cfg_min_version: Configured Minimum Microversion |
| 48 | :param cfg_max_version: Configured Maximum Microversion |
| 49 | :returns: boolean |
| 50 | """ |
| 51 | |
Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 52 | min_version = api_version_request.APIVersionRequest(test_min_version) |
| 53 | max_version = api_version_request.APIVersionRequest(test_max_version) |
| 54 | config_min_version = api_version_request.APIVersionRequest(cfg_min_version) |
| 55 | config_max_version = api_version_request.APIVersionRequest(cfg_max_version) |
| 56 | if ((min_version > max_version) or |
| 57 | (config_min_version > config_max_version)): |
Ghanshyam | d2e7a0a | 2016-02-02 10:53:33 +0900 | [diff] [blame] | 58 | msg = ("Test Class versions [%s - %s]. " |
| 59 | "Configuration versions [%s - %s]." |
Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 60 | % (min_version.get_string(), |
| 61 | max_version.get_string(), |
| 62 | config_min_version.get_string(), |
| 63 | config_max_version.get_string())) |
Ghanshyam | d2e7a0a | 2016-02-02 10:53:33 +0900 | [diff] [blame] | 64 | raise exceptions.InvalidAPIVersionRange(msg) |
Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 65 | |
| 66 | # NOTE: Select tests which are in range of configuration like |
| 67 | # config min config max |
| 68 | # ----------------+--------------------------+---------------- |
| 69 | # ...don't-select| |
| 70 | # ...select... ...select... ...select... |
| 71 | # |don't-select... |
| 72 | # ......................select............................ |
| 73 | if (max_version < config_min_version or |
| 74 | config_max_version < min_version): |
| 75 | msg = ("The microversion range[%s - %s] of this test is out of the " |
april | 4567efe | 2015-12-30 22:32:45 +0800 | [diff] [blame] | 76 | "configuration range[%s - %s]." |
Ken'ichi Ohmichi | 4d237e7 | 2015-11-05 06:32:33 +0000 | [diff] [blame] | 77 | % (min_version.get_string(), |
| 78 | max_version.get_string(), |
| 79 | config_min_version.get_string(), |
| 80 | config_max_version.get_string())) |
| 81 | raise testtools.TestCase.skipException(msg) |
ghanshyam | 4e2be34 | 2015-11-27 18:07:46 +0900 | [diff] [blame] | 82 | |
| 83 | |
| 84 | def select_request_microversion(test_min_version, cfg_min_version): |
ghanshyam | c3b0b8b | 2016-03-16 11:58:34 +0900 | [diff] [blame] | 85 | """Select microversion from test and configuration min version. |
Ghanshyam | 1f47cf9 | 2016-02-25 04:57:18 +0900 | [diff] [blame] | 86 | |
| 87 | Compare requested microversion and return the maximum |
| 88 | microversion out of those. |
| 89 | |
| 90 | :param test_min_version: Test Minimum Microversion |
| 91 | :param cfg_min_version: Configured Minimum Microversion |
| 92 | :returns: Selected microversion string |
| 93 | """ |
| 94 | |
ghanshyam | 4e2be34 | 2015-11-27 18:07:46 +0900 | [diff] [blame] | 95 | test_version = api_version_request.APIVersionRequest(test_min_version) |
| 96 | cfg_version = api_version_request.APIVersionRequest(cfg_min_version) |
| 97 | max_version = cfg_version if cfg_version >= test_version else test_version |
| 98 | return max_version.get_string() |
Ghanshyam | bbdb33b | 2016-01-08 11:51:07 +0900 | [diff] [blame] | 99 | |
| 100 | |
| 101 | def assert_version_header_matches_request(api_microversion_header_name, |
| 102 | api_microversion, |
| 103 | response_header): |
ghanshyam | c3b0b8b | 2016-03-16 11:58:34 +0900 | [diff] [blame] | 104 | """Checks API microversion in response header |
Ghanshyam | bbdb33b | 2016-01-08 11:51:07 +0900 | [diff] [blame] | 105 | |
| 106 | Verify whether microversion is present in response header |
| 107 | and with specified 'api_microversion' value. |
| 108 | |
Ghanshyam | 1f47cf9 | 2016-02-25 04:57:18 +0900 | [diff] [blame] | 109 | :param api_microversion_header_name: Microversion header name |
Ghanshyam | bbdb33b | 2016-01-08 11:51:07 +0900 | [diff] [blame] | 110 | Example- "X-OpenStack-Nova-API-Version" |
Ghanshyam | 1f47cf9 | 2016-02-25 04:57:18 +0900 | [diff] [blame] | 111 | :param api_microversion: Microversion number like "2.10" |
| 112 | :param response_header: Response header where microversion is |
Ghanshyam | bbdb33b | 2016-01-08 11:51:07 +0900 | [diff] [blame] | 113 | expected to be present. |
| 114 | """ |
| 115 | api_microversion_header_name = api_microversion_header_name.lower() |
| 116 | if (api_microversion_header_name not in response_header or |
| 117 | api_microversion != response_header[api_microversion_header_name]): |
| 118 | msg = ("Microversion header '%s' with value '%s' does not match in " |
| 119 | "response - %s. " % (api_microversion_header_name, |
| 120 | api_microversion, |
| 121 | response_header)) |
| 122 | raise exceptions.InvalidHTTPResponseHeader(msg) |
Felipe Monteiro | 9ff5c28 | 2017-06-21 21:05:07 +0100 | [diff] [blame] | 123 | |
| 124 | |
| 125 | def compare_version_header_to_response(api_microversion_header_name, |
| 126 | api_microversion, |
| 127 | response_header, |
| 128 | operation='eq'): |
| 129 | """Compares API microversion in response header to ``api_microversion``. |
| 130 | |
| 131 | Compare the ``api_microversion`` value in response header if microversion |
| 132 | header is present in response, otherwise return false. |
| 133 | |
| 134 | To make this function work for APIs which do not return microversion |
| 135 | header in response (example compute v2.0), this function does *not* raise |
| 136 | InvalidHTTPResponseHeader. |
| 137 | |
| 138 | :param api_microversion_header_name: Microversion header name. Example: |
| 139 | 'Openstack-Api-Version'. |
| 140 | :param api_microversion: Microversion number. Example: |
| 141 | |
| 142 | * '2.10' for the old-style header name, 'X-OpenStack-Nova-API-Version' |
| 143 | * 'Compute 2.10' for the new-style header name, 'Openstack-Api-Version' |
| 144 | |
| 145 | :param response_header: Response header where microversion is |
| 146 | expected to be present. |
| 147 | :param operation: The boolean operation to use to compare the |
| 148 | ``api_microversion`` to the microversion in ``response_header``. |
| 149 | Can be 'lt', 'eq', 'gt', 'le', 'ne', 'ge'. Default is 'eq'. The |
| 150 | operation type should be based on the order of the arguments: |
| 151 | ``api_microversion`` <operation> ``response_header`` microversion. |
| 152 | :returns: True if the comparison is logically true, else False if the |
| 153 | comparison is logically false or if ``api_microversion_header_name`` is |
| 154 | missing in the ``response_header``. |
| 155 | :raises InvalidParam: If the operation is not lt, eq, gt, le, ne or ge. |
| 156 | """ |
| 157 | api_microversion_header_name = api_microversion_header_name.lower() |
| 158 | if api_microversion_header_name not in response_header: |
| 159 | return False |
| 160 | |
| 161 | op = getattr(api_version_request.APIVersionRequest, |
| 162 | '__%s__' % operation, None) |
| 163 | |
| 164 | if op is None: |
| 165 | msg = ("Operation %s is invalid. Valid options include: lt, eq, gt, " |
| 166 | "le, ne, ge." % operation) |
Felipe Monteiro | 9ff5c28 | 2017-06-21 21:05:07 +0100 | [diff] [blame] | 167 | raise exceptions.InvalidParam(invalid_param=msg) |
| 168 | |
| 169 | # Remove "volume" from "volume <microversion>", for example, so that the |
| 170 | # microversion can be converted to `APIVersionRequest`. |
| 171 | api_version = api_microversion.split(' ')[-1] |
| 172 | resp_version = response_header[api_microversion_header_name].split(' ')[-1] |
| 173 | if not op( |
| 174 | api_version_request.APIVersionRequest(api_version), |
| 175 | api_version_request.APIVersionRequest(resp_version)): |
| 176 | return False |
| 177 | |
| 178 | return True |