"group" word should be used instead "pool"
Currently, when creating a new flavor, here it need to set pool group name for the first argument "pool". For making clear between a pool and pool group, So we should replace "pool" word with "pool_group" at all the places. According the discussion in IRC, for giving users time to mirgate, we will support 'pool' and 'pool_group' both in M, and will remove 'pool' in N. APIImpact Change-Id: Id4c976a1fc9cc7fb9b72482b4e3a7f7f80f94492 Closes-Bug: #1504959
This commit is contained in:
parent
a425e1104d
commit
f204280187
@ -38,14 +38,26 @@ patch_pool = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patch_pool_group = {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'pool_group': {
|
||||||
|
'type': 'string'
|
||||||
|
},
|
||||||
|
'additionalProperties': False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
create = {
|
create = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
|
'pool_group': patch_pool_group['properties']['pool_group'],
|
||||||
'pool': patch_pool['properties']['pool'],
|
'pool': patch_pool['properties']['pool'],
|
||||||
'capabilities': patch_capabilities['properties']['capabilities']
|
'capabilities': patch_capabilities['properties']['capabilities']
|
||||||
},
|
},
|
||||||
# NOTE(flaper87): capabilities need not be present. Storage drivers
|
# NOTE(flaper87): capabilities need not be present. Storage drivers
|
||||||
# must provide reasonable defaults.
|
# must provide reasonable defaults.
|
||||||
'required': ['pool'],
|
# NOTE(wanghao): remove pool in Newton release.
|
||||||
|
'oneOf': [{'required': ['pool_group']}, {'required': ['pool']}],
|
||||||
'additionalProperties': False
|
'additionalProperties': False
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,14 @@ class PoolDoesNotExist(DoesNotExist):
|
|||||||
super(PoolDoesNotExist, self).__init__(pool=pool)
|
super(PoolDoesNotExist, self).__init__(pool=pool)
|
||||||
|
|
||||||
|
|
||||||
|
class PoolGroupDoesNotExist(DoesNotExist):
|
||||||
|
|
||||||
|
msg_format = u'Pool group {pool_group} does not exist'
|
||||||
|
|
||||||
|
def __init__(self, pool_group):
|
||||||
|
super(PoolGroupDoesNotExist, self).__init__(pool_group=pool_group)
|
||||||
|
|
||||||
|
|
||||||
class FlavorDoesNotExist(DoesNotExist):
|
class FlavorDoesNotExist(DoesNotExist):
|
||||||
|
|
||||||
msg_format = u'Flavor {flavor} does not exist'
|
msg_format = u'Flavor {flavor} does not exist'
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
Schema:
|
Schema:
|
||||||
'n': name :: six.text_type
|
'n': name :: six.text_type
|
||||||
'p': project :: six.text_type
|
'p': project :: six.text_type
|
||||||
's': storage pool :: six.text_type
|
's': storage pool_group :: six.text_type
|
||||||
'c': capabilities :: dict
|
'c': capabilities :: dict
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -56,13 +56,13 @@ class FlavorsController(base.FlavorsBase):
|
|||||||
unique=True)
|
unique=True)
|
||||||
self._col.ensure_index(FLAVORS_STORAGE_POOL_INDEX,
|
self._col.ensure_index(FLAVORS_STORAGE_POOL_INDEX,
|
||||||
background=True,
|
background=True,
|
||||||
name='flavors_storage_pool_name')
|
name='flavors_storage_pool_group_name')
|
||||||
|
|
||||||
self._pools_ctrl = self.driver.pools_controller
|
self._pools_ctrl = self.driver.pools_controller
|
||||||
|
|
||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
def _list_by_pool(self, pool, limit=10, detailed=False):
|
def _list_by_pool_group(self, pool_group, limit=10, detailed=False):
|
||||||
query = {'s': pool}
|
query = {'s': pool_group}
|
||||||
cursor = self._col.find(query, projection=_field_spec(detailed),
|
cursor = self._col.find(query, projection=_field_spec(detailed),
|
||||||
limit=limit).sort('n', 1)
|
limit=limit).sort('n', 1)
|
||||||
|
|
||||||
@ -97,16 +97,18 @@ class FlavorsController(base.FlavorsBase):
|
|||||||
return _normalize(res, detailed)
|
return _normalize(res, detailed)
|
||||||
|
|
||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
def create(self, name, pool, project=None, capabilities=None):
|
def create(self, name, pool_group, project=None, capabilities=None):
|
||||||
|
|
||||||
# NOTE(flaper87): Check if there are pools in this group.
|
# NOTE(flaper87): Check if there are pools in this group.
|
||||||
# Should there be a `group_exists` method?
|
# Should there be a `group_exists` method?
|
||||||
if not list(self._pools_ctrl.get_pools_by_group(pool)):
|
# NOTE(wanghao): Since we didn't pass the group name just pool name,
|
||||||
raise errors.PoolDoesNotExist(pool)
|
# so we don't need to get the pool by group.
|
||||||
|
if not list(self._pools_ctrl.get_pools_by_group(pool_group)):
|
||||||
|
raise errors.PoolGroupDoesNotExist(pool_group)
|
||||||
|
|
||||||
capabilities = {} if capabilities is None else capabilities
|
capabilities = {} if capabilities is None else capabilities
|
||||||
self._col.update({'n': name, 'p': project},
|
self._col.update({'n': name, 'p': project},
|
||||||
{'$set': {'s': pool, 'c': capabilities}},
|
{'$set': {'s': pool_group, 'c': capabilities}},
|
||||||
upsert=True)
|
upsert=True)
|
||||||
|
|
||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
@ -114,16 +116,16 @@ class FlavorsController(base.FlavorsBase):
|
|||||||
return self._col.find_one({'n': name, 'p': project}) is not None
|
return self._col.find_one({'n': name, 'p': project}) is not None
|
||||||
|
|
||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
def update(self, name, project=None, pool=None, capabilities=None):
|
def update(self, name, project=None, pool_group=None, capabilities=None):
|
||||||
fields = {}
|
fields = {}
|
||||||
|
|
||||||
if capabilities is not None:
|
if capabilities is not None:
|
||||||
fields['c'] = capabilities
|
fields['c'] = capabilities
|
||||||
|
|
||||||
if pool is not None:
|
if pool_group is not None:
|
||||||
fields['s'] = pool
|
fields['s'] = pool_group
|
||||||
|
|
||||||
assert fields, '`pool` or `capabilities` not found in kwargs'
|
assert fields, '`pool_group` or `capabilities` not found in kwargs'
|
||||||
res = self._col.update({'n': name, 'p': project},
|
res = self._col.update({'n': name, 'p': project},
|
||||||
{'$set': fields},
|
{'$set': fields},
|
||||||
upsert=False)
|
upsert=False)
|
||||||
@ -144,7 +146,7 @@ class FlavorsController(base.FlavorsBase):
|
|||||||
def _normalize(flavor, detailed=False):
|
def _normalize(flavor, detailed=False):
|
||||||
ret = {
|
ret = {
|
||||||
'name': flavor['n'],
|
'name': flavor['n'],
|
||||||
'pool': flavor['s'],
|
'pool_group': flavor['s'],
|
||||||
}
|
}
|
||||||
|
|
||||||
if detailed:
|
if detailed:
|
||||||
|
@ -137,7 +137,7 @@ class PoolsController(base.PoolsBase):
|
|||||||
pool = self.get(name)
|
pool = self.get(name)
|
||||||
pools_group = self.get_pools_by_group(pool['group'])
|
pools_group = self.get_pools_by_group(pool['group'])
|
||||||
flavor_ctl = self.driver.flavors_controller
|
flavor_ctl = self.driver.flavors_controller
|
||||||
res = list(flavor_ctl._list_by_pool(pool['group']))
|
res = list(flavor_ctl._list_by_pool_group(pool['group']))
|
||||||
|
|
||||||
# NOTE(flaper87): If this is the only pool in the
|
# NOTE(flaper87): If this is the only pool in the
|
||||||
# group and it's being used by a flavor, don't allow
|
# group and it's being used by a flavor, don't allow
|
||||||
|
@ -490,7 +490,7 @@ class Catalog(object):
|
|||||||
if flavor is not None:
|
if flavor is not None:
|
||||||
flavor = self._flavor_ctrl.get(flavor, project=project)
|
flavor = self._flavor_ctrl.get(flavor, project=project)
|
||||||
pools = self._pools_ctrl.get_pools_by_group(
|
pools = self._pools_ctrl.get_pools_by_group(
|
||||||
group=flavor['pool'],
|
group=flavor['pool_group'],
|
||||||
detailed=True)
|
detailed=True)
|
||||||
pool = select.weighted(pools)
|
pool = select.weighted(pools)
|
||||||
pool = pool and pool['name'] or None
|
pool = pool and pool['name'] or None
|
||||||
|
@ -71,21 +71,22 @@ class FlavorsController(base.FlavorsBase):
|
|||||||
return _normalize(flavor, detailed)
|
return _normalize(flavor, detailed)
|
||||||
|
|
||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
def create(self, name, pool, project=None, capabilities=None):
|
def create(self, name, pool_group, project=None, capabilities=None):
|
||||||
cap = None if capabilities is None else utils.json_encode(capabilities)
|
cap = None if capabilities is None else utils.json_encode(capabilities)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stmt = sa.sql.expression.insert(tables.Flavors).values(
|
stmt = sa.sql.expression.insert(tables.Flavors).values(
|
||||||
name=name, pool=pool, project=project, capabilities=cap
|
name=name, pool_group=pool_group, project=project,
|
||||||
|
capabilities=cap
|
||||||
)
|
)
|
||||||
self.driver.connection.execute(stmt)
|
self.driver.connection.execute(stmt)
|
||||||
except sa.exc.IntegrityError:
|
except sa.exc.IntegrityError:
|
||||||
if not self._pools_ctrl.get_pools_by_group(pool):
|
if not self._pools_ctrl.get_pools_by_group(pool_group):
|
||||||
raise errors.PoolDoesNotExist(pool)
|
raise errors.PoolGroupDoesNotExist(pool_group)
|
||||||
|
|
||||||
# TODO(flaper87): merge update/create into a single
|
# TODO(flaper87): merge update/create into a single
|
||||||
# method with introduction of upsert
|
# method with introduction of upsert
|
||||||
self.update(name, pool=pool,
|
self.update(name, pool_group=pool_group,
|
||||||
project=project,
|
project=project,
|
||||||
capabilities=cap)
|
capabilities=cap)
|
||||||
|
|
||||||
@ -98,16 +99,16 @@ class FlavorsController(base.FlavorsBase):
|
|||||||
return self.driver.connection.execute(stmt).fetchone() is not None
|
return self.driver.connection.execute(stmt).fetchone() is not None
|
||||||
|
|
||||||
@utils.raises_conn_error
|
@utils.raises_conn_error
|
||||||
def update(self, name, project=None, pool=None, capabilities=None):
|
def update(self, name, project=None, pool_group=None, capabilities=None):
|
||||||
fields = {}
|
fields = {}
|
||||||
|
|
||||||
if capabilities is not None:
|
if capabilities is not None:
|
||||||
fields['capabilities'] = capabilities
|
fields['capabilities'] = capabilities
|
||||||
|
|
||||||
if pool is not None:
|
if pool_group is not None:
|
||||||
fields['pool'] = pool
|
fields['pool_group'] = pool_group
|
||||||
|
|
||||||
assert fields, '`pool` or `capabilities` not found in kwargs'
|
assert fields, '`pool_group` or `capabilities` not found in kwargs'
|
||||||
if 'capabilities' in fields:
|
if 'capabilities' in fields:
|
||||||
fields['capabilities'] = utils.json_encode(fields['capabilities'])
|
fields['capabilities'] = utils.json_encode(fields['capabilities'])
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ class FlavorsController(base.FlavorsBase):
|
|||||||
def _normalize(flavor, detailed=False):
|
def _normalize(flavor, detailed=False):
|
||||||
ret = {
|
ret = {
|
||||||
'name': flavor[0],
|
'name': flavor[0],
|
||||||
'pool': flavor[2],
|
'pool_group': flavor[2],
|
||||||
}
|
}
|
||||||
|
|
||||||
if detailed:
|
if detailed:
|
||||||
|
@ -46,8 +46,8 @@ Pools = sa.Table('Pools', metadata,
|
|||||||
Flavors = sa.Table('Flavors', metadata,
|
Flavors = sa.Table('Flavors', metadata,
|
||||||
sa.Column('name', sa.String(64), primary_key=True),
|
sa.Column('name', sa.String(64), primary_key=True),
|
||||||
sa.Column('project', sa.String(64)),
|
sa.Column('project', sa.String(64)),
|
||||||
sa.Column('pool', sa.ForeignKey('PoolGroup.name',
|
sa.Column('pool_group', sa.ForeignKey('PoolGroup.name',
|
||||||
ondelete='CASCADE'),
|
ondelete='CASCADE'),
|
||||||
nullable=False),
|
nullable=False),
|
||||||
sa.Column('capabilities', sa.Text()))
|
sa.Column('capabilities', sa.Text()))
|
||||||
|
|
||||||
|
@ -1424,8 +1424,8 @@ class FlavorsControllerTest(ControllerBaseTest):
|
|||||||
self.assertIn('name', flavor)
|
self.assertIn('name', flavor)
|
||||||
self.assertEqual(xname, flavor['name'])
|
self.assertEqual(xname, flavor['name'])
|
||||||
self.assertNotIn('project', flavor)
|
self.assertNotIn('project', flavor)
|
||||||
self.assertIn('pool', flavor)
|
self.assertIn('pool_group', flavor)
|
||||||
self.assertEqual(xpool, flavor['pool'])
|
self.assertEqual(xpool, flavor['pool_group'])
|
||||||
|
|
||||||
def test_create_replaces_on_duplicate_insert(self):
|
def test_create_replaces_on_duplicate_insert(self):
|
||||||
name = str(uuid.uuid1())
|
name = str(uuid.uuid1())
|
||||||
@ -1493,18 +1493,18 @@ class FlavorsControllerTest(ControllerBaseTest):
|
|||||||
detailed=True)
|
detailed=True)
|
||||||
|
|
||||||
p = 'olympic'
|
p = 'olympic'
|
||||||
group = 'sports'
|
pool_group = 'sports'
|
||||||
self.pools_controller.create(p, 100, 'localhost2',
|
self.pools_controller.create(p, 100, 'localhost2',
|
||||||
group=group, options={})
|
group=pool_group, options={})
|
||||||
self.addCleanup(self.pools_controller.delete, p)
|
self.addCleanup(self.pools_controller.delete, p)
|
||||||
|
|
||||||
new_capabilities = {'fifo': False}
|
new_capabilities = {'fifo': False}
|
||||||
self.flavors_controller.update(name, project=self.project,
|
self.flavors_controller.update(name, project=self.project,
|
||||||
pool=group,
|
pool_group=pool_group,
|
||||||
capabilities={'fifo': False})
|
capabilities={'fifo': False})
|
||||||
res = self.flavors_controller.get(name, project=self.project,
|
res = self.flavors_controller.get(name, project=self.project,
|
||||||
detailed=True)
|
detailed=True)
|
||||||
self._flavors_expects(res, name, self.project, group)
|
self._flavors_expects(res, name, self.project, pool_group)
|
||||||
self.assertEqual(new_capabilities, res['capabilities'])
|
self.assertEqual(new_capabilities, res['capabilities'])
|
||||||
|
|
||||||
def test_delete_works(self):
|
def test_delete_works(self):
|
||||||
@ -1529,13 +1529,15 @@ class FlavorsControllerTest(ControllerBaseTest):
|
|||||||
name_gen = lambda i: chr(ord('A') + i)
|
name_gen = lambda i: chr(ord('A') + i)
|
||||||
for i in range(15):
|
for i in range(15):
|
||||||
pool = str(i)
|
pool = str(i)
|
||||||
|
pool_group = pool
|
||||||
uri = 'localhost:2701' + pool
|
uri = 'localhost:2701' + pool
|
||||||
self.pools_controller.create(pool, 100, uri,
|
self.pools_controller.create(pool, 100, uri,
|
||||||
group=pool, options={})
|
group=pool_group, options={})
|
||||||
self.addCleanup(self.pools_controller.delete, pool)
|
self.addCleanup(self.pools_controller.delete, pool)
|
||||||
|
|
||||||
self.flavors_controller.create(name_gen(i), project=self.project,
|
self.flavors_controller.create(name_gen(i), project=self.project,
|
||||||
pool=pool, capabilities={})
|
pool_group=pool_group,
|
||||||
|
capabilities={})
|
||||||
|
|
||||||
def get_res(**kwargs):
|
def get_res(**kwargs):
|
||||||
cursor = self.flavors_controller.list(project=self.project,
|
cursor = self.flavors_controller.list(project=self.project,
|
||||||
|
@ -24,7 +24,7 @@ from zaqar.tests.unit.transport.wsgi import base
|
|||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def flavor(test, name, pool, capabilities={}):
|
def flavor(test, name, pool_group, capabilities={}):
|
||||||
"""A context manager for constructing a flavor for use in testing.
|
"""A context manager for constructing a flavor for use in testing.
|
||||||
|
|
||||||
Deletes the flavor after exiting the context.
|
Deletes the flavor after exiting the context.
|
||||||
@ -32,27 +32,27 @@ def flavor(test, name, pool, capabilities={}):
|
|||||||
:param test: Must expose simulate_* methods
|
:param test: Must expose simulate_* methods
|
||||||
:param name: Name for this flavor
|
:param name: Name for this flavor
|
||||||
:type name: six.text_type
|
:type name: six.text_type
|
||||||
:type pool: six.text_type
|
:type pool_group: six.text_type
|
||||||
:type capabilities: dict
|
:type capabilities: dict
|
||||||
:returns: (name, uri, capabilities)
|
:returns: (name, uri, capabilities)
|
||||||
:rtype: see above
|
:rtype: see above
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
doc = {'pool': pool, 'capabilities': capabilities}
|
doc = {'pool_group': pool_group, 'capabilities': capabilities}
|
||||||
path = test.url_prefix + '/flavors/' + name
|
path = test.url_prefix + '/flavors/' + name
|
||||||
|
|
||||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield name, pool, capabilities
|
yield name, pool_group, capabilities
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
test.simulate_delete(path)
|
test.simulate_delete(path)
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def flavors(test, count, pool):
|
def flavors(test, count, pool_group):
|
||||||
"""A context manager for constructing flavors for use in testing.
|
"""A context manager for constructing flavors for use in testing.
|
||||||
|
|
||||||
Deletes the flavors after exiting the context.
|
Deletes the flavors after exiting the context.
|
||||||
@ -60,7 +60,7 @@ def flavors(test, count, pool):
|
|||||||
:param test: Must expose simulate_* methods
|
:param test: Must expose simulate_* methods
|
||||||
:param count: Number of pools to create
|
:param count: Number of pools to create
|
||||||
:type count: int
|
:type count: int
|
||||||
:returns: (paths, pool, capabilities)
|
:returns: (paths, pool_group, capabilities)
|
||||||
:rtype: ([six.text_type], [six.text_type], [dict])
|
:rtype: ([six.text_type], [six.text_type], [dict])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -69,7 +69,7 @@ def flavors(test, count, pool):
|
|||||||
args = sorted([(base + str(i), {str(i): i}, str(i)) for i in range(count)],
|
args = sorted([(base + str(i), {str(i): i}, str(i)) for i in range(count)],
|
||||||
key=lambda tup: tup[2])
|
key=lambda tup: tup[2])
|
||||||
for path, capabilities, _ in args:
|
for path, capabilities, _ in args:
|
||||||
doc = {'pool': pool, 'capabilities': capabilities}
|
doc = {'pool_group': pool_group, 'capabilities': capabilities}
|
||||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -99,7 +99,7 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
self.simulate_put(self.pool_path, body=jsonutils.dumps(self.pool_doc))
|
self.simulate_put(self.pool_path, body=jsonutils.dumps(self.pool_doc))
|
||||||
|
|
||||||
self.flavor = 'test-flavor'
|
self.flavor = 'test-flavor'
|
||||||
self.doc = {'capabilities': {}, 'pool': self.pool_group}
|
self.doc = {'capabilities': {}, 'pool_group': self.pool_group}
|
||||||
self.flavor_path = self.url_prefix + '/flavors/' + self.flavor
|
self.flavor_path = self.url_prefix + '/flavors/' + self.flavor
|
||||||
self.simulate_put(self.flavor_path, body=jsonutils.dumps(self.doc))
|
self.simulate_put(self.flavor_path, body=jsonutils.dumps(self.doc))
|
||||||
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
||||||
@ -114,7 +114,7 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
|
|
||||||
def test_put_flavor_works(self):
|
def test_put_flavor_works(self):
|
||||||
name = str(uuid.uuid1())
|
name = str(uuid.uuid1())
|
||||||
with flavor(self, name, self.doc['pool']):
|
with flavor(self, name, self.doc['pool_group']):
|
||||||
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
||||||
|
|
||||||
def test_put_raises_if_missing_fields(self):
|
def test_put_raises_if_missing_fields(self):
|
||||||
@ -130,13 +130,13 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
def test_put_raises_if_invalid_pool(self, pool):
|
def test_put_raises_if_invalid_pool(self, pool):
|
||||||
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
||||||
self.simulate_put(path,
|
self.simulate_put(path,
|
||||||
body=jsonutils.dumps({'pool': pool}))
|
body=jsonutils.dumps({'pool_group': pool}))
|
||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
@ddt.data(-1, 'wee', [])
|
@ddt.data(-1, 'wee', [])
|
||||||
def test_put_raises_if_invalid_capabilities(self, capabilities):
|
def test_put_raises_if_invalid_capabilities(self, capabilities):
|
||||||
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
||||||
doc = {'pool': 'a', 'capabilities': capabilities}
|
doc = {'pool_group': 'a', 'capabilities': capabilities}
|
||||||
self.simulate_put(path, body=jsonutils.dumps(doc))
|
self.simulate_put(path, body=jsonutils.dumps(doc))
|
||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
@ -150,9 +150,9 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
result = self.simulate_get(self.flavor_path)
|
result = self.simulate_get(self.flavor_path)
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
doc = jsonutils.loads(result[0])
|
doc = jsonutils.loads(result[0])
|
||||||
self.assertEqual(expect['pool'], doc['pool'])
|
self.assertEqual(expect['pool_group'], doc['pool_group'])
|
||||||
|
|
||||||
def test_create_flavor_no_pool(self):
|
def test_create_flavor_no_pool_group(self):
|
||||||
self.simulate_delete(self.flavor_path)
|
self.simulate_delete(self.flavor_path)
|
||||||
self.assertEqual(falcon.HTTP_204, self.srmock.status)
|
self.assertEqual(falcon.HTTP_204, self.srmock.status)
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{'description': 'Flavor test-flavor could not be created. '
|
{'description': 'Flavor test-flavor could not be created. '
|
||||||
'Pool mypool-group does not exist',
|
'Pool group mypool-group does not exist',
|
||||||
'title': 'Unable to create'},
|
'title': 'Unable to create'},
|
||||||
jsonutils.loads(resp[0]))
|
jsonutils.loads(resp[0]))
|
||||||
|
|
||||||
@ -183,23 +183,23 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
self.assertIn('href', flavor)
|
self.assertIn('href', flavor)
|
||||||
self.assertIn('name', flavor)
|
self.assertIn('name', flavor)
|
||||||
self.assertEqual(xhref, flavor['href'])
|
self.assertEqual(xhref, flavor['href'])
|
||||||
self.assertIn('pool', flavor)
|
self.assertIn('pool_group', flavor)
|
||||||
self.assertEqual(xpool, flavor['pool'])
|
self.assertEqual(xpool, flavor['pool_group'])
|
||||||
|
|
||||||
def test_get_works(self):
|
def test_get_works(self):
|
||||||
result = self.simulate_get(self.flavor_path)
|
result = self.simulate_get(self.flavor_path)
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
pool = jsonutils.loads(result[0])
|
flavor = jsonutils.loads(result[0])
|
||||||
self._flavor_expect(pool, self.flavor_path, self.doc['pool'])
|
self._flavor_expect(flavor, self.flavor_path, self.doc['pool_group'])
|
||||||
|
|
||||||
def test_detailed_get_works(self):
|
def test_detailed_get_works(self):
|
||||||
result = self.simulate_get(self.flavor_path,
|
result = self.simulate_get(self.flavor_path,
|
||||||
query_string='detailed=True')
|
query_string='detailed=True')
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
pool = jsonutils.loads(result[0])
|
flavor = jsonutils.loads(result[0])
|
||||||
self._flavor_expect(pool, self.flavor_path, self.doc['pool'])
|
self._flavor_expect(flavor, self.flavor_path, self.doc['pool_group'])
|
||||||
self.assertIn('capabilities', pool)
|
self.assertIn('capabilities', flavor)
|
||||||
self.assertEqual({}, pool['capabilities'])
|
self.assertEqual({}, flavor['capabilities'])
|
||||||
|
|
||||||
def test_patch_raises_if_missing_fields(self):
|
def test_patch_raises_if_missing_fields(self):
|
||||||
self.simulate_patch(self.flavor_path,
|
self.simulate_patch(self.flavor_path,
|
||||||
@ -214,23 +214,23 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
result = self.simulate_get(self.flavor_path,
|
result = self.simulate_get(self.flavor_path,
|
||||||
query_string='detailed=True')
|
query_string='detailed=True')
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
pool = jsonutils.loads(result[0])
|
flavor = jsonutils.loads(result[0])
|
||||||
self._flavor_expect(pool, self.flavor_path, doc['pool'])
|
self._flavor_expect(flavor, self.flavor_path, doc['pool_group'])
|
||||||
self.assertEqual(doc['capabilities'], pool['capabilities'])
|
self.assertEqual(doc['capabilities'], flavor['capabilities'])
|
||||||
|
|
||||||
def test_patch_works(self):
|
def test_patch_works(self):
|
||||||
doc = {'pool': 'my-pool', 'capabilities': {'a': 1}}
|
doc = {'pool_group': 'my-pool-group', 'capabilities': {'a': 1}}
|
||||||
self._patch_test(doc)
|
self._patch_test(doc)
|
||||||
|
|
||||||
def test_patch_works_with_extra_fields(self):
|
def test_patch_works_with_extra_fields(self):
|
||||||
doc = {'pool': 'my-pool', 'capabilities': {'a': 1},
|
doc = {'pool_group': 'my-pool-group', 'capabilities': {'a': 1},
|
||||||
'location': 100, 'partition': 'taco'}
|
'location': 100, 'partition': 'taco'}
|
||||||
self._patch_test(doc)
|
self._patch_test(doc)
|
||||||
|
|
||||||
@ddt.data(-1, 2**32+1, [])
|
@ddt.data(-1, 2**32+1, [])
|
||||||
def test_patch_raises_400_on_invalid_pool(self, pool):
|
def test_patch_raises_400_on_invalid_pool_group(self, pool_group):
|
||||||
self.simulate_patch(self.flavor_path,
|
self.simulate_patch(self.flavor_path,
|
||||||
body=jsonutils.dumps({'pool': pool}))
|
body=jsonutils.dumps({'pool_group': pool_group}))
|
||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
@ddt.data(-1, 'wee', [])
|
@ddt.data(-1, 'wee', [])
|
||||||
@ -241,7 +241,7 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
|
|
||||||
def test_patch_raises_404_if_flavor_not_found(self):
|
def test_patch_raises_404_if_flavor_not_found(self):
|
||||||
self.simulate_patch(self.url_prefix + '/flavors/notexists',
|
self.simulate_patch(self.url_prefix + '/flavors/notexists',
|
||||||
body=jsonutils.dumps({'pool': 'test'}))
|
body=jsonutils.dumps({'pool_group': 'test'}))
|
||||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||||
|
|
||||||
def test_empty_listing(self):
|
def test_empty_listing(self):
|
||||||
@ -261,7 +261,7 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
if marker:
|
if marker:
|
||||||
query += '&marker={2}'.format(marker)
|
query += '&marker={2}'.format(marker)
|
||||||
|
|
||||||
with flavors(self, count, self.doc['pool']) as expected:
|
with flavors(self, count, self.doc['pool_group']) as expected:
|
||||||
result = self.simulate_get(self.url_prefix + '/flavors',
|
result = self.simulate_get(self.url_prefix + '/flavors',
|
||||||
query_string=query)
|
query_string=query)
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
@ -297,7 +297,7 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
for i, s in enumerate(flavors_list + next_flavors_list):
|
for i, s in enumerate(flavors_list + next_flavors_list):
|
||||||
expect = expected[i]
|
expect = expected[i]
|
||||||
path, capabilities = expect[:2]
|
path, capabilities = expect[:2]
|
||||||
self._flavor_expect(s, path, self.doc['pool'])
|
self._flavor_expect(s, path, self.doc['pool_group'])
|
||||||
if detailed:
|
if detailed:
|
||||||
self.assertIn('capabilities', s)
|
self.assertIn('capabilities', s)
|
||||||
self.assertEqual(s['capabilities'], capabilities)
|
self.assertEqual(s['capabilities'], capabilities)
|
||||||
@ -317,14 +317,14 @@ class TestFlavorsMongoDB(base.V1_1Base):
|
|||||||
def test_listing_marker_is_respected(self):
|
def test_listing_marker_is_respected(self):
|
||||||
self.simulate_delete(self.flavor_path)
|
self.simulate_delete(self.flavor_path)
|
||||||
|
|
||||||
with flavors(self, 10, self.doc['pool']) as expected:
|
with flavors(self, 10, self.doc['pool_group']) as expected:
|
||||||
result = self.simulate_get(self.url_prefix + '/flavors',
|
result = self.simulate_get(self.url_prefix + '/flavors',
|
||||||
query_string='marker=3')
|
query_string='marker=3')
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
flavor_list = jsonutils.loads(result[0])['flavors']
|
flavor_list = jsonutils.loads(result[0])['flavors']
|
||||||
self.assertEqual(6, len(flavor_list))
|
self.assertEqual(6, len(flavor_list))
|
||||||
path, capabilities = expected[4][:2]
|
path, capabilities = expected[4][:2]
|
||||||
self._flavor_expect(flavor_list[0], path, self.doc['pool'])
|
self._flavor_expect(flavor_list[0], path, self.doc['pool_group'])
|
||||||
|
|
||||||
def test_queue_create_works(self):
|
def test_queue_create_works(self):
|
||||||
metadata = {'_flavor': self.flavor}
|
metadata = {'_flavor': self.flavor}
|
||||||
|
@ -24,7 +24,7 @@ from zaqar.tests.unit.transport.wsgi import base
|
|||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def flavor(test, name, pool):
|
def flavor(test, name, pool_group):
|
||||||
"""A context manager for constructing a flavor for use in testing.
|
"""A context manager for constructing a flavor for use in testing.
|
||||||
|
|
||||||
Deletes the flavor after exiting the context.
|
Deletes the flavor after exiting the context.
|
||||||
@ -38,20 +38,20 @@ def flavor(test, name, pool):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
doc = {'pool': pool}
|
doc = {'pool_group': pool_group}
|
||||||
path = test.url_prefix + '/flavors/' + name
|
path = test.url_prefix + '/flavors/' + name
|
||||||
|
|
||||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield name, pool
|
yield name, pool_group
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
test.simulate_delete(path)
|
test.simulate_delete(path)
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def flavors(test, count, pool):
|
def flavors(test, count, pool_group):
|
||||||
"""A context manager for constructing flavors for use in testing.
|
"""A context manager for constructing flavors for use in testing.
|
||||||
|
|
||||||
Deletes the flavors after exiting the context.
|
Deletes the flavors after exiting the context.
|
||||||
@ -59,7 +59,7 @@ def flavors(test, count, pool):
|
|||||||
:param test: Must expose simulate_* methods
|
:param test: Must expose simulate_* methods
|
||||||
:param count: Number of pools to create
|
:param count: Number of pools to create
|
||||||
:type count: int
|
:type count: int
|
||||||
:returns: (paths, pool, capabilities)
|
:returns: (paths, pool_group, capabilities)
|
||||||
:rtype: ([six.text_type], [six.text_type], [dict])
|
:rtype: ([six.text_type], [six.text_type], [dict])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -68,7 +68,7 @@ def flavors(test, count, pool):
|
|||||||
args = sorted([(base + str(i), str(i)) for i in range(count)],
|
args = sorted([(base + str(i), str(i)) for i in range(count)],
|
||||||
key=lambda tup: tup[1])
|
key=lambda tup: tup[1])
|
||||||
for path, _ in args:
|
for path, _ in args:
|
||||||
doc = {'pool': pool}
|
doc = {'pool_group': pool_group}
|
||||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -98,7 +98,7 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
self.simulate_put(self.pool_path, body=jsonutils.dumps(self.pool_doc))
|
self.simulate_put(self.pool_path, body=jsonutils.dumps(self.pool_doc))
|
||||||
|
|
||||||
self.flavor = 'test-flavor'
|
self.flavor = 'test-flavor'
|
||||||
self.doc = {'capabilities': {}, 'pool': self.pool_group}
|
self.doc = {'capabilities': {}, 'pool_group': self.pool_group}
|
||||||
self.flavor_path = self.url_prefix + '/flavors/' + self.flavor
|
self.flavor_path = self.url_prefix + '/flavors/' + self.flavor
|
||||||
self.simulate_put(self.flavor_path, body=jsonutils.dumps(self.doc))
|
self.simulate_put(self.flavor_path, body=jsonutils.dumps(self.doc))
|
||||||
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
||||||
@ -113,7 +113,7 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
|
|
||||||
def test_put_flavor_works(self):
|
def test_put_flavor_works(self):
|
||||||
name = str(uuid.uuid1())
|
name = str(uuid.uuid1())
|
||||||
with flavor(self, name, self.doc['pool']):
|
with flavor(self, name, self.doc['pool_group']):
|
||||||
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
self.assertEqual(falcon.HTTP_201, self.srmock.status)
|
||||||
|
|
||||||
def test_put_raises_if_missing_fields(self):
|
def test_put_raises_if_missing_fields(self):
|
||||||
@ -126,16 +126,16 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
@ddt.data(1, 2**32+1, [])
|
@ddt.data(1, 2**32+1, [])
|
||||||
def test_put_raises_if_invalid_pool(self, pool):
|
def test_put_raises_if_invalid_pool(self, pool_group):
|
||||||
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
||||||
self.simulate_put(path,
|
self.simulate_put(path,
|
||||||
body=jsonutils.dumps({'pool': pool}))
|
body=jsonutils.dumps({'pool_group': pool_group}))
|
||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
@ddt.data(-1, 'wee', [])
|
@ddt.data(-1, 'wee', [])
|
||||||
def test_put_raises_if_invalid_capabilities(self, capabilities):
|
def test_put_raises_if_invalid_capabilities(self, capabilities):
|
||||||
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
path = self.url_prefix + '/flavors/' + str(uuid.uuid1())
|
||||||
doc = {'pool': 'a', 'capabilities': capabilities}
|
doc = {'pool_group': 'a', 'capabilities': capabilities}
|
||||||
self.simulate_put(path, body=jsonutils.dumps(doc))
|
self.simulate_put(path, body=jsonutils.dumps(doc))
|
||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
@ -149,9 +149,9 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
result = self.simulate_get(self.flavor_path)
|
result = self.simulate_get(self.flavor_path)
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
doc = jsonutils.loads(result[0])
|
doc = jsonutils.loads(result[0])
|
||||||
self.assertEqual(expect['pool'], doc['pool'])
|
self.assertEqual(expect['pool_group'], doc['pool_group'])
|
||||||
|
|
||||||
def test_create_flavor_no_pool(self):
|
def test_create_flavor_no_pool_group(self):
|
||||||
self.simulate_delete(self.flavor_path)
|
self.simulate_delete(self.flavor_path)
|
||||||
self.assertEqual(falcon.HTTP_204, self.srmock.status)
|
self.assertEqual(falcon.HTTP_204, self.srmock.status)
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{'description': 'Flavor test-flavor could not be created. '
|
{'description': 'Flavor test-flavor could not be created. '
|
||||||
'Pool mypool-group does not exist',
|
'Pool group mypool-group does not exist',
|
||||||
'title': 'Unable to create'},
|
'title': 'Unable to create'},
|
||||||
jsonutils.loads(resp[0]))
|
jsonutils.loads(resp[0]))
|
||||||
|
|
||||||
@ -178,22 +178,22 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
self.simulate_get(self.url_prefix + '/flavors/nonexisting')
|
self.simulate_get(self.url_prefix + '/flavors/nonexisting')
|
||||||
self.assertEqual(falcon.HTTP_404, self.srmock.status)
|
self.assertEqual(falcon.HTTP_404, self.srmock.status)
|
||||||
|
|
||||||
def _flavor_expect(self, flavor, xhref, xpool):
|
def _flavor_expect(self, flavor, xhref, xpool_group):
|
||||||
self.assertIn('href', flavor)
|
self.assertIn('href', flavor)
|
||||||
self.assertIn('name', flavor)
|
self.assertIn('name', flavor)
|
||||||
self.assertEqual(xhref, flavor['href'])
|
self.assertEqual(xhref, flavor['href'])
|
||||||
self.assertIn('pool', flavor)
|
self.assertIn('pool_group', flavor)
|
||||||
self.assertEqual(xpool, flavor['pool'])
|
self.assertEqual(xpool_group, flavor['pool_group'])
|
||||||
|
|
||||||
def test_get_works(self):
|
def test_get_works(self):
|
||||||
result = self.simulate_get(self.flavor_path)
|
result = self.simulate_get(self.flavor_path)
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
pool = jsonutils.loads(result[0])
|
flavor = jsonutils.loads(result[0])
|
||||||
self._flavor_expect(pool, self.flavor_path, self.doc['pool'])
|
self._flavor_expect(flavor, self.flavor_path, self.doc['pool_group'])
|
||||||
|
|
||||||
store_caps = ['FIFO', 'CLAIMS', 'DURABILITY',
|
store_caps = ['FIFO', 'CLAIMS', 'DURABILITY',
|
||||||
'AOD', 'HIGH_THROUGHPUT']
|
'AOD', 'HIGH_THROUGHPUT']
|
||||||
self.assertEqual(store_caps, pool['capabilities'])
|
self.assertEqual(store_caps, flavor['capabilities'])
|
||||||
|
|
||||||
def test_patch_raises_if_missing_fields(self):
|
def test_patch_raises_if_missing_fields(self):
|
||||||
self.simulate_patch(self.flavor_path,
|
self.simulate_patch(self.flavor_path,
|
||||||
@ -205,28 +205,29 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
body=jsonutils.dumps(doc))
|
body=jsonutils.dumps(doc))
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
updated_flavor = jsonutils.loads(result[0])
|
updated_flavor = jsonutils.loads(result[0])
|
||||||
self._flavor_expect(updated_flavor, self.flavor_path, doc['pool'])
|
self._flavor_expect(updated_flavor, self.flavor_path,
|
||||||
|
doc['pool_group'])
|
||||||
self.assertEqual(doc['capabilities'], updated_flavor['capabilities'])
|
self.assertEqual(doc['capabilities'], updated_flavor['capabilities'])
|
||||||
|
|
||||||
result = self.simulate_get(self.flavor_path)
|
result = self.simulate_get(self.flavor_path)
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
flavor = jsonutils.loads(result[0])
|
flavor = jsonutils.loads(result[0])
|
||||||
self._flavor_expect(flavor, self.flavor_path, doc['pool'])
|
self._flavor_expect(flavor, self.flavor_path, doc['pool_group'])
|
||||||
self.assertEqual(doc['capabilities'], flavor['capabilities'])
|
self.assertEqual(doc['capabilities'], flavor['capabilities'])
|
||||||
|
|
||||||
def test_patch_works(self):
|
def test_patch_works(self):
|
||||||
doc = {'pool': 'mypool', 'capabilities': []}
|
doc = {'pool_group': 'mypoolgroup', 'capabilities': []}
|
||||||
self._patch_test(doc)
|
self._patch_test(doc)
|
||||||
|
|
||||||
def test_patch_works_with_extra_fields(self):
|
def test_patch_works_with_extra_fields(self):
|
||||||
doc = {'pool': 'mypool', 'capabilities': [],
|
doc = {'pool_group': 'mypoolgroup', 'capabilities': [],
|
||||||
'location': 100, 'partition': 'taco'}
|
'location': 100, 'partition': 'taco'}
|
||||||
self._patch_test(doc)
|
self._patch_test(doc)
|
||||||
|
|
||||||
@ddt.data(-1, 2**32+1, [])
|
@ddt.data(-1, 2**32+1, [])
|
||||||
def test_patch_raises_400_on_invalid_pool(self, pool):
|
def test_patch_raises_400_on_invalid_pool_group(self, pool_group):
|
||||||
self.simulate_patch(self.flavor_path,
|
self.simulate_patch(self.flavor_path,
|
||||||
body=jsonutils.dumps({'pool': pool}))
|
body=jsonutils.dumps({'pool_group': pool_group}))
|
||||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||||
|
|
||||||
@ddt.data(-1, 'wee', [])
|
@ddt.data(-1, 'wee', [])
|
||||||
@ -237,7 +238,7 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
|
|
||||||
def test_patch_raises_404_if_flavor_not_found(self):
|
def test_patch_raises_404_if_flavor_not_found(self):
|
||||||
self.simulate_patch(self.url_prefix + '/flavors/notexists',
|
self.simulate_patch(self.url_prefix + '/flavors/notexists',
|
||||||
body=jsonutils.dumps({'pool': 'test'}))
|
body=jsonutils.dumps({'pool_group': 'test'}))
|
||||||
self.assertEqual(falcon.HTTP_404, self.srmock.status)
|
self.assertEqual(falcon.HTTP_404, self.srmock.status)
|
||||||
|
|
||||||
def test_empty_listing(self):
|
def test_empty_listing(self):
|
||||||
@ -257,7 +258,7 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
if marker:
|
if marker:
|
||||||
query += '&marker={2}'.format(marker)
|
query += '&marker={2}'.format(marker)
|
||||||
|
|
||||||
with flavors(self, count, self.doc['pool']) as expected:
|
with flavors(self, count, self.doc['pool_group']) as expected:
|
||||||
result = self.simulate_get(self.url_prefix + '/flavors',
|
result = self.simulate_get(self.url_prefix + '/flavors',
|
||||||
query_string=query)
|
query_string=query)
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
@ -295,7 +296,7 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
path = expect[0]
|
path = expect[0]
|
||||||
capabilities = ['FIFO', 'CLAIMS', 'DURABILITY',
|
capabilities = ['FIFO', 'CLAIMS', 'DURABILITY',
|
||||||
'AOD', 'HIGH_THROUGHPUT']
|
'AOD', 'HIGH_THROUGHPUT']
|
||||||
self._flavor_expect(s, path, self.doc['pool'])
|
self._flavor_expect(s, path, self.doc['pool_group'])
|
||||||
if detailed:
|
if detailed:
|
||||||
self.assertIn('capabilities', s)
|
self.assertIn('capabilities', s)
|
||||||
self.assertEqual(s['capabilities'], capabilities)
|
self.assertEqual(s['capabilities'], capabilities)
|
||||||
@ -315,14 +316,14 @@ class TestFlavorsMongoDB(base.V2Base):
|
|||||||
def test_listing_marker_is_respected(self):
|
def test_listing_marker_is_respected(self):
|
||||||
self.simulate_delete(self.flavor_path)
|
self.simulate_delete(self.flavor_path)
|
||||||
|
|
||||||
with flavors(self, 10, self.doc['pool']) as expected:
|
with flavors(self, 10, self.doc['pool_group']) as expected:
|
||||||
result = self.simulate_get(self.url_prefix + '/flavors',
|
result = self.simulate_get(self.url_prefix + '/flavors',
|
||||||
query_string='marker=3')
|
query_string='marker=3')
|
||||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||||
flavor_list = jsonutils.loads(result[0])['flavors']
|
flavor_list = jsonutils.loads(result[0])['flavors']
|
||||||
self.assertEqual(6, len(flavor_list))
|
self.assertEqual(6, len(flavor_list))
|
||||||
path, capabilities = expected[4][:2]
|
path, capabilities = expected[4][:2]
|
||||||
self._flavor_expect(flavor_list[0], path, self.doc['pool'])
|
self._flavor_expect(flavor_list[0], path, self.doc['pool_group'])
|
||||||
|
|
||||||
def test_queue_create_works(self):
|
def test_queue_create_works(self):
|
||||||
metadata = {'_flavor': self.flavor}
|
metadata = {'_flavor': self.flavor}
|
||||||
|
@ -73,6 +73,8 @@ class Listing(object):
|
|||||||
|
|
||||||
for entry in flavors:
|
for entry in flavors:
|
||||||
entry['href'] = request.path + '/' + entry['name']
|
entry['href'] = request.path + '/' + entry['name']
|
||||||
|
# NOTE(wanghao): remove this in Newton.
|
||||||
|
entry['pool'] = entry['pool_group']
|
||||||
|
|
||||||
results['links'] = [
|
results['links'] = [
|
||||||
{
|
{
|
||||||
@ -98,6 +100,8 @@ class Resource(object):
|
|||||||
validator_type = jsonschema.Draft4Validator
|
validator_type = jsonschema.Draft4Validator
|
||||||
self._validators = {
|
self._validators = {
|
||||||
'create': validator_type(schema.create),
|
'create': validator_type(schema.create),
|
||||||
|
'pool_group': validator_type(schema.patch_pool_group),
|
||||||
|
# NOTE(wanghao): Remove this in Newton.
|
||||||
'pool': validator_type(schema.patch_pool),
|
'pool': validator_type(schema.patch_pool),
|
||||||
'capabilities': validator_type(schema.patch_capabilities),
|
'capabilities': validator_type(schema.patch_capabilities),
|
||||||
}
|
}
|
||||||
@ -107,7 +111,7 @@ class Resource(object):
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
{"pool": "", capabilities: {...}}
|
{"pool_group": "", capabilities: {...}}
|
||||||
|
|
||||||
:returns: HTTP | [200, 404]
|
:returns: HTTP | [200, 404]
|
||||||
"""
|
"""
|
||||||
@ -120,7 +124,8 @@ class Resource(object):
|
|||||||
data = self._ctrl.get(flavor,
|
data = self._ctrl.get(flavor,
|
||||||
project=project_id,
|
project=project_id,
|
||||||
detailed=detailed)
|
detailed=detailed)
|
||||||
|
# NOTE(wanghao): remove this in Newton.
|
||||||
|
data['pool'] = data['pool_group']
|
||||||
except errors.FlavorDoesNotExist as ex:
|
except errors.FlavorDoesNotExist as ex:
|
||||||
LOG.debug(ex)
|
LOG.debug(ex)
|
||||||
raise falcon.HTTPNotFound()
|
raise falcon.HTTPNotFound()
|
||||||
@ -134,7 +139,7 @@ class Resource(object):
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
{"pool": "my-pool", "capabilities": {}}
|
{"pool_group": "my-pool-group", "capabilities": {}}
|
||||||
|
|
||||||
A capabilities object may also be provided.
|
A capabilities object may also be provided.
|
||||||
|
|
||||||
@ -145,19 +150,19 @@ class Resource(object):
|
|||||||
|
|
||||||
data = wsgi_utils.load(request)
|
data = wsgi_utils.load(request)
|
||||||
wsgi_utils.validate(self._validators['create'], data)
|
wsgi_utils.validate(self._validators['create'], data)
|
||||||
|
pool_group = data.get('pool_group') or data.get('pool')
|
||||||
try:
|
try:
|
||||||
self._ctrl.create(flavor,
|
self._ctrl.create(flavor,
|
||||||
pool=data['pool'],
|
pool_group=pool_group,
|
||||||
project=project_id,
|
project=project_id,
|
||||||
capabilities=data['capabilities'])
|
capabilities=data['capabilities'])
|
||||||
response.status = falcon.HTTP_201
|
response.status = falcon.HTTP_201
|
||||||
response.location = request.path
|
response.location = request.path
|
||||||
except errors.PoolDoesNotExist as ex:
|
except errors.PoolGroupDoesNotExist as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
description = (_(u'Flavor %(flavor)s could not be created. '
|
description = (_(u'Flavor %(flavor)s could not be created. '
|
||||||
u'Pool %(pool)s does not exist') %
|
u'Pool group %(pool_group)s does not exist') %
|
||||||
dict(flavor=flavor, pool=data['pool']))
|
dict(flavor=flavor, pool_group=pool_group))
|
||||||
raise falcon.HTTPBadRequest(_('Unable to create'), description)
|
raise falcon.HTTPBadRequest(_('Unable to create'), description)
|
||||||
|
|
||||||
def on_delete(self, request, response, project_id, flavor):
|
def on_delete(self, request, response, project_id, flavor):
|
||||||
@ -174,7 +179,7 @@ class Resource(object):
|
|||||||
"""Allows one to update a flavors's pool and/or capabilities.
|
"""Allows one to update a flavors's pool and/or capabilities.
|
||||||
|
|
||||||
This method expects the user to submit a JSON object
|
This method expects the user to submit a JSON object
|
||||||
containing at least one of: 'pool', 'capabilities'. If
|
containing at least one of: 'pool_group', 'capabilities'. If
|
||||||
none are found, the request is flagged as bad. There is also
|
none are found, the request is flagged as bad. There is also
|
||||||
strict format checking through the use of
|
strict format checking through the use of
|
||||||
jsonschema. Appropriate errors are returned in each case for
|
jsonschema. Appropriate errors are returned in each case for
|
||||||
@ -186,11 +191,11 @@ class Resource(object):
|
|||||||
LOG.debug(u'PATCH flavor - name: %s', flavor)
|
LOG.debug(u'PATCH flavor - name: %s', flavor)
|
||||||
data = wsgi_utils.load(request)
|
data = wsgi_utils.load(request)
|
||||||
|
|
||||||
EXPECT = ('pool', 'capabilities')
|
EXPECT = ('pool_group', 'capabilities', 'pool')
|
||||||
if not any([(field in data) for field in EXPECT]):
|
if not any([(field in data) for field in EXPECT]):
|
||||||
LOG.debug(u'PATCH flavor, bad params')
|
LOG.debug(u'PATCH flavor, bad params')
|
||||||
raise wsgi_errors.HTTPBadRequestBody(
|
raise wsgi_errors.HTTPBadRequestBody(
|
||||||
'One of `pool` or `capabilities` needs '
|
'One of `pool_group` or `capabilities` or `pool` needs '
|
||||||
'to be specified'
|
'to be specified'
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -199,6 +204,10 @@ class Resource(object):
|
|||||||
|
|
||||||
fields = common_utils.fields(data, EXPECT,
|
fields = common_utils.fields(data, EXPECT,
|
||||||
pred=lambda v: v is not None)
|
pred=lambda v: v is not None)
|
||||||
|
# NOTE(wanghao): remove this in Newton.
|
||||||
|
if fields.get('pool') and fields.get('pool_group') is None:
|
||||||
|
fields['pool_group'] = fields.get('pool')
|
||||||
|
fields.pop('pool')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._ctrl.update(flavor, project=project_id, **fields)
|
self._ctrl.update(flavor, project=project_id, **fields)
|
||||||
|
@ -47,7 +47,7 @@ class Listing(object):
|
|||||||
|
|
||||||
{
|
{
|
||||||
"flavors": [
|
"flavors": [
|
||||||
{"href": "", "capabilities": {}, "pool": ""},
|
{"href": "", "capabilities": {}, "pool_group": ""},
|
||||||
...
|
...
|
||||||
],
|
],
|
||||||
"links": [
|
"links": [
|
||||||
@ -76,8 +76,11 @@ class Listing(object):
|
|||||||
|
|
||||||
for entry in flavors:
|
for entry in flavors:
|
||||||
entry['href'] = request.path + '/' + entry['name']
|
entry['href'] = request.path + '/' + entry['name']
|
||||||
|
pool_group = entry['pool_group']
|
||||||
|
# NOTE(wanghao): remove this in Newton.
|
||||||
|
entry['pool'] = entry['pool_group']
|
||||||
if detailed:
|
if detailed:
|
||||||
caps = self._pools_ctrl.capabilities(group=entry['pool'])
|
caps = self._pools_ctrl.capabilities(group=pool_group)
|
||||||
entry['capabilities'] = [str(cap).split('.')[-1]
|
entry['capabilities'] = [str(cap).split('.')[-1]
|
||||||
for cap in caps]
|
for cap in caps]
|
||||||
|
|
||||||
@ -111,6 +114,8 @@ class Resource(object):
|
|||||||
validator_type = jsonschema.Draft4Validator
|
validator_type = jsonschema.Draft4Validator
|
||||||
self._validators = {
|
self._validators = {
|
||||||
'create': validator_type(schema.create),
|
'create': validator_type(schema.create),
|
||||||
|
'pool_group': validator_type(schema.patch_pool_group),
|
||||||
|
# NOTE(wanghao): Remove this in Newton.
|
||||||
'pool': validator_type(schema.patch_pool),
|
'pool': validator_type(schema.patch_pool),
|
||||||
'capabilities': validator_type(schema.patch_capabilities),
|
'capabilities': validator_type(schema.patch_capabilities),
|
||||||
}
|
}
|
||||||
@ -131,7 +136,10 @@ class Resource(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
data = self._ctrl.get(flavor, project=project_id)
|
data = self._ctrl.get(flavor, project=project_id)
|
||||||
capabilities = self._pools_ctrl.capabilities(group=data['pool'])
|
pool_group = data['pool_group']
|
||||||
|
# NOTE(wanghao): remove this in Newton.
|
||||||
|
data['pool'] = data['pool_group']
|
||||||
|
capabilities = self._pools_ctrl.capabilities(group=pool_group)
|
||||||
data['capabilities'] = [str(cap).split('.')[-1]
|
data['capabilities'] = [str(cap).split('.')[-1]
|
||||||
for cap in capabilities]
|
for cap in capabilities]
|
||||||
|
|
||||||
@ -149,7 +157,7 @@ class Resource(object):
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
{"pool": "my-pool", "capabilities": {}}
|
{"pool_group": "my-pool-group", "capabilities": {}}
|
||||||
|
|
||||||
A capabilities object may also be provided.
|
A capabilities object may also be provided.
|
||||||
|
|
||||||
@ -160,18 +168,18 @@ class Resource(object):
|
|||||||
|
|
||||||
data = wsgi_utils.load(request)
|
data = wsgi_utils.load(request)
|
||||||
wsgi_utils.validate(self._validators['create'], data)
|
wsgi_utils.validate(self._validators['create'], data)
|
||||||
|
pool_group = data.get('pool_group') or data.get('pool')
|
||||||
try:
|
try:
|
||||||
self._ctrl.create(flavor,
|
self._ctrl.create(flavor,
|
||||||
pool=data['pool'],
|
pool_group=pool_group,
|
||||||
project=project_id)
|
project=project_id)
|
||||||
response.status = falcon.HTTP_201
|
response.status = falcon.HTTP_201
|
||||||
response.location = request.path
|
response.location = request.path
|
||||||
except errors.PoolDoesNotExist as ex:
|
except errors.PoolGroupDoesNotExist as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
description = (_(u'Flavor %(flavor)s could not be created. '
|
description = (_(u'Flavor %(flavor)s could not be created. '
|
||||||
u'Pool %(pool)s does not exist') %
|
u'Pool group %(pool_group)s does not exist') %
|
||||||
dict(flavor=flavor, pool=data['pool']))
|
dict(flavor=flavor, pool_group=pool_group))
|
||||||
raise falcon.HTTPBadRequest(_('Unable to create'), description)
|
raise falcon.HTTPBadRequest(_('Unable to create'), description)
|
||||||
|
|
||||||
@acl.enforce("flavors:delete")
|
@acl.enforce("flavors:delete")
|
||||||
@ -187,11 +195,11 @@ class Resource(object):
|
|||||||
|
|
||||||
@acl.enforce("flavors:update")
|
@acl.enforce("flavors:update")
|
||||||
def on_patch(self, request, response, project_id, flavor):
|
def on_patch(self, request, response, project_id, flavor):
|
||||||
"""Allows one to update a flavors's pool.
|
"""Allows one to update a flavors's pool_group.
|
||||||
|
|
||||||
This method expects the user to submit a JSON object
|
This method expects the user to submit a JSON object
|
||||||
containing 'pool'. If none is found, the request is flagged as bad.
|
containing 'pool_group'. If none is found, the request is flagged
|
||||||
There is also strict format checking through the use of
|
as bad. There is also strict format checking through the use of
|
||||||
jsonschema. Appropriate errors are returned in each case for
|
jsonschema. Appropriate errors are returned in each case for
|
||||||
badly formatted input.
|
badly formatted input.
|
||||||
|
|
||||||
@ -201,11 +209,11 @@ class Resource(object):
|
|||||||
LOG.debug(u'PATCH flavor - name: %s', flavor)
|
LOG.debug(u'PATCH flavor - name: %s', flavor)
|
||||||
data = wsgi_utils.load(request)
|
data = wsgi_utils.load(request)
|
||||||
|
|
||||||
EXPECT = ('pool', )
|
EXPECT = ('pool_group', 'pool')
|
||||||
if not any([(field in data) for field in EXPECT]):
|
if not any([(field in data) for field in EXPECT]):
|
||||||
LOG.debug(u'PATCH flavor, bad params')
|
LOG.debug(u'PATCH flavor, bad params')
|
||||||
raise wsgi_errors.HTTPBadRequestBody(
|
raise wsgi_errors.HTTPBadRequestBody(
|
||||||
'`pool` needs to be specified'
|
'`pool_group` or `pool` needs to be specified'
|
||||||
)
|
)
|
||||||
|
|
||||||
for field in EXPECT:
|
for field in EXPECT:
|
||||||
@ -213,12 +221,17 @@ class Resource(object):
|
|||||||
|
|
||||||
fields = common_utils.fields(data, EXPECT,
|
fields = common_utils.fields(data, EXPECT,
|
||||||
pred=lambda v: v is not None)
|
pred=lambda v: v is not None)
|
||||||
|
# NOTE(wanghao): remove this in Newton.
|
||||||
|
if fields.get('pool') and fields.get('pool_group') is None:
|
||||||
|
fields['pool_group'] = fields.get('pool')
|
||||||
|
fields.pop('pool')
|
||||||
|
|
||||||
resp_data = None
|
resp_data = None
|
||||||
try:
|
try:
|
||||||
self._ctrl.update(flavor, project=project_id, **fields)
|
self._ctrl.update(flavor, project=project_id, **fields)
|
||||||
resp_data = self._ctrl.get(flavor, project=project_id)
|
resp_data = self._ctrl.get(flavor, project=project_id)
|
||||||
capabilities = self._pools_ctrl.capabilities(
|
capabilities = self._pools_ctrl.capabilities(
|
||||||
group=resp_data['pool'])
|
group=resp_data['pool_group'])
|
||||||
resp_data['capabilities'] = [str(cap).split('.')[-1]
|
resp_data['capabilities'] = [str(cap).split('.')[-1]
|
||||||
for cap in capabilities]
|
for cap in capabilities]
|
||||||
except errors.FlavorDoesNotExist as ex:
|
except errors.FlavorDoesNotExist as ex:
|
||||||
|
Loading…
Reference in New Issue
Block a user