Make metadata handling consistent in Compute
Make metadata handling consistent across all Compute resources. The consistent methods are get_*_metdata, set_*_metadata, and delete_*_metadata which is similar to the __get__, __set__, and __delete__ methods of a descriptor or the __getitem__, __setitem__, and __delitem__ of a MutableMapping so it should be fairly natural for Python users. Change-Id: I977e8741bdd755e8af8c0f3c4e16e38cfba79bd5 Closes-Bug: #1546156
This commit is contained in:
parent
4fafbbe406
commit
1f6990edbf
|
@ -198,64 +198,27 @@ class Proxy(proxy.BaseProxy):
|
|||
else:
|
||||
return base({"id": res})
|
||||
|
||||
def get_image_metadata(self, image, key=None):
|
||||
def get_image_metadata(self, image):
|
||||
"""Return a dictionary of metadata for an image
|
||||
|
||||
:param server: Either the ID of an image or a
|
||||
:param image: Either the ID of an image or a
|
||||
:class:`~openstack.compute.v2.image.Image` or
|
||||
:class:`~openstack.compute.v2.image.ImageDetail`
|
||||
instance.
|
||||
:param key: An optional key to retrieve from the image's metadata.
|
||||
When no ``key`` is specified, all metadata is retrieved.
|
||||
|
||||
:returns: A dictionary of the image's metadata. All keys and values
|
||||
are Unicode text.
|
||||
:rtype: dict
|
||||
:returns: A :class:`~openstack.compute.v2.image.Image` with only the
|
||||
image's metadata. All keys and values are Unicode text.
|
||||
:rtype: :class:`~openstack.compute.v2.image.Image`
|
||||
"""
|
||||
res = self._get_base_resource(image, _image.Image)
|
||||
return res.get_metadata(self.session, key)
|
||||
metadata = res.get_metadata(self.session)
|
||||
result = _image.Image.existing(id=res.id, metadata=metadata)
|
||||
return result
|
||||
|
||||
def create_image_metadata(self, image, **metadata):
|
||||
"""Create metadata for an image
|
||||
|
||||
:param server: Either the ID of an image or a
|
||||
:class:`~openstack.compute.v2.image.Image` or
|
||||
:class:`~openstack.compute.v2.image.ImageDetail`
|
||||
instance.
|
||||
:param kwargs metadata: Key/value pairs to be added as metadata
|
||||
on the image. All keys and values
|
||||
are stored as Unicode.
|
||||
|
||||
:returns: A dictionary of the metadata that was created on the image.
|
||||
All keys and values are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
res = self._get_base_resource(image, _image.Image)
|
||||
return res.create_metadata(self.session, **metadata)
|
||||
|
||||
def replace_image_metadata(self, image, **metadata):
|
||||
"""Replace metadata for an image
|
||||
|
||||
:param server: Either the ID of a image or a
|
||||
:class:`~openstack.compute.v2.image.Image` or
|
||||
:class:`~openstack.compute.v2.image.ImageDetail`
|
||||
instance.
|
||||
:param kwargs metadata: Key/value pairs to be added as metadata
|
||||
on the image. Any other existing metadata
|
||||
is removed. All keys and values are stored
|
||||
as Unicode.
|
||||
|
||||
:returns: A dictionary of the metadata for the image. All keys and
|
||||
values are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
res = self._get_base_resource(image, _image.Image)
|
||||
return res.replace_metadata(self.session, **metadata)
|
||||
|
||||
def update_image_metadata(self, image, **metadata):
|
||||
def set_image_metadata(self, image, **metadata):
|
||||
"""Update metadata for an image
|
||||
|
||||
:param server: Either the ID of an image or a
|
||||
:param image: Either the ID of an image or a
|
||||
:class:`~openstack.compute.v2.image.Image` or
|
||||
:class:`~openstack.compute.v2.image.ImageDetail`
|
||||
instance.
|
||||
|
@ -264,26 +227,30 @@ class Proxy(proxy.BaseProxy):
|
|||
by this call. All keys and values are stored
|
||||
as Unicode.
|
||||
|
||||
:returns: A dictionary of the metadata for the image. All keys and
|
||||
values are Unicode text.
|
||||
:rtype: dict
|
||||
:returns: A :class:`~openstack.compute.v2.image.Image` with only the
|
||||
image's metadata. All keys and values are Unicode text.
|
||||
:rtype: :class:`~openstack.compute.v2.image.Image`
|
||||
"""
|
||||
res = self._get_base_resource(image, _image.Image)
|
||||
return res.update_metadata(self.session, **metadata)
|
||||
metadata = res.set_metadata(self.session, **metadata)
|
||||
result = _image.Image.existing(id=res.id, metadata=metadata)
|
||||
return result
|
||||
|
||||
def delete_image_metadata(self, image, key):
|
||||
def delete_image_metadata(self, image, keys):
|
||||
"""Delete metadata for an image
|
||||
|
||||
:param server: Either the ID of an image or a
|
||||
Note: This method will do a HTTP DELETE request for every key in keys.
|
||||
|
||||
:param image: Either the ID of an image or a
|
||||
:class:`~openstack.compute.v2.image.Image` or
|
||||
:class:`~openstack.compute.v2.image.ImageDetail`
|
||||
instance.
|
||||
:param key: The key to delete
|
||||
:param list keys: The keys to delete.
|
||||
|
||||
:rtype: ``None``
|
||||
"""
|
||||
res = self._get_base_resource(image, _image.Image)
|
||||
return res.delete_metadata(self.session, key)
|
||||
return res.delete_metadata(self.session, keys)
|
||||
|
||||
def create_keypair(self, **attrs):
|
||||
"""Create a new keypair from attributes
|
||||
|
@ -681,61 +648,24 @@ class Proxy(proxy.BaseProxy):
|
|||
return self._list(availability_zone.AvailabilityZone,
|
||||
paginated=False, **query)
|
||||
|
||||
def get_server_metadata(self, server, key=None):
|
||||
def get_server_metadata(self, server):
|
||||
"""Return a dictionary of metadata for a server
|
||||
|
||||
:param server: Either the ID of a server or a
|
||||
:class:`~openstack.compute.v2.server.Server` or
|
||||
:class:`~openstack.compute.v2.server.ServerDetail`
|
||||
instance.
|
||||
:param key: An optional key to retrieve from the server's metadata.
|
||||
When no ``key`` is specified, all metadata is retrieved.
|
||||
|
||||
:returns: A dictionary of the server's metadata. All keys and values
|
||||
are Unicode text.
|
||||
:rtype: dict
|
||||
:returns: A :class:`~openstack.compute.v2.server.Server` with only the
|
||||
server's metadata. All keys and values are Unicode text.
|
||||
:rtype: :class:`~openstack.compute.v2.server.Server`
|
||||
"""
|
||||
res = self._get_base_resource(server, _server.Server)
|
||||
return res.get_metadata(self.session, key)
|
||||
metadata = res.get_metadata(self.session)
|
||||
result = _server.Server.existing(id=res.id, metadata=metadata)
|
||||
return result
|
||||
|
||||
def create_server_metadata(self, server, **metadata):
|
||||
"""Create metadata for a server
|
||||
|
||||
:param server: Either the ID of a server or a
|
||||
:class:`~openstack.compute.v2.server.Server` or
|
||||
:class:`~openstack.compute.v2.server.ServerDetail`
|
||||
instance.
|
||||
:param kwargs metadata: Key/value pairs to be added as metadata
|
||||
on the server. All keys and values
|
||||
are stored as Unicode.
|
||||
|
||||
:returns: A dictionary of the metadata that was created on the server.
|
||||
All keys and values are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
res = self._get_base_resource(server, _server.Server)
|
||||
return res.create_metadata(self.session, **metadata)
|
||||
|
||||
def replace_server_metadata(self, server, **metadata):
|
||||
"""Replace metadata for a server
|
||||
|
||||
:param server: Either the ID of a server or a
|
||||
:class:`~openstack.compute.v2.server.Server` or
|
||||
:class:`~openstack.compute.v2.server.ServerDetail`
|
||||
instance.
|
||||
:param kwargs metadata: Key/value pairs to be added as metadata
|
||||
on the server. Any other existing metadata
|
||||
is removed. All keys and values are stored
|
||||
as Unicode.
|
||||
|
||||
:returns: A dictionary of the metadata for the server. All keys and
|
||||
values are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
res = self._get_base_resource(server, _server.Server)
|
||||
return res.replace_metadata(self.session, **metadata)
|
||||
|
||||
def update_server_metadata(self, server, **metadata):
|
||||
def set_server_metadata(self, server, **metadata):
|
||||
"""Update metadata for a server
|
||||
|
||||
:param server: Either the ID of a server or a
|
||||
|
@ -747,26 +677,30 @@ class Proxy(proxy.BaseProxy):
|
|||
by this call. All keys and values are stored
|
||||
as Unicode.
|
||||
|
||||
:returns: A dictionary of the metadata for the server. All keys and
|
||||
values are Unicode text.
|
||||
:rtype: dict
|
||||
:returns: A :class:`~openstack.compute.v2.server.Server` with only the
|
||||
server's metadata. All keys and values are Unicode text.
|
||||
:rtype: :class:`~openstack.compute.v2.server.Server`
|
||||
"""
|
||||
res = self._get_base_resource(server, _server.Server)
|
||||
return res.update_metadata(self.session, **metadata)
|
||||
metadata = res.set_metadata(self.session, **metadata)
|
||||
result = _server.Server.existing(id=res.id, metadata=metadata)
|
||||
return result
|
||||
|
||||
def delete_server_metadata(self, server, key):
|
||||
def delete_server_metadata(self, server, keys):
|
||||
"""Delete metadata for a server
|
||||
|
||||
Note: This method will do a HTTP DELETE request for every key in keys.
|
||||
|
||||
:param server: Either the ID of a server or a
|
||||
:class:`~openstack.compute.v2.server.Server` or
|
||||
:class:`~openstack.compute.v2.server.ServerDetail`
|
||||
instance.
|
||||
:param key: The key to delete
|
||||
:param list keys: The keys to delete
|
||||
|
||||
:rtype: ``None``
|
||||
"""
|
||||
res = self._get_base_resource(server, _server.Server)
|
||||
return res.delete_metadata(self.session, key)
|
||||
return res.delete_metadata(self.session, keys)
|
||||
|
||||
def create_server_group(self, **attrs):
|
||||
"""Create a new server group from attributes
|
||||
|
|
|
@ -39,7 +39,7 @@ class MetadataMixin(object):
|
|||
|
||||
kwargs = {"endpoint_filter": self.service}
|
||||
if metadata or clear:
|
||||
# 'meta' is the key for singlular modifications.
|
||||
# 'meta' is the key for singular modifications.
|
||||
# 'metadata' is the key for mass modifications.
|
||||
key = "meta" if key is not None else "metadata"
|
||||
kwargs["json"] = {key: metadata}
|
||||
|
@ -51,70 +51,19 @@ class MetadataMixin(object):
|
|||
# DELETE doesn't return a JSON body while everything else does.
|
||||
return response.json() if not delete else None
|
||||
|
||||
def get_metadata(self, session, key=None):
|
||||
def get_metadata(self, session):
|
||||
"""Retrieve metadata
|
||||
|
||||
:param session: The session to use for this request.
|
||||
:param key: If specified, retrieve metadata only for this key.
|
||||
If not specified, or ``None`` (the default),
|
||||
retrieve all available metadata.
|
||||
|
||||
:returns: A dictionary of the requested metadata. All keys and values
|
||||
are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
result = self._metadata(session.get, key=key)
|
||||
return result["metadata"] if key is None else result["meta"]
|
||||
|
||||
def create_metadata(self, session, **metadata):
|
||||
"""Create metadata
|
||||
|
||||
NOTE: One PUT call will be made for each key/value pair specified.
|
||||
|
||||
:param session: The session to use for this request.
|
||||
:param kwargs metadata: key/value metadata pairs to be created on
|
||||
this server instance. All keys and values
|
||||
are stored as Unicode.
|
||||
|
||||
:returns: A dictionary of the metadata that was created. All keys and
|
||||
values are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
results = {}
|
||||
# A PUT to /metadata will entirely replace any existing metadata,
|
||||
# so we need to PUT each individual key/value to /metadata/key
|
||||
# in order to preserve anything existing and only add new keys.
|
||||
for key, value in metadata.items():
|
||||
result = self._metadata(session.put, key=key, **{key: value})
|
||||
results[key] = result["meta"][key]
|
||||
return results
|
||||
|
||||
def replace_metadata(self, session, **metadata):
|
||||
"""Replace metadata
|
||||
|
||||
This call will replace any existing metadata with the key/value pairs
|
||||
given here.
|
||||
|
||||
:param session: The session to use for this request.
|
||||
:param kwargs metadata: key/value metadata pairs to be created on
|
||||
this server instance. Any other existing
|
||||
metadata is removed.
|
||||
When metadata is not set, it is effectively
|
||||
cleared out, replacing the metadata
|
||||
with nothing.
|
||||
All keys and values are stored as Unicode.
|
||||
|
||||
|
||||
:returns: A dictionary of the metadata after being replaced.
|
||||
All keys and values are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
# A PUT with empty metadata will clear anything out.
|
||||
clear = True if not metadata else False
|
||||
result = self._metadata(session.put, clear=clear, **metadata)
|
||||
result = self._metadata(session.get)
|
||||
return result["metadata"]
|
||||
|
||||
def update_metadata(self, session, **metadata):
|
||||
def set_metadata(self, session, **metadata):
|
||||
"""Update metadata
|
||||
|
||||
This call will replace only the metadata with the same keys
|
||||
|
@ -129,15 +78,21 @@ class MetadataMixin(object):
|
|||
All keys and values are Unicode text.
|
||||
:rtype: dict
|
||||
"""
|
||||
if not metadata:
|
||||
return dict()
|
||||
|
||||
result = self._metadata(session.post, **metadata)
|
||||
return result["metadata"]
|
||||
|
||||
def delete_metadata(self, session, key):
|
||||
def delete_metadata(self, session, keys):
|
||||
"""Delete metadata
|
||||
|
||||
Note: This method will do a HTTP DELETE request for every key in keys.
|
||||
|
||||
:param session: The session to use for this request.
|
||||
:param string key: The key to delete.
|
||||
:param list keys: The keys to delete.
|
||||
|
||||
:rtype: ``None``
|
||||
"""
|
||||
self._metadata(session.delete, key=key, delete=True)
|
||||
for key in keys:
|
||||
self._metadata(session.delete, key=key, delete=True)
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
|
||||
from openstack.compute import compute_service
|
||||
from openstack import resource
|
||||
|
||||
|
||||
class ServerMeta(resource.Resource):
|
||||
resource_key = 'meta'
|
||||
id_attribute = 'key'
|
||||
base_path = '/servers/%(server_id)s/metadata'
|
||||
service = compute_service.ComputeService()
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_retrieve = True
|
||||
allow_update = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
# Properties
|
||||
#: The metadata key.
|
||||
key = resource.prop('key')
|
||||
#: The ID of a server.
|
||||
server_id = resource.prop('server_id')
|
||||
#: The metadata value.
|
||||
value = resource.prop('value')
|
||||
|
||||
@classmethod
|
||||
def create_by_id(cls, session, attrs, resource_id=None, path_args=None):
|
||||
url = cls._get_url(path_args, resource_id)
|
||||
body = {cls.resource_key: {attrs['key']: attrs['value']}}
|
||||
resp = session.put(url, endpoint_filter=cls.service, json=body)
|
||||
resp = resp.json()
|
||||
return {'key': resource_id,
|
||||
'value': resp[cls.resource_key][resource_id]}
|
||||
|
||||
@classmethod
|
||||
def get_data_by_id(cls, session, resource_id, path_args=None,
|
||||
include_headers=False):
|
||||
url = cls._get_url(path_args, resource_id)
|
||||
resp = session.get(url, endpoint_filter=cls.service)
|
||||
resp = resp.json()
|
||||
return {'key': resource_id,
|
||||
'value': resp[cls.resource_key][resource_id]}
|
||||
|
||||
@classmethod
|
||||
def update_by_id(cls, session, resource_id, attrs, path_args=None):
|
||||
return cls.create_by_id(session, attrs, resource_id, path_args)
|
||||
|
||||
@classmethod
|
||||
def delete_by_id(cls, session, resource_id, path_args=None):
|
||||
url = cls._get_url(path_args, resource_id)
|
||||
headers = {'Accept': ''}
|
||||
session.delete(url, endpoint_filter=cls.service, headers=headers)
|
||||
|
||||
@classmethod
|
||||
def list(cls, session, path_args=None, **params):
|
||||
url = '/servers/%(server_id)s/metadata' % path_args
|
||||
resp = session.get(url, endpoint_filter=cls.service, params=params)
|
||||
resp = resp.json()
|
||||
resp = resp['metadata']
|
||||
return [cls.existing(server_id=path_args['server_id'], key=key,
|
||||
value=value)
|
||||
for key, value in six.iteritems(resp)]
|
|
@ -1,53 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.compute import compute_service
|
||||
from openstack import resource
|
||||
|
||||
|
||||
class ServerMetadata(resource.Resource):
|
||||
resource_key = 'metadata'
|
||||
id_attribute = 'server_id'
|
||||
base_path = '/servers/%(server_id)s/metadata'
|
||||
service = compute_service.ComputeService()
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_retrieve = True
|
||||
allow_update = True
|
||||
|
||||
# Properties
|
||||
#: The ID of a server.
|
||||
server_id = resource.prop('server_id')
|
||||
|
||||
@classmethod
|
||||
def create_by_id(cls, session, attrs, resource_id=None, path_args=None):
|
||||
no_id = attrs.copy()
|
||||
no_id.pop('server_id')
|
||||
body = {"metadata": no_id}
|
||||
url = cls._get_url(path_args)
|
||||
resp = session.put(url, endpoint_filter=cls.service, json=body)
|
||||
resp = resp.json()
|
||||
attrs = resp["metadata"].copy()
|
||||
attrs['server_id'] = resource_id
|
||||
return attrs
|
||||
|
||||
@classmethod
|
||||
def get_data_by_id(cls, session, resource_id, path_args=None, args=None,
|
||||
include_headers=False):
|
||||
url = cls._get_url(path_args)
|
||||
resp = session.get(url, endpoint_filter=cls.service)
|
||||
return resp.json()[cls.resource_key]
|
||||
|
||||
@classmethod
|
||||
def update_by_id(cls, session, resource_id, attrs, path_args=None):
|
||||
return cls.create_by_id(session, attrs, resource_id, path_args)
|
|
@ -55,40 +55,55 @@ class TestImage(base.BaseFunctionalTest):
|
|||
|
||||
def test_image_metadata(self):
|
||||
image = self._get_non_test_image()
|
||||
sot = self.conn.compute.get_image(image.id)
|
||||
|
||||
# Start by clearing out any other metadata.
|
||||
self.assertDictEqual(self.conn.compute.replace_image_metadata(sot),
|
||||
{})
|
||||
# delete pre-existing metadata
|
||||
self.conn.compute.delete_image_metadata(image, image.metadata.keys())
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertFalse(image.metadata)
|
||||
|
||||
# Insert first and last name metadata
|
||||
meta = {"first": "Matthew", "last": "Dellavedova"}
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.create_image_metadata(sot, **meta), meta)
|
||||
# get metadata
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertFalse(image.metadata)
|
||||
|
||||
# Update only the first name
|
||||
short = {"first": "Matt", "last": "Dellavedova"}
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.update_image_metadata(sot,
|
||||
first=short["first"]),
|
||||
short)
|
||||
# set no metadata
|
||||
self.conn.compute.set_image_metadata(image)
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertFalse(image.metadata)
|
||||
|
||||
# Get all metadata and then only the last name
|
||||
self.assertDictEqual(self.conn.compute.get_image_metadata(sot),
|
||||
short)
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.get_image_metadata(sot, "last"),
|
||||
{"last": short["last"]})
|
||||
# set empty metadata
|
||||
self.conn.compute.set_image_metadata(image, k0='')
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertFalse(image.metadata)
|
||||
|
||||
# Replace everything with just a nickname
|
||||
nick = {"nickname": "Delly"}
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.replace_image_metadata(sot, **nick),
|
||||
nick)
|
||||
self.assertDictEqual(self.conn.compute.get_image_metadata(sot),
|
||||
nick)
|
||||
# set metadata
|
||||
self.conn.compute.set_image_metadata(image, k1='v1')
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertTrue(image.metadata)
|
||||
self.assertEqual(1, len(image.metadata))
|
||||
self.assertIn('k1', image.metadata)
|
||||
self.assertEqual('v1', image.metadata['k1'])
|
||||
|
||||
# Delete the only remaining key, make sure we're empty
|
||||
self.assertIsNone(
|
||||
self.conn.compute.delete_image_metadata(sot, "nickname"))
|
||||
self.assertDictEqual(self.conn.compute.get_image_metadata(sot), {})
|
||||
# set more metadata
|
||||
self.conn.compute.set_image_metadata(image, k2='v2')
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertTrue(image.metadata)
|
||||
self.assertEqual(2, len(image.metadata))
|
||||
self.assertIn('k1', image.metadata)
|
||||
self.assertEqual('v1', image.metadata['k1'])
|
||||
self.assertIn('k2', image.metadata)
|
||||
self.assertEqual('v2', image.metadata['k2'])
|
||||
|
||||
# update metadata
|
||||
self.conn.compute.set_image_metadata(image, k1='v1.1')
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertTrue(image.metadata)
|
||||
self.assertEqual(2, len(image.metadata))
|
||||
self.assertIn('k1', image.metadata)
|
||||
self.assertEqual('v1.1', image.metadata['k1'])
|
||||
self.assertIn('k2', image.metadata)
|
||||
self.assertEqual('v2', image.metadata['k2'])
|
||||
|
||||
# delete metadata
|
||||
self.conn.compute.delete_image_metadata(image, image.metadata.keys())
|
||||
image = self.conn.compute.get_image_metadata(image)
|
||||
self.assertFalse(image.metadata)
|
||||
|
|
|
@ -69,45 +69,58 @@ class TestServer(base.BaseFunctionalTest):
|
|||
self.assertIn(self.NAME, names)
|
||||
|
||||
def test_server_metadata(self):
|
||||
sot = self.conn.compute.get_server(self.server.id)
|
||||
test_server = self.conn.compute.get_server(self.server.id)
|
||||
|
||||
# Start by clearing out any other metadata.
|
||||
self.assertDictEqual(self.conn.compute.replace_server_metadata(sot),
|
||||
{})
|
||||
# get metadata
|
||||
test_server = self.conn.compute.get_server_metadata(test_server)
|
||||
self.assertFalse(test_server.metadata)
|
||||
|
||||
# Create first and last name metadata
|
||||
meta = {"first": "Matthew", "last": "Dellavedova"}
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.create_server_metadata(sot, **meta), meta)
|
||||
# set no metadata
|
||||
self.conn.compute.set_server_metadata(test_server)
|
||||
test_server = self.conn.compute.get_server_metadata(test_server)
|
||||
self.assertFalse(test_server.metadata)
|
||||
|
||||
# Create something that already exists
|
||||
meta = {"last": "Inman"}
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.create_server_metadata(sot, **meta), meta)
|
||||
# set empty metadata
|
||||
self.conn.compute.set_server_metadata(test_server, k0='')
|
||||
server = self.conn.compute.get_server_metadata(test_server)
|
||||
self.assertTrue(server.metadata)
|
||||
|
||||
# Update only the first name
|
||||
short = {"first": "Matt", "last": "Inman"}
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.update_server_metadata(sot,
|
||||
first=short["first"]),
|
||||
short)
|
||||
# set metadata
|
||||
self.conn.compute.set_server_metadata(test_server, k1='v1')
|
||||
test_server = self.conn.compute.get_server_metadata(test_server)
|
||||
self.assertTrue(test_server.metadata)
|
||||
self.assertEqual(2, len(test_server.metadata))
|
||||
self.assertIn('k0', test_server.metadata)
|
||||
self.assertEqual('', test_server.metadata['k0'])
|
||||
self.assertIn('k1', test_server.metadata)
|
||||
self.assertEqual('v1', test_server.metadata['k1'])
|
||||
|
||||
# Get all metadata and then only the last name
|
||||
self.assertDictEqual(self.conn.compute.get_server_metadata(sot),
|
||||
short)
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.get_server_metadata(sot, "last"),
|
||||
{"last": short["last"]})
|
||||
# set more metadata
|
||||
self.conn.compute.set_server_metadata(test_server, k2='v2')
|
||||
test_server = self.conn.compute.get_server_metadata(test_server)
|
||||
self.assertTrue(test_server.metadata)
|
||||
self.assertEqual(3, len(test_server.metadata))
|
||||
self.assertIn('k0', test_server.metadata)
|
||||
self.assertEqual('', test_server.metadata['k0'])
|
||||
self.assertIn('k1', test_server.metadata)
|
||||
self.assertEqual('v1', test_server.metadata['k1'])
|
||||
self.assertIn('k2', test_server.metadata)
|
||||
self.assertEqual('v2', test_server.metadata['k2'])
|
||||
|
||||
# Replace everything with just a nickname
|
||||
nick = {"nickname": "Delly"}
|
||||
self.assertDictEqual(
|
||||
self.conn.compute.replace_server_metadata(sot, **nick),
|
||||
nick)
|
||||
self.assertDictEqual(self.conn.compute.get_server_metadata(sot),
|
||||
nick)
|
||||
# update metadata
|
||||
self.conn.compute.set_server_metadata(test_server, k1='v1.1')
|
||||
test_server = self.conn.compute.get_server_metadata(test_server)
|
||||
self.assertTrue(test_server.metadata)
|
||||
self.assertEqual(3, len(test_server.metadata))
|
||||
self.assertIn('k0', test_server.metadata)
|
||||
self.assertEqual('', test_server.metadata['k0'])
|
||||
self.assertIn('k1', test_server.metadata)
|
||||
self.assertEqual('v1.1', test_server.metadata['k1'])
|
||||
self.assertIn('k2', test_server.metadata)
|
||||
self.assertEqual('v2', test_server.metadata['k2'])
|
||||
|
||||
# Delete the only remaining key, make sure we're empty
|
||||
self.assertIsNone(
|
||||
self.conn.compute.delete_server_metadata(sot, "nickname"))
|
||||
self.assertDictEqual(self.conn.compute.get_server_metadata(sot), {})
|
||||
# delete metadata
|
||||
self.conn.compute.delete_server_metadata(
|
||||
test_server, test_server.metadata.keys())
|
||||
test_server = self.conn.compute.get_server_metadata(test_server)
|
||||
self.assertFalse(test_server.metadata)
|
||||
|
|
|
@ -52,96 +52,7 @@ class TestMetadata(testtools.TestCase):
|
|||
headers={},
|
||||
endpoint_filter=sot.service)
|
||||
|
||||
def test_get_one_metadata(self):
|
||||
response = mock.Mock()
|
||||
response.json.return_value = self.meta_result
|
||||
sess = mock.Mock()
|
||||
sess.get.return_value = response
|
||||
|
||||
sot = server.Server({"id": IDENTIFIER})
|
||||
|
||||
key = "lol"
|
||||
result = sot.get_metadata(sess, key)
|
||||
|
||||
self.assertEqual(result, self.meta_result["meta"])
|
||||
sess.get.assert_called_once_with("servers/IDENTIFIER/metadata/" + key,
|
||||
headers={},
|
||||
endpoint_filter=sot.service)
|
||||
|
||||
def test_create_metadata_bad_type(self):
|
||||
sess = mock.Mock()
|
||||
sess.put = mock.Mock()
|
||||
|
||||
sot = server.Server({"id": IDENTIFIER})
|
||||
self.assertRaises(ValueError,
|
||||
sot.create_metadata, sess, some_key=True)
|
||||
|
||||
def test_create_metadata(self):
|
||||
metadata = {"first": "1", "second": "2"}
|
||||
responses = []
|
||||
for key, value in metadata.items():
|
||||
response = mock.Mock()
|
||||
response.json.return_value = {"meta": {key: value}}
|
||||
responses.append(response)
|
||||
|
||||
sess = mock.Mock()
|
||||
sess.put.side_effect = responses
|
||||
|
||||
sot = server.Server({"id": IDENTIFIER})
|
||||
|
||||
result = sot.create_metadata(sess, **metadata)
|
||||
|
||||
self.assertEqual(result, dict([(k, v) for k, v in metadata.items()]))
|
||||
|
||||
# assert_called_with depends on sequence, which doesn't work nicely
|
||||
# with all of the dictionaries we're working with here. Build up
|
||||
# our own list of calls and check that they've happend
|
||||
calls = []
|
||||
for key in metadata.keys():
|
||||
calls.append(mock.call("servers/IDENTIFIER/metadata/" + key,
|
||||
endpoint_filter=sot.service,
|
||||
headers={},
|
||||
json={"meta": {key: metadata[key]}}))
|
||||
|
||||
sess.put.assert_has_calls(calls, any_order=True)
|
||||
|
||||
def test_replace_metadata(self):
|
||||
response = mock.Mock()
|
||||
response.json.return_value = self.metadata_result
|
||||
sess = mock.Mock()
|
||||
sess.put.return_value = response
|
||||
|
||||
sot = server.Server({"id": IDENTIFIER})
|
||||
|
||||
new_meta = {"lol": "rofl"}
|
||||
|
||||
result = sot.replace_metadata(sess, **new_meta)
|
||||
|
||||
self.assertEqual(result, self.metadata_result["metadata"])
|
||||
sess.put.assert_called_once_with("servers/IDENTIFIER/metadata",
|
||||
endpoint_filter=sot.service,
|
||||
headers={},
|
||||
json={"metadata": new_meta})
|
||||
|
||||
def test_replace_metadata_clear(self):
|
||||
empty = {}
|
||||
|
||||
response = mock.Mock()
|
||||
response.json.return_value = {"metadata": empty}
|
||||
sess = mock.Mock()
|
||||
sess.put.return_value = response
|
||||
|
||||
sot = server.Server({"id": IDENTIFIER})
|
||||
|
||||
result = sot.replace_metadata(sess)
|
||||
|
||||
self.assertEqual(result, empty)
|
||||
sess.put.assert_called_once_with("servers/IDENTIFIER/metadata",
|
||||
endpoint_filter=sot.service,
|
||||
headers={},
|
||||
json={"metadata": empty})
|
||||
|
||||
def test_update_metadata(self):
|
||||
def test_set_metadata(self):
|
||||
response = mock.Mock()
|
||||
response.json.return_value = self.metadata_result
|
||||
sess = mock.Mock()
|
||||
|
@ -149,15 +60,15 @@ class TestMetadata(testtools.TestCase):
|
|||
|
||||
sot = server.Server({"id": IDENTIFIER})
|
||||
|
||||
updated_meta = {"lol": "rofl"}
|
||||
set_meta = {"lol": "rofl"}
|
||||
|
||||
result = sot.update_metadata(sess, **updated_meta)
|
||||
result = sot.set_metadata(sess, **set_meta)
|
||||
|
||||
self.assertEqual(result, self.metadata_result["metadata"])
|
||||
sess.post.assert_called_once_with("servers/IDENTIFIER/metadata",
|
||||
endpoint_filter=sot.service,
|
||||
headers={},
|
||||
json={"metadata": updated_meta})
|
||||
json={"metadata": set_meta})
|
||||
|
||||
def test_delete_metadata(self):
|
||||
sess = mock.Mock()
|
||||
|
@ -167,9 +78,8 @@ class TestMetadata(testtools.TestCase):
|
|||
|
||||
key = "hey"
|
||||
|
||||
result = sot.delete_metadata(sess, key)
|
||||
sot.delete_metadata(sess, [key])
|
||||
|
||||
self.assertIsNone(result)
|
||||
sess.delete.assert_called_once_with(
|
||||
"servers/IDENTIFIER/metadata/" + key,
|
||||
headers={"Accept": ""},
|
||||
|
|
|
@ -289,47 +289,23 @@ class TestComputeProxy(test_proxy_base.TestProxyBase):
|
|||
def test_get_all_server_metadata(self):
|
||||
self._verify2("openstack.compute.v2.server.Server.get_metadata",
|
||||
self.proxy.get_server_metadata,
|
||||
expected_result={},
|
||||
method_args=["value"],
|
||||
expected_args=[self.session, None])
|
||||
method_result=server.Server.existing(id="value",
|
||||
metadata={}),
|
||||
expected_args=[self.session],
|
||||
expected_result={})
|
||||
|
||||
def test_get_one_server_metadata(self):
|
||||
self._verify2("openstack.compute.v2.server.Server.get_metadata",
|
||||
self.proxy.get_server_metadata,
|
||||
expected_result={},
|
||||
method_args=["value"],
|
||||
method_kwargs={"key": "key"},
|
||||
expected_args=[self.session, "key"])
|
||||
|
||||
def test_create_server_metadata(self):
|
||||
def test_set_server_metadata(self):
|
||||
kwargs = {"a": "1", "b": "2"}
|
||||
self._verify2("openstack.compute.v2.server.Server.create_metadata",
|
||||
self.proxy.create_server_metadata,
|
||||
expected_result={},
|
||||
self._verify2("openstack.compute.v2.server.Server.set_metadata",
|
||||
self.proxy.set_server_metadata,
|
||||
method_args=["value"],
|
||||
method_kwargs=kwargs,
|
||||
method_result=server.Server.existing(id="value",
|
||||
metadata=kwargs),
|
||||
expected_args=[self.session],
|
||||
expected_kwargs=kwargs)
|
||||
|
||||
def test_replace_server_metadata(self):
|
||||
kwargs = {"a": "1", "b": "2"}
|
||||
self._verify2("openstack.compute.v2.server.Server.replace_metadata",
|
||||
self.proxy.replace_server_metadata,
|
||||
expected_result={},
|
||||
method_args=["value"],
|
||||
method_kwargs=kwargs,
|
||||
expected_args=[self.session],
|
||||
expected_kwargs=kwargs)
|
||||
|
||||
def test_update_server_metadata(self):
|
||||
kwargs = {"a": "1", "b": "2"}
|
||||
self._verify2("openstack.compute.v2.server.Server.update_metadata",
|
||||
self.proxy.update_server_metadata,
|
||||
expected_result={},
|
||||
method_args=["value"],
|
||||
method_kwargs=kwargs,
|
||||
expected_args=[self.session],
|
||||
expected_kwargs=kwargs)
|
||||
expected_kwargs=kwargs,
|
||||
expected_result=kwargs)
|
||||
|
||||
def test_delete_server_metadata(self):
|
||||
self._verify2("openstack.compute.v2.server.Server.delete_metadata",
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from openstack.compute.v2 import server_meta
|
||||
|
||||
FAKE_KEY = 'cervus'
|
||||
FAKE_SERVER_ID = 'cervidae'
|
||||
FAKE_VALUE = 'canadensis'
|
||||
EXAMPLE = {
|
||||
'key': FAKE_KEY,
|
||||
'server_id': FAKE_SERVER_ID,
|
||||
'value': FAKE_VALUE,
|
||||
}
|
||||
FAKE_RESPONSE = {"meta": {FAKE_KEY: FAKE_VALUE}}
|
||||
FAKE_RESPONSES = {"metadata": {FAKE_KEY: FAKE_VALUE}}
|
||||
|
||||
|
||||
class TestServerMeta(testtools.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = server_meta.ServerMeta()
|
||||
self.assertEqual('meta', sot.resource_key)
|
||||
self.assertIsNone(sot.resources_key)
|
||||
self.assertEqual('/servers/%(server_id)s/metadata', sot.base_path)
|
||||
self.assertEqual('compute', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = server_meta.ServerMeta(EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['key'], sot.key)
|
||||
self.assertEqual(EXAMPLE['server_id'], sot.server_id)
|
||||
self.assertEqual(EXAMPLE['value'], sot.value)
|
||||
|
||||
def test_create(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSE
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.put = mock.Mock(return_value=resp)
|
||||
sot = server_meta.ServerMeta(EXAMPLE)
|
||||
|
||||
sot.create(sess)
|
||||
|
||||
url = 'servers/' + FAKE_SERVER_ID + '/metadata/' + FAKE_KEY
|
||||
body = {"meta": {FAKE_KEY: FAKE_VALUE}}
|
||||
sess.put.assert_called_with(url, endpoint_filter=sot.service,
|
||||
json=body)
|
||||
self.assertEqual(FAKE_VALUE, sot.value)
|
||||
self.assertEqual(FAKE_KEY, sot.key)
|
||||
self.assertEqual(FAKE_SERVER_ID, sot.server_id)
|
||||
|
||||
def test_get(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSES
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.get = mock.Mock(return_value=resp)
|
||||
sot = server_meta.ServerMeta()
|
||||
path_args = {'server_id': FAKE_SERVER_ID}
|
||||
|
||||
resp = sot.list(sess, path_args=path_args)
|
||||
|
||||
url = '/servers/' + FAKE_SERVER_ID + '/metadata'
|
||||
sess.get.assert_called_with(url, endpoint_filter=sot.service,
|
||||
params={})
|
||||
self.assertEqual(1, len(resp))
|
||||
self.assertEqual(FAKE_SERVER_ID, resp[0].server_id)
|
||||
self.assertEqual(FAKE_KEY, resp[0].key)
|
||||
self.assertEqual(FAKE_VALUE, resp[0].value)
|
||||
|
||||
def test_update(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSE
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.put = mock.Mock(return_value=resp)
|
||||
sot = server_meta.ServerMeta(EXAMPLE)
|
||||
|
||||
sot.update(sess)
|
||||
|
||||
url = 'servers/' + FAKE_SERVER_ID + '/metadata/' + FAKE_KEY
|
||||
body = {"meta": {FAKE_KEY: FAKE_VALUE}}
|
||||
sess.put.assert_called_with(url, endpoint_filter=sot.service,
|
||||
json=body)
|
||||
self.assertEqual(FAKE_VALUE, sot.value)
|
||||
self.assertEqual(FAKE_KEY, sot.key)
|
||||
self.assertEqual(FAKE_SERVER_ID, sot.server_id)
|
||||
|
||||
def test_delete(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSES
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.delete = mock.Mock(return_value=resp)
|
||||
sot = server_meta.ServerMeta(EXAMPLE)
|
||||
|
||||
sot.delete(sess)
|
||||
|
||||
url = 'servers/' + FAKE_SERVER_ID + '/metadata/' + FAKE_KEY
|
||||
headers = {'Accept': ''}
|
||||
sess.delete.assert_called_with(url, endpoint_filter=sot.service,
|
||||
headers=headers)
|
||||
|
||||
def test_list(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSES
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.get = mock.Mock(return_value=resp)
|
||||
sot = server_meta.ServerMeta()
|
||||
path_args = {'server_id': FAKE_SERVER_ID}
|
||||
|
||||
resp = sot.list(sess, path_args=path_args)
|
||||
|
||||
url = '/servers/' + FAKE_SERVER_ID + '/metadata'
|
||||
sess.get.assert_called_with(url, endpoint_filter=sot.service,
|
||||
params={})
|
||||
self.assertEqual(1, len(resp))
|
||||
self.assertEqual(FAKE_SERVER_ID, resp[0].server_id)
|
||||
self.assertEqual(FAKE_KEY, resp[0].key)
|
||||
self.assertEqual(FAKE_VALUE, resp[0].value)
|
|
@ -1,97 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from openstack.compute.v2 import server_metadata
|
||||
|
||||
FAKE_SERVER_ID = 'cervidae'
|
||||
FAKE_KEY = 'cervus'
|
||||
FAKE_VALUE = 'canadensis'
|
||||
FAKE_KEY2 = 'odocoileus'
|
||||
FAKE_VALUE2 = 'hemionus'
|
||||
EXAMPLE = {
|
||||
'server_id': FAKE_SERVER_ID,
|
||||
FAKE_KEY: FAKE_VALUE,
|
||||
}
|
||||
FAKE_RESPONSE = {"metadata": {FAKE_KEY: FAKE_VALUE, FAKE_KEY2: FAKE_VALUE2}}
|
||||
|
||||
|
||||
class TestServerMetadata(testtools.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = server_metadata.ServerMetadata()
|
||||
self.assertEqual('metadata', sot.resource_key)
|
||||
self.assertIsNone(sot.resources_key)
|
||||
self.assertEqual('/servers/%(server_id)s/metadata', sot.base_path)
|
||||
self.assertEqual('compute', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertFalse(sot.allow_delete)
|
||||
self.assertFalse(sot.allow_list)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = server_metadata.ServerMetadata(EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['server_id'], sot.server_id)
|
||||
self.assertEqual(FAKE_VALUE, sot[FAKE_KEY])
|
||||
|
||||
def test_create(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSE
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.put = mock.Mock(return_value=resp)
|
||||
sot = server_metadata.ServerMetadata(EXAMPLE.copy())
|
||||
|
||||
sot.create(sess)
|
||||
|
||||
url = '/servers/' + FAKE_SERVER_ID + '/metadata'
|
||||
body = {"metadata": {FAKE_KEY: FAKE_VALUE}}
|
||||
sess.put.assert_called_with(url, endpoint_filter=sot.service,
|
||||
json=body)
|
||||
self.assertEqual(FAKE_SERVER_ID, sot.server_id)
|
||||
self.assertEqual(FAKE_VALUE, sot[FAKE_KEY])
|
||||
|
||||
def test_get(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSE
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.get = mock.Mock(return_value=resp)
|
||||
sot = server_metadata.ServerMetadata(EXAMPLE.copy())
|
||||
|
||||
sot.get(sess)
|
||||
|
||||
url = '/servers/' + FAKE_SERVER_ID + '/metadata'
|
||||
sess.get.assert_called_with(url, endpoint_filter=sot.service)
|
||||
self.assertEqual(FAKE_SERVER_ID, sot.server_id)
|
||||
self.assertEqual(FAKE_VALUE, sot[FAKE_KEY])
|
||||
self.assertEqual(FAKE_VALUE2, sot[FAKE_KEY2])
|
||||
|
||||
def test_update(self):
|
||||
resp = mock.Mock()
|
||||
resp.body = FAKE_RESPONSE
|
||||
resp.json = mock.Mock(return_value=resp.body)
|
||||
sess = mock.Mock()
|
||||
sess.put = mock.Mock(return_value=resp)
|
||||
sot = server_metadata.ServerMetadata(EXAMPLE.copy())
|
||||
|
||||
sot.update(sess)
|
||||
|
||||
url = '/servers/' + FAKE_SERVER_ID + '/metadata'
|
||||
body = {"metadata": {FAKE_KEY: FAKE_VALUE}}
|
||||
sess.put.assert_called_with(url, endpoint_filter=sot.service,
|
||||
json=body)
|
||||
self.assertEqual(FAKE_SERVER_ID, sot.server_id)
|
||||
self.assertEqual(FAKE_VALUE, sot[FAKE_KEY])
|
|
@ -50,7 +50,7 @@ class TestProxyBase(base.TestCase):
|
|||
# the _verify method. It will be removed once there is one API to
|
||||
# be verifying.
|
||||
def _verify2(self, mock_method, test_method,
|
||||
method_args=None, method_kwargs=None,
|
||||
method_args=None, method_kwargs=None, method_result=None,
|
||||
expected_args=None, expected_kwargs=None,
|
||||
expected_result=None):
|
||||
with mock.patch(mock_method) as mocked:
|
||||
|
@ -62,8 +62,12 @@ class TestProxyBase(base.TestCase):
|
|||
expected_args = expected_args or ()
|
||||
expected_kwargs = expected_kwargs or {}
|
||||
|
||||
self.assertEqual(expected_result, test_method(*method_args,
|
||||
**method_kwargs))
|
||||
if method_result:
|
||||
self.assertEqual(method_result, test_method(*method_args,
|
||||
**method_kwargs))
|
||||
else:
|
||||
self.assertEqual(expected_result, test_method(*method_args,
|
||||
**method_kwargs))
|
||||
mocked.assert_called_with(*expected_args, **expected_kwargs)
|
||||
else:
|
||||
self.assertEqual(expected_result, test_method())
|
||||
|
|
Loading…
Reference in New Issue