summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2019-07-26 22:56:08 -0700
committerTim Burke <tim.burke@gmail.com>2019-08-01 20:42:31 -0700
commit78753987468cb6b04d0b4e06b432e22f5a7189bd (patch)
tree67a7363af5abd18dd11c557f2b0e47bf8c356455 /tests
parent5bd66947fc3d8987d4b24d5119a346031004229e (diff)
downloadpython-swiftclient-78753987468cb6b04d0b4e06b432e22f5a7189bd.tar.gz
Delete/overwrite symlinks better
Previously, when deleting a symlink that points to an xLO, we'd clean up the xLO's segments then delete the symlink, leaving the xLO itself busted. Similar trouble would come from overwriting a symlink pointing to an xLO. Check for a Content-Location in the HEAD response and leave such segments. Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com> Change-Id: I45b210cf380a68bd88187c91fa2d63a8b2bb709b
Diffstat (limited to 'tests')
-rw-r--r--tests/unit/test_service.py15
-rw-r--r--tests/unit/test_shell.py29
2 files changed, 37 insertions, 7 deletions
diff --git a/tests/unit/test_service.py b/tests/unit/test_service.py
index 12fbaa0..b760352 100644
--- a/tests/unit/test_service.py
+++ b/tests/unit/test_service.py
@@ -312,8 +312,8 @@ class TestServiceDelete(_TestServiceBase):
s = SwiftService()
r = s._delete_object(mock_conn, 'test_c', 'test_o', self.opts, mock_q)
- mock_conn.head_object.assert_called_once_with('test_c', 'test_o',
- headers={})
+ 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={},
headers={}
@@ -335,7 +335,8 @@ class TestServiceDelete(_TestServiceBase):
r = s._delete_object(mock_conn, 'test_c', 'test_o', opt_c, mock_q)
mock_conn.head_object.assert_called_once_with(
- 'test_c', 'test_o', headers={'Skip-Middleware': 'Test'})
+ '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={},
headers={'Skip-Middleware': 'Test'}
@@ -362,8 +363,8 @@ class TestServiceDelete(_TestServiceBase):
r = s._delete_object(mock_conn, 'test_c', 'test_o', self.opts, mock_q)
after = time.time()
- mock_conn.head_object.assert_called_once_with('test_c', 'test_o',
- headers={})
+ 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={},
headers={}
@@ -389,8 +390,8 @@ class TestServiceDelete(_TestServiceBase):
s = SwiftService()
r = s._delete_object(mock_conn, 'test_c', 'test_o', self.opts, mock_q)
- mock_conn.head_object.assert_called_once_with('test_c', 'test_o',
- headers={})
+ 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='multipart-manifest=delete',
diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py
index d9ddb3e..c972281 100644
--- a/tests/unit/test_shell.py
+++ b/tests/unit/test_shell.py
@@ -833,6 +833,35 @@ class TestShell(unittest.TestCase):
)
@mock.patch('swiftclient.service.Connection')
+ def test_upload_over_symlink_to_slo(self, connection):
+ # Upload delete existing segments
+ connection.return_value.head_container.return_value = {
+ 'x-storage-policy': 'one'}
+ connection.return_value.attempts = 0
+ connection.return_value.head_object.side_effect = [
+ {'x-static-large-object': 'true',
+ 'content-location': '/v1/a/c/manifest',
+ 'content-length': '2'},
+ ]
+ connection.return_value.get_object.return_value = (
+ {'content-location': '/v1/a/c/manifest'},
+ b'[{"name": "container1/old_seg1"},'
+ b' {"name": "container2/old_seg2"}]'
+ )
+ connection.return_value.put_object.return_value = EMPTY_ETAG
+ connection.return_value.delete_object.return_value = None
+ argv = ["", "upload", "container", self.tmpfile]
+ swiftclient.shell.main(argv)
+ connection.return_value.put_object.assert_called_with(
+ 'container',
+ self.tmpfile.lstrip('/'),
+ mock.ANY,
+ content_length=0,
+ headers={'x-object-meta-mtime': mock.ANY},
+ response_dict={})
+ self.assertEqual([], connection.return_value.delete_object.mock_calls)
+
+ @mock.patch('swiftclient.service.Connection')
def test_upload_leave_slo_segments(self, connection):
# Test upload overwriting a manifest respects --leave-segments
connection.return_value.head_container.return_value = {