From 51a8a5a7ae3a065307974791ed1dd43503fb3b5a Mon Sep 17 00:00:00 2001
From: Marek Kaleta <marek.kaleta@firma.seznam.cz>
Date: Wed, 23 Mar 2016 12:09:49 +0100
Subject: [PATCH] Fix SwiftPostObject options usage in SwiftService

SwiftService().post(cont, [SwiftPostObject(obj, options]) currently
ignores options['header'], raises exception when options['headers']
is set and make malformed metadata when options['meta'] is set.

Fix tipos in code, add unittest for SwiftService().post
Closes-Bug: #1560052

Change-Id: Ie460f753492e9b73836b4adfc7c9c0f2130a8a91
---
 swiftclient/service.py     |  6 ++---
 tests/unit/test_service.py | 46 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/swiftclient/service.py b/swiftclient/service.py
index f253ec86..99c833e0 100644
--- a/swiftclient/service.py
+++ b/swiftclient/service.py
@@ -569,7 +569,7 @@ class SwiftService(object):
 
                             {
                                 'meta': [],
-                                'headers': [],
+                                'header': [],
                                 'read_acl': None,   # For containers only
                                 'write_acl': None,  # For containers only
                                 'sync_to': None,    # For containers only
@@ -700,10 +700,10 @@ class SwiftService(object):
                     if 'meta' in obj_options:
                         headers.update(
                             split_headers(
-                                obj_options['meta'], 'X-Object-Meta'
+                                obj_options['meta'], 'X-Object-Meta-'
                             )
                         )
-                    if 'headers' in obj_options:
+                    if 'header' in obj_options:
                         headers.update(
                             split_headers(obj_options['header'], '')
                         )
diff --git a/tests/unit/test_service.py b/tests/unit/test_service.py
index 418ee85b..a392967d 100644
--- a/tests/unit/test_service.py
+++ b/tests/unit/test_service.py
@@ -2130,3 +2130,49 @@ class TestServiceDownload(_TestServiceBase):
                           resp_chunk_size=65536,
                           headers={'If-None-Match': on_disk_md5},
                           response_dict={})])
+
+
+class TestServicePost(_TestServiceBase):
+
+    def setUp(self):
+        super(TestServicePost, self).setUp()
+        self.opts = swiftclient.service._default_local_options.copy()
+
+    @mock.patch('swiftclient.service.MultiThreadingManager')
+    @mock.patch('swiftclient.service.ResultsIterator')
+    def test_object_post(self, res_iter, thread_manager):
+        """
+        Check post method translates strings and objects to _post_object_job
+        calls correctly
+        """
+        tm_instance = Mock()
+        thread_manager.return_value = tm_instance
+
+        self.opts.update({'meta': ["meta1:test1"], "header": ["hdr1:test1"]})
+        spo = swiftclient.service.SwiftPostObject(
+            "test_spo",
+            {'meta': ["meta1:test2"], "header": ["hdr1:test2"]})
+
+        service = SwiftService()
+        SwiftService().post('test_c', ['test_o', spo], self.opts)
+
+        calls = [
+            mock.call(
+                service._post_object_job, 'test_c', 'test_o',
+                {
+                    "X-Object-Meta-Meta1": "test1",
+                    "Hdr1": "test1"},
+                {}),
+            mock.call(
+                service._post_object_job, 'test_c', 'test_spo',
+                {
+                    "X-Object-Meta-Meta1": "test2",
+                    "Hdr1": "test2"},
+                {}),
+        ]
+        tm_instance.object_uu_pool.submit.assert_has_calls(calls)
+        self.assertEqual(
+            tm_instance.object_uu_pool.submit.call_count, len(calls))
+
+        res_iter.assert_called_with(
+            [tm_instance.object_uu_pool.submit()] * len(calls))