Statistics
| Branch: | Tag: | Revision:

root / pithos / api / tests.py @ 038f1ae9

History | View | Annotate | Download (67.9 kB)

1 4288ade0 Sofia Papagiannaki
# Copyright 2011 GRNET S.A. All rights reserved.
2 4288ade0 Sofia Papagiannaki
# 
3 4288ade0 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 4288ade0 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 4288ade0 Sofia Papagiannaki
# conditions are met:
6 4288ade0 Sofia Papagiannaki
# 
7 4288ade0 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 4288ade0 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 4288ade0 Sofia Papagiannaki
#      disclaimer.
10 4288ade0 Sofia Papagiannaki
# 
11 4288ade0 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 4288ade0 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 4288ade0 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 4288ade0 Sofia Papagiannaki
#      provided with the distribution.
15 4288ade0 Sofia Papagiannaki
# 
16 4288ade0 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 4288ade0 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 4288ade0 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 4288ade0 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 4288ade0 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 4288ade0 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 4288ade0 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 4288ade0 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 4288ade0 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 4288ade0 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 4288ade0 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 4288ade0 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 4288ade0 Sofia Papagiannaki
# 
29 4288ade0 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 4288ade0 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 4288ade0 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 4288ade0 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 4288ade0 Sofia Papagiannaki
34 b09c9aaa Sofia Papagiannaki
from django.test.client import Client
35 b09c9aaa Sofia Papagiannaki
from django.test import TestCase
36 b09c9aaa Sofia Papagiannaki
from django.utils import simplejson as json
37 b09c9aaa Sofia Papagiannaki
from xml.dom import minidom
38 b09c9aaa Sofia Papagiannaki
import types
39 b09c9aaa Sofia Papagiannaki
import hashlib
40 b09c9aaa Sofia Papagiannaki
import os
41 b09c9aaa Sofia Papagiannaki
import mimetypes
42 b09c9aaa Sofia Papagiannaki
import random
43 b09c9aaa Sofia Papagiannaki
import datetime
44 d1e43d6f Sofia Papagiannaki
import string
45 d1e43d6f Sofia Papagiannaki
from pithos.backends import backend
46 b09c9aaa Sofia Papagiannaki
47 b09c9aaa Sofia Papagiannaki
DATE_FORMATS = ["%a %b %d %H:%M:%S %Y",
48 b09c9aaa Sofia Papagiannaki
                "%A, %d-%b-%y %H:%M:%S GMT",
49 b09c9aaa Sofia Papagiannaki
                "%a, %d %b %Y %H:%M:%S GMT"]
50 b09c9aaa Sofia Papagiannaki
51 b09c9aaa Sofia Papagiannaki
class AaiClient(Client):
52 b09c9aaa Sofia Papagiannaki
    def request(self, **request):
53 02c0c3fa Antony Chazapis
        request['HTTP_X_AUTH_TOKEN'] = '0000'
54 b09c9aaa Sofia Papagiannaki
        return super(AaiClient, self).request(**request)
55 b09c9aaa Sofia Papagiannaki
56 b09c9aaa Sofia Papagiannaki
class BaseTestCase(TestCase):
57 b09c9aaa Sofia Papagiannaki
    #TODO unauthorized request
58 b09c9aaa Sofia Papagiannaki
    def setUp(self):
59 b09c9aaa Sofia Papagiannaki
        self.client = AaiClient()
60 b09c9aaa Sofia Papagiannaki
        self.headers = {
61 b09c9aaa Sofia Papagiannaki
            'account':(
62 b09c9aaa Sofia Papagiannaki
                'X-Account-Container-Count',
63 b09c9aaa Sofia Papagiannaki
                'X-Account-Bytes-Used',
64 b09c9aaa Sofia Papagiannaki
                'Last-Modified',
65 b09c9aaa Sofia Papagiannaki
                'Content-Length',
66 b09c9aaa Sofia Papagiannaki
                'Date',
67 b09c9aaa Sofia Papagiannaki
                'Content-Type',),
68 b09c9aaa Sofia Papagiannaki
            'container':(
69 b09c9aaa Sofia Papagiannaki
                'X-Container-Object-Count',
70 b09c9aaa Sofia Papagiannaki
                'X-Container-Bytes-Used',
71 b09c9aaa Sofia Papagiannaki
                'Content-Type',
72 b09c9aaa Sofia Papagiannaki
                'Last-Modified',
73 b09c9aaa Sofia Papagiannaki
                'Content-Length',
74 33ffca25 Sofia Papagiannaki
                'Date',
75 33ffca25 Sofia Papagiannaki
                'X-Container-Block-Size',
76 307915f1 Antony Chazapis
                'X-Container-Block-Hash',
77 307915f1 Antony Chazapis
                'X-Container-Policy-Quota',
78 307915f1 Antony Chazapis
                'X-Container-Policy-Versioning',),
79 b09c9aaa Sofia Papagiannaki
            'object':(
80 b09c9aaa Sofia Papagiannaki
                'ETag',
81 b09c9aaa Sofia Papagiannaki
                'Content-Length',
82 b09c9aaa Sofia Papagiannaki
                'Content-Type',
83 b09c9aaa Sofia Papagiannaki
                'Content-Encoding',
84 b09c9aaa Sofia Papagiannaki
                'Last-Modified',
85 b09c9aaa Sofia Papagiannaki
                'Date',
86 b09c9aaa Sofia Papagiannaki
                'X-Object-Manifest',
87 58a6c894 Antony Chazapis
                'Content-Range',
88 104626e3 Antony Chazapis
                'X-Object-Modified-By',
89 58a6c894 Antony Chazapis
                'X-Object-Version',
90 58a6c894 Antony Chazapis
                'X-Object-Version-Timestamp',)}
91 b09c9aaa Sofia Papagiannaki
        self.contentTypes = {'xml':'application/xml',
92 b09c9aaa Sofia Papagiannaki
                             'json':'application/json',
93 b09c9aaa Sofia Papagiannaki
                             '':'text/plain'}
94 b09c9aaa Sofia Papagiannaki
        self.extended = {
95 b09c9aaa Sofia Papagiannaki
            'container':(
96 b09c9aaa Sofia Papagiannaki
                'name',
97 b09c9aaa Sofia Papagiannaki
                'count',
98 b09c9aaa Sofia Papagiannaki
                'bytes',
99 b09c9aaa Sofia Papagiannaki
                'last_modified'),
100 b09c9aaa Sofia Papagiannaki
            'object':(
101 b09c9aaa Sofia Papagiannaki
                'name',
102 b09c9aaa Sofia Papagiannaki
                'hash',
103 b09c9aaa Sofia Papagiannaki
                'bytes',
104 b09c9aaa Sofia Papagiannaki
                'content_type',
105 b09c9aaa Sofia Papagiannaki
                'content_encoding',
106 b09c9aaa Sofia Papagiannaki
                'last_modified',)}
107 b09c9aaa Sofia Papagiannaki
        self.return_codes = (400, 401, 404, 503,)
108 d1e43d6f Sofia Papagiannaki
109 b09c9aaa Sofia Papagiannaki
    def assertFault(self, response, status_code, name):
110 b09c9aaa Sofia Papagiannaki
        self.assertEqual(response.status_code, status_code)
111 d1e43d6f Sofia Papagiannaki
112 b09c9aaa Sofia Papagiannaki
    def assertBadRequest(self, response):
113 b09c9aaa Sofia Papagiannaki
        self.assertFault(response, 400, 'badRequest')
114 d1e43d6f Sofia Papagiannaki
115 b09c9aaa Sofia Papagiannaki
    def assertItemNotFound(self, response):
116 b09c9aaa Sofia Papagiannaki
        self.assertFault(response, 404, 'itemNotFound')
117 b09c9aaa Sofia Papagiannaki
118 b09c9aaa Sofia Papagiannaki
    def assertUnauthorized(self, response):
119 b09c9aaa Sofia Papagiannaki
        self.assertFault(response, 401, 'unauthorized')
120 b09c9aaa Sofia Papagiannaki
121 b09c9aaa Sofia Papagiannaki
    def assertServiceUnavailable(self, response):
122 b09c9aaa Sofia Papagiannaki
        self.assertFault(response, 503, 'serviceUnavailable')
123 b09c9aaa Sofia Papagiannaki
124 b09c9aaa Sofia Papagiannaki
    def assertNonEmpty(self, response):
125 b09c9aaa Sofia Papagiannaki
        self.assertFault(response, 409, 'nonEmpty')
126 b09c9aaa Sofia Papagiannaki
127 b09c9aaa Sofia Papagiannaki
    def assert_status(self, response, codes):
128 b09c9aaa Sofia Papagiannaki
        l = [elem for elem in self.return_codes]
129 b09c9aaa Sofia Papagiannaki
        if type(codes) == types.ListType:
130 b09c9aaa Sofia Papagiannaki
            l.extend(codes)
131 b09c9aaa Sofia Papagiannaki
        else:
132 b09c9aaa Sofia Papagiannaki
            l.append(codes)
133 b09c9aaa Sofia Papagiannaki
        self.assertTrue(response.status_code in l)
134 b09c9aaa Sofia Papagiannaki
135 b09c9aaa Sofia Papagiannaki
    def get_account_meta(self, account, exp_meta={}):
136 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s' % account
137 b09c9aaa Sofia Papagiannaki
        response = self.client.head(path)
138 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, 204)
139 b09c9aaa Sofia Papagiannaki
        self.assert_headers(response, 'account', exp_meta)
140 b09c9aaa Sofia Papagiannaki
        return response
141 b09c9aaa Sofia Papagiannaki
142 33ffca25 Sofia Papagiannaki
    def list_containers(self, account, limit=10000, marker='', format='',
143 33ffca25 Sofia Papagiannaki
                        **headers):
144 b09c9aaa Sofia Papagiannaki
        params = locals()
145 b09c9aaa Sofia Papagiannaki
        params.pop('self')
146 b09c9aaa Sofia Papagiannaki
        params.pop('account')
147 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s' % account
148 d1e43d6f Sofia Papagiannaki
        response = self.client.get(path, params, **headers)
149 d1e43d6f Sofia Papagiannaki
        self.assert_status(response, [200, 204, 304, 412])
150 b09c9aaa Sofia Papagiannaki
        response.content = response.content.strip()
151 b09c9aaa Sofia Papagiannaki
        if format:
152 b09c9aaa Sofia Papagiannaki
            self.assert_extended(response, format, 'container', limit)
153 b09c9aaa Sofia Papagiannaki
        else:
154 b09c9aaa Sofia Papagiannaki
            names = get_content_splitted(response)
155 b09c9aaa Sofia Papagiannaki
            self.assertTrue(len(names) <= limit)
156 b09c9aaa Sofia Papagiannaki
        return response
157 b09c9aaa Sofia Papagiannaki
158 b09c9aaa Sofia Papagiannaki
    def update_account_meta(self, account, **metadata):
159 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s' % account
160 b09c9aaa Sofia Papagiannaki
        response = self.client.post(path, **metadata)
161 0a425890 Antony Chazapis
        response.content = response.content
162 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, 202)
163 b09c9aaa Sofia Papagiannaki
        return response
164 b09c9aaa Sofia Papagiannaki
165 b09c9aaa Sofia Papagiannaki
    def get_container_meta(self, account, container, exp_meta={}):
166 b09c9aaa Sofia Papagiannaki
        params = locals()
167 b09c9aaa Sofia Papagiannaki
        params.pop('self')
168 b09c9aaa Sofia Papagiannaki
        params.pop('account')
169 b09c9aaa Sofia Papagiannaki
        params.pop('container')
170 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s' %(account, container)
171 b09c9aaa Sofia Papagiannaki
        response = self.client.head(path, params)
172 0a425890 Antony Chazapis
        response.content = response.content
173 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, 204)
174 b09c9aaa Sofia Papagiannaki
        if response.status_code == 204:
175 b09c9aaa Sofia Papagiannaki
            self.assert_headers(response, 'container', exp_meta)
176 b09c9aaa Sofia Papagiannaki
        return response
177 b09c9aaa Sofia Papagiannaki
178 33ffca25 Sofia Papagiannaki
    def list_objects(self, account, container, limit=10000, marker='',
179 33ffca25 Sofia Papagiannaki
                     prefix='', format='', path='', delimiter='', meta='',
180 33ffca25 Sofia Papagiannaki
                     **headers):
181 b09c9aaa Sofia Papagiannaki
        params = locals()
182 b09c9aaa Sofia Papagiannaki
        params.pop('self')
183 b09c9aaa Sofia Papagiannaki
        params.pop('account')
184 b09c9aaa Sofia Papagiannaki
        params.pop('container')
185 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s' % (account, container)
186 d1e43d6f Sofia Papagiannaki
        response = self.client.get(path, params, **headers)
187 b09c9aaa Sofia Papagiannaki
        response.content = response.content.strip()
188 b09c9aaa Sofia Papagiannaki
        if format:
189 b09c9aaa Sofia Papagiannaki
            self.assert_extended(response, format, 'object', limit)
190 d1e43d6f Sofia Papagiannaki
        self.assert_status(response, [200, 204, 304, 412])
191 b09c9aaa Sofia Papagiannaki
        return response
192 b09c9aaa Sofia Papagiannaki
193 b09c9aaa Sofia Papagiannaki
    def create_container(self, account, name, **meta):
194 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s' %(account, name)
195 b09c9aaa Sofia Papagiannaki
        response = self.client.put(path, **meta)
196 0a425890 Antony Chazapis
        response.content = response.content
197 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, [201, 202])
198 b09c9aaa Sofia Papagiannaki
        return response
199 b09c9aaa Sofia Papagiannaki
200 b09c9aaa Sofia Papagiannaki
    def update_container_meta(self, account, name, **meta):
201 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s' %(account, name)
202 33ffca25 Sofia Papagiannaki
        response = self.client.post(path,
203 33ffca25 Sofia Papagiannaki
                                    data=None,
204 33ffca25 Sofia Papagiannaki
                                    content_type='text/xml',
205 33ffca25 Sofia Papagiannaki
                                    follow=False, **meta)
206 0a425890 Antony Chazapis
        response.content = response.content
207 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, 202)
208 b09c9aaa Sofia Papagiannaki
        return response
209 b09c9aaa Sofia Papagiannaki
210 b09c9aaa Sofia Papagiannaki
    def delete_container(self, account, container):
211 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s' %(account, container)
212 b09c9aaa Sofia Papagiannaki
        response = self.client.delete(path)
213 0a425890 Antony Chazapis
        response.content = response.content
214 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, [204, 409])
215 b09c9aaa Sofia Papagiannaki
        return response
216 b09c9aaa Sofia Papagiannaki
217 b09c9aaa Sofia Papagiannaki
    def get_object_meta(self, account, container, name):
218 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s/%s' %(account, container, name)
219 b09c9aaa Sofia Papagiannaki
        response = self.client.head(path)
220 0a425890 Antony Chazapis
        response.content = response.content
221 468b8b86 Antony Chazapis
        self.assert_status(response, 200)
222 b09c9aaa Sofia Papagiannaki
        return response
223 b09c9aaa Sofia Papagiannaki
224 d1e43d6f Sofia Papagiannaki
    def get_object(self, account, container, name, format='', **headers):
225 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s/%s' %(account, container, name)
226 d1e43d6f Sofia Papagiannaki
        response = self.client.get(path, {'format':format}, **headers)
227 0a425890 Antony Chazapis
        response.content = response.content
228 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, [200, 206, 304, 412, 416])
229 b09c9aaa Sofia Papagiannaki
        if response.status_code in [200, 206]:
230 b09c9aaa Sofia Papagiannaki
            self.assert_headers(response, 'object')
231 b09c9aaa Sofia Papagiannaki
        return response
232 b09c9aaa Sofia Papagiannaki
233 33ffca25 Sofia Papagiannaki
    def upload_object(self, account, container, name, data, content_type='',
234 33ffca25 Sofia Papagiannaki
                      **headers):
235 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s/%s' %(account, container, name)
236 b09c9aaa Sofia Papagiannaki
        response = self.client.put(path, data, content_type, **headers)
237 0a425890 Antony Chazapis
        response.content = response.content
238 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, [201, 411, 422])
239 b09c9aaa Sofia Papagiannaki
        if response.status_code == 201:
240 b09c9aaa Sofia Papagiannaki
            self.assertTrue(response['Etag'])
241 b09c9aaa Sofia Papagiannaki
        return response
242 b09c9aaa Sofia Papagiannaki
243 b09c9aaa Sofia Papagiannaki
    def copy_object(self, account, container, name, src, **headers):
244 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s/%s' %(account, container, name)
245 b09c9aaa Sofia Papagiannaki
        headers['HTTP_X_COPY_FROM'] = src
246 b09c9aaa Sofia Papagiannaki
        response = self.client.put(path, **headers)
247 0a425890 Antony Chazapis
        response.content = response.content
248 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, 201)
249 b09c9aaa Sofia Papagiannaki
        return response
250 b09c9aaa Sofia Papagiannaki
251 b09c9aaa Sofia Papagiannaki
    def move_object(self, account, container, name, src, **headers):
252 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s/%s' % (account, container, name)
253 b09c9aaa Sofia Papagiannaki
        headers['HTTP_X_MOVE_FROM'] = src
254 b09c9aaa Sofia Papagiannaki
        response = self.client.put(path, **headers)
255 0a425890 Antony Chazapis
        response.content = response.content
256 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, 201)
257 b09c9aaa Sofia Papagiannaki
        return response
258 b09c9aaa Sofia Papagiannaki
259 79a6b6ee Sofia Papagiannaki
    def update_object(self, account, container, name, data='',
260 79a6b6ee Sofia Papagiannaki
                      content_type='', **headers):
261 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s/%s' %(account, container, name)
262 33ffca25 Sofia Papagiannaki
        response = self.client.post(path, data, content_type, **headers)
263 0a425890 Antony Chazapis
        response.content = response.content
264 33ffca25 Sofia Papagiannaki
        self.assert_status(response, [202, 204, 416])
265 b09c9aaa Sofia Papagiannaki
        return response
266 b09c9aaa Sofia Papagiannaki
267 b09c9aaa Sofia Papagiannaki
    def delete_object(self, account, container, name):
268 b09c9aaa Sofia Papagiannaki
        path = '/v1/%s/%s/%s' %(account, container, name)
269 b09c9aaa Sofia Papagiannaki
        response = self.client.delete(path)
270 0a425890 Antony Chazapis
        response.content = response.content
271 b09c9aaa Sofia Papagiannaki
        self.assert_status(response, 204)
272 b09c9aaa Sofia Papagiannaki
        return response
273 b09c9aaa Sofia Papagiannaki
274 b09c9aaa Sofia Papagiannaki
    def assert_headers(self, response, type, exp_meta={}):
275 b09c9aaa Sofia Papagiannaki
        entities = ['Account', 'Container', 'Container-Object', 'Object']
276 b09c9aaa Sofia Papagiannaki
        user_defined_meta = ['X-%s-Meta' %elem for elem in entities]
277 b09c9aaa Sofia Papagiannaki
        headers = [item for item in response._headers.values()]
278 33ffca25 Sofia Papagiannaki
        t = tuple(user_defined_meta)
279 33ffca25 Sofia Papagiannaki
        system_headers = [h for h in headers if not h[0].startswith(t)]
280 b09c9aaa Sofia Papagiannaki
        for h in system_headers:
281 b09c9aaa Sofia Papagiannaki
            self.assertTrue(h[0] in self.headers[type])
282 b09c9aaa Sofia Papagiannaki
            if exp_meta:
283 b09c9aaa Sofia Papagiannaki
                self.assertEqual(h[1], exp_meta[h[0]])
284 b09c9aaa Sofia Papagiannaki
285 b09c9aaa Sofia Papagiannaki
    def assert_extended(self, response, format, type, size):
286 33ffca25 Sofia Papagiannaki
        exp_content_type = self.contentTypes[format]
287 33ffca25 Sofia Papagiannaki
        self.assertEqual(response['Content-Type'].find(exp_content_type), 0)
288 b09c9aaa Sofia Papagiannaki
        if format == 'xml':
289 b09c9aaa Sofia Papagiannaki
            self.assert_xml(response, type, size)
290 b09c9aaa Sofia Papagiannaki
        elif format == 'json':
291 b09c9aaa Sofia Papagiannaki
            self.assert_json(response, type, size)
292 b09c9aaa Sofia Papagiannaki
293 b09c9aaa Sofia Papagiannaki
    def assert_json(self, response, type, size):
294 b09c9aaa Sofia Papagiannaki
        convert = lambda s: s.lower()
295 b09c9aaa Sofia Papagiannaki
        info = [convert(elem) for elem in self.extended[type]]
296 b09c9aaa Sofia Papagiannaki
        data = json.loads(response.content)
297 b09c9aaa Sofia Papagiannaki
        self.assertTrue(len(data) <= size)
298 b09c9aaa Sofia Papagiannaki
        for item in info:
299 b09c9aaa Sofia Papagiannaki
            for i in data:
300 b09c9aaa Sofia Papagiannaki
                if 'subdir' in i.keys():
301 b09c9aaa Sofia Papagiannaki
                    continue
302 b09c9aaa Sofia Papagiannaki
                self.assertTrue(item in i.keys())
303 b09c9aaa Sofia Papagiannaki
304 b09c9aaa Sofia Papagiannaki
    def assert_xml(self, response, type, size):
305 b09c9aaa Sofia Papagiannaki
        convert = lambda s: s.lower()
306 b09c9aaa Sofia Papagiannaki
        info = [convert(elem) for elem in self.extended[type]]
307 b09c9aaa Sofia Papagiannaki
        try:
308 b09c9aaa Sofia Papagiannaki
            info.remove('content_encoding')
309 b09c9aaa Sofia Papagiannaki
        except ValueError:
310 b09c9aaa Sofia Papagiannaki
            pass
311 b09c9aaa Sofia Papagiannaki
        xml = minidom.parseString(response.content)
312 b09c9aaa Sofia Papagiannaki
        for item in info:
313 b09c9aaa Sofia Papagiannaki
            nodes = xml.getElementsByTagName(item)
314 b09c9aaa Sofia Papagiannaki
            self.assertTrue(nodes)
315 b09c9aaa Sofia Papagiannaki
            self.assertTrue(len(nodes) <= size)
316 b09c9aaa Sofia Papagiannaki
            
317 b09c9aaa Sofia Papagiannaki
318 b09c9aaa Sofia Papagiannaki
    def upload_os_file(self, account, container, fullpath, meta={}):
319 b09c9aaa Sofia Papagiannaki
        try:
320 b09c9aaa Sofia Papagiannaki
            f = open(fullpath, 'r')
321 b09c9aaa Sofia Papagiannaki
            data = f.read()
322 b09c9aaa Sofia Papagiannaki
            name = os.path.split(fullpath)[-1]
323 b09c9aaa Sofia Papagiannaki
            return self.upload_data(account, container, name, data)    
324 b09c9aaa Sofia Papagiannaki
        except IOError:
325 b09c9aaa Sofia Papagiannaki
            return
326 b09c9aaa Sofia Papagiannaki
327 33ffca25 Sofia Papagiannaki
    def upload_random_data(self, account, container, name, length=1024,
328 33ffca25 Sofia Papagiannaki
                           meta={}):
329 33ffca25 Sofia Papagiannaki
        data = get_random_data(length)
330 b09c9aaa Sofia Papagiannaki
        return self.upload_data(account, container, name, data, meta)
331 b09c9aaa Sofia Papagiannaki
332 b09c9aaa Sofia Papagiannaki
    def upload_data(self, account, container, name, data, meta={}):
333 b09c9aaa Sofia Papagiannaki
        obj = {}
334 b09c9aaa Sofia Papagiannaki
        obj['name'] = name
335 b09c9aaa Sofia Papagiannaki
        try:
336 b09c9aaa Sofia Papagiannaki
            obj['data'] = data
337 d1e43d6f Sofia Papagiannaki
            obj['hash'] = compute_md5_hash(obj['data'])
338 b09c9aaa Sofia Papagiannaki
            meta.update({'HTTP_X_OBJECT_META_TEST':'test1',
339 b09c9aaa Sofia Papagiannaki
                         'HTTP_ETAG':obj['hash']})
340 33ffca25 Sofia Papagiannaki
            type, enc = mimetypes.guess_type(name)
341 33ffca25 Sofia Papagiannaki
            meta['HTTP_CONTENT_TYPE'] = type and type or 'plain/text'
342 b09c9aaa Sofia Papagiannaki
            if enc:
343 33ffca25 Sofia Papagiannaki
                meta['HTTP_CONTENT_ENCODING'] = enc
344 33ffca25 Sofia Papagiannaki
            
345 b09c9aaa Sofia Papagiannaki
            obj['meta'] = meta
346 b09c9aaa Sofia Papagiannaki
            r = self.upload_object(account,
347 b09c9aaa Sofia Papagiannaki
                               container,
348 b09c9aaa Sofia Papagiannaki
                               obj['name'],
349 b09c9aaa Sofia Papagiannaki
                               obj['data'],
350 b09c9aaa Sofia Papagiannaki
                               meta['HTTP_CONTENT_TYPE'],
351 b09c9aaa Sofia Papagiannaki
                               **meta)
352 b09c9aaa Sofia Papagiannaki
            if r.status_code == 201:
353 b09c9aaa Sofia Papagiannaki
                return obj
354 b09c9aaa Sofia Papagiannaki
        except IOError:
355 b09c9aaa Sofia Papagiannaki
            return
356 b09c9aaa Sofia Papagiannaki
357 d1e43d6f Sofia Papagiannaki
class AccountHead(BaseTestCase):
358 d1e43d6f Sofia Papagiannaki
    def setUp(self):
359 d1e43d6f Sofia Papagiannaki
        BaseTestCase.setUp(self)
360 d1e43d6f Sofia Papagiannaki
        self.account = 'test'
361 d1e43d6f Sofia Papagiannaki
        self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
362 d1e43d6f Sofia Papagiannaki
        for item in self.containers:
363 d1e43d6f Sofia Papagiannaki
            self.create_container(self.account, item)
364 d1e43d6f Sofia Papagiannaki
365 d1e43d6f Sofia Papagiannaki
    def tearDown(self):
366 d1e43d6f Sofia Papagiannaki
        for c in  get_content_splitted(self.list_containers(self.account)):
367 d1e43d6f Sofia Papagiannaki
            self.delete_container(self.account, c)
368 d1e43d6f Sofia Papagiannaki
369 d1e43d6f Sofia Papagiannaki
    def test_get_account_meta(self):
370 d1e43d6f Sofia Papagiannaki
        response = self.get_account_meta(self.account)
371 d1e43d6f Sofia Papagiannaki
        r2 = self.list_containers(self.account)
372 d1e43d6f Sofia Papagiannaki
        containers =  get_content_splitted(r2)
373 33ffca25 Sofia Papagiannaki
        l = str(len(containers))
374 33ffca25 Sofia Papagiannaki
        self.assertEqual(response['X-Account-Container-Count'], l)
375 d1e43d6f Sofia Papagiannaki
        size = 0
376 d1e43d6f Sofia Papagiannaki
        for c in containers:
377 d1e43d6f Sofia Papagiannaki
            r = self.get_container_meta(self.account, c)
378 d1e43d6f Sofia Papagiannaki
            size = size + int(r['X-Container-Bytes-Used'])
379 d1e43d6f Sofia Papagiannaki
        self.assertEqual(response['X-Account-Bytes-Used'], str(size))
380 d1e43d6f Sofia Papagiannaki
381 d1e43d6f Sofia Papagiannaki
    #def test_get_account_401(self):
382 d1e43d6f Sofia Papagiannaki
    #    response = self.get_account_meta('non-existing-account')
383 d1e43d6f Sofia Papagiannaki
    #    print response
384 d1e43d6f Sofia Papagiannaki
    #    self.assertEqual(response.status_code, 401)
385 d1e43d6f Sofia Papagiannaki
386 d1e43d6f Sofia Papagiannaki
class AccountGet(BaseTestCase):
387 b09c9aaa Sofia Papagiannaki
    def setUp(self):
388 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
389 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
390 b09c9aaa Sofia Papagiannaki
        #create some containers
391 b09c9aaa Sofia Papagiannaki
        self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
392 b09c9aaa Sofia Papagiannaki
        for item in self.containers:
393 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, item)
394 b09c9aaa Sofia Papagiannaki
395 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
396 b09c9aaa Sofia Papagiannaki
        for c in get_content_splitted(self.list_containers(self.account)):
397 b09c9aaa Sofia Papagiannaki
            response = self.delete_container(self.account, c)
398 b09c9aaa Sofia Papagiannaki
399 b09c9aaa Sofia Papagiannaki
    def test_list(self):
400 b09c9aaa Sofia Papagiannaki
        #list containers
401 b09c9aaa Sofia Papagiannaki
        response = self.list_containers(self.account)
402 b09c9aaa Sofia Papagiannaki
        containers = get_content_splitted(response)
403 b09c9aaa Sofia Papagiannaki
        self.assertEquals(self.containers, containers)
404 b09c9aaa Sofia Papagiannaki
405 b09c9aaa Sofia Papagiannaki
    #def test_list_204(self):
406 b09c9aaa Sofia Papagiannaki
    #    response = self.list_containers('non-existing-account')
407 b09c9aaa Sofia Papagiannaki
    #    self.assertEqual(response.status_code, 204)
408 b09c9aaa Sofia Papagiannaki
409 b09c9aaa Sofia Papagiannaki
    def test_list_with_limit(self):
410 b09c9aaa Sofia Papagiannaki
        limit = 2
411 b09c9aaa Sofia Papagiannaki
        response = self.list_containers(self.account, limit=limit)
412 b09c9aaa Sofia Papagiannaki
        containers = get_content_splitted(response)
413 b09c9aaa Sofia Papagiannaki
        self.assertEquals(len(containers), limit)
414 b09c9aaa Sofia Papagiannaki
        self.assertEquals(self.containers[:2], containers)
415 b09c9aaa Sofia Papagiannaki
416 b09c9aaa Sofia Papagiannaki
    def test_list_with_marker(self):
417 33ffca25 Sofia Papagiannaki
        l = 2
418 33ffca25 Sofia Papagiannaki
        m = 'bananas'
419 33ffca25 Sofia Papagiannaki
        response = self.list_containers(self.account, limit=l, marker=m)
420 b09c9aaa Sofia Papagiannaki
        containers =  get_content_splitted(response)
421 33ffca25 Sofia Papagiannaki
        i = self.containers.index(m) + 1
422 33ffca25 Sofia Papagiannaki
        self.assertEquals(self.containers[i:(i+l)], containers)
423 b09c9aaa Sofia Papagiannaki
        
424 33ffca25 Sofia Papagiannaki
        m = 'oranges'
425 33ffca25 Sofia Papagiannaki
        response = self.list_containers(self.account, limit=l, marker=m)
426 b09c9aaa Sofia Papagiannaki
        containers = get_content_splitted(response)
427 33ffca25 Sofia Papagiannaki
        i = self.containers.index(m) + 1
428 33ffca25 Sofia Papagiannaki
        self.assertEquals(self.containers[i:(i+l)], containers)
429 b09c9aaa Sofia Papagiannaki
430 b09c9aaa Sofia Papagiannaki
    #def test_extended_list(self):
431 b09c9aaa Sofia Papagiannaki
    #    self.list_containers(self.account, limit=3, format='xml')
432 b09c9aaa Sofia Papagiannaki
    #    self.list_containers(self.account, limit=3, format='json')
433 b09c9aaa Sofia Papagiannaki
434 b09c9aaa Sofia Papagiannaki
    def test_list_json_with_marker(self):
435 33ffca25 Sofia Papagiannaki
        l = 2
436 33ffca25 Sofia Papagiannaki
        m = 'bananas'
437 33ffca25 Sofia Papagiannaki
        response = self.list_containers(self.account, limit=l, marker=m,
438 33ffca25 Sofia Papagiannaki
                                        format='json')
439 b09c9aaa Sofia Papagiannaki
        containers = json.loads(response.content)
440 b09c9aaa Sofia Papagiannaki
        self.assertEqual(containers[0]['name'], 'kiwis')
441 b09c9aaa Sofia Papagiannaki
        self.assertEqual(containers[1]['name'], 'oranges')
442 b09c9aaa Sofia Papagiannaki
443 b09c9aaa Sofia Papagiannaki
    def test_list_xml_with_marker(self):
444 33ffca25 Sofia Papagiannaki
        l = 2
445 33ffca25 Sofia Papagiannaki
        m = 'oranges'
446 33ffca25 Sofia Papagiannaki
        response = self.list_containers(self.account, limit=l, marker=m,
447 33ffca25 Sofia Papagiannaki
                                        format='xml')
448 b09c9aaa Sofia Papagiannaki
        xml = minidom.parseString(response.content)
449 b09c9aaa Sofia Papagiannaki
        nodes = xml.getElementsByTagName('name')
450 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(nodes), 1)
451 b09c9aaa Sofia Papagiannaki
        self.assertEqual(nodes[0].childNodes[0].data, 'pears')
452 b09c9aaa Sofia Papagiannaki
453 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since(self):
454 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
455 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
456 d1e43d6f Sofia Papagiannaki
        
457 d1e43d6f Sofia Papagiannaki
        #add a new container
458 d1e43d6f Sofia Papagiannaki
        self.create_container(self.account,
459 d1e43d6f Sofia Papagiannaki
                              'dummy')
460 d1e43d6f Sofia Papagiannaki
461 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
462 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
463 d1e43d6f Sofia Papagiannaki
            
464 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_MODIFIED_SINCE':'%s' %past}
465 d1e43d6f Sofia Papagiannaki
            r = self.list_containers(self.account, **headers)
466 d1e43d6f Sofia Papagiannaki
            
467 d1e43d6f Sofia Papagiannaki
            #assert get success
468 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
469 d1e43d6f Sofia Papagiannaki
470 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since_invalid_date(self):
471 d1e43d6f Sofia Papagiannaki
        headers = {'HTTP_IF_MODIFIED_SINCE':''}
472 d1e43d6f Sofia Papagiannaki
        r = self.list_containers(self.account, **headers)
473 d1e43d6f Sofia Papagiannaki
            
474 d1e43d6f Sofia Papagiannaki
        #assert get success
475 d1e43d6f Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
476 d1e43d6f Sofia Papagiannaki
477 d1e43d6f Sofia Papagiannaki
    def test_if_not_modified_since(self):
478 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
479 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
480 d1e43d6f Sofia Papagiannaki
        
481 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
482 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_MODIFIED_SINCE':'%s' %since.strftime(f)}
483 d1e43d6f Sofia Papagiannaki
            r = self.list_containers(self.account, **headers)
484 d1e43d6f Sofia Papagiannaki
            
485 d1e43d6f Sofia Papagiannaki
            #assert not modified
486 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 304)
487 d1e43d6f Sofia Papagiannaki
488 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since(self):
489 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
490 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
491 d1e43d6f Sofia Papagiannaki
        
492 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
493 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_UNMODIFIED_SINCE':'%s' %since.strftime(f)}
494 d1e43d6f Sofia Papagiannaki
            r = self.list_containers(self.account, **headers)
495 d1e43d6f Sofia Papagiannaki
            
496 d1e43d6f Sofia Papagiannaki
            #assert success
497 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
498 d1e43d6f Sofia Papagiannaki
            self.assertEqual(self.containers, get_content_splitted(r))
499 d1e43d6f Sofia Papagiannaki
500 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since_precondition_failed(self):
501 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
502 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
503 d1e43d6f Sofia Papagiannaki
        
504 d1e43d6f Sofia Papagiannaki
        #add a new container
505 d1e43d6f Sofia Papagiannaki
        self.create_container(self.account,
506 d1e43d6f Sofia Papagiannaki
                              'dummy')
507 d1e43d6f Sofia Papagiannaki
        
508 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
509 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
510 d1e43d6f Sofia Papagiannaki
            
511 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_UNMODIFIED_SINCE':'%s' %past}
512 d1e43d6f Sofia Papagiannaki
            r = self.list_containers(self.account, **headers)
513 d1e43d6f Sofia Papagiannaki
            
514 d1e43d6f Sofia Papagiannaki
            #assert get success
515 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 412)
516 d1e43d6f Sofia Papagiannaki
517 d1e43d6f Sofia Papagiannaki
class AccountPost(BaseTestCase):
518 b09c9aaa Sofia Papagiannaki
    def setUp(self):
519 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
520 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
521 b09c9aaa Sofia Papagiannaki
        self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
522 b09c9aaa Sofia Papagiannaki
        for item in self.containers:
523 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, item)
524 b09c9aaa Sofia Papagiannaki
525 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
526 b09c9aaa Sofia Papagiannaki
        for c in  get_content_splitted(self.list_containers(self.account)):
527 b09c9aaa Sofia Papagiannaki
            self.delete_container(self.account, c)
528 b09c9aaa Sofia Papagiannaki
529 b09c9aaa Sofia Papagiannaki
    def test_update_meta(self):
530 33ffca25 Sofia Papagiannaki
        meta = {'HTTP_X_ACCOUNT_META_TEST':'test',
531 33ffca25 Sofia Papagiannaki
                'HTTP_X_ACCOUNT_META_TOST':'tost'}
532 b09c9aaa Sofia Papagiannaki
        response = self.update_account_meta(self.account, **meta)
533 b09c9aaa Sofia Papagiannaki
        response = self.get_account_meta(self.account)
534 b09c9aaa Sofia Papagiannaki
        for k,v in meta.items():
535 b09c9aaa Sofia Papagiannaki
            key = '-'.join(elem.capitalize() for elem in k.split('_')[1:])
536 b09c9aaa Sofia Papagiannaki
            self.assertTrue(response[key])
537 b09c9aaa Sofia Papagiannaki
            self.assertEqual(response[key], v)
538 b09c9aaa Sofia Papagiannaki
539 b09c9aaa Sofia Papagiannaki
    #def test_invalid_account_update_meta(self):
540 b09c9aaa Sofia Papagiannaki
    #    with AssertInvariant(self.get_account_meta, self.account):
541 33ffca25 Sofia Papagiannaki
    #        meta = {'HTTP_X_ACCOUNT_META_TEST':'test',
542 33ffca25 Sofia Papagiannaki
    #               'HTTP_X_ACCOUNT_META_TOST':'tost'}
543 b09c9aaa Sofia Papagiannaki
    #        response = self.update_account_meta('non-existing-account', **meta)
544 b09c9aaa Sofia Papagiannaki
545 d1e43d6f Sofia Papagiannaki
class ContainerHead(BaseTestCase):
546 d1e43d6f Sofia Papagiannaki
    def setUp(self):
547 d1e43d6f Sofia Papagiannaki
        BaseTestCase.setUp(self)
548 d1e43d6f Sofia Papagiannaki
        self.account = 'test'
549 d1e43d6f Sofia Papagiannaki
        self.container = 'apples'
550 d1e43d6f Sofia Papagiannaki
        self.create_container(self.account, self.container)
551 d1e43d6f Sofia Papagiannaki
552 d1e43d6f Sofia Papagiannaki
    def tearDown(self):
553 d1e43d6f Sofia Papagiannaki
        for o in self.list_objects(self.account, self.container):
554 d1e43d6f Sofia Papagiannaki
            self.delete_object(self.account, self.container, o)
555 d1e43d6f Sofia Papagiannaki
        self.delete_container(self.account, self.container)
556 d1e43d6f Sofia Papagiannaki
557 d1e43d6f Sofia Papagiannaki
    def test_get_meta(self):
558 d1e43d6f Sofia Papagiannaki
        headers = {'HTTP_X_OBJECT_META_TRASH':'true'}
559 d1e43d6f Sofia Papagiannaki
        t1 = datetime.datetime.utcnow()
560 d1e43d6f Sofia Papagiannaki
        o = self.upload_random_data(self.account,
561 d1e43d6f Sofia Papagiannaki
                                self.container,
562 d1e43d6f Sofia Papagiannaki
                                'McIntosh.jpg',
563 d1e43d6f Sofia Papagiannaki
                                meta=headers)
564 d1e43d6f Sofia Papagiannaki
        if o:
565 d1e43d6f Sofia Papagiannaki
            r = self.get_container_meta(self.account,
566 d1e43d6f Sofia Papagiannaki
                                        self.container)
567 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r['X-Container-Object-Count'], '1')
568 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r['X-Container-Bytes-Used'], str(len(o['data'])))
569 d1e43d6f Sofia Papagiannaki
            t2 = datetime.datetime.strptime(r['Last-Modified'], DATE_FORMATS[2])
570 d1e43d6f Sofia Papagiannaki
            delta = (t2 - t1)
571 d1e43d6f Sofia Papagiannaki
            threashold = datetime.timedelta(seconds=1) 
572 d1e43d6f Sofia Papagiannaki
            self.assertTrue(delta < threashold)
573 d1e43d6f Sofia Papagiannaki
            self.assertTrue(r['X-Container-Object-Meta'])
574 d1e43d6f Sofia Papagiannaki
            self.assertTrue('Trash' in r['X-Container-Object-Meta'])
575 d1e43d6f Sofia Papagiannaki
576 d1e43d6f Sofia Papagiannaki
class ContainerGet(BaseTestCase):
577 b09c9aaa Sofia Papagiannaki
    def setUp(self):
578 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
579 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
580 b09c9aaa Sofia Papagiannaki
        self.container = ['pears', 'apples']
581 b09c9aaa Sofia Papagiannaki
        for c in self.container:
582 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, c)
583 b09c9aaa Sofia Papagiannaki
        self.obj = []
584 b09c9aaa Sofia Papagiannaki
        for o in o_names[:8]:
585 b09c9aaa Sofia Papagiannaki
            self.obj.append(self.upload_random_data(self.account,
586 b09c9aaa Sofia Papagiannaki
                                                    self.container[0],
587 b09c9aaa Sofia Papagiannaki
                                                    o))
588 b09c9aaa Sofia Papagiannaki
        for o in o_names[8:]:
589 b09c9aaa Sofia Papagiannaki
            self.obj.append(self.upload_random_data(self.account,
590 b09c9aaa Sofia Papagiannaki
                                                    self.container[1],
591 b09c9aaa Sofia Papagiannaki
                                                    o))
592 b09c9aaa Sofia Papagiannaki
593 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
594 b09c9aaa Sofia Papagiannaki
        for c in self.container:
595 d1e43d6f Sofia Papagiannaki
            for obj in get_content_splitted(self.list_objects(self.account, c)):
596 d1e43d6f Sofia Papagiannaki
                self.delete_object(self.account, c, obj)
597 d1e43d6f Sofia Papagiannaki
            self.delete_container(self.account, c)
598 b09c9aaa Sofia Papagiannaki
599 b09c9aaa Sofia Papagiannaki
    def test_list_objects(self):
600 b09c9aaa Sofia Papagiannaki
        response = self.list_objects(self.account, self.container[0])
601 b09c9aaa Sofia Papagiannaki
        objects = get_content_splitted(response)
602 b09c9aaa Sofia Papagiannaki
        l = [elem['name'] for elem in self.obj[:8]]
603 b09c9aaa Sofia Papagiannaki
        l.sort()
604 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects, l)
605 b09c9aaa Sofia Papagiannaki
606 b09c9aaa Sofia Papagiannaki
    def test_list_objects_with_limit_marker(self):
607 b09c9aaa Sofia Papagiannaki
        response = self.list_objects(self.account, self.container[0], limit=2)
608 b09c9aaa Sofia Papagiannaki
        objects = get_content_splitted(response)
609 b09c9aaa Sofia Papagiannaki
        l = [elem['name'] for elem in self.obj[:8]]
610 b09c9aaa Sofia Papagiannaki
        l.sort()
611 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects, l[:2])
612 b09c9aaa Sofia Papagiannaki
        
613 b09c9aaa Sofia Papagiannaki
        markers = ['How To Win Friends And Influence People.pdf',
614 b09c9aaa Sofia Papagiannaki
                   'moms_birthday.jpg']
615 b09c9aaa Sofia Papagiannaki
        limit = 4
616 b09c9aaa Sofia Papagiannaki
        for m in markers:
617 33ffca25 Sofia Papagiannaki
            response = self.list_objects(self.account, self.container[0],
618 33ffca25 Sofia Papagiannaki
                                         limit=limit, marker=m)
619 b09c9aaa Sofia Papagiannaki
            objects = get_content_splitted(response)
620 b09c9aaa Sofia Papagiannaki
            l = [elem['name'] for elem in self.obj[:8]]
621 b09c9aaa Sofia Papagiannaki
            l.sort()
622 b09c9aaa Sofia Papagiannaki
            start = l.index(m) + 1
623 b09c9aaa Sofia Papagiannaki
            end = start + limit
624 b09c9aaa Sofia Papagiannaki
            end = len(l) >= end and end or len(l)
625 b09c9aaa Sofia Papagiannaki
            self.assertEqual(objects, l[start:end])
626 b09c9aaa Sofia Papagiannaki
627 b09c9aaa Sofia Papagiannaki
    def test_list_pseudo_hierarchical_folders(self):
628 33ffca25 Sofia Papagiannaki
        response = self.list_objects(self.account, self.container[1],
629 33ffca25 Sofia Papagiannaki
                                     prefix='photos', delimiter='/')
630 b09c9aaa Sofia Papagiannaki
        objects = get_content_splitted(response)
631 33ffca25 Sofia Papagiannaki
        self.assertEquals(['photos/animals/', 'photos/me.jpg',
632 33ffca25 Sofia Papagiannaki
                           'photos/plants/'], objects)
633 b09c9aaa Sofia Papagiannaki
        
634 33ffca25 Sofia Papagiannaki
        response = self.list_objects(self.account, self.container[1],
635 33ffca25 Sofia Papagiannaki
                                     prefix='photos/animals', delimiter='/')
636 33ffca25 Sofia Papagiannaki
        objs = get_content_splitted(response)
637 33ffca25 Sofia Papagiannaki
        l = ['photos/animals/cats/', 'photos/animals/dogs/']
638 33ffca25 Sofia Papagiannaki
        self.assertEquals(l, objs)
639 b09c9aaa Sofia Papagiannaki
        
640 33ffca25 Sofia Papagiannaki
        response = self.list_objects(self.account, self.container[1],
641 33ffca25 Sofia Papagiannaki
                                     path='photos')
642 b09c9aaa Sofia Papagiannaki
        objects = get_content_splitted(response)
643 b09c9aaa Sofia Papagiannaki
        self.assertEquals(['photos/me.jpg'], objects)
644 b09c9aaa Sofia Papagiannaki
645 b09c9aaa Sofia Papagiannaki
    def test_extended_list_json(self):
646 33ffca25 Sofia Papagiannaki
        response = self.list_objects(self.account,
647 33ffca25 Sofia Papagiannaki
                                     self.container[1],
648 33ffca25 Sofia Papagiannaki
                                     format='json', limit=2,
649 33ffca25 Sofia Papagiannaki
                                     prefix='photos/animals',
650 33ffca25 Sofia Papagiannaki
                                     delimiter='/')
651 b09c9aaa Sofia Papagiannaki
        objects = json.loads(response.content)
652 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects[0]['subdir'], 'photos/animals/cats/')
653 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects[1]['subdir'], 'photos/animals/dogs/')
654 b09c9aaa Sofia Papagiannaki
655 b09c9aaa Sofia Papagiannaki
    def test_extended_list_xml(self):
656 33ffca25 Sofia Papagiannaki
        response = self.list_objects(self.account, self.container[1],
657 33ffca25 Sofia Papagiannaki
                                     format='xml', limit=4, prefix='photos',
658 33ffca25 Sofia Papagiannaki
                                     delimiter='/')
659 b09c9aaa Sofia Papagiannaki
        xml = minidom.parseString(response.content)
660 b09c9aaa Sofia Papagiannaki
        dirs = xml.getElementsByTagName('subdir')
661 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(dirs), 2)
662 b09c9aaa Sofia Papagiannaki
        self.assertEqual(dirs[0].attributes['name'].value, 'photos/animals/')
663 b09c9aaa Sofia Papagiannaki
        self.assertEqual(dirs[1].attributes['name'].value, 'photos/plants/')
664 b09c9aaa Sofia Papagiannaki
        
665 b09c9aaa Sofia Papagiannaki
        objects = xml.getElementsByTagName('name')
666 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(objects), 1)
667 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects[0].childNodes[0].data, 'photos/me.jpg')
668 b09c9aaa Sofia Papagiannaki
669 3364a52a Sofia Papagiannaki
    def test_list_meta_double_matching(self):
670 3364a52a Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_QUALITY':'aaa',
671 3364a52a Sofia Papagiannaki
                'HTTP_X_OBJECT_META_STOCK':'true'}
672 3364a52a Sofia Papagiannaki
        r = self.update_object(self.account,
673 3364a52a Sofia Papagiannaki
                                    self.container[0],
674 3364a52a Sofia Papagiannaki
                                    self.obj[0]['name'],
675 79a6b6ee Sofia Papagiannaki
                                    
676 3364a52a Sofia Papagiannaki
                                    **meta)
677 3364a52a Sofia Papagiannaki
        r = self.list_objects(self.account,
678 3364a52a Sofia Papagiannaki
                          self.container[0],
679 3364a52a Sofia Papagiannaki
                          meta='Quality,Stock')
680 3364a52a Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
681 3364a52a Sofia Papagiannaki
        obj = get_content_splitted(r)
682 3364a52a Sofia Papagiannaki
        self.assertEqual(len(obj), 1)
683 3364a52a Sofia Papagiannaki
        self.assertTrue(obj, self.obj[0]['name'])
684 3364a52a Sofia Papagiannaki
685 b09c9aaa Sofia Papagiannaki
    def test_list_using_meta(self):
686 b09c9aaa Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_QUALITY':'aaa'}
687 b09c9aaa Sofia Papagiannaki
        for o in self.obj[:2]:
688 33ffca25 Sofia Papagiannaki
            r = self.update_object(self.account,
689 b09c9aaa Sofia Papagiannaki
                                    self.container[0],
690 b09c9aaa Sofia Papagiannaki
                                    o['name'],
691 b09c9aaa Sofia Papagiannaki
                                    **meta)
692 b09c9aaa Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_STOCK':'true'}
693 b09c9aaa Sofia Papagiannaki
        for o in self.obj[3:5]:
694 33ffca25 Sofia Papagiannaki
            r = self.update_object(self.account,
695 b09c9aaa Sofia Papagiannaki
                                    self.container[0],
696 b09c9aaa Sofia Papagiannaki
                                    o['name'],
697 b09c9aaa Sofia Papagiannaki
                                    **meta)
698 d1e43d6f Sofia Papagiannaki
        
699 b09c9aaa Sofia Papagiannaki
        r = self.list_objects(self.account,
700 b09c9aaa Sofia Papagiannaki
                          self.container[0],
701 b09c9aaa Sofia Papagiannaki
                          meta='Quality')
702 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
703 b09c9aaa Sofia Papagiannaki
        obj = get_content_splitted(r)
704 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(obj), 2)
705 86dacd7f Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
706 b09c9aaa Sofia Papagiannaki
        
707 b09c9aaa Sofia Papagiannaki
        # test case insensitive
708 b09c9aaa Sofia Papagiannaki
        r = self.list_objects(self.account,
709 b09c9aaa Sofia Papagiannaki
                          self.container[0],
710 b09c9aaa Sofia Papagiannaki
                          meta='quality')
711 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
712 b09c9aaa Sofia Papagiannaki
        obj = get_content_splitted(r)
713 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(obj), 2)
714 86dacd7f Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
715 b09c9aaa Sofia Papagiannaki
        
716 b09c9aaa Sofia Papagiannaki
        # test multiple matches
717 b09c9aaa Sofia Papagiannaki
        r = self.list_objects(self.account,
718 b09c9aaa Sofia Papagiannaki
                          self.container[0],
719 3364a52a Sofia Papagiannaki
                          meta='Quality,Stock')
720 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
721 b09c9aaa Sofia Papagiannaki
        obj = get_content_splitted(r)
722 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(obj), 4)
723 86dacd7f Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:4]])
724 b09c9aaa Sofia Papagiannaki
        
725 b09c9aaa Sofia Papagiannaki
        # test non 1-1 multiple match
726 b09c9aaa Sofia Papagiannaki
        r = self.list_objects(self.account,
727 b09c9aaa Sofia Papagiannaki
                          self.container[0],
728 3364a52a Sofia Papagiannaki
                          meta='Quality,aaaa')
729 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
730 b09c9aaa Sofia Papagiannaki
        obj = get_content_splitted(r)
731 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(obj), 2)
732 d1e43d6f Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
733 b09c9aaa Sofia Papagiannaki
734 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since(self):
735 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
736 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
737 d1e43d6f Sofia Papagiannaki
        
738 d1e43d6f Sofia Papagiannaki
        #add a new container
739 d1e43d6f Sofia Papagiannaki
        self.upload_random_data(self.account,
740 d1e43d6f Sofia Papagiannaki
                                self.container[0],
741 d1e43d6f Sofia Papagiannaki
                                'dummy.txt')
742 b09c9aaa Sofia Papagiannaki
743 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
744 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
745 d1e43d6f Sofia Papagiannaki
            
746 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_MODIFIED_SINCE':'%s' %past}
747 d1e43d6f Sofia Papagiannaki
            r = self.list_objects(self.account,
748 d1e43d6f Sofia Papagiannaki
                                  self.container[0], **headers)
749 d1e43d6f Sofia Papagiannaki
            
750 d1e43d6f Sofia Papagiannaki
            #assert get success
751 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
752 b09c9aaa Sofia Papagiannaki
753 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since_invalid_date(self):
754 d1e43d6f Sofia Papagiannaki
        headers = {'HTTP_IF_MODIFIED_SINCE':''}
755 d1e43d6f Sofia Papagiannaki
        r = self.list_objects(self.account,
756 d1e43d6f Sofia Papagiannaki
                              self.container[0], **headers)
757 d1e43d6f Sofia Papagiannaki
        
758 d1e43d6f Sofia Papagiannaki
        #assert get success
759 d1e43d6f Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
760 d1e43d6f Sofia Papagiannaki
761 d1e43d6f Sofia Papagiannaki
    def test_if_not_modified_since(self):
762 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
763 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
764 d1e43d6f Sofia Papagiannaki
        
765 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
766 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_MODIFIED_SINCE':'%s' %since.strftime(f)}
767 d1e43d6f Sofia Papagiannaki
            r = self.list_objects(self.account,
768 d1e43d6f Sofia Papagiannaki
                              self.container[0], **headers)
769 d1e43d6f Sofia Papagiannaki
        
770 d1e43d6f Sofia Papagiannaki
            #assert not modified
771 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 304)
772 d1e43d6f Sofia Papagiannaki
773 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since(self):
774 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
775 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
776 d1e43d6f Sofia Papagiannaki
        
777 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
778 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_UNMODIFIED_SINCE':'%s' %since.strftime(f)}
779 d1e43d6f Sofia Papagiannaki
            r = self.list_objects(self.account,
780 d1e43d6f Sofia Papagiannaki
                              self.container[0], **headers)
781 d1e43d6f Sofia Papagiannaki
        
782 d1e43d6f Sofia Papagiannaki
            #assert success
783 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
784 33ffca25 Sofia Papagiannaki
            objlist = self.list_objects(self.account, self.container[0])
785 d1e43d6f Sofia Papagiannaki
            self.assertEqual(get_content_splitted(r),
786 33ffca25 Sofia Papagiannaki
                             get_content_splitted(objlist))
787 b09c9aaa Sofia Papagiannaki
788 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since_precondition_failed(self):
789 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
790 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
791 d1e43d6f Sofia Papagiannaki
        
792 d1e43d6f Sofia Papagiannaki
        #add a new container
793 d1e43d6f Sofia Papagiannaki
        self.create_container(self.account,
794 d1e43d6f Sofia Papagiannaki
                              'dummy')
795 d1e43d6f Sofia Papagiannaki
796 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
797 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
798 d1e43d6f Sofia Papagiannaki
            
799 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_UNMODIFIED_SINCE':'%s' %past}
800 d1e43d6f Sofia Papagiannaki
            r = self.list_objects(self.account,
801 d1e43d6f Sofia Papagiannaki
                              self.container[0], **headers)
802 d1e43d6f Sofia Papagiannaki
        
803 d1e43d6f Sofia Papagiannaki
            #assert get success
804 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 412)
805 d1e43d6f Sofia Papagiannaki
806 d1e43d6f Sofia Papagiannaki
class ContainerPut(BaseTestCase):
807 b09c9aaa Sofia Papagiannaki
    def setUp(self):
808 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
809 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
810 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
811 b09c9aaa Sofia Papagiannaki
812 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
813 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
814 b09c9aaa Sofia Papagiannaki
            r = self.delete_container(self.account, c)
815 b09c9aaa Sofia Papagiannaki
816 b09c9aaa Sofia Papagiannaki
    def test_create(self):
817 b09c9aaa Sofia Papagiannaki
        response = self.create_container(self.account, self.containers[0])
818 b09c9aaa Sofia Papagiannaki
        if response.status_code == 201:
819 b09c9aaa Sofia Papagiannaki
            response = self.list_containers(self.account)
820 33ffca25 Sofia Papagiannaki
            content = get_content_splitted(response)
821 33ffca25 Sofia Papagiannaki
            self.assertTrue(self.containers[0] in content)
822 b09c9aaa Sofia Papagiannaki
            r = self.get_container_meta(self.account, self.containers[0])
823 b09c9aaa Sofia Papagiannaki
            self.assertEqual(r.status_code, 204)
824 b09c9aaa Sofia Papagiannaki
825 b09c9aaa Sofia Papagiannaki
    def test_create_twice(self):
826 b09c9aaa Sofia Papagiannaki
        response = self.create_container(self.account, self.containers[0])
827 b09c9aaa Sofia Papagiannaki
        if response.status_code == 201:
828 33ffca25 Sofia Papagiannaki
            r = self.create_container(self.account, self.containers[0])
829 33ffca25 Sofia Papagiannaki
            self.assertTrue(r.status_code, 202)
830 b09c9aaa Sofia Papagiannaki
831 d1e43d6f Sofia Papagiannaki
class ContainerPost(BaseTestCase):
832 d1e43d6f Sofia Papagiannaki
    def setUp(self):
833 d1e43d6f Sofia Papagiannaki
        BaseTestCase.setUp(self)
834 d1e43d6f Sofia Papagiannaki
        self.account = 'test'
835 d1e43d6f Sofia Papagiannaki
        self.container = 'apples'
836 d1e43d6f Sofia Papagiannaki
        self.create_container(self.account, self.container)
837 d1e43d6f Sofia Papagiannaki
838 d1e43d6f Sofia Papagiannaki
    def tearDown(self):
839 d1e43d6f Sofia Papagiannaki
        for o in self.list_objects(self.account, self.container):
840 d1e43d6f Sofia Papagiannaki
            self.delete_object(self.account, self.container, o)
841 d1e43d6f Sofia Papagiannaki
        self.delete_container(self.account, self.container)
842 d1e43d6f Sofia Papagiannaki
843 d1e43d6f Sofia Papagiannaki
    def test_update_meta(self):
844 d1e43d6f Sofia Papagiannaki
        meta = {'HTTP_X_CONTAINER_META_TEST':'test33',
845 d1e43d6f Sofia Papagiannaki
                'HTTP_X_CONTAINER_META_TOST':'tost22'}
846 33ffca25 Sofia Papagiannaki
        response = self.update_container_meta(self.account, self.container,
847 33ffca25 Sofia Papagiannaki
                                              **meta)
848 d1e43d6f Sofia Papagiannaki
        response = self.get_container_meta(self.account, self.container)
849 d1e43d6f Sofia Papagiannaki
        for k,v in meta.items():
850 d1e43d6f Sofia Papagiannaki
            key = '-'.join(elem.capitalize() for elem in k.split('_')[1:])
851 d1e43d6f Sofia Papagiannaki
            self.assertTrue(response[key])
852 d1e43d6f Sofia Papagiannaki
            self.assertEqual(response[key], v)
853 d1e43d6f Sofia Papagiannaki
854 d1e43d6f Sofia Papagiannaki
class ContainerDelete(BaseTestCase):
855 b09c9aaa Sofia Papagiannaki
    def setUp(self):
856 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
857 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
858 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
859 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
860 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, c)
861 b09c9aaa Sofia Papagiannaki
        self.upload_random_data(self.account,
862 b09c9aaa Sofia Papagiannaki
                                self.containers[1],
863 b09c9aaa Sofia Papagiannaki
                                'nice.jpg')
864 b09c9aaa Sofia Papagiannaki
865 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
866 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
867 b09c9aaa Sofia Papagiannaki
            for o in get_content_splitted(self.list_objects(self.account, c)):
868 b09c9aaa Sofia Papagiannaki
                self.delete_object(self.account, c, o)
869 b09c9aaa Sofia Papagiannaki
            self.delete_container(self.account, c)
870 b09c9aaa Sofia Papagiannaki
871 b09c9aaa Sofia Papagiannaki
    def test_delete(self):
872 b09c9aaa Sofia Papagiannaki
        r = self.delete_container(self.account, self.containers[0])
873 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
874 b09c9aaa Sofia Papagiannaki
875 b09c9aaa Sofia Papagiannaki
    def test_delete_non_empty(self):
876 b09c9aaa Sofia Papagiannaki
        r = self.delete_container(self.account, self.containers[1])
877 b09c9aaa Sofia Papagiannaki
        self.assertNonEmpty(r)
878 b09c9aaa Sofia Papagiannaki
879 b09c9aaa Sofia Papagiannaki
    def test_delete_invalid(self):
880 b09c9aaa Sofia Papagiannaki
        self.assertItemNotFound(self.delete_container(self.account, 'c3'))
881 b09c9aaa Sofia Papagiannaki
882 d1e43d6f Sofia Papagiannaki
class ObjectHead(BaseTestCase):
883 d1e43d6f Sofia Papagiannaki
    pass
884 d1e43d6f Sofia Papagiannaki
885 d1e43d6f Sofia Papagiannaki
class ObjectGet(BaseTestCase):
886 b09c9aaa Sofia Papagiannaki
    def setUp(self):
887 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
888 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
889 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
890 b09c9aaa Sofia Papagiannaki
        #create some containers
891 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
892 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, c)
893 b09c9aaa Sofia Papagiannaki
        
894 b09c9aaa Sofia Papagiannaki
        #upload a file
895 b09c9aaa Sofia Papagiannaki
        self.objects = []
896 b09c9aaa Sofia Papagiannaki
        self.objects.append(self.upload_os_file(self.account,
897 b09c9aaa Sofia Papagiannaki
                            self.containers[1],
898 b09c9aaa Sofia Papagiannaki
                            './api/tests.py'))
899 b09c9aaa Sofia Papagiannaki
        self.objects.append(self.upload_os_file(self.account,
900 b09c9aaa Sofia Papagiannaki
                            self.containers[1],
901 b09c9aaa Sofia Papagiannaki
                            'settings.py'))
902 b09c9aaa Sofia Papagiannaki
903 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
904 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
905 b09c9aaa Sofia Papagiannaki
            for o in get_content_splitted(self.list_objects(self.account, c)):
906 b09c9aaa Sofia Papagiannaki
                self.delete_object(self.account, c, o)
907 b09c9aaa Sofia Papagiannaki
            self.delete_container(self.account, c)
908 b09c9aaa Sofia Papagiannaki
909 b09c9aaa Sofia Papagiannaki
    def test_get(self):
910 b09c9aaa Sofia Papagiannaki
        #perform get
911 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
912 b09c9aaa Sofia Papagiannaki
                            self.containers[1],
913 b09c9aaa Sofia Papagiannaki
                            self.objects[0]['name'],
914 b09c9aaa Sofia Papagiannaki
                            self.objects[0]['meta'])
915 b09c9aaa Sofia Papagiannaki
        #assert success
916 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
917 33ffca25 Sofia Papagiannaki
        
918 33ffca25 Sofia Papagiannaki
        #assert content-type
919 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
920 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
921 b09c9aaa Sofia Papagiannaki
922 b09c9aaa Sofia Papagiannaki
    def test_get_invalid(self):
923 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
924 b09c9aaa Sofia Papagiannaki
                            self.containers[0],
925 b09c9aaa Sofia Papagiannaki
                            self.objects[0]['name'])
926 b09c9aaa Sofia Papagiannaki
        self.assertItemNotFound(r)
927 b09c9aaa Sofia Papagiannaki
928 b09c9aaa Sofia Papagiannaki
    def test_get_partial(self):
929 b09c9aaa Sofia Papagiannaki
        #perform get with range
930 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_RANGE':'bytes=0-499'}
931 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
932 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
933 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
934 b09c9aaa Sofia Papagiannaki
                        **headers)
935 b09c9aaa Sofia Papagiannaki
        
936 b09c9aaa Sofia Papagiannaki
        #assert successful partial content
937 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
938 b09c9aaa Sofia Papagiannaki
        
939 33ffca25 Sofia Papagiannaki
        #assert content-type
940 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
941 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
942 33ffca25 Sofia Papagiannaki
        
943 b09c9aaa Sofia Papagiannaki
        #assert content length
944 b09c9aaa Sofia Papagiannaki
        self.assertEqual(int(r['Content-Length']), 500)
945 b09c9aaa Sofia Papagiannaki
        
946 b09c9aaa Sofia Papagiannaki
        #assert content
947 b09c9aaa Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'][:500], r.content)
948 b09c9aaa Sofia Papagiannaki
949 b09c9aaa Sofia Papagiannaki
    def test_get_final_500(self):
950 b09c9aaa Sofia Papagiannaki
        #perform get with range
951 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_RANGE':'bytes=-500'}
952 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
953 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
954 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
955 b09c9aaa Sofia Papagiannaki
                        **headers)
956 b09c9aaa Sofia Papagiannaki
        
957 b09c9aaa Sofia Papagiannaki
        #assert successful partial content
958 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
959 b09c9aaa Sofia Papagiannaki
        
960 33ffca25 Sofia Papagiannaki
        #assert content-type
961 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
962 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
963 33ffca25 Sofia Papagiannaki
        
964 b09c9aaa Sofia Papagiannaki
        #assert content length
965 b09c9aaa Sofia Papagiannaki
        self.assertEqual(int(r['Content-Length']), 500)
966 b09c9aaa Sofia Papagiannaki
        
967 b09c9aaa Sofia Papagiannaki
        #assert content
968 b09c9aaa Sofia Papagiannaki
        self.assertTrue(self.objects[0]['data'][-500:], r.content)
969 b09c9aaa Sofia Papagiannaki
970 b09c9aaa Sofia Papagiannaki
    def test_get_rest(self):
971 b09c9aaa Sofia Papagiannaki
        #perform get with range
972 b09c9aaa Sofia Papagiannaki
        offset = len(self.objects[0]['data']) - 500
973 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_RANGE':'bytes=%s-' %offset}
974 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
975 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
976 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
977 b09c9aaa Sofia Papagiannaki
                        **headers)
978 b09c9aaa Sofia Papagiannaki
        
979 b09c9aaa Sofia Papagiannaki
        #assert successful partial content
980 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
981 b09c9aaa Sofia Papagiannaki
        
982 33ffca25 Sofia Papagiannaki
        #assert content-type
983 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
984 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
985 33ffca25 Sofia Papagiannaki
        
986 b09c9aaa Sofia Papagiannaki
        #assert content length
987 b09c9aaa Sofia Papagiannaki
        self.assertEqual(int(r['Content-Length']), 500)
988 b09c9aaa Sofia Papagiannaki
        
989 b09c9aaa Sofia Papagiannaki
        #assert content
990 b09c9aaa Sofia Papagiannaki
        self.assertTrue(self.objects[0]['data'][-500:], r.content)
991 d1e43d6f Sofia Papagiannaki
992 b09c9aaa Sofia Papagiannaki
    def test_get_range_not_satisfiable(self):
993 b09c9aaa Sofia Papagiannaki
        #perform get with range
994 b09c9aaa Sofia Papagiannaki
        offset = len(self.objects[0]['data']) + 1
995 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_RANGE':'bytes=0-%s' %offset}
996 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
997 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
998 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
999 b09c9aaa Sofia Papagiannaki
                        **headers)
1000 b09c9aaa Sofia Papagiannaki
        
1001 b09c9aaa Sofia Papagiannaki
        #assert Range Not Satisfiable
1002 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 416)
1003 b09c9aaa Sofia Papagiannaki
1004 b09c9aaa Sofia Papagiannaki
    def test_multiple_range(self):
1005 b09c9aaa Sofia Papagiannaki
        #perform get with multiple range
1006 b09c9aaa Sofia Papagiannaki
        ranges = ['0-499', '-500', '1000-']
1007 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_RANGE' : 'bytes=%s' % ','.join(ranges)}
1008 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1009 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1010 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1011 b09c9aaa Sofia Papagiannaki
                        **headers)
1012 b09c9aaa Sofia Papagiannaki
        
1013 b09c9aaa Sofia Papagiannaki
        # assert partial content
1014 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 206)
1015 b09c9aaa Sofia Papagiannaki
        
1016 b09c9aaa Sofia Papagiannaki
        # assert Content-Type of the reply will be multipart/byteranges
1017 b09c9aaa Sofia Papagiannaki
        self.assertTrue(r['Content-Type'])
1018 b09c9aaa Sofia Papagiannaki
        content_type_parts = r['Content-Type'].split()
1019 b09c9aaa Sofia Papagiannaki
        self.assertEqual(content_type_parts[0], ('multipart/byteranges;'))
1020 b09c9aaa Sofia Papagiannaki
        
1021 b09c9aaa Sofia Papagiannaki
        boundary = '--%s' %content_type_parts[1].split('=')[-1:][0]
1022 b09c9aaa Sofia Papagiannaki
        cparts = r.content.split(boundary)[1:-1]
1023 b09c9aaa Sofia Papagiannaki
        
1024 b09c9aaa Sofia Papagiannaki
        # assert content parts are exactly 2
1025 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(cparts), len(ranges))
1026 b09c9aaa Sofia Papagiannaki
        
1027 b09c9aaa Sofia Papagiannaki
        # for each content part assert headers
1028 b09c9aaa Sofia Papagiannaki
        i = 0
1029 b09c9aaa Sofia Papagiannaki
        for cpart in cparts:
1030 b09c9aaa Sofia Papagiannaki
            content = cpart.split('\r\n')
1031 b09c9aaa Sofia Papagiannaki
            headers = content[1:3]
1032 b09c9aaa Sofia Papagiannaki
            content_range = headers[0].split(': ')
1033 b09c9aaa Sofia Papagiannaki
            self.assertEqual(content_range[0], 'Content-Range')
1034 b09c9aaa Sofia Papagiannaki
            
1035 b09c9aaa Sofia Papagiannaki
            r = ranges[i].split('-')
1036 b09c9aaa Sofia Papagiannaki
            if not r[0] and not r[1]:
1037 b09c9aaa Sofia Papagiannaki
                pass
1038 b09c9aaa Sofia Papagiannaki
            elif not r[0]:
1039 b09c9aaa Sofia Papagiannaki
                start = len(self.objects[0]['data']) - int(r[1])
1040 b09c9aaa Sofia Papagiannaki
                end = len(self.objects[0]['data'])
1041 b09c9aaa Sofia Papagiannaki
            elif not r[1]:
1042 b09c9aaa Sofia Papagiannaki
                start = int(r[0])
1043 b09c9aaa Sofia Papagiannaki
                end = len(self.objects[0]['data'])
1044 b09c9aaa Sofia Papagiannaki
            else:
1045 b09c9aaa Sofia Papagiannaki
                start = int(r[0])
1046 b09c9aaa Sofia Papagiannaki
                end = int(r[1]) + 1
1047 b09c9aaa Sofia Papagiannaki
            fdata = self.objects[0]['data'][start:end]
1048 b09c9aaa Sofia Papagiannaki
            sdata = '\r\n'.join(content[4:-1])
1049 b09c9aaa Sofia Papagiannaki
            self.assertEqual(len(fdata), len(sdata))
1050 b09c9aaa Sofia Papagiannaki
            self.assertEquals(fdata, sdata)
1051 b09c9aaa Sofia Papagiannaki
            i+=1
1052 b09c9aaa Sofia Papagiannaki
1053 b09c9aaa Sofia Papagiannaki
    def test_multiple_range_not_satisfiable(self):
1054 b09c9aaa Sofia Papagiannaki
        #perform get with multiple range
1055 b09c9aaa Sofia Papagiannaki
        out_of_range = len(self.objects[0]['data']) + 1
1056 b09c9aaa Sofia Papagiannaki
        ranges = ['0-499', '-500', '%d-' %out_of_range]
1057 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_RANGE' : 'bytes=%s' % ','.join(ranges)}
1058 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1059 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1060 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1061 b09c9aaa Sofia Papagiannaki
                        **headers)
1062 b09c9aaa Sofia Papagiannaki
        
1063 b09c9aaa Sofia Papagiannaki
        # assert partial content
1064 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 416)
1065 b09c9aaa Sofia Papagiannaki
1066 b09c9aaa Sofia Papagiannaki
    def test_get_with_if_match(self):
1067 b09c9aaa Sofia Papagiannaki
        #perform get with If-Match
1068 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_MATCH':self.objects[0]['hash']}
1069 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1070 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1071 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1072 b09c9aaa Sofia Papagiannaki
                        **headers)
1073 b09c9aaa Sofia Papagiannaki
        #assert get success
1074 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
1075 b09c9aaa Sofia Papagiannaki
        
1076 33ffca25 Sofia Papagiannaki
        #assert content-type
1077 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
1078 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
1079 33ffca25 Sofia Papagiannaki
        
1080 b09c9aaa Sofia Papagiannaki
        #assert response content
1081 b09c9aaa Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'].strip(), r.content.strip())
1082 b09c9aaa Sofia Papagiannaki
1083 b09c9aaa Sofia Papagiannaki
    def test_get_with_if_match_star(self):
1084 b09c9aaa Sofia Papagiannaki
        #perform get with If-Match *
1085 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_MATCH':'*'}
1086 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1087 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1088 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1089 b09c9aaa Sofia Papagiannaki
                        **headers)
1090 b09c9aaa Sofia Papagiannaki
        #assert get success
1091 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
1092 b09c9aaa Sofia Papagiannaki
        
1093 33ffca25 Sofia Papagiannaki
        #assert content-type
1094 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
1095 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
1096 33ffca25 Sofia Papagiannaki
        
1097 b09c9aaa Sofia Papagiannaki
        #assert response content
1098 b09c9aaa Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'].strip(), r.content.strip())
1099 b09c9aaa Sofia Papagiannaki
1100 b09c9aaa Sofia Papagiannaki
    def test_get_with_multiple_if_match(self):
1101 b09c9aaa Sofia Papagiannaki
        #perform get with If-Match
1102 b09c9aaa Sofia Papagiannaki
        etags = [i['hash'] for i in self.objects if i]
1103 b09c9aaa Sofia Papagiannaki
        etags = ','.join('"%s"' % etag for etag in etags)
1104 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_MATCH':etags}
1105 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1106 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1107 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1108 b09c9aaa Sofia Papagiannaki
                        **headers)
1109 b09c9aaa Sofia Papagiannaki
        #assert get success
1110 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
1111 b09c9aaa Sofia Papagiannaki
        
1112 33ffca25 Sofia Papagiannaki
        #assert content-type
1113 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
1114 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
1115 33ffca25 Sofia Papagiannaki
        
1116 33ffca25 Sofia Papagiannaki
        #assert content-type
1117 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
1118 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
1119 33ffca25 Sofia Papagiannaki
        
1120 b09c9aaa Sofia Papagiannaki
        #assert response content
1121 b09c9aaa Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'].strip(), r.content.strip())
1122 b09c9aaa Sofia Papagiannaki
1123 b09c9aaa Sofia Papagiannaki
    def test_if_match_precondition_failed(self):
1124 b09c9aaa Sofia Papagiannaki
        #perform get with If-Match
1125 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_MATCH':'123'}
1126 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1127 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1128 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1129 b09c9aaa Sofia Papagiannaki
                        **headers)
1130 b09c9aaa Sofia Papagiannaki
        #assert precondition failed 
1131 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 412)
1132 b09c9aaa Sofia Papagiannaki
1133 b09c9aaa Sofia Papagiannaki
    def test_if_none_match(self):
1134 d1e43d6f Sofia Papagiannaki
        #perform get with If-None-Match
1135 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_NONE_MATCH':'123'}
1136 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1137 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1138 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1139 b09c9aaa Sofia Papagiannaki
                        **headers)
1140 b09c9aaa Sofia Papagiannaki
        
1141 b09c9aaa Sofia Papagiannaki
        #assert get success
1142 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
1143 33ffca25 Sofia Papagiannaki
        
1144 33ffca25 Sofia Papagiannaki
        #assert content-type
1145 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
1146 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
1147 b09c9aaa Sofia Papagiannaki
1148 b09c9aaa Sofia Papagiannaki
    def test_if_none_match(self):
1149 d1e43d6f Sofia Papagiannaki
        #perform get with If-None-Match *
1150 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_NONE_MATCH':'*'}
1151 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1152 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1153 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1154 b09c9aaa Sofia Papagiannaki
                        **headers)
1155 b09c9aaa Sofia Papagiannaki
        
1156 b09c9aaa Sofia Papagiannaki
        #assert get success
1157 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 304)
1158 d1e43d6f Sofia Papagiannaki
1159 b09c9aaa Sofia Papagiannaki
    def test_if_none_match_not_modified(self):
1160 d1e43d6f Sofia Papagiannaki
        #perform get with If-None-Match
1161 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_NONE_MATCH':'%s' %self.objects[0]['hash']}
1162 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1163 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1164 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1165 b09c9aaa Sofia Papagiannaki
                        **headers)
1166 b09c9aaa Sofia Papagiannaki
        
1167 b09c9aaa Sofia Papagiannaki
        #assert not modified
1168 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 304)
1169 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r['ETag'], self.objects[0]['hash'])
1170 d1e43d6f Sofia Papagiannaki
1171 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since(self):
1172 b09c9aaa Sofia Papagiannaki
        t = datetime.datetime.utcnow()
1173 b09c9aaa Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
1174 b09c9aaa Sofia Papagiannaki
        
1175 b09c9aaa Sofia Papagiannaki
        #modify the object
1176 b09c9aaa Sofia Papagiannaki
        self.upload_object(self.account,
1177 b09c9aaa Sofia Papagiannaki
                           self.containers[1],
1178 b09c9aaa Sofia Papagiannaki
                           self.objects[0]['name'],
1179 b09c9aaa Sofia Papagiannaki
                           self.objects[0]['data'][:200])
1180 b09c9aaa Sofia Papagiannaki
        
1181 b09c9aaa Sofia Papagiannaki
        for f in DATE_FORMATS:
1182 b09c9aaa Sofia Papagiannaki
            past = t2.strftime(f)
1183 b09c9aaa Sofia Papagiannaki
            
1184 b09c9aaa Sofia Papagiannaki
            headers = {'HTTP_IF_MODIFIED_SINCE':'%s' %past}
1185 b09c9aaa Sofia Papagiannaki
            r = self.get_object(self.account,
1186 b09c9aaa Sofia Papagiannaki
                        self.containers[1],
1187 b09c9aaa Sofia Papagiannaki
                        self.objects[0]['name'],
1188 b09c9aaa Sofia Papagiannaki
                        **headers)
1189 b09c9aaa Sofia Papagiannaki
            
1190 b09c9aaa Sofia Papagiannaki
            #assert get success
1191 b09c9aaa Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
1192 33ffca25 Sofia Papagiannaki
            
1193 33ffca25 Sofia Papagiannaki
            #assert content-type
1194 33ffca25 Sofia Papagiannaki
            self.assertEqual(r['Content-Type'],
1195 33ffca25 Sofia Papagiannaki
                             self.objects[0]['meta']['HTTP_CONTENT_TYPE'])   
1196 d1e43d6f Sofia Papagiannaki
1197 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since_invalid_date(self):
1198 b09c9aaa Sofia Papagiannaki
        headers = {'HTTP_IF_MODIFIED_SINCE':''}
1199 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1200 b09c9aaa Sofia Papagiannaki
                    self.containers[1],
1201 b09c9aaa Sofia Papagiannaki
                    self.objects[0]['name'],
1202 b09c9aaa Sofia Papagiannaki
                    **headers)
1203 b09c9aaa Sofia Papagiannaki
        
1204 b09c9aaa Sofia Papagiannaki
        #assert get success
1205 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
1206 33ffca25 Sofia Papagiannaki
        
1207 33ffca25 Sofia Papagiannaki
        #assert content-type
1208 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['Content-Type'],
1209 33ffca25 Sofia Papagiannaki
                         self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
1210 b09c9aaa Sofia Papagiannaki
1211 d1e43d6f Sofia Papagiannaki
    def test_if_not_modified_since(self):
1212 b09c9aaa Sofia Papagiannaki
        now = datetime.datetime.utcnow()
1213 b09c9aaa Sofia Papagiannaki
        since = now + datetime.timedelta(1)
1214 b09c9aaa Sofia Papagiannaki
        
1215 b09c9aaa Sofia Papagiannaki
        for f in DATE_FORMATS:
1216 b09c9aaa Sofia Papagiannaki
            headers = {'HTTP_IF_MODIFIED_SINCE':'%s' %since.strftime(f)}
1217 b09c9aaa Sofia Papagiannaki
            r = self.get_object(self.account,
1218 b09c9aaa Sofia Papagiannaki
                                self.containers[1],
1219 b09c9aaa Sofia Papagiannaki
                                self.objects[0]['name'],
1220 b09c9aaa Sofia Papagiannaki
                                **headers)
1221 b09c9aaa Sofia Papagiannaki
            
1222 b09c9aaa Sofia Papagiannaki
            #assert not modified
1223 b09c9aaa Sofia Papagiannaki
            self.assertEqual(r.status_code, 304)
1224 b09c9aaa Sofia Papagiannaki
1225 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since(self):
1226 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
1227 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
1228 d1e43d6f Sofia Papagiannaki
        
1229 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
1230 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_UNMODIFIED_SINCE':'%s' %since.strftime(f)}
1231 d1e43d6f Sofia Papagiannaki
            r = self.get_object(self.account,
1232 d1e43d6f Sofia Papagiannaki
                                self.containers[1],
1233 d1e43d6f Sofia Papagiannaki
                                self.objects[0]['name'],
1234 d1e43d6f Sofia Papagiannaki
                                **headers)
1235 d1e43d6f Sofia Papagiannaki
            #assert success
1236 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 200)
1237 d1e43d6f Sofia Papagiannaki
            self.assertEqual(self.objects[0]['data'], r.content)
1238 33ffca25 Sofia Papagiannaki
            
1239 33ffca25 Sofia Papagiannaki
            #assert content-type
1240 33ffca25 Sofia Papagiannaki
            self.assertEqual(r['Content-Type'],
1241 33ffca25 Sofia Papagiannaki
                             self.objects[0]['meta']['HTTP_CONTENT_TYPE'])
1242 b09c9aaa Sofia Papagiannaki
1243 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since_precondition_failed(self):
1244 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
1245 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
1246 d1e43d6f Sofia Papagiannaki
        
1247 d1e43d6f Sofia Papagiannaki
        #modify the object
1248 d1e43d6f Sofia Papagiannaki
        self.upload_object(self.account,
1249 d1e43d6f Sofia Papagiannaki
                           self.containers[1],
1250 d1e43d6f Sofia Papagiannaki
                           self.objects[0]['name'],
1251 d1e43d6f Sofia Papagiannaki
                           self.objects[0]['data'][:200])
1252 d1e43d6f Sofia Papagiannaki
        
1253 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
1254 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
1255 d1e43d6f Sofia Papagiannaki
            
1256 d1e43d6f Sofia Papagiannaki
            headers = {'HTTP_IF_UNMODIFIED_SINCE':'%s' %past}
1257 d1e43d6f Sofia Papagiannaki
            r = self.get_object(self.account,
1258 d1e43d6f Sofia Papagiannaki
                        self.containers[1],
1259 d1e43d6f Sofia Papagiannaki
                        self.objects[0]['name'],
1260 d1e43d6f Sofia Papagiannaki
                        **headers)
1261 d1e43d6f Sofia Papagiannaki
            #assert get success
1262 d1e43d6f Sofia Papagiannaki
            self.assertEqual(r.status_code, 412)
1263 d1e43d6f Sofia Papagiannaki
1264 d1e43d6f Sofia Papagiannaki
    def test_hashes(self):
1265 33ffca25 Sofia Papagiannaki
        l = 8388609
1266 33ffca25 Sofia Papagiannaki
        fname = 'largefile'
1267 d1e43d6f Sofia Papagiannaki
        o = self.upload_random_data(self.account,
1268 d1e43d6f Sofia Papagiannaki
                                self.containers[1],
1269 d1e43d6f Sofia Papagiannaki
                                fname,
1270 d1e43d6f Sofia Papagiannaki
                                l)
1271 d1e43d6f Sofia Papagiannaki
        if o:
1272 d1e43d6f Sofia Papagiannaki
            r = self.get_object(self.account,
1273 d1e43d6f Sofia Papagiannaki
                                self.containers[1],
1274 d1e43d6f Sofia Papagiannaki
                                fname,
1275 d1e43d6f Sofia Papagiannaki
                                'json')
1276 33ffca25 Sofia Papagiannaki
            body = json.loads(r.content)
1277 33ffca25 Sofia Papagiannaki
            hashes = body['hashes']
1278 33ffca25 Sofia Papagiannaki
            block_size = body['block_size']
1279 33ffca25 Sofia Papagiannaki
            block_hash = body['block_hash']
1280 33ffca25 Sofia Papagiannaki
            block_num = l/block_size == 0 and l/block_size or l/block_size + 1
1281 33ffca25 Sofia Papagiannaki
            self.assertTrue(len(hashes), block_num)
1282 d1e43d6f Sofia Papagiannaki
            i = 0
1283 d1e43d6f Sofia Papagiannaki
            for h in hashes:
1284 d1e43d6f Sofia Papagiannaki
                start = i * block_size
1285 d1e43d6f Sofia Papagiannaki
                end = (i + 1) * block_size
1286 33ffca25 Sofia Papagiannaki
                hash = compute_block_hash(o['data'][start:end], block_hash)
1287 33ffca25 Sofia Papagiannaki
                self.assertEqual(h, hash)
1288 d1e43d6f Sofia Papagiannaki
                i += 1
1289 d1e43d6f Sofia Papagiannaki
1290 d1e43d6f Sofia Papagiannaki
class ObjectPut(BaseTestCase):
1291 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1292 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1293 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
1294 b09c9aaa Sofia Papagiannaki
        self.container = 'c1'
1295 b09c9aaa Sofia Papagiannaki
        self.create_container(self.account, self.container)
1296 b09c9aaa Sofia Papagiannaki
        
1297 b09c9aaa Sofia Papagiannaki
        self.src = os.path.join('.', 'api', 'tests.py')
1298 b09c9aaa Sofia Papagiannaki
        self.dest = os.path.join('.', 'api', 'chunked_update_test_file')
1299 b09c9aaa Sofia Papagiannaki
        create_chunked_update_test_file(self.src, self.dest)
1300 b09c9aaa Sofia Papagiannaki
1301 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
1302 33ffca25 Sofia Papagiannaki
        r = self.list_objects(self.account, self.container)
1303 33ffca25 Sofia Papagiannaki
        for o in get_content_splitted(r):
1304 b09c9aaa Sofia Papagiannaki
            self.delete_object(self.account, self.container, o)
1305 b09c9aaa Sofia Papagiannaki
        self.delete_container(self.account, self.container)
1306 b09c9aaa Sofia Papagiannaki
        
1307 b09c9aaa Sofia Papagiannaki
        # delete test file
1308 b09c9aaa Sofia Papagiannaki
        os.remove(self.dest)
1309 d1e43d6f Sofia Papagiannaki
1310 b09c9aaa Sofia Papagiannaki
    def test_upload(self):
1311 b09c9aaa Sofia Papagiannaki
        filename = 'tests.py'
1312 b09c9aaa Sofia Papagiannaki
        fullpath = os.path.join('.', 'api', filename) 
1313 b09c9aaa Sofia Papagiannaki
        f = open(fullpath, 'r')
1314 b09c9aaa Sofia Papagiannaki
        data = f.read()
1315 d1e43d6f Sofia Papagiannaki
        hash = compute_md5_hash(data)
1316 b09c9aaa Sofia Papagiannaki
        meta={'HTTP_ETAG':hash,
1317 b09c9aaa Sofia Papagiannaki
              'HTTP_X_OBJECT_META_TEST':'test1'
1318 b09c9aaa Sofia Papagiannaki
              }
1319 33ffca25 Sofia Papagiannaki
        type, enc = mimetypes.guess_type(fullpath)
1320 33ffca25 Sofia Papagiannaki
        meta['HTTP_CONTENT_TYPE'] = type and type or 'plain/text'
1321 33ffca25 Sofia Papagiannaki
        if enc:
1322 33ffca25 Sofia Papagiannaki
            meta['HTTP_CONTENT_ENCODING'] = enc
1323 b09c9aaa Sofia Papagiannaki
        r = self.upload_object(self.account,
1324 b09c9aaa Sofia Papagiannaki
                               self.container,
1325 b09c9aaa Sofia Papagiannaki
                               filename,
1326 b09c9aaa Sofia Papagiannaki
                               data,
1327 b09c9aaa Sofia Papagiannaki
                               content_type=meta['HTTP_CONTENT_TYPE'],
1328 b09c9aaa Sofia Papagiannaki
                               **meta)
1329 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
1330 b09c9aaa Sofia Papagiannaki
        r = self.get_object_meta(self.account, self.container, filename)
1331 b09c9aaa Sofia Papagiannaki
        self.assertTrue(r['X-Object-Meta-Test'])
1332 33ffca25 Sofia Papagiannaki
        self.assertEqual(r['X-Object-Meta-Test'],
1333 33ffca25 Sofia Papagiannaki
                         meta['HTTP_X_OBJECT_META_TEST'])
1334 b09c9aaa Sofia Papagiannaki
        
1335 b09c9aaa Sofia Papagiannaki
        #assert uploaded content
1336 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account, self.container, filename)
1337 b09c9aaa Sofia Papagiannaki
        self.assertEqual(os.path.getsize(fullpath), int(r['Content-Length']))
1338 b09c9aaa Sofia Papagiannaki
        self.assertEqual(data.strip(), r.content.strip())
1339 b09c9aaa Sofia Papagiannaki
1340 b09c9aaa Sofia Papagiannaki
    def test_upload_unprocessable_entity(self):
1341 b09c9aaa Sofia Papagiannaki
        filename = 'tests.py'
1342 b09c9aaa Sofia Papagiannaki
        fullpath = os.path.join('.', 'api', filename) 
1343 b09c9aaa Sofia Papagiannaki
        f = open(fullpath, 'r')
1344 b09c9aaa Sofia Papagiannaki
        data = f.read()
1345 b09c9aaa Sofia Papagiannaki
        meta={'HTTP_ETAG':'123',
1346 b09c9aaa Sofia Papagiannaki
              'HTTP_X_OBJECT_META_TEST':'test1'
1347 b09c9aaa Sofia Papagiannaki
              }
1348 33ffca25 Sofia Papagiannaki
        type, enc = mimetypes.guess_type(fullpath)
1349 33ffca25 Sofia Papagiannaki
        meta['HTTP_CONTENT_TYPE'] = type and type or 'plain/text'
1350 33ffca25 Sofia Papagiannaki
        if enc:
1351 33ffca25 Sofia Papagiannaki
            meta['HTTP_CONTENT_ENCODING'] = enc
1352 b09c9aaa Sofia Papagiannaki
        r = self.upload_object(self.account,
1353 b09c9aaa Sofia Papagiannaki
                               self.container,
1354 b09c9aaa Sofia Papagiannaki
                               filename,
1355 b09c9aaa Sofia Papagiannaki
                               data,
1356 b09c9aaa Sofia Papagiannaki
                               content_type = meta['HTTP_CONTENT_TYPE'],
1357 b09c9aaa Sofia Papagiannaki
                               **meta)
1358 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 422)
1359 d1e43d6f Sofia Papagiannaki
1360 b09c9aaa Sofia Papagiannaki
    def test_chucked_update(self):
1361 b09c9aaa Sofia Papagiannaki
        objname = os.path.split(self.src)[-1:][0]
1362 b09c9aaa Sofia Papagiannaki
        f = open(self.dest, 'r')
1363 b09c9aaa Sofia Papagiannaki
        data = f.read()
1364 b09c9aaa Sofia Papagiannaki
        meta = {}
1365 33ffca25 Sofia Papagiannaki
        type, enc = mimetypes.guess_type(self.dest)
1366 33ffca25 Sofia Papagiannaki
        meta['HTTP_CONTENT_TYPE'] = type and type or 'plain/text'
1367 33ffca25 Sofia Papagiannaki
        if enc:
1368 33ffca25 Sofia Papagiannaki
            meta['HTTP_CONTENT_ENCODING'] = enc
1369 b09c9aaa Sofia Papagiannaki
        meta.update({'HTTP_TRANSFER_ENCODING':'chunked'})
1370 b09c9aaa Sofia Papagiannaki
        r = self.upload_object(self.account,
1371 b09c9aaa Sofia Papagiannaki
                               self.container,
1372 b09c9aaa Sofia Papagiannaki
                               objname,
1373 b09c9aaa Sofia Papagiannaki
                               data,
1374 b09c9aaa Sofia Papagiannaki
                               content_type = 'plain/text',
1375 b09c9aaa Sofia Papagiannaki
                               **meta)
1376 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
1377 b09c9aaa Sofia Papagiannaki
        
1378 b09c9aaa Sofia Papagiannaki
        r = self.get_object(self.account,
1379 b09c9aaa Sofia Papagiannaki
                            self.container,
1380 b09c9aaa Sofia Papagiannaki
                            objname)
1381 b09c9aaa Sofia Papagiannaki
        uploaded_data = r.content
1382 b09c9aaa Sofia Papagiannaki
        f = open(self.src, 'r')
1383 b09c9aaa Sofia Papagiannaki
        actual_data = f.read()
1384 b09c9aaa Sofia Papagiannaki
        self.assertEqual(actual_data, uploaded_data)
1385 b09c9aaa Sofia Papagiannaki
1386 d1e43d6f Sofia Papagiannaki
class ObjectCopy(BaseTestCase):
1387 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1388 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1389 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
1390 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
1391 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1392 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, c)
1393 b09c9aaa Sofia Papagiannaki
        self.obj = self.upload_os_file(self.account,
1394 b09c9aaa Sofia Papagiannaki
                            self.containers[0],
1395 b09c9aaa Sofia Papagiannaki
                            './api/tests.py')
1396 b09c9aaa Sofia Papagiannaki
1397 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
1398 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1399 b09c9aaa Sofia Papagiannaki
            for o in get_content_splitted(self.list_objects(self.account, c)):
1400 b09c9aaa Sofia Papagiannaki
                self.delete_object(self.account, c, o)
1401 b09c9aaa Sofia Papagiannaki
            self.delete_container(self.account, c)
1402 b09c9aaa Sofia Papagiannaki
1403 b09c9aaa Sofia Papagiannaki
    def test_copy(self):
1404 33ffca25 Sofia Papagiannaki
        with AssertInvariant(self.get_object_meta, self.account,
1405 33ffca25 Sofia Papagiannaki
                             self.containers[0], self.obj['name']):
1406 b09c9aaa Sofia Papagiannaki
            #perform copy
1407 b09c9aaa Sofia Papagiannaki
            meta = {'HTTP_X_OBJECT_META_TEST':'testcopy'}
1408 b09c9aaa Sofia Papagiannaki
            src_path = os.path.join('/', self.containers[0], self.obj['name'])
1409 b09c9aaa Sofia Papagiannaki
            r = self.copy_object(self.account,
1410 b09c9aaa Sofia Papagiannaki
                             self.containers[0],
1411 b09c9aaa Sofia Papagiannaki
                             'testcopy',
1412 b09c9aaa Sofia Papagiannaki
                             src_path,
1413 b09c9aaa Sofia Papagiannaki
                             **meta)
1414 b09c9aaa Sofia Papagiannaki
            #assert copy success
1415 b09c9aaa Sofia Papagiannaki
            self.assertEqual(r.status_code, 201)
1416 b09c9aaa Sofia Papagiannaki
            
1417 b09c9aaa Sofia Papagiannaki
            #assert access the new object
1418 b09c9aaa Sofia Papagiannaki
            r = self.get_object_meta(self.account,
1419 b09c9aaa Sofia Papagiannaki
                                     self.containers[0],
1420 b09c9aaa Sofia Papagiannaki
                                     'testcopy')
1421 b09c9aaa Sofia Papagiannaki
            self.assertTrue(r['X-Object-Meta-Test'])
1422 b09c9aaa Sofia Papagiannaki
            self.assertTrue(r['X-Object-Meta-Test'], 'testcopy')
1423 b09c9aaa Sofia Papagiannaki
            
1424 b09c9aaa Sofia Papagiannaki
            #assert etag is the same
1425 b09c9aaa Sofia Papagiannaki
            self.assertEqual(r['ETag'], self.obj['hash'])
1426 b09c9aaa Sofia Papagiannaki
            
1427 b09c9aaa Sofia Papagiannaki
            #assert src object still exists
1428 33ffca25 Sofia Papagiannaki
            r = self.get_object_meta(self.account, self.containers[0],
1429 33ffca25 Sofia Papagiannaki
                                     self.obj['name'])
1430 468b8b86 Antony Chazapis
            self.assertEqual(r.status_code, 200)
1431 b09c9aaa Sofia Papagiannaki
1432 b09c9aaa Sofia Papagiannaki
    def test_copy_from_different_container(self):
1433 b09c9aaa Sofia Papagiannaki
        with AssertInvariant(self.get_object_meta,
1434 b09c9aaa Sofia Papagiannaki
                             self.account,
1435 b09c9aaa Sofia Papagiannaki
                             self.containers[0],
1436 b09c9aaa Sofia Papagiannaki
                             self.obj['name']):
1437 b09c9aaa Sofia Papagiannaki
            meta = {'HTTP_X_OBJECT_META_TEST':'testcopy'}
1438 b09c9aaa Sofia Papagiannaki
            src_path = os.path.join('/', self.containers[0], self.obj['name'])
1439 b09c9aaa Sofia Papagiannaki
            r = self.copy_object(self.account,
1440 b09c9aaa Sofia Papagiannaki
                             self.containers[1],
1441 b09c9aaa Sofia Papagiannaki
                             'testcopy',
1442 b09c9aaa Sofia Papagiannaki
                             src_path,
1443 b09c9aaa Sofia Papagiannaki
                             **meta)
1444 b09c9aaa Sofia Papagiannaki
            self.assertEqual(r.status_code, 201)
1445 b09c9aaa Sofia Papagiannaki
            
1446 b09c9aaa Sofia Papagiannaki
            # assert updated metadata
1447 b09c9aaa Sofia Papagiannaki
            r = self.get_object_meta(self.account,
1448 b09c9aaa Sofia Papagiannaki
                                     self.containers[1],
1449 b09c9aaa Sofia Papagiannaki
                                     'testcopy')
1450 b09c9aaa Sofia Papagiannaki
            self.assertTrue(r['X-Object-Meta-Test'])
1451 b09c9aaa Sofia Papagiannaki
            self.assertTrue(r['X-Object-Meta-Test'], 'testcopy')
1452 b09c9aaa Sofia Papagiannaki
            
1453 b09c9aaa Sofia Papagiannaki
            #assert src object still exists
1454 33ffca25 Sofia Papagiannaki
            r = self.get_object_meta(self.account, self.containers[0],
1455 33ffca25 Sofia Papagiannaki
                                     self.obj['name'])
1456 468b8b86 Antony Chazapis
            self.assertEqual(r.status_code, 200)
1457 b09c9aaa Sofia Papagiannaki
1458 b09c9aaa Sofia Papagiannaki
    def test_copy_invalid(self):
1459 b09c9aaa Sofia Papagiannaki
        #copy from invalid object
1460 b09c9aaa Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_TEST':'testcopy'}
1461 b09c9aaa Sofia Papagiannaki
        r = self.copy_object(self.account,
1462 b09c9aaa Sofia Papagiannaki
                         self.containers[1],
1463 b09c9aaa Sofia Papagiannaki
                         'testcopy',
1464 b09c9aaa Sofia Papagiannaki
                         os.path.join('/', self.containers[0], 'test.py'),
1465 b09c9aaa Sofia Papagiannaki
                         **meta)
1466 b09c9aaa Sofia Papagiannaki
        self.assertItemNotFound(r)
1467 b09c9aaa Sofia Papagiannaki
        
1468 b09c9aaa Sofia Papagiannaki
        #copy from invalid container
1469 b09c9aaa Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_TEST':'testcopy'}
1470 b09c9aaa Sofia Papagiannaki
        src_path = os.path.join('/', self.containers[1], self.obj['name'])
1471 b09c9aaa Sofia Papagiannaki
        r = self.copy_object(self.account,
1472 b09c9aaa Sofia Papagiannaki
                         self.containers[1],
1473 b09c9aaa Sofia Papagiannaki
                         'testcopy',
1474 b09c9aaa Sofia Papagiannaki
                         src_path,
1475 b09c9aaa Sofia Papagiannaki
                         **meta)
1476 b09c9aaa Sofia Papagiannaki
        self.assertItemNotFound(r)
1477 b09c9aaa Sofia Papagiannaki
1478 d1e43d6f Sofia Papagiannaki
class ObjectMove(ObjectCopy):
1479 b09c9aaa Sofia Papagiannaki
    def test_move(self):
1480 b09c9aaa Sofia Papagiannaki
        #perform move
1481 b09c9aaa Sofia Papagiannaki
        meta = {'HTTP_X_OBJECT_META_TEST':'testcopy'}
1482 b09c9aaa Sofia Papagiannaki
        src_path = os.path.join('/', self.containers[0], self.obj['name'])
1483 b09c9aaa Sofia Papagiannaki
        r = self.move_object(self.account,
1484 b09c9aaa Sofia Papagiannaki
                         self.containers[0],
1485 b09c9aaa Sofia Papagiannaki
                         'testcopy',
1486 b09c9aaa Sofia Papagiannaki
                         src_path,
1487 b09c9aaa Sofia Papagiannaki
                         **meta)
1488 b09c9aaa Sofia Papagiannaki
        #assert successful move
1489 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
1490 b09c9aaa Sofia Papagiannaki
        
1491 b09c9aaa Sofia Papagiannaki
        #assert updated metadata
1492 b09c9aaa Sofia Papagiannaki
        r = self.get_object_meta(self.account,
1493 b09c9aaa Sofia Papagiannaki
                                 self.containers[0],
1494 b09c9aaa Sofia Papagiannaki
                                 'testcopy')
1495 b09c9aaa Sofia Papagiannaki
        self.assertTrue(r['X-Object-Meta-Test'])
1496 b09c9aaa Sofia Papagiannaki
        self.assertTrue(r['X-Object-Meta-Test'], 'testcopy')
1497 b09c9aaa Sofia Papagiannaki
        
1498 b09c9aaa Sofia Papagiannaki
        #assert src object no more exists
1499 33ffca25 Sofia Papagiannaki
        r = self.get_object_meta(self.account, self.containers[0],
1500 33ffca25 Sofia Papagiannaki
                                 self.obj['name'])
1501 b09c9aaa Sofia Papagiannaki
        self.assertItemNotFound(r)
1502 b09c9aaa Sofia Papagiannaki
1503 d1e43d6f Sofia Papagiannaki
class ObjectPost(BaseTestCase):
1504 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1505 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1506 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
1507 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
1508 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1509 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, c)
1510 b09c9aaa Sofia Papagiannaki
        self.obj = self.upload_os_file(self.account,
1511 b09c9aaa Sofia Papagiannaki
                                       self.containers[0],
1512 b09c9aaa Sofia Papagiannaki
                                       './api/tests.py')
1513 b09c9aaa Sofia Papagiannaki
1514 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
1515 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1516 b09c9aaa Sofia Papagiannaki
            for o in get_content_splitted(self.list_objects(self.account, c)):
1517 b09c9aaa Sofia Papagiannaki
                self.delete_object(self.account, c, o)
1518 b09c9aaa Sofia Papagiannaki
            self.delete_container(self.account, c)
1519 b09c9aaa Sofia Papagiannaki
1520 33ffca25 Sofia Papagiannaki
    def test_update_meta(self):
1521 b09c9aaa Sofia Papagiannaki
        #perform update metadata
1522 b09c9aaa Sofia Papagiannaki
        more = {'HTTP_X_OBJECT_META_FOO':'foo',
1523 b09c9aaa Sofia Papagiannaki
                'HTTP_X_OBJECT_META_BAR':'bar'}
1524 33ffca25 Sofia Papagiannaki
        r = self.update_object(self.account,
1525 b09c9aaa Sofia Papagiannaki
                                self.containers[0],
1526 b09c9aaa Sofia Papagiannaki
                                self.obj['name'],
1527 b09c9aaa Sofia Papagiannaki
                                **more)
1528 b09c9aaa Sofia Papagiannaki
        #assert request accepted
1529 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
1530 b09c9aaa Sofia Papagiannaki
        
1531 b09c9aaa Sofia Papagiannaki
        #assert old metadata are still there
1532 33ffca25 Sofia Papagiannaki
        r = self.get_object_meta(self.account, self.containers[0],
1533 33ffca25 Sofia Papagiannaki
                                 self.obj['name'])
1534 b09c9aaa Sofia Papagiannaki
        self.assertTrue('X-Object-Meta-Test' not in r.items())
1535 b09c9aaa Sofia Papagiannaki
        
1536 b09c9aaa Sofia Papagiannaki
        #assert new metadata have been updated
1537 b09c9aaa Sofia Papagiannaki
        for k,v in more.items():
1538 b09c9aaa Sofia Papagiannaki
            key = '-'.join(elem.capitalize() for elem in k.split('_')[1:])
1539 b09c9aaa Sofia Papagiannaki
            self.assertTrue(r[key])
1540 b09c9aaa Sofia Papagiannaki
            self.assertTrue(r[key], v)
1541 b09c9aaa Sofia Papagiannaki
1542 33ffca25 Sofia Papagiannaki
    def test_update_object(self,
1543 33ffca25 Sofia Papagiannaki
                           first_byte_pos=0,
1544 33ffca25 Sofia Papagiannaki
                           last_byte_pos=499,
1545 33ffca25 Sofia Papagiannaki
                           instance_length = True,
1546 33ffca25 Sofia Papagiannaki
                           content_length = 500):
1547 33ffca25 Sofia Papagiannaki
        l = len(self.obj['data'])
1548 bd8a3026 Sofia Papagiannaki
        length =  instance_length and l or '*'
1549 bd8a3026 Sofia Papagiannaki
        range = 'bytes %d-%d/%s' %(first_byte_pos,
1550 33ffca25 Sofia Papagiannaki
                                       last_byte_pos,
1551 bd8a3026 Sofia Papagiannaki
                                       length)
1552 33ffca25 Sofia Papagiannaki
        partial = last_byte_pos - first_byte_pos + 1
1553 33ffca25 Sofia Papagiannaki
        data = get_random_data(partial)
1554 33ffca25 Sofia Papagiannaki
        more = {'HTTP_CONTENT_RANGE':range}
1555 33ffca25 Sofia Papagiannaki
        if content_length:
1556 33ffca25 Sofia Papagiannaki
            more.update({'CONTENT_LENGTH':'%s' % content_length})
1557 33ffca25 Sofia Papagiannaki
        
1558 33ffca25 Sofia Papagiannaki
        r = self.update_object(self.account,
1559 33ffca25 Sofia Papagiannaki
                                self.containers[0],
1560 33ffca25 Sofia Papagiannaki
                                self.obj['name'],
1561 33ffca25 Sofia Papagiannaki
                                data,
1562 33ffca25 Sofia Papagiannaki
                                'application/octet-stream',
1563 33ffca25 Sofia Papagiannaki
                                **more)
1564 33ffca25 Sofia Papagiannaki
        
1565 33ffca25 Sofia Papagiannaki
        if partial < 0 or (instance_length and l <= last_byte_pos):
1566 ac62f6da Antony Chazapis
            self.assertEqual(r.status_code, 416)    
1567 33ffca25 Sofia Papagiannaki
        elif content_length and content_length != partial:
1568 33ffca25 Sofia Papagiannaki
            self.assertEqual(r.status_code, 400)
1569 33ffca25 Sofia Papagiannaki
        else:
1570 33ffca25 Sofia Papagiannaki
            self.assertEqual(r.status_code, 204)
1571 33ffca25 Sofia Papagiannaki
            
1572 33ffca25 Sofia Papagiannaki
            #check modified object
1573 33ffca25 Sofia Papagiannaki
            r = self.get_object(self.account,
1574 33ffca25 Sofia Papagiannaki
                            self.containers[0],
1575 33ffca25 Sofia Papagiannaki
                            self.obj['name'])
1576 33ffca25 Sofia Papagiannaki
            self.assertEqual(r.content[0:partial], data)
1577 33ffca25 Sofia Papagiannaki
            self.assertEqual(r.content[partial:l], self.obj['data'][partial:l])
1578 33ffca25 Sofia Papagiannaki
1579 33ffca25 Sofia Papagiannaki
    def test_update_object_no_content_length(self):
1580 33ffca25 Sofia Papagiannaki
        self.test_update_object(content_length = None)
1581 33ffca25 Sofia Papagiannaki
1582 33ffca25 Sofia Papagiannaki
    def test_update_object_invalid_content_length(self):
1583 33ffca25 Sofia Papagiannaki
        with AssertContentInvariant(self.get_object, self.account, self.containers[0],
1584 33ffca25 Sofia Papagiannaki
                            self.obj['name']):
1585 33ffca25 Sofia Papagiannaki
            self.test_update_object(content_length = 1000)
1586 33ffca25 Sofia Papagiannaki
1587 33ffca25 Sofia Papagiannaki
    def test_update_object_with_unknown_instance_length(self):
1588 33ffca25 Sofia Papagiannaki
        self.test_update_object(instance_length = False)
1589 33ffca25 Sofia Papagiannaki
1590 33ffca25 Sofia Papagiannaki
    def test_update_object_invalid_range(self):
1591 33ffca25 Sofia Papagiannaki
        with AssertContentInvariant(self.get_object, self.account, self.containers[0],
1592 33ffca25 Sofia Papagiannaki
                            self.obj['name']):
1593 33ffca25 Sofia Papagiannaki
            self.test_update_object(499, 0, True)
1594 33ffca25 Sofia Papagiannaki
    
1595 33ffca25 Sofia Papagiannaki
    def test_update_object_invalid_range_and_length(self):
1596 33ffca25 Sofia Papagiannaki
        with AssertContentInvariant(self.get_object, self.account, self.containers[0],
1597 33ffca25 Sofia Papagiannaki
                            self.obj['name']):
1598 33ffca25 Sofia Papagiannaki
            self.test_update_object(499, 0, True, -1)
1599 33ffca25 Sofia Papagiannaki
    
1600 33ffca25 Sofia Papagiannaki
    def test_update_object_invalid_range_with_no_content_length(self):
1601 33ffca25 Sofia Papagiannaki
        with AssertContentInvariant(self.get_object, self.account, self.containers[0],
1602 33ffca25 Sofia Papagiannaki
                            self.obj['name']):
1603 33ffca25 Sofia Papagiannaki
            self.test_update_object(499, 0, True, content_length = None)
1604 33ffca25 Sofia Papagiannaki
    
1605 33ffca25 Sofia Papagiannaki
    def test_update_object_out_of_limits(self):    
1606 33ffca25 Sofia Papagiannaki
        with AssertContentInvariant(self.get_object, self.account, self.containers[0],
1607 33ffca25 Sofia Papagiannaki
                            self.obj['name']):
1608 33ffca25 Sofia Papagiannaki
            l = len(self.obj['data'])
1609 33ffca25 Sofia Papagiannaki
            self.test_update_object(0, l+1, True)
1610 33ffca25 Sofia Papagiannaki
1611 33ffca25 Sofia Papagiannaki
    def test_append(self):
1612 33ffca25 Sofia Papagiannaki
        data = get_random_data(500)
1613 33ffca25 Sofia Papagiannaki
        more = {'CONTENT_LENGTH':'500',
1614 33ffca25 Sofia Papagiannaki
                'HTTP_CONTENT_RANGE':'bytes */*'}
1615 33ffca25 Sofia Papagiannaki
        
1616 33ffca25 Sofia Papagiannaki
        r = self.update_object(self.account,
1617 33ffca25 Sofia Papagiannaki
                                self.containers[0],
1618 33ffca25 Sofia Papagiannaki
                                self.obj['name'],
1619 33ffca25 Sofia Papagiannaki
                                data,
1620 33ffca25 Sofia Papagiannaki
                                'application/octet-stream',
1621 33ffca25 Sofia Papagiannaki
                                **more)
1622 33ffca25 Sofia Papagiannaki
        
1623 33ffca25 Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1624 33ffca25 Sofia Papagiannaki
        
1625 33ffca25 Sofia Papagiannaki
        r = self.get_object(self.account,
1626 33ffca25 Sofia Papagiannaki
                                self.containers[0],
1627 33ffca25 Sofia Papagiannaki
                                self.obj['name'])
1628 33ffca25 Sofia Papagiannaki
        self.assertEqual(len(r.content), len(self.obj['data']) + 500)
1629 bd8a3026 Sofia Papagiannaki
        self.assertEqual(r.content[:-500], self.obj['data'])
1630 bd8a3026 Sofia Papagiannaki
1631 bd8a3026 Sofia Papagiannaki
    def test_update_with_chunked_transfer(self):
1632 bd8a3026 Sofia Papagiannaki
        data, pure = create_random_chunked_data()
1633 bd8a3026 Sofia Papagiannaki
        dl = len(pure)
1634 bd8a3026 Sofia Papagiannaki
        fl = len(self.obj['data'])
1635 bd8a3026 Sofia Papagiannaki
        meta = {'HTTP_TRANSFER_ENCODING':'chunked',
1636 bd8a3026 Sofia Papagiannaki
                'HTTP_CONTENT_RANGE':'bytes 0-/%d' %fl}
1637 bd8a3026 Sofia Papagiannaki
        r = self.update_object(self.account,
1638 bd8a3026 Sofia Papagiannaki
                                self.containers[0],
1639 bd8a3026 Sofia Papagiannaki
                                self.obj['name'],
1640 bd8a3026 Sofia Papagiannaki
                                data,
1641 bd8a3026 Sofia Papagiannaki
                                'application/octet-stream',
1642 bd8a3026 Sofia Papagiannaki
                                **meta)
1643 bd8a3026 Sofia Papagiannaki
        
1644 bd8a3026 Sofia Papagiannaki
        #check modified object
1645 bd8a3026 Sofia Papagiannaki
        r = self.get_object(self.account,
1646 bd8a3026 Sofia Papagiannaki
                        self.containers[0],
1647 bd8a3026 Sofia Papagiannaki
                        self.obj['name'])
1648 bd8a3026 Sofia Papagiannaki
        self.assertEqual(r.content[0:dl], pure)
1649 bd8a3026 Sofia Papagiannaki
        self.assertEqual(r.content[dl:fl], self.obj['data'][dl:fl])
1650 bd8a3026 Sofia Papagiannaki
1651 bd8a3026 Sofia Papagiannaki
    def test_update_with_chunked_transfer_strict_range(self):
1652 bd8a3026 Sofia Papagiannaki
        data, pure = create_random_chunked_data()
1653 bd8a3026 Sofia Papagiannaki
        dl = len(pure) - 1
1654 bd8a3026 Sofia Papagiannaki
        fl = len(self.obj['data'])
1655 bd8a3026 Sofia Papagiannaki
        meta = {'HTTP_TRANSFER_ENCODING':'chunked',
1656 bd8a3026 Sofia Papagiannaki
                'HTTP_CONTENT_RANGE':'bytes 0-%d/%d' %(dl, fl)}
1657 bd8a3026 Sofia Papagiannaki
        r = self.update_object(self.account,
1658 bd8a3026 Sofia Papagiannaki
                                self.containers[0],
1659 bd8a3026 Sofia Papagiannaki
                                self.obj['name'],
1660 bd8a3026 Sofia Papagiannaki
                                data,
1661 bd8a3026 Sofia Papagiannaki
                                'application/octet-stream',
1662 bd8a3026 Sofia Papagiannaki
                                **meta)
1663 bd8a3026 Sofia Papagiannaki
        
1664 bd8a3026 Sofia Papagiannaki
        #check modified object
1665 bd8a3026 Sofia Papagiannaki
        r = self.get_object(self.account,
1666 bd8a3026 Sofia Papagiannaki
                        self.containers[0],
1667 bd8a3026 Sofia Papagiannaki
                        self.obj['name'])
1668 bd8a3026 Sofia Papagiannaki
        self.assertEqual(r.content[0:dl+1], pure)
1669 bd8a3026 Sofia Papagiannaki
        self.assertEqual(r.content[dl+1:fl], self.obj['data'][dl+1:fl])
1670 33ffca25 Sofia Papagiannaki
1671 d1e43d6f Sofia Papagiannaki
class ObjectDelete(BaseTestCase):
1672 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1673 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1674 b09c9aaa Sofia Papagiannaki
        self.account = 'test'
1675 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
1676 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1677 b09c9aaa Sofia Papagiannaki
            self.create_container(self.account, c)
1678 b09c9aaa Sofia Papagiannaki
        self.obj = self.upload_os_file(self.account,
1679 b09c9aaa Sofia Papagiannaki
                            self.containers[0],
1680 b09c9aaa Sofia Papagiannaki
                            './api/tests.py')
1681 b09c9aaa Sofia Papagiannaki
1682 b09c9aaa Sofia Papagiannaki
    def tearDown(self):
1683 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1684 b09c9aaa Sofia Papagiannaki
            for o in get_content_splitted(self.list_objects(self.account, c)):
1685 b09c9aaa Sofia Papagiannaki
                self.delete_object(self.account, c, o)
1686 b09c9aaa Sofia Papagiannaki
            self.delete_container(self.account, c)
1687 b09c9aaa Sofia Papagiannaki
1688 b09c9aaa Sofia Papagiannaki
    def test_delete(self):
1689 b09c9aaa Sofia Papagiannaki
        #perform delete object
1690 33ffca25 Sofia Papagiannaki
        r = self.delete_object(self.account, self.containers[0],
1691 33ffca25 Sofia Papagiannaki
                               self.obj['name'])
1692 b09c9aaa Sofia Papagiannaki
        
1693 b09c9aaa Sofia Papagiannaki
        #assert success
1694 b09c9aaa Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
1695 d1e43d6f Sofia Papagiannaki
1696 b09c9aaa Sofia Papagiannaki
    def test_delete_invalid(self):
1697 b09c9aaa Sofia Papagiannaki
        #perform delete object
1698 33ffca25 Sofia Papagiannaki
        r = self.delete_object(self.account, self.containers[1],
1699 33ffca25 Sofia Papagiannaki
                               self.obj['name'])
1700 b09c9aaa Sofia Papagiannaki
        
1701 b09c9aaa Sofia Papagiannaki
        #assert failure
1702 b09c9aaa Sofia Papagiannaki
        self.assertItemNotFound(r)
1703 b09c9aaa Sofia Papagiannaki
1704 b09c9aaa Sofia Papagiannaki
class AssertInvariant(object):
1705 b09c9aaa Sofia Papagiannaki
    def __init__(self, callable, *args, **kwargs):
1706 b09c9aaa Sofia Papagiannaki
        self.callable = callable
1707 b09c9aaa Sofia Papagiannaki
        self.args = args
1708 b09c9aaa Sofia Papagiannaki
        self.kwargs = kwargs
1709 b09c9aaa Sofia Papagiannaki
1710 b09c9aaa Sofia Papagiannaki
    def __enter__(self):
1711 b09c9aaa Sofia Papagiannaki
        self.items = self.callable(*self.args, **self.kwargs).items()
1712 b09c9aaa Sofia Papagiannaki
        return self.items
1713 b09c9aaa Sofia Papagiannaki
1714 b09c9aaa Sofia Papagiannaki
    def __exit__(self, type, value, tb):
1715 b09c9aaa Sofia Papagiannaki
        items = self.callable(*self.args, **self.kwargs).items()
1716 b09c9aaa Sofia Papagiannaki
        assert self.items == items
1717 b09c9aaa Sofia Papagiannaki
1718 33ffca25 Sofia Papagiannaki
class AssertContentInvariant(object):
1719 33ffca25 Sofia Papagiannaki
    def __init__(self, callable, *args, **kwargs):
1720 33ffca25 Sofia Papagiannaki
        self.callable = callable
1721 33ffca25 Sofia Papagiannaki
        self.args = args
1722 33ffca25 Sofia Papagiannaki
        self.kwargs = kwargs
1723 33ffca25 Sofia Papagiannaki
1724 33ffca25 Sofia Papagiannaki
    def __enter__(self):
1725 33ffca25 Sofia Papagiannaki
        self.content = self.callable(*self.args, **self.kwargs).content
1726 33ffca25 Sofia Papagiannaki
        return self.content
1727 33ffca25 Sofia Papagiannaki
1728 33ffca25 Sofia Papagiannaki
    def __exit__(self, type, value, tb):
1729 33ffca25 Sofia Papagiannaki
        content = self.callable(*self.args, **self.kwargs).content
1730 33ffca25 Sofia Papagiannaki
        assert self.content == content
1731 33ffca25 Sofia Papagiannaki
1732 b09c9aaa Sofia Papagiannaki
def get_content_splitted(response):
1733 b09c9aaa Sofia Papagiannaki
    if response:
1734 b09c9aaa Sofia Papagiannaki
        return response.content.split('\n')
1735 b09c9aaa Sofia Papagiannaki
1736 d1e43d6f Sofia Papagiannaki
def compute_md5_hash(data):
1737 b09c9aaa Sofia Papagiannaki
    md5 = hashlib.md5()
1738 b09c9aaa Sofia Papagiannaki
    offset = 0
1739 b09c9aaa Sofia Papagiannaki
    md5.update(data)
1740 b09c9aaa Sofia Papagiannaki
    return md5.hexdigest().lower()
1741 b09c9aaa Sofia Papagiannaki
1742 33ffca25 Sofia Papagiannaki
def compute_block_hash(data, algorithm):
1743 33ffca25 Sofia Papagiannaki
    h = hashlib.new(algorithm)
1744 d1e43d6f Sofia Papagiannaki
    h.update(data.rstrip('\x00'))
1745 d1e43d6f Sofia Papagiannaki
    return h.hexdigest()
1746 d1e43d6f Sofia Papagiannaki
1747 b09c9aaa Sofia Papagiannaki
def create_chunked_update_test_file(src, dest):
1748 b09c9aaa Sofia Papagiannaki
    fr = open(src, 'r')
1749 b09c9aaa Sofia Papagiannaki
    fw = open(dest, 'w')
1750 b09c9aaa Sofia Papagiannaki
    data = fr.readline()
1751 b09c9aaa Sofia Papagiannaki
    while data:
1752 b09c9aaa Sofia Papagiannaki
        fw.write(hex(len(data)))
1753 b09c9aaa Sofia Papagiannaki
        fw.write('\r\n')
1754 b09c9aaa Sofia Papagiannaki
        fw.write(data)
1755 b09c9aaa Sofia Papagiannaki
        data = fr.readline()
1756 b09c9aaa Sofia Papagiannaki
    fw.write(hex(0))
1757 b09c9aaa Sofia Papagiannaki
    fw.write('\r\n')
1758 b09c9aaa Sofia Papagiannaki
1759 bd8a3026 Sofia Papagiannaki
def create_random_chunked_data(rows=5):
1760 33ffca25 Sofia Papagiannaki
    i = 0
1761 33ffca25 Sofia Papagiannaki
    out = []
1762 bd8a3026 Sofia Papagiannaki
    pure= []
1763 33ffca25 Sofia Papagiannaki
    while i < rows:
1764 33ffca25 Sofia Papagiannaki
        data = get_random_data(random.randint(1, 100))
1765 33ffca25 Sofia Papagiannaki
        out.append(hex(len(data)))
1766 33ffca25 Sofia Papagiannaki
        out.append(data)
1767 bd8a3026 Sofia Papagiannaki
        pure.append(data)
1768 33ffca25 Sofia Papagiannaki
        i+=1
1769 33ffca25 Sofia Papagiannaki
    out.append(hex(0))
1770 33ffca25 Sofia Papagiannaki
    out.append('\r\n')
1771 bd8a3026 Sofia Papagiannaki
    return '\r\n'.join(out), ''.join(pure)
1772 33ffca25 Sofia Papagiannaki
1773 bd8a3026 Sofia Papagiannaki
def get_random_data(length=500):
1774 33ffca25 Sofia Papagiannaki
    char_set = string.ascii_uppercase + string.digits
1775 33ffca25 Sofia Papagiannaki
    return ''.join(random.choice(char_set) for x in range(length))
1776 33ffca25 Sofia Papagiannaki
1777 b09c9aaa Sofia Papagiannaki
o_names = ['kate.jpg',
1778 b09c9aaa Sofia Papagiannaki
           'kate_beckinsale.jpg',
1779 b09c9aaa Sofia Papagiannaki
           'How To Win Friends And Influence People.pdf',
1780 b09c9aaa Sofia Papagiannaki
           'moms_birthday.jpg',
1781 b09c9aaa Sofia Papagiannaki
           'poodle_strut.mov',
1782 b09c9aaa Sofia Papagiannaki
           'Disturbed - Down With The Sickness.mp3',
1783 b09c9aaa Sofia Papagiannaki
           'army_of_darkness.avi',
1784 b09c9aaa Sofia Papagiannaki
           'the_mad.avi',
1785 b09c9aaa Sofia Papagiannaki
           'photos/animals/dogs/poodle.jpg',
1786 b09c9aaa Sofia Papagiannaki
           'photos/animals/dogs/terrier.jpg',
1787 b09c9aaa Sofia Papagiannaki
           'photos/animals/cats/persian.jpg',
1788 b09c9aaa Sofia Papagiannaki
           'photos/animals/cats/siamese.jpg',
1789 b09c9aaa Sofia Papagiannaki
           'photos/plants/fern.jpg',
1790 b09c9aaa Sofia Papagiannaki
           'photos/plants/rose.jpg',
1791 0a425890 Antony Chazapis
           'photos/me.jpg']