Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-app / pithos / api / test / objects.py @ e4c7cbeb

History | View | Annotate | Download (49.3 kB)

1 3a19e99b Sofia Papagiannaki
#!/usr/bin/env python
2 3a19e99b Sofia Papagiannaki
#coding=utf8
3 3a19e99b Sofia Papagiannaki
4 3a19e99b Sofia Papagiannaki
# Copyright 2011-2013 GRNET S.A. All rights reserved.
5 3a19e99b Sofia Papagiannaki
#
6 3a19e99b Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
7 3a19e99b Sofia Papagiannaki
# without modification, are permitted provided that the following
8 3a19e99b Sofia Papagiannaki
# conditions are met:
9 3a19e99b Sofia Papagiannaki
#
10 3a19e99b Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
11 3a19e99b Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
12 3a19e99b Sofia Papagiannaki
#      disclaimer.
13 3a19e99b Sofia Papagiannaki
#
14 3a19e99b Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
15 3a19e99b Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
16 3a19e99b Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
17 3a19e99b Sofia Papagiannaki
#      provided with the distribution.
18 3a19e99b Sofia Papagiannaki
#
19 3a19e99b Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
20 3a19e99b Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 3a19e99b Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 3a19e99b Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
23 3a19e99b Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 3a19e99b Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 3a19e99b Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 3a19e99b Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 3a19e99b Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 3a19e99b Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 3a19e99b Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 3a19e99b Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
31 3a19e99b Sofia Papagiannaki
#
32 3a19e99b Sofia Papagiannaki
# The views and conclusions contained in the software and
33 3a19e99b Sofia Papagiannaki
# documentation are those of the authors and should not be
34 3a19e99b Sofia Papagiannaki
# interpreted as representing official policies, either expressed
35 3a19e99b Sofia Papagiannaki
# or implied, of GRNET S.A.
36 3a19e99b Sofia Papagiannaki
37 3a19e99b Sofia Papagiannaki
from collections import defaultdict
38 3a19e99b Sofia Papagiannaki
from urllib import quote
39 5fe43b8c Sofia Papagiannaki
from functools import partial
40 3a19e99b Sofia Papagiannaki
41 3a19e99b Sofia Papagiannaki
from pithos.api.test import (PithosAPITest, pithos_settings,
42 3a19e99b Sofia Papagiannaki
                             AssertMappingInvariant, AssertUUidInvariant,
43 5fe43b8c Sofia Papagiannaki
                             TEST_BLOCK_SIZE, TEST_HASH_ALGORITHM,
44 3a19e99b Sofia Papagiannaki
                             DATE_FORMATS)
45 bc4f25c0 Sofia Papagiannaki
from pithos.api.test.util import (md5_hash, merkle, strnextling,
46 bc4f25c0 Sofia Papagiannaki
                                  get_random_data, get_random_name)
47 3a19e99b Sofia Papagiannaki
48 3a19e99b Sofia Papagiannaki
from synnefo.lib import join_urls
49 3a19e99b Sofia Papagiannaki
50 3a19e99b Sofia Papagiannaki
import django.utils.simplejson as json
51 3a19e99b Sofia Papagiannaki
52 3a19e99b Sofia Papagiannaki
import random
53 3a19e99b Sofia Papagiannaki
import re
54 3a19e99b Sofia Papagiannaki
import datetime
55 5fe43b8c Sofia Papagiannaki
import time as _time
56 5fe43b8c Sofia Papagiannaki
57 5fe43b8c Sofia Papagiannaki
merkle = partial(merkle,
58 5fe43b8c Sofia Papagiannaki
                 blocksize=TEST_BLOCK_SIZE,
59 5fe43b8c Sofia Papagiannaki
                 blockhash=TEST_HASH_ALGORITHM)
60 3a19e99b Sofia Papagiannaki
61 3a19e99b Sofia Papagiannaki
62 2a194295 Sofia Papagiannaki
class ObjectHead(PithosAPITest):
63 2a194295 Sofia Papagiannaki
    def setUp(self):
64 2a194295 Sofia Papagiannaki
        cname = self.create_container()[0]
65 2a194295 Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
66 2a194295 Sofia Papagiannaki
67 2a194295 Sofia Papagiannaki
        url = join_urls(self.pithos_path, cname, oname)
68 2a194295 Sofia Papagiannaki
        r = self.head(url)
69 2a194295 Sofia Papagiannaki
        map(lambda i: self.assertTrue(i in r),
70 2a194295 Sofia Papagiannaki
            ['Etag',
71 2a194295 Sofia Papagiannaki
             'Content-Length',
72 2a194295 Sofia Papagiannaki
             'Content-Type',
73 2a194295 Sofia Papagiannaki
             'Last-Modified',
74 2a194295 Sofia Papagiannaki
             'Content-Encoding',
75 2a194295 Sofia Papagiannaki
             'Content-Disposition',
76 2a194295 Sofia Papagiannaki
             'X-Object-Hash',
77 2a194295 Sofia Papagiannaki
             'X-Object-UUID',
78 2a194295 Sofia Papagiannaki
             'X-Object-Version',
79 2a194295 Sofia Papagiannaki
             'X-Object-Version-Timestamp',
80 2a194295 Sofia Papagiannaki
             'X-Object-Modified-By',
81 2a194295 Sofia Papagiannaki
             'X-Object-Manifest'])
82 2a194295 Sofia Papagiannaki
83 2a194295 Sofia Papagiannaki
84 3a19e99b Sofia Papagiannaki
class ObjectGet(PithosAPITest):
85 3a19e99b Sofia Papagiannaki
    def setUp(self):
86 3a19e99b Sofia Papagiannaki
        PithosAPITest.setUp(self)
87 3a19e99b Sofia Papagiannaki
        self.containers = ['c1', 'c2']
88 3a19e99b Sofia Papagiannaki
89 3a19e99b Sofia Papagiannaki
        # create some containers
90 3a19e99b Sofia Papagiannaki
        for c in self.containers:
91 3a19e99b Sofia Papagiannaki
            self.create_container(c)
92 3a19e99b Sofia Papagiannaki
93 3a19e99b Sofia Papagiannaki
        # upload files
94 3a19e99b Sofia Papagiannaki
        self.objects = defaultdict(list)
95 3a19e99b Sofia Papagiannaki
        self.objects['c1'].append(self.upload_object('c1')[0])
96 3a19e99b Sofia Papagiannaki
97 3a19e99b Sofia Papagiannaki
    def test_versions(self):
98 3a19e99b Sofia Papagiannaki
        c = 'c1'
99 3a19e99b Sofia Papagiannaki
        o = self.objects[c][0]
100 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, c, o)
101 3a19e99b Sofia Papagiannaki
102 3a19e99b Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_QUALITY': 'AAA'}
103 3a19e99b Sofia Papagiannaki
        r = self.post(url, content_type='', **meta)
104 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
105 3a19e99b Sofia Papagiannaki
106 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, c, o)
107 3a19e99b Sofia Papagiannaki
        r = self.get('%s?version=list&format=json' % url)
108 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
109 3a19e99b Sofia Papagiannaki
        l1 = json.loads(r.content)['versions']
110 3a19e99b Sofia Papagiannaki
        self.assertEqual(len(l1), 2)
111 3a19e99b Sofia Papagiannaki
112 3a19e99b Sofia Papagiannaki
        # update meta
113 3a19e99b Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_QUALITY': 'AB',
114 3a19e99b Sofia Papagiannaki
                'HTTP_X_OBJECT_META_STOCK': 'True'}
115 3a19e99b Sofia Papagiannaki
        r = self.post(url, content_type='', **meta)
116 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
117 3a19e99b Sofia Papagiannaki
118 3a19e99b Sofia Papagiannaki
        # assert a newly created version has been created
119 3a19e99b Sofia Papagiannaki
        r = self.get('%s?version=list&format=json' % url)
120 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
121 3a19e99b Sofia Papagiannaki
        l2 = json.loads(r.content)['versions']
122 3a19e99b Sofia Papagiannaki
        self.assertEqual(len(l2), len(l1) + 1)
123 3a19e99b Sofia Papagiannaki
        self.assertEqual(l2[:-1], l1)
124 3a19e99b Sofia Papagiannaki
125 3a19e99b Sofia Papagiannaki
        vserial, _ = l2[-2]
126 3a19e99b Sofia Papagiannaki
        self.assertEqual(self.get_object_meta(c, o, version=vserial),
127 3a19e99b Sofia Papagiannaki
                         {'X-Object-Meta-Quality': 'AAA'})
128 3a19e99b Sofia Papagiannaki
129 3a19e99b Sofia Papagiannaki
        # update data
130 3a19e99b Sofia Papagiannaki
        self.append_object_data(c, o)
131 3a19e99b Sofia Papagiannaki
132 3a19e99b Sofia Papagiannaki
        # assert a newly created version has been created
133 3a19e99b Sofia Papagiannaki
        r = self.get('%s?version=list&format=json' % url)
134 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
135 3a19e99b Sofia Papagiannaki
        l3 = json.loads(r.content)['versions']
136 3a19e99b Sofia Papagiannaki
        self.assertEqual(len(l3), len(l2) + 1)
137 3a19e99b Sofia Papagiannaki
        self.assertEqual(l3[:-1], l2)
138 3a19e99b Sofia Papagiannaki
139 3a19e99b Sofia Papagiannaki
    def test_objects_with_trailing_spaces(self):
140 3a19e99b Sofia Papagiannaki
        # create object
141 3a19e99b Sofia Papagiannaki
        oname = self.upload_object('c1')[0]
142 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, 'c1', oname)
143 3a19e99b Sofia Papagiannaki
144 3a19e99b Sofia Papagiannaki
        r = self.get(quote('%s ' % url))
145 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
146 3a19e99b Sofia Papagiannaki
147 3a19e99b Sofia Papagiannaki
        # delete object
148 3a19e99b Sofia Papagiannaki
        self.delete(url)
149 3a19e99b Sofia Papagiannaki
150 3a19e99b Sofia Papagiannaki
        r = self.get(url)
151 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
152 3a19e99b Sofia Papagiannaki
153 3a19e99b Sofia Papagiannaki
        # upload object with trailing space
154 bc4f25c0 Sofia Papagiannaki
        oname = self.upload_object('c1', quote('%s ' % get_random_name()))[0]
155 3a19e99b Sofia Papagiannaki
156 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, 'c1', oname)
157 3a19e99b Sofia Papagiannaki
        r = self.get(url)
158 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
159 3a19e99b Sofia Papagiannaki
160 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, 'c1', oname[:-1])
161 3a19e99b Sofia Papagiannaki
        r = self.get(url)
162 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
163 3a19e99b Sofia Papagiannaki
164 3a19e99b Sofia Papagiannaki
    def test_get_partial(self):
165 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
166 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(cname, length=512)[:-1]
167 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
168 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_RANGE='bytes=0-499')
169 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
170 3a19e99b Sofia Papagiannaki
        data = r.content
171 3a19e99b Sofia Papagiannaki
        self.assertEqual(data, odata[:500])
172 3a19e99b Sofia Papagiannaki
        self.assertTrue('Content-Range' in r)
173 3a19e99b Sofia Papagiannaki
        self.assertEqual(r['Content-Range'], 'bytes 0-499/%s' % len(odata))
174 3a19e99b Sofia Papagiannaki
        self.assertTrue('Content-Type' in r)
175 3a19e99b Sofia Papagiannaki
        self.assertTrue(r['Content-Type'], 'application/octet-stream')
176 3a19e99b Sofia Papagiannaki
177 3a19e99b Sofia Papagiannaki
    def test_get_final_500(self):
178 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
179 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(cname, length=512)[:-1]
180 3a19e99b Sofia Papagiannaki
        size = len(odata)
181 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
182 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_RANGE='bytes=-500')
183 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
184 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, odata[-500:])
185 3a19e99b Sofia Papagiannaki
        self.assertTrue('Content-Range' in r)
186 3a19e99b Sofia Papagiannaki
        self.assertEqual(r['Content-Range'],
187 3a19e99b Sofia Papagiannaki
                         'bytes %s-%s/%s' % (size - 500, size - 1, size))
188 3a19e99b Sofia Papagiannaki
        self.assertTrue('Content-Type' in r)
189 3a19e99b Sofia Papagiannaki
        self.assertTrue(r['Content-Type'], 'application/octet-stream')
190 3a19e99b Sofia Papagiannaki
191 3a19e99b Sofia Papagiannaki
    def test_get_rest(self):
192 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
193 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(cname, length=512)[:-1]
194 3a19e99b Sofia Papagiannaki
        size = len(odata)
195 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
196 3a19e99b Sofia Papagiannaki
        offset = len(odata) - random.randint(1, 512)
197 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_RANGE='bytes=%s-' % offset)
198 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
199 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, odata[offset:])
200 3a19e99b Sofia Papagiannaki
        self.assertTrue('Content-Range' in r)
201 3a19e99b Sofia Papagiannaki
        self.assertEqual(r['Content-Range'],
202 3a19e99b Sofia Papagiannaki
                         'bytes %s-%s/%s' % (offset, size - 1, size))
203 3a19e99b Sofia Papagiannaki
        self.assertTrue('Content-Type' in r)
204 3a19e99b Sofia Papagiannaki
        self.assertTrue(r['Content-Type'], 'application/octet-stream')
205 3a19e99b Sofia Papagiannaki
206 3a19e99b Sofia Papagiannaki
    def test_get_range_not_satisfiable(self):
207 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
208 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(cname, length=512)[:-1]
209 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
210 3a19e99b Sofia Papagiannaki
211 3a19e99b Sofia Papagiannaki
        # TODO
212 3a19e99b Sofia Papagiannaki
        #r = self.get(url, HTTP_RANGE='bytes=50-10')
213 3a19e99b Sofia Papagiannaki
        #self.assertEqual(r.status_code, 416)
214 3a19e99b Sofia Papagiannaki
215 3a19e99b Sofia Papagiannaki
        offset = len(odata) + 1
216 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_RANGE='bytes=0-%s' % offset)
217 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 416)
218 3a19e99b Sofia Papagiannaki
219 3a19e99b Sofia Papagiannaki
    def test_multiple_range(self):
220 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
221 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
222 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
223 3a19e99b Sofia Papagiannaki
224 3a19e99b Sofia Papagiannaki
        l = ['0-499', '-500', '1000-']
225 3a19e99b Sofia Papagiannaki
        ranges = 'bytes=%s' % ','.join(l)
226 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_RANGE=ranges)
227 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
228 3a19e99b Sofia Papagiannaki
        self.assertTrue('content-type' in r)
229 3a19e99b Sofia Papagiannaki
        p = re.compile(
230 3a19e99b Sofia Papagiannaki
            'multipart/byteranges; boundary=(?P<boundary>[0-9a-f]{32}\Z)',
231 3a19e99b Sofia Papagiannaki
            re.I)
232 3a19e99b Sofia Papagiannaki
        m = p.match(r['content-type'])
233 3a19e99b Sofia Papagiannaki
        if m is None:
234 3a19e99b Sofia Papagiannaki
            self.fail('Invalid multiple range content type')
235 3a19e99b Sofia Papagiannaki
        boundary = m.groupdict()['boundary']
236 3a19e99b Sofia Papagiannaki
        cparts = r.content.split('--%s' % boundary)[1:-1]
237 3a19e99b Sofia Papagiannaki
238 3a19e99b Sofia Papagiannaki
        # assert content parts length
239 3a19e99b Sofia Papagiannaki
        self.assertEqual(len(cparts), len(l))
240 3a19e99b Sofia Papagiannaki
241 3a19e99b Sofia Papagiannaki
        # for each content part assert headers
242 3a19e99b Sofia Papagiannaki
        i = 0
243 3a19e99b Sofia Papagiannaki
        for cpart in cparts:
244 3a19e99b Sofia Papagiannaki
            content = cpart.split('\r\n')
245 3a19e99b Sofia Papagiannaki
            headers = content[1:3]
246 3a19e99b Sofia Papagiannaki
            content_range = headers[0].split(': ')
247 3a19e99b Sofia Papagiannaki
            self.assertEqual(content_range[0], 'Content-Range')
248 3a19e99b Sofia Papagiannaki
249 3a19e99b Sofia Papagiannaki
            r = l[i].split('-')
250 3a19e99b Sofia Papagiannaki
            if not r[0] and not r[1]:
251 3a19e99b Sofia Papagiannaki
                pass
252 3a19e99b Sofia Papagiannaki
            elif not r[0]:
253 3a19e99b Sofia Papagiannaki
                start = len(odata) - int(r[1])
254 3a19e99b Sofia Papagiannaki
                end = len(odata)
255 3a19e99b Sofia Papagiannaki
            elif not r[1]:
256 3a19e99b Sofia Papagiannaki
                start = int(r[0])
257 3a19e99b Sofia Papagiannaki
                end = len(odata)
258 3a19e99b Sofia Papagiannaki
            else:
259 3a19e99b Sofia Papagiannaki
                start = int(r[0])
260 3a19e99b Sofia Papagiannaki
                end = int(r[1]) + 1
261 3a19e99b Sofia Papagiannaki
            fdata = odata[start:end]
262 3a19e99b Sofia Papagiannaki
            sdata = '\r\n'.join(content[4:-1])
263 3a19e99b Sofia Papagiannaki
            self.assertEqual(len(fdata), len(sdata))
264 3a19e99b Sofia Papagiannaki
            self.assertEquals(fdata, sdata)
265 3a19e99b Sofia Papagiannaki
            i += 1
266 3a19e99b Sofia Papagiannaki
267 3a19e99b Sofia Papagiannaki
    def test_multiple_range_not_satisfiable(self):
268 3a19e99b Sofia Papagiannaki
        # perform get with multiple range
269 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
270 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
271 3a19e99b Sofia Papagiannaki
        out_of_range = len(odata) + 1
272 3a19e99b Sofia Papagiannaki
        l = ['0-499', '-500', '%d-' % out_of_range]
273 3a19e99b Sofia Papagiannaki
        ranges = 'bytes=%s' % ','.join(l)
274 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
275 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_RANGE=ranges)
276 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 416)
277 3a19e99b Sofia Papagiannaki
278 5fe43b8c Sofia Papagiannaki
    def test_get_if_match(self):
279 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
280 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
281 3a19e99b Sofia Papagiannaki
282 3a19e99b Sofia Papagiannaki
        # perform get with If-Match
283 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
284 3a19e99b Sofia Papagiannaki
285 3a19e99b Sofia Papagiannaki
        if pithos_settings.UPDATE_MD5:
286 5fe43b8c Sofia Papagiannaki
            etag = md5_hash(odata)
287 3a19e99b Sofia Papagiannaki
        else:
288 3a19e99b Sofia Papagiannaki
            etag = merkle(odata)
289 3a19e99b Sofia Papagiannaki
290 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_IF_MATCH=etag)
291 3a19e99b Sofia Papagiannaki
292 3a19e99b Sofia Papagiannaki
        # assert get success
293 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
294 3a19e99b Sofia Papagiannaki
295 3a19e99b Sofia Papagiannaki
        # assert response content
296 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, odata)
297 3a19e99b Sofia Papagiannaki
298 5fe43b8c Sofia Papagiannaki
    def test_get_if_match_star(self):
299 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
300 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
301 3a19e99b Sofia Papagiannaki
302 3a19e99b Sofia Papagiannaki
        # perform get with If-Match *
303 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
304 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_IF_MATCH='*')
305 3a19e99b Sofia Papagiannaki
306 3a19e99b Sofia Papagiannaki
        # assert get success
307 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
308 3a19e99b Sofia Papagiannaki
309 3a19e99b Sofia Papagiannaki
        # assert response content
310 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, odata)
311 3a19e99b Sofia Papagiannaki
312 5fe43b8c Sofia Papagiannaki
    def test_get_multiple_if_match(self):
313 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
314 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
315 3a19e99b Sofia Papagiannaki
316 3a19e99b Sofia Papagiannaki
        # perform get with If-Match
317 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
318 3a19e99b Sofia Papagiannaki
319 3a19e99b Sofia Papagiannaki
        if pithos_settings.UPDATE_MD5:
320 5fe43b8c Sofia Papagiannaki
            etag = md5_hash(odata)
321 3a19e99b Sofia Papagiannaki
        else:
322 3a19e99b Sofia Papagiannaki
            etag = merkle(odata)
323 3a19e99b Sofia Papagiannaki
324 5fe43b8c Sofia Papagiannaki
        quoted = lambda s: '"%s"' % s
325 5fe43b8c Sofia Papagiannaki
        r = self.get(url, HTTP_IF_MATCH=','.join(
326 5fe43b8c Sofia Papagiannaki
            [quoted(etag), quoted(get_random_data(64))]))
327 3a19e99b Sofia Papagiannaki
328 3a19e99b Sofia Papagiannaki
        # assert get success
329 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
330 3a19e99b Sofia Papagiannaki
331 3a19e99b Sofia Papagiannaki
        # assert response content
332 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, odata)
333 3a19e99b Sofia Papagiannaki
334 3a19e99b Sofia Papagiannaki
    def test_if_match_precondition_failed(self):
335 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
336 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
337 3a19e99b Sofia Papagiannaki
338 3a19e99b Sofia Papagiannaki
        # perform get with If-Match
339 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
340 bc4f25c0 Sofia Papagiannaki
        r = self.get(url, HTTP_IF_MATCH=get_random_name())
341 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 412)
342 3a19e99b Sofia Papagiannaki
343 a1f429b2 Sofia Papagiannaki
    def test_if_none_match(self):
344 3a19e99b Sofia Papagiannaki
        # upload object
345 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
346 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
347 3a19e99b Sofia Papagiannaki
348 3a19e99b Sofia Papagiannaki
        if pithos_settings.UPDATE_MD5:
349 5fe43b8c Sofia Papagiannaki
            etag = md5_hash(odata)
350 3a19e99b Sofia Papagiannaki
        else:
351 3a19e99b Sofia Papagiannaki
            etag = merkle(odata)
352 3a19e99b Sofia Papagiannaki
353 3a19e99b Sofia Papagiannaki
        # perform get with If-None-Match
354 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
355 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_IF_NONE_MATCH=etag)
356 3a19e99b Sofia Papagiannaki
357 3a19e99b Sofia Papagiannaki
        # assert precondition_failed
358 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 304)
359 3a19e99b Sofia Papagiannaki
360 3a19e99b Sofia Papagiannaki
        # update object data
361 3a19e99b Sofia Papagiannaki
        r = self.append_object_data(cname, oname)[-1]
362 3a19e99b Sofia Papagiannaki
        self.assertTrue(etag != r['ETag'])
363 3a19e99b Sofia Papagiannaki
364 3a19e99b Sofia Papagiannaki
        # perform get with If-None-Match
365 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
366 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_IF_NONE_MATCH=etag)
367 3a19e99b Sofia Papagiannaki
368 3a19e99b Sofia Papagiannaki
        # assert get success
369 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
370 3a19e99b Sofia Papagiannaki
371 a1f429b2 Sofia Papagiannaki
    def test_if_none_match_star(self):
372 3a19e99b Sofia Papagiannaki
        # upload object
373 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
374 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
375 3a19e99b Sofia Papagiannaki
376 3a19e99b Sofia Papagiannaki
        # perform get with If-None-Match with star
377 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
378 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_IF_NONE_MATCH='*')
379 3a19e99b Sofia Papagiannaki
380 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 304)
381 3a19e99b Sofia Papagiannaki
382 3a19e99b Sofia Papagiannaki
    def test_if_modified_since(self):
383 3a19e99b Sofia Papagiannaki
        # upload object
384 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
385 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
386 3a19e99b Sofia Papagiannaki
        object_info = self.get_object_info(cname, oname)
387 3a19e99b Sofia Papagiannaki
        last_modified = object_info['Last-Modified']
388 3a19e99b Sofia Papagiannaki
        t1 = datetime.datetime.strptime(last_modified, DATE_FORMATS[-1])
389 3a19e99b Sofia Papagiannaki
        t1_formats = map(t1.strftime, DATE_FORMATS)
390 3a19e99b Sofia Papagiannaki
391 3a19e99b Sofia Papagiannaki
        # Check not modified since
392 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
393 3a19e99b Sofia Papagiannaki
        for t in t1_formats:
394 3a19e99b Sofia Papagiannaki
            r = self.get(url, HTTP_IF_MODIFIED_SINCE=t)
395 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 304)
396 3a19e99b Sofia Papagiannaki
397 3a19e99b Sofia Papagiannaki
        _time.sleep(1)
398 3a19e99b Sofia Papagiannaki
399 3a19e99b Sofia Papagiannaki
        # update object data
400 3a19e99b Sofia Papagiannaki
        appended_data = self.append_object_data(cname, oname)[1]
401 3a19e99b Sofia Papagiannaki
402 3a19e99b Sofia Papagiannaki
        # Check modified since
403 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
404 3a19e99b Sofia Papagiannaki
        for t in t1_formats:
405 3a19e99b Sofia Papagiannaki
            r = self.get(url, HTTP_IF_MODIFIED_SINCE=t)
406 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
407 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.content, odata + appended_data)
408 3a19e99b Sofia Papagiannaki
409 3a19e99b Sofia Papagiannaki
    def test_if_modified_since_invalid_date(self):
410 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
411 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
412 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
413 3a19e99b Sofia Papagiannaki
        r = self.get(url, HTTP_IF_MODIFIED_SINCE='Monday')
414 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
415 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, odata)
416 3a19e99b Sofia Papagiannaki
417 3a19e99b Sofia Papagiannaki
    def test_if_not_modified_since(self):
418 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
419 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
420 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
421 3a19e99b Sofia Papagiannaki
        object_info = self.get_object_info(cname, oname)
422 3a19e99b Sofia Papagiannaki
        last_modified = object_info['Last-Modified']
423 3a19e99b Sofia Papagiannaki
        t = datetime.datetime.strptime(last_modified, DATE_FORMATS[-1])
424 3a19e99b Sofia Papagiannaki
425 3a19e99b Sofia Papagiannaki
        # Check unmodified
426 3a19e99b Sofia Papagiannaki
        t1 = t + datetime.timedelta(seconds=1)
427 3a19e99b Sofia Papagiannaki
        t1_formats = map(t1.strftime, DATE_FORMATS)
428 3a19e99b Sofia Papagiannaki
        for t in t1_formats:
429 3a19e99b Sofia Papagiannaki
            r = self.get(url, HTTP_IF_UNMODIFIED_SINCE=t)
430 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
431 2a194295 Sofia Papagiannaki
            self.assertEqual(r.content, odata)
432 3a19e99b Sofia Papagiannaki
433 3a19e99b Sofia Papagiannaki
        # modify object
434 3a19e99b Sofia Papagiannaki
        _time.sleep(2)
435 3a19e99b Sofia Papagiannaki
        self.append_object_data(cname, oname)
436 3a19e99b Sofia Papagiannaki
437 3a19e99b Sofia Papagiannaki
        object_info = self.get_object_info(cname, oname)
438 3a19e99b Sofia Papagiannaki
        last_modified = object_info['Last-Modified']
439 3a19e99b Sofia Papagiannaki
        t = datetime.datetime.strptime(last_modified, DATE_FORMATS[-1])
440 3a19e99b Sofia Papagiannaki
        t2 = t - datetime.timedelta(seconds=1)
441 3a19e99b Sofia Papagiannaki
        t2_formats = map(t2.strftime, DATE_FORMATS)
442 3a19e99b Sofia Papagiannaki
443 5fe43b8c Sofia Papagiannaki
        # check modified
444 3a19e99b Sofia Papagiannaki
        for t in t2_formats:
445 3a19e99b Sofia Papagiannaki
            r = self.get(url, HTTP_IF_UNMODIFIED_SINCE=t)
446 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 412)
447 3a19e99b Sofia Papagiannaki
448 800af189 Sofia Papagiannaki
        # modify account: update object meta
449 3a19e99b Sofia Papagiannaki
        _time.sleep(1)
450 3a19e99b Sofia Papagiannaki
        self.update_object_meta(cname, oname, {'foo': 'bar'})
451 3a19e99b Sofia Papagiannaki
452 3a19e99b Sofia Papagiannaki
        object_info = self.get_object_info(cname, oname)
453 3a19e99b Sofia Papagiannaki
        last_modified = object_info['Last-Modified']
454 3a19e99b Sofia Papagiannaki
        t = datetime.datetime.strptime(last_modified, DATE_FORMATS[-1])
455 3a19e99b Sofia Papagiannaki
        t3 = t - datetime.timedelta(seconds=1)
456 3a19e99b Sofia Papagiannaki
        t3_formats = map(t3.strftime, DATE_FORMATS)
457 3a19e99b Sofia Papagiannaki
458 5fe43b8c Sofia Papagiannaki
        # check modified
459 3a19e99b Sofia Papagiannaki
        for t in t3_formats:
460 3a19e99b Sofia Papagiannaki
            r = self.get(url, HTTP_IF_UNMODIFIED_SINCE=t)
461 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 412)
462 3a19e99b Sofia Papagiannaki
463 3a19e99b Sofia Papagiannaki
    def test_if_unmodified_since(self):
464 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
465 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
466 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
467 3a19e99b Sofia Papagiannaki
        object_info = self.get_object_info(cname, oname)
468 3a19e99b Sofia Papagiannaki
        last_modified = object_info['Last-Modified']
469 3a19e99b Sofia Papagiannaki
        t = datetime.datetime.strptime(last_modified, DATE_FORMATS[-1])
470 3a19e99b Sofia Papagiannaki
        t = t + datetime.timedelta(seconds=1)
471 3a19e99b Sofia Papagiannaki
        t_formats = map(t.strftime, DATE_FORMATS)
472 3a19e99b Sofia Papagiannaki
473 3a19e99b Sofia Papagiannaki
        for tf in t_formats:
474 3a19e99b Sofia Papagiannaki
            r = self.get(url, HTTP_IF_UNMODIFIED_SINCE=tf)
475 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
476 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.content, odata)
477 3a19e99b Sofia Papagiannaki
478 3a19e99b Sofia Papagiannaki
    def test_if_unmodified_since_precondition_failed(self):
479 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
480 5fe43b8c Sofia Papagiannaki
        oname, odata = self.upload_object(cname)[:-1]
481 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
482 3a19e99b Sofia Papagiannaki
        object_info = self.get_object_info(cname, oname)
483 3a19e99b Sofia Papagiannaki
        last_modified = object_info['Last-Modified']
484 3a19e99b Sofia Papagiannaki
        t = datetime.datetime.strptime(last_modified, DATE_FORMATS[-1])
485 3a19e99b Sofia Papagiannaki
        t = t - datetime.timedelta(seconds=1)
486 3a19e99b Sofia Papagiannaki
        t_formats = map(t.strftime, DATE_FORMATS)
487 3a19e99b Sofia Papagiannaki
488 3a19e99b Sofia Papagiannaki
        for tf in t_formats:
489 3a19e99b Sofia Papagiannaki
            r = self.get(url, HTTP_IF_UNMODIFIED_SINCE=tf)
490 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 412)
491 3a19e99b Sofia Papagiannaki
492 3a19e99b Sofia Papagiannaki
    def test_hashes(self):
493 3a19e99b Sofia Papagiannaki
        l = random.randint(2, 5) * pithos_settings.BACKEND_BLOCK_SIZE
494 3a19e99b Sofia Papagiannaki
        cname = self.containers[0]
495 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(cname, length=l)[:-1]
496 3a19e99b Sofia Papagiannaki
        size = len(odata)
497 3a19e99b Sofia Papagiannaki
498 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
499 3a19e99b Sofia Papagiannaki
        r = self.get('%s?format=json&hashmap' % url)
500 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
501 3a19e99b Sofia Papagiannaki
        body = json.loads(r.content)
502 3a19e99b Sofia Papagiannaki
503 3a19e99b Sofia Papagiannaki
        hashes = body['hashes']
504 3a19e99b Sofia Papagiannaki
        block_size = body['block_size']
505 3a19e99b Sofia Papagiannaki
        block_num = size / block_size if size / block_size == 0 else\
506 3a19e99b Sofia Papagiannaki
            size / block_size + 1
507 3a19e99b Sofia Papagiannaki
        self.assertTrue(len(hashes), block_num)
508 3a19e99b Sofia Papagiannaki
        i = 0
509 3a19e99b Sofia Papagiannaki
        for h in hashes:
510 3a19e99b Sofia Papagiannaki
            start = i * block_size
511 3a19e99b Sofia Papagiannaki
            end = (i + 1) * block_size
512 5fe43b8c Sofia Papagiannaki
            hash = merkle(odata[start:end])
513 3a19e99b Sofia Papagiannaki
            self.assertEqual(h, hash)
514 3a19e99b Sofia Papagiannaki
            i += 1
515 3a19e99b Sofia Papagiannaki
516 3a19e99b Sofia Papagiannaki
517 3a19e99b Sofia Papagiannaki
class ObjectPut(PithosAPITest):
518 3a19e99b Sofia Papagiannaki
    def setUp(self):
519 3a19e99b Sofia Papagiannaki
        PithosAPITest.setUp(self)
520 bc4f25c0 Sofia Papagiannaki
        self.container = get_random_name()
521 3a19e99b Sofia Papagiannaki
        self.create_container(self.container)
522 3a19e99b Sofia Papagiannaki
523 3a19e99b Sofia Papagiannaki
    def test_upload(self):
524 3a19e99b Sofia Papagiannaki
        cname = self.container
525 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
526 5fe43b8c Sofia Papagiannaki
        data = get_random_data()
527 3a19e99b Sofia Papagiannaki
        meta = {'test': 'test1'}
528 3a19e99b Sofia Papagiannaki
        headers = dict(('HTTP_X_OBJECT_META_%s' % k.upper(), v)
529 3a19e99b Sofia Papagiannaki
                       for k, v in meta.iteritems())
530 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
531 3a19e99b Sofia Papagiannaki
        r = self.put(url, data=data, content_type='application/pdf', **headers)
532 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
533 3a19e99b Sofia Papagiannaki
        self.assertTrue('ETag' in r)
534 3a19e99b Sofia Papagiannaki
        self.assertTrue('X-Object-Version' in r)
535 3a19e99b Sofia Papagiannaki
536 3a19e99b Sofia Papagiannaki
        info = self.get_object_info(cname, oname)
537 3a19e99b Sofia Papagiannaki
538 3a19e99b Sofia Papagiannaki
        # assert object meta
539 3a19e99b Sofia Papagiannaki
        self.assertTrue('X-Object-Meta-Test' in info)
540 3a19e99b Sofia Papagiannaki
        self.assertEqual(info['X-Object-Meta-Test'], 'test1')
541 3a19e99b Sofia Papagiannaki
542 3a19e99b Sofia Papagiannaki
        # assert content-type
543 3a19e99b Sofia Papagiannaki
        self.assertEqual(info['content-type'], 'application/pdf')
544 3a19e99b Sofia Papagiannaki
545 3a19e99b Sofia Papagiannaki
        # assert uploaded content
546 3a19e99b Sofia Papagiannaki
        r = self.get(url)
547 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
548 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, data)
549 3a19e99b Sofia Papagiannaki
550 3a19e99b Sofia Papagiannaki
    def test_maximum_upload_size_exceeds(self):
551 3a19e99b Sofia Papagiannaki
        cname = self.container
552 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
553 3a19e99b Sofia Papagiannaki
554 3a19e99b Sofia Papagiannaki
        # set container quota to 100
555 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname)
556 3a19e99b Sofia Papagiannaki
        r = self.post(url, HTTP_X_CONTAINER_POLICY_QUOTA='100')
557 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
558 3a19e99b Sofia Papagiannaki
559 3a19e99b Sofia Papagiannaki
        info = self.get_container_info(cname)
560 3a19e99b Sofia Papagiannaki
        length = int(info['X-Container-Policy-Quota']) + 1
561 3a19e99b Sofia Papagiannaki
562 3a19e99b Sofia Papagiannaki
        data = get_random_data(length)
563 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
564 3a19e99b Sofia Papagiannaki
        r = self.put(url, data=data)
565 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 413)
566 3a19e99b Sofia Papagiannaki
567 3a19e99b Sofia Papagiannaki
    def test_upload_with_name_containing_slash(self):
568 3a19e99b Sofia Papagiannaki
        cname = self.container
569 bc4f25c0 Sofia Papagiannaki
        oname = '/%s' % get_random_name()
570 5fe43b8c Sofia Papagiannaki
        data = get_random_data()
571 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
572 3a19e99b Sofia Papagiannaki
        r = self.put(url, data=data)
573 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
574 3a19e99b Sofia Papagiannaki
        self.assertTrue('ETag' in r)
575 3a19e99b Sofia Papagiannaki
        self.assertTrue('X-Object-Version' in r)
576 3a19e99b Sofia Papagiannaki
577 3a19e99b Sofia Papagiannaki
        r = self.get(url)
578 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
579 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, data)
580 3a19e99b Sofia Papagiannaki
581 3a19e99b Sofia Papagiannaki
    def test_upload_unprocessable_entity(self):
582 3a19e99b Sofia Papagiannaki
        cname = self.container
583 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
584 5fe43b8c Sofia Papagiannaki
        data = get_random_data()
585 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
586 3a19e99b Sofia Papagiannaki
        r = self.put(url, data=data, HTTP_ETAG='123')
587 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 422)
588 3a19e99b Sofia Papagiannaki
589 3a19e99b Sofia Papagiannaki
#    def test_chunked_transfer(self):
590 3a19e99b Sofia Papagiannaki
#        cname = self.container
591 bc4f25c0 Sofia Papagiannaki
#        oname = '/%s' % get_random_name()
592 5fe43b8c Sofia Papagiannaki
#        data = get_random_data()
593 3a19e99b Sofia Papagiannaki
#        url = join_urls(self.pithos_path, self.user, cname, oname)
594 3a19e99b Sofia Papagiannaki
#        r = self.put(url, data=data, HTTP_TRANSFER_ENCODING='chunked')
595 3a19e99b Sofia Papagiannaki
#        self.assertEqual(r.status_code, 201)
596 3a19e99b Sofia Papagiannaki
#        self.assertTrue('ETag' in r)
597 3a19e99b Sofia Papagiannaki
#        self.assertTrue('X-Object-Version' in r)
598 3a19e99b Sofia Papagiannaki
599 3a19e99b Sofia Papagiannaki
    def test_manifestation(self):
600 3a19e99b Sofia Papagiannaki
        cname = self.container
601 3a19e99b Sofia Papagiannaki
        prefix = 'myobject/'
602 3a19e99b Sofia Papagiannaki
        data = ''
603 3a19e99b Sofia Papagiannaki
        for i in range(random.randint(2, 10)):
604 3a19e99b Sofia Papagiannaki
            part = '%s%d' % (prefix, i)
605 3a19e99b Sofia Papagiannaki
            data += self.upload_object(cname, oname=part)[1]
606 3a19e99b Sofia Papagiannaki
607 3a19e99b Sofia Papagiannaki
        manifest = '%s/%s' % (cname, prefix)
608 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
609 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
610 3a19e99b Sofia Papagiannaki
        r = self.put(url, data='', HTTP_X_OBJECT_MANIFEST=manifest)
611 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
612 3a19e99b Sofia Papagiannaki
613 3a19e99b Sofia Papagiannaki
        # assert object exists
614 3a19e99b Sofia Papagiannaki
        r = self.get(url)
615 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
616 3a19e99b Sofia Papagiannaki
617 3a19e99b Sofia Papagiannaki
        # assert its content
618 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, data)
619 3a19e99b Sofia Papagiannaki
620 3a19e99b Sofia Papagiannaki
        # invalid manifestation
621 bc4f25c0 Sofia Papagiannaki
        invalid_manifestation = '%s/%s' % (cname, get_random_name())
622 3a19e99b Sofia Papagiannaki
        self.put(url, data='', HTTP_X_OBJECT_MANIFEST=invalid_manifestation)
623 3a19e99b Sofia Papagiannaki
        r = self.get(url)
624 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, '')
625 3a19e99b Sofia Papagiannaki
626 3a19e99b Sofia Papagiannaki
    def test_create_zero_length_object(self):
627 3a19e99b Sofia Papagiannaki
        cname = self.container
628 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
629 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
630 3a19e99b Sofia Papagiannaki
        r = self.put(url, data='')
631 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
632 3a19e99b Sofia Papagiannaki
633 3a19e99b Sofia Papagiannaki
        r = self.get(url)
634 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
635 3a19e99b Sofia Papagiannaki
        self.assertEqual(int(r['Content-Length']), 0)
636 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, '')
637 3a19e99b Sofia Papagiannaki
638 3a19e99b Sofia Papagiannaki
        r = self.get('%s?hashmap=&format=json' % url)
639 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
640 3a19e99b Sofia Papagiannaki
        body = json.loads(r.content)
641 3a19e99b Sofia Papagiannaki
        hashes = body['hashes']
642 5fe43b8c Sofia Papagiannaki
        hash = merkle('')
643 3a19e99b Sofia Papagiannaki
        self.assertEqual(hashes, [hash])
644 3a19e99b Sofia Papagiannaki
645 3a19e99b Sofia Papagiannaki
    def test_create_object_by_hashmap(self):
646 3a19e99b Sofia Papagiannaki
        cname = self.container
647 3a19e99b Sofia Papagiannaki
        block_size = pithos_settings.BACKEND_BLOCK_SIZE
648 3a19e99b Sofia Papagiannaki
649 3a19e99b Sofia Papagiannaki
        # upload an object
650 3a19e99b Sofia Papagiannaki
        oname, data = self.upload_object(cname, length=block_size + 1)[:-1]
651 3a19e99b Sofia Papagiannaki
        # get it hashmap
652 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
653 3a19e99b Sofia Papagiannaki
        r = self.get('%s?hashmap=&format=json' % url)
654 3a19e99b Sofia Papagiannaki
655 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
656 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, cname, oname)
657 3a19e99b Sofia Papagiannaki
        r = self.put('%s?hashmap=' % url, data=r.content)
658 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
659 3a19e99b Sofia Papagiannaki
660 3a19e99b Sofia Papagiannaki
        r = self.get(url)
661 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
662 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, data)
663 3a19e99b Sofia Papagiannaki
664 3a19e99b Sofia Papagiannaki
665 3a19e99b Sofia Papagiannaki
class ObjectCopy(PithosAPITest):
666 3a19e99b Sofia Papagiannaki
    def setUp(self):
667 3a19e99b Sofia Papagiannaki
        PithosAPITest.setUp(self)
668 3a19e99b Sofia Papagiannaki
        self.container = 'c1'
669 3a19e99b Sofia Papagiannaki
        self.create_container(self.container)
670 3a19e99b Sofia Papagiannaki
        self.object, self.data = self.upload_object(self.container)[:-1]
671 3a19e99b Sofia Papagiannaki
672 3a19e99b Sofia Papagiannaki
        url = join_urls(
673 3a19e99b Sofia Papagiannaki
            self.pithos_path, self.user, self.container, self.object)
674 3a19e99b Sofia Papagiannaki
        r = self.head(url)
675 3a19e99b Sofia Papagiannaki
        self.etag = r['X-Object-Hash']
676 3a19e99b Sofia Papagiannaki
677 3a19e99b Sofia Papagiannaki
    def test_copy(self):
678 3a19e99b Sofia Papagiannaki
        with AssertMappingInvariant(self.get_object_info, self.container,
679 3a19e99b Sofia Papagiannaki
                                    self.object):
680 3a19e99b Sofia Papagiannaki
            # copy object
681 bc4f25c0 Sofia Papagiannaki
            oname = get_random_name()
682 3a19e99b Sofia Papagiannaki
            url = join_urls(self.pithos_path, self.user, self.container, oname)
683 3a19e99b Sofia Papagiannaki
            r = self.put(url, data='', HTTP_X_OBJECT_META_TEST='testcopy',
684 3a19e99b Sofia Papagiannaki
                         HTTP_X_COPY_FROM='/%s/%s' % (
685 3a19e99b Sofia Papagiannaki
                             self.container, self.object))
686 3a19e99b Sofia Papagiannaki
687 3a19e99b Sofia Papagiannaki
            # assert copy success
688 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 201)
689 3a19e99b Sofia Papagiannaki
690 3a19e99b Sofia Papagiannaki
            # assert access the new object
691 3a19e99b Sofia Papagiannaki
            r = self.head(url)
692 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
693 3a19e99b Sofia Papagiannaki
            self.assertTrue('X-Object-Meta-Test' in r)
694 3a19e99b Sofia Papagiannaki
            self.assertEqual(r['X-Object-Meta-Test'], 'testcopy')
695 3a19e99b Sofia Papagiannaki
696 3a19e99b Sofia Papagiannaki
            # assert etag is the same
697 3a19e99b Sofia Papagiannaki
            self.assertTrue('X-Object-Hash' in r)
698 3a19e99b Sofia Papagiannaki
            self.assertEqual(r['X-Object-Hash'], self.etag)
699 3a19e99b Sofia Papagiannaki
700 3a19e99b Sofia Papagiannaki
    def test_copy_from_different_container(self):
701 3a19e99b Sofia Papagiannaki
        cname = 'c2'
702 3a19e99b Sofia Papagiannaki
        self.create_container(cname)
703 3a19e99b Sofia Papagiannaki
        with AssertMappingInvariant(self.get_object_info, self.container,
704 3a19e99b Sofia Papagiannaki
                                    self.object):
705 bc4f25c0 Sofia Papagiannaki
            oname = get_random_name()
706 3a19e99b Sofia Papagiannaki
            url = join_urls(self.pithos_path, self.user, cname, oname)
707 3a19e99b Sofia Papagiannaki
            r = self.put(url, data='', HTTP_X_OBJECT_META_TEST='testcopy',
708 3a19e99b Sofia Papagiannaki
                         HTTP_X_COPY_FROM='/%s/%s' % (
709 3a19e99b Sofia Papagiannaki
                             self.container, self.object))
710 3a19e99b Sofia Papagiannaki
711 3a19e99b Sofia Papagiannaki
            # assert copy success
712 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 201)
713 3a19e99b Sofia Papagiannaki
714 3a19e99b Sofia Papagiannaki
            # assert access the new object
715 3a19e99b Sofia Papagiannaki
            r = self.head(url)
716 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
717 3a19e99b Sofia Papagiannaki
            self.assertTrue('X-Object-Meta-Test' in r)
718 3a19e99b Sofia Papagiannaki
            self.assertEqual(r['X-Object-Meta-Test'], 'testcopy')
719 3a19e99b Sofia Papagiannaki
720 3a19e99b Sofia Papagiannaki
            # assert etag is the same
721 3a19e99b Sofia Papagiannaki
            self.assertTrue('X-Object-Hash' in r)
722 3a19e99b Sofia Papagiannaki
            self.assertEqual(r['X-Object-Hash'], self.etag)
723 3a19e99b Sofia Papagiannaki
724 3a19e99b Sofia Papagiannaki
    def test_copy_invalid(self):
725 3a19e99b Sofia Papagiannaki
        # copy from non-existent object
726 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
727 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
728 3a19e99b Sofia Papagiannaki
        r = self.put(url, data='', HTTP_X_OBJECT_META_TEST='testcopy',
729 3a19e99b Sofia Papagiannaki
                     HTTP_X_COPY_FROM='/%s/%s' % (
730 bc4f25c0 Sofia Papagiannaki
                         self.container, get_random_name()))
731 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
732 3a19e99b Sofia Papagiannaki
733 3a19e99b Sofia Papagiannaki
        # copy from non-existent container
734 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
735 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
736 3a19e99b Sofia Papagiannaki
        r = self.put(url, data='', HTTP_X_OBJECT_META_TEST='testcopy',
737 3a19e99b Sofia Papagiannaki
                     HTTP_X_COPY_FROM='/%s/%s' % (
738 bc4f25c0 Sofia Papagiannaki
                         get_random_name(), self.object))
739 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
740 3a19e99b Sofia Papagiannaki
741 3a19e99b Sofia Papagiannaki
    def test_copy_dir(self):
742 3a19e99b Sofia Papagiannaki
        folder = self.create_folder(self.container)[0]
743 3a19e99b Sofia Papagiannaki
        subfolder = self.create_folder(
744 bc4f25c0 Sofia Papagiannaki
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
745 3a19e99b Sofia Papagiannaki
        objects = [subfolder]
746 3a19e99b Sofia Papagiannaki
        append = objects.append
747 3a19e99b Sofia Papagiannaki
        append(self.upload_object(self.container,
748 bc4f25c0 Sofia Papagiannaki
                                  '%s/%s' % (folder, get_random_name()),
749 3a19e99b Sofia Papagiannaki
                                  HTTP_X_OBJECT_META_DEPTH='1')[0])
750 3a19e99b Sofia Papagiannaki
        append(self.upload_object(self.container,
751 bc4f25c0 Sofia Papagiannaki
                                  '%s/%s' % (subfolder, get_random_name()),
752 3a19e99b Sofia Papagiannaki
                                  HTTP_X_OBJECT_META_DEPTH='2')[0])
753 3a19e99b Sofia Papagiannaki
        other = self.upload_object(self.container, strnextling(folder))[0]
754 3a19e99b Sofia Papagiannaki
755 3a19e99b Sofia Papagiannaki
        # copy dir
756 3a19e99b Sofia Papagiannaki
        copy_folder = self.create_folder(self.container)[0]
757 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
758 3a19e99b Sofia Papagiannaki
                        copy_folder)
759 3a19e99b Sofia Papagiannaki
        r = self.put('%s?delimiter=/' % url, data='',
760 3a19e99b Sofia Papagiannaki
                     HTTP_X_COPY_FROM='/%s/%s' % (self.container, folder))
761 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
762 3a19e99b Sofia Papagiannaki
763 3a19e99b Sofia Papagiannaki
        for obj in objects:
764 3a19e99b Sofia Papagiannaki
            # assert object exists
765 3a19e99b Sofia Papagiannaki
            url = join_urls(self.pithos_path, self.user, self.container,
766 3a19e99b Sofia Papagiannaki
                            obj.replace(folder, copy_folder))
767 3a19e99b Sofia Papagiannaki
            r = self.head(url)
768 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
769 3a19e99b Sofia Papagiannaki
770 3a19e99b Sofia Papagiannaki
            # assert metadata
771 3a19e99b Sofia Papagiannaki
            meta = self.get_object_meta(self.container, obj)
772 3a19e99b Sofia Papagiannaki
            for k in meta.keys():
773 3a19e99b Sofia Papagiannaki
                self.assertTrue(k in r)
774 3a19e99b Sofia Papagiannaki
                self.assertEqual(r[k], meta[k])
775 3a19e99b Sofia Papagiannaki
776 3a19e99b Sofia Papagiannaki
        # assert other has not been created under copy folder
777 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
778 3a19e99b Sofia Papagiannaki
                        '%s/%s' % (copy_folder,
779 3a19e99b Sofia Papagiannaki
                                   other.replace(folder, copy_folder)))
780 3a19e99b Sofia Papagiannaki
        r = self.head(url)
781 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
782 3a19e99b Sofia Papagiannaki
783 3a19e99b Sofia Papagiannaki
784 3a19e99b Sofia Papagiannaki
class ObjectMove(PithosAPITest):
785 3a19e99b Sofia Papagiannaki
    def setUp(self):
786 3a19e99b Sofia Papagiannaki
        PithosAPITest.setUp(self)
787 3a19e99b Sofia Papagiannaki
        self.container = 'c1'
788 3a19e99b Sofia Papagiannaki
        self.create_container(self.container)
789 3a19e99b Sofia Papagiannaki
        self.object, self.data = self.upload_object(self.container)[:-1]
790 3a19e99b Sofia Papagiannaki
791 3a19e99b Sofia Papagiannaki
        url = join_urls(
792 3a19e99b Sofia Papagiannaki
            self.pithos_path, self.user, self.container, self.object)
793 3a19e99b Sofia Papagiannaki
        r = self.head(url)
794 3a19e99b Sofia Papagiannaki
        self.etag = r['X-Object-Hash']
795 3a19e99b Sofia Papagiannaki
796 3a19e99b Sofia Papagiannaki
    def test_move(self):
797 3a19e99b Sofia Papagiannaki
        # move object
798 bc4f25c0 Sofia Papagiannaki
        oname = get_random_name()
799 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
800 3a19e99b Sofia Papagiannaki
        r = self.put(url, data='', HTTP_X_OBJECT_META_TEST='testcopy',
801 3a19e99b Sofia Papagiannaki
                     HTTP_X_MOVE_FROM='/%s/%s' % (
802 3a19e99b Sofia Papagiannaki
                         self.container, self.object))
803 3a19e99b Sofia Papagiannaki
804 3a19e99b Sofia Papagiannaki
        # assert move success
805 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
806 3a19e99b Sofia Papagiannaki
807 3a19e99b Sofia Papagiannaki
        # assert access the new object
808 3a19e99b Sofia Papagiannaki
        r = self.head(url)
809 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
810 3a19e99b Sofia Papagiannaki
        self.assertTrue('X-Object-Meta-Test' in r)
811 3a19e99b Sofia Papagiannaki
        self.assertEqual(r['X-Object-Meta-Test'], 'testcopy')
812 3a19e99b Sofia Papagiannaki
813 3a19e99b Sofia Papagiannaki
        # assert etag is the same
814 3a19e99b Sofia Papagiannaki
        self.assertTrue('X-Object-Hash' in r)
815 3a19e99b Sofia Papagiannaki
816 3a19e99b Sofia Papagiannaki
        # assert the initial object has been deleted
817 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
818 3a19e99b Sofia Papagiannaki
                        self.object)
819 3a19e99b Sofia Papagiannaki
        r = self.head(url)
820 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
821 3a19e99b Sofia Papagiannaki
822 3a19e99b Sofia Papagiannaki
    def test_move_dir(self):
823 3a19e99b Sofia Papagiannaki
        folder = self.create_folder(self.container)[0]
824 3a19e99b Sofia Papagiannaki
        subfolder = self.create_folder(
825 bc4f25c0 Sofia Papagiannaki
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
826 3a19e99b Sofia Papagiannaki
        objects = [subfolder]
827 3a19e99b Sofia Papagiannaki
        append = objects.append
828 3a19e99b Sofia Papagiannaki
        meta = {}
829 3a19e99b Sofia Papagiannaki
        meta[objects[0]] = {}
830 3a19e99b Sofia Papagiannaki
        append(self.upload_object(self.container,
831 bc4f25c0 Sofia Papagiannaki
                                  '%s/%s' % (folder, get_random_name()),
832 3a19e99b Sofia Papagiannaki
                                  HTTP_X_OBJECT_META_DEPTH='1')[0])
833 3a19e99b Sofia Papagiannaki
        meta[objects[1]] = {'X-Object-Meta-Depth': '1'}
834 3a19e99b Sofia Papagiannaki
        append(self.upload_object(self.container,
835 bc4f25c0 Sofia Papagiannaki
                                  '%s/%s' % (subfolder, get_random_name()),
836 3a19e99b Sofia Papagiannaki
                                  HTTP_X_OBJECT_META_DEPTH='2')[0])
837 3a19e99b Sofia Papagiannaki
        meta[objects[1]] = {'X-Object-Meta-Depth': '2'}
838 3a19e99b Sofia Papagiannaki
        other = self.upload_object(self.container, strnextling(folder))[0]
839 3a19e99b Sofia Papagiannaki
840 3a19e99b Sofia Papagiannaki
        # move dir
841 3a19e99b Sofia Papagiannaki
        copy_folder = self.create_folder(self.container)[0]
842 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
843 3a19e99b Sofia Papagiannaki
                        copy_folder)
844 3a19e99b Sofia Papagiannaki
        r = self.put('%s?delimiter=/' % url, data='',
845 3a19e99b Sofia Papagiannaki
                     HTTP_X_MOVE_FROM='/%s/%s' % (self.container, folder))
846 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
847 3a19e99b Sofia Papagiannaki
848 3a19e99b Sofia Papagiannaki
        for obj in objects:
849 3a19e99b Sofia Papagiannaki
            # assert initial object does not exist
850 3a19e99b Sofia Papagiannaki
            url = join_urls(self.pithos_path, self.user, self.container, obj)
851 3a19e99b Sofia Papagiannaki
            r = self.head(url)
852 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 404)
853 3a19e99b Sofia Papagiannaki
854 3a19e99b Sofia Papagiannaki
            # assert new object was created
855 3a19e99b Sofia Papagiannaki
            url = join_urls(self.pithos_path, self.user, self.container,
856 3a19e99b Sofia Papagiannaki
                            obj.replace(folder, copy_folder))
857 3a19e99b Sofia Papagiannaki
            r = self.head(url)
858 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
859 3a19e99b Sofia Papagiannaki
860 3a19e99b Sofia Papagiannaki
#            # assert metadata
861 3a19e99b Sofia Papagiannaki
#            for k in meta[obj].keys():
862 3a19e99b Sofia Papagiannaki
#                self.assertTrue(k in r)
863 3a19e99b Sofia Papagiannaki
#                self.assertEqual(r[k], meta[obj][k])
864 3a19e99b Sofia Papagiannaki
865 3a19e99b Sofia Papagiannaki
        # assert other has not been created under copy folder
866 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
867 3a19e99b Sofia Papagiannaki
                        '%s/%s' % (copy_folder,
868 3a19e99b Sofia Papagiannaki
                                   other.replace(folder, copy_folder)))
869 3a19e99b Sofia Papagiannaki
        r = self.head(url)
870 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
871 3a19e99b Sofia Papagiannaki
872 3a19e99b Sofia Papagiannaki
873 3a19e99b Sofia Papagiannaki
class ObjectPost(PithosAPITest):
874 3a19e99b Sofia Papagiannaki
    def setUp(self):
875 3a19e99b Sofia Papagiannaki
        PithosAPITest.setUp(self)
876 3a19e99b Sofia Papagiannaki
        self.container = 'c1'
877 3a19e99b Sofia Papagiannaki
        self.create_container(self.container)
878 3a19e99b Sofia Papagiannaki
        self.object, self.object_data = self.upload_object(self.container)[:2]
879 3a19e99b Sofia Papagiannaki
880 3a19e99b Sofia Papagiannaki
    def test_update_meta(self):
881 3a19e99b Sofia Papagiannaki
        with AssertUUidInvariant(self.get_object_info,
882 3a19e99b Sofia Papagiannaki
                                 self.container,
883 3a19e99b Sofia Papagiannaki
                                 self.object):
884 3a19e99b Sofia Papagiannaki
            # update metadata
885 3a19e99b Sofia Papagiannaki
            d = {'a' * 114: 'b' * 256}
886 3a19e99b Sofia Papagiannaki
            kwargs = dict(('HTTP_X_OBJECT_META_%s' % k, v) for
887 3a19e99b Sofia Papagiannaki
                          k, v in d.items())
888 3a19e99b Sofia Papagiannaki
            url = join_urls(self.pithos_path, self.user, self.container,
889 3a19e99b Sofia Papagiannaki
                            self.object)
890 3a19e99b Sofia Papagiannaki
            r = self.post(url, content_type='', **kwargs)
891 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 202)
892 3a19e99b Sofia Papagiannaki
893 3a19e99b Sofia Papagiannaki
            # assert metadata have been updated
894 3a19e99b Sofia Papagiannaki
            meta = self.get_object_meta(self.container, self.object)
895 3a19e99b Sofia Papagiannaki
896 3a19e99b Sofia Papagiannaki
            for k, v in d.items():
897 3a19e99b Sofia Papagiannaki
                key = 'X-Object-Meta-%s' % k.title()
898 3a19e99b Sofia Papagiannaki
                self.assertTrue(key in meta)
899 3a19e99b Sofia Papagiannaki
                self.assertTrue(meta[key], v)
900 3a19e99b Sofia Papagiannaki
901 3a19e99b Sofia Papagiannaki
            # Header key too large
902 3a19e99b Sofia Papagiannaki
            d = {'a' * 115: 'b' * 256}
903 3a19e99b Sofia Papagiannaki
            kwargs = dict(('HTTP_X_OBJECT_META_%s' % k, v) for
904 3a19e99b Sofia Papagiannaki
                          k, v in d.items())
905 3a19e99b Sofia Papagiannaki
            r = self.post(url, content_type='', **kwargs)
906 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 400)
907 3a19e99b Sofia Papagiannaki
908 3a19e99b Sofia Papagiannaki
            # Header value too large
909 3a19e99b Sofia Papagiannaki
            d = {'a' * 114: 'b' * 257}
910 3a19e99b Sofia Papagiannaki
            kwargs = dict(('HTTP_X_OBJECT_META_%s' % k, v) for
911 3a19e99b Sofia Papagiannaki
                          k, v in d.items())
912 3a19e99b Sofia Papagiannaki
            r = self.post(url, content_type='', **kwargs)
913 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 400)
914 3a19e99b Sofia Papagiannaki
915 3a19e99b Sofia Papagiannaki
#            # Check utf-8 meta
916 3a19e99b Sofia Papagiannaki
#            d = {'α' * (114 / 2): 'β' * (256 / 2)}
917 3a19e99b Sofia Papagiannaki
#            kwargs = dict(('HTTP_X_OBJECT_META_%s' % quote(k), quote(v)) for
918 3a19e99b Sofia Papagiannaki
#                          k, v in d.items())
919 3a19e99b Sofia Papagiannaki
#            url = join_urls(self.pithos_path, self.user, self.container,
920 3a19e99b Sofia Papagiannaki
#                            self.object)
921 3a19e99b Sofia Papagiannaki
#            r = self.post(url, content_type='', **kwargs)
922 3a19e99b Sofia Papagiannaki
#            self.assertEqual(r.status_code, 202)
923 3a19e99b Sofia Papagiannaki
#
924 3a19e99b Sofia Papagiannaki
#            # assert metadata have been updated
925 3a19e99b Sofia Papagiannaki
#            meta = self.get_object_meta(self.container, self.object)
926 3a19e99b Sofia Papagiannaki
#
927 3a19e99b Sofia Papagiannaki
#            for k, v in d.items():
928 3a19e99b Sofia Papagiannaki
#                key = 'X-Object-Meta-%s' % k.title()
929 3a19e99b Sofia Papagiannaki
#                self.assertTrue(key in meta)
930 3a19e99b Sofia Papagiannaki
#                self.assertTrue(meta[key], v)
931 3a19e99b Sofia Papagiannaki
#
932 3a19e99b Sofia Papagiannaki
#            # Header key too large
933 3a19e99b Sofia Papagiannaki
#            d = {'α' * 114: 'β' * (256 / 2)}
934 3a19e99b Sofia Papagiannaki
#            kwargs = dict(('HTTP_X_OBJECT_META_%s' % quote(k), quote(v)) for
935 3a19e99b Sofia Papagiannaki
#                          k, v in d.items())
936 3a19e99b Sofia Papagiannaki
#            r = self.post(url, content_type='', **kwargs)
937 3a19e99b Sofia Papagiannaki
#            self.assertEqual(r.status_code, 400)
938 3a19e99b Sofia Papagiannaki
#
939 3a19e99b Sofia Papagiannaki
#            # Header value too large
940 3a19e99b Sofia Papagiannaki
#            d = {'α' * 114: 'β' * 256}
941 3a19e99b Sofia Papagiannaki
#            kwargs = dict(('HTTP_X_OBJECT_META_%s' % quote(k), quote(v)) for
942 3a19e99b Sofia Papagiannaki
#                          k, v in d.items())
943 3a19e99b Sofia Papagiannaki
#            r = self.udpate(url, content_type='', **kwargs)
944 3a19e99b Sofia Papagiannaki
#            self.assertEqual(r.status_code, 400)
945 3a19e99b Sofia Papagiannaki
946 3a19e99b Sofia Papagiannaki
    def test_update_object(self):
947 3a19e99b Sofia Papagiannaki
        block_size = pithos_settings.BACKEND_BLOCK_SIZE
948 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(
949 3a19e99b Sofia Papagiannaki
            self.container, length=random.randint(
950 3a19e99b Sofia Papagiannaki
                block_size + 1, 2 * block_size))[:2]
951 3a19e99b Sofia Papagiannaki
952 3a19e99b Sofia Papagiannaki
        length = len(odata)
953 3a19e99b Sofia Papagiannaki
        first_byte_pos = random.randint(1, block_size)
954 3a19e99b Sofia Papagiannaki
        last_byte_pos = random.randint(block_size + 1, length - 1)
955 3a19e99b Sofia Papagiannaki
        range = 'bytes %s-%s/%s' % (first_byte_pos, last_byte_pos, length)
956 3a19e99b Sofia Papagiannaki
        kwargs = {'content_type': 'application/octet-stream',
957 3a19e99b Sofia Papagiannaki
                  'HTTP_CONTENT_RANGE': range}
958 3a19e99b Sofia Papagiannaki
959 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
960 3a19e99b Sofia Papagiannaki
        partial = last_byte_pos - first_byte_pos + 1
961 3a19e99b Sofia Papagiannaki
        data = get_random_data(partial)
962 3a19e99b Sofia Papagiannaki
        r = self.post(url, data=data, **kwargs)
963 3a19e99b Sofia Papagiannaki
964 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
965 3a19e99b Sofia Papagiannaki
        self.assertTrue('ETag' in r)
966 3a19e99b Sofia Papagiannaki
        updated_data = odata.replace(odata[first_byte_pos: last_byte_pos + 1],
967 3a19e99b Sofia Papagiannaki
                                     data)
968 3a19e99b Sofia Papagiannaki
        if pithos_settings.UPDATE_MD5:
969 5fe43b8c Sofia Papagiannaki
            etag = md5_hash(updated_data)
970 3a19e99b Sofia Papagiannaki
        else:
971 3a19e99b Sofia Papagiannaki
            etag = merkle(updated_data)
972 3a19e99b Sofia Papagiannaki
        #self.assertEqual(r['ETag'], etag)
973 3a19e99b Sofia Papagiannaki
974 3a19e99b Sofia Papagiannaki
        # check modified object
975 3a19e99b Sofia Papagiannaki
        r = self.get(url)
976 3a19e99b Sofia Papagiannaki
977 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
978 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, updated_data)
979 3a19e99b Sofia Papagiannaki
        self.assertEqual(etag, r['ETag'])
980 3a19e99b Sofia Papagiannaki
981 3a19e99b Sofia Papagiannaki
    def test_update_object_divided_by_blocksize(self):
982 3a19e99b Sofia Papagiannaki
        block_size = pithos_settings.BACKEND_BLOCK_SIZE
983 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(self.container,
984 3a19e99b Sofia Papagiannaki
                                          length=2 * block_size)[:2]
985 3a19e99b Sofia Papagiannaki
986 3a19e99b Sofia Papagiannaki
        length = len(odata)
987 3a19e99b Sofia Papagiannaki
        first_byte_pos = block_size
988 3a19e99b Sofia Papagiannaki
        last_byte_pos = 2 * block_size - 1
989 3a19e99b Sofia Papagiannaki
        range = 'bytes %s-%s/%s' % (first_byte_pos, last_byte_pos, length)
990 3a19e99b Sofia Papagiannaki
        kwargs = {'content_type': 'application/octet-stream',
991 3a19e99b Sofia Papagiannaki
                  'HTTP_CONTENT_RANGE': range}
992 3a19e99b Sofia Papagiannaki
993 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
994 3a19e99b Sofia Papagiannaki
        partial = last_byte_pos - first_byte_pos + 1
995 3a19e99b Sofia Papagiannaki
        data = get_random_data(partial)
996 3a19e99b Sofia Papagiannaki
        r = self.post(url, data=data, **kwargs)
997 3a19e99b Sofia Papagiannaki
998 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
999 3a19e99b Sofia Papagiannaki
        self.assertTrue('ETag' in r)
1000 3a19e99b Sofia Papagiannaki
        updated_data = odata.replace(odata[first_byte_pos: last_byte_pos + 1],
1001 3a19e99b Sofia Papagiannaki
                                     data)
1002 3a19e99b Sofia Papagiannaki
        if pithos_settings.UPDATE_MD5:
1003 5fe43b8c Sofia Papagiannaki
            etag = md5_hash(updated_data)
1004 3a19e99b Sofia Papagiannaki
        else:
1005 3a19e99b Sofia Papagiannaki
            etag = merkle(updated_data)
1006 3a19e99b Sofia Papagiannaki
        #self.assertEqual(r['ETag'], etag)
1007 3a19e99b Sofia Papagiannaki
1008 3a19e99b Sofia Papagiannaki
        # check modified object
1009 3a19e99b Sofia Papagiannaki
        r = self.get(url)
1010 3a19e99b Sofia Papagiannaki
1011 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
1012 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.content, updated_data)
1013 3a19e99b Sofia Papagiannaki
        self.assertEqual(etag, r['ETag'])
1014 3a19e99b Sofia Papagiannaki
1015 3a19e99b Sofia Papagiannaki
    def test_update_object_invalid_content_length(self):
1016 3a19e99b Sofia Papagiannaki
        block_size = pithos_settings.BACKEND_BLOCK_SIZE
1017 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(
1018 3a19e99b Sofia Papagiannaki
            self.container, length=random.randint(
1019 3a19e99b Sofia Papagiannaki
                block_size + 1, 2 * block_size))[:2]
1020 3a19e99b Sofia Papagiannaki
1021 3a19e99b Sofia Papagiannaki
        length = len(odata)
1022 3a19e99b Sofia Papagiannaki
        first_byte_pos = random.randint(1, block_size)
1023 3a19e99b Sofia Papagiannaki
        last_byte_pos = random.randint(block_size + 1, length - 1)
1024 3a19e99b Sofia Papagiannaki
        partial = last_byte_pos - first_byte_pos + 1
1025 3a19e99b Sofia Papagiannaki
        data = get_random_data(partial)
1026 3a19e99b Sofia Papagiannaki
        range = 'bytes %s-%s/%s' % (first_byte_pos, last_byte_pos, length)
1027 3a19e99b Sofia Papagiannaki
        kwargs = {'content_type': 'application/octet-stream',
1028 3a19e99b Sofia Papagiannaki
                  'HTTP_CONTENT_RANGE': range,
1029 3a19e99b Sofia Papagiannaki
                  'CONTENT_LENGTH': partial + 1}
1030 3a19e99b Sofia Papagiannaki
1031 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
1032 3a19e99b Sofia Papagiannaki
        r = self.post(url, data=data, **kwargs)
1033 3a19e99b Sofia Papagiannaki
1034 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
1035 3a19e99b Sofia Papagiannaki
1036 3a19e99b Sofia Papagiannaki
    def test_update_object_invalid_range(self):
1037 3a19e99b Sofia Papagiannaki
        block_size = pithos_settings.BACKEND_BLOCK_SIZE
1038 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(
1039 3a19e99b Sofia Papagiannaki
            self.container, length=random.randint(block_size + 1,
1040 3a19e99b Sofia Papagiannaki
                                                  2 * block_size))[:2]
1041 3a19e99b Sofia Papagiannaki
1042 3a19e99b Sofia Papagiannaki
        length = len(odata)
1043 3a19e99b Sofia Papagiannaki
        first_byte_pos = random.randint(1, block_size)
1044 3a19e99b Sofia Papagiannaki
        last_byte_pos = first_byte_pos - 1
1045 3a19e99b Sofia Papagiannaki
        range = 'bytes %s-%s/%s' % (first_byte_pos, last_byte_pos, length)
1046 3a19e99b Sofia Papagiannaki
        kwargs = {'content_type': 'application/octet-stream',
1047 3a19e99b Sofia Papagiannaki
                  'HTTP_CONTENT_RANGE': range}
1048 3a19e99b Sofia Papagiannaki
1049 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
1050 5fe43b8c Sofia Papagiannaki
        r = self.post(url, data=get_random_data(), **kwargs)
1051 3a19e99b Sofia Papagiannaki
1052 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 416)
1053 3a19e99b Sofia Papagiannaki
1054 3a19e99b Sofia Papagiannaki
    def test_update_object_out_of_limits(self):
1055 3a19e99b Sofia Papagiannaki
        block_size = pithos_settings.BACKEND_BLOCK_SIZE
1056 3a19e99b Sofia Papagiannaki
        oname, odata = self.upload_object(
1057 3a19e99b Sofia Papagiannaki
            self.container, length=random.randint(block_size + 1,
1058 3a19e99b Sofia Papagiannaki
                                                  2 * block_size))[:2]
1059 3a19e99b Sofia Papagiannaki
1060 3a19e99b Sofia Papagiannaki
        length = len(odata)
1061 3a19e99b Sofia Papagiannaki
        first_byte_pos = random.randint(1, block_size)
1062 3a19e99b Sofia Papagiannaki
        last_byte_pos = length + 1
1063 3a19e99b Sofia Papagiannaki
        range = 'bytes %s-%s/%s' % (first_byte_pos, last_byte_pos, length)
1064 3a19e99b Sofia Papagiannaki
        kwargs = {'content_type': 'application/octet-stream',
1065 3a19e99b Sofia Papagiannaki
                  'HTTP_CONTENT_RANGE': range}
1066 3a19e99b Sofia Papagiannaki
1067 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, oname)
1068 5fe43b8c Sofia Papagiannaki
        r = self.post(url, data=get_random_data(), **kwargs)
1069 3a19e99b Sofia Papagiannaki
1070 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 416)
1071 3a19e99b Sofia Papagiannaki
1072 3a19e99b Sofia Papagiannaki
    def test_append(self):
1073 5fe43b8c Sofia Papagiannaki
        data = get_random_data()
1074 5fe43b8c Sofia Papagiannaki
        length = len(data)
1075 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
1076 3a19e99b Sofia Papagiannaki
                        self.object)
1077 3a19e99b Sofia Papagiannaki
        r = self.post(url, data=data, content_type='application/octet-stream',
1078 3a19e99b Sofia Papagiannaki
                      HTTP_CONTENT_LENGTH=str(length),
1079 3a19e99b Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes */*')
1080 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1081 3a19e99b Sofia Papagiannaki
1082 3a19e99b Sofia Papagiannaki
        r = self.get(url)
1083 3a19e99b Sofia Papagiannaki
        content = r.content
1084 3a19e99b Sofia Papagiannaki
        self.assertEqual(len(content), len(self.object_data) + length)
1085 3a19e99b Sofia Papagiannaki
        self.assertEqual(content, self.object_data + data)
1086 3a19e99b Sofia Papagiannaki
1087 5fe43b8c Sofia Papagiannaki
    # TODO Fix the test
1088 5fe43b8c Sofia Papagiannaki
    def _test_update_with_chunked_transfer(self):
1089 5fe43b8c Sofia Papagiannaki
        data = get_random_data()
1090 5fe43b8c Sofia Papagiannaki
        length = len(data)
1091 3a19e99b Sofia Papagiannaki
1092 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
1093 3a19e99b Sofia Papagiannaki
                        self.object)
1094 3a19e99b Sofia Papagiannaki
        r = self.post(url, data=data, content_type='application/octet-stream',
1095 3a19e99b Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes 0-/*',
1096 3a19e99b Sofia Papagiannaki
                      HTTP_TRANSFER_ENCODING='chunked')
1097 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1098 3a19e99b Sofia Papagiannaki
1099 3a19e99b Sofia Papagiannaki
        # check modified object
1100 3a19e99b Sofia Papagiannaki
        r = self.get(url)
1101 3a19e99b Sofia Papagiannaki
        content = r.content
1102 3a19e99b Sofia Papagiannaki
        self.assertEqual(content[0:length], data)
1103 3a19e99b Sofia Papagiannaki
        self.assertEqual(content[length:], self.object_data[length:])
1104 3a19e99b Sofia Papagiannaki
1105 3a19e99b Sofia Papagiannaki
    def test_update_from_other_object(self):
1106 3a19e99b Sofia Papagiannaki
        src = self.object
1107 bc4f25c0 Sofia Papagiannaki
        dest = get_random_name()
1108 3a19e99b Sofia Papagiannaki
1109 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, src)
1110 3a19e99b Sofia Papagiannaki
        r = self.get(url)
1111 3a19e99b Sofia Papagiannaki
        source_data = r.content
1112 3a19e99b Sofia Papagiannaki
        source_meta = self.get_object_info(self.container, src)
1113 3a19e99b Sofia Papagiannaki
1114 3a19e99b Sofia Papagiannaki
        # update zero length object
1115 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, dest)
1116 3a19e99b Sofia Papagiannaki
        r = self.put(url, data='')
1117 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
1118 3a19e99b Sofia Papagiannaki
1119 3a19e99b Sofia Papagiannaki
        r = self.post(url,
1120 3a19e99b Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes */*',
1121 3a19e99b Sofia Papagiannaki
                      HTTP_X_SOURCE_OBJECT='/%s/%s' % (self.container, src))
1122 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1123 3a19e99b Sofia Papagiannaki
1124 3a19e99b Sofia Papagiannaki
        r = self.get(url)
1125 3a19e99b Sofia Papagiannaki
        dest_data = r.content
1126 3a19e99b Sofia Papagiannaki
        dest_meta = self.get_object_info(self.container, dest)
1127 3a19e99b Sofia Papagiannaki
1128 3a19e99b Sofia Papagiannaki
        self.assertEqual(source_data, dest_data)
1129 3a19e99b Sofia Papagiannaki
        #self.assertEqual(source_meta['ETag'], dest_meta['ETag'])
1130 3a19e99b Sofia Papagiannaki
        self.assertEqual(source_meta['X-Object-Hash'],
1131 3a19e99b Sofia Papagiannaki
                         dest_meta['X-Object-Hash'])
1132 3a19e99b Sofia Papagiannaki
        self.assertTrue(
1133 3a19e99b Sofia Papagiannaki
            source_meta['X-Object-UUID'] != dest_meta['X-Object-UUID'])
1134 3a19e99b Sofia Papagiannaki
1135 3a19e99b Sofia Papagiannaki
    def test_update_range_from_other_object(self):
1136 3a19e99b Sofia Papagiannaki
        src = self.object
1137 bc4f25c0 Sofia Papagiannaki
        dest = get_random_name()
1138 3a19e99b Sofia Papagiannaki
1139 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, src)
1140 3a19e99b Sofia Papagiannaki
        r = self.get(url)
1141 3a19e99b Sofia Papagiannaki
        source_data = r.content
1142 3a19e99b Sofia Papagiannaki
1143 3a19e99b Sofia Papagiannaki
        # update zero length object
1144 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, dest)
1145 5fe43b8c Sofia Papagiannaki
        initial_data = get_random_data()
1146 5fe43b8c Sofia Papagiannaki
        length = len(initial_data)
1147 a1f429b2 Sofia Papagiannaki
        r = self.put(url, data=initial_data)
1148 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
1149 3a19e99b Sofia Papagiannaki
1150 3a19e99b Sofia Papagiannaki
        offset = random.randint(1, length - 2)
1151 3a19e99b Sofia Papagiannaki
        upto = random.randint(offset, length - 1)
1152 3a19e99b Sofia Papagiannaki
        r = self.post(url,
1153 3a19e99b Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes %s-%s/*' % (offset, upto),
1154 3a19e99b Sofia Papagiannaki
                      HTTP_X_SOURCE_OBJECT='/%s/%s' % (self.container, src))
1155 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1156 3a19e99b Sofia Papagiannaki
1157 3a19e99b Sofia Papagiannaki
        r = self.get(url)
1158 3a19e99b Sofia Papagiannaki
        content = r.content
1159 a1f429b2 Sofia Papagiannaki
        self.assertEqual(content, (initial_data[:offset] +
1160 a1f429b2 Sofia Papagiannaki
                                   source_data[:upto - offset + 1] +
1161 a1f429b2 Sofia Papagiannaki
                                   initial_data[upto + 1:]))
1162 3a19e99b Sofia Papagiannaki
1163 e4c7cbeb Sofia Papagiannaki
    def test_update_range_from_invalid_other_object(self):
1164 e4c7cbeb Sofia Papagiannaki
        src = self.object
1165 e4c7cbeb Sofia Papagiannaki
        dest = get_random_name()
1166 e4c7cbeb Sofia Papagiannaki
1167 e4c7cbeb Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, src)
1168 e4c7cbeb Sofia Papagiannaki
        r = self.get(url)
1169 e4c7cbeb Sofia Papagiannaki
1170 e4c7cbeb Sofia Papagiannaki
        # update zero length object
1171 e4c7cbeb Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, dest)
1172 e4c7cbeb Sofia Papagiannaki
        initial_data = get_random_data()
1173 e4c7cbeb Sofia Papagiannaki
        length = len(initial_data)
1174 e4c7cbeb Sofia Papagiannaki
        r = self.put(url, data=initial_data)
1175 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
1176 e4c7cbeb Sofia Papagiannaki
1177 e4c7cbeb Sofia Papagiannaki
        offset = random.randint(1, length - 2)
1178 e4c7cbeb Sofia Papagiannaki
        upto = random.randint(offset, length - 1)
1179 e4c7cbeb Sofia Papagiannaki
1180 e4c7cbeb Sofia Papagiannaki
        # source object does not start with /
1181 e4c7cbeb Sofia Papagiannaki
        r = self.post(url,
1182 e4c7cbeb Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes %s-%s/*' % (offset, upto),
1183 e4c7cbeb Sofia Papagiannaki
                      HTTP_X_SOURCE_OBJECT='%s/%s' % (self.container, src))
1184 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(r.status_code, 400)
1185 e4c7cbeb Sofia Papagiannaki
1186 e4c7cbeb Sofia Papagiannaki
        # source object does not exist
1187 e4c7cbeb Sofia Papagiannaki
        r = self.post(url,
1188 e4c7cbeb Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes %s-%s/*' % (offset, upto),
1189 e4c7cbeb Sofia Papagiannaki
                      HTTP_X_SOURCE_OBJECT='/%s/%s1' % (self.container, src))
1190 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
1191 e4c7cbeb Sofia Papagiannaki
1192 e4c7cbeb Sofia Papagiannaki
    def test_update_from_other_version(self):
1193 e4c7cbeb Sofia Papagiannaki
        versions = []
1194 e4c7cbeb Sofia Papagiannaki
        info = self.get_object_info(self.container, self.object)
1195 e4c7cbeb Sofia Papagiannaki
        versions.append(info['X-Object-Version'])
1196 e4c7cbeb Sofia Papagiannaki
        pre_length = int(info['Content-Length'])
1197 e4c7cbeb Sofia Papagiannaki
1198 e4c7cbeb Sofia Papagiannaki
        # update object
1199 e4c7cbeb Sofia Papagiannaki
        d1, r = self.upload_object(self.container, self.object,
1200 e4c7cbeb Sofia Papagiannaki
                                   length=pre_length - 1)[1:]
1201 e4c7cbeb Sofia Papagiannaki
        self.assertTrue('X-Object-Version' in r)
1202 e4c7cbeb Sofia Papagiannaki
        versions.append(r['X-Object-Version'])
1203 e4c7cbeb Sofia Papagiannaki
1204 e4c7cbeb Sofia Papagiannaki
        # update object
1205 e4c7cbeb Sofia Papagiannaki
        d2, r = self.upload_object(self.container, self.object,
1206 e4c7cbeb Sofia Papagiannaki
                                   length=pre_length - 2)[1:]
1207 e4c7cbeb Sofia Papagiannaki
        self.assertTrue('X-Object-Version' in r)
1208 e4c7cbeb Sofia Papagiannaki
        versions.append(r['X-Object-Version'])
1209 e4c7cbeb Sofia Papagiannaki
1210 e4c7cbeb Sofia Papagiannaki
        # get previous version
1211 e4c7cbeb Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
1212 e4c7cbeb Sofia Papagiannaki
                        self.object)
1213 e4c7cbeb Sofia Papagiannaki
        r = self.get('%s?version=list&format=json' % url)
1214 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
1215 e4c7cbeb Sofia Papagiannaki
        l = json.loads(r.content)['versions']
1216 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(len(l), 3)
1217 e4c7cbeb Sofia Papagiannaki
        self.assertEqual([str(v[0]) for v in l], versions)
1218 e4c7cbeb Sofia Papagiannaki
1219 e4c7cbeb Sofia Papagiannaki
        # update with the previous version
1220 e4c7cbeb Sofia Papagiannaki
        r = self.post(url,
1221 e4c7cbeb Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes 0-/*',
1222 e4c7cbeb Sofia Papagiannaki
                      HTTP_X_SOURCE_OBJECT='/%s/%s' % (self.container,
1223 e4c7cbeb Sofia Papagiannaki
                                                       self.object),
1224 e4c7cbeb Sofia Papagiannaki
                      HTTP_X_SOURCE_VERSION=versions[0])
1225 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1226 e4c7cbeb Sofia Papagiannaki
1227 e4c7cbeb Sofia Papagiannaki
        # check content
1228 e4c7cbeb Sofia Papagiannaki
        r = self.get(url)
1229 e4c7cbeb Sofia Papagiannaki
        content = r.content
1230 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(len(content), pre_length)
1231 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(content, self.object_data)
1232 e4c7cbeb Sofia Papagiannaki
1233 e4c7cbeb Sofia Papagiannaki
        # update object
1234 e4c7cbeb Sofia Papagiannaki
        d3, r = self.upload_object(self.container, self.object,
1235 e4c7cbeb Sofia Papagiannaki
                                   length=len(d2) + 1)[1:]
1236 e4c7cbeb Sofia Papagiannaki
        self.assertTrue('X-Object-Version' in r)
1237 e4c7cbeb Sofia Papagiannaki
        versions.append(r['X-Object-Version'])
1238 e4c7cbeb Sofia Papagiannaki
1239 e4c7cbeb Sofia Papagiannaki
        # update with the previous version
1240 e4c7cbeb Sofia Papagiannaki
        r = self.post(url,
1241 e4c7cbeb Sofia Papagiannaki
                      HTTP_CONTENT_RANGE='bytes 0-/*',
1242 e4c7cbeb Sofia Papagiannaki
                      HTTP_X_SOURCE_OBJECT='/%s/%s' % (self.container,
1243 e4c7cbeb Sofia Papagiannaki
                                                       self.object),
1244 e4c7cbeb Sofia Papagiannaki
                      HTTP_X_SOURCE_VERSION=versions[-2])
1245 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1246 e4c7cbeb Sofia Papagiannaki
1247 e4c7cbeb Sofia Papagiannaki
        # check content
1248 e4c7cbeb Sofia Papagiannaki
        r = self.get(url)
1249 e4c7cbeb Sofia Papagiannaki
        content = r.content
1250 e4c7cbeb Sofia Papagiannaki
        self.assertEqual(content, d2 + d3[-1])
1251 e4c7cbeb Sofia Papagiannaki
1252 3a19e99b Sofia Papagiannaki
1253 3a19e99b Sofia Papagiannaki
class ObjectDelete(PithosAPITest):
1254 3a19e99b Sofia Papagiannaki
    def setUp(self):
1255 3a19e99b Sofia Papagiannaki
        PithosAPITest.setUp(self)
1256 3a19e99b Sofia Papagiannaki
        self.container = 'c1'
1257 3a19e99b Sofia Papagiannaki
        self.create_container(self.container)
1258 3a19e99b Sofia Papagiannaki
        self.object, self.object_data = self.upload_object(self.container)[:2]
1259 3a19e99b Sofia Papagiannaki
1260 3a19e99b Sofia Papagiannaki
    def test_delete(self):
1261 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
1262 3a19e99b Sofia Papagiannaki
                        self.object)
1263 3a19e99b Sofia Papagiannaki
        r = self.delete(url)
1264 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1265 3a19e99b Sofia Papagiannaki
1266 3a19e99b Sofia Papagiannaki
        r = self.head(url)
1267 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
1268 3a19e99b Sofia Papagiannaki
1269 3a19e99b Sofia Papagiannaki
    def test_delete_non_existent(self):
1270 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container,
1271 bc4f25c0 Sofia Papagiannaki
                        get_random_name())
1272 3a19e99b Sofia Papagiannaki
        r = self.delete(url)
1273 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 404)
1274 3a19e99b Sofia Papagiannaki
1275 3a19e99b Sofia Papagiannaki
    def test_delete_dir(self):
1276 3a19e99b Sofia Papagiannaki
        folder = self.create_folder(self.container)[0]
1277 3a19e99b Sofia Papagiannaki
        subfolder = self.create_folder(
1278 bc4f25c0 Sofia Papagiannaki
            self.container, oname='%s/%s' % (folder, get_random_name()))[0]
1279 3a19e99b Sofia Papagiannaki
        objects = [subfolder]
1280 3a19e99b Sofia Papagiannaki
        append = objects.append
1281 3a19e99b Sofia Papagiannaki
        meta = {}
1282 3a19e99b Sofia Papagiannaki
        meta[objects[0]] = {}
1283 3a19e99b Sofia Papagiannaki
        append(self.upload_object(self.container,
1284 bc4f25c0 Sofia Papagiannaki
                                  '%s/%s' % (folder, get_random_name()),
1285 3a19e99b Sofia Papagiannaki
                                  HTTP_X_OBJECT_META_DEPTH='1')[0])
1286 3a19e99b Sofia Papagiannaki
        meta[objects[1]] = {'X-Object-Meta-Depth': '1'}
1287 3a19e99b Sofia Papagiannaki
        append(self.upload_object(self.container,
1288 bc4f25c0 Sofia Papagiannaki
                                  '%s/%s' % (subfolder, get_random_name()),
1289 3a19e99b Sofia Papagiannaki
                                  HTTP_X_OBJECT_META_DEPTH='2')[0])
1290 3a19e99b Sofia Papagiannaki
        meta[objects[1]] = {'X-Object-Meta-Depth': '2'}
1291 3a19e99b Sofia Papagiannaki
        other = self.upload_object(self.container, strnextling(folder))[0]
1292 3a19e99b Sofia Papagiannaki
1293 3a19e99b Sofia Papagiannaki
        # move dir
1294 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, folder)
1295 3a19e99b Sofia Papagiannaki
        r = self.delete('%s?delimiter=/' % url)
1296 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1297 3a19e99b Sofia Papagiannaki
1298 3a19e99b Sofia Papagiannaki
        for obj in objects:
1299 3a19e99b Sofia Papagiannaki
            # assert object does not exist
1300 3a19e99b Sofia Papagiannaki
            url = join_urls(self.pithos_path, self.user, self.container, obj)
1301 3a19e99b Sofia Papagiannaki
            r = self.head(url)
1302 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 404)
1303 3a19e99b Sofia Papagiannaki
1304 3a19e99b Sofia Papagiannaki
        # assert other has not been deleted
1305 3a19e99b Sofia Papagiannaki
        url = join_urls(self.pithos_path, self.user, self.container, other)
1306 3a19e99b Sofia Papagiannaki
        r = self.head(url)
1307 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)