Support flavor ids with leading '0'
When Trove moved to support alphanumeric flavor ids, the case of having a numeric string id with leading zeros was not taken into account. The behavior on the client side is to see if the id is all digits, and if so it is converted to an int. That means that a flavor of '01' will be incorrectly interpreted as '1'. This behavior has been fixed and unit tests created. Change-Id: I5acdec576a2e7da6cbfbb1cfc61c49fbbf7379af Partial-Bug: #1603187
This commit is contained in:
@@ -163,7 +163,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
"status": "ACTIVE",
|
"status": "ACTIVE",
|
||||||
"ip": ["10.0.0.13"],
|
"ip": ["10.0.0.13"],
|
||||||
"volume": {"size": 2},
|
"volume": {"size": 2},
|
||||||
"flavor": {"id": "2"},
|
"flavor": {"id": "02"},
|
||||||
"datastore": {"version": "5.6", "type": "mysql"}},
|
"datastore": {"version": "5.6", "type": "mysql"}},
|
||||||
{
|
{
|
||||||
"id": "5678",
|
"id": "5678",
|
||||||
@@ -213,7 +213,12 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
"str_id": "7d0d16e5-875f-4198-b6da-90ab2d3e899e",
|
"str_id": "7d0d16e5-875f-4198-b6da-90ab2d3e899e",
|
||||||
"ram": 8192,
|
"ram": 8192,
|
||||||
"id": None,
|
"id": None,
|
||||||
"name": "m1.uuid"}]})
|
"name": "m1.uuid"},
|
||||||
|
{
|
||||||
|
"str_id": "02",
|
||||||
|
"ram": 1024,
|
||||||
|
"id": None,
|
||||||
|
"name": "m1.leading-zero"}]})
|
||||||
|
|
||||||
def get_datastores_mysql_versions_some_version_id_flavors(self, **kw):
|
def get_datastores_mysql_versions_some_version_id_flavors(self, **kw):
|
||||||
return self.get_flavors()
|
return self.get_flavors()
|
||||||
@@ -238,6 +243,14 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
r = {'flavor': self.get_flavors()[2]['flavors'][4]}
|
r = {'flavor': self.get_flavors()[2]['flavors'][4]}
|
||||||
return (200, {}, r)
|
return (200, {}, r)
|
||||||
|
|
||||||
|
def get_flavors_02(self, **kw):
|
||||||
|
r = {'flavor': self.get_flavors()[2]['flavors'][5]}
|
||||||
|
return (200, {}, r)
|
||||||
|
|
||||||
|
def get_flavors_m1_leading_zero(self, **kw):
|
||||||
|
r = {'flavor': self.get_flavors()[2]['flavors'][5]}
|
||||||
|
return (200, {}, r)
|
||||||
|
|
||||||
def get_clusters(self, **kw):
|
def get_clusters(self, **kw):
|
||||||
return (200, {}, {"clusters": [
|
return (200, {}, {"clusters": [
|
||||||
{
|
{
|
||||||
@@ -246,7 +259,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
"type": "member",
|
"type": "member",
|
||||||
"id": "member-1",
|
"id": "member-1",
|
||||||
"ip": ["10.0.0.3"],
|
"ip": ["10.0.0.3"],
|
||||||
"flavor": {"id": "2"},
|
"flavor": {"id": "02"},
|
||||||
"name": "test-clstr-member-1"
|
"name": "test-clstr-member-1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -230,6 +230,10 @@ class ShellTest(utils.TestCase):
|
|||||||
self.run_command('flavor-show 1')
|
self.run_command('flavor-show 1')
|
||||||
self.assert_called('GET', '/flavors/1')
|
self.assert_called('GET', '/flavors/1')
|
||||||
|
|
||||||
|
def test_flavor_show_leading_zero(self):
|
||||||
|
self.run_command('flavor-show 02')
|
||||||
|
self.assert_called('GET', '/flavors/02')
|
||||||
|
|
||||||
def test_flavor_show_by_name(self):
|
def test_flavor_show_by_name(self):
|
||||||
self.run_command('flavor-show m1.tiny') # defined in fakes.py
|
self.run_command('flavor-show m1.tiny') # defined in fakes.py
|
||||||
self.assert_called('GET', '/flavors/m1.tiny')
|
self.assert_called('GET', '/flavors/m1.tiny')
|
||||||
@@ -287,6 +291,17 @@ class ShellTest(utils.TestCase):
|
|||||||
'name': 'test-member-1'
|
'name': 'test-member-1'
|
||||||
}})
|
}})
|
||||||
|
|
||||||
|
def test_boot_by_flavor_leading_zero(self):
|
||||||
|
self.run_command(
|
||||||
|
'create test-member-zero 02 --size 1 --volume_type lvm')
|
||||||
|
self.assert_called_anytime(
|
||||||
|
'POST', '/instances',
|
||||||
|
{'instance': {
|
||||||
|
'volume': {'size': 1, 'type': 'lvm'},
|
||||||
|
'flavorRef': '02',
|
||||||
|
'name': 'test-member-zero'
|
||||||
|
}})
|
||||||
|
|
||||||
def test_boot_repl_set(self):
|
def test_boot_repl_set(self):
|
||||||
self.run_command('create repl-1 1 --size 1 --locality=anti-affinity '
|
self.run_command('create repl-1 1 --size 1 --locality=anti-affinity '
|
||||||
'--replica_count=4')
|
'--replica_count=4')
|
||||||
@@ -377,7 +392,7 @@ class ShellTest(utils.TestCase):
|
|||||||
|
|
||||||
def test_cluster_create(self):
|
def test_cluster_create(self):
|
||||||
cmd = ('cluster-create test-clstr vertica 7.1 '
|
cmd = ('cluster-create test-clstr vertica 7.1 '
|
||||||
'--instance flavor=2,volume=2 '
|
'--instance flavor=02,volume=2 '
|
||||||
'--instance flavor=2,volume=1 '
|
'--instance flavor=2,volume=1 '
|
||||||
'--instance flavor=2,volume=1,volume_type=my-type-1')
|
'--instance flavor=2,volume=1,volume_type=my-type-1')
|
||||||
self.run_command(cmd)
|
self.run_command(cmd)
|
||||||
@@ -387,7 +402,7 @@ class ShellTest(utils.TestCase):
|
|||||||
'instances': [
|
'instances': [
|
||||||
{
|
{
|
||||||
'volume': {'size': '2'},
|
'volume': {'size': '2'},
|
||||||
'flavorRef': '2'
|
'flavorRef': '02'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'volume': {'size': '1'},
|
'volume': {'size': '1'},
|
||||||
@@ -403,7 +418,7 @@ class ShellTest(utils.TestCase):
|
|||||||
def test_cluster_create_by_flavor_name(self):
|
def test_cluster_create_by_flavor_name(self):
|
||||||
cmd = ('cluster-create test-clstr vertica 7.1 '
|
cmd = ('cluster-create test-clstr vertica 7.1 '
|
||||||
'--instance flavor=m1.small,volume=2 '
|
'--instance flavor=m1.small,volume=2 '
|
||||||
'--instance flavor=m1.small,volume=1')
|
'--instance flavor=m1.leading-zero,volume=1')
|
||||||
self.run_command(cmd)
|
self.run_command(cmd)
|
||||||
self.assert_called_anytime(
|
self.assert_called_anytime(
|
||||||
'POST', '/clusters',
|
'POST', '/clusters',
|
||||||
@@ -415,7 +430,7 @@ class ShellTest(utils.TestCase):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'volume': {'size': '1'},
|
'volume': {'size': '1'},
|
||||||
'flavorRef': '2'
|
'flavorRef': '02'
|
||||||
}],
|
}],
|
||||||
'datastore': {'version': '7.1', 'type': 'vertica'},
|
'datastore': {'version': '7.1', 'type': 'vertica'},
|
||||||
'name': 'test-clstr'}})
|
'name': 'test-clstr'}})
|
||||||
@@ -430,7 +445,7 @@ class ShellTest(utils.TestCase):
|
|||||||
def test_cluster_grow(self):
|
def test_cluster_grow(self):
|
||||||
cmd = ('cluster-grow cls-1234 '
|
cmd = ('cluster-grow cls-1234 '
|
||||||
'--instance flavor=2,volume=2 '
|
'--instance flavor=2,volume=2 '
|
||||||
'--instance flavor=2,volume=1')
|
'--instance flavor=02,volume=1')
|
||||||
self.run_command(cmd)
|
self.run_command(cmd)
|
||||||
self.assert_called('POST', '/clusters/cls-1234')
|
self.assert_called('POST', '/clusters/cls-1234')
|
||||||
|
|
||||||
@@ -442,7 +457,7 @@ class ShellTest(utils.TestCase):
|
|||||||
def test_cluster_create_with_locality(self):
|
def test_cluster_create_with_locality(self):
|
||||||
cmd = ('cluster-create test-clstr2 redis 3.0 --locality=affinity '
|
cmd = ('cluster-create test-clstr2 redis 3.0 --locality=affinity '
|
||||||
'--instance flavor=2,volume=1 '
|
'--instance flavor=2,volume=1 '
|
||||||
'--instance flavor=2,volume=1 '
|
'--instance flavor=02,volume=1 '
|
||||||
'--instance flavor=2,volume=1 ')
|
'--instance flavor=2,volume=1 ')
|
||||||
self.run_command(cmd)
|
self.run_command(cmd)
|
||||||
self.assert_called_anytime(
|
self.assert_called_anytime(
|
||||||
@@ -451,7 +466,7 @@ class ShellTest(utils.TestCase):
|
|||||||
'instances': [
|
'instances': [
|
||||||
{'flavorRef': '2',
|
{'flavorRef': '2',
|
||||||
'volume': {'size': '1'}},
|
'volume': {'size': '1'}},
|
||||||
{'flavorRef': '2',
|
{'flavorRef': '02',
|
||||||
'volume': {'size': '1'}},
|
'volume': {'size': '1'}},
|
||||||
{'flavorRef': '2',
|
{'flavorRef': '2',
|
||||||
'volume': {'size': '1'}},
|
'volume': {'size': '1'}},
|
||||||
|
@@ -209,7 +209,9 @@ def find_resource(manager, name_or_id):
|
|||||||
"""Helper for the _find_* methods."""
|
"""Helper for the _find_* methods."""
|
||||||
# first try to get entity as integer id
|
# first try to get entity as integer id
|
||||||
|
|
||||||
if isinstance(name_or_id, int) or name_or_id.isdigit():
|
# if the 'id' starts with '0' don't treat it as an int
|
||||||
|
if isinstance(name_or_id, int) or (
|
||||||
|
name_or_id.isdigit() and not name_or_id.startswith('0')):
|
||||||
name_or_id = int(name_or_id)
|
name_or_id = int(name_or_id)
|
||||||
elif sys.version_info <= (3, 0):
|
elif sys.version_info <= (3, 0):
|
||||||
name_or_id = encodeutils.safe_decode(name_or_id)
|
name_or_id = encodeutils.safe_decode(name_or_id)
|
||||||
|
@@ -224,7 +224,8 @@ def do_flavor_list(cs, args):
|
|||||||
labels={'ram': 'RAM'})
|
labels={'ram': 'RAM'})
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('flavor', metavar='<flavor>', help='ID or name of the flavor.')
|
@utils.arg('flavor', metavar='<flavor>', type=str,
|
||||||
|
help='ID or name of the flavor.')
|
||||||
@utils.service_type('database')
|
@utils.service_type('database')
|
||||||
def do_flavor_show(cs, args):
|
def do_flavor_show(cs, args):
|
||||||
"""Shows details of a flavor."""
|
"""Shows details of a flavor."""
|
||||||
@@ -417,6 +418,7 @@ def do_update(cs, args):
|
|||||||
help="Volume type. Optional when volume support is enabled.")
|
help="Volume type. Optional when volume support is enabled.")
|
||||||
@utils.arg('flavor',
|
@utils.arg('flavor',
|
||||||
metavar='<flavor>',
|
metavar='<flavor>',
|
||||||
|
type=str,
|
||||||
help='A flavor name or ID.')
|
help='A flavor name or ID.')
|
||||||
@utils.arg('--databases', metavar='<database>',
|
@utils.arg('--databases', metavar='<database>',
|
||||||
help='Optional list of databases.',
|
help='Optional list of databases.',
|
||||||
@@ -747,6 +749,7 @@ def do_cluster_create(cs, args):
|
|||||||
help='ID or name of the instance.')
|
help='ID or name of the instance.')
|
||||||
@utils.arg('flavor',
|
@utils.arg('flavor',
|
||||||
metavar='<flavor>',
|
metavar='<flavor>',
|
||||||
|
type=str,
|
||||||
help='New flavor of the instance.')
|
help='New flavor of the instance.')
|
||||||
@utils.service_type('database')
|
@utils.service_type('database')
|
||||||
def do_resize_instance(cs, args):
|
def do_resize_instance(cs, args):
|
||||||
|
Reference in New Issue
Block a user