Make Discover.version_data accept null max_version

Make Discover.version_data a little more lenient in the JSON data it
accepts with respect to "max_version" and "version".  Previously, if the
"max_version" field was present but empty, the "version" field would be
ignored, even if populated with a proper version number.  This goes
against the intent of the API.  This change causes version_data to
ignore a blank "max_version" if "version" is populated.

This change also introduces a unit test harness for the various
permutations of version_data translating input version data to
min/max_microversion, including cases for the above.

Change-Id: I1cb4ebdd57a6eadc1a16efc0fc1ceeda640f26c2
Closes-Bug: #1703438
This commit is contained in:
Eric Fried 2017-07-10 14:00:44 -05:00
parent 37a2352a21
commit 4e4a1a89dd
2 changed files with 82 additions and 1 deletions

View File

@ -298,10 +298,16 @@ class Discover(object):
version_number = normalize_version_number(version_str)
# collect microversion information
# NOTE(efried): Some existing discovery documents (e.g. from nova
# v2.0 in the pike release) include *version keys with "" (empty
# string) values, expecting them to be treated the same as if the
# keys were absent.
min_microversion = v.get('min_version') or None
if min_microversion:
min_microversion = normalize_version_number(min_microversion)
max_microversion = v.get('max_version', v.get('version')) or None
max_microversion = v.get('max_version')
if not max_microversion:
max_microversion = v.get('version') or None
if max_microversion:
max_microversion = normalize_version_number(max_microversion)

View File

@ -359,6 +359,81 @@ class VersionDataTests(utils.TestCase):
self.assertTrue(mock.called_once)
def test_version_data_microversions(self):
"""Validate [min_|max_]version conversion to {min|max}_microversion."""
def setup_mock(versions_in):
# Set up the test data with the input version data
jsondata = {
"versions": [
dict(
{
"status": "CURRENT",
"id": "v2.2",
"links": [
{
"href": V3_URL,
"rel": "self"
}
]
},
**versions_in
)
]
}
self.requests_mock.get(
V3_URL, status_code=200, json=jsondata)
def test_ok(versions_in, versions_out):
setup_mock(versions_in)
# Ensure the output contains the expected microversions
self.assertEqual(
[
dict(
{
'collection': None,
'version': (2, 2),
'url': V3_URL,
'raw_status': 'CURRENT',
},
**versions_out
)
],
discover.Discover(self.session, V3_URL).version_data())
def test_exc(versions_in):
setup_mock(versions_in)
# Ensure TypeError is raised
self.assertRaises(
TypeError,
discover.Discover(self.session, V3_URL).version_data)
# no version info in input
test_ok({},
{'min_microversion': None, 'max_microversion': None})
# version => max_microversion
test_ok({'version': '2.2'},
{'min_microversion': None, 'max_microversion': (2, 2)})
# max_version supersedes version (even if malformed). min_version &
# normalization.
test_ok({'min_version': '2', 'version': 'foo', 'max_version': '2.2'},
{'min_microversion': (2, 0), 'max_microversion': (2, 2)})
# Edge case: min/max_version ignored if present but "empty"; version
# used for max_microversion.
test_ok({'min_version': '', 'version': '2.1', 'max_version': ''},
{'min_microversion': None, 'max_microversion': (2, 1)})
# Badly-formatted min_version
test_exc({'min_version': 'foo', 'max_version': '2.1'})
# Badly-formatted max_version
test_exc({'min_version': '2.1', 'max_version': 'foo'})
# Badly-formatted version (when max_version omitted)
test_exc({'min_version': '2.1', 'version': 'foo'})
def test_data_for_url(self):
mock = self.requests_mock.get(V3_URL,
status_code=200,