internal client unicode paths

made internal client handle unicode path parts by adding make_path method
fixed pep8 problems in internal client and its test
moved internal client unit test file to correct directory

Change-Id: Id1c81c9cb0db05342e4e8a8393db93552fda4647
This commit is contained in:
Greg Lange 2012-10-02 18:25:24 +00:00
parent 5b02fded4e
commit e7f3a9865e
2 changed files with 255 additions and 178 deletions

View File

@ -53,8 +53,9 @@ class CompressingFileReader(object):
def __init__(self, file_obj, compresslevel=9): def __init__(self, file_obj, compresslevel=9):
self._f = file_obj self._f = file_obj
self._compressor = compressobj(compresslevel, zlib.DEFLATED, self._compressor = compressobj(
-zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0) compresslevel, zlib.DEFLATED, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL,
0)
self.done = False self.done = False
self.first = True self.first = True
self.crc32 = 0 self.crc32 = 0
@ -118,8 +119,8 @@ class InternalClient(object):
self.user_agent = user_agent self.user_agent = user_agent
self.request_tries = request_tries self.request_tries = request_tries
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
body_file=None): self, method, path, headers, acceptable_statuses, body_file=None):
""" """
Makes a request to Swift with retries. Makes a request to Swift with retries.
@ -142,8 +143,8 @@ class InternalClient(object):
headers['user-agent'] = self.user_agent headers['user-agent'] = self.user_agent
resp = exc_type = exc_value = exc_traceback = None resp = exc_type = exc_value = exc_traceback = None
for attempt in xrange(self.request_tries): for attempt in xrange(self.request_tries):
req = Request.blank(path, environ={'REQUEST_METHOD': method}, req = Request.blank(
headers=headers) path, environ={'REQUEST_METHOD': method}, headers=headers)
if body_file is not None: if body_file is not None:
if hasattr(body_file, 'seek'): if hasattr(body_file, 'seek'):
body_file.seek(0) body_file.seek(0)
@ -157,14 +158,14 @@ class InternalClient(object):
exc_type, exc_value, exc_traceback = exc_info() exc_type, exc_value, exc_traceback = exc_info()
sleep(2 ** (attempt + 1)) sleep(2 ** (attempt + 1))
if resp: if resp:
raise UnexpectedResponse(_('Unexpected response: %s' % raise UnexpectedResponse(
(resp.status,)), resp) _('Unexpected response: %s' % (resp.status,)), resp)
if exc_type: if exc_type:
# To make pep8 tool happy, in place of raise t, v, tb: # To make pep8 tool happy, in place of raise t, v, tb:
raise exc_type(*exc_value.args), None, exc_traceback raise exc_type(*exc_value.args), None, exc_traceback
def _get_metadata(self, path, metadata_prefix='', def _get_metadata(
acceptable_statuses=(2,)): self, path, metadata_prefix='', acceptable_statuses=(2,)):
""" """
Gets metadata by doing a HEAD on a path and using the metadata_prefix Gets metadata by doing a HEAD on a path and using the metadata_prefix
to get values from the headers returned. to get values from the headers returned.
@ -192,7 +193,8 @@ class InternalClient(object):
metadata[k[len(metadata_prefix):]] = v metadata[k[len(metadata_prefix):]] = v
return metadata return metadata
def _iter_items(self, path, marker='', end_marker='', def _iter_items(
self, path, marker='', end_marker='',
acceptable_statuses=(2, HTTP_NOT_FOUND)): acceptable_statuses=(2, HTTP_NOT_FOUND)):
""" """
Returns an iterator of items from a json listing. Assumes listing has Returns an iterator of items from a json listing. Assumes listing has
@ -212,8 +214,8 @@ class InternalClient(object):
""" """
while True: while True:
resp = self.make_request('GET', resp = self.make_request(
'%s?format=json&marker=%s&end_marker=%s' % 'GET', '%s?format=json&marker=%s&end_marker=%s' %
(path, quote(marker), quote(end_marker)), (path, quote(marker), quote(end_marker)),
{}, acceptable_statuses) {}, acceptable_statuses)
if resp.status_int != 200: if resp.status_int != 200:
@ -225,7 +227,40 @@ class InternalClient(object):
yield item yield item
marker = data[-1]['name'] marker = data[-1]['name']
def _set_metadata(self, path, metadata, metadata_prefix='', def make_path(self, account, container=None, obj=None):
"""
Returns a swift path for a request quoting and utf-8 encoding the path
parts as need be.
:param account: swift account
:param container: container, defaults to None
:param obj: object, defaults to None
:raises ValueError: Is raised if obj is specified and container is
not.
"""
if isinstance(account, unicode):
account = account.encode('utf-8')
if isinstance(container, unicode):
container = container.encode('utf-8')
if isinstance(obj, unicode):
obj = obj.encode('utf-8')
path = '/v1/%s' % quote(account)
if container:
path += '/%s' % quote(container)
if obj:
path += '/%s' % quote(obj)
elif obj:
raise ValueError('Object specified without container')
return path
def _set_metadata(
self, path, metadata, metadata_prefix='',
acceptable_statuses=(2,)): acceptable_statuses=(2,)):
""" """
Sets metadata on path using metadata_prefix to set values in headers of Sets metadata on path using metadata_prefix to set values in headers of
@ -255,7 +290,8 @@ class InternalClient(object):
# account methods # account methods
def iter_containers(self, account, marker='', end_marker='', def iter_containers(
self, account, marker='', end_marker='',
acceptable_statuses=(2, HTTP_NOT_FOUND)): acceptable_statuses=(2, HTTP_NOT_FOUND)):
""" """
Returns an iterator of containers dicts from an account. Returns an iterator of containers dicts from an account.
@ -273,11 +309,11 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s' % (quote(account),) path = self.make_path(account)
return self._iter_items(path, marker, end_marker, acceptable_statuses) return self._iter_items(path, marker, end_marker, acceptable_statuses)
def get_account_info(self, account, def get_account_info(
acceptable_statuses=(2, HTTP_NOT_FOUND)): self, account, acceptable_statuses=(2, HTTP_NOT_FOUND)):
""" """
Returns (container_count, object_count) for an account. Returns (container_count, object_count) for an account.
@ -291,13 +327,13 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s' % (quote(account),) path = self.make_path(account)
resp = self.make_request('HEAD', path, {}, acceptable_statuses) resp = self.make_request('HEAD', path, {}, acceptable_statuses)
return (int(resp.headers.get('x-account-container-count', 0)), return (int(resp.headers.get('x-account-container-count', 0)),
int(resp.headers.get('x-account-object-count', 0))) int(resp.headers.get('x-account-object-count', 0)))
def get_account_metadata(self, account, metadata_prefix='', def get_account_metadata(
acceptable_statuses=(2,)): self, account, metadata_prefix='', acceptable_statuses=(2,)):
""" """
Gets account metadata. Gets account metadata.
@ -316,10 +352,11 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s' % (quote(account)) path = self.make_path(account)
return self._get_metadata(path, metadata_prefix, acceptable_statuses) return self._get_metadata(path, metadata_prefix, acceptable_statuses)
def set_account_metadata(self, account, metadata, metadata_prefix='', def set_account_metadata(
self, account, metadata, metadata_prefix='',
acceptable_statuses=(2,)): acceptable_statuses=(2,)):
""" """
Sets account metadata. A call to this will add to the account Sets account metadata. A call to this will add to the account
@ -341,9 +378,9 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s' % (quote(account)) path = self.make_path(account)
self._set_metadata(path, metadata, metadata_prefix, self._set_metadata(
acceptable_statuses) path, metadata, metadata_prefix, acceptable_statuses)
# container methods # container methods
@ -362,12 +399,12 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s' % (quote(account), quote(container)) path = self.make_path(account, container)
resp = self.make_request('HEAD', path, {}, (2, HTTP_NOT_FOUND)) resp = self.make_request('HEAD', path, {}, (2, HTTP_NOT_FOUND))
return resp.status_int != HTTP_NOT_FOUND return resp.status_int != HTTP_NOT_FOUND
def create_container(self, account, container, headers=None, def create_container(
acceptable_statuses=(2,)): self, account, container, headers=None, acceptable_statuses=(2,)):
""" """
Creates container. Creates container.
@ -384,11 +421,11 @@ class InternalClient(object):
""" """
headers = headers or {} headers = headers or {}
path = '/v1/%s/%s' % (quote(account), quote(container)) path = self.make_path(account, container)
self.make_request('PUT', path, headers, acceptable_statuses) self.make_request('PUT', path, headers, acceptable_statuses)
def delete_container(self, account, container, def delete_container(
acceptable_statuses=(2, HTTP_NOT_FOUND)): self, account, container, acceptable_statuses=(2, HTTP_NOT_FOUND)):
""" """
Deletes a container. Deletes a container.
@ -403,10 +440,11 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s' % (quote(account), quote(container)) path = self.make_path(account, container)
self.make_request('DELETE', path, {}, acceptable_statuses) self.make_request('DELETE', path, {}, acceptable_statuses)
def get_container_metadata(self, account, container, metadata_prefix='', def get_container_metadata(
self, account, container, metadata_prefix='',
acceptable_statuses=(2,)): acceptable_statuses=(2,)):
""" """
Gets container metadata. Gets container metadata.
@ -427,10 +465,11 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s' % (quote(account), quote(container)) path = self.make_path(account, container)
return self._get_metadata(path, metadata_prefix, acceptable_statuses) return self._get_metadata(path, metadata_prefix, acceptable_statuses)
def iter_objects(self, account, container, marker='', end_marker='', def iter_objects(
self, account, container, marker='', end_marker='',
acceptable_statuses=(2, HTTP_NOT_FOUND)): acceptable_statuses=(2, HTTP_NOT_FOUND)):
""" """
Returns an iterator of object dicts from a container. Returns an iterator of object dicts from a container.
@ -449,11 +488,12 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s' % (quote(account), quote(container)) path = self.make_path(account, container)
return self._iter_items(path, marker, end_marker, acceptable_statuses) return self._iter_items(path, marker, end_marker, acceptable_statuses)
def set_container_metadata(self, account, container, metadata, def set_container_metadata(
metadata_prefix='', acceptable_statuses=(2,)): self, account, container, metadata, metadata_prefix='',
acceptable_statuses=(2,)):
""" """
Sets container metadata. A call to this will add to the container Sets container metadata. A call to this will add to the container
metadata and not overwrite all of it with values in the metadata dict. metadata and not overwrite all of it with values in the metadata dict.
@ -475,20 +515,21 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s' % (quote(account), quote(container)) path = self.make_path(account, container)
self._set_metadata(path, metadata, metadata_prefix, self._set_metadata(
acceptable_statuses) path, metadata, metadata_prefix, acceptable_statuses)
# object methods # object methods
def delete_object(self, account, container, object_name, def delete_object(
self, account, container, obj,
acceptable_statuses=(2, HTTP_NOT_FOUND)): acceptable_statuses=(2, HTTP_NOT_FOUND)):
""" """
Deletes an object. Deletes an object.
:param account: The object's account. :param account: The object's account.
:param container: The object's container. :param container: The object's container.
:param object_name: The object. :param obj: The object.
:param acceptable_statuses: List of status for valid responses, :param acceptable_statuses: List of status for valid responses,
defaults to (2, HTTP_NOT_FOUND). defaults to (2, HTTP_NOT_FOUND).
@ -498,18 +539,18 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s/%s' % (quote(account), quote(container), path = self.make_path(account, container, obj)
quote(object_name))
self.make_request('DELETE', path, {}, acceptable_statuses) self.make_request('DELETE', path, {}, acceptable_statuses)
def get_object_metadata(self, account, container, object_name, def get_object_metadata(
metadata_prefix='', acceptable_statuses=(2,)): self, account, container, obj, metadata_prefix='',
acceptable_statuses=(2,)):
""" """
Gets object metadata. Gets object metadata.
:param account: The object's account. :param account: The object's account.
:param container: The object's container. :param container: The object's container.
:param object_name: The object. :param obj: The object.
:param metadata_prefix: Used to filter values from the headers :param metadata_prefix: Used to filter values from the headers
returned. Will strip that prefix from the returned. Will strip that prefix from the
keys in the dict returned. Defaults to ''. keys in the dict returned. Defaults to ''.
@ -524,11 +565,11 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s/%s' % (quote(account), quote(container), path = self.make_path(account, container, obj)
quote(object_name))
return self._get_metadata(path, metadata_prefix, acceptable_statuses) return self._get_metadata(path, metadata_prefix, acceptable_statuses)
def iter_object_lines(self, account, container, object_name, headers=None, def iter_object_lines(
self, account, container, obj, headers=None,
acceptable_statuses=(2,)): acceptable_statuses=(2,)):
""" """
Returns an iterator of object lines from an uncompressed or compressed Returns an iterator of object lines from an uncompressed or compressed
@ -549,13 +590,12 @@ class InternalClient(object):
""" """
headers = headers or {} headers = headers or {}
path = '/v1/%s/%s/%s' % (quote(account), quote(container), path = self.make_path(account, container, obj)
quote(object_name))
resp = self.make_request('GET', path, headers, acceptable_statuses) resp = self.make_request('GET', path, headers, acceptable_statuses)
last_part = '' last_part = ''
compressed = object_name.endswith('.gz') compressed = obj.endswith('.gz')
# magic in the following zlib.decompressobj argument is courtesy of # magic in the following zlib.decompressobj argument is courtesy of
# Python decompressing gzip chunk-by-chunk # Python decompressing gzip chunk-by-chunk
# http://stackoverflow.com/questions/2423866 # http://stackoverflow.com/questions/2423866
@ -574,7 +614,8 @@ class InternalClient(object):
if last_part: if last_part:
yield last_part yield last_part
def set_object_metadata(self, account, container, object_name, metadata, def set_object_metadata(
self, account, container, obj, metadata,
metadata_prefix='', acceptable_statuses=(2,)): metadata_prefix='', acceptable_statuses=(2,)):
""" """
Sets an object's metadata. The object's metadata will be overwritten Sets an object's metadata. The object's metadata will be overwritten
@ -582,7 +623,7 @@ class InternalClient(object):
:param account: The object's account. :param account: The object's account.
:param container: The object's container. :param container: The object's container.
:param object_name: The object. :param obj: The object.
:param metadata: Dict of metadata to set. :param metadata: Dict of metadata to set.
:param metadata_prefix: Prefix used to set metadata values in headers :param metadata_prefix: Prefix used to set metadata values in headers
of requests, used to prefix keys in metadata of requests, used to prefix keys in metadata
@ -596,18 +637,17 @@ class InternalClient(object):
unexpected way. unexpected way.
""" """
path = '/v1/%s/%s/%s' % (quote(account), quote(container), path = self.make_path(account, container, obj)
quote(object_name)) self._set_metadata(
self._set_metadata(path, metadata, metadata_prefix, path, metadata, metadata_prefix, acceptable_statuses)
acceptable_statuses)
def upload_object(self, fobj, account, container, object_name, def upload_object(
headers=None): self, fobj, account, container, obj, headers=None):
""" """
:param fobj: File object to read object's content from. :param fobj: File object to read object's content from.
:param account: The object's account. :param account: The object's account.
:param container: The object's container. :param container: The object's container.
:param object_name: The object. :param obj: The object.
:param headers: Headers to send with request, defaults ot empty dict. :param headers: Headers to send with request, defaults ot empty dict.
:raises UnexpectedResponse: Exception raised when requests fail :raises UnexpectedResponse: Exception raised when requests fail
@ -618,6 +658,5 @@ class InternalClient(object):
headers = dict(headers or {}) headers = dict(headers or {})
headers['Transfer-Encoding'] = 'chunked' headers['Transfer-Encoding'] = 'chunked'
path = '/v1/%s/%s/%s' % (quote(account), quote(container), path = self.make_path(account, container, obj)
quote(object_name))
self.make_request('PUT', path, headers, (2,), fobj) self.make_request('PUT', path, headers, (2,), fobj)

View File

@ -16,6 +16,7 @@
import json import json
from StringIO import StringIO from StringIO import StringIO
import unittest import unittest
from urllib import quote
import zlib import zlib
from swift.common import internal_client from swift.common import internal_client
@ -25,6 +26,31 @@ def not_sleep(seconds):
pass pass
def unicode_string(start, length):
return u''.join([unichr(x) for x in xrange(start, start + length)])
def path_parts():
account = unicode_string(1000, 4) + ' ' + unicode_string(1000, 4)
container = unicode_string(1000, 4) + ' ' + unicode_string(1000, 4)
obj = unicode_string(1000, 4) + ' ' + unicode_string(1000, 4)
return account, container, obj
def make_path(account, container=None, obj=None):
path = '/v1/%s' % quote(account.encode('utf-8'))
if container:
path += '/%s' % quote(container.encode('utf-8'))
if obj:
path += '/%s' % quote(obj.encode('utf-8'))
return path
class InternalClient(internal_client.InternalClient):
def __init__(self):
pass
class GetMetadataInternalClient(internal_client.InternalClient): class GetMetadataInternalClient(internal_client.InternalClient):
def __init__(self, test, path, metadata_prefix, acceptable_statuses): def __init__(self, test, path, metadata_prefix, acceptable_statuses):
self.test = test self.test = test
@ -43,8 +69,8 @@ class GetMetadataInternalClient(internal_client.InternalClient):
class SetMetadataInternalClient(internal_client.InternalClient): class SetMetadataInternalClient(internal_client.InternalClient):
def __init__(self, test, path, metadata, metadata_prefix, def __init__(
acceptable_statuses): self, test, path, metadata, metadata_prefix, acceptable_statuses):
self.test = test self.test = test
self.path = path self.path = path
self.metadata = metadata self.metadata = metadata
@ -53,7 +79,8 @@ class SetMetadataInternalClient(internal_client.InternalClient):
self.set_metadata_called = 0 self.set_metadata_called = 0
self.metadata = 'some_metadata' self.metadata = 'some_metadata'
def _set_metadata(self, path, metadata, metadata_prefix='', def _set_metadata(
self, path, metadata, metadata_prefix='',
acceptable_statuses=None): acceptable_statuses=None):
self.set_metadata_called += 1 self.set_metadata_called += 1
self.test.assertEquals(self.path, path) self.test.assertEquals(self.path, path)
@ -63,8 +90,8 @@ class SetMetadataInternalClient(internal_client.InternalClient):
class IterInternalClient(internal_client.InternalClient): class IterInternalClient(internal_client.InternalClient):
def __init__(self, test, path, marker, end_marker, acceptable_statuses, def __init__(
items): self, test, path, marker, end_marker, acceptable_statuses, items):
self.test = test self.test = test
self.path = path self.path = path
self.marker = marker self.marker = marker
@ -72,8 +99,8 @@ class IterInternalClient(internal_client.InternalClient):
self.acceptable_statuses = acceptable_statuses self.acceptable_statuses = acceptable_statuses
self.items = items self.items = items
def _iter_items(self, path, marker='', end_marker='', def _iter_items(
acceptable_statuses=None): self, path, marker='', end_marker='', acceptable_statuses=None):
self.test.assertEquals(self.path, path) self.test.assertEquals(self.path, path)
self.test.assertEquals(self.marker, marker) self.test.assertEquals(self.marker, marker)
self.test.assertEquals(self.end_marker, end_marker) self.test.assertEquals(self.end_marker, end_marker)
@ -94,8 +121,8 @@ class TestCompressingfileReader(unittest.TestCase):
return self return self
try: try:
compressobj = CompressObj(self, 9, zlib.DEFLATED, -zlib.MAX_WBITS, compressobj = CompressObj(
zlib.DEF_MEM_LEVEL, 0) self, 9, zlib.DEFLATED, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0)
old_compressobj = internal_client.compressobj old_compressobj = internal_client.compressobj
internal_client.compressobj = compressobj.method internal_client.compressobj = compressobj.method
@ -146,8 +173,8 @@ class TestInternalClient(unittest.TestCase):
request_tries = 'some_request_tries' request_tries = 'some_request_tries'
try: try:
client = internal_client.InternalClient(conf_path, user_agent, client = internal_client.InternalClient(
request_tries) conf_path, user_agent, request_tries)
finally: finally:
internal_client.loadapp = old_loadapp internal_client.loadapp = old_loadapp
@ -185,8 +212,8 @@ class TestInternalClient(unittest.TestCase):
def fake_app(self, env, start_response): def fake_app(self, env, start_response):
self.tries += 1 self.tries += 1
if self.tries < self.request_tries: if self.tries < self.request_tries:
start_response('500 Internal Server Error', start_response(
[('Content-Length', '0')]) '500 Internal Server Error', [('Content-Length', '0')])
else: else:
start_response('200 Ok', [('Content-Length', '0')]) start_response('200 Ok', [('Content-Length', '0')])
return [] return []
@ -318,8 +345,8 @@ class TestInternalClient(unittest.TestCase):
try: try:
old_sleep = internal_client.sleep old_sleep = internal_client.sleep
internal_client.sleep = not_sleep internal_client.sleep = not_sleep
self.assertRaises(Exception, self.assertRaises(
client.make_request, 'GET', '/', {}, (2,)) Exception, client.make_request, 'GET', '/', {}, (2,))
finally: finally:
internal_client.sleep = old_sleep internal_client.sleep = old_sleep
@ -335,7 +362,8 @@ class TestInternalClient(unittest.TestCase):
self.resp_headers = resp_headers self.resp_headers = resp_headers
self.make_request_called = 0 self.make_request_called = 0
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
self.test.assertEquals('HEAD', method) self.test.assertEquals('HEAD', method)
@ -364,6 +392,17 @@ class TestInternalClient(unittest.TestCase):
self.assertEquals(exp_metadata, metadata) self.assertEquals(exp_metadata, metadata)
self.assertEquals(1, client.make_request_called) self.assertEquals(1, client.make_request_called)
def test_make_path(self):
account, container, obj = path_parts()
path = make_path(account, container, obj)
c = InternalClient()
self.assertEquals(path, c.make_path(account, container, obj))
def test_make_path_exception(self):
c = InternalClient()
self.assertRaises(ValueError, c.make_path, 'account', None, 'obj')
def test_iter_items(self): def test_iter_items(self):
class Response(object): class Response(object):
def __init__(self, status_int, body): def __init__(self, status_int, body):
@ -376,7 +415,8 @@ class TestInternalClient(unittest.TestCase):
self.responses = responses self.responses = responses
self.make_request_called = 0 self.make_request_called = 0
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
return self.responses.pop(0) return self.responses.pop(0)
@ -392,7 +432,8 @@ class TestInternalClient(unittest.TestCase):
exp_items = [] exp_items = []
responses = [] responses = []
for i in xrange(3): for i in xrange(3):
data = [{'name': 'item%02d' % (2 * i)}, data = [
{'name': 'item%02d' % (2 * i)},
{'name': 'item%02d' % (2 * i + 1)}] {'name': 'item%02d' % (2 * i + 1)}]
responses.append(Response(200, json.dumps(data))) responses.append(Response(200, json.dumps(data)))
exp_items.extend(data) exp_items.extend(data)
@ -416,7 +457,8 @@ class TestInternalClient(unittest.TestCase):
self.paths = paths self.paths = paths
self.responses = responses self.responses = responses
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
exp_path = self.paths.pop(0) exp_path = self.paths.pop(0)
self.test.assertEquals(exp_path, path) self.test.assertEquals(exp_path, path)
@ -449,7 +491,8 @@ class TestInternalClient(unittest.TestCase):
self.exp_headers = exp_headers self.exp_headers = exp_headers
self.make_request_called = 0 self.make_request_called = 0
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
self.test.assertEquals('POST', method) self.test.assertEquals('POST', method)
@ -476,16 +519,17 @@ class TestInternalClient(unittest.TestCase):
self.assertEquals(1, client.make_request_called) self.assertEquals(1, client.make_request_called)
def test_iter_containers(self): def test_iter_containers(self):
account = 'some_account' account, container, obj = path_parts()
path = '/v1/%s' % (account) path = make_path(account)
items = '0 1 2'.split() items = '0 1 2'.split()
marker = 'some_marker' marker = 'some_marker'
end_marker = 'some_end_marker' end_marker = 'some_end_marker'
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
client = IterInternalClient(self, path, marker, end_marker, client = IterInternalClient(
acceptable_statuses, items) self, path, marker, end_marker, acceptable_statuses, items)
ret_items = [] ret_items = []
for container in client.iter_containers(account, marker, end_marker, for container in client.iter_containers(
account, marker, end_marker,
acceptable_statuses=acceptable_statuses): acceptable_statuses=acceptable_statuses):
ret_items.append(container) ret_items.append(container)
self.assertEquals(items, ret_items) self.assertEquals(items, ret_items)
@ -504,7 +548,8 @@ class TestInternalClient(unittest.TestCase):
self.path = path self.path = path
self.resp = resp self.resp = resp
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.test.assertEquals('HEAD', method) self.test.assertEquals('HEAD', method)
self.test.assertEquals(self.path, path) self.test.assertEquals(self.path, path)
@ -513,35 +558,35 @@ class TestInternalClient(unittest.TestCase):
self.test.assertEquals(None, body_file) self.test.assertEquals(None, body_file)
return self.resp return self.resp
account = 'some_account' account, container, obj = path_parts()
path = '/v1/%s' % (account) path = make_path(account)
containers, objects = 10, 100 containers, objects = 10, 100
client = InternalClient(self, path, Response(containers, objects)) client = InternalClient(self, path, Response(containers, objects))
info = client.get_account_info(account) info = client.get_account_info(account)
self.assertEquals((containers, objects), info) self.assertEquals((containers, objects), info)
def test_get_account_metadata(self): def test_get_account_metadata(self):
account = 'some_account' account, container, obj = path_parts()
path = '/v1/%s' % (account) path = make_path(account)
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
metadata_prefix = 'some_metadata_prefix' metadata_prefix = 'some_metadata_prefix'
client = GetMetadataInternalClient(self, path, metadata_prefix, client = GetMetadataInternalClient(
acceptable_statuses) self, path, metadata_prefix, acceptable_statuses)
metadata = client.get_account_metadata(account, metadata_prefix, metadata = client.get_account_metadata(
acceptable_statuses) account, metadata_prefix, acceptable_statuses)
self.assertEquals(client.metadata, metadata) self.assertEquals(client.metadata, metadata)
self.assertEquals(1, client.get_metadata_called) self.assertEquals(1, client.get_metadata_called)
def test_set_account_metadata(self): def test_set_account_metadata(self):
account = 'some_account' account, container, obj = path_parts()
path = '/v1/%s' % (account) path = make_path(account)
metadata = 'some_metadata' metadata = 'some_metadata'
metadata_prefix = 'some_metadata_prefix' metadata_prefix = 'some_metadata_prefix'
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
client = SetMetadataInternalClient(self, path, metadata, client = SetMetadataInternalClient(
metadata_prefix, acceptable_statuses) self, path, metadata, metadata_prefix, acceptable_statuses)
client.set_account_metadata(account, metadata, metadata_prefix, client.set_account_metadata(
acceptable_statuses) account, metadata, metadata_prefix, acceptable_statuses)
self.assertEquals(1, client.set_metadata_called) self.assertEquals(1, client.set_metadata_called)
def test_container_exists(self): def test_container_exists(self):
@ -556,7 +601,8 @@ class TestInternalClient(unittest.TestCase):
self.make_request_called = 0 self.make_request_called = 0
self.resp = resp self.resp = resp
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
self.test.assertEquals('HEAD', method) self.test.assertEquals('HEAD', method)
@ -566,9 +612,8 @@ class TestInternalClient(unittest.TestCase):
self.test.assertEquals(None, body_file) self.test.assertEquals(None, body_file)
return self.resp return self.resp
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container)
path = '/v1/%s/%s' % (account, container)
client = InternalClient(self, path, Response(200)) client = InternalClient(self, path, Response(200))
self.assertEquals(True, client.container_exists(account, container)) self.assertEquals(True, client.container_exists(account, container))
@ -586,7 +631,8 @@ class TestInternalClient(unittest.TestCase):
self.headers = headers self.headers = headers
self.make_request_called = 0 self.make_request_called = 0
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
self.test.assertEquals('PUT', method) self.test.assertEquals('PUT', method)
@ -595,9 +641,8 @@ class TestInternalClient(unittest.TestCase):
self.test.assertEquals((2,), acceptable_statuses) self.test.assertEquals((2,), acceptable_statuses)
self.test.assertEquals(None, body_file) self.test.assertEquals(None, body_file)
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container)
path = '/v1/%s/%s' % (account, container)
headers = 'some_headers' headers = 'some_headers'
client = InternalClient(self, path, headers) client = InternalClient(self, path, headers)
client.create_container(account, container, headers) client.create_container(account, container, headers)
@ -610,7 +655,8 @@ class TestInternalClient(unittest.TestCase):
self.path = path self.path = path
self.make_request_called = 0 self.make_request_called = 0
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
self.test.assertEquals('DELETE', method) self.test.assertEquals('DELETE', method)
@ -619,53 +665,49 @@ class TestInternalClient(unittest.TestCase):
self.test.assertEquals((2, 404), acceptable_statuses) self.test.assertEquals((2, 404), acceptable_statuses)
self.test.assertEquals(None, body_file) self.test.assertEquals(None, body_file)
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container)
path = '/v1/%s/%s' % (account, container)
client = InternalClient(self, path) client = InternalClient(self, path)
client.delete_container(account, container) client.delete_container(account, container)
self.assertEquals(1, client.make_request_called) self.assertEquals(1, client.make_request_called)
def test_get_container_metadata(self): def test_get_container_metadata(self):
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container)
path = '/v1/%s/%s' % (account, container)
metadata_prefix = 'some_metadata_prefix' metadata_prefix = 'some_metadata_prefix'
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
client = GetMetadataInternalClient(self, path, metadata_prefix, client = GetMetadataInternalClient(
acceptable_statuses) self, path, metadata_prefix, acceptable_statuses)
metadata = client.get_container_metadata(account, container, metadata = client.get_container_metadata(
metadata_prefix, acceptable_statuses) account, container, metadata_prefix, acceptable_statuses)
self.assertEquals(client.metadata, metadata) self.assertEquals(client.metadata, metadata)
self.assertEquals(1, client.get_metadata_called) self.assertEquals(1, client.get_metadata_called)
def test_iter_objects(self): def test_iter_objects(self):
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container)
path = '/v1/%s/%s' % (account, container)
marker = 'some_maker' marker = 'some_maker'
end_marker = 'some_end_marker' end_marker = 'some_end_marker'
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
items = '0 1 2'.split() items = '0 1 2'.split()
client = IterInternalClient(self, path, marker, end_marker, client = IterInternalClient(
acceptable_statuses, items) self, path, marker, end_marker, acceptable_statuses, items)
ret_items = [] ret_items = []
for obj in client.iter_objects(account, container, marker, end_marker, for obj in client.iter_objects(
acceptable_statuses): account, container, marker, end_marker, acceptable_statuses):
ret_items.append(obj) ret_items.append(obj)
self.assertEquals(items, ret_items) self.assertEquals(items, ret_items)
def test_set_container_metadata(self): def test_set_container_metadata(self):
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container)
path = '/v1/%s/%s' % (account, container)
metadata = 'some_metadata' metadata = 'some_metadata'
metadata_prefix = 'some_metadata_prefix' metadata_prefix = 'some_metadata_prefix'
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
client = SetMetadataInternalClient(self, path, metadata, client = SetMetadataInternalClient(
metadata_prefix, acceptable_statuses) self, path, metadata, metadata_prefix, acceptable_statuses)
client.set_container_metadata(account, container, metadata, client.set_container_metadata(
metadata_prefix, acceptable_statuses) account, container, metadata, metadata_prefix, acceptable_statuses)
self.assertEquals(1, client.set_metadata_called) self.assertEquals(1, client.set_metadata_called)
def test_delete_object(self): def test_delete_object(self):
@ -675,7 +717,8 @@ class TestInternalClient(unittest.TestCase):
self.path = path self.path = path
self.make_request_called = 0 self.make_request_called = 0
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
self.test.assertEquals('DELETE', method) self.test.assertEquals('DELETE', method)
@ -684,26 +727,23 @@ class TestInternalClient(unittest.TestCase):
self.test.assertEquals((2, 404), acceptable_statuses) self.test.assertEquals((2, 404), acceptable_statuses)
self.test.assertEquals(None, body_file) self.test.assertEquals(None, body_file)
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container, obj)
object_name = 'some_object'
path = '/v1/%s/%s/%s' % (account, container, object_name)
client = InternalClient(self, path) client = InternalClient(self, path)
client.delete_object(account, container, object_name) client.delete_object(account, container, obj)
self.assertEquals(1, client.make_request_called) self.assertEquals(1, client.make_request_called)
def test_get_object_metadata(self): def test_get_object_metadata(self):
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container, obj)
object_name = 'some_object'
path = '/v1/%s/%s/%s' % (account, container, object_name)
metadata_prefix = 'some_metadata_prefix' metadata_prefix = 'some_metadata_prefix'
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
client = GetMetadataInternalClient(self, path, metadata_prefix, client = GetMetadataInternalClient(
self, path, metadata_prefix, acceptable_statuses)
metadata = client.get_object_metadata(
account, container, obj, metadata_prefix,
acceptable_statuses) acceptable_statuses)
metadata = client.get_object_metadata(account, container, object_name,
metadata_prefix, acceptable_statuses)
self.assertEquals(client.metadata, metadata) self.assertEquals(client.metadata, metadata)
self.assertEquals(1, client.get_metadata_called) self.assertEquals(1, client.get_metadata_called)
@ -742,23 +782,22 @@ class TestInternalClient(unittest.TestCase):
lines = 'line1 line2 line3'.split() lines = 'line1 line2 line3'.split()
client = InternalClient(lines) client = InternalClient(lines)
ret_lines = [] ret_lines = []
for line in client.iter_object_lines('account', 'container', for line in client.iter_object_lines(
'object.gz'): 'account', 'container', 'object.gz'):
ret_lines.append(line) ret_lines.append(line)
self.assertEquals(lines, ret_lines) self.assertEquals(lines, ret_lines)
def test_set_object_metadata(self): def test_set_object_metadata(self):
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container, obj)
object_name = 'some_object'
path = '/v1/%s/%s/%s' % (account, container, object_name)
metadata = 'some_metadata' metadata = 'some_metadata'
metadata_prefix = 'some_metadata_prefix' metadata_prefix = 'some_metadata_prefix'
acceptable_statuses = 'some_status_list' acceptable_statuses = 'some_status_list'
client = SetMetadataInternalClient(self, path, metadata, client = SetMetadataInternalClient(
metadata_prefix, acceptable_statuses) self, path, metadata, metadata_prefix, acceptable_statuses)
client.set_object_metadata(account, container, object_name, metadata, client.set_object_metadata(
metadata_prefix, acceptable_statuses) account, container, obj, metadata, metadata_prefix,
acceptable_statuses)
self.assertEquals(1, client.set_metadata_called) self.assertEquals(1, client.set_metadata_called)
def test_upload_object(self): def test_upload_object(self):
@ -770,7 +809,8 @@ class TestInternalClient(unittest.TestCase):
self.fobj = fobj self.fobj = fobj
self.make_request_called = 0 self.make_request_called = 0
def make_request(self, method, path, headers, acceptable_statuses, def make_request(
self, method, path, headers, acceptable_statuses,
body_file=None): body_file=None):
self.make_request_called += 1 self.make_request_called += 1
self.test.assertEquals(self.path, path) self.test.assertEquals(self.path, path)
@ -780,14 +820,12 @@ class TestInternalClient(unittest.TestCase):
self.test.assertEquals(self.fobj, fobj) self.test.assertEquals(self.fobj, fobj)
fobj = 'some_fobj' fobj = 'some_fobj'
account = 'some_account' account, container, obj = path_parts()
container = 'some_container' path = make_path(account, container, obj)
object_name = 'some_object'
path = '/v1/%s/%s/%s' % (account, container, object_name)
headers = {'key': 'value'} headers = {'key': 'value'}
client = InternalClient(self, path, headers, fobj) client = InternalClient(self, path, headers, fobj)
client.upload_object(fobj, account, container, object_name, headers) client.upload_object(fobj, account, container, obj, headers)
self.assertEquals(1, client.make_request_called) self.assertEquals(1, client.make_request_called)
if __name__ == '__main__': if __name__ == '__main__':