summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-11-13 03:30:01 +0000
committerGerrit Code Review <review@openstack.org>2014-11-13 03:30:01 +0000
commit202bbab2d06b9ef751fba306effd09f3bae8f383 (patch)
tree50a64b15194fe95b82d3c9b6e262bfcc40cd74a7
parentf99e71da0fa80b2110887a9694512c2fcaddc191 (diff)
parent95056d1ef49730d98eda1fc246b7e4bb1070a311 (diff)
downloadpython-swiftclient-202bbab2d06b9ef751fba306effd09f3bae8f383.tar.gz
Merge "Make swift post output an error message when failing"
-rw-r--r--swiftclient/service.py131
-rwxr-xr-xswiftclient/shell.py14
-rw-r--r--tests/unit/test_shell.py67
3 files changed, 134 insertions, 78 deletions
diff --git a/swiftclient/service.py b/swiftclient/service.py
index 281947e..1b591d3 100644
--- a/swiftclient/service.py
+++ b/swiftclient/service.py
@@ -594,44 +594,31 @@ class SwiftService(object):
'error': err,
'response_dict': response_dict
})
- return res
- else:
- if not objects:
- res["action"] = "post_container"
- response_dict = {}
- headers = split_headers(
- options['meta'], 'X-Container-Meta-')
- headers.update(
- split_headers(options['header'], ''))
- if options['read_acl'] is not None:
- headers['X-Container-Read'] = options['read_acl']
- if options['write_acl'] is not None:
- headers['X-Container-Write'] = options['write_acl']
- if options['sync_to'] is not None:
- headers['X-Container-Sync-To'] = options['sync_to']
- if options['sync_key'] is not None:
- headers['X-Container-Sync-Key'] = options['sync_key']
- res['headers'] = headers
- try:
- post = self.thread_manager.container_pool.submit(
- self._post_container_job, container,
- headers, response_dict
- )
- get_future_result(post)
- except ClientException as err:
- if err.http_status != 404:
- res.update({
- 'action': 'post_container',
- 'success': False,
- 'error': err,
- 'response_dict': response_dict
- })
- return res
- raise SwiftError(
- "Container '%s' not found" % container,
- container=container
- )
- except Exception as err:
+ return res
+ if not objects:
+ res["action"] = "post_container"
+ response_dict = {}
+ headers = split_headers(
+ options['meta'], 'X-Container-Meta-')
+ headers.update(
+ split_headers(options['header'], ''))
+ if options['read_acl'] is not None:
+ headers['X-Container-Read'] = options['read_acl']
+ if options['write_acl'] is not None:
+ headers['X-Container-Write'] = options['write_acl']
+ if options['sync_to'] is not None:
+ headers['X-Container-Sync-To'] = options['sync_to']
+ if options['sync_key'] is not None:
+ headers['X-Container-Sync-Key'] = options['sync_key']
+ res['headers'] = headers
+ try:
+ post = self.thread_manager.container_pool.submit(
+ self._post_container_job, container,
+ headers, response_dict
+ )
+ get_future_result(post)
+ except ClientException as err:
+ if err.http_status != 404:
res.update({
'action': 'post_container',
'success': False,
@@ -639,37 +626,49 @@ class SwiftService(object):
'response_dict': response_dict
})
return res
- else:
- post_futures = []
- post_objects = self._make_post_objects(objects)
- for post_object in post_objects:
- obj = post_object.object_name
- obj_options = post_object.options
- response_dict = {}
- headers = split_headers(
- options['meta'], 'X-Object-Meta-')
- # add header options to the headers object for the request.
- headers.update(
- split_headers(options['header'], ''))
- if obj_options is not None:
- if 'meta' in obj_options:
- headers.update(
- split_headers(
- obj_options['meta'], 'X-Object-Meta'
- )
- )
- if 'headers' in obj_options:
- headers.update(
- split_headers(obj_options['header'], '')
+ raise SwiftError(
+ "Container '%s' not found" % container,
+ container=container
+ )
+ except Exception as err:
+ res.update({
+ 'action': 'post_container',
+ 'success': False,
+ 'error': err,
+ 'response_dict': response_dict
+ })
+ return res
+ else:
+ post_futures = []
+ post_objects = self._make_post_objects(objects)
+ for post_object in post_objects:
+ obj = post_object.object_name
+ obj_options = post_object.options
+ response_dict = {}
+ headers = split_headers(
+ options['meta'], 'X-Object-Meta-')
+ # add header options to the headers object for the request.
+ headers.update(
+ split_headers(options['header'], ''))
+ if obj_options is not None:
+ if 'meta' in obj_options:
+ headers.update(
+ split_headers(
+ obj_options['meta'], 'X-Object-Meta'
)
+ )
+ if 'headers' in obj_options:
+ headers.update(
+ split_headers(obj_options['header'], '')
+ )
- post = self.thread_manager.object_uu_pool.submit(
- self._post_object_job, container, obj,
- headers, response_dict
- )
- post_futures.append(post)
+ post = self.thread_manager.object_uu_pool.submit(
+ self._post_object_job, container, obj,
+ headers, response_dict
+ )
+ post_futures.append(post)
- return ResultsIterator(post_futures)
+ return ResultsIterator(post_futures)
@staticmethod
def _make_post_objects(objects):
diff --git a/swiftclient/shell.py b/swiftclient/shell.py
index 015c9d9..2c627ad 100755
--- a/swiftclient/shell.py
+++ b/swiftclient/shell.py
@@ -547,8 +547,7 @@ If the container is not found, it will be created automatically.
Positional arguments:
[container] Name of container to post to.
- [object] Name of object to post. Specify multiple times
- for multiple objects.
+ [object] Name of object to post.
Optional arguments:
--read-acl <acl> Read ACL for containers. Quick summary of ACL syntax:
@@ -600,7 +599,7 @@ def st_post(parser, args, output_manager):
with SwiftService(options=_opts) as swift:
try:
if not args:
- swift.post()
+ result = swift.post()
else:
container = args[0]
if '/' in container:
@@ -616,15 +615,16 @@ def st_post(parser, args, output_manager):
results_iterator = swift.post(
container=container, objects=objects
)
- for result in results_iterator: # only 1 result
- if not result["success"]:
- raise(result["error"])
+ result = next(results_iterator)
else:
output_manager.error(
'Usage: %s post %s\n%s', BASENAME,
st_post_options, st_post_help)
+ return
else:
- swift.post(container=container)
+ result = swift.post(container=container)
+ if not result["success"]:
+ raise(result["error"])
except SwiftError as e:
output_manager.error(e.value)
diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py
index 29d7472..bdba193 100644
--- a/tests/unit/test_shell.py
+++ b/tests/unit/test_shell.py
@@ -390,26 +390,68 @@ class TestShell(unittest.TestCase):
@mock.patch('swiftclient.service.Connection')
def test_post_account(self, connection):
argv = ["", "post"]
- connection.return_value.head_object.return_value = {}
swiftclient.shell.main(argv)
connection.return_value.post_account.assert_called_with(
headers={}, response_dict={})
+ @mock.patch('swiftclient.shell.OutputManager.error')
+ @mock.patch('swiftclient.service.Connection')
+ def test_post_account_bad_auth(self, connection, error):
+ argv = ["", "post"]
+ connection.return_value.post_account.side_effect = \
+ swiftclient.ClientException('bad auth')
+ swiftclient.shell.main(argv)
+ error.assert_called_with('bad auth')
+
+ @mock.patch('swiftclient.shell.OutputManager.error')
+ @mock.patch('swiftclient.service.Connection')
+ def test_post_account_not_found(self, connection, error):
+ argv = ["", "post"]
+ connection.return_value.post_account.side_effect = \
+ swiftclient.ClientException('test', http_status=404)
+ swiftclient.shell.main(argv)
+ error.assert_called_with('Account not found')
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_post_container(self, connection):
argv = ["", "post", "container"]
- connection.return_value.head_object.return_value = {}
swiftclient.shell.main(argv)
connection.return_value.post_container.assert_called_with(
'container', headers={}, response_dict={})
+ @mock.patch('swiftclient.shell.OutputManager.error')
@mock.patch('swiftclient.service.Connection')
- def test_post_container(self, connection):
+ def test_post_container_bad_auth(self, connection, error):
+ argv = ["", "post", "container"]
+ connection.return_value.post_container.side_effect = \
+ swiftclient.ClientException('bad auth')
+ swiftclient.shell.main(argv)
+ error.assert_called_with('bad auth')
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_post_container_not_found_causes_put(self, connection):
+ argv = ["", "post", "container"]
+ connection.return_value.post_container.side_effect = \
+ swiftclient.ClientException('test', http_status=404)
+ swiftclient.shell.main(argv)
+ self.assertEqual('container',
+ connection.return_value.put_container.call_args[0][0])
+
+ @mock.patch('swiftclient.shell.OutputManager.error')
+ def test_post_container_with_bad_name(self, error):
+ argv = ["", "post", "conta/iner"]
+ swiftclient.shell.main(argv)
+ self.assertTrue(error.called)
+ self.assertTrue(error.call_args[0][0].startswith('WARNING: / in'))
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_post_container_with_options(self, connection):
argv = ["", "post", "container",
"--read-acl", "test2:tester2",
"--write-acl", "test3:tester3 test4",
"--sync-to", "othersite",
"--sync-key", "secret",
]
- connection.return_value.head_object.return_value = {}
swiftclient.shell.main(argv)
connection.return_value.post_container.assert_called_with(
'container', headers={
@@ -424,13 +466,28 @@ class TestShell(unittest.TestCase):
"--meta", "Color:Blue",
"--header", "content-type:text/plain"
]
- connection.return_value.head_object.return_value = {}
swiftclient.shell.main(argv)
connection.return_value.post_object.assert_called_with(
'container', 'object', headers={
'Content-Type': 'text/plain',
'X-Object-Meta-Color': 'Blue'}, response_dict={})
+ @mock.patch('swiftclient.shell.OutputManager.error')
+ @mock.patch('swiftclient.service.Connection')
+ def test_post_object_bad_auth(self, connection, error):
+ argv = ["", "post", "container", "object"]
+ connection.return_value.post_object.side_effect = \
+ swiftclient.ClientException("bad auth")
+ swiftclient.shell.main(argv)
+ error.assert_called_with('bad auth')
+
+ @mock.patch('swiftclient.shell.OutputManager.error')
+ def test_post_object_too_many_args(self, error):
+ argv = ["", "post", "container", "object", "bad_arg"]
+ swiftclient.shell.main(argv)
+ self.assertTrue(error.called)
+ self.assertTrue(error.call_args[0][0].startswith('Usage'))
+
@mock.patch('swiftclient.shell.generate_temp_url')
def test_temp_url(self, temp_url):
argv = ["", "tempurl", "GET", "60", "/v1/AUTH_account/c/o",