Basic testing
This commit is contained in:
@@ -29,21 +29,34 @@ class Image(base.Resource):
|
||||
class ImageManager(base.Manager):
|
||||
resource_class = Image
|
||||
|
||||
def get(self, image):
|
||||
"""Get the metadata for a specific image.
|
||||
|
||||
:param image: image object or id to look up
|
||||
:rtype: :class:`Image`
|
||||
"""
|
||||
resp, body = self.api.head("/images/%s" % base.getid(image))
|
||||
def _image_meta_from_headers(self, headers):
|
||||
meta = {'properties': {}}
|
||||
for key, value in resp.iteritems():
|
||||
for key, value in headers.iteritems():
|
||||
if key.startswith('x-image-meta-property-'):
|
||||
_key = key[22:]
|
||||
meta['properties'][_key] = value
|
||||
elif key.startswith('x-image-meta-'):
|
||||
_key = key[13:]
|
||||
meta[_key] = value
|
||||
return meta
|
||||
|
||||
def _image_meta_to_headers(self, fields):
|
||||
headers = {}
|
||||
for key, value in fields.iteritems():
|
||||
if key == 'properties':
|
||||
headers['x-image-meta-property-%s' % key] = value
|
||||
else:
|
||||
headers['x-image-meta-%s' % key] = value
|
||||
return headers
|
||||
|
||||
def get(self, image):
|
||||
"""Get the metadata for a specific image.
|
||||
|
||||
:param image: image object or id to look up
|
||||
:rtype: :class:`Image`
|
||||
"""
|
||||
resp, body = self.api.head('/v1/images/%s' % base.getid(image))
|
||||
meta = self._image_meta_from_headers(resp)
|
||||
return Image(self, meta)
|
||||
|
||||
def list(self, limit=None, marker=None):
|
||||
@@ -58,13 +71,29 @@ class ImageManager(base.Manager):
|
||||
params['limit'] = int(limit)
|
||||
if marker:
|
||||
params['marker'] = int(marker)
|
||||
|
||||
query = ""
|
||||
if params:
|
||||
query = "?" + urllib.urlencode(params)
|
||||
|
||||
return self._list("/images/detail%s" % query, "images")
|
||||
query = '?%s' % urllib.urlencode(params) if params else ''
|
||||
return self._list('/v1/images/detail%s' % query, "images")
|
||||
|
||||
def delete(self, image):
|
||||
"""Delete an image."""
|
||||
self._delete("/images/%s" % base.getid(image))
|
||||
self._delete("/v1/images/%s" % base.getid(image))
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create an image"""
|
||||
fields = {}
|
||||
if 'name' in kwargs:
|
||||
fields['name'] = kwargs['name']
|
||||
resp, body = self.api.post('/v1/images', body={'image': fields})
|
||||
meta = self._image_meta_from_headers(resp)
|
||||
return Image(self, meta)
|
||||
|
||||
def update(self, image, **kwargs):
|
||||
"""Update an image"""
|
||||
fields = {}
|
||||
if 'name' in kwargs:
|
||||
fields['name'] = kwargs['name']
|
||||
send_meta = self._image_meta_to_headers(fields)
|
||||
url = '/v1/images/%s' % base.getid(image)
|
||||
resp, body = self.api.put(url, headers=send_meta)
|
||||
recv_meta = self._image_meta_from_headers(resp)
|
||||
return Image(self, recv_meta)
|
||||
|
@@ -50,7 +50,7 @@ function run_tests {
|
||||
function run_pep8 {
|
||||
echo "Running pep8..."
|
||||
PEP8_OPTIONS="--exclude=$PEP8_EXCLUDE --repeat"
|
||||
PEP8_INCLUDE="glanceclient/* setup.py run_tests.py tools/install_venv.py"
|
||||
PEP8_INCLUDE="glanceclient/*.py setup.py run_tests.py tools/install_venv.py"
|
||||
${wrapper} pep8 $PEP8_OPTIONS $PEP8_INCLUDE
|
||||
}
|
||||
|
||||
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
@@ -1,5 +0,0 @@
|
||||
import unittest
|
||||
|
||||
class TestCase(unittest.TestCase):
|
||||
def test_one(self):
|
||||
self.assertTrue(True)
|
0
tests/v1/__init__.py
Normal file
0
tests/v1/__init__.py
Normal file
59
tests/v1/test_images.py
Normal file
59
tests/v1/test_images.py
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
import unittest
|
||||
|
||||
from tests.v1 import utils
|
||||
|
||||
import glanceclient.v1.images
|
||||
|
||||
|
||||
class ImageManagerTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.api = utils.FakeAPI()
|
||||
self.mgr = glanceclient.v1.images.ImageManager(self.api)
|
||||
|
||||
def test_list(self):
|
||||
images = self.mgr.list()
|
||||
expect = [('GET', '/v1/images/detail', {}, None)]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(len(images), 1)
|
||||
self.assertEqual(images[0].id, '1')
|
||||
self.assertEqual(images[0].name, 'image-1')
|
||||
self.assertEqual(images[0].properties, {'arch': 'x86_64'})
|
||||
|
||||
def test_list_with_limit(self):
|
||||
self.mgr.list(limit=10)
|
||||
expect = [('GET', '/v1/images/detail?limit=10', {}, None)]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
|
||||
def test_list_with_marker(self):
|
||||
self.mgr.list(marker=20)
|
||||
expect = [('GET', '/v1/images/detail?marker=20', {}, None)]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
|
||||
def test_get(self):
|
||||
image = self.mgr.get('1')
|
||||
expect = [('HEAD', '/v1/images/1', {}, None)]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(image.id, '1')
|
||||
self.assertEqual(image.name, 'image-1')
|
||||
|
||||
def test_delete(self):
|
||||
self.mgr.delete('1')
|
||||
expect = [('DELETE', '/v1/images/1', {}, None)]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
|
||||
def test_create(self):
|
||||
image = self.mgr.create(name='image-1')
|
||||
expect = [('POST', '/v1/images', {}, {'image': {'name': 'image-1'}})]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(image.id, '1')
|
||||
self.assertEqual(image.name, 'image-1')
|
||||
|
||||
def test_update(self):
|
||||
image = self.mgr.update('1', name='image-2')
|
||||
expect_hdrs = {'x-image-meta-name': 'image-2'}
|
||||
expect = [('PUT', '/v1/images/1', expect_hdrs, None)]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(image.id, '1')
|
||||
self.assertEqual(image.name, 'image-2')
|
70
tests/v1/utils.py
Normal file
70
tests/v1/utils.py
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
fixtures = {
|
||||
'/v1/images': {
|
||||
'POST': (
|
||||
{
|
||||
'location': '/v1/images/1',
|
||||
'x-image-meta-id': '1',
|
||||
'x-image-meta-name': 'image-1',
|
||||
'x-image-meta-property-arch': 'x86_64',
|
||||
},
|
||||
None),
|
||||
},
|
||||
'/v1/images/detail': {
|
||||
'GET': (
|
||||
{},
|
||||
{'images': [
|
||||
{
|
||||
'id': '1',
|
||||
'name': 'image-1',
|
||||
'properties': {'arch': 'x86_64'},
|
||||
},
|
||||
]},
|
||||
),
|
||||
},
|
||||
'/v1/images/1': {
|
||||
'HEAD': (
|
||||
{
|
||||
'x-image-meta-id': '1',
|
||||
'x-image-meta-name': 'image-1',
|
||||
'x-image-meta-property-arch': 'x86_64',
|
||||
},
|
||||
None),
|
||||
'PUT': (
|
||||
{
|
||||
'x-image-meta-id': '1',
|
||||
'x-image-meta-name': 'image-2',
|
||||
'x-image-meta-property-arch': 'x86_64',
|
||||
},
|
||||
None),
|
||||
'DELETE': ({}, None),
|
||||
}
|
||||
}
|
||||
|
||||
class FakeAPI(object):
|
||||
|
||||
def __init__(self):
|
||||
self.calls = []
|
||||
|
||||
def _request(self, method, url, headers=None, body=None):
|
||||
call = (method, url, headers or {}, body)
|
||||
self.calls.append(call)
|
||||
# drop any query params
|
||||
url = url.split('?', 1)[0]
|
||||
return fixtures[url][method]
|
||||
|
||||
def get(self, url):
|
||||
return self._request('GET', url)
|
||||
|
||||
def head(self, url):
|
||||
return self._request('HEAD', url)
|
||||
|
||||
def post(self, url, headers=None, body=None):
|
||||
return self._request('POST', url, headers, body)
|
||||
|
||||
def put(self, url, headers=None, body=None):
|
||||
return self._request('PUT', url, headers, body)
|
||||
|
||||
def delete(self, url):
|
||||
return self._request('DELETE', url)
|
Reference in New Issue
Block a user