summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorClay Gerrard <clay.gerrard@gmail.com>2019-10-29 09:59:03 -0500
committerTim Burke <tim.burke@gmail.com>2020-04-08 13:07:26 -0700
commit78edffa46c591fdc53f253b343e1ea144e24089d (patch)
tree21205561c27782986e87d60ed1e12176b46d7129 /test
parent02e8f4f228c006927fe87f8a350c281b9cfccd98 (diff)
downloadpython-swiftclient-78edffa46c591fdc53f253b343e1ea144e24089d.tar.gz
object versioning features
* add --versions to list * add --versions to delete * add --version-id to stat * add --version-id to delete * add --version-id to download Change-Id: I89802064921778fee7efe57c7d60c976cdde3a27
Diffstat (limited to 'test')
-rw-r--r--test/unit/test_service.py259
-rw-r--r--test/unit/test_shell.py220
2 files changed, 448 insertions, 31 deletions
diff --git a/test/unit/test_service.py b/test/unit/test_service.py
index ed3a2d6..e86a4ff 100644
--- a/test/unit/test_service.py
+++ b/test/unit/test_service.py
@@ -21,6 +21,7 @@ import six
import tempfile
import unittest
import time
+import json
from concurrent.futures import Future
from hashlib import md5
@@ -33,7 +34,7 @@ import swiftclient
import swiftclient.utils as utils
from swiftclient.client import Connection, ClientException
from swiftclient.service import (
- SwiftService, SwiftError, SwiftUploadObject
+ SwiftService, SwiftError, SwiftUploadObject, SwiftDeleteObject
)
from test.unit import utils as test_utils
@@ -315,11 +316,39 @@ class TestServiceDelete(_TestServiceBase):
mock_conn.head_object.assert_called_once_with(
'test_c', 'test_o', query_string='symlink=get', headers={})
mock_conn.delete_object.assert_called_once_with(
- 'test_c', 'test_o', query_string=None, response_dict={},
+ 'test_c', 'test_o', query_string='', response_dict={},
headers={}
)
self.assertEqual(expected_r, r)
+ @mock.patch('swiftclient.service.Connection')
+ def test_delete_object_version(self, mock_connection_class):
+ mock_conn = mock_connection_class.return_value
+ mock_conn.url = 'http://saio/v1/AUTH_test'
+ mock_conn.attempts = 0
+ mock_conn.head_object.return_value = {}
+ mock_conn.delete_object.return_value = {}
+ expected = {
+ 'action': 'delete_object',
+ 'attempts': 0,
+ 'container': 'c',
+ 'object': 'o',
+ 'response_dict': {},
+ 'success': True}
+ with SwiftService() as swift:
+ delete_results = swift.delete(
+ container='c', objects='o', options={
+ 'version_id': '234567.8'})
+ for delete_result in delete_results:
+ self.assertEqual(delete_result, expected)
+ self.assertEqual(mock_conn.mock_calls, [
+ mock.call.head_object('c', 'o', headers={},
+ query_string='symlink=get'),
+ mock.call.delete_object('c', 'o', headers={},
+ query_string='version-id=234567.8',
+ response_dict={}),
+ ])
+
def test_delete_object_with_headers(self):
mock_q = Queue()
mock_conn = self._get_mock_connection()
@@ -338,7 +367,7 @@ class TestServiceDelete(_TestServiceBase):
'test_c', 'test_o', headers={'Skip-Middleware': 'Test'},
query_string='symlink=get')
mock_conn.delete_object.assert_called_once_with(
- 'test_c', 'test_o', query_string=None, response_dict={},
+ 'test_c', 'test_o', query_string='', response_dict={},
headers={'Skip-Middleware': 'Test'}
)
self.assertEqual(expected_r, r)
@@ -366,7 +395,7 @@ class TestServiceDelete(_TestServiceBase):
mock_conn.head_object.assert_called_once_with(
'test_c', 'test_o', query_string='symlink=get', headers={})
mock_conn.delete_object.assert_called_once_with(
- 'test_c', 'test_o', query_string=None, response_dict={},
+ 'test_c', 'test_o', query_string='', response_dict={},
headers={}
)
self.assertEqual(expected_r, r)
@@ -431,7 +460,7 @@ class TestServiceDelete(_TestServiceBase):
self.assertEqual(expected_r, r)
expected = [
- mock.call('test_c', 'test_o', query_string=None, response_dict={},
+ mock.call('test_c', 'test_o', query_string='', response_dict={},
headers={}),
mock.call('manifest_c', 'test_seg_1', response_dict={}),
mock.call('manifest_c', 'test_seg_2', response_dict={})]
@@ -529,6 +558,63 @@ class TestServiceDelete(_TestServiceBase):
if errors:
self.fail('_bulk_delete_page_size() failed\n' + '\n'.join(errors))
+ @mock.patch('swiftclient.service.Connection')
+ def test_bulk_delete(self, mock_connection_class):
+ mock_conn = mock_connection_class.return_value
+ mock_conn.attempts = 0
+ mock_conn.get_capabilities.return_value = {
+ 'bulk_delete': {}}
+ stub_headers = {}
+ stub_resp = []
+ mock_conn.post_account.return_value = (
+ stub_headers, json.dumps(stub_resp).encode('utf8'))
+ obj_list = ['x%02d' % i for i in range(100)]
+ expected = [{
+ 'action': u'bulk_delete',
+ 'attempts': 0,
+ 'container': 'c',
+ 'objects': list(objs),
+ 'response_dict': {},
+ 'result': [],
+ 'success': True,
+ } for objs in zip(*[iter(obj_list)] * 10)]
+ found_result = []
+ with SwiftService(options={'object_dd_threads': 10}) as swift:
+ delete_results = swift.delete(container='c', objects=obj_list)
+ for delete_result in delete_results:
+ found_result.append(delete_result)
+ self.assertEqual(sorted(found_result, key=lambda r: r['objects'][0]),
+ expected)
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_bulk_delete_versions(self, mock_connection_class):
+ mock_conn = mock_connection_class.return_value
+ mock_conn.attempts = 0
+ mock_conn.get_capabilities.return_value = {
+ 'bulk_delete': {}}
+ mock_conn.head_object.return_value = {}
+ stub_headers = {}
+ stub_resp = []
+ mock_conn.post_account.return_value = (
+ stub_headers, json.dumps(stub_resp))
+ obj_list = [SwiftDeleteObject('x%02d' % i, options={'version_id': i})
+ for i in range(100)]
+ expected = [{
+ 'action': u'delete_object',
+ 'attempts': 0,
+ 'container': 'c',
+ 'object': obj.object_name,
+ 'response_dict': {},
+ 'success': True,
+ } for obj in obj_list]
+ found_result = []
+ with SwiftService(options={'object_dd_threads': 10}) as swift:
+ delete_results = swift.delete(container='c', objects=obj_list)
+ for delete_result in delete_results:
+ found_result.append(delete_result)
+ self.assertEqual(sorted(found_result, key=lambda r: r['object']),
+ expected)
+
class TestSwiftError(unittest.TestCase):
@@ -938,9 +1024,11 @@ class TestServiceList(_TestServiceBase):
self.assertIsNone(self._get_queue(mock_q))
self.assertEqual(mock_conn.get_container.mock_calls, [
mock.call('test_c', headers={'Skip-Middleware': 'Test'},
- delimiter='', marker='', prefix=None),
+ delimiter='', marker='', prefix=None,
+ query_string=None, version_marker=''),
mock.call('test_c', headers={'Skip-Middleware': 'Test'},
- delimiter='', marker='test_o', prefix=None)])
+ delimiter='', marker='test_o', prefix=None,
+ query_string=None, version_marker='')])
def test_list_container_exception(self):
mock_q = Queue()
@@ -952,6 +1040,7 @@ class TestServiceList(_TestServiceBase):
'success': False,
'error': self.exc,
'marker': '',
+ 'version_marker': '',
'error_timestamp': mock.ANY,
'traceback': mock.ANY
})
@@ -961,11 +1050,61 @@ class TestServiceList(_TestServiceBase):
)
mock_conn.get_container.assert_called_once_with(
- 'test_c', marker='', delimiter='', prefix=None, headers={}
+ 'test_c', marker='', delimiter='', prefix=None, headers={},
+ query_string=None, version_marker='',
)
self.assertEqual(expected_r, self._get_queue(mock_q))
self.assertIsNone(self._get_queue(mock_q))
+ @mock.patch('swiftclient.service.Connection')
+ def test_list_container_versions(self, mock_connection_class):
+ mock_conn = mock_connection_class.return_value
+ mock_conn.url = 'http://saio/v1/AUTH_test'
+ resp_headers = {}
+ items = [{
+ "bytes": 9,
+ "content_type": "application/octet-stream",
+ "hash": "e55cedc11adb39c404b7365f7d6291fa",
+ "is_latest": True,
+ "last_modified": "2019-11-08T05:00:15.115360",
+ "name": "test",
+ "version_id": "1573189215.11536"
+ }, {
+ "bytes": 8,
+ "content_type": "application/octet-stream",
+ "hash": "70c1db56f301c9e337b0099bd4174b28",
+ "is_latest": False,
+ "last_modified": "2019-11-08T05:00:14.730240",
+ "name": "test",
+ "version_id": "1573184903.06720"
+ }]
+ mock_conn.get_container.side_effect = [
+ (resp_headers, items),
+ (resp_headers, []),
+ ]
+ expected = {
+ 'action': 'list_container_part',
+ 'container': 'c',
+ 'listing': items,
+ 'marker': '',
+ 'prefix': None,
+ 'success': True,
+ }
+ with SwiftService() as swift:
+ list_result_gen = swift.list(container='c', options={
+ 'versions': True})
+ self.maxDiff = None
+ for result in list_result_gen:
+ self.assertEqual(result, expected)
+ self.assertEqual(mock_conn.get_container.mock_calls, [
+ mock.call('c', delimiter=None, headers={}, marker='',
+ prefix=None, query_string='versions=true',
+ version_marker=''),
+ mock.call('c', delimiter=None, headers={}, marker='test',
+ prefix=None, query_string='versions=true',
+ version_marker='1573184903.06720'),
+ ])
+
@mock.patch('swiftclient.service.get_conn')
def test_list_queue_size(self, mock_get_conn):
mock_conn = self._get_mock_connection()
@@ -1042,6 +1181,67 @@ class TestServiceList(_TestServiceBase):
self.assertEqual(observed_listing, expected_listing)
+class TestServiceStat(_TestServiceBase):
+
+ maxDiff = None
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_stat_object(self, mock_connection_class):
+ mock_conn = mock_connection_class.return_value
+ mock_conn.url = 'http://saio/v1/AUTH_test'
+ mock_conn.head_object.return_value = {}
+ expected = {
+ 'action': 'stat_object',
+ 'container': 'c',
+ 'object': 'o',
+ 'headers': {},
+ 'items': [('Account', 'AUTH_test'),
+ ('Container', 'c'),
+ ('Object', 'o'),
+ ('Content Type', None),
+ ('Content Length', '0'),
+ ('Last Modified', None),
+ ('ETag', None),
+ ('Manifest', None)],
+ 'success': True}
+ with SwiftService() as swift:
+ stat_results = swift.stat(container='c', objects='o')
+ for stat_result in stat_results:
+ self.assertEqual(stat_result, expected)
+ self.assertEqual(mock_conn.head_object.mock_calls, [
+ mock.call('c', 'o', headers={}, query_string=None),
+ ])
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_stat_versioned_object(self, mock_connection_class):
+ mock_conn = mock_connection_class.return_value
+ mock_conn.url = 'http://saio/v1/AUTH_test'
+ mock_conn.head_object.return_value = {}
+ expected = {
+ 'action': 'stat_object',
+ 'container': 'c',
+ 'object': 'o',
+ 'headers': {},
+ 'items': [('Account', 'AUTH_test'),
+ ('Container', 'c'),
+ ('Object', 'o'),
+ ('Content Type', None),
+ ('Content Length', '0'),
+ ('Last Modified', None),
+ ('ETag', None),
+ ('Manifest', None)],
+ 'success': True}
+ with SwiftService() as swift:
+ stat_results = swift.stat(container='c', objects='o', options={
+ 'version_id': '234567.8'})
+ for stat_result in stat_results:
+ self.assertEqual(stat_result, expected)
+ self.assertEqual(mock_conn.head_object.mock_calls, [
+ mock.call('c', 'o', headers={},
+ query_string='version-id=234567.8'),
+ ])
+
+
class TestService(unittest.TestCase):
def test_upload_with_bad_segment_size(self):
@@ -1791,13 +1991,14 @@ class TestServiceUpload(_TestServiceBase):
mock_conn.head_object.assert_called_with('test_c', 'test_o')
expected = [
mock.call('test_c_segments', prefix='test_o/prefix',
- marker='', delimiter=None, headers={}),
+ marker='', delimiter=None, headers={},
+ query_string=None, version_marker=''),
mock.call('test_c_segments', prefix='test_o/prefix',
marker="test_o/prefix/01", delimiter=None,
- headers={}),
+ headers={}, query_string=None, version_marker=''),
mock.call('test_c_segments', prefix='test_o/prefix',
marker="test_o/prefix/02", delimiter=None,
- headers={}),
+ headers={}, query_string=None, version_marker=''),
]
mock_conn.get_container.assert_has_calls(expected)
@@ -2332,6 +2533,29 @@ class TestServiceDownload(_TestServiceBase):
self.assertEqual(resp['object'], 'test')
self.assertEqual(resp['path'], 'test')
+ def test_download_version_id(self):
+ self.opts['version_id'] = '23456.7'
+ with mock.patch('swiftclient.service.Connection') as mock_conn:
+ header = {'content-length': self.obj_len,
+ 'etag': self.obj_etag}
+ mock_conn.get_object.return_value = header, self._readbody()
+
+ resp = SwiftService()._download_object_job(mock_conn,
+ 'c',
+ 'test',
+ self.opts)
+
+ self.assertIsNone(resp.get('error'))
+ self.assertIs(True, resp['success'])
+ self.assertEqual(resp['action'], 'download_object')
+ self.assertEqual(resp['object'], 'test')
+ self.assertEqual(resp['path'], 'test')
+ self.assertEqual(mock_conn.get_object.mock_calls, [
+ mock.call(
+ 'c', 'test', headers={}, query_string='version-id=23456.7',
+ resp_chunk_size=65536, response_dict={}),
+ ])
+
@mock.patch('swiftclient.service.interruptable_as_completed')
@mock.patch('swiftclient.service.SwiftService._download_container')
@mock.patch('swiftclient.service.SwiftService._download_object_job')
@@ -2545,17 +2769,17 @@ class TestServiceDownload(_TestServiceBase):
delimiter=None,
prefix='test_o/prefix',
marker='',
- headers={}),
+ headers={}, query_string=None, version_marker=''),
mock.call('test_c_segments',
delimiter=None,
prefix='test_o/prefix',
marker='test_o/prefix/2',
- headers={}),
+ headers={}, query_string=None, version_marker=''),
mock.call('test_c_segments',
delimiter=None,
prefix='test_o/prefix',
marker='test_o/prefix/3',
- headers={})])
+ headers={}, query_string=None, version_marker='')])
def test_download_object_job_skip_identical_nested_slo(self):
with tempfile.NamedTemporaryFile() as f:
@@ -2682,6 +2906,7 @@ class TestServiceDownload(_TestServiceBase):
obj='test_o',
options=options)
+ self.maxDiff = None
self.assertEqual(r, expected_r)
self.assertEqual(mock_conn.get_container.mock_calls, [
@@ -2689,17 +2914,17 @@ class TestServiceDownload(_TestServiceBase):
delimiter=None,
prefix='test_o/prefix',
marker='',
- headers={}),
+ headers={}, query_string=None, version_marker=''),
mock.call('test_c_segments',
delimiter=None,
prefix='test_o/prefix',
marker='test_o/prefix/2',
- headers={}),
+ headers={}, query_string=None, version_marker=''),
mock.call('test_c_segments',
delimiter=None,
prefix='test_o/prefix',
marker='test_o/prefix/3',
- headers={})])
+ headers={}, query_string=None, version_marker='')])
self.assertEqual(mock_conn.get_object.mock_calls, [
mock.call('test_c',
'test_o',
diff --git a/test/unit/test_shell.py b/test/unit/test_shell.py
index 1fa0db4..b94cdcf 100644
--- a/test/unit/test_shell.py
+++ b/test/unit/test_shell.py
@@ -242,6 +242,30 @@ class TestShell(unittest.TestCase):
mock.call('container', headers={'Skip-Middleware': 'Test'})])
@mock.patch('swiftclient.service.Connection')
+ def test_stat_version_id(self, connection):
+ argv = ["", "stat", "--version-id", "1"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--version-id option only allowed for "
+ "object stats")
+
+ argv = ["", "stat", "--version-id", "1", "container"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--version-id option only allowed for "
+ "object stats")
+
+ argv = ["", "stat", "--version-id", "1", "container", "object"]
+ connection.return_value.head_object.return_value = {}
+ with CaptureOutput():
+ swiftclient.shell.main(argv)
+ self.assertEqual([mock.call('container', 'object', headers={},
+ query_string='version-id=1')],
+ connection.return_value.head_object.mock_calls)
+
+ @mock.patch('swiftclient.service.Connection')
def test_stat_object(self, connection):
return_headers = {
'x-object-manifest': 'manifest',
@@ -295,7 +319,45 @@ class TestShell(unittest.TestCase):
' Manifest: manifest\n')
self.assertEqual(connection.return_value.head_object.mock_calls, [
mock.call('container', 'object',
- headers={'Skip-Middleware': 'Test'})])
+ headers={'Skip-Middleware': 'Test'},
+ query_string=None)])
+
+ def test_list_account_with_delimiter(self):
+ argv = ["", "list", "--delimiter", "foo"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "-d option only allowed for "
+ "container listings")
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_list_container_with_versions(self, connection):
+ connection.return_value.get_container.side_effect = [
+ [None, [
+ {'name': 'foo', 'version_id': '2'},
+ {'name': 'foo', 'version_id': '1'},
+ ]],
+ [None, []],
+ ]
+ argv = ["", "list", "container", "--versions"]
+ with CaptureOutput(suppress_systemexit=True) as output:
+ swiftclient.shell.main(argv)
+ calls = [mock.call('container', delimiter=None, headers={}, marker='',
+ prefix=None, query_string='versions=true',
+ version_marker=''),
+ mock.call('container', delimiter=None, headers={},
+ marker='foo', prefix=None,
+ query_string='versions=true', version_marker='1')]
+ connection.return_value.get_container.assert_has_calls(calls)
+ self.assertEqual(output.out, 'foo\nfoo\n')
+
+ def test_list_account_with_versions(self):
+ argv = ["", "list", "--versions"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--versions option only allowed for "
+ "container listings")
@mock.patch('swiftclient.service.Connection')
def test_list_json(self, connection):
@@ -431,9 +493,11 @@ class TestShell(unittest.TestCase):
swiftclient.shell.main(argv)
calls = [
mock.call('container', marker='',
- delimiter=None, prefix=None, headers={}),
+ delimiter=None, prefix=None, headers={},
+ query_string=None, version_marker=''),
mock.call('container', marker='object_a',
- delimiter=None, prefix=None, headers={})]
+ delimiter=None, prefix=None, headers={},
+ query_string=None, version_marker='')]
connection.return_value.get_container.assert_has_calls(calls)
self.assertEqual(output.out, 'object_a\n')
@@ -450,9 +514,11 @@ class TestShell(unittest.TestCase):
swiftclient.shell.main(argv)
calls = [
mock.call('container', marker='',
- delimiter=None, prefix=None, headers={}),
+ delimiter=None, prefix=None, headers={},
+ query_string=None, version_marker=''),
mock.call('container', marker='object_a',
- delimiter=None, prefix=None, headers={})]
+ delimiter=None, prefix=None, headers={},
+ query_string=None, version_marker='')]
connection.return_value.get_container.assert_has_calls(calls)
self.assertEqual(output.out,
@@ -472,14 +538,44 @@ class TestShell(unittest.TestCase):
calls = [
mock.call('container', marker='',
delimiter=None, prefix=None,
- headers={'Skip-Middleware': 'Test'}),
+ headers={'Skip-Middleware': 'Test'},
+ query_string=None, version_marker=''),
mock.call('container', marker='object_a',
delimiter=None, prefix=None,
- headers={'Skip-Middleware': 'Test'})]
+ headers={'Skip-Middleware': 'Test'},
+ query_string=None, version_marker='')]
connection.return_value.get_container.assert_has_calls(calls)
self.assertEqual(output.out, 'object_a\n')
+ @mock.patch('swiftclient.service.Connection')
+ def test_download_version_id(self, connection):
+ argv = ["", "download", "--yes-all", "--version-id", "5"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--version-id option only allowed for "
+ "object downloads")
+
+ argv = ["", "download", "--version-id", "2", "container"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--version-id option only allowed for "
+ "object downloads")
+
+ argv = ["", "download", "--version-id", "1", "container", "object"]
+ connection.return_value.head_object.return_value = {}
+ connection.return_value.get_object.return_value = {}, ''
+ connection.return_value.attempts = 0
+ with CaptureOutput():
+ swiftclient.shell.main(argv)
+ self.assertEqual([mock.call('container', 'object', headers={},
+ query_string='version-id=1',
+ resp_chunk_size=65536,
+ response_dict={})],
+ connection.return_value.get_object.mock_calls)
+
@mock.patch('swiftclient.service.makedirs')
@mock.patch('swiftclient.service.Connection')
def test_download(self, connection, makedirs):
@@ -1085,6 +1181,33 @@ class TestShell(unittest.TestCase):
check_good(["--object-threads", "1"])
check_good(["--container-threads", "1"])
+ @mock.patch('swiftclient.service.Connection')
+ def test_delete_version_id(self, connection):
+ argv = ["", "delete", "--yes-all", "--version-id", "3"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--version-id option only allowed for "
+ "object deletes")
+
+ argv = ["", "delete", "--version-id", "1", "container"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--version-id option only allowed for "
+ "object deletes")
+
+ argv = ["", "delete", "--version-id", "1", "container", "object"]
+ connection.return_value.head_object.return_value = {}
+ connection.return_value.delete_object.return_value = None
+ connection.return_value.attempts = 0
+ with CaptureOutput():
+ swiftclient.shell.main(argv)
+ self.assertEqual([mock.call('container', 'object', headers={},
+ query_string='version-id=1',
+ response_dict={})],
+ connection.return_value.delete_object.mock_calls)
+
@mock.patch.object(swiftclient.service.SwiftService,
'_bulk_delete_page_size', lambda *a: 1)
@mock.patch('swiftclient.service.Connection')
@@ -1094,10 +1217,12 @@ class TestShell(unittest.TestCase):
[None, [{'name': 'empty_container'}]],
[None, []],
]
+ # N.B: missing --versions flag, version-id gets ignored
+ # only latest object is deleted
connection.return_value.get_container.side_effect = [
[None, [{'name': 'object'}, {'name': 'obj\xe9ct2'}]],
[None, []],
- [None, [{'name': 'object'}]],
+ [None, [{'name': 'object', 'version_id': 1}]],
[None, []],
[None, []],
]
@@ -1107,11 +1232,48 @@ class TestShell(unittest.TestCase):
connection.return_value.delete_object.return_value = None
swiftclient.shell.main(argv)
connection.return_value.delete_object.assert_has_calls([
- mock.call('container', 'object', query_string=None,
+ mock.call('container', 'object', query_string='',
response_dict={}, headers={}),
- mock.call('container', 'obj\xe9ct2', query_string=None,
+ mock.call('container', 'obj\xe9ct2', query_string='',
response_dict={}, headers={}),
- mock.call('container2', 'object', query_string=None,
+ mock.call('container2', 'object', query_string='',
+ response_dict={}, headers={})], any_order=True)
+ self.assertEqual(3, connection.return_value.delete_object.call_count,
+ 'Expected 3 calls but found\n%r'
+ % connection.return_value.delete_object.mock_calls)
+ self.assertEqual(
+ connection.return_value.delete_container.mock_calls, [
+ mock.call('container', response_dict={}, headers={}),
+ mock.call('container2', response_dict={}, headers={}),
+ mock.call('empty_container', response_dict={}, headers={})])
+
+ @mock.patch.object(swiftclient.service.SwiftService,
+ '_bulk_delete_page_size', lambda *a: 1)
+ @mock.patch('swiftclient.service.Connection')
+ def test_delete_account_versions(self, connection):
+ connection.return_value.get_account.side_effect = [
+ [None, [{'name': 'container'}, {'name': 'container2'}]],
+ [None, [{'name': 'empty_container'}]],
+ [None, []],
+ ]
+ connection.return_value.get_container.side_effect = [
+ [None, [{'name': 'object'}, {'name': 'obj\xe9ct2'}]],
+ [None, []],
+ [None, [{'name': 'obj', 'version_id': 1}]],
+ [None, []],
+ [None, []],
+ ]
+ connection.return_value.attempts = 0
+ argv = ["", "delete", "--all", "--versions"]
+ connection.return_value.head_object.return_value = {}
+ connection.return_value.delete_object.return_value = None
+ swiftclient.shell.main(argv)
+ connection.return_value.delete_object.assert_has_calls([
+ mock.call('container', 'object', query_string='',
+ response_dict={}, headers={}),
+ mock.call('container', 'obj\xe9ct2', query_string='',
+ response_dict={}, headers={}),
+ mock.call('container2', 'obj', query_string='version-id=1',
response_dict={}, headers={})], any_order=True)
self.assertEqual(3, connection.return_value.delete_object.call_count,
'Expected 3 calls but found\n%r'
@@ -1323,12 +1485,42 @@ class TestShell(unittest.TestCase):
connection.return_value.delete_container.assert_called_with(
'container', response_dict={}, headers={})
connection.return_value.delete_object.assert_called_with(
- 'container', 'object', query_string=None, response_dict={},
+ 'container', 'object', query_string='', response_dict={},
headers={})
@mock.patch.object(swiftclient.service.SwiftService,
'_bulk_delete_page_size', lambda *a: 1)
@mock.patch('swiftclient.service.Connection')
+ def test_delete_container_versions(self, connection):
+ argv = ["", "delete", "--versions", "container", "obj"]
+ with self.assertRaises(SystemExit) as caught:
+ swiftclient.shell.main(argv)
+ self.assertEqual(str(caught.exception),
+ "--versions option not allowed for object deletes")
+
+ connection.return_value.get_container.side_effect = [
+ [None, [{'name': 'object', 'version_id': 2},
+ {'name': 'object', 'version_id': 1}]],
+ [None, []],
+ ]
+ connection.return_value.attempts = 0
+ argv = ["", "delete", "--versions", "container"]
+ connection.return_value.head_object.return_value = {}
+ swiftclient.shell.main(argv)
+ connection.return_value.delete_container.assert_called_with(
+ 'container', response_dict={}, headers={})
+ expected_calls = [
+ mock.call('container', 'object', query_string='version-id=2',
+ response_dict={}, headers={}),
+ mock.call('container', 'object', query_string='version-id=1',
+ response_dict={}, headers={})]
+
+ self.assertEqual(connection.return_value.delete_object.mock_calls,
+ expected_calls)
+
+ @mock.patch.object(swiftclient.service.SwiftService,
+ '_bulk_delete_page_size', lambda *a: 1)
+ @mock.patch('swiftclient.service.Connection')
def test_delete_container_headers(self, connection):
connection.return_value.get_container.side_effect = [
[None, [{'name': 'object'}]],
@@ -1342,7 +1534,7 @@ class TestShell(unittest.TestCase):
'container', response_dict={},
headers={'Skip-Middleware': 'Test'})
connection.return_value.delete_object.assert_called_with(
- 'container', 'object', query_string=None, response_dict={},
+ 'container', 'object', query_string='', response_dict={},
headers={'Skip-Middleware': 'Test'})
@mock.patch.object(swiftclient.service.SwiftService,
@@ -1408,7 +1600,7 @@ class TestShell(unittest.TestCase):
connection.return_value.attempts = 0
swiftclient.shell.main(argv)
connection.return_value.delete_object.assert_called_with(
- 'container', 'object', query_string=None, response_dict={},
+ 'container', 'object', query_string='', response_dict={},
headers={})
@mock.patch.object(swiftclient.service.SwiftService,