diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | setup.cfg | 1 | ||||
-rw-r--r-- | swiftclient/service.py | 2 | ||||
-rwxr-xr-x | swiftclient/shell.py | 56 | ||||
-rw-r--r-- | tests/unit/test_service.py | 16 | ||||
-rw-r--r-- | tests/unit/test_shell.py | 2 | ||||
-rw-r--r-- | tox.ini | 6 |
7 files changed, 73 insertions, 15 deletions
@@ -1,8 +1,7 @@ -2.8.0 +3.0.0 ----- -* Python 2.6 support has been removed. Also, Python 3.3 gate testing has - been removed. Support for Python 3.3 is only best-effort. Currently +* Python 2.6 and Python 3.3 support has been removed. Currently supported and tested versions of Python are Python 2.7 and Python 3.4. * Do not reveal sensitive headers in swiftclient log messages by default. @@ -17,7 +17,6 @@ classifier = Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 - Programming Language :: Python :: 3.3 Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 diff --git a/swiftclient/service.py b/swiftclient/service.py index 5fa2870..f253ec8 100644 --- a/swiftclient/service.py +++ b/swiftclient/service.py @@ -1004,7 +1004,7 @@ class SwiftService(object): raise raise SwiftError('Account not found', exc=err) - elif not objects: + elif objects is None: if '/' in container: raise SwiftError('\'/\' in container name', container=container) diff --git a/swiftclient/shell.py b/swiftclient/shell.py index 68b9344..4ba71b4 100755 --- a/swiftclient/shell.py +++ b/swiftclient/shell.py @@ -94,11 +94,11 @@ def st_delete(parser, args, output_manager): parser.add_option( '', '--object-threads', type=int, default=10, help='Number of threads to use for deleting objects. ' - 'Default is 10.') + 'Its value must be a positive integer. Default is 10.') parser.add_option( '', '--container-threads', type=int, default=10, help='Number of threads to use for deleting containers. ' - 'Default is 10.') + 'Its value must be a positive integer. Default is 10.') (options, args) = parse_args(parser, args) args = args[1:] if (not args and not options.yes_all) or (args and options.yes_all): @@ -107,6 +107,22 @@ def st_delete(parser, args, output_manager): st_delete_help) return + if options.object_threads <= 0: + output_manager.error( + 'ERROR: option --object-threads should be a positive integer.' + '\n\nUsage: %s delete %s\n%s', + BASENAME, st_delete_options, + st_delete_help) + return + + if options.container_threads <= 0: + output_manager.error( + 'ERROR: option --container-threads should be a positive integer.' + '\n\nUsage: %s delete %s\n%s', + BASENAME, st_delete_options, + st_delete_help) + return + _opts = vars(options) _opts['object_dd_threads'] = options.object_threads with SwiftService(options=_opts) as swift: @@ -274,11 +290,11 @@ def st_download(parser, args, output_manager): parser.add_option( '', '--object-threads', type=int, default=10, help='Number of threads to use for downloading objects. ' - 'Default is 10.') + 'Its value must be a positive integer. Default is 10.') parser.add_option( '', '--container-threads', type=int, default=10, help='Number of threads to use for downloading containers. ' - 'Default is 10.') + 'Its value must be a positive integer. Default is 10.') parser.add_option( '', '--no-download', action='store_true', default=False, @@ -320,6 +336,20 @@ def st_download(parser, args, output_manager): st_download_options, st_download_help) return + if options.object_threads <= 0: + output_manager.error( + 'ERROR: option --object-threads should be a positive integer.\n\n' + 'Usage: %s download %s\n%s', BASENAME, + st_download_options, st_download_help) + return + + if options.container_threads <= 0: + output_manager.error( + 'ERROR: option --container-threads should be a positive integer.' + '\n\nUsage: %s download %s\n%s', BASENAME, + st_download_options, st_download_help) + return + _opts = vars(options) _opts['object_dd_threads'] = options.object_threads with SwiftService(options=_opts) as swift: @@ -805,11 +835,11 @@ def st_upload(parser, args, output_manager): parser.add_option( '', '--object-threads', type=int, default=10, help='Number of threads to use for uploading full objects. ' - 'Default is 10.') + 'Its value must be a positive integer. Default is 10.') parser.add_option( '', '--segment-threads', type=int, default=10, help='Number of threads to use for uploading object segments. ' - 'Default is 10.') + 'Its value must be a positive integer. Default is 10.') parser.add_option( '-H', '--header', action='append', dest='header', default=[], help='Set request headers with the syntax header:value. ' @@ -862,6 +892,20 @@ def st_upload(parser, args, output_manager): output_manager.error("segment-size should be positive") return + if options.object_threads <= 0: + output_manager.error( + 'ERROR: option --object-threads should be a positive integer.' + '\n\nUsage: %s upload %s\n%s', BASENAME, st_upload_options, + st_upload_help) + return + + if options.segment_threads <= 0: + output_manager.error( + 'ERROR: option --segment-threads should be a positive integer.' + '\n\nUsage: %s upload %s\n%s', BASENAME, st_upload_options, + st_upload_help) + return + _opts = vars(options) _opts['object_uu_threads'] = options.object_threads with SwiftService(options=_opts) as swift: diff --git a/tests/unit/test_service.py b/tests/unit/test_service.py index 997d992..418ee85 100644 --- a/tests/unit/test_service.py +++ b/tests/unit/test_service.py @@ -1672,6 +1672,22 @@ class TestServiceDownload(_TestServiceBase): self.assertEqual(resp['object'], 'test') self.assertEqual(resp['path'], 'test') + @mock.patch('swiftclient.service.interruptable_as_completed') + @mock.patch('swiftclient.service.SwiftService._download_container') + @mock.patch('swiftclient.service.SwiftService._download_object_job') + def test_download_with_objects_empty(self, mock_down_obj, + mock_down_cont, mock_as_comp): + fake_future = Future() + fake_future.set_result(1) + mock_as_comp.return_value = [fake_future] + service = SwiftService() + next(service.download('c', [], self.opts), None) + mock_down_obj.assert_not_called() + mock_down_cont.assert_not_called() + + next(service.download('c', options=self.opts), None) + self.assertEqual(True, mock_down_cont.called) + def test_download_with_output_dir(self): service = SwiftService() with mock.patch('swiftclient.service.Connection') as mock_conn: diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py index 3ea9336..36c1593 100644 --- a/tests/unit/test_shell.py +++ b/tests/unit/test_shell.py @@ -688,10 +688,10 @@ class TestShell(unittest.TestCase): [None, []] ] connection.return_value.put_object.return_value = EMPTY_ETAG - swiftclient.shell.main(argv) # create the delete_object child mock here in attempt to fix # https://bugs.launchpad.net/python-swiftclient/+bug/1480223 connection.return_value.delete_object.return_value = None + swiftclient.shell.main(argv) connection.return_value.put_object.assert_called_with( 'container', self.tmpfile.lstrip('/'), @@ -1,5 +1,5 @@ [tox] -envlist = py27,py33,py34,py35,pypy,pep8 +envlist = py27,py34,py35,pypy,pep8 minversion = 1.6 skipsdist = True @@ -12,9 +12,9 @@ setenv = deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt -commands = sh -c 'find . -not \( -type d -name .?\* -prune \) \ +commands = sh -c '(find . -not \( -type d -name .?\* -prune \) \ \( -type d -name "__pycache__" -or -type f -name "*.py[co]" \) \ - -print0 | xargs -0 rm -rf' + -print0; find . -name "*.dbm*" -print0) | xargs -0 rm -rf' python setup.py testr --testr-args="{posargs}" whitelist_externals = sh passenv = SWIFT_* *_proxy |