From 794b125e76e8ab4798d777ec85c559fb0aa1e5d1 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Singh <pradeep.singh@nectechnologies.in> Date: Sun, 24 May 2015 21:16:54 +0530 Subject: [PATCH] SwiftClient object upload beginning with / or "./" Currently SwiftClient populate response dictionary before removing "./" or "/" at begining of object name. This patch fixes that by changing that order. Closes-bug: #1412425 Change-Id: I80222754caba5d42a468f4677ac539e46682dd31 --- swiftclient/service.py | 8 +++---- tests/unit/test_service.py | 45 ++++++++++++++++++++++++++++++++++---- tests/unit/test_shell.py | 8 +++---- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/swiftclient/service.py b/swiftclient/service.py index c533297e..5a24dac4 100644 --- a/swiftclient/service.py +++ b/swiftclient/service.py @@ -1552,6 +1552,10 @@ class SwiftService(object): def _upload_object_job(self, conn, container, source, obj, options, results_queue=None): + if obj.startswith('./') or obj.startswith('.\\'): + obj = obj[2:] + if obj.startswith('/'): + obj = obj[1:] res = { 'action': 'upload_object', 'container': container, @@ -1564,10 +1568,6 @@ class SwiftService(object): path = source res['path'] = path try: - if obj.startswith('./') or obj.startswith('.\\'): - obj = obj[2:] - if obj.startswith('/'): - obj = obj[1:] if path is not None: put_headers = {'x-object-meta-mtime': "%f" % getmtime(path)} else: diff --git a/tests/unit/test_service.py b/tests/unit/test_service.py index 0e8aff10..68d2e123 100644 --- a/tests/unit/test_service.py +++ b/tests/unit/test_service.py @@ -21,12 +21,16 @@ from hashlib import md5 from mock import Mock, PropertyMock from six.moves.queue import Queue, Empty as QueueEmptyError from six import BytesIO - import swiftclient import swiftclient.utils as utils -from swiftclient.client import Connection -from swiftclient.service import SwiftService, SwiftError - +from swiftclient.client import Connection, ClientException +from swiftclient.service import SwiftService, SwiftError,\ + SwiftUploadObject +import six +if six.PY2: + import __builtin__ as builtins +else: + import builtins clean_os_environ = {} environ_prefixes = ('ST_', 'OS_') @@ -551,6 +555,39 @@ class TestService(testtools.TestCase): self.assertEqual('Segment size should be an integer value', exc.value) + @mock.patch('swiftclient.service.stat') + @mock.patch('swiftclient.service.getmtime', return_value=1.0) + @mock.patch('swiftclient.service.getsize', return_value=4) + @mock.patch.object(builtins, 'open', return_value=six.StringIO('asdf')) + def test_upload_with_relative_path(self, *args, **kwargs): + service = SwiftService({}) + objects = [{'path': "./test", + 'strt_indx': 2}, + {'path': os.path.join(os.getcwd(), "test"), + 'strt_indx': 1}, + {'path': ".\\test", + 'strt_indx': 2}] + for obj in objects: + with mock.patch('swiftclient.service.Connection') as mock_conn: + mock_conn.return_value.head_object.side_effect = \ + ClientException('Not Found', http_status=404) + mock_conn.return_value.put_object.return_value =\ + 'd41d8cd98f00b204e9800998ecf8427e' + resp_iter = service.upload( + 'c', [SwiftUploadObject(obj['path'])]) + responses = [x for x in resp_iter] + for resp in responses: + self.assertTrue(resp['success']) + self.assertEqual(2, len(responses)) + create_container_resp, upload_obj_resp = responses + self.assertEqual(create_container_resp['action'], + 'create_container') + self.assertEqual(upload_obj_resp['action'], + 'upload_object') + self.assertEqual(upload_obj_resp['object'], + obj['path'][obj['strt_indx']:]) + self.assertEqual(upload_obj_resp['path'], obj['path']) + class TestServiceUpload(testtools.TestCase): diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py index b89df96f..fd41069e 100644 --- a/tests/unit/test_shell.py +++ b/tests/unit/test_shell.py @@ -1608,7 +1608,7 @@ class TestCrossAccountObjectAccess(TestBase, MockHttpTest): self.assertRequests([('PUT', self.cont_path), ('PUT', self.obj_path)]) - self.assertEqual(self.obj, out.strip()) + self.assertEqual(self.obj[1:], out.strip()) expected_err = 'Warning: failed to create container %r: 403 Fake' \ % self.cont self.assertEqual(expected_err, out.err.strip()) @@ -1617,7 +1617,6 @@ class TestCrossAccountObjectAccess(TestBase, MockHttpTest): req_handler = self._fake_cross_account_auth(False, True) fake_conn = self.fake_http_connection(403, 403, on_request=req_handler) - args, env = self._make_cmd('upload', cmd_args=[self.cont, self.obj, '--leave-segments']) with mock.patch('swiftclient.client._import_keystone_client', @@ -1629,10 +1628,9 @@ class TestCrossAccountObjectAccess(TestBase, MockHttpTest): swiftclient.shell.main(args) except SystemExit as e: self.fail('Unexpected SystemExit: %s' % e) - self.assertRequests([('PUT', self.cont_path), ('PUT', self.obj_path)]) - self.assertEqual(self.obj, out.strip()) + self.assertEqual(self.obj[1:], out.strip()) expected_err = 'Warning: failed to create container %r: 403 Fake' \ % self.cont self.assertEqual(expected_err, out.err.strip()) @@ -1667,7 +1665,7 @@ class TestCrossAccountObjectAccess(TestBase, MockHttpTest): self.assert_request(('PUT', segment_path_0)) self.assert_request(('PUT', segment_path_1)) self.assert_request(('PUT', self.obj_path)) - self.assertTrue(self.obj in out.out) + self.assertTrue(self.obj[1:] in out.out) expected_err = 'Warning: failed to create container %r: 403 Fake' \ % self.cont self.assertEqual(expected_err, out.err.strip())