Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / test / pithos.py @ de27950a

History | View | Annotate | Download (30.7 kB)

1 24851aa5 Stavros Sachtouris
# Copyright 2013 GRNET S.A. All rights reserved.
2 c1004a00 Stavros Sachtouris
#
3 c1004a00 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 c1004a00 Stavros Sachtouris
# without modification, are permitted provided that the following
5 c1004a00 Stavros Sachtouris
# conditions are met:
6 c1004a00 Stavros Sachtouris
#
7 c1004a00 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 c1004a00 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 c1004a00 Stavros Sachtouris
#      disclaimer.
10 c1004a00 Stavros Sachtouris
#
11 c1004a00 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 c1004a00 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 c1004a00 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 c1004a00 Stavros Sachtouris
#      provided with the distribution.
15 c1004a00 Stavros Sachtouris
#
16 c1004a00 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 c1004a00 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 c1004a00 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 c1004a00 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 c1004a00 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 c1004a00 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 c1004a00 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 c1004a00 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 c1004a00 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 c1004a00 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 c1004a00 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 c1004a00 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 c1004a00 Stavros Sachtouris
#
29 c1004a00 Stavros Sachtouris
# The views and conclusions contained in the software and
30 c1004a00 Stavros Sachtouris
# documentation are those of the authors and should not be
31 c1004a00 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 c1004a00 Stavros Sachtouris
# or implied, of GRNET S.A.
33 c1004a00 Stavros Sachtouris
34 24851aa5 Stavros Sachtouris
from unittest import TestCase
35 24851aa5 Stavros Sachtouris
from mock import patch, call, Mock
36 2a7292f1 Stavros Sachtouris
from tempfile import NamedTemporaryFile
37 2a7292f1 Stavros Sachtouris
from os import urandom
38 c1004a00 Stavros Sachtouris
39 24851aa5 Stavros Sachtouris
from kamaki.clients import ClientError
40 8c599ca2 Stavros Sachtouris
from kamaki.clients.pithos import PithosClient as PC
41 c1004a00 Stavros Sachtouris
from kamaki.clients.astakos import AstakosClient
42 24851aa5 Stavros Sachtouris
from kamaki.clients.connection.kamakicon import KamakiHTTPConnection as C
43 24851aa5 Stavros Sachtouris
44 24851aa5 Stavros Sachtouris
user_id = 'ac0un7-1d-5tr1ng'
45 cb65588d Stavros Sachtouris
obj = 'obj3c7N4m3'
46 24851aa5 Stavros Sachtouris
47 24851aa5 Stavros Sachtouris
account_info = {
48 24851aa5 Stavros Sachtouris
    'content-language': 'en-us',
49 24851aa5 Stavros Sachtouris
    'content-type': 'text/html; charset=utf-8',
50 24851aa5 Stavros Sachtouris
    'date': 'Wed, 06 Mar 2013 13:25:51 GMT',
51 24851aa5 Stavros Sachtouris
    'last-modified': 'Mon, 04 Mar 2013 18:22:31 GMT',
52 24851aa5 Stavros Sachtouris
    'server': 'gunicorn/0.14.5',
53 24851aa5 Stavros Sachtouris
    'vary': 'Accept-Language',
54 24851aa5 Stavros Sachtouris
    'x-account-bytes-used': '751615526',
55 24851aa5 Stavros Sachtouris
    'x-account-container-count': 7,
56 24851aa5 Stavros Sachtouris
    'x-account-policy-quota': 53687091200,
57 24851aa5 Stavros Sachtouris
    'x-account-policy-versioning': 'auto'}
58 d12e8569 Stavros Sachtouris
container_info = {
59 d12e8569 Stavros Sachtouris
    'content-language': 'en-us',
60 d12e8569 Stavros Sachtouris
    'content-type': 'text/html; charset=utf-8',
61 d12e8569 Stavros Sachtouris
    'date': 'Wed, 06 Mar 2013 15:11:05 GMT',
62 d12e8569 Stavros Sachtouris
    'last-modified': 'Wed, 27 Feb 2013 15:56:13 GMT',
63 d12e8569 Stavros Sachtouris
    'server': 'gunicorn/0.14.5',
64 d12e8569 Stavros Sachtouris
    'vary': 'Accept-Language',
65 d12e8569 Stavros Sachtouris
    'x-container-block-hash': 'sha256',
66 d12e8569 Stavros Sachtouris
    'x-container-block-size': 4194304,
67 d12e8569 Stavros Sachtouris
    'x-container-bytes-used': 309528938,
68 d12e8569 Stavros Sachtouris
    'x-container-object-count': 14,
69 d12e8569 Stavros Sachtouris
    'x-container-object-meta': '',
70 d12e8569 Stavros Sachtouris
    'x-container-policy-quota': 53687091200,
71 d12e8569 Stavros Sachtouris
    'x-container-policy-versioning': 'auto'}
72 723e9d47 Stavros Sachtouris
object_info = {
73 723e9d47 Stavros Sachtouris
    'content-language': 'en-us',
74 723e9d47 Stavros Sachtouris
    'content-length': 254965,
75 723e9d47 Stavros Sachtouris
    'content-type': 'application/octet-stream',
76 723e9d47 Stavros Sachtouris
    'date': 'Thu, 07 Mar 2013 13:27:43 GMT',
77 723e9d47 Stavros Sachtouris
    'etag': '',
78 723e9d47 Stavros Sachtouris
    'last-modified': 'Mon, 04 Mar 2013 18:22:31 GMT',
79 723e9d47 Stavros Sachtouris
    'server': 'gunicorn/0.14.5',
80 723e9d47 Stavros Sachtouris
    'vary': 'Accept-Language',
81 723e9d47 Stavros Sachtouris
    'x-object-hash': 'obj3c7h45h1s0bj3c7h45h411r34dY',
82 723e9d47 Stavros Sachtouris
    'x-object-uuid': 'd0c747ca-34bd-49e0-8e98-1d07d8b0cbc7',
83 723e9d47 Stavros Sachtouris
    'x-object-version': '525996',
84 3e2e07be Stavros Sachtouris
    'x-object-version-timestamp': 'Mon, 04 Mar 2013 18:22:31 GMT',
85 3e2e07be Stavros Sachtouris
    'x-object-meta-k1': 'v1',
86 3e2e07be Stavros Sachtouris
    'x-object-meta-k2': 'v2'}
87 efaa8675 Stavros Sachtouris
container_list = [
88 efaa8675 Stavros Sachtouris
    dict(
89 efaa8675 Stavros Sachtouris
        count=2,
90 efaa8675 Stavros Sachtouris
        last_modified="2013-02-27T11:56:09.893033+00:00",
91 efaa8675 Stavros Sachtouris
        bytes=677076979,
92 efaa8675 Stavros Sachtouris
        name="pithos",
93 efaa8675 Stavros Sachtouris
        x_container_policy=dict(quota="21474836480", versioning="auto")),
94 efaa8675 Stavros Sachtouris
    dict(
95 efaa8675 Stavros Sachtouris
        count=0,
96 efaa8675 Stavros Sachtouris
        last_modified="2012-10-23T12:25:17.229187+00:00",
97 efaa8675 Stavros Sachtouris
        bytes=0,
98 efaa8675 Stavros Sachtouris
        name="trash",
99 efaa8675 Stavros Sachtouris
        x_container_policy=dict(quota="21474836480", versioning="auto"))]
100 39c737d4 Stavros Sachtouris
object_list = [
101 39c737d4 Stavros Sachtouris
    dict(hash="",
102 39c737d4 Stavros Sachtouris
        name="The_Secret_Garden.zip",
103 39c737d4 Stavros Sachtouris
        x_object_public="/public/wdp9p",
104 39c737d4 Stavros Sachtouris
        bytes=203304947,
105 39c737d4 Stavros Sachtouris
        x_object_version_timestamp="1360237915.7027509",
106 39c737d4 Stavros Sachtouris
        x_object_uuid="s0m3uu1df0r0bj0n3",
107 39c737d4 Stavros Sachtouris
        last_modified="2013-02-07T11:51:55.702751+00:00",
108 39c737d4 Stavros Sachtouris
        content_type="application/octet-stream",
109 39c737d4 Stavros Sachtouris
        x_object_hash="0afdf29f71cd53126225c3f54ca",
110 39c737d4 Stavros Sachtouris
        x_object_version=17737,
111 39c737d4 Stavros Sachtouris
        x_object_modified_by=user_id),
112 39c737d4 Stavros Sachtouris
    dict(hash="",
113 39c737d4 Stavros Sachtouris
        name="The_Revealed_Garden.zip",
114 39c737d4 Stavros Sachtouris
        x_object_public="/public/wpd7p",
115 39c737d4 Stavros Sachtouris
        bytes=20330947,
116 39c737d4 Stavros Sachtouris
        x_object_version_timestamp="13602915.7027509",
117 39c737d4 Stavros Sachtouris
        x_object_uuid="s0m3uu1df0r0bj70w",
118 39c737d4 Stavros Sachtouris
        last_modified="2013-02-07T11:51:55.702751+00:00",
119 39c737d4 Stavros Sachtouris
        content_type="application/octet-stream",
120 39c737d4 Stavros Sachtouris
        x_object_hash="0afdf29f71cd53126225c3f54ca",
121 39c737d4 Stavros Sachtouris
        x_object_version=17737,
122 39c737d4 Stavros Sachtouris
        x_object_modified_by=user_id)]
123 b4e29772 Stavros Sachtouris
object_hashmap = dict(
124 b4e29772 Stavros Sachtouris
    block_hash="sha256", block_size=4194304, bytes=33554432,
125 b4e29772 Stavros Sachtouris
    hashes=[
126 b4e29772 Stavros Sachtouris
        "4988438cc1c0292c085d289649b28cf547ba3db71c6efaac9f2df7e193d4d0af",
127 b4e29772 Stavros Sachtouris
        "b214244aa56df7d1df7c6cac066e7cef268d9c2beb4dcf7ce68af667b0626f91",
128 b4e29772 Stavros Sachtouris
        "17f365f25e0682565ded30576066bb13377a3d306967e4d74e06bb6bbc20f75f",
129 b4e29772 Stavros Sachtouris
        "2524ae208932669fff89adf8a2fc0df3b67736ca0d3aadce7a2ce640f142af37",
130 b4e29772 Stavros Sachtouris
        "5d807a2129d2fcd3c221c3da418ed52af3fc48d0817b62e0bb437acffccd3514",
131 b4e29772 Stavros Sachtouris
        "609de22ce842d997f645fc49d5f14e0e3766dd51a6cbe66383b2bab82c8dfcd0",
132 b4e29772 Stavros Sachtouris
        "3102851ac168c78be70e35ff5178c7b1ebebd589e5106d565ca1094d1ca8ff59",
133 b4e29772 Stavros Sachtouris
        "bfe306dd24e92a8d85caf7055643f250fd319e8c4cdd4755ddabbf3ff97e83c7"])
134 24851aa5 Stavros Sachtouris
135 24851aa5 Stavros Sachtouris
136 24851aa5 Stavros Sachtouris
class Pithos(TestCase):
137 24851aa5 Stavros Sachtouris
138 24851aa5 Stavros Sachtouris
    class FR(object):
139 24851aa5 Stavros Sachtouris
        """FR stands for Fake Response"""
140 24851aa5 Stavros Sachtouris
        json = dict()
141 bcbf3cf0 Stavros Sachtouris
        headers = dict()
142 24851aa5 Stavros Sachtouris
        content = json
143 24851aa5 Stavros Sachtouris
        status = None
144 8c599ca2 Stavros Sachtouris
        status_code = 200
145 24851aa5 Stavros Sachtouris
146 24851aa5 Stavros Sachtouris
        def release(self):
147 c1004a00 Stavros Sachtouris
            pass
148 c1004a00 Stavros Sachtouris
149 24851aa5 Stavros Sachtouris
    files = []
150 c1004a00 Stavros Sachtouris
151 cb65588d Stavros Sachtouris
    def _create_temp_file(self, num_of_blocks):
152 2a7292f1 Stavros Sachtouris
        self.files.append(NamedTemporaryFile())
153 2a7292f1 Stavros Sachtouris
        tmpFile = self.files[-1]
154 2a7292f1 Stavros Sachtouris
        file_size = num_of_blocks * 4 * 1024 * 1024
155 2a7292f1 Stavros Sachtouris
        print('\n\tCreate tmp file')
156 2a7292f1 Stavros Sachtouris
        tmpFile.write(urandom(file_size))
157 2a7292f1 Stavros Sachtouris
        tmpFile.flush()
158 2a7292f1 Stavros Sachtouris
        tmpFile.seek(0)
159 2a7292f1 Stavros Sachtouris
        print('\t\tDone')
160 2a7292f1 Stavros Sachtouris
        return tmpFile
161 2a7292f1 Stavros Sachtouris
162 24851aa5 Stavros Sachtouris
    def assert_dicts_are_equal(self, d1, d2):
163 24851aa5 Stavros Sachtouris
        for k, v in d1.items():
164 24851aa5 Stavros Sachtouris
            self.assertTrue(k in d2)
165 24851aa5 Stavros Sachtouris
            if isinstance(v, dict):
166 24851aa5 Stavros Sachtouris
                self.assert_dicts_are_equal(v, d2[k])
167 24851aa5 Stavros Sachtouris
            else:
168 24851aa5 Stavros Sachtouris
                self.assertEqual(unicode(v), unicode(d2[k]))
169 c1004a00 Stavros Sachtouris
170 24851aa5 Stavros Sachtouris
    def setUp(self):
171 24851aa5 Stavros Sachtouris
        self.url = 'https://www.example.com/pithos'
172 24851aa5 Stavros Sachtouris
        self.token = 'p17h0570k3n'
173 8c599ca2 Stavros Sachtouris
        self.client = PC(self.url, self.token)
174 24851aa5 Stavros Sachtouris
        self.client.account = user_id
175 24851aa5 Stavros Sachtouris
        self.client.container = 'c0nt@1n3r_i'
176 c1004a00 Stavros Sachtouris
177 c1004a00 Stavros Sachtouris
    def tearDown(self):
178 24851aa5 Stavros Sachtouris
        self.FR.headers = dict()
179 8c599ca2 Stavros Sachtouris
        self.FR.status_code = 200
180 bcbf3cf0 Stavros Sachtouris
        self.FR.json = dict()
181 b4e29772 Stavros Sachtouris
        self.FR.content = self.FR.json
182 cf687343 Stavros Sachtouris
        for f in self.files:
183 cf687343 Stavros Sachtouris
            f.close()
184 24851aa5 Stavros Sachtouris
185 2a7292f1 Stavros Sachtouris
    #  Pithos+ methods that extend storage API
186 2a7292f1 Stavros Sachtouris
187 24851aa5 Stavros Sachtouris
    def test_get_account_info(self):
188 24851aa5 Stavros Sachtouris
        self.FR.headers = account_info
189 8c599ca2 Stavros Sachtouris
        self.FR.status_code = 204
190 24851aa5 Stavros Sachtouris
        with patch.object(C, 'perform_request', return_value=self.FR()):
191 24851aa5 Stavros Sachtouris
            r = self.client.get_account_info()
192 24851aa5 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
193 24851aa5 Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, '/%s' % user_id)
194 24851aa5 Stavros Sachtouris
            self.assert_dicts_are_equal(r, account_info)
195 8c599ca2 Stavros Sachtouris
            PC.set_param = Mock()
196 24851aa5 Stavros Sachtouris
            untils = ['date 1', 'date 2', 'date 3']
197 24851aa5 Stavros Sachtouris
            for unt in untils:
198 24851aa5 Stavros Sachtouris
                r = self.client.get_account_info(until=unt)
199 24851aa5 Stavros Sachtouris
                self.assert_dicts_are_equal(r, account_info)
200 24851aa5 Stavros Sachtouris
            for i in range(len(untils)):
201 24851aa5 Stavros Sachtouris
                self.assertEqual(
202 8c599ca2 Stavros Sachtouris
                    PC.set_param.mock_calls[i],
203 24851aa5 Stavros Sachtouris
                    call('until', untils[i], iff=untils[i]))
204 756e9de9 Stavros Sachtouris
            self.FR.status_code = 401
205 756e9de9 Stavros Sachtouris
            self.assertRaises(ClientError, self.client.get_account_info)
206 514f9b88 Stavros Sachtouris
207 514f9b88 Stavros Sachtouris
    def test_replace_account_meta(self):
208 514f9b88 Stavros Sachtouris
        self.FR.status_code = 202
209 514f9b88 Stavros Sachtouris
        metas = dict(k1='v1', k2='v2', k3='v3')
210 8c599ca2 Stavros Sachtouris
        PC.set_header = Mock()
211 514f9b88 Stavros Sachtouris
        with patch.object(C, 'perform_request', return_value=self.FR()):
212 514f9b88 Stavros Sachtouris
            self.client.replace_account_meta(metas)
213 514f9b88 Stavros Sachtouris
            self.assertEqual(self.client.http_client.url, self.url)
214 514f9b88 Stavros Sachtouris
            self.assertEqual(self.client.http_client.path, '/%s' % user_id)
215 514f9b88 Stavros Sachtouris
            prfx = 'X-Account-Meta-'
216 514f9b88 Stavros Sachtouris
            expected = [call('%s%s' % (prfx, k), v) for k, v in metas.items()]
217 8c599ca2 Stavros Sachtouris
            self.assertEqual(PC.set_header.mock_calls, expected)
218 8c599ca2 Stavros Sachtouris
219 8c599ca2 Stavros Sachtouris
    def test_del_account_meta(self):
220 8c599ca2 Stavros Sachtouris
        keys = ['k1', 'k2', 'k3']
221 8c599ca2 Stavros Sachtouris
        with patch.object(PC, 'account_post', return_value=self.FR()) as ap:
222 8c599ca2 Stavros Sachtouris
            expected = []
223 8c599ca2 Stavros Sachtouris
            for key in keys:
224 8c599ca2 Stavros Sachtouris
                self.client.del_account_meta(key)
225 8c599ca2 Stavros Sachtouris
                expected.append(call(update=True, metadata={key: ''}))
226 8c599ca2 Stavros Sachtouris
            self.assertEqual(ap.mock_calls, expected)
227 756e9de9 Stavros Sachtouris
228 756e9de9 Stavros Sachtouris
    def test_create_container(self):
229 756e9de9 Stavros Sachtouris
        self.FR.status_code = 201
230 756e9de9 Stavros Sachtouris
        with patch.object(PC, 'put', return_value=self.FR()) as put:
231 756e9de9 Stavros Sachtouris
            cont = 's0m3c0n731n3r'
232 756e9de9 Stavros Sachtouris
            self.client.create_container(cont)
233 756e9de9 Stavros Sachtouris
            expected = [call('/%s/%s' % (user_id, cont), success=(201, 202))]
234 756e9de9 Stavros Sachtouris
            self.assertEqual(put.mock_calls, expected)
235 756e9de9 Stavros Sachtouris
            self.FR.status_code = 202
236 756e9de9 Stavros Sachtouris
            self.assertRaises(ClientError, self.client.create_container, cont)
237 d12e8569 Stavros Sachtouris
238 d12e8569 Stavros Sachtouris
    def test_get_container_info(self):
239 d12e8569 Stavros Sachtouris
        self.FR.headers = container_info
240 d12e8569 Stavros Sachtouris
        with patch.object(PC, 'container_head', return_value=self.FR()) as ch:
241 d12e8569 Stavros Sachtouris
            r = self.client.get_container_info()
242 d12e8569 Stavros Sachtouris
            self.assert_dicts_are_equal(r, container_info)
243 d12e8569 Stavros Sachtouris
            u = 'some date'
244 d12e8569 Stavros Sachtouris
            r = self.client.get_container_info(until=u)
245 d12e8569 Stavros Sachtouris
            self.assertEqual(ch.mock_calls, [call(until=None), call(until=u)])
246 5549c0ab Stavros Sachtouris
247 5549c0ab Stavros Sachtouris
    def test_delete_container(self):
248 5549c0ab Stavros Sachtouris
        self.FR.status_code = 204
249 5549c0ab Stavros Sachtouris
        with patch.object(PC, 'delete', return_value=self.FR()) as delete:
250 5549c0ab Stavros Sachtouris
            cont = 's0m3c0n731n3r'
251 5549c0ab Stavros Sachtouris
            self.client.delete_container(cont)
252 5549c0ab Stavros Sachtouris
            self.FR.status_code = 404
253 5549c0ab Stavros Sachtouris
            self.assertRaises(ClientError, self.client.delete_container, cont)
254 5549c0ab Stavros Sachtouris
            self.FR.status_code = 409
255 5549c0ab Stavros Sachtouris
            self.assertRaises(ClientError, self.client.delete_container, cont)
256 5549c0ab Stavros Sachtouris
            acall = call('/%s/%s' % (user_id, cont), success=(204, 404, 409))
257 5549c0ab Stavros Sachtouris
            self.assertEqual(delete.mock_calls, [acall] * 3)
258 efaa8675 Stavros Sachtouris
259 efaa8675 Stavros Sachtouris
    def test_list_containers(self):
260 efaa8675 Stavros Sachtouris
        self.FR.json = container_list
261 efaa8675 Stavros Sachtouris
        with patch.object(PC, 'account_get', return_value=self.FR()):
262 efaa8675 Stavros Sachtouris
            r = self.client.list_containers()
263 efaa8675 Stavros Sachtouris
            for i in range(len(r)):
264 efaa8675 Stavros Sachtouris
                self.assert_dicts_are_equal(r[i], container_list[i])
265 bcbf3cf0 Stavros Sachtouris
266 bcbf3cf0 Stavros Sachtouris
    def test_upload_object(self):
267 bcbf3cf0 Stavros Sachtouris
        PC.get_container_info = Mock(return_value=container_info)
268 bcbf3cf0 Stavros Sachtouris
        PC.container_post = Mock(return_value=self.FR())
269 bcbf3cf0 Stavros Sachtouris
        PC.object_put = Mock(return_value=self.FR())
270 cb65588d Stavros Sachtouris
        num_of_blocks = 8
271 cb65588d Stavros Sachtouris
        tmpFile = self._create_temp_file(num_of_blocks)
272 cf687343 Stavros Sachtouris
273 2a7292f1 Stavros Sachtouris
        # Without kwargs
274 bcbf3cf0 Stavros Sachtouris
        self.client.upload_object(obj, tmpFile)
275 bcbf3cf0 Stavros Sachtouris
        self.assertEqual(PC.get_container_info.mock_calls, [call()])
276 bcbf3cf0 Stavros Sachtouris
        [call1, call2] = PC.object_put.mock_calls
277 bcbf3cf0 Stavros Sachtouris
278 cf687343 Stavros Sachtouris
        (args1, kwargs1) = call1[1:3]
279 cf687343 Stavros Sachtouris
        (args2, kwargs2) = call2[1:3]
280 cf687343 Stavros Sachtouris
        self.assertEqual(args1, (obj,))
281 cf687343 Stavros Sachtouris
        expected1 = dict(
282 bcbf3cf0 Stavros Sachtouris
            hashmap=True,
283 bcbf3cf0 Stavros Sachtouris
            success=(201, 409),
284 bcbf3cf0 Stavros Sachtouris
            format='json',
285 bcbf3cf0 Stavros Sachtouris
            json=dict(
286 bcbf3cf0 Stavros Sachtouris
                hashes=['s0m3h@5h'] * num_of_blocks,
287 cb65588d Stavros Sachtouris
                bytes=num_of_blocks * 4 * 1024 * 1024),
288 bcbf3cf0 Stavros Sachtouris
            etag=None,
289 bcbf3cf0 Stavros Sachtouris
            content_encoding=None,
290 bcbf3cf0 Stavros Sachtouris
            content_type='application/octet-stream',
291 bcbf3cf0 Stavros Sachtouris
            content_disposition=None,
292 bcbf3cf0 Stavros Sachtouris
            public=None,
293 bcbf3cf0 Stavros Sachtouris
            permissions=None)
294 cf687343 Stavros Sachtouris
        for k, v in expected1.items():
295 cf687343 Stavros Sachtouris
            if k == 'json':
296 cf687343 Stavros Sachtouris
                self.assertEqual(len(v['hashes']), len(kwargs1[k]['hashes']))
297 cf687343 Stavros Sachtouris
                self.assertEqual(v['bytes'], kwargs1[k]['bytes'])
298 cf687343 Stavros Sachtouris
            else:
299 cf687343 Stavros Sachtouris
                self.assertEqual(v, kwargs1[k])
300 cf687343 Stavros Sachtouris
301 cf687343 Stavros Sachtouris
        (args2, kwargs2) = call2[1:3]
302 cf687343 Stavros Sachtouris
        self.assertEqual(args2, (obj,))
303 cf687343 Stavros Sachtouris
        expected2 = dict(
304 cf687343 Stavros Sachtouris
            json=dict(
305 cf687343 Stavros Sachtouris
                hashes=['s0m3h@5h'] * num_of_blocks,
306 cb65588d Stavros Sachtouris
                bytes=num_of_blocks * 4 * 1024 * 1024),
307 cf687343 Stavros Sachtouris
            content_type='application/octet-stream',
308 cf687343 Stavros Sachtouris
            hashmap=True,
309 cf687343 Stavros Sachtouris
            success=201,
310 cf687343 Stavros Sachtouris
            format='json')
311 cf687343 Stavros Sachtouris
        for k, v in expected2.items():
312 bcbf3cf0 Stavros Sachtouris
            if k == 'json':
313 cf687343 Stavros Sachtouris
                self.assertEqual(len(v['hashes']), len(kwargs2[k]['hashes']))
314 cf687343 Stavros Sachtouris
                self.assertEqual(v['bytes'], kwargs2[k]['bytes'])
315 bcbf3cf0 Stavros Sachtouris
            else:
316 cf687343 Stavros Sachtouris
                self.assertEqual(v, kwargs2[k])
317 cf687343 Stavros Sachtouris
318 cf687343 Stavros Sachtouris
        OP = PC.object_put
319 cf687343 Stavros Sachtouris
        mock_offset = 2
320 cf687343 Stavros Sachtouris
321 cf687343 Stavros Sachtouris
        #  With progress bars
322 cf687343 Stavros Sachtouris
        try:
323 cf687343 Stavros Sachtouris
            from progress.bar import ShadyBar
324 cf687343 Stavros Sachtouris
            blck_bar = ShadyBar('Mock blck calc.')
325 cf687343 Stavros Sachtouris
            upld_bar = ShadyBar('Mock uplds')
326 cf687343 Stavros Sachtouris
        except ImportError:
327 cf687343 Stavros Sachtouris
            blck_bar = None
328 cf687343 Stavros Sachtouris
            upld_bar = None
329 cf687343 Stavros Sachtouris
330 cf687343 Stavros Sachtouris
        if blck_bar and upld_bar:
331 cf687343 Stavros Sachtouris
332 cf687343 Stavros Sachtouris
            def blck_gen(n):
333 cf687343 Stavros Sachtouris
                for i in blck_bar.iter(range(n)):
334 cf687343 Stavros Sachtouris
                    yield
335 cf687343 Stavros Sachtouris
                yield
336 cf687343 Stavros Sachtouris
337 cf687343 Stavros Sachtouris
            def upld_gen(n):
338 cf687343 Stavros Sachtouris
                for i in upld_bar.iter(range(n)):
339 cf687343 Stavros Sachtouris
                    yield
340 cf687343 Stavros Sachtouris
                yield
341 cf687343 Stavros Sachtouris
342 cf687343 Stavros Sachtouris
            tmpFile.seek(0)
343 cf687343 Stavros Sachtouris
            self.client.upload_object(
344 cf687343 Stavros Sachtouris
                obj, tmpFile,
345 cf687343 Stavros Sachtouris
                hash_cb=blck_gen, upload_cb=upld_gen)
346 cf687343 Stavros Sachtouris
347 cf687343 Stavros Sachtouris
            for i, c in enumerate(OP.mock_calls[-mock_offset:]):
348 cf687343 Stavros Sachtouris
                self.assertEqual(OP.mock_calls[i], c)
349 cf687343 Stavros Sachtouris
350 cf687343 Stavros Sachtouris
        #  With content-type
351 cf687343 Stavros Sachtouris
        tmpFile.seek(0)
352 cf687343 Stavros Sachtouris
        ctype = 'video/mpeg'
353 cf687343 Stavros Sachtouris
        sharing = dict(read=['u1', 'g1', 'u2'], write=['u1'])
354 cf687343 Stavros Sachtouris
        self.client.upload_object(obj, tmpFile,
355 cf687343 Stavros Sachtouris
            content_type=ctype, sharing=sharing)
356 cf687343 Stavros Sachtouris
        self.assertEqual(OP.mock_calls[-1][2]['content_type'], ctype)
357 cf687343 Stavros Sachtouris
        self.assert_dicts_are_equal(
358 cf687343 Stavros Sachtouris
            OP.mock_calls[-2][2]['permissions'],
359 cf687343 Stavros Sachtouris
            sharing)
360 cf687343 Stavros Sachtouris
361 cf687343 Stavros Sachtouris
        # With other args
362 cf687343 Stavros Sachtouris
        tmpFile.seek(0)
363 cf687343 Stavros Sachtouris
        kwargs = dict(
364 cf687343 Stavros Sachtouris
            etag='s0m3E74g',
365 cf687343 Stavros Sachtouris
            content_type=ctype,
366 cf687343 Stavros Sachtouris
            content_disposition=ctype + 'd15p051710n',
367 cf687343 Stavros Sachtouris
            public=True,
368 cf687343 Stavros Sachtouris
            content_encoding='802.11')
369 cf687343 Stavros Sachtouris
        self.client.upload_object(obj, tmpFile, **kwargs)
370 cf687343 Stavros Sachtouris
        for arg, val in kwargs.items():
371 cf687343 Stavros Sachtouris
            self.assertEqual(OP.mock_calls[-2][2][arg], val)
372 b4780663 Stavros Sachtouris
373 b4780663 Stavros Sachtouris
    def test_create_object(self):
374 bd3a524f Stavros Sachtouris
        PC.set_header = Mock()
375 b4780663 Stavros Sachtouris
        cont = self.client.container
376 b4780663 Stavros Sachtouris
        ctype = 'c0n73n7/typ3'
377 b4780663 Stavros Sachtouris
        exp_shd = [
378 b4780663 Stavros Sachtouris
            call('Content-Type', 'application/octet-stream'),
379 b4780663 Stavros Sachtouris
            call('Content-length', '0'),
380 b4780663 Stavros Sachtouris
            call('Content-Type', ctype), call('Content-length', '42')]
381 b4780663 Stavros Sachtouris
        exp_put = [call('/%s/%s/%s' % (user_id, cont, obj), success=201)] * 2
382 b4780663 Stavros Sachtouris
        with patch.object(PC, 'put', return_value=self.FR()) as put:
383 b4780663 Stavros Sachtouris
            self.client.create_object(obj)
384 b4780663 Stavros Sachtouris
            self.client.create_object(obj,
385 b4780663 Stavros Sachtouris
                content_type=ctype, content_length=42)
386 b4780663 Stavros Sachtouris
            self.assertEqual(PC.set_header.mock_calls, exp_shd)
387 b4780663 Stavros Sachtouris
            self.assertEqual(put.mock_calls, exp_put)
388 4227e4be Stavros Sachtouris
389 4227e4be Stavros Sachtouris
    def test_create_directory(self):
390 bd3a524f Stavros Sachtouris
        PC.set_header = Mock()
391 4227e4be Stavros Sachtouris
        cont = self.client.container
392 4227e4be Stavros Sachtouris
        exp_shd = [
393 4227e4be Stavros Sachtouris
            call('Content-Type', 'application/directory'),
394 4227e4be Stavros Sachtouris
            call('Content-length', '0')]
395 4227e4be Stavros Sachtouris
        exp_put = [call('/%s/%s/%s' % (user_id, cont, obj), success=201)]
396 4227e4be Stavros Sachtouris
        with patch.object(PC, 'put', return_value=self.FR()) as put:
397 4227e4be Stavros Sachtouris
            self.client.create_directory(obj)
398 4227e4be Stavros Sachtouris
            self.assertEqual(PC.set_header.mock_calls, exp_shd)
399 4227e4be Stavros Sachtouris
            self.assertEqual(put.mock_calls, exp_put)
400 723e9d47 Stavros Sachtouris
401 723e9d47 Stavros Sachtouris
    def test_get_object_info(self):
402 723e9d47 Stavros Sachtouris
        self.FR.headers = object_info
403 723e9d47 Stavros Sachtouris
        version = 'v3r510n'
404 723e9d47 Stavros Sachtouris
        with patch.object(PC, 'object_head', return_value=self.FR()) as head:
405 723e9d47 Stavros Sachtouris
            r = self.client.get_object_info(obj)
406 723e9d47 Stavros Sachtouris
            self.assertEqual(r, object_info)
407 723e9d47 Stavros Sachtouris
            r = self.client.get_object_info(obj, version=version)
408 723e9d47 Stavros Sachtouris
            self.assertEqual(head.mock_calls, [
409 723e9d47 Stavros Sachtouris
                call(obj, version=None),
410 723e9d47 Stavros Sachtouris
                call(obj, version=version)])
411 723e9d47 Stavros Sachtouris
        with patch.object(
412 723e9d47 Stavros Sachtouris
                PC,
413 723e9d47 Stavros Sachtouris
                'object_head',
414 723e9d47 Stavros Sachtouris
                side_effect=ClientError('Obj not found', 404)):
415 723e9d47 Stavros Sachtouris
            self.assertRaises(
416 723e9d47 Stavros Sachtouris
                ClientError,
417 723e9d47 Stavros Sachtouris
                self.client.get_object_info,
418 723e9d47 Stavros Sachtouris
                obj, version=version)
419 3e2e07be Stavros Sachtouris
420 3e2e07be Stavros Sachtouris
    def test_get_object_meta(self):
421 3e2e07be Stavros Sachtouris
        expected = dict()
422 3e2e07be Stavros Sachtouris
        for k, v in object_info.items():
423 3e2e07be Stavros Sachtouris
            expected[k] = v
424 3e2e07be Stavros Sachtouris
        with patch.object(
425 3e2e07be Stavros Sachtouris
                PC,
426 3e2e07be Stavros Sachtouris
                'get_object_info',
427 3e2e07be Stavros Sachtouris
                return_value=object_info):
428 3e2e07be Stavros Sachtouris
            r = self.client.get_object_meta(obj)
429 3e2e07be Stavros Sachtouris
            self.assert_dicts_are_equal(r, expected)
430 da1597b9 Stavros Sachtouris
431 da1597b9 Stavros Sachtouris
    def test_del_object_meta(self):
432 da1597b9 Stavros Sachtouris
        metakey = '50m3m3t4k3y'
433 da1597b9 Stavros Sachtouris
        with patch.object(PC, 'object_post', return_value=self.FR()) as post:
434 da1597b9 Stavros Sachtouris
            self.client.del_object_meta(obj, metakey)
435 da1597b9 Stavros Sachtouris
            self.assertEqual(
436 da1597b9 Stavros Sachtouris
                post.mock_calls,
437 da1597b9 Stavros Sachtouris
                [call(obj, update=True, metadata={metakey: ''})])
438 bd3a524f Stavros Sachtouris
439 bd3a524f Stavros Sachtouris
    def test_replace_object_meta(self):
440 bd3a524f Stavros Sachtouris
        PC.set_header = Mock()
441 bd3a524f Stavros Sachtouris
        metas = dict(k1='new1', k2='new2', k3='new3')
442 bd3a524f Stavros Sachtouris
        cont = self.client.container
443 bd3a524f Stavros Sachtouris
        with patch.object(PC, 'post', return_value=self.FR()) as post:
444 bd3a524f Stavros Sachtouris
            self.client.replace_object_meta(metas)
445 bd3a524f Stavros Sachtouris
            self.assertEqual(post.mock_calls, [
446 bd3a524f Stavros Sachtouris
                call('/%s/%s' % (user_id, cont),
447 bd3a524f Stavros Sachtouris
                success=202)])
448 bd3a524f Stavros Sachtouris
            prfx = 'X-Object-Meta-'
449 bd3a524f Stavros Sachtouris
            expected = [call('%s%s' % (prfx, k), v) for k, v in metas.items()]
450 bd3a524f Stavros Sachtouris
            self.assertEqual(PC.set_header.mock_calls, expected)
451 33487500 Stavros Sachtouris
452 33487500 Stavros Sachtouris
    def test_copy_object(self):
453 33487500 Stavros Sachtouris
        src_cont = 'src-c0nt41n3r'
454 33487500 Stavros Sachtouris
        src_obj = 'src-0bj'
455 33487500 Stavros Sachtouris
        dst_cont = 'dst-c0nt41n3r'
456 33487500 Stavros Sachtouris
        dst_obj = 'dst-0bj'
457 33487500 Stavros Sachtouris
        expected = call(
458 33487500 Stavros Sachtouris
            src_obj,
459 33487500 Stavros Sachtouris
            content_length=0,
460 33487500 Stavros Sachtouris
            source_account=None,
461 33487500 Stavros Sachtouris
            success=201,
462 33487500 Stavros Sachtouris
            copy_from='/%s/%s' % (src_cont, src_obj),
463 33487500 Stavros Sachtouris
            delimiter=None,
464 33487500 Stavros Sachtouris
            content_type=None,
465 33487500 Stavros Sachtouris
            source_version=None,
466 33487500 Stavros Sachtouris
            public=False)
467 33487500 Stavros Sachtouris
        with patch.object(PC, 'object_put', return_value=self.FR()) as put:
468 33487500 Stavros Sachtouris
            self.client.copy_object(src_cont, src_obj, dst_cont)
469 33487500 Stavros Sachtouris
            self.assertEqual(put.mock_calls[-1], expected)
470 33487500 Stavros Sachtouris
            self.client.copy_object(src_cont, src_obj, dst_cont, dst_obj)
471 33487500 Stavros Sachtouris
            self.assertEqual(put.mock_calls[-1][1], (dst_obj,))
472 33487500 Stavros Sachtouris
            kwargs = dict(
473 33487500 Stavros Sachtouris
                source_version='src-v3r510n',
474 33487500 Stavros Sachtouris
                source_account='src-4cc0un7',
475 33487500 Stavros Sachtouris
                public=True,
476 33487500 Stavros Sachtouris
                content_type='c0n73n7Typ3',
477 33487500 Stavros Sachtouris
                delimiter='5')
478 33487500 Stavros Sachtouris
            self.client.copy_object(src_cont, src_obj, dst_cont, **kwargs)
479 33487500 Stavros Sachtouris
            for k, v in kwargs.items():
480 33487500 Stavros Sachtouris
                self.assertEqual(v, put.mock_calls[-1][2][k])
481 898e6fb7 Stavros Sachtouris
482 898e6fb7 Stavros Sachtouris
    def test_move_object(self):
483 898e6fb7 Stavros Sachtouris
        src_cont = 'src-c0nt41n3r'
484 898e6fb7 Stavros Sachtouris
        src_obj = 'src-0bj'
485 898e6fb7 Stavros Sachtouris
        dst_cont = 'dst-c0nt41n3r'
486 898e6fb7 Stavros Sachtouris
        dst_obj = 'dst-0bj'
487 898e6fb7 Stavros Sachtouris
        expected = call(
488 898e6fb7 Stavros Sachtouris
            src_obj,
489 898e6fb7 Stavros Sachtouris
            content_length=0,
490 898e6fb7 Stavros Sachtouris
            source_account=None,
491 898e6fb7 Stavros Sachtouris
            success=201,
492 898e6fb7 Stavros Sachtouris
            move_from='/%s/%s' % (src_cont, src_obj),
493 898e6fb7 Stavros Sachtouris
            delimiter=None,
494 898e6fb7 Stavros Sachtouris
            content_type=None,
495 898e6fb7 Stavros Sachtouris
            source_version=None,
496 898e6fb7 Stavros Sachtouris
            public=False)
497 898e6fb7 Stavros Sachtouris
        with patch.object(PC, 'object_put', return_value=self.FR()) as put:
498 898e6fb7 Stavros Sachtouris
            self.client.move_object(src_cont, src_obj, dst_cont)
499 898e6fb7 Stavros Sachtouris
            self.assertEqual(put.mock_calls[-1], expected)
500 898e6fb7 Stavros Sachtouris
            self.client.move_object(src_cont, src_obj, dst_cont, dst_obj)
501 898e6fb7 Stavros Sachtouris
            self.assertEqual(put.mock_calls[-1][1], (dst_obj,))
502 898e6fb7 Stavros Sachtouris
            kwargs = dict(
503 898e6fb7 Stavros Sachtouris
                source_version='src-v3r510n',
504 898e6fb7 Stavros Sachtouris
                source_account='src-4cc0un7',
505 898e6fb7 Stavros Sachtouris
                public=True,
506 898e6fb7 Stavros Sachtouris
                content_type='c0n73n7Typ3',
507 898e6fb7 Stavros Sachtouris
                delimiter='5')
508 898e6fb7 Stavros Sachtouris
            self.client.move_object(src_cont, src_obj, dst_cont, **kwargs)
509 898e6fb7 Stavros Sachtouris
            for k, v in kwargs.items():
510 898e6fb7 Stavros Sachtouris
                self.assertEqual(v, put.mock_calls[-1][2][k])
511 39c737d4 Stavros Sachtouris
512 39c737d4 Stavros Sachtouris
    def test_delete_object(self):
513 39c737d4 Stavros Sachtouris
        cont = self.client.container
514 39c737d4 Stavros Sachtouris
        with patch.object(PC, 'delete', return_value=self.FR()) as delete:
515 39c737d4 Stavros Sachtouris
            self.client.delete_object(obj)
516 39c737d4 Stavros Sachtouris
            self.assertEqual(delete.mock_calls, [
517 39c737d4 Stavros Sachtouris
                call('/%s/%s/%s' % (user_id, cont, obj), success=(204, 404))])
518 39c737d4 Stavros Sachtouris
            self.FR.status_code = 404
519 39c737d4 Stavros Sachtouris
            self.assertRaises(ClientError, self.client.delete_object, obj)
520 39c737d4 Stavros Sachtouris
521 39c737d4 Stavros Sachtouris
    def test_list_objects(self):
522 39c737d4 Stavros Sachtouris
        self.FR.json = object_list
523 39c737d4 Stavros Sachtouris
        acc = self.client.account
524 39c737d4 Stavros Sachtouris
        cont = self.client.container
525 39c737d4 Stavros Sachtouris
        PC.set_param = Mock()
526 39c737d4 Stavros Sachtouris
        SP = PC.set_param
527 39c737d4 Stavros Sachtouris
        with patch.object(PC, 'get', return_value=self.FR()) as get:
528 39c737d4 Stavros Sachtouris
            r = self.client.list_objects()
529 39c737d4 Stavros Sachtouris
            for i in range(len(r)):
530 39c737d4 Stavros Sachtouris
                self.assert_dicts_are_equal(r[i], object_list[i])
531 39c737d4 Stavros Sachtouris
            self.assertEqual(get.mock_calls, [
532 39c737d4 Stavros Sachtouris
                call('/%s/%s' % (acc, cont), success=(200, 204, 304, 404))])
533 39c737d4 Stavros Sachtouris
            self.assertEqual(SP.mock_calls, [call('format', 'json')])
534 39c737d4 Stavros Sachtouris
            self.FR.status_code = 304
535 39c737d4 Stavros Sachtouris
            self.assertEqual(self.client.list_objects(), [])
536 39c737d4 Stavros Sachtouris
            self.FR.status_code = 404
537 39c737d4 Stavros Sachtouris
            self.assertRaises(ClientError, self.client.list_objects)
538 5ffdab56 Stavros Sachtouris
539 5ffdab56 Stavros Sachtouris
    def test_list_objects_in_path(self):
540 5ffdab56 Stavros Sachtouris
        self.FR.json = object_list
541 5ffdab56 Stavros Sachtouris
        path = '/some/awsome/path'
542 5ffdab56 Stavros Sachtouris
        acc = self.client.account
543 5ffdab56 Stavros Sachtouris
        cont = self.client.container
544 5ffdab56 Stavros Sachtouris
        PC.set_param = Mock()
545 5ffdab56 Stavros Sachtouris
        SP = PC.set_param
546 5ffdab56 Stavros Sachtouris
        with patch.object(PC, 'get', return_value=self.FR()) as get:
547 5ffdab56 Stavros Sachtouris
            self.client.list_objects_in_path(path)
548 5ffdab56 Stavros Sachtouris
            self.assertEqual(get.mock_calls, [
549 5ffdab56 Stavros Sachtouris
                call('/%s/%s' % (acc, cont), success=(200, 204, 404))])
550 5ffdab56 Stavros Sachtouris
            self.assertEqual(SP.mock_calls, [
551 5ffdab56 Stavros Sachtouris
                call('format', 'json'), call('path', path)])
552 5ffdab56 Stavros Sachtouris
            self.FR.status_code = 404
553 5ffdab56 Stavros Sachtouris
            self.assertRaises(ClientError, self.client.list_objects)
554 2a7292f1 Stavros Sachtouris
555 2a7292f1 Stavros Sachtouris
    #  Pithos+ only methods
556 2a7292f1 Stavros Sachtouris
557 2a7292f1 Stavros Sachtouris
    def test_purge_container(self):
558 2a7292f1 Stavros Sachtouris
        with patch.object(
559 2a7292f1 Stavros Sachtouris
                PC,
560 2a7292f1 Stavros Sachtouris
                'container_delete',
561 2a7292f1 Stavros Sachtouris
                return_value=self.FR()) as cd:
562 2a7292f1 Stavros Sachtouris
            self.client.purge_container()
563 2a7292f1 Stavros Sachtouris
            self.assertTrue('until' in cd.mock_calls[-1][2])
564 2a7292f1 Stavros Sachtouris
            cont = self.client.container
565 2a7292f1 Stavros Sachtouris
            self.client.purge_container('another-container')
566 2a7292f1 Stavros Sachtouris
            self.assertEqual(self.client.container, cont)
567 2a7292f1 Stavros Sachtouris
568 2a7292f1 Stavros Sachtouris
    def test_upload_object_unchunked(self):
569 cb65588d Stavros Sachtouris
        num_of_blocks = 8
570 cb65588d Stavros Sachtouris
        tmpFile = self._create_temp_file(num_of_blocks)
571 2a7292f1 Stavros Sachtouris
        expected = dict(
572 2a7292f1 Stavros Sachtouris
                success=201,
573 cb65588d Stavros Sachtouris
                data=num_of_blocks * 4 * 1024 * 1024,
574 2a7292f1 Stavros Sachtouris
                etag='some-etag',
575 2a7292f1 Stavros Sachtouris
                content_encoding='some content_encoding',
576 2a7292f1 Stavros Sachtouris
                content_type='some content-type',
577 2a7292f1 Stavros Sachtouris
                content_disposition='some content_disposition',
578 2a7292f1 Stavros Sachtouris
                public=True,
579 2a7292f1 Stavros Sachtouris
                permissions=dict(read=['u1', 'g1', 'u2'], write=['u1']))
580 2a7292f1 Stavros Sachtouris
        with patch.object(PC, 'object_put', return_value=self.FR()) as put:
581 2a7292f1 Stavros Sachtouris
            self.client.upload_object_unchunked(obj, tmpFile)
582 2a7292f1 Stavros Sachtouris
            self.assertEqual(put.mock_calls[-1][1], (obj,))
583 2a7292f1 Stavros Sachtouris
            self.assertEqual(
584 2a7292f1 Stavros Sachtouris
                sorted(put.mock_calls[-1][2].keys()),
585 2a7292f1 Stavros Sachtouris
                sorted(expected.keys()))
586 2a7292f1 Stavros Sachtouris
            kwargs = dict(expected)
587 2a7292f1 Stavros Sachtouris
            kwargs.pop('success')
588 2a7292f1 Stavros Sachtouris
            kwargs['size'] = kwargs.pop('data')
589 2a7292f1 Stavros Sachtouris
            kwargs['sharing'] = kwargs.pop('permissions')
590 2a7292f1 Stavros Sachtouris
            tmpFile.seek(0)
591 2a7292f1 Stavros Sachtouris
            self.client.upload_object_unchunked(obj, tmpFile, **kwargs)
592 2a7292f1 Stavros Sachtouris
            pmc = put.mock_calls[-1][2]
593 2a7292f1 Stavros Sachtouris
            for k, v in expected.items():
594 2a7292f1 Stavros Sachtouris
                if k == 'data':
595 2a7292f1 Stavros Sachtouris
                    self.assertEqual(len(pmc[k]), v)
596 2a7292f1 Stavros Sachtouris
                else:
597 2a7292f1 Stavros Sachtouris
                    self.assertEqual(pmc[k], v)
598 e82edbb0 Stavros Sachtouris
            self.assertRaises(
599 e82edbb0 Stavros Sachtouris
                ClientError,
600 e82edbb0 Stavros Sachtouris
                self.client.upload_object_unchunked,
601 e82edbb0 Stavros Sachtouris
                obj, tmpFile, withHashFile=True)
602 e82edbb0 Stavros Sachtouris
603 e82edbb0 Stavros Sachtouris
    def test_create_object_by_manifestation(self):
604 e82edbb0 Stavros Sachtouris
        manifest = '%s/%s' % (self.client.container, obj)
605 e82edbb0 Stavros Sachtouris
        kwargs = dict(
606 e82edbb0 Stavros Sachtouris
                etag='some-etag',
607 e82edbb0 Stavros Sachtouris
                content_encoding='some content_encoding',
608 e82edbb0 Stavros Sachtouris
                content_type='some content-type',
609 e82edbb0 Stavros Sachtouris
                content_disposition='some content_disposition',
610 e82edbb0 Stavros Sachtouris
                public=True,
611 e82edbb0 Stavros Sachtouris
                sharing=dict(read=['u1', 'g1', 'u2'], write=['u1']))
612 e82edbb0 Stavros Sachtouris
        with patch.object(PC, 'object_put', return_value=self.FR()) as put:
613 e82edbb0 Stavros Sachtouris
            self.client.create_object_by_manifestation(obj)
614 e82edbb0 Stavros Sachtouris
            expected = dict(content_length=0, manifest=manifest)
615 e82edbb0 Stavros Sachtouris
            for k in kwargs:
616 e82edbb0 Stavros Sachtouris
                expected['permissions' if k == 'sharing' else k] = None
617 e82edbb0 Stavros Sachtouris
            self.assertEqual(put.mock_calls[-1], call(obj, **expected))
618 e82edbb0 Stavros Sachtouris
            self.client.create_object_by_manifestation(obj, **kwargs)
619 e82edbb0 Stavros Sachtouris
            expected.update(kwargs)
620 e82edbb0 Stavros Sachtouris
            expected['permissions'] = expected.pop('sharing')
621 e82edbb0 Stavros Sachtouris
            self.assertEqual(put.mock_calls[-1], call(obj, **expected))
622 b4e29772 Stavros Sachtouris
623 b4e29772 Stavros Sachtouris
    def test_download_object(self):
624 b4e29772 Stavros Sachtouris
        PC.get_object_hashmap = Mock(return_value=object_hashmap)
625 cb65588d Stavros Sachtouris
        num_of_blocks = 8
626 cb65588d Stavros Sachtouris
        tmpFile = self._create_temp_file(num_of_blocks)
627 b4e29772 Stavros Sachtouris
        self.FR.content = tmpFile.read(4 * 1024 * 1024)
628 cb65588d Stavros Sachtouris
        tmpFile = self._create_temp_file(num_of_blocks)
629 b4e29772 Stavros Sachtouris
        PC.object_get = Mock(return_value=self.FR())
630 b4e29772 Stavros Sachtouris
        GET = PC.object_get
631 b4e29772 Stavros Sachtouris
        num_of_blocks = len(object_hashmap['hashes'])
632 b4e29772 Stavros Sachtouris
633 b4e29772 Stavros Sachtouris
        kwargs = dict(
634 b4e29772 Stavros Sachtouris
            resume=True,
635 cb65588d Stavros Sachtouris
            version='version',
636 b4e29772 Stavros Sachtouris
            range_str='10-20',
637 b4e29772 Stavros Sachtouris
            if_match='if and only if',
638 b4e29772 Stavros Sachtouris
            if_none_match='if and only not',
639 b4e29772 Stavros Sachtouris
            if_modified_since='what if not?',
640 b4e29772 Stavros Sachtouris
            if_unmodified_since='this happens if not!',
641 b4e29772 Stavros Sachtouris
            async_headers=dict(Range='bytes=0-88888888'))
642 b4e29772 Stavros Sachtouris
643 b4e29772 Stavros Sachtouris
        self.client.download_object(obj, tmpFile)
644 b4e29772 Stavros Sachtouris
        self.assertEqual(len(GET.mock_calls), num_of_blocks)
645 b4e29772 Stavros Sachtouris
        self.assertEqual(GET.mock_calls[-1][1], (obj,))
646 b4e29772 Stavros Sachtouris
        for k, v in kwargs.items():
647 b4e29772 Stavros Sachtouris
            if k == 'async_headers':
648 b4e29772 Stavros Sachtouris
                self.assertTrue('Range' in GET.mock_calls[-1][2][k])
649 b4e29772 Stavros Sachtouris
            elif k in ('resume', 'range_str'):
650 b4e29772 Stavros Sachtouris
                continue
651 b4e29772 Stavros Sachtouris
            else:
652 b4e29772 Stavros Sachtouris
                self.assertEqual(GET.mock_calls[-1][2][k], None)
653 b4e29772 Stavros Sachtouris
654 b4e29772 Stavros Sachtouris
        #  Check ranges are consecutive
655 b4e29772 Stavros Sachtouris
        starts = []
656 b4e29772 Stavros Sachtouris
        ends = []
657 b4e29772 Stavros Sachtouris
        for c in GET.mock_calls:
658 b4e29772 Stavros Sachtouris
            rng_str = c[2]['async_headers']['Range']
659 b4e29772 Stavros Sachtouris
            (start, rng_str) = rng_str.split('=')
660 b4e29772 Stavros Sachtouris
            (start, end) = rng_str.split('-')
661 b4e29772 Stavros Sachtouris
            starts.append(start)
662 b4e29772 Stavros Sachtouris
            ends.append(end)
663 b4e29772 Stavros Sachtouris
        ends = sorted(ends)
664 b4e29772 Stavros Sachtouris
        for i, start in enumerate(sorted(starts)):
665 b4e29772 Stavros Sachtouris
            if i:
666 b4e29772 Stavros Sachtouris
                int(ends[i - 1]) == int(start) - 1
667 b4e29772 Stavros Sachtouris
668 b4e29772 Stavros Sachtouris
        #  With progress bars
669 b4e29772 Stavros Sachtouris
        try:
670 b4e29772 Stavros Sachtouris
            from progress.bar import ShadyBar
671 b4e29772 Stavros Sachtouris
            dl_bar = ShadyBar('Mock dl')
672 b4e29772 Stavros Sachtouris
        except ImportError:
673 b4e29772 Stavros Sachtouris
            dl_bar = None
674 b4e29772 Stavros Sachtouris
675 b4e29772 Stavros Sachtouris
        if dl_bar:
676 b4e29772 Stavros Sachtouris
677 b4e29772 Stavros Sachtouris
            def blck_gen(n):
678 b4e29772 Stavros Sachtouris
                for i in dl_bar.iter(range(n)):
679 b4e29772 Stavros Sachtouris
                    yield
680 b4e29772 Stavros Sachtouris
                yield
681 b4e29772 Stavros Sachtouris
682 b4e29772 Stavros Sachtouris
            tmpFile.seek(0)
683 b4e29772 Stavros Sachtouris
            self.client.download_object(obj, tmpFile, download_cb=blck_gen)
684 b4e29772 Stavros Sachtouris
            self.assertEqual(len(GET.mock_calls), 2 * num_of_blocks)
685 b4e29772 Stavros Sachtouris
686 b4e29772 Stavros Sachtouris
        tmpFile.seek(0)
687 b4e29772 Stavros Sachtouris
        kwargs.pop('async_headers')
688 b4e29772 Stavros Sachtouris
        kwargs.pop('resume')
689 b4e29772 Stavros Sachtouris
        self.client.download_object(obj, tmpFile, **kwargs)
690 b4e29772 Stavros Sachtouris
        for k, v in kwargs.items():
691 b4e29772 Stavros Sachtouris
            if k == 'range_str':
692 b4e29772 Stavros Sachtouris
                self.assertEqual(
693 b4e29772 Stavros Sachtouris
                    GET.mock_calls[-1][2]['data_range'],
694 b4e29772 Stavros Sachtouris
                    'bytes=%s' % v)
695 b4e29772 Stavros Sachtouris
            else:
696 b4e29772 Stavros Sachtouris
                self.assertEqual(GET.mock_calls[-1][2][k], v)
697 b4e29772 Stavros Sachtouris
698 b4e29772 Stavros Sachtouris
        #  ALl options on no tty
699 b4e29772 Stavros Sachtouris
700 b4e29772 Stavros Sachtouris
        def foo():
701 b4e29772 Stavros Sachtouris
            return True
702 b4e29772 Stavros Sachtouris
703 b4e29772 Stavros Sachtouris
        tmpFile.seek(0)
704 b4e29772 Stavros Sachtouris
        tmpFile.isatty = foo
705 b4e29772 Stavros Sachtouris
        self.client.download_object(obj, tmpFile, **kwargs)
706 b4e29772 Stavros Sachtouris
        for k, v in kwargs.items():
707 b4e29772 Stavros Sachtouris
            if k == 'range_str':
708 b4e29772 Stavros Sachtouris
                self.assertTrue('data_range' in GET.mock_calls[-1][2])
709 b4e29772 Stavros Sachtouris
            else:
710 b4e29772 Stavros Sachtouris
                self.assertEqual(GET.mock_calls[-1][2][k], v)
711 cb65588d Stavros Sachtouris
712 cb65588d Stavros Sachtouris
    def test_get_object_hashmap(self):
713 cb65588d Stavros Sachtouris
        self.FR.json = object_hashmap
714 cb65588d Stavros Sachtouris
        for empty in (304, 412):
715 cb65588d Stavros Sachtouris
            with patch.object(
716 cb65588d Stavros Sachtouris
                    PC, 'object_get',
717 cb65588d Stavros Sachtouris
                    side_effect=ClientError('Empty', status=empty)):
718 cb65588d Stavros Sachtouris
                r = self.client.get_object_hashmap(obj)
719 cb65588d Stavros Sachtouris
                self.assertEqual(r, {})
720 cb65588d Stavros Sachtouris
        exp_args = dict(
721 cb65588d Stavros Sachtouris
            hashmap=True,
722 cb65588d Stavros Sachtouris
            data_range=None,
723 cb65588d Stavros Sachtouris
            version=None,
724 cb65588d Stavros Sachtouris
            if_etag_match=None,
725 cb65588d Stavros Sachtouris
            if_etag_not_match=None,
726 cb65588d Stavros Sachtouris
            if_modified_since=None,
727 cb65588d Stavros Sachtouris
            if_unmodified_since=None)
728 cb65588d Stavros Sachtouris
        kwargs = dict(
729 cb65588d Stavros Sachtouris
            version='s0m3v3r51on',
730 cb65588d Stavros Sachtouris
            if_match='if match',
731 cb65588d Stavros Sachtouris
            if_none_match='if non match',
732 cb65588d Stavros Sachtouris
            if_modified_since='some date here',
733 cb65588d Stavros Sachtouris
            if_unmodified_since='some date here',
734 cb65588d Stavros Sachtouris
            data_range='10-20')
735 cb65588d Stavros Sachtouris
        with patch.object(PC, 'object_get', return_value=self.FR()) as get:
736 cb65588d Stavros Sachtouris
            r = self.client.get_object_hashmap(obj)
737 cb65588d Stavros Sachtouris
            self.assertEqual(r, object_hashmap)
738 cb65588d Stavros Sachtouris
            self.assertEqual(get.mock_calls[-1], call(obj, **exp_args))
739 cb65588d Stavros Sachtouris
            r = self.client.get_object_hashmap(obj, **kwargs)
740 cb65588d Stavros Sachtouris
            exp_args['if_etag_match'] = kwargs.pop('if_match')
741 cb65588d Stavros Sachtouris
            exp_args['if_etag_not_match'] = kwargs.pop('if_none_match')
742 cb65588d Stavros Sachtouris
            exp_args.update(kwargs)
743 cb65588d Stavros Sachtouris
            self.assertEqual(get.mock_calls[-1], call(obj, **exp_args))
744 8b71426c Stavros Sachtouris
745 8b71426c Stavros Sachtouris
    def test_set_account_group(self):
746 8b71426c Stavros Sachtouris
        group = 'aU53rGr0up'
747 8b71426c Stavros Sachtouris
        usernames = ['u1', 'u2', 'u3']
748 8b71426c Stavros Sachtouris
        with patch.object(PC, 'account_post', return_value=self.FR()) as post:
749 8b71426c Stavros Sachtouris
            self.client.set_account_group(group, usernames)
750 8b71426c Stavros Sachtouris
            self.assertEqual(
751 8b71426c Stavros Sachtouris
                post.mock_calls[-1],
752 8b71426c Stavros Sachtouris
                call(update=True, groups={group: usernames}))
753 419fa6c4 Stavros Sachtouris
754 419fa6c4 Stavros Sachtouris
    def test_del_account_group(self):
755 419fa6c4 Stavros Sachtouris
        group = 'aU53rGr0up'
756 419fa6c4 Stavros Sachtouris
        with patch.object(PC, 'account_post', return_value=self.FR()) as post:
757 419fa6c4 Stavros Sachtouris
            self.client.del_account_group(group)
758 419fa6c4 Stavros Sachtouris
            self.assertEqual(
759 419fa6c4 Stavros Sachtouris
                post.mock_calls[-1],
760 419fa6c4 Stavros Sachtouris
                call(update=True, groups={group: []}))
761 34f48ce0 Stavros Sachtouris
762 34f48ce0 Stavros Sachtouris
    def test_get_account_quota(self):
763 34f48ce0 Stavros Sachtouris
        key = 'x-account-policy-quota'
764 34f48ce0 Stavros Sachtouris
        with patch.object(PC, 'get_account_info', return_value=account_info):
765 34f48ce0 Stavros Sachtouris
            r = self.client.get_account_quota()
766 34f48ce0 Stavros Sachtouris
            self.assertEqual(r[key], account_info[key])
767 16b77981 Stavros Sachtouris
768 16b77981 Stavros Sachtouris
    def test_get_account_versioning(self):
769 16b77981 Stavros Sachtouris
        key = 'x-account-policy-versioning'
770 16b77981 Stavros Sachtouris
        with patch.object(PC, 'get_account_info', return_value=account_info):
771 16b77981 Stavros Sachtouris
            r = self.client.get_account_versioning()
772 16b77981 Stavros Sachtouris
            self.assertEqual(r[key], account_info[key])
773 de27950a Stavros Sachtouris
774 de27950a Stavros Sachtouris
    def test_get_account_meta(self):
775 de27950a Stavros Sachtouris
        key = 'x-account-meta'
776 de27950a Stavros Sachtouris
        with patch.object(PC, 'get_account_info', return_value=account_info):
777 de27950a Stavros Sachtouris
            r = self.client.get_account_meta()
778 de27950a Stavros Sachtouris
            self.assertFalse(key in r)
779 de27950a Stavros Sachtouris
        acc_info = dict(account_info)
780 de27950a Stavros Sachtouris
        acc_info['x-account-meta-k1'] = 'v1'
781 de27950a Stavros Sachtouris
        acc_info['x-account-meta-k2'] = 'v2'
782 de27950a Stavros Sachtouris
        acc_info['x-account-meta-k3'] = 'v3'
783 de27950a Stavros Sachtouris
        with patch.object(PC, 'get_account_info', return_value=acc_info):
784 de27950a Stavros Sachtouris
            r = self.client.get_account_meta()
785 de27950a Stavros Sachtouris
            for k in [k for k in acc_info if k.startswith('X-Account-Meta-')]:
786 de27950a Stavros Sachtouris
                print(r[k], acc_info[k])