Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-tools / pithos / tools / test.py @ db117cac

History | View | Annotate | Download (96.2 kB)

1 952f4da1 Sofia Papagiannaki
#!/usr/bin/env python
2 ae75584f Sofia Papagiannaki
#coding=utf8
3 ae75584f Sofia Papagiannaki
4 2e662088 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
5 7067193f Kostas Papadimitriou
#
6 4288ade0 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
7 4288ade0 Sofia Papagiannaki
# without modification, are permitted provided that the following
8 4288ade0 Sofia Papagiannaki
# conditions are met:
9 7067193f Kostas Papadimitriou
#
10 4288ade0 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
11 4288ade0 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
12 4288ade0 Sofia Papagiannaki
#      disclaimer.
13 7067193f Kostas Papadimitriou
#
14 4288ade0 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
15 4288ade0 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
16 4288ade0 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
17 4288ade0 Sofia Papagiannaki
#      provided with the distribution.
18 7067193f Kostas Papadimitriou
#
19 4288ade0 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
20 4288ade0 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 4288ade0 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 4288ade0 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
23 4288ade0 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 4288ade0 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 4288ade0 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 4288ade0 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 4288ade0 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 4288ade0 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 4288ade0 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 4288ade0 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
31 7067193f Kostas Papadimitriou
#
32 4288ade0 Sofia Papagiannaki
# The views and conclusions contained in the software and
33 4288ade0 Sofia Papagiannaki
# documentation are those of the authors and should not be
34 4288ade0 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
35 4288ade0 Sofia Papagiannaki
# or implied, of GRNET S.A.
36 4288ade0 Sofia Papagiannaki
37 6e147ecc Antony Chazapis
from pithos.tools.lib.client import Pithos_Client, Fault
38 6e147ecc Antony Chazapis
from pithos.tools.lib.util import get_user, get_auth, get_url
39 5a96180b Antony Chazapis
40 b09c9aaa Sofia Papagiannaki
from xml.dom import minidom
41 25c3841c Sofia Papagiannaki
from StringIO import StringIO
42 35390ded Sofia Papagiannaki
from hashlib import new as newhasher
43 35390ded Sofia Papagiannaki
from binascii import hexlify
44 79520131 Sofia Papagiannaki
from httplib import HTTPConnection, HTTPSConnection
45 96738a78 Sofia Papagiannaki
from urlparse import urlparse
46 b5dc1bda Sofia Papagiannaki
47 e7b51248 Sofia Papagiannaki
import json
48 7812e1f9 Sofia Papagiannaki
import unittest
49 f0eacc2c Sofia Papagiannaki
import time as _time
50 b09c9aaa Sofia Papagiannaki
import types
51 b09c9aaa Sofia Papagiannaki
import hashlib
52 b09c9aaa Sofia Papagiannaki
import mimetypes
53 b09c9aaa Sofia Papagiannaki
import random
54 b09c9aaa Sofia Papagiannaki
import datetime
55 d1e43d6f Sofia Papagiannaki
import string
56 23028d31 Sofia Papagiannaki
import re
57 23028d31 Sofia Papagiannaki
58 b09c9aaa Sofia Papagiannaki
DATE_FORMATS = ["%a %b %d %H:%M:%S %Y",
59 b09c9aaa Sofia Papagiannaki
                "%A, %d-%b-%y %H:%M:%S GMT",
60 b09c9aaa Sofia Papagiannaki
                "%a, %d %b %Y %H:%M:%S GMT"]
61 b09c9aaa Sofia Papagiannaki
62 ae75584f Sofia Papagiannaki
OTHER_ACCOUNTS = {
63 ae75584f Sofia Papagiannaki
    '0001': 'verigak',
64 ae75584f Sofia Papagiannaki
    '0002': 'chazapis',
65 ae75584f Sofia Papagiannaki
    '0003': 'gtsouk',
66 ae75584f Sofia Papagiannaki
    '0004': 'papagian',
67 ae75584f Sofia Papagiannaki
    '0005': 'louridas',
68 ae75584f Sofia Papagiannaki
    '0006': 'chstath',
69 ae75584f Sofia Papagiannaki
    '0007': 'pkanavos',
70 e7b51248 Sofia Papagiannaki
    '0008': 'mvasilak',
71 95e92490 Sofia Papagiannaki
    '0009': 'διογένης'}
72 ae75584f Sofia Papagiannaki
73 23028d31 Sofia Papagiannaki
class BaseTestCase(unittest.TestCase):
74 b09c9aaa Sofia Papagiannaki
    #TODO unauthorized request
75 b09c9aaa Sofia Papagiannaki
    def setUp(self):
76 43cc6f76 Sofia Papagiannaki
        self.client = Pithos_Client(get_url(), get_auth(), get_user())
77 96bfb229 Sofia Papagiannaki
        self._clean_account()
78 43cc6f76 Sofia Papagiannaki
        self.invalid_client = Pithos_Client(get_url(), get_auth(), 'invalid')
79 7067193f Kostas Papadimitriou
80 68229c3e Sofia Papagiannaki
        #keep track of initial account groups
81 68229c3e Sofia Papagiannaki
        self.initial_groups = self.client.retrieve_account_groups()
82 7067193f Kostas Papadimitriou
83 68229c3e Sofia Papagiannaki
        #keep track of initial account meta
84 68229c3e Sofia Papagiannaki
        self.initial_meta = self.client.retrieve_account_metadata(restricted=True)
85 7067193f Kostas Papadimitriou
86 b09c9aaa Sofia Papagiannaki
        self.extended = {
87 b09c9aaa Sofia Papagiannaki
            'container':(
88 b09c9aaa Sofia Papagiannaki
                'name',
89 b09c9aaa Sofia Papagiannaki
                'count',
90 b09c9aaa Sofia Papagiannaki
                'bytes',
91 ae75584f Sofia Papagiannaki
                'last_modified',
92 ce9e59cf Sofia Papagiannaki
                'x_container_policy'),
93 b09c9aaa Sofia Papagiannaki
            'object':(
94 b09c9aaa Sofia Papagiannaki
                'name',
95 b09c9aaa Sofia Papagiannaki
                'hash',
96 b09c9aaa Sofia Papagiannaki
                'bytes',
97 b09c9aaa Sofia Papagiannaki
                'content_type',
98 b09c9aaa Sofia Papagiannaki
                'content_encoding',
99 b09c9aaa Sofia Papagiannaki
                'last_modified',)}
100 297513ba Antony Chazapis
        self.return_codes = (400, 401, 403, 404, 503,)
101 7067193f Kostas Papadimitriou
102 25c3841c Sofia Papagiannaki
    def tearDown(self):
103 68229c3e Sofia Papagiannaki
        #delete additionally created meta
104 68229c3e Sofia Papagiannaki
        l = []
105 68229c3e Sofia Papagiannaki
        for m in self.client.retrieve_account_metadata(restricted=True):
106 68229c3e Sofia Papagiannaki
            if m not in self.initial_meta:
107 68229c3e Sofia Papagiannaki
                l.append(m)
108 68229c3e Sofia Papagiannaki
        self.client.delete_account_metadata(l)
109 7067193f Kostas Papadimitriou
110 68229c3e Sofia Papagiannaki
        #delete additionally created groups
111 68229c3e Sofia Papagiannaki
        l = []
112 68229c3e Sofia Papagiannaki
        for g in self.client.retrieve_account_groups():
113 68229c3e Sofia Papagiannaki
            if g not in self.initial_groups:
114 68229c3e Sofia Papagiannaki
                l.append(g)
115 68229c3e Sofia Papagiannaki
        self.client.unset_account_groups(l)
116 96bfb229 Sofia Papagiannaki
        self._clean_account()
117 7067193f Kostas Papadimitriou
118 96bfb229 Sofia Papagiannaki
    def _clean_account(self):
119 25c3841c Sofia Papagiannaki
        for c in self.client.list_containers():
120 ae75584f Sofia Papagiannaki
            while True:
121 ae75584f Sofia Papagiannaki
                #list objects returns at most 10000 objects
122 ae75584f Sofia Papagiannaki
                #so repeat until there are no more objects
123 ae75584f Sofia Papagiannaki
                objects = self.client.list_objects(c)
124 ae75584f Sofia Papagiannaki
                if not objects:
125 ae75584f Sofia Papagiannaki
                    break
126 ae75584f Sofia Papagiannaki
                for o in objects:
127 ae75584f Sofia Papagiannaki
                    self.client.delete_object(c, o)
128 25c3841c Sofia Papagiannaki
            self.client.delete_container(c)
129 7067193f Kostas Papadimitriou
130 23028d31 Sofia Papagiannaki
    def assert_status(self, status, codes):
131 b09c9aaa Sofia Papagiannaki
        l = [elem for elem in self.return_codes]
132 b09c9aaa Sofia Papagiannaki
        if type(codes) == types.ListType:
133 b09c9aaa Sofia Papagiannaki
            l.extend(codes)
134 b09c9aaa Sofia Papagiannaki
        else:
135 b09c9aaa Sofia Papagiannaki
            l.append(codes)
136 23028d31 Sofia Papagiannaki
        self.assertTrue(status in l)
137 7067193f Kostas Papadimitriou
138 ae75584f Sofia Papagiannaki
    def assert_extended(self, data, format, type, size=10000):
139 f0eacc2c Sofia Papagiannaki
        if format == 'xml':
140 f0eacc2c Sofia Papagiannaki
            self._assert_xml(data, type, size)
141 f0eacc2c Sofia Papagiannaki
        elif format == 'json':
142 f0eacc2c Sofia Papagiannaki
            self._assert_json(data, type, size)
143 7067193f Kostas Papadimitriou
144 f0eacc2c Sofia Papagiannaki
    def _assert_json(self, data, type, size):
145 f0eacc2c Sofia Papagiannaki
        convert = lambda s: s.lower()
146 f0eacc2c Sofia Papagiannaki
        info = [convert(elem) for elem in self.extended[type]]
147 f0eacc2c Sofia Papagiannaki
        self.assertTrue(len(data) <= size)
148 f0eacc2c Sofia Papagiannaki
        for item in info:
149 f0eacc2c Sofia Papagiannaki
            for i in data:
150 f0eacc2c Sofia Papagiannaki
                if 'subdir' in i.keys():
151 f0eacc2c Sofia Papagiannaki
                    continue
152 f0eacc2c Sofia Papagiannaki
                self.assertTrue(item in i.keys())
153 7067193f Kostas Papadimitriou
154 f0eacc2c Sofia Papagiannaki
    def _assert_xml(self, data, type, size):
155 f0eacc2c Sofia Papagiannaki
        convert = lambda s: s.lower()
156 f0eacc2c Sofia Papagiannaki
        info = [convert(elem) for elem in self.extended[type]]
157 f0eacc2c Sofia Papagiannaki
        try:
158 f0eacc2c Sofia Papagiannaki
            info.remove('content_encoding')
159 f0eacc2c Sofia Papagiannaki
        except ValueError:
160 f0eacc2c Sofia Papagiannaki
            pass
161 f0eacc2c Sofia Papagiannaki
        xml = data
162 f0eacc2c Sofia Papagiannaki
        entities = xml.getElementsByTagName(type)
163 f0eacc2c Sofia Papagiannaki
        self.assertTrue(len(entities) <= size)
164 f0eacc2c Sofia Papagiannaki
        for e in entities:
165 f0eacc2c Sofia Papagiannaki
            for item in info:
166 ae75584f Sofia Papagiannaki
                self.assertTrue(e.getElementsByTagName(item))
167 7067193f Kostas Papadimitriou
168 23028d31 Sofia Papagiannaki
    def assert_raises_fault(self, status, callableObj, *args, **kwargs):
169 23028d31 Sofia Papagiannaki
        """
170 23028d31 Sofia Papagiannaki
        asserts that a Fault with a specific status is raised
171 23028d31 Sofia Papagiannaki
        when callableObj is called with the specific arguments
172 23028d31 Sofia Papagiannaki
        """
173 23028d31 Sofia Papagiannaki
        try:
174 ae75584f Sofia Papagiannaki
            r = callableObj(*args, **kwargs)
175 23028d31 Sofia Papagiannaki
            self.fail('Should never reach here')
176 23028d31 Sofia Papagiannaki
        except Fault, f:
177 0538cac6 Sofia Papagiannaki
            if type(status) == types.ListType:
178 0538cac6 Sofia Papagiannaki
                self.failUnless(f.status in status)
179 0538cac6 Sofia Papagiannaki
            else:
180 0538cac6 Sofia Papagiannaki
                self.failUnless(f.status == status)
181 7067193f Kostas Papadimitriou
182 e7b51248 Sofia Papagiannaki
    def assert_not_raises_fault(self, status, callableObj, *args, **kwargs):
183 e7b51248 Sofia Papagiannaki
        """
184 e7b51248 Sofia Papagiannaki
        asserts that a Fault with a specific status is not raised
185 e7b51248 Sofia Papagiannaki
        when callableObj is called with the specific arguments
186 e7b51248 Sofia Papagiannaki
        """
187 e7b51248 Sofia Papagiannaki
        try:
188 e7b51248 Sofia Papagiannaki
            r = callableObj(*args, **kwargs)
189 e7b51248 Sofia Papagiannaki
        except Fault, f:
190 95e92490 Sofia Papagiannaki
            self.failIfEqual(f.status, status)
191 7067193f Kostas Papadimitriou
192 25c3841c Sofia Papagiannaki
    def assert_container_exists(self, container):
193 25c3841c Sofia Papagiannaki
        """
194 25c3841c Sofia Papagiannaki
        asserts the existence of a container
195 25c3841c Sofia Papagiannaki
        """
196 25c3841c Sofia Papagiannaki
        try:
197 25c3841c Sofia Papagiannaki
            self.client.retrieve_container_metadata(container)
198 25c3841c Sofia Papagiannaki
        except Fault, f:
199 25c3841c Sofia Papagiannaki
            self.failIf(f.status == 404)
200 7067193f Kostas Papadimitriou
201 e7b51248 Sofia Papagiannaki
    def assert_container_not_exists(self, container):
202 e7b51248 Sofia Papagiannaki
        """
203 e7b51248 Sofia Papagiannaki
        asserts there is no such a container
204 e7b51248 Sofia Papagiannaki
        """
205 e7b51248 Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.retrieve_container_metadata,
206 e7b51248 Sofia Papagiannaki
                                 container)
207 7067193f Kostas Papadimitriou
208 23028d31 Sofia Papagiannaki
    def assert_object_exists(self, container, object):
209 23028d31 Sofia Papagiannaki
        """
210 23028d31 Sofia Papagiannaki
        asserts the existence of an object
211 23028d31 Sofia Papagiannaki
        """
212 23028d31 Sofia Papagiannaki
        try:
213 23028d31 Sofia Papagiannaki
            self.client.retrieve_object_metadata(container, object)
214 23028d31 Sofia Papagiannaki
        except Fault, f:
215 23028d31 Sofia Papagiannaki
            self.failIf(f.status == 404)
216 7067193f Kostas Papadimitriou
217 23028d31 Sofia Papagiannaki
    def assert_object_not_exists(self, container, object):
218 23028d31 Sofia Papagiannaki
        """
219 23028d31 Sofia Papagiannaki
        asserts there is no such an object
220 23028d31 Sofia Papagiannaki
        """
221 23028d31 Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.retrieve_object_metadata,
222 23028d31 Sofia Papagiannaki
                                 container, object)
223 7067193f Kostas Papadimitriou
224 8d964102 Sofia Papagiannaki
    def assert_versionlist_structure(self, versionlist):
225 8d964102 Sofia Papagiannaki
        self.assertTrue(type(versionlist) == types.ListType)
226 8d964102 Sofia Papagiannaki
        for elem in versionlist:
227 8d964102 Sofia Papagiannaki
            self.assertTrue(type(elem) == types.ListType)
228 8d964102 Sofia Papagiannaki
            self.assertEqual(len(elem), 2)
229 7067193f Kostas Papadimitriou
230 23028d31 Sofia Papagiannaki
    def upload_random_data(self, container, name, length=1024, type=None,
231 23028d31 Sofia Papagiannaki
                           enc=None, **meta):
232 33ffca25 Sofia Papagiannaki
        data = get_random_data(length)
233 23028d31 Sofia Papagiannaki
        return self.upload_data(container, name, data, type, enc, **meta)
234 7067193f Kostas Papadimitriou
235 23028d31 Sofia Papagiannaki
    def upload_data(self, container, name, data, type=None, enc=None, etag=None,
236 23028d31 Sofia Papagiannaki
                    **meta):
237 b09c9aaa Sofia Papagiannaki
        obj = {}
238 b09c9aaa Sofia Papagiannaki
        obj['name'] = name
239 b09c9aaa Sofia Papagiannaki
        try:
240 b09c9aaa Sofia Papagiannaki
            obj['data'] = data
241 d1e43d6f Sofia Papagiannaki
            obj['hash'] = compute_md5_hash(obj['data'])
242 7067193f Kostas Papadimitriou
243 25c3841c Sofia Papagiannaki
            args = {}
244 25c3841c Sofia Papagiannaki
            args['etag'] = etag if etag else obj['hash']
245 7067193f Kostas Papadimitriou
246 ae75584f Sofia Papagiannaki
            try:
247 ae75584f Sofia Papagiannaki
                guess = mimetypes.guess_type(name)
248 ae75584f Sofia Papagiannaki
                type = type if type else guess[0]
249 ae75584f Sofia Papagiannaki
                enc = enc if enc else guess[1]
250 ae75584f Sofia Papagiannaki
            except:
251 ae75584f Sofia Papagiannaki
                pass
252 25c3841c Sofia Papagiannaki
            args['content_type'] = type if type else 'plain/text'
253 25c3841c Sofia Papagiannaki
            args['content_encoding'] = enc if enc else None
254 7067193f Kostas Papadimitriou
255 25c3841c Sofia Papagiannaki
            obj['meta'] = args
256 7067193f Kostas Papadimitriou
257 23028d31 Sofia Papagiannaki
            path = '/%s/%s' % (container, name)
258 ad7e4bea Sofia Papagiannaki
            self.client.create_object(container, name, f=StringIO(obj['data']),
259 ad7e4bea Sofia Papagiannaki
                                      meta=meta, **args)
260 7067193f Kostas Papadimitriou
261 25c3841c Sofia Papagiannaki
            return obj
262 b09c9aaa Sofia Papagiannaki
        except IOError:
263 b09c9aaa Sofia Papagiannaki
            return
264 b09c9aaa Sofia Papagiannaki
265 d1e43d6f Sofia Papagiannaki
class AccountHead(BaseTestCase):
266 d1e43d6f Sofia Papagiannaki
    def setUp(self):
267 d1e43d6f Sofia Papagiannaki
        BaseTestCase.setUp(self)
268 d1e43d6f Sofia Papagiannaki
        self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
269 d1e43d6f Sofia Papagiannaki
        for item in self.containers:
270 25c3841c Sofia Papagiannaki
            self.client.create_container(item)
271 7067193f Kostas Papadimitriou
272 7812e1f9 Sofia Papagiannaki
        meta = {'foo':'bar'}
273 7812e1f9 Sofia Papagiannaki
        self.client.update_account_metadata(**meta)
274 68229c3e Sofia Papagiannaki
        #self.updated_meta = self.initial_meta.update(meta)
275 7067193f Kostas Papadimitriou
276 d1e43d6f Sofia Papagiannaki
    def test_get_account_meta(self):
277 25c3841c Sofia Papagiannaki
        meta = self.client.retrieve_account_metadata()
278 7067193f Kostas Papadimitriou
279 25c3841c Sofia Papagiannaki
        containers = self.client.list_containers()
280 33ffca25 Sofia Papagiannaki
        l = str(len(containers))
281 25c3841c Sofia Papagiannaki
        self.assertEqual(meta['x-account-container-count'], l)
282 d1e43d6f Sofia Papagiannaki
        size = 0
283 d1e43d6f Sofia Papagiannaki
        for c in containers:
284 25c3841c Sofia Papagiannaki
            m = self.client.retrieve_container_metadata(c)
285 25c3841c Sofia Papagiannaki
            size = size + int(m['x-container-bytes-used'])
286 25c3841c Sofia Papagiannaki
        self.assertEqual(meta['x-account-bytes-used'], str(size))
287 7067193f Kostas Papadimitriou
288 297513ba Antony Chazapis
    def test_get_account_403(self):
289 297513ba Antony Chazapis
        self.assert_raises_fault(403,
290 f0eacc2c Sofia Papagiannaki
                                 self.invalid_client.retrieve_account_metadata)
291 7067193f Kostas Papadimitriou
292 f0eacc2c Sofia Papagiannaki
    def test_get_account_meta_until(self):
293 f0eacc2c Sofia Papagiannaki
        t = datetime.datetime.utcnow()
294 f0eacc2c Sofia Papagiannaki
        past = t - datetime.timedelta(minutes=-15)
295 f0eacc2c Sofia Papagiannaki
        past = int(_time.mktime(past.timetuple()))
296 7067193f Kostas Papadimitriou
297 7812e1f9 Sofia Papagiannaki
        meta = {'premium':True}
298 f0eacc2c Sofia Papagiannaki
        self.client.update_account_metadata(**meta)
299 f0eacc2c Sofia Papagiannaki
        meta = self.client.retrieve_account_metadata(restricted=True,
300 f0eacc2c Sofia Papagiannaki
                                                     until=past)
301 7812e1f9 Sofia Papagiannaki
        self.assertTrue('premium' not in meta)
302 7067193f Kostas Papadimitriou
303 f0eacc2c Sofia Papagiannaki
        meta = self.client.retrieve_account_metadata(restricted=True)
304 7812e1f9 Sofia Papagiannaki
        self.assertTrue('premium' in meta)
305 7067193f Kostas Papadimitriou
306 f0eacc2c Sofia Papagiannaki
    def test_get_account_meta_until_invalid_date(self):
307 7812e1f9 Sofia Papagiannaki
        meta = {'premium':True}
308 f0eacc2c Sofia Papagiannaki
        self.client.update_account_metadata(**meta)
309 f0eacc2c Sofia Papagiannaki
        meta = self.client.retrieve_account_metadata(restricted=True,
310 f0eacc2c Sofia Papagiannaki
                                                     until='kshfksfh')
311 7812e1f9 Sofia Papagiannaki
        self.assertTrue('premium' in meta)
312 7067193f Kostas Papadimitriou
313 d1e43d6f Sofia Papagiannaki
class AccountGet(BaseTestCase):
314 b09c9aaa Sofia Papagiannaki
    def setUp(self):
315 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
316 b09c9aaa Sofia Papagiannaki
        #create some containers
317 b09c9aaa Sofia Papagiannaki
        self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
318 b09c9aaa Sofia Papagiannaki
        for item in self.containers:
319 25c3841c Sofia Papagiannaki
            self.client.create_container(item)
320 7067193f Kostas Papadimitriou
321 b09c9aaa Sofia Papagiannaki
    def test_list(self):
322 b09c9aaa Sofia Papagiannaki
        #list containers
323 25c3841c Sofia Papagiannaki
        containers = self.client.list_containers()
324 b09c9aaa Sofia Papagiannaki
        self.assertEquals(self.containers, containers)
325 7067193f Kostas Papadimitriou
326 297513ba Antony Chazapis
    def test_list_403(self):
327 297513ba Antony Chazapis
        self.assert_raises_fault(403, self.invalid_client.list_containers)
328 7067193f Kostas Papadimitriou
329 b09c9aaa Sofia Papagiannaki
    def test_list_with_limit(self):
330 b09c9aaa Sofia Papagiannaki
        limit = 2
331 25c3841c Sofia Papagiannaki
        containers = self.client.list_containers(limit=limit)
332 b09c9aaa Sofia Papagiannaki
        self.assertEquals(len(containers), limit)
333 b09c9aaa Sofia Papagiannaki
        self.assertEquals(self.containers[:2], containers)
334 7067193f Kostas Papadimitriou
335 b09c9aaa Sofia Papagiannaki
    def test_list_with_marker(self):
336 33ffca25 Sofia Papagiannaki
        l = 2
337 33ffca25 Sofia Papagiannaki
        m = 'bananas'
338 25c3841c Sofia Papagiannaki
        containers = self.client.list_containers(limit=l, marker=m)
339 33ffca25 Sofia Papagiannaki
        i = self.containers.index(m) + 1
340 33ffca25 Sofia Papagiannaki
        self.assertEquals(self.containers[i:(i+l)], containers)
341 7067193f Kostas Papadimitriou
342 33ffca25 Sofia Papagiannaki
        m = 'oranges'
343 25c3841c Sofia Papagiannaki
        containers = self.client.list_containers(limit=l, marker=m)
344 33ffca25 Sofia Papagiannaki
        i = self.containers.index(m) + 1
345 33ffca25 Sofia Papagiannaki
        self.assertEquals(self.containers[i:(i+l)], containers)
346 7067193f Kostas Papadimitriou
347 b09c9aaa Sofia Papagiannaki
    def test_list_json_with_marker(self):
348 33ffca25 Sofia Papagiannaki
        l = 2
349 33ffca25 Sofia Papagiannaki
        m = 'bananas'
350 f0eacc2c Sofia Papagiannaki
        containers = self.client.list_containers(limit=l, marker=m, format='json')
351 f0eacc2c Sofia Papagiannaki
        self.assert_extended(containers, 'json', 'container', l)
352 b09c9aaa Sofia Papagiannaki
        self.assertEqual(containers[0]['name'], 'kiwis')
353 b09c9aaa Sofia Papagiannaki
        self.assertEqual(containers[1]['name'], 'oranges')
354 7067193f Kostas Papadimitriou
355 f0eacc2c Sofia Papagiannaki
    def test_list_xml_with_marker(self):
356 f0eacc2c Sofia Papagiannaki
        l = 2
357 f0eacc2c Sofia Papagiannaki
        m = 'oranges'
358 f0eacc2c Sofia Papagiannaki
        xml = self.client.list_containers(limit=l, marker=m, format='xml')
359 ae75584f Sofia Papagiannaki
        self.assert_extended(xml, 'xml', 'container', l)
360 f0eacc2c Sofia Papagiannaki
        nodes = xml.getElementsByTagName('name')
361 f0eacc2c Sofia Papagiannaki
        self.assertEqual(len(nodes), 1)
362 f0eacc2c Sofia Papagiannaki
        self.assertEqual(nodes[0].childNodes[0].data, 'pears')
363 7067193f Kostas Papadimitriou
364 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since(self):
365 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
366 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
367 7067193f Kostas Papadimitriou
368 d1e43d6f Sofia Papagiannaki
        #add a new container
369 25c3841c Sofia Papagiannaki
        self.client.create_container('dummy')
370 7067193f Kostas Papadimitriou
371 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
372 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
373 25c3841c Sofia Papagiannaki
            try:
374 25c3841c Sofia Papagiannaki
                c = self.client.list_containers(if_modified_since=past)
375 25c3841c Sofia Papagiannaki
                self.assertEqual(len(c), len(self.containers) + 1)
376 25c3841c Sofia Papagiannaki
            except Fault, f:
377 25c3841c Sofia Papagiannaki
                self.failIf(f.status == 304) #fail if not modified
378 2535deff Sofia Papagiannaki
        
379 7067193f Kostas Papadimitriou
380 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since_invalid_date(self):
381 25c3841c Sofia Papagiannaki
        c = self.client.list_containers(if_modified_since='')
382 25c3841c Sofia Papagiannaki
        self.assertEqual(len(c), len(self.containers))
383 7067193f Kostas Papadimitriou
384 d1e43d6f Sofia Papagiannaki
    def test_if_not_modified_since(self):
385 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
386 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
387 7067193f Kostas Papadimitriou
388 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
389 25c3841c Sofia Papagiannaki
            args = {'if_modified_since':'%s' %since.strftime(f)}
390 7067193f Kostas Papadimitriou
391 d1e43d6f Sofia Papagiannaki
            #assert not modified
392 25c3841c Sofia Papagiannaki
            self.assert_raises_fault(304, self.client.list_containers, **args)
393 7067193f Kostas Papadimitriou
394 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since(self):
395 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
396 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
397 7067193f Kostas Papadimitriou
398 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
399 25c3841c Sofia Papagiannaki
            c = self.client.list_containers(if_unmodified_since=since.strftime(f))
400 7067193f Kostas Papadimitriou
401 d1e43d6f Sofia Papagiannaki
            #assert success
402 25c3841c Sofia Papagiannaki
            self.assertEqual(self.containers, c)
403 7067193f Kostas Papadimitriou
404 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since_precondition_failed(self):
405 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
406 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
407 7067193f Kostas Papadimitriou
408 d1e43d6f Sofia Papagiannaki
        #add a new container
409 25c3841c Sofia Papagiannaki
        self.client.create_container('dummy')
410 7067193f Kostas Papadimitriou
411 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
412 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
413 7067193f Kostas Papadimitriou
414 25c3841c Sofia Papagiannaki
            args = {'if_unmodified_since':'%s' %past}
415 7067193f Kostas Papadimitriou
416 23028d31 Sofia Papagiannaki
            #assert precondition failed
417 25c3841c Sofia Papagiannaki
            self.assert_raises_fault(412, self.client.list_containers, **args)
418 7067193f Kostas Papadimitriou
419 d1e43d6f Sofia Papagiannaki
class AccountPost(BaseTestCase):
420 b09c9aaa Sofia Papagiannaki
    def setUp(self):
421 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
422 b09c9aaa Sofia Papagiannaki
        self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
423 b09c9aaa Sofia Papagiannaki
        for item in self.containers:
424 25c3841c Sofia Papagiannaki
            self.client.create_container(item)
425 7067193f Kostas Papadimitriou
426 cd6ada1d Sofia Papagiannaki
        meta = {'foo':'bar'}
427 25c3841c Sofia Papagiannaki
        self.client.update_account_metadata(**meta)
428 5893eeef Sofia Papagiannaki
        self.updated_meta = self.initial_meta.update(meta)
429 7067193f Kostas Papadimitriou
430 cd6ada1d Sofia Papagiannaki
    def test_update_meta(self):
431 cd6ada1d Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_account_groups):
432 cd6ada1d Sofia Papagiannaki
            meta = {'test':'test', 'tost':'tost'}
433 cd6ada1d Sofia Papagiannaki
            self.client.update_account_metadata(**meta)
434 7067193f Kostas Papadimitriou
435 cd6ada1d Sofia Papagiannaki
            meta.update(self.initial_meta)
436 cd6ada1d Sofia Papagiannaki
            self.assertEqual(meta,
437 cd6ada1d Sofia Papagiannaki
                             self.client.retrieve_account_metadata(
438 cd6ada1d Sofia Papagiannaki
                                restricted=True))
439 7067193f Kostas Papadimitriou
440 f0eacc2c Sofia Papagiannaki
    def test_invalid_account_update_meta(self):
441 cd6ada1d Sofia Papagiannaki
        meta = {'test':'test', 'tost':'tost'}
442 297513ba Antony Chazapis
        self.assert_raises_fault(403,
443 f0eacc2c Sofia Papagiannaki
                                 self.invalid_client.update_account_metadata,
444 f0eacc2c Sofia Papagiannaki
                                 **meta)
445 7067193f Kostas Papadimitriou
446 cd6ada1d Sofia Papagiannaki
    def test_reset_meta(self):
447 cd6ada1d Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_account_groups):
448 cd6ada1d Sofia Papagiannaki
            meta = {'test':'test', 'tost':'tost'}
449 cd6ada1d Sofia Papagiannaki
            self.client.update_account_metadata(**meta)
450 7067193f Kostas Papadimitriou
451 cd6ada1d Sofia Papagiannaki
            meta = {'test':'test33'}
452 cd6ada1d Sofia Papagiannaki
            self.client.reset_account_metadata(**meta)
453 7067193f Kostas Papadimitriou
454 cd6ada1d Sofia Papagiannaki
            self.assertEqual(meta, self.client.retrieve_account_metadata(restricted=True))
455 7067193f Kostas Papadimitriou
456 7812e1f9 Sofia Papagiannaki
    def test_delete_meta(self):
457 7812e1f9 Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_account_groups):
458 7812e1f9 Sofia Papagiannaki
            meta = {'test':'test', 'tost':'tost'}
459 7812e1f9 Sofia Papagiannaki
            self.client.update_account_metadata(**meta)
460 7067193f Kostas Papadimitriou
461 7812e1f9 Sofia Papagiannaki
            self.client.delete_account_metadata(meta.keys())
462 7067193f Kostas Papadimitriou
463 7812e1f9 Sofia Papagiannaki
            account_meta = self.client.retrieve_account_metadata(restricted=True)
464 7812e1f9 Sofia Papagiannaki
            for m in meta:
465 7812e1f9 Sofia Papagiannaki
                self.assertTrue(m not in account_meta.keys())
466 7067193f Kostas Papadimitriou
467 cd6ada1d Sofia Papagiannaki
    def test_set_account_groups(self):
468 cd6ada1d Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_account_metadata):
469 cd6ada1d Sofia Papagiannaki
            groups = {'pithosdev':'verigak,gtsouk,chazapis'}
470 cd6ada1d Sofia Papagiannaki
            self.client.set_account_groups(**groups)
471 7067193f Kostas Papadimitriou
472 62f915a1 Antony Chazapis
            self.assertEqual(set(groups['pithosdev']),
473 62f915a1 Antony Chazapis
                             set(self.client.retrieve_account_groups()['pithosdev']))
474 7067193f Kostas Papadimitriou
475 cd6ada1d Sofia Papagiannaki
            more_groups = {'clientsdev':'pkanavos,mvasilak'}
476 cd6ada1d Sofia Papagiannaki
            self.client.set_account_groups(**more_groups)
477 7067193f Kostas Papadimitriou
478 cd6ada1d Sofia Papagiannaki
            groups.update(more_groups)
479 62f915a1 Antony Chazapis
            self.assertEqual(set(groups['clientsdev']),
480 62f915a1 Antony Chazapis
                             set(self.client.retrieve_account_groups()['clientsdev']))
481 7067193f Kostas Papadimitriou
482 cd6ada1d Sofia Papagiannaki
    def test_reset_account_groups(self):
483 cd6ada1d Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_account_metadata):
484 cd6ada1d Sofia Papagiannaki
            groups = {'pithosdev':'verigak,gtsouk,chazapis',
485 cd6ada1d Sofia Papagiannaki
                      'clientsdev':'pkanavos,mvasilak'}
486 cd6ada1d Sofia Papagiannaki
            self.client.set_account_groups(**groups)
487 7067193f Kostas Papadimitriou
488 62f915a1 Antony Chazapis
            self.assertEqual(set(groups['pithosdev'].split(',')),
489 62f915a1 Antony Chazapis
                             set(self.client.retrieve_account_groups()['pithosdev'].split(',')))
490 62f915a1 Antony Chazapis
            self.assertEqual(set(groups['clientsdev'].split(',')),
491 62f915a1 Antony Chazapis
                             set(self.client.retrieve_account_groups()['clientsdev'].split(',')))
492 7067193f Kostas Papadimitriou
493 e7b51248 Sofia Papagiannaki
            groups = {'pithosdev':'verigak,gtsouk,chazapis,papagian'}
494 cd6ada1d Sofia Papagiannaki
            self.client.reset_account_groups(**groups)
495 7067193f Kostas Papadimitriou
496 62f915a1 Antony Chazapis
            self.assertEqual(set(groups['pithosdev'].split(',')),
497 62f915a1 Antony Chazapis
                             set(self.client.retrieve_account_groups()['pithosdev'].split(',')))
498 7067193f Kostas Papadimitriou
499 cd6ada1d Sofia Papagiannaki
    def test_delete_account_groups(self):
500 cd6ada1d Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_account_metadata):
501 cd6ada1d Sofia Papagiannaki
            groups = {'pithosdev':'verigak,gtsouk,chazapis',
502 cd6ada1d Sofia Papagiannaki
                      'clientsdev':'pkanavos,mvasilak'}
503 cd6ada1d Sofia Papagiannaki
            self.client.set_account_groups(**groups)
504 7067193f Kostas Papadimitriou
505 cd6ada1d Sofia Papagiannaki
            self.client.unset_account_groups(groups.keys())
506 7067193f Kostas Papadimitriou
507 cd6ada1d Sofia Papagiannaki
            self.assertEqual({}, self.client.retrieve_account_groups())
508 7067193f Kostas Papadimitriou
509 d1e43d6f Sofia Papagiannaki
class ContainerHead(BaseTestCase):
510 d1e43d6f Sofia Papagiannaki
    def setUp(self):
511 d1e43d6f Sofia Papagiannaki
        BaseTestCase.setUp(self)
512 d1e43d6f Sofia Papagiannaki
        self.container = 'apples'
513 25c3841c Sofia Papagiannaki
        self.client.create_container(self.container)
514 7067193f Kostas Papadimitriou
515 d1e43d6f Sofia Papagiannaki
    def test_get_meta(self):
516 23028d31 Sofia Papagiannaki
        meta = {'trash':'true'}
517 d1e43d6f Sofia Papagiannaki
        t1 = datetime.datetime.utcnow()
518 23028d31 Sofia Papagiannaki
        o = self.upload_random_data(self.container, o_names[0], **meta)
519 d1e43d6f Sofia Papagiannaki
        if o:
520 25c3841c Sofia Papagiannaki
            headers = self.client.retrieve_container_metadata(self.container)
521 23028d31 Sofia Papagiannaki
            self.assertEqual(headers['x-container-object-count'], '1')
522 23028d31 Sofia Papagiannaki
            self.assertEqual(headers['x-container-bytes-used'], str(len(o['data'])))
523 23028d31 Sofia Papagiannaki
            t2 = datetime.datetime.strptime(headers['last-modified'], DATE_FORMATS[2])
524 d1e43d6f Sofia Papagiannaki
            delta = (t2 - t1)
525 7067193f Kostas Papadimitriou
            threashold = datetime.timedelta(seconds=1)
526 d1e43d6f Sofia Papagiannaki
            self.assertTrue(delta < threashold)
527 23028d31 Sofia Papagiannaki
            self.assertTrue(headers['x-container-object-meta'])
528 23028d31 Sofia Papagiannaki
            self.assertTrue('Trash' in headers['x-container-object-meta'])
529 d1e43d6f Sofia Papagiannaki
530 d1e43d6f Sofia Papagiannaki
class ContainerGet(BaseTestCase):
531 b09c9aaa Sofia Papagiannaki
    def setUp(self):
532 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
533 b09c9aaa Sofia Papagiannaki
        self.container = ['pears', 'apples']
534 b09c9aaa Sofia Papagiannaki
        for c in self.container:
535 25c3841c Sofia Papagiannaki
            self.client.create_container(c)
536 b09c9aaa Sofia Papagiannaki
        self.obj = []
537 b09c9aaa Sofia Papagiannaki
        for o in o_names[:8]:
538 23028d31 Sofia Papagiannaki
            self.obj.append(self.upload_random_data(self.container[0], o))
539 b09c9aaa Sofia Papagiannaki
        for o in o_names[8:]:
540 23028d31 Sofia Papagiannaki
            self.obj.append(self.upload_random_data(self.container[1], o))
541 7067193f Kostas Papadimitriou
542 b09c9aaa Sofia Papagiannaki
    def test_list_objects(self):
543 25c3841c Sofia Papagiannaki
        objects = self.client.list_objects(self.container[0])
544 b09c9aaa Sofia Papagiannaki
        l = [elem['name'] for elem in self.obj[:8]]
545 b09c9aaa Sofia Papagiannaki
        l.sort()
546 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects, l)
547 7067193f Kostas Papadimitriou
548 ae75584f Sofia Papagiannaki
    def test_list_objects_containing_slash(self):
549 ae75584f Sofia Papagiannaki
        self.client.create_container('test')
550 ae75584f Sofia Papagiannaki
        self.upload_random_data('test', '/objectname')
551 7067193f Kostas Papadimitriou
552 ae75584f Sofia Papagiannaki
        objects = self.client.list_objects('test')
553 ae75584f Sofia Papagiannaki
        self.assertEqual(objects, ['/objectname'])
554 7067193f Kostas Papadimitriou
555 ae75584f Sofia Papagiannaki
        objects = self.client.list_objects('test', format='json')
556 ae75584f Sofia Papagiannaki
        self.assertEqual(objects[0]['name'], '/objectname')
557 7067193f Kostas Papadimitriou
558 ae75584f Sofia Papagiannaki
        objects = self.client.list_objects('test', format='xml')
559 ae75584f Sofia Papagiannaki
        self.assert_extended(objects, 'xml', 'object')
560 ae75584f Sofia Papagiannaki
        node_name = objects.getElementsByTagName('name')[0]
561 ae75584f Sofia Papagiannaki
        self.assertEqual(node_name.firstChild.data, '/objectname')
562 ae75584f Sofia Papagiannaki
563 b09c9aaa Sofia Papagiannaki
    def test_list_objects_with_limit_marker(self):
564 25c3841c Sofia Papagiannaki
        objects = self.client.list_objects(self.container[0], limit=2)
565 b09c9aaa Sofia Papagiannaki
        l = [elem['name'] for elem in self.obj[:8]]
566 b09c9aaa Sofia Papagiannaki
        l.sort()
567 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects, l[:2])
568 7067193f Kostas Papadimitriou
569 b09c9aaa Sofia Papagiannaki
        markers = ['How To Win Friends And Influence People.pdf',
570 b09c9aaa Sofia Papagiannaki
                   'moms_birthday.jpg']
571 b09c9aaa Sofia Papagiannaki
        limit = 4
572 b09c9aaa Sofia Papagiannaki
        for m in markers:
573 25c3841c Sofia Papagiannaki
            objects = self.client.list_objects(self.container[0], limit=limit,
574 25c3841c Sofia Papagiannaki
                                               marker=m)
575 b09c9aaa Sofia Papagiannaki
            l = [elem['name'] for elem in self.obj[:8]]
576 b09c9aaa Sofia Papagiannaki
            l.sort()
577 b09c9aaa Sofia Papagiannaki
            start = l.index(m) + 1
578 b09c9aaa Sofia Papagiannaki
            end = start + limit
579 af6d3b5d Antony Chazapis
            end = end if len(l) >= end else len(l)
580 b09c9aaa Sofia Papagiannaki
            self.assertEqual(objects, l[start:end])
581 7067193f Kostas Papadimitriou
582 ae75584f Sofia Papagiannaki
    #takes too long
583 9ac5299c Antony Chazapis
    def _test_list_limit_exceeds(self):
584 e7b51248 Sofia Papagiannaki
        self.client.create_container('pithos')
585 7067193f Kostas Papadimitriou
586 e7b51248 Sofia Papagiannaki
        for i in range(10001):
587 e7b51248 Sofia Papagiannaki
            self.client.create_zero_length_object('pithos', i)
588 7067193f Kostas Papadimitriou
589 e7b51248 Sofia Papagiannaki
        self.assertEqual(10000, len(self.client.list_objects('pithos')))
590 7067193f Kostas Papadimitriou
591 ae75584f Sofia Papagiannaki
    def test_list_empty_params(self):
592 a5149fd0 Sofia Papagiannaki
        objects = self.client.get('/%s/%s' % (get_user(), self.container[0]))[2]
593 ae75584f Sofia Papagiannaki
        if objects:
594 ae75584f Sofia Papagiannaki
            objects = objects.strip().split('\n')
595 ae75584f Sofia Papagiannaki
        self.assertEqual(objects,
596 ae75584f Sofia Papagiannaki
                         self.client.list_objects(self.container[0]))
597 7067193f Kostas Papadimitriou
598 b09c9aaa Sofia Papagiannaki
    def test_list_pseudo_hierarchical_folders(self):
599 25c3841c Sofia Papagiannaki
        objects = self.client.list_objects(self.container[1], prefix='photos',
600 25c3841c Sofia Papagiannaki
                                           delimiter='/')
601 33ffca25 Sofia Papagiannaki
        self.assertEquals(['photos/animals/', 'photos/me.jpg',
602 33ffca25 Sofia Papagiannaki
                           'photos/plants/'], objects)
603 7067193f Kostas Papadimitriou
604 25c3841c Sofia Papagiannaki
        objects = self.client.list_objects(self.container[1],
605 25c3841c Sofia Papagiannaki
                                           prefix='photos/animals',
606 25c3841c Sofia Papagiannaki
                                           delimiter='/')
607 33ffca25 Sofia Papagiannaki
        l = ['photos/animals/cats/', 'photos/animals/dogs/']
608 23028d31 Sofia Papagiannaki
        self.assertEquals(l, objects)
609 7067193f Kostas Papadimitriou
610 25c3841c Sofia Papagiannaki
        objects = self.client.list_objects(self.container[1], path='photos')
611 b09c9aaa Sofia Papagiannaki
        self.assertEquals(['photos/me.jpg'], objects)
612 7067193f Kostas Papadimitriou
613 b09c9aaa Sofia Papagiannaki
    def test_extended_list_json(self):
614 f0eacc2c Sofia Papagiannaki
        objects = self.client.list_objects(self.container[1], format='json',
615 25c3841c Sofia Papagiannaki
                                           limit=2, prefix='photos/animals',
616 25c3841c Sofia Papagiannaki
                                           delimiter='/')
617 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects[0]['subdir'], 'photos/animals/cats/')
618 b09c9aaa Sofia Papagiannaki
        self.assertEqual(objects[1]['subdir'], 'photos/animals/dogs/')
619 7067193f Kostas Papadimitriou
620 f0eacc2c Sofia Papagiannaki
    def test_extended_list_xml(self):
621 f0eacc2c Sofia Papagiannaki
        xml = self.client.list_objects(self.container[1], format='xml', limit=4,
622 f0eacc2c Sofia Papagiannaki
                                       prefix='photos', delimiter='/')
623 ae75584f Sofia Papagiannaki
        self.assert_extended(xml, 'xml', 'object', size=4)
624 f0eacc2c Sofia Papagiannaki
        dirs = xml.getElementsByTagName('subdir')
625 f0eacc2c Sofia Papagiannaki
        self.assertEqual(len(dirs), 2)
626 f0eacc2c Sofia Papagiannaki
        self.assertEqual(dirs[0].attributes['name'].value, 'photos/animals/')
627 f0eacc2c Sofia Papagiannaki
        self.assertEqual(dirs[1].attributes['name'].value, 'photos/plants/')
628 7067193f Kostas Papadimitriou
629 f0eacc2c Sofia Papagiannaki
        objects = xml.getElementsByTagName('name')
630 f0eacc2c Sofia Papagiannaki
        self.assertEqual(len(objects), 1)
631 f0eacc2c Sofia Papagiannaki
        self.assertEqual(objects[0].childNodes[0].data, 'photos/me.jpg')
632 7067193f Kostas Papadimitriou
633 3364a52a Sofia Papagiannaki
    def test_list_meta_double_matching(self):
634 23028d31 Sofia Papagiannaki
        meta = {'quality':'aaa', 'stock':'true'}
635 23028d31 Sofia Papagiannaki
        self.client.update_object_metadata(self.container[0],
636 23028d31 Sofia Papagiannaki
                                           self.obj[0]['name'], **meta)
637 25c3841c Sofia Papagiannaki
        obj = self.client.list_objects(self.container[0], meta='Quality,Stock')
638 3364a52a Sofia Papagiannaki
        self.assertEqual(len(obj), 1)
639 3364a52a Sofia Papagiannaki
        self.assertTrue(obj, self.obj[0]['name'])
640 7067193f Kostas Papadimitriou
641 b09c9aaa Sofia Papagiannaki
    def test_list_using_meta(self):
642 23028d31 Sofia Papagiannaki
        meta = {'quality':'aaa'}
643 b09c9aaa Sofia Papagiannaki
        for o in self.obj[:2]:
644 23028d31 Sofia Papagiannaki
            self.client.update_object_metadata(self.container[0], o['name'],
645 23028d31 Sofia Papagiannaki
                                               **meta)
646 23028d31 Sofia Papagiannaki
        meta = {'stock':'true'}
647 b09c9aaa Sofia Papagiannaki
        for o in self.obj[3:5]:
648 23028d31 Sofia Papagiannaki
            self.client.update_object_metadata(self.container[0], o['name'],
649 23028d31 Sofia Papagiannaki
                                               **meta)
650 7067193f Kostas Papadimitriou
651 25c3841c Sofia Papagiannaki
        obj = self.client.list_objects(self.container[0], meta='Quality')
652 25c3841c Sofia Papagiannaki
        self.assertEqual(len(obj), 2)
653 25c3841c Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
654 7067193f Kostas Papadimitriou
655 b09c9aaa Sofia Papagiannaki
        # test case insensitive
656 25c3841c Sofia Papagiannaki
        obj = self.client.list_objects(self.container[0], meta='quality')
657 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(obj), 2)
658 86dacd7f Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
659 7067193f Kostas Papadimitriou
660 b09c9aaa Sofia Papagiannaki
        # test multiple matches
661 25c3841c Sofia Papagiannaki
        obj = self.client.list_objects(self.container[0], meta='Quality,Stock')
662 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(obj), 4)
663 86dacd7f Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:4]])
664 7067193f Kostas Papadimitriou
665 b09c9aaa Sofia Papagiannaki
        # test non 1-1 multiple match
666 25c3841c Sofia Papagiannaki
        obj = self.client.list_objects(self.container[0], meta='Quality,aaaa')
667 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(obj), 2)
668 d1e43d6f Sofia Papagiannaki
        self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
669 7067193f Kostas Papadimitriou
670 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since(self):
671 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
672 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
673 7067193f Kostas Papadimitriou
674 23028d31 Sofia Papagiannaki
        #add a new object
675 23028d31 Sofia Papagiannaki
        self.upload_random_data(self.container[0], o_names[0])
676 7067193f Kostas Papadimitriou
677 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
678 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
679 25c3841c Sofia Papagiannaki
            try:
680 25c3841c Sofia Papagiannaki
                o = self.client.list_objects(self.container[0],
681 25c3841c Sofia Papagiannaki
                                            if_modified_since=past)
682 25c3841c Sofia Papagiannaki
                self.assertEqual(o,
683 25c3841c Sofia Papagiannaki
                                 self.client.list_objects(self.container[0]))
684 25c3841c Sofia Papagiannaki
            except Fault, f:
685 25c3841c Sofia Papagiannaki
                self.failIf(f.status == 304) #fail if not modified
686 7067193f Kostas Papadimitriou
687 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since_invalid_date(self):
688 23028d31 Sofia Papagiannaki
        headers = {'if-modified-since':''}
689 25c3841c Sofia Papagiannaki
        o = self.client.list_objects(self.container[0], if_modified_since='')
690 25c3841c Sofia Papagiannaki
        self.assertEqual(o, self.client.list_objects(self.container[0]))
691 7067193f Kostas Papadimitriou
692 d1e43d6f Sofia Papagiannaki
    def test_if_not_modified_since(self):
693 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
694 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
695 7067193f Kostas Papadimitriou
696 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
697 25c3841c Sofia Papagiannaki
            args = {'if_modified_since':'%s' %since.strftime(f)}
698 7067193f Kostas Papadimitriou
699 d1e43d6f Sofia Papagiannaki
            #assert not modified
700 25c3841c Sofia Papagiannaki
            self.assert_raises_fault(304, self.client.list_objects,
701 25c3841c Sofia Papagiannaki
                                     self.container[0], **args)
702 7067193f Kostas Papadimitriou
703 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since(self):
704 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
705 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
706 7067193f Kostas Papadimitriou
707 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
708 25c3841c Sofia Papagiannaki
            obj = self.client.list_objects(self.container[0],
709 25c3841c Sofia Papagiannaki
                                           if_unmodified_since=since.strftime(f))
710 7067193f Kostas Papadimitriou
711 25c3841c Sofia Papagiannaki
            #assert unmodified
712 25c3841c Sofia Papagiannaki
            self.assertEqual(obj, self.client.list_objects(self.container[0]))
713 7067193f Kostas Papadimitriou
714 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since_precondition_failed(self):
715 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
716 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
717 7067193f Kostas Papadimitriou
718 d1e43d6f Sofia Papagiannaki
        #add a new container
719 25c3841c Sofia Papagiannaki
        self.client.create_container('dummy')
720 7067193f Kostas Papadimitriou
721 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
722 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
723 7067193f Kostas Papadimitriou
724 25c3841c Sofia Papagiannaki
            args = {'if_unmodified_since':'%s' %past}
725 7067193f Kostas Papadimitriou
726 23028d31 Sofia Papagiannaki
            #assert precondition failed
727 25c3841c Sofia Papagiannaki
            self.assert_raises_fault(412, self.client.list_objects,
728 25c3841c Sofia Papagiannaki
                                     self.container[0], **args)
729 d1e43d6f Sofia Papagiannaki
730 d1e43d6f Sofia Papagiannaki
class ContainerPut(BaseTestCase):
731 b09c9aaa Sofia Papagiannaki
    def setUp(self):
732 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
733 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
734 7067193f Kostas Papadimitriou
735 b09c9aaa Sofia Papagiannaki
    def test_create(self):
736 25c3841c Sofia Papagiannaki
        self.client.create_container(self.containers[0])
737 25c3841c Sofia Papagiannaki
        containers = self.client.list_containers()
738 23028d31 Sofia Papagiannaki
        self.assertTrue(self.containers[0] in containers)
739 25c3841c Sofia Papagiannaki
        self.assert_container_exists(self.containers[0])
740 7067193f Kostas Papadimitriou
741 b09c9aaa Sofia Papagiannaki
    def test_create_twice(self):
742 25c3841c Sofia Papagiannaki
        self.client.create_container(self.containers[0])
743 25c3841c Sofia Papagiannaki
        self.assertTrue(not self.client.create_container(self.containers[0]))
744 7067193f Kostas Papadimitriou
745 81ed48a5 Sofia Papagiannaki
    def test_quota(self):
746 81ed48a5 Sofia Papagiannaki
        self.client.create_container(self.containers[0])
747 7067193f Kostas Papadimitriou
748 81ed48a5 Sofia Papagiannaki
        policy = {'quota':100}
749 81ed48a5 Sofia Papagiannaki
        self.client.set_container_policies('c1', **policy)
750 7067193f Kostas Papadimitriou
751 81ed48a5 Sofia Papagiannaki
        meta = self.client.retrieve_container_metadata('c1')
752 81ed48a5 Sofia Papagiannaki
        self.assertTrue('x-container-policy-quota' in meta)
753 81ed48a5 Sofia Papagiannaki
        self.assertEqual(meta['x-container-policy-quota'], '100')
754 7067193f Kostas Papadimitriou
755 81ed48a5 Sofia Papagiannaki
        args = ['c1', 'o1']
756 81ed48a5 Sofia Papagiannaki
        kwargs = {'length':101}
757 81ed48a5 Sofia Papagiannaki
        self.assert_raises_fault(413, self.upload_random_data, *args, **kwargs)
758 7067193f Kostas Papadimitriou
759 531252f0 Sofia Papagiannaki
        #reset quota
760 531252f0 Sofia Papagiannaki
        policy = {'quota':0}
761 531252f0 Sofia Papagiannaki
        self.client.set_container_policies('c1', **policy)
762 7067193f Kostas Papadimitriou
763 d1e43d6f Sofia Papagiannaki
class ContainerPost(BaseTestCase):
764 d1e43d6f Sofia Papagiannaki
    def setUp(self):
765 d1e43d6f Sofia Papagiannaki
        BaseTestCase.setUp(self)
766 d1e43d6f Sofia Papagiannaki
        self.container = 'apples'
767 25c3841c Sofia Papagiannaki
        self.client.create_container(self.container)
768 7067193f Kostas Papadimitriou
769 d1e43d6f Sofia Papagiannaki
    def test_update_meta(self):
770 23028d31 Sofia Papagiannaki
        meta = {'test':'test33',
771 23028d31 Sofia Papagiannaki
                'tost':'tost22'}
772 23028d31 Sofia Papagiannaki
        self.client.update_container_metadata(self.container, **meta)
773 25c3841c Sofia Papagiannaki
        headers = self.client.retrieve_container_metadata(self.container)
774 d1e43d6f Sofia Papagiannaki
        for k,v in meta.items():
775 23028d31 Sofia Papagiannaki
            k = 'x-container-meta-%s' % k
776 23028d31 Sofia Papagiannaki
            self.assertTrue(headers[k])
777 23028d31 Sofia Papagiannaki
            self.assertEqual(headers[k], v)
778 d1e43d6f Sofia Papagiannaki
779 d1e43d6f Sofia Papagiannaki
class ContainerDelete(BaseTestCase):
780 b09c9aaa Sofia Papagiannaki
    def setUp(self):
781 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
782 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
783 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
784 25c3841c Sofia Papagiannaki
            self.client.create_container(c)
785 7067193f Kostas Papadimitriou
786 b09c9aaa Sofia Papagiannaki
    def test_delete(self):
787 23028d31 Sofia Papagiannaki
        status = self.client.delete_container(self.containers[0])[0]
788 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 204)
789 7067193f Kostas Papadimitriou
790 b09c9aaa Sofia Papagiannaki
    def test_delete_non_empty(self):
791 81ed48a5 Sofia Papagiannaki
        self.upload_random_data(self.containers[1], o_names[0])
792 23028d31 Sofia Papagiannaki
        self.assert_raises_fault(409, self.client.delete_container,
793 23028d31 Sofia Papagiannaki
                                 self.containers[1])
794 7067193f Kostas Papadimitriou
795 b09c9aaa Sofia Papagiannaki
    def test_delete_invalid(self):
796 23028d31 Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.delete_container, 'c3')
797 b09c9aaa Sofia Papagiannaki
798 d1e43d6f Sofia Papagiannaki
class ObjectGet(BaseTestCase):
799 b09c9aaa Sofia Papagiannaki
    def setUp(self):
800 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
801 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
802 b09c9aaa Sofia Papagiannaki
        #create some containers
803 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
804 25c3841c Sofia Papagiannaki
            self.client.create_container(c)
805 7067193f Kostas Papadimitriou
806 b09c9aaa Sofia Papagiannaki
        #upload a file
807 23028d31 Sofia Papagiannaki
        names = ('obj1', 'obj2')
808 b09c9aaa Sofia Papagiannaki
        self.objects = []
809 23028d31 Sofia Papagiannaki
        for n in names:
810 23028d31 Sofia Papagiannaki
            self.objects.append(self.upload_random_data(self.containers[1], n))
811 7067193f Kostas Papadimitriou
812 8d964102 Sofia Papagiannaki
    def test_versions(self):
813 8d964102 Sofia Papagiannaki
        c = self.containers[1]
814 8d964102 Sofia Papagiannaki
        o = self.objects[0]
815 8d964102 Sofia Papagiannaki
        b = self.client.retrieve_object_versionlist(c, o['name'])['versions']
816 8d964102 Sofia Papagiannaki
        self.assert_versionlist_structure(b)
817 7067193f Kostas Papadimitriou
818 8d964102 Sofia Papagiannaki
        #update meta
819 8d964102 Sofia Papagiannaki
        meta = {'quality':'AAA', 'stock':True}
820 8d964102 Sofia Papagiannaki
        self.client.update_object_metadata(c, o['name'], **meta)
821 7067193f Kostas Papadimitriou
822 8d964102 Sofia Papagiannaki
        a = self.client.retrieve_object_versionlist(c, o['name'])['versions']
823 8d964102 Sofia Papagiannaki
        self.assert_versionlist_structure(a)
824 8d964102 Sofia Papagiannaki
        self.assertEqual(len(b)+1, len(a))
825 8d964102 Sofia Papagiannaki
        self.assertEqual(b, a[:-1])
826 7067193f Kostas Papadimitriou
827 8d964102 Sofia Papagiannaki
        #get exact previous version metadata
828 8d964102 Sofia Papagiannaki
        v = a[-2][0]
829 8d964102 Sofia Papagiannaki
        v_meta = self.client.retrieve_object_metadata(c, o['name'],
830 8d964102 Sofia Papagiannaki
                                                      restricted=True,
831 8d964102 Sofia Papagiannaki
                                                      version=v)
832 8d964102 Sofia Papagiannaki
        for k in meta.keys():
833 8d964102 Sofia Papagiannaki
            self.assertTrue(k not in v_meta)
834 7067193f Kostas Papadimitriou
835 8d964102 Sofia Papagiannaki
        #update obejct
836 8d964102 Sofia Papagiannaki
        data = get_random_data()
837 8d964102 Sofia Papagiannaki
        self.client.update_object(c, o['name'], StringIO(data))
838 7067193f Kostas Papadimitriou
839 8d964102 Sofia Papagiannaki
        aa = self.client.retrieve_object_versionlist(c, o['name'])['versions']
840 8d964102 Sofia Papagiannaki
        self.assert_versionlist_structure(aa)
841 8d964102 Sofia Papagiannaki
        self.assertEqual(len(a)+1, len(aa))
842 8d964102 Sofia Papagiannaki
        self.assertEqual(a, aa[:-1])
843 7067193f Kostas Papadimitriou
844 8d964102 Sofia Papagiannaki
        #get exact previous version
845 8d964102 Sofia Papagiannaki
        v = aa[-3][0]
846 8d964102 Sofia Papagiannaki
        v_data = self.client.retrieve_object_version(c, o['name'], version=v)
847 8d964102 Sofia Papagiannaki
        self.assertEqual(o['data'], v_data)
848 8d964102 Sofia Papagiannaki
        self.assertEqual(self.client.retrieve_object(c, o['name']),
849 8d964102 Sofia Papagiannaki
                         '%s%s' %(v_data, data))
850 7067193f Kostas Papadimitriou
851 b09c9aaa Sofia Papagiannaki
    def test_get(self):
852 b09c9aaa Sofia Papagiannaki
        #perform get
853 25c3841c Sofia Papagiannaki
        o = self.client.retrieve_object(self.containers[1],
854 25c3841c Sofia Papagiannaki
                                        self.objects[0]['name'],
855 25c3841c Sofia Papagiannaki
                                        self.objects[0]['meta'])
856 25c3841c Sofia Papagiannaki
        self.assertEqual(o, self.objects[0]['data'])
857 7067193f Kostas Papadimitriou
858 e414f54d Sofia Papagiannaki
    def test_objects_with_trailing_spaces(self):
859 e414f54d Sofia Papagiannaki
        self.client.create_container('test')
860 e414f54d Sofia Papagiannaki
        #create 'a' object
861 e414f54d Sofia Papagiannaki
        self.upload_random_data('test', 'a')
862 e414f54d Sofia Papagiannaki
        #look for 'a ' object
863 e414f54d Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.retrieve_object,
864 e414f54d Sofia Papagiannaki
                                 'test', 'a ')
865 7067193f Kostas Papadimitriou
866 e414f54d Sofia Papagiannaki
        #delete 'a' object
867 e414f54d Sofia Papagiannaki
        self.client.delete_object('test', 'a')
868 e414f54d Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.retrieve_object,
869 e414f54d Sofia Papagiannaki
                                 'test', 'a')
870 7067193f Kostas Papadimitriou
871 e414f54d Sofia Papagiannaki
        #create 'a ' object
872 e414f54d Sofia Papagiannaki
        self.upload_random_data('test', 'a ')
873 e414f54d Sofia Papagiannaki
        #look for 'a' object
874 e414f54d Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.retrieve_object,
875 e414f54d Sofia Papagiannaki
                                 'test', 'a')
876 7067193f Kostas Papadimitriou
877 b09c9aaa Sofia Papagiannaki
    def test_get_invalid(self):
878 25c3841c Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.retrieve_object,
879 25c3841c Sofia Papagiannaki
                                 self.containers[0], self.objects[0]['name'])
880 7067193f Kostas Papadimitriou
881 b09c9aaa Sofia Papagiannaki
    def test_get_partial(self):
882 b09c9aaa Sofia Papagiannaki
        #perform get with range
883 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
884 25c3841c Sofia Papagiannaki
                                                            self.objects[0]['name'],
885 25c3841c Sofia Papagiannaki
                                                            range='bytes=0-499')
886 7067193f Kostas Papadimitriou
887 b09c9aaa Sofia Papagiannaki
        #assert successful partial content
888 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 206)
889 7067193f Kostas Papadimitriou
890 33ffca25 Sofia Papagiannaki
        #assert content-type
891 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['content-type'],
892 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
893 7067193f Kostas Papadimitriou
894 b09c9aaa Sofia Papagiannaki
        #assert content length
895 23028d31 Sofia Papagiannaki
        self.assertEqual(int(headers['content-length']), 500)
896 7067193f Kostas Papadimitriou
897 b09c9aaa Sofia Papagiannaki
        #assert content
898 23028d31 Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'][:500], data)
899 7067193f Kostas Papadimitriou
900 b09c9aaa Sofia Papagiannaki
    def test_get_final_500(self):
901 b09c9aaa Sofia Papagiannaki
        #perform get with range
902 23028d31 Sofia Papagiannaki
        headers = {'range':'bytes=-500'}
903 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
904 25c3841c Sofia Papagiannaki
                                                            self.objects[0]['name'],
905 25c3841c Sofia Papagiannaki
                                                            range='bytes=-500')
906 7067193f Kostas Papadimitriou
907 b09c9aaa Sofia Papagiannaki
        #assert successful partial content
908 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 206)
909 7067193f Kostas Papadimitriou
910 33ffca25 Sofia Papagiannaki
        #assert content-type
911 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['content-type'],
912 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
913 7067193f Kostas Papadimitriou
914 b09c9aaa Sofia Papagiannaki
        #assert content length
915 23028d31 Sofia Papagiannaki
        self.assertEqual(int(headers['content-length']), 500)
916 7067193f Kostas Papadimitriou
917 b09c9aaa Sofia Papagiannaki
        #assert content
918 23028d31 Sofia Papagiannaki
        self.assertTrue(self.objects[0]['data'][-500:], data)
919 7067193f Kostas Papadimitriou
920 b09c9aaa Sofia Papagiannaki
    def test_get_rest(self):
921 b09c9aaa Sofia Papagiannaki
        #perform get with range
922 b09c9aaa Sofia Papagiannaki
        offset = len(self.objects[0]['data']) - 500
923 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
924 23028d31 Sofia Papagiannaki
                                                self.objects[0]['name'],
925 25c3841c Sofia Papagiannaki
                                                range='bytes=%s-' %offset)
926 7067193f Kostas Papadimitriou
927 b09c9aaa Sofia Papagiannaki
        #assert successful partial content
928 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 206)
929 7067193f Kostas Papadimitriou
930 33ffca25 Sofia Papagiannaki
        #assert content-type
931 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['content-type'],
932 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
933 7067193f Kostas Papadimitriou
934 b09c9aaa Sofia Papagiannaki
        #assert content length
935 23028d31 Sofia Papagiannaki
        self.assertEqual(int(headers['content-length']), 500)
936 7067193f Kostas Papadimitriou
937 b09c9aaa Sofia Papagiannaki
        #assert content
938 23028d31 Sofia Papagiannaki
        self.assertTrue(self.objects[0]['data'][-500:], data)
939 7067193f Kostas Papadimitriou
940 b09c9aaa Sofia Papagiannaki
    def test_get_range_not_satisfiable(self):
941 b09c9aaa Sofia Papagiannaki
        #perform get with range
942 b09c9aaa Sofia Papagiannaki
        offset = len(self.objects[0]['data']) + 1
943 7067193f Kostas Papadimitriou
944 23028d31 Sofia Papagiannaki
        #assert range not satisfiable
945 25c3841c Sofia Papagiannaki
        self.assert_raises_fault(416, self.client.retrieve_object,
946 25c3841c Sofia Papagiannaki
                                 self.containers[1], self.objects[0]['name'],
947 25c3841c Sofia Papagiannaki
                                 range='bytes=0-%s' %offset)
948 7067193f Kostas Papadimitriou
949 b09c9aaa Sofia Papagiannaki
    def test_multiple_range(self):
950 b09c9aaa Sofia Papagiannaki
        #perform get with multiple range
951 b09c9aaa Sofia Papagiannaki
        ranges = ['0-499', '-500', '1000-']
952 25c3841c Sofia Papagiannaki
        bytes = 'bytes=%s' % ','.join(ranges)
953 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
954 25c3841c Sofia Papagiannaki
                                                           self.objects[0]['name'],
955 25c3841c Sofia Papagiannaki
                                                           range=bytes)
956 7067193f Kostas Papadimitriou
957 b09c9aaa Sofia Papagiannaki
        # assert partial content
958 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 206)
959 7067193f Kostas Papadimitriou
960 b09c9aaa Sofia Papagiannaki
        # assert Content-Type of the reply will be multipart/byteranges
961 23028d31 Sofia Papagiannaki
        self.assertTrue(headers['content-type'])
962 23028d31 Sofia Papagiannaki
        content_type_parts = headers['content-type'].split()
963 b09c9aaa Sofia Papagiannaki
        self.assertEqual(content_type_parts[0], ('multipart/byteranges;'))
964 7067193f Kostas Papadimitriou
965 b09c9aaa Sofia Papagiannaki
        boundary = '--%s' %content_type_parts[1].split('=')[-1:][0]
966 23028d31 Sofia Papagiannaki
        cparts = data.split(boundary)[1:-1]
967 7067193f Kostas Papadimitriou
968 b09c9aaa Sofia Papagiannaki
        # assert content parts are exactly 2
969 b09c9aaa Sofia Papagiannaki
        self.assertEqual(len(cparts), len(ranges))
970 7067193f Kostas Papadimitriou
971 b09c9aaa Sofia Papagiannaki
        # for each content part assert headers
972 b09c9aaa Sofia Papagiannaki
        i = 0
973 b09c9aaa Sofia Papagiannaki
        for cpart in cparts:
974 b09c9aaa Sofia Papagiannaki
            content = cpart.split('\r\n')
975 b09c9aaa Sofia Papagiannaki
            headers = content[1:3]
976 b09c9aaa Sofia Papagiannaki
            content_range = headers[0].split(': ')
977 b09c9aaa Sofia Papagiannaki
            self.assertEqual(content_range[0], 'Content-Range')
978 7067193f Kostas Papadimitriou
979 b09c9aaa Sofia Papagiannaki
            r = ranges[i].split('-')
980 b09c9aaa Sofia Papagiannaki
            if not r[0] and not r[1]:
981 b09c9aaa Sofia Papagiannaki
                pass
982 b09c9aaa Sofia Papagiannaki
            elif not r[0]:
983 b09c9aaa Sofia Papagiannaki
                start = len(self.objects[0]['data']) - int(r[1])
984 b09c9aaa Sofia Papagiannaki
                end = len(self.objects[0]['data'])
985 b09c9aaa Sofia Papagiannaki
            elif not r[1]:
986 b09c9aaa Sofia Papagiannaki
                start = int(r[0])
987 b09c9aaa Sofia Papagiannaki
                end = len(self.objects[0]['data'])
988 b09c9aaa Sofia Papagiannaki
            else:
989 b09c9aaa Sofia Papagiannaki
                start = int(r[0])
990 b09c9aaa Sofia Papagiannaki
                end = int(r[1]) + 1
991 b09c9aaa Sofia Papagiannaki
            fdata = self.objects[0]['data'][start:end]
992 b09c9aaa Sofia Papagiannaki
            sdata = '\r\n'.join(content[4:-1])
993 b09c9aaa Sofia Papagiannaki
            self.assertEqual(len(fdata), len(sdata))
994 b09c9aaa Sofia Papagiannaki
            self.assertEquals(fdata, sdata)
995 b09c9aaa Sofia Papagiannaki
            i+=1
996 7067193f Kostas Papadimitriou
997 b09c9aaa Sofia Papagiannaki
    def test_multiple_range_not_satisfiable(self):
998 b09c9aaa Sofia Papagiannaki
        #perform get with multiple range
999 b09c9aaa Sofia Papagiannaki
        out_of_range = len(self.objects[0]['data']) + 1
1000 b09c9aaa Sofia Papagiannaki
        ranges = ['0-499', '-500', '%d-' %out_of_range]
1001 25c3841c Sofia Papagiannaki
        bytes = 'bytes=%s' % ','.join(ranges)
1002 7067193f Kostas Papadimitriou
1003 b09c9aaa Sofia Papagiannaki
        # assert partial content
1004 25c3841c Sofia Papagiannaki
        self.assert_raises_fault(416, self.client.retrieve_object,
1005 25c3841c Sofia Papagiannaki
                                 self.containers[1],
1006 25c3841c Sofia Papagiannaki
                                 self.objects[0]['name'], range=bytes)
1007 7067193f Kostas Papadimitriou
1008 b09c9aaa Sofia Papagiannaki
    def test_get_with_if_match(self):
1009 b09c9aaa Sofia Papagiannaki
        #perform get with If-Match
1010 25c3841c Sofia Papagiannaki
        etag = self.objects[0]['hash']
1011 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
1012 25c3841c Sofia Papagiannaki
                                                           self.objects[0]['name'],
1013 25c3841c Sofia Papagiannaki
                                                           if_match=etag)
1014 b09c9aaa Sofia Papagiannaki
        #assert get success
1015 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 200)
1016 7067193f Kostas Papadimitriou
1017 33ffca25 Sofia Papagiannaki
        #assert content-type
1018 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['content-type'],
1019 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
1020 7067193f Kostas Papadimitriou
1021 b09c9aaa Sofia Papagiannaki
        #assert response content
1022 23028d31 Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'], data)
1023 7067193f Kostas Papadimitriou
1024 b09c9aaa Sofia Papagiannaki
    def test_get_with_if_match_star(self):
1025 b09c9aaa Sofia Papagiannaki
        #perform get with If-Match *
1026 23028d31 Sofia Papagiannaki
        headers = {'if-match':'*'}
1027 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
1028 23028d31 Sofia Papagiannaki
                                                self.objects[0]['name'],
1029 23028d31 Sofia Papagiannaki
                                                **headers)
1030 b09c9aaa Sofia Papagiannaki
        #assert get success
1031 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 200)
1032 7067193f Kostas Papadimitriou
1033 33ffca25 Sofia Papagiannaki
        #assert content-type
1034 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['content-type'],
1035 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
1036 7067193f Kostas Papadimitriou
1037 b09c9aaa Sofia Papagiannaki
        #assert response content
1038 23028d31 Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'], data)
1039 7067193f Kostas Papadimitriou
1040 b09c9aaa Sofia Papagiannaki
    def test_get_with_multiple_if_match(self):
1041 b09c9aaa Sofia Papagiannaki
        #perform get with If-Match
1042 b09c9aaa Sofia Papagiannaki
        etags = [i['hash'] for i in self.objects if i]
1043 b09c9aaa Sofia Papagiannaki
        etags = ','.join('"%s"' % etag for etag in etags)
1044 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
1045 25c3841c Sofia Papagiannaki
                                                           self.objects[0]['name'],
1046 25c3841c Sofia Papagiannaki
                                                           if_match=etags)
1047 b09c9aaa Sofia Papagiannaki
        #assert get success
1048 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 200)
1049 7067193f Kostas Papadimitriou
1050 33ffca25 Sofia Papagiannaki
        #assert content-type
1051 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['content-type'],
1052 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
1053 7067193f Kostas Papadimitriou
1054 33ffca25 Sofia Papagiannaki
        #assert content-type
1055 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['content-type'],
1056 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
1057 7067193f Kostas Papadimitriou
1058 b09c9aaa Sofia Papagiannaki
        #assert response content
1059 23028d31 Sofia Papagiannaki
        self.assertEqual(self.objects[0]['data'], data)
1060 7067193f Kostas Papadimitriou
1061 b09c9aaa Sofia Papagiannaki
    def test_if_match_precondition_failed(self):
1062 23028d31 Sofia Papagiannaki
        #assert precondition failed
1063 25c3841c Sofia Papagiannaki
        self.assert_raises_fault(412, self.client.retrieve_object,
1064 25c3841c Sofia Papagiannaki
                                 self.containers[1],
1065 25c3841c Sofia Papagiannaki
                                 self.objects[0]['name'], if_match='123')
1066 7067193f Kostas Papadimitriou
1067 b09c9aaa Sofia Papagiannaki
    def test_if_none_match(self):
1068 d1e43d6f Sofia Papagiannaki
        #perform get with If-None-Match
1069 25c3841c Sofia Papagiannaki
        status, headers, data = self.client.request_object(self.containers[1],
1070 25c3841c Sofia Papagiannaki
                                                           self.objects[0]['name'],
1071 25c3841c Sofia Papagiannaki
                                                           if_none_match='123')
1072 7067193f Kostas Papadimitriou
1073 b09c9aaa Sofia Papagiannaki
        #assert get success
1074 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 200)
1075 7067193f Kostas Papadimitriou
1076 33ffca25 Sofia Papagiannaki
        #assert content-type
1077 25c3841c Sofia Papagiannaki
        self.assertEqual(headers['content_type'],
1078 25c3841c Sofia Papagiannaki
                         self.objects[0]['meta']['content_type'])
1079 7067193f Kostas Papadimitriou
1080 b09c9aaa Sofia Papagiannaki
    def test_if_none_match(self):
1081 25c3841c Sofia Papagiannaki
        #perform get with If-None-Match * and assert not modified
1082 25c3841c Sofia Papagiannaki
        self.assert_raises_fault(304, self.client.retrieve_object,
1083 25c3841c Sofia Papagiannaki
                                 self.containers[1],
1084 25c3841c Sofia Papagiannaki
                                 self.objects[0]['name'],
1085 25c3841c Sofia Papagiannaki
                                 if_none_match='*')
1086 7067193f Kostas Papadimitriou
1087 b09c9aaa Sofia Papagiannaki
    def test_if_none_match_not_modified(self):
1088 25c3841c Sofia Papagiannaki
        #perform get with If-None-Match and assert not modified
1089 25c3841c Sofia Papagiannaki
        self.assert_raises_fault(304, self.client.retrieve_object,
1090 25c3841c Sofia Papagiannaki
                                 self.containers[1],
1091 25c3841c Sofia Papagiannaki
                                 self.objects[0]['name'],
1092 25c3841c Sofia Papagiannaki
                                 if_none_match=self.objects[0]['hash'])
1093 7067193f Kostas Papadimitriou
1094 25c3841c Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata(self.containers[1],
1095 25c3841c Sofia Papagiannaki
                                                    self.objects[0]['name'])
1096 25c3841c Sofia Papagiannaki
        self.assertEqual(meta['etag'], self.objects[0]['hash'])
1097 7067193f Kostas Papadimitriou
1098 d1e43d6f Sofia Papagiannaki
    def test_if_modified_since(self):
1099 b09c9aaa Sofia Papagiannaki
        t = datetime.datetime.utcnow()
1100 b09c9aaa Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
1101 7067193f Kostas Papadimitriou
1102 b09c9aaa Sofia Papagiannaki
        #modify the object
1103 23028d31 Sofia Papagiannaki
        self.upload_data(self.containers[1],
1104 b09c9aaa Sofia Papagiannaki
                           self.objects[0]['name'],
1105 b09c9aaa Sofia Papagiannaki
                           self.objects[0]['data'][:200])
1106 7067193f Kostas Papadimitriou
1107 b09c9aaa Sofia Papagiannaki
        for f in DATE_FORMATS:
1108 b09c9aaa Sofia Papagiannaki
            past = t2.strftime(f)
1109 7067193f Kostas Papadimitriou
1110 23028d31 Sofia Papagiannaki
            headers = {'if-modified-since':'%s' %past}
1111 25c3841c Sofia Papagiannaki
            try:
1112 25c3841c Sofia Papagiannaki
                o = self.client.retrieve_object(self.containers[1],
1113 23028d31 Sofia Papagiannaki
                                                self.objects[0]['name'],
1114 25c3841c Sofia Papagiannaki
                                                if_modified_since=past)
1115 25c3841c Sofia Papagiannaki
                self.assertEqual(o,
1116 25c3841c Sofia Papagiannaki
                                 self.client.retrieve_object(self.containers[1],
1117 25c3841c Sofia Papagiannaki
                                                             self.objects[0]['name']))
1118 25c3841c Sofia Papagiannaki
            except Fault, f:
1119 25c3841c Sofia Papagiannaki
                self.failIf(f.status == 304)
1120 7067193f Kostas Papadimitriou
1121 25c3841c Sofia Papagiannaki
    def test_if_modified_since_invalid_date(self):
1122 25c3841c Sofia Papagiannaki
        o = self.client.retrieve_object(self.containers[1],
1123 25c3841c Sofia Papagiannaki
                                        self.objects[0]['name'],
1124 25c3841c Sofia Papagiannaki
                                        if_modified_since='')
1125 25c3841c Sofia Papagiannaki
        self.assertEqual(o, self.client.retrieve_object(self.containers[1],
1126 25c3841c Sofia Papagiannaki
                                                        self.objects[0]['name']))
1127 7067193f Kostas Papadimitriou
1128 d1e43d6f Sofia Papagiannaki
    def test_if_not_modified_since(self):
1129 b09c9aaa Sofia Papagiannaki
        now = datetime.datetime.utcnow()
1130 b09c9aaa Sofia Papagiannaki
        since = now + datetime.timedelta(1)
1131 7067193f Kostas Papadimitriou
1132 b09c9aaa Sofia Papagiannaki
        for f in DATE_FORMATS:
1133 b09c9aaa Sofia Papagiannaki
            #assert not modified
1134 25c3841c Sofia Papagiannaki
            self.assert_raises_fault(304, self.client.retrieve_object,
1135 25c3841c Sofia Papagiannaki
                                     self.containers[1], self.objects[0]['name'],
1136 25c3841c Sofia Papagiannaki
                                     if_modified_since=since.strftime(f))
1137 7067193f Kostas Papadimitriou
1138 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since(self):
1139 d1e43d6f Sofia Papagiannaki
        now = datetime.datetime.utcnow()
1140 d1e43d6f Sofia Papagiannaki
        since = now + datetime.timedelta(1)
1141 7067193f Kostas Papadimitriou
1142 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
1143 25c3841c Sofia Papagiannaki
            t = since.strftime(f)
1144 25c3841c Sofia Papagiannaki
            status, headers, data = self.client.request_object(self.containers[1],
1145 25c3841c Sofia Papagiannaki
                                                               self.objects[0]['name'],
1146 25c3841c Sofia Papagiannaki
                                                               if_unmodified_since=t)
1147 d1e43d6f Sofia Papagiannaki
            #assert success
1148 23028d31 Sofia Papagiannaki
            self.assertEqual(status, 200)
1149 23028d31 Sofia Papagiannaki
            self.assertEqual(self.objects[0]['data'], data)
1150 7067193f Kostas Papadimitriou
1151 33ffca25 Sofia Papagiannaki
            #assert content-type
1152 23028d31 Sofia Papagiannaki
            self.assertEqual(headers['content-type'],
1153 25c3841c Sofia Papagiannaki
                             self.objects[0]['meta']['content_type'])
1154 7067193f Kostas Papadimitriou
1155 d1e43d6f Sofia Papagiannaki
    def test_if_unmodified_since_precondition_failed(self):
1156 d1e43d6f Sofia Papagiannaki
        t = datetime.datetime.utcnow()
1157 d1e43d6f Sofia Papagiannaki
        t2 = t - datetime.timedelta(minutes=10)
1158 7067193f Kostas Papadimitriou
1159 d1e43d6f Sofia Papagiannaki
        #modify the object
1160 23028d31 Sofia Papagiannaki
        self.upload_data(self.containers[1],
1161 d1e43d6f Sofia Papagiannaki
                           self.objects[0]['name'],
1162 d1e43d6f Sofia Papagiannaki
                           self.objects[0]['data'][:200])
1163 7067193f Kostas Papadimitriou
1164 d1e43d6f Sofia Papagiannaki
        for f in DATE_FORMATS:
1165 d1e43d6f Sofia Papagiannaki
            past = t2.strftime(f)
1166 23028d31 Sofia Papagiannaki
            #assert precondition failed
1167 25c3841c Sofia Papagiannaki
            self.assert_raises_fault(412, self.client.retrieve_object,
1168 25c3841c Sofia Papagiannaki
                                     self.containers[1], self.objects[0]['name'],
1169 25c3841c Sofia Papagiannaki
                                     if_unmodified_since=past)
1170 7067193f Kostas Papadimitriou
1171 d1e43d6f Sofia Papagiannaki
    def test_hashes(self):
1172 33ffca25 Sofia Papagiannaki
        l = 8388609
1173 33ffca25 Sofia Papagiannaki
        fname = 'largefile'
1174 23028d31 Sofia Papagiannaki
        o = self.upload_random_data(self.containers[1], fname, l)
1175 d1e43d6f Sofia Papagiannaki
        if o:
1176 3078108a Sofia Papagiannaki
            body = self.client.retrieve_object(self.containers[1], fname,
1177 f0eacc2c Sofia Papagiannaki
                                               format='json')
1178 33ffca25 Sofia Papagiannaki
            hashes = body['hashes']
1179 33ffca25 Sofia Papagiannaki
            block_size = body['block_size']
1180 33ffca25 Sofia Papagiannaki
            block_hash = body['block_hash']
1181 af6d3b5d Antony Chazapis
            block_num = l/block_size if l/block_size == 0 else l/block_size + 1
1182 33ffca25 Sofia Papagiannaki
            self.assertTrue(len(hashes), block_num)
1183 d1e43d6f Sofia Papagiannaki
            i = 0
1184 d1e43d6f Sofia Papagiannaki
            for h in hashes:
1185 d1e43d6f Sofia Papagiannaki
                start = i * block_size
1186 d1e43d6f Sofia Papagiannaki
                end = (i + 1) * block_size
1187 33ffca25 Sofia Papagiannaki
                hash = compute_block_hash(o['data'][start:end], block_hash)
1188 33ffca25 Sofia Papagiannaki
                self.assertEqual(h, hash)
1189 d1e43d6f Sofia Papagiannaki
                i += 1
1190 d1e43d6f Sofia Papagiannaki
1191 d1e43d6f Sofia Papagiannaki
class ObjectPut(BaseTestCase):
1192 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1193 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1194 b09c9aaa Sofia Papagiannaki
        self.container = 'c1'
1195 25c3841c Sofia Papagiannaki
        self.client.create_container(self.container)
1196 7067193f Kostas Papadimitriou
1197 b09c9aaa Sofia Papagiannaki
    def test_upload(self):
1198 23028d31 Sofia Papagiannaki
        name = o_names[0]
1199 23028d31 Sofia Papagiannaki
        meta = {'test':'test1'}
1200 23028d31 Sofia Papagiannaki
        o = self.upload_random_data(self.container, name, **meta)
1201 7067193f Kostas Papadimitriou
1202 23028d31 Sofia Papagiannaki
        headers = self.client.retrieve_object_metadata(self.container,
1203 23028d31 Sofia Papagiannaki
                                                       name,
1204 23028d31 Sofia Papagiannaki
                                                       restricted=True)
1205 23028d31 Sofia Papagiannaki
        self.assertTrue('test' in headers.keys())
1206 23028d31 Sofia Papagiannaki
        self.assertEqual(headers['test'], meta['test'])
1207 7067193f Kostas Papadimitriou
1208 b09c9aaa Sofia Papagiannaki
        #assert uploaded content
1209 25c3841c Sofia Papagiannaki
        status, h, data = self.client.request_object(self.container, name)
1210 25c3841c Sofia Papagiannaki
        self.assertEqual(len(o['data']), int(h['content-length']))
1211 25c3841c Sofia Papagiannaki
        self.assertEqual(o['data'], data)
1212 7067193f Kostas Papadimitriou
1213 25c3841c Sofia Papagiannaki
        #assert content-type
1214 25c3841c Sofia Papagiannaki
        self.assertEqual(h['content-type'], o['meta']['content_type'])
1215 7067193f Kostas Papadimitriou
1216 e7b51248 Sofia Papagiannaki
    def _test_maximum_upload_size_exceeds(self):
1217 ae75584f Sofia Papagiannaki
        name = o_names[0]
1218 ae75584f Sofia Papagiannaki
        meta = {'test':'test1'}
1219 ae75584f Sofia Papagiannaki
        #upload 100MB
1220 ae75584f Sofia Papagiannaki
        length=1024*1024*100
1221 ae75584f Sofia Papagiannaki
        self.assert_raises_fault(400, self.upload_random_data, self.container,
1222 ae75584f Sofia Papagiannaki
                                 name, length, **meta)
1223 7067193f Kostas Papadimitriou
1224 7812e1f9 Sofia Papagiannaki
    def test_upload_with_name_containing_slash(self):
1225 7812e1f9 Sofia Papagiannaki
        name = '/%s' % o_names[0]
1226 7812e1f9 Sofia Papagiannaki
        meta = {'test':'test1'}
1227 7812e1f9 Sofia Papagiannaki
        o = self.upload_random_data(self.container, name, **meta)
1228 7067193f Kostas Papadimitriou
1229 7812e1f9 Sofia Papagiannaki
        self.assertEqual(o['data'],
1230 7812e1f9 Sofia Papagiannaki
                         self.client.retrieve_object(self.container, name))
1231 7067193f Kostas Papadimitriou
1232 7812e1f9 Sofia Papagiannaki
        self.assertTrue(name in self.client.list_objects(self.container))
1233 7067193f Kostas Papadimitriou
1234 7812e1f9 Sofia Papagiannaki
    def test_create_directory_marker(self):
1235 7812e1f9 Sofia Papagiannaki
        self.client.create_directory_marker(self.container, 'foo')
1236 7812e1f9 Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata(self.container, 'foo')
1237 7812e1f9 Sofia Papagiannaki
        self.assertEqual(meta['content-length'], '0')
1238 7812e1f9 Sofia Papagiannaki
        self.assertEqual(meta['content-type'], 'application/directory')
1239 7812e1f9 Sofia Papagiannaki
1240 b09c9aaa Sofia Papagiannaki
    def test_upload_unprocessable_entity(self):
1241 23028d31 Sofia Papagiannaki
        meta={'etag':'123', 'test':'test1'}
1242 7067193f Kostas Papadimitriou
1243 23028d31 Sofia Papagiannaki
        #assert unprocessable entity
1244 25c3841c Sofia Papagiannaki
        self.assert_raises_fault(422, self.upload_random_data, self.container,
1245 23028d31 Sofia Papagiannaki
                                 o_names[0], **meta)
1246 7067193f Kostas Papadimitriou
1247 f0eacc2c Sofia Papagiannaki
    def test_chunked_transfer(self):
1248 25c3841c Sofia Papagiannaki
        data = get_random_data()
1249 25c3841c Sofia Papagiannaki
        objname = 'object'
1250 25c3841c Sofia Papagiannaki
        self.client.create_object_using_chunks(self.container, objname,
1251 25c3841c Sofia Papagiannaki
                                               StringIO(data))
1252 7067193f Kostas Papadimitriou
1253 25c3841c Sofia Papagiannaki
        uploaded_data = self.client.retrieve_object(self.container, objname)
1254 25c3841c Sofia Papagiannaki
        self.assertEqual(data, uploaded_data)
1255 7067193f Kostas Papadimitriou
1256 ae75584f Sofia Papagiannaki
    def test_manifestation(self):
1257 ae75584f Sofia Papagiannaki
        prefix = 'myobject/'
1258 ae75584f Sofia Papagiannaki
        data = ''
1259 ae75584f Sofia Papagiannaki
        for i in range(5):
1260 ae75584f Sofia Papagiannaki
            part = '%s%d' %(prefix, i)
1261 ae75584f Sofia Papagiannaki
            o = self.upload_random_data(self.container, part)
1262 ae75584f Sofia Papagiannaki
            data += o['data']
1263 7067193f Kostas Papadimitriou
1264 ae75584f Sofia Papagiannaki
        manifest = '%s/%s' %(self.container, prefix)
1265 95e92490 Sofia Papagiannaki
        self.client.create_manifestation(self.container, 'large-object', manifest)
1266 7067193f Kostas Papadimitriou
1267 ae75584f Sofia Papagiannaki
        self.assert_object_exists(self.container, 'large-object')
1268 ae75584f Sofia Papagiannaki
        self.assertEqual(data, self.client.retrieve_object(self.container,
1269 ae75584f Sofia Papagiannaki
                                                           'large-object'))
1270 9b26015d Sofia Papagiannaki
        
1271 9b26015d Sofia Papagiannaki
        r = self.client.retrieve_object_hashmap(self.container,'large-object')
1272 9b26015d Sofia Papagiannaki
        hashes = r['hashes']
1273 9b26015d Sofia Papagiannaki
        block_size = int(r['block_size'])
1274 9b26015d Sofia Papagiannaki
        block_hash = r['block_hash']
1275 9b26015d Sofia Papagiannaki
        l = len(data)
1276 9b26015d Sofia Papagiannaki
        block_num = l/block_size if l/block_size != 0 else l/block_size + 1
1277 9b26015d Sofia Papagiannaki
        self.assertEqual(block_num, len(hashes))
1278 9b26015d Sofia Papagiannaki
        
1279 ae75584f Sofia Papagiannaki
        #wrong manifestation
1280 ae75584f Sofia Papagiannaki
        self.client.create_manifestation(self.container, 'large-object',
1281 95e92490 Sofia Papagiannaki
                                         '%s/invalid' % self.container)
1282 95e92490 Sofia Papagiannaki
        self.assertEqual('', self.client.retrieve_object(self.container,
1283 95e92490 Sofia Papagiannaki
                                                         'large-object'))
1284 7067193f Kostas Papadimitriou
1285 3078108a Sofia Papagiannaki
    def test_create_zero_length_object(self):
1286 3078108a Sofia Papagiannaki
        c = self.container
1287 3078108a Sofia Papagiannaki
        o = 'object'
1288 3078108a Sofia Papagiannaki
        zero = self.client.create_zero_length_object(c, o)
1289 3078108a Sofia Papagiannaki
        zero_meta = self.client.retrieve_object_metadata(c, o)
1290 fd9f505c Antony Chazapis
        zero_hash = self.client.retrieve_object_hashmap(c, o)["hashes"]
1291 3078108a Sofia Papagiannaki
        zero_data = self.client.retrieve_object(c, o)
1292 7067193f Kostas Papadimitriou
1293 3078108a Sofia Papagiannaki
        self.assertEqual(int(zero_meta['content-length']), 0)
1294 35390ded Sofia Papagiannaki
        hasher = newhasher('sha256')
1295 35390ded Sofia Papagiannaki
        hasher.update("")
1296 35390ded Sofia Papagiannaki
        emptyhash = hasher.digest()
1297 35390ded Sofia Papagiannaki
        self.assertEqual(zero_hash, [hexlify(emptyhash)])
1298 3078108a Sofia Papagiannaki
        self.assertEqual(zero_data, '')
1299 7067193f Kostas Papadimitriou
1300 ad7e4bea Sofia Papagiannaki
    def test_create_object_by_hashmap(self):
1301 ad7e4bea Sofia Papagiannaki
        c = self.container
1302 ad7e4bea Sofia Papagiannaki
        o = 'object'
1303 ad7e4bea Sofia Papagiannaki
        self.upload_random_data(c, o)
1304 ad7e4bea Sofia Papagiannaki
        hashmap = self.client.retrieve_object(c, o, format='json')
1305 ad7e4bea Sofia Papagiannaki
        o2 = 'object-copy'
1306 ad7e4bea Sofia Papagiannaki
        self.client.create_object_by_hashmap(c, o2, hashmap)
1307 ad7e4bea Sofia Papagiannaki
        self.assertEqual(self.client.retrieve_object(c, o),
1308 ad7e4bea Sofia Papagiannaki
                         self.client.retrieve_object(c, o))
1309 3078108a Sofia Papagiannaki
1310 d1e43d6f Sofia Papagiannaki
class ObjectCopy(BaseTestCase):
1311 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1312 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1313 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
1314 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1315 25c3841c Sofia Papagiannaki
            self.client.create_container(c)
1316 23028d31 Sofia Papagiannaki
        self.obj = self.upload_random_data(self.containers[0], o_names[0])
1317 7067193f Kostas Papadimitriou
1318 b09c9aaa Sofia Papagiannaki
    def test_copy(self):
1319 23028d31 Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_object_metadata,
1320 33ffca25 Sofia Papagiannaki
                             self.containers[0], self.obj['name']):
1321 b09c9aaa Sofia Papagiannaki
            #perform copy
1322 23028d31 Sofia Papagiannaki
            meta = {'test':'testcopy'}
1323 23028d31 Sofia Papagiannaki
            status = self.client.copy_object(self.containers[0],
1324 23028d31 Sofia Papagiannaki
                                              self.obj['name'],
1325 23028d31 Sofia Papagiannaki
                                              self.containers[0],
1326 23028d31 Sofia Papagiannaki
                                              'testcopy',
1327 7812e1f9 Sofia Papagiannaki
                                              meta)[0]
1328 7067193f Kostas Papadimitriou
1329 b09c9aaa Sofia Papagiannaki
            #assert copy success
1330 23028d31 Sofia Papagiannaki
            self.assertEqual(status, 201)
1331 7067193f Kostas Papadimitriou
1332 b09c9aaa Sofia Papagiannaki
            #assert access the new object
1333 23028d31 Sofia Papagiannaki
            headers = self.client.retrieve_object_metadata(self.containers[0],
1334 23028d31 Sofia Papagiannaki
                                                           'testcopy')
1335 23028d31 Sofia Papagiannaki
            self.assertTrue('x-object-meta-test' in headers.keys())
1336 23028d31 Sofia Papagiannaki
            self.assertTrue(headers['x-object-meta-test'], 'testcopy')
1337 7067193f Kostas Papadimitriou
1338 b09c9aaa Sofia Papagiannaki
            #assert etag is the same
1339 23028d31 Sofia Papagiannaki
            self.assertEqual(headers['etag'], self.obj['hash'])
1340 7067193f Kostas Papadimitriou
1341 b09c9aaa Sofia Papagiannaki
            #assert src object still exists
1342 23028d31 Sofia Papagiannaki
            self.assert_object_exists(self.containers[0], self.obj['name'])
1343 7067193f Kostas Papadimitriou
1344 b09c9aaa Sofia Papagiannaki
    def test_copy_from_different_container(self):
1345 23028d31 Sofia Papagiannaki
        with AssertMappingInvariant(self.client.retrieve_object_metadata,
1346 23028d31 Sofia Papagiannaki
                             self.containers[0], self.obj['name']):
1347 23028d31 Sofia Papagiannaki
            meta = {'test':'testcopy'}
1348 23028d31 Sofia Papagiannaki
            status = self.client.copy_object(self.containers[0],
1349 23028d31 Sofia Papagiannaki
                                             self.obj['name'],
1350 23028d31 Sofia Papagiannaki
                                             self.containers[1],
1351 23028d31 Sofia Papagiannaki
                                             'testcopy',
1352 7812e1f9 Sofia Papagiannaki
                                             meta)[0]
1353 23028d31 Sofia Papagiannaki
            self.assertEqual(status, 201)
1354 7067193f Kostas Papadimitriou
1355 b09c9aaa Sofia Papagiannaki
            # assert updated metadata
1356 23028d31 Sofia Papagiannaki
            meta = self.client.retrieve_object_metadata(self.containers[1],
1357 23028d31 Sofia Papagiannaki
                                                           'testcopy',
1358 23028d31 Sofia Papagiannaki
                                                           restricted=True)
1359 23028d31 Sofia Papagiannaki
            self.assertTrue('test' in meta.keys())
1360 23028d31 Sofia Papagiannaki
            self.assertTrue(meta['test'], 'testcopy')
1361 7067193f Kostas Papadimitriou
1362 b09c9aaa Sofia Papagiannaki
            #assert src object still exists
1363 23028d31 Sofia Papagiannaki
            self.assert_object_exists(self.containers[0], self.obj['name'])
1364 7067193f Kostas Papadimitriou
1365 b09c9aaa Sofia Papagiannaki
    def test_copy_invalid(self):
1366 b09c9aaa Sofia Papagiannaki
        #copy from invalid object
1367 23028d31 Sofia Papagiannaki
        meta = {'test':'testcopy'}
1368 23028d31 Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.copy_object, self.containers[0],
1369 7812e1f9 Sofia Papagiannaki
                                 'test.py', self.containers[1], 'testcopy', meta)
1370 7067193f Kostas Papadimitriou
1371 b09c9aaa Sofia Papagiannaki
        #copy from invalid container
1372 23028d31 Sofia Papagiannaki
        meta = {'test':'testcopy'}
1373 23028d31 Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.copy_object, self.containers[1],
1374 23028d31 Sofia Papagiannaki
                                 self.obj['name'], self.containers[1],
1375 7812e1f9 Sofia Papagiannaki
                                 'testcopy', meta)
1376 b09c9aaa Sofia Papagiannaki
1377 7812e1f9 Sofia Papagiannaki
class ObjectMove(BaseTestCase):
1378 7812e1f9 Sofia Papagiannaki
    def setUp(self):
1379 7812e1f9 Sofia Papagiannaki
        BaseTestCase.setUp(self)
1380 7812e1f9 Sofia Papagiannaki
        self.containers = ['c1', 'c2']
1381 7812e1f9 Sofia Papagiannaki
        for c in self.containers:
1382 7812e1f9 Sofia Papagiannaki
            self.client.create_container(c)
1383 7812e1f9 Sofia Papagiannaki
        self.obj = self.upload_random_data(self.containers[0], o_names[0])
1384 7067193f Kostas Papadimitriou
1385 b09c9aaa Sofia Papagiannaki
    def test_move(self):
1386 95e0d8ee Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata(self.containers[0],
1387 95e0d8ee Sofia Papagiannaki
                                                    self.obj['name'])
1388 95e0d8ee Sofia Papagiannaki
        self.assertTrue('x-object-uuid' in meta)
1389 95e0d8ee Sofia Papagiannaki
        uuid = meta['x-object-uuid']
1390 7067193f Kostas Papadimitriou
1391 b09c9aaa Sofia Papagiannaki
        #perform move
1392 23028d31 Sofia Papagiannaki
        meta = {'test':'testcopy'}
1393 f7667baf Antony Chazapis
        src_path = '/'.join(('/', self.containers[0], self.obj['name']))
1394 23028d31 Sofia Papagiannaki
        status = self.client.move_object(self.containers[0], self.obj['name'],
1395 23028d31 Sofia Papagiannaki
                                         self.containers[0], 'testcopy',
1396 7812e1f9 Sofia Papagiannaki
                                         meta)[0]
1397 7067193f Kostas Papadimitriou
1398 b09c9aaa Sofia Papagiannaki
        #assert successful move
1399 23028d31 Sofia Papagiannaki
        self.assertEqual(status, 201)
1400 7067193f Kostas Papadimitriou
1401 b09c9aaa Sofia Papagiannaki
        #assert updated metadata
1402 23028d31 Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata(self.containers[0],
1403 95e0d8ee Sofia Papagiannaki
                                                    'testcopy')
1404 95e0d8ee Sofia Papagiannaki
        self.assertTrue('x-object-meta-test' in meta.keys())
1405 95e0d8ee Sofia Papagiannaki
        self.assertTrue(meta['x-object-meta-test'], 'testcopy')
1406 7067193f Kostas Papadimitriou
1407 95e0d8ee Sofia Papagiannaki
        #assert same uuid
1408 95e0d8ee Sofia Papagiannaki
        self.assertTrue(meta['x-object-uuid'], uuid)
1409 7067193f Kostas Papadimitriou
1410 b09c9aaa Sofia Papagiannaki
        #assert src object no more exists
1411 23028d31 Sofia Papagiannaki
        self.assert_object_not_exists(self.containers[0], self.obj['name'])
1412 b09c9aaa Sofia Papagiannaki
1413 d1e43d6f Sofia Papagiannaki
class ObjectPost(BaseTestCase):
1414 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1415 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1416 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
1417 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1418 25c3841c Sofia Papagiannaki
            self.client.create_container(c)
1419 3078108a Sofia Papagiannaki
        self.obj = []
1420 3078108a Sofia Papagiannaki
        for i in range(2):
1421 3078108a Sofia Papagiannaki
            self.obj.append(self.upload_random_data(self.containers[0], o_names[i]))
1422 7067193f Kostas Papadimitriou
1423 33ffca25 Sofia Papagiannaki
    def test_update_meta(self):
1424 95e0d8ee Sofia Papagiannaki
        with AssertUUidInvariant(self.client.retrieve_object_metadata,
1425 95e0d8ee Sofia Papagiannaki
                                 self.containers[0],
1426 95e0d8ee Sofia Papagiannaki
                                 self.obj[0]['name']):
1427 95e0d8ee Sofia Papagiannaki
            #perform update metadata
1428 62bf8157 Antony Chazapis
            more = {'foo': 'foo', 'bar': 'bar', 'f' * 114: 'b' * 256}
1429 95e0d8ee Sofia Papagiannaki
            status = self.client.update_object_metadata(self.containers[0],
1430 95e0d8ee Sofia Papagiannaki
                                                        self.obj[0]['name'],
1431 95e0d8ee Sofia Papagiannaki
                                                        **more)[0]
1432 95e0d8ee Sofia Papagiannaki
            #assert request accepted
1433 95e0d8ee Sofia Papagiannaki
            self.assertEqual(status, 202)
1434 7067193f Kostas Papadimitriou
1435 95e0d8ee Sofia Papagiannaki
            #assert old metadata are still there
1436 95e0d8ee Sofia Papagiannaki
            headers = self.client.retrieve_object_metadata(self.containers[0],
1437 95e0d8ee Sofia Papagiannaki
                                                           self.obj[0]['name'],
1438 95e0d8ee Sofia Papagiannaki
                                                           restricted=True)
1439 95e0d8ee Sofia Papagiannaki
            #assert new metadata have been updated
1440 95e0d8ee Sofia Papagiannaki
            for k,v in more.items():
1441 95e0d8ee Sofia Papagiannaki
                self.assertTrue(k in headers.keys())
1442 95e0d8ee Sofia Papagiannaki
                self.assertTrue(headers[k], v)
1443 7067193f Kostas Papadimitriou
1444 62bf8157 Antony Chazapis
            #out of limits
1445 62bf8157 Antony Chazapis
            more = {'f' * 114: 'b' * 257}
1446 62bf8157 Antony Chazapis
            self.assert_raises_fault(400, self.client.update_object_metadata,
1447 62bf8157 Antony Chazapis
                                                        self.containers[0],
1448 62bf8157 Antony Chazapis
                                                        self.obj[0]['name'],
1449 62bf8157 Antony Chazapis
                                                        **more)
1450 9b26015d Sofia Papagiannaki
            
1451 9b26015d Sofia Papagiannaki
            #perform update metadata
1452 9b26015d Sofia Papagiannaki
            more = {'α': 'β' * 256}
1453 9b26015d Sofia Papagiannaki
            status = self.client.update_object_metadata(self.containers[0],
1454 9b26015d Sofia Papagiannaki
                                                        self.obj[0]['name'],
1455 9b26015d Sofia Papagiannaki
                                                        **more)[0]
1456 9b26015d Sofia Papagiannaki
            #assert request accepted
1457 9b26015d Sofia Papagiannaki
            self.assertEqual(status, 202)
1458 9b26015d Sofia Papagiannaki
            
1459 9b26015d Sofia Papagiannaki
            #assert old metadata are still there
1460 9b26015d Sofia Papagiannaki
            headers = self.client.retrieve_object_metadata(self.containers[0],
1461 9b26015d Sofia Papagiannaki
                                                           self.obj[0]['name'],
1462 9b26015d Sofia Papagiannaki
                                                           restricted=True)
1463 9b26015d Sofia Papagiannaki
            #assert new metadata have been updated
1464 9b26015d Sofia Papagiannaki
            for k,v in more.items():
1465 9b26015d Sofia Papagiannaki
                self.assertTrue(k in headers.keys())
1466 9b26015d Sofia Papagiannaki
                self.assertTrue(headers[k], v)
1467 9b26015d Sofia Papagiannaki
            
1468 9b26015d Sofia Papagiannaki
            #out of limits
1469 9b26015d Sofia Papagiannaki
            more = {'α': 'β' * 257}
1470 9b26015d Sofia Papagiannaki
            self.assert_raises_fault(400, self.client.update_object_metadata,
1471 9b26015d Sofia Papagiannaki
                                                        self.containers[0],
1472 9b26015d Sofia Papagiannaki
                                                        self.obj[0]['name'],
1473 9b26015d Sofia Papagiannaki
                                                        **more)
1474 9b26015d Sofia Papagiannaki
    
1475 33ffca25 Sofia Papagiannaki
    def test_update_object(self,
1476 33ffca25 Sofia Papagiannaki
                           first_byte_pos=0,
1477 33ffca25 Sofia Papagiannaki
                           last_byte_pos=499,
1478 33ffca25 Sofia Papagiannaki
                           instance_length = True,
1479 33ffca25 Sofia Papagiannaki
                           content_length = 500):
1480 95e0d8ee Sofia Papagiannaki
        with AssertUUidInvariant(self.client.retrieve_object_metadata,
1481 95e0d8ee Sofia Papagiannaki
                                 self.containers[0],
1482 95e0d8ee Sofia Papagiannaki
                                 self.obj[0]['name']):
1483 95e0d8ee Sofia Papagiannaki
            l = len(self.obj[0]['data'])
1484 95e0d8ee Sofia Papagiannaki
            range = 'bytes %d-%d/%s' %(first_byte_pos,
1485 95e0d8ee Sofia Papagiannaki
                                           last_byte_pos,
1486 95e0d8ee Sofia Papagiannaki
                                            l if instance_length else '*')
1487 95e0d8ee Sofia Papagiannaki
            partial = last_byte_pos - first_byte_pos + 1
1488 95e0d8ee Sofia Papagiannaki
            length = first_byte_pos + partial
1489 95e0d8ee Sofia Papagiannaki
            data = get_random_data(partial)
1490 95e0d8ee Sofia Papagiannaki
            args = {'content_type':'application/octet-stream',
1491 95e0d8ee Sofia Papagiannaki
                    'content_range':'%s' %range}
1492 95e0d8ee Sofia Papagiannaki
            if content_length:
1493 95e0d8ee Sofia Papagiannaki
                args['content_length'] = content_length
1494 7067193f Kostas Papadimitriou
1495 5a8dc30c Sofia Papagiannaki
            r = self.client.update_object(self.containers[0], self.obj[0]['name'],
1496 5a8dc30c Sofia Papagiannaki
                                      StringIO(data), **args)
1497 5a8dc30c Sofia Papagiannaki
            status = r[0]
1498 5a8dc30c Sofia Papagiannaki
            etag = r[1]['etag']
1499 95e0d8ee Sofia Papagiannaki
            if partial < 0 or (instance_length and l <= last_byte_pos):
1500 7067193f Kostas Papadimitriou
                self.assertEqual(status, 202)
1501 95e0d8ee Sofia Papagiannaki
            else:
1502 7067193f Kostas Papadimitriou
                self.assertEqual(status, 204)
1503 95e0d8ee Sofia Papagiannaki
                #check modified object
1504 95e0d8ee Sofia Papagiannaki
                content = self.client.retrieve_object(self.containers[0],
1505 95e0d8ee Sofia Papagiannaki
                                                  self.obj[0]['name'])
1506 95e0d8ee Sofia Papagiannaki
                self.assertEqual(content[:first_byte_pos], self.obj[0]['data'][:first_byte_pos])
1507 95e0d8ee Sofia Papagiannaki
                self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
1508 95e0d8ee Sofia Papagiannaki
                self.assertEqual(content[last_byte_pos+1:], self.obj[0]['data'][last_byte_pos+1:])
1509 5a8dc30c Sofia Papagiannaki
                self.assertEqual(etag, compute_md5_hash(content))
1510 7067193f Kostas Papadimitriou
1511 3078108a Sofia Papagiannaki
    def test_update_object_lt_blocksize(self):
1512 3078108a Sofia Papagiannaki
        self.test_update_object(10, 20, content_length=None)
1513 7067193f Kostas Papadimitriou
1514 3078108a Sofia Papagiannaki
    def test_update_object_gt_blocksize(self):
1515 3078108a Sofia Papagiannaki
        o = self.upload_random_data(self.containers[0], o_names[1],
1516 3078108a Sofia Papagiannaki
                                length=4*1024*1024+5)
1517 3078108a Sofia Papagiannaki
        c = self.containers[0]
1518 3078108a Sofia Papagiannaki
        o_name = o['name']
1519 3078108a Sofia Papagiannaki
        o_data = o['data']
1520 3078108a Sofia Papagiannaki
        first_byte_pos = 4*1024*1024+1
1521 3078108a Sofia Papagiannaki
        last_byte_pos = 4*1024*1024+4
1522 3078108a Sofia Papagiannaki
        l = last_byte_pos - first_byte_pos + 1
1523 3078108a Sofia Papagiannaki
        data = get_random_data(l)
1524 3078108a Sofia Papagiannaki
        range = 'bytes %d-%d/*' %(first_byte_pos, last_byte_pos)
1525 3078108a Sofia Papagiannaki
        self.client.update_object(c, o_name, StringIO(data), content_range=range)
1526 3078108a Sofia Papagiannaki
        content = self.client.retrieve_object(c, o_name)
1527 3078108a Sofia Papagiannaki
        self.assertEqual(content[:first_byte_pos], o_data[:first_byte_pos])
1528 3078108a Sofia Papagiannaki
        self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
1529 7067193f Kostas Papadimitriou
        self.assertEqual(content[last_byte_pos+1:], o_data[last_byte_pos+1:])
1530 7067193f Kostas Papadimitriou
1531 3078108a Sofia Papagiannaki
    def test_update_object_divided_by_blocksize(self):
1532 3078108a Sofia Papagiannaki
        o = self.upload_random_data(self.containers[0], o_names[1],
1533 3078108a Sofia Papagiannaki
                                length=4*1024*1024+5)
1534 3078108a Sofia Papagiannaki
        c = self.containers[0]
1535 3078108a Sofia Papagiannaki
        o_name = o['name']
1536 3078108a Sofia Papagiannaki
        o_data = o['data']
1537 3078108a Sofia Papagiannaki
        first_byte_pos = 4*1024*1024
1538 3078108a Sofia Papagiannaki
        last_byte_pos = 5*1024*1024
1539 3078108a Sofia Papagiannaki
        l = last_byte_pos - first_byte_pos + 1
1540 3078108a Sofia Papagiannaki
        data = get_random_data(l)
1541 3078108a Sofia Papagiannaki
        range = 'bytes %d-%d/*' %(first_byte_pos, last_byte_pos)
1542 3078108a Sofia Papagiannaki
        self.client.update_object(c, o_name, StringIO(data), content_range=range)
1543 3078108a Sofia Papagiannaki
        content = self.client.retrieve_object(c, o_name)
1544 3078108a Sofia Papagiannaki
        self.assertEqual(content[:first_byte_pos], o_data[:first_byte_pos])
1545 3078108a Sofia Papagiannaki
        self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
1546 7067193f Kostas Papadimitriou
        self.assertEqual(content[last_byte_pos+1:], o_data[last_byte_pos+1:])
1547 7067193f Kostas Papadimitriou
1548 33ffca25 Sofia Papagiannaki
    def test_update_object_no_content_length(self):
1549 33ffca25 Sofia Papagiannaki
        self.test_update_object(content_length = None)
1550 7067193f Kostas Papadimitriou
1551 25c3841c Sofia Papagiannaki
    def test_update_object_invalid_content_length(self):
1552 25c3841c Sofia Papagiannaki
        with AssertContentInvariant(self.client.retrieve_object,
1553 3078108a Sofia Papagiannaki
                                    self.containers[0], self.obj[0]['name']):
1554 25c3841c Sofia Papagiannaki
            self.assert_raises_fault(400, self.test_update_object,
1555 25c3841c Sofia Papagiannaki
                                     content_length = 1000)
1556 7067193f Kostas Papadimitriou
1557 68229c3e Sofia Papagiannaki
    def _test_update_object_invalid_range(self):
1558 25c3841c Sofia Papagiannaki
        with AssertContentInvariant(self.client.retrieve_object,
1559 3078108a Sofia Papagiannaki
                                    self.containers[0], self.obj[0]['name']):
1560 cd6ada1d Sofia Papagiannaki
            self.assert_raises_fault(416, self.test_update_object, 499, 0, True)
1561 7067193f Kostas Papadimitriou
1562 68229c3e Sofia Papagiannaki
    def _test_update_object_invalid_range_and_length(self):
1563 25c3841c Sofia Papagiannaki
        with AssertContentInvariant(self.client.retrieve_object,
1564 3078108a Sofia Papagiannaki
                                    self.containers[0], self.obj[0]['name']):
1565 0538cac6 Sofia Papagiannaki
            self.assert_raises_fault([400, 416], self.test_update_object, 499, 0, True,
1566 cd6ada1d Sofia Papagiannaki
                                     -1)
1567 7067193f Kostas Papadimitriou
1568 33ffca25 Sofia Papagiannaki
    def test_update_object_invalid_range_with_no_content_length(self):
1569 25c3841c Sofia Papagiannaki
        with AssertContentInvariant(self.client.retrieve_object,
1570 3078108a Sofia Papagiannaki
                                    self.containers[0], self.obj[0]['name']):
1571 cd6ada1d Sofia Papagiannaki
            self.assert_raises_fault(416, self.test_update_object, 499, 0, True,
1572 cd6ada1d Sofia Papagiannaki
                                     content_length = None)
1573 7067193f Kostas Papadimitriou
1574 7067193f Kostas Papadimitriou
    def test_update_object_out_of_limits(self):
1575 25c3841c Sofia Papagiannaki
        with AssertContentInvariant(self.client.retrieve_object,
1576 3078108a Sofia Papagiannaki
                                    self.containers[0], self.obj[0]['name']):
1577 3078108a Sofia Papagiannaki
            l = len(self.obj[0]['data'])
1578 23028d31 Sofia Papagiannaki
            self.assert_raises_fault(416, self.test_update_object, 0, l+1, True)
1579 7067193f Kostas Papadimitriou
1580 33ffca25 Sofia Papagiannaki
    def test_append(self):
1581 33ffca25 Sofia Papagiannaki
        data = get_random_data(500)
1582 25c3841c Sofia Papagiannaki
        headers = {}
1583 3078108a Sofia Papagiannaki
        self.client.update_object(self.containers[0], self.obj[0]['name'],
1584 25c3841c Sofia Papagiannaki
                                  StringIO(data), content_length=500,
1585 25c3841c Sofia Papagiannaki
                                  content_type='application/octet-stream')
1586 7067193f Kostas Papadimitriou
1587 25c3841c Sofia Papagiannaki
        content = self.client.retrieve_object(self.containers[0],
1588 3078108a Sofia Papagiannaki
                                              self.obj[0]['name'])
1589 3078108a Sofia Papagiannaki
        self.assertEqual(len(content), len(self.obj[0]['data']) + 500)
1590 3078108a Sofia Papagiannaki
        self.assertEqual(content[:-500], self.obj[0]['data'])
1591 7067193f Kostas Papadimitriou
1592 bd8a3026 Sofia Papagiannaki
    def test_update_with_chunked_transfer(self):
1593 25c3841c Sofia Papagiannaki
        data = get_random_data(500)
1594 25c3841c Sofia Papagiannaki
        dl = len(data)
1595 3078108a Sofia Papagiannaki
        fl = len(self.obj[0]['data'])
1596 7067193f Kostas Papadimitriou
1597 25c3841c Sofia Papagiannaki
        self.client.update_object_using_chunks(self.containers[0],
1598 3078108a Sofia Papagiannaki
                                               self.obj[0]['name'],
1599 3078108a Sofia Papagiannaki
                                               StringIO(data),
1600 25c3841c Sofia Papagiannaki
                                               offset=0,
1601 25c3841c Sofia Papagiannaki
                                               content_type='application/octet-stream')
1602 7067193f Kostas Papadimitriou
1603 bd8a3026 Sofia Papagiannaki
        #check modified object
1604 25c3841c Sofia Papagiannaki
        content = self.client.retrieve_object(self.containers[0],
1605 3078108a Sofia Papagiannaki
                                              self.obj[0]['name'])
1606 25c3841c Sofia Papagiannaki
        self.assertEqual(content[0:dl], data)
1607 3078108a Sofia Papagiannaki
        self.assertEqual(content[dl:fl], self.obj[0]['data'][dl:fl])
1608 7067193f Kostas Papadimitriou
1609 a5149fd0 Sofia Papagiannaki
    def test_update_from_other_object(self):
1610 3078108a Sofia Papagiannaki
        c = self.containers[0]
1611 3078108a Sofia Papagiannaki
        src = o_names[0]
1612 3078108a Sofia Papagiannaki
        dest = 'object'
1613 7067193f Kostas Papadimitriou
1614 3078108a Sofia Papagiannaki
        source_data = self.client.retrieve_object(c, src)
1615 3078108a Sofia Papagiannaki
        source_meta = self.client.retrieve_object_metadata(c, src)
1616 fd9f505c Antony Chazapis
        source_hash = self.client.retrieve_object_hashmap(c, src)["hashes"]
1617 7067193f Kostas Papadimitriou
1618 3078108a Sofia Papagiannaki
        #update zero length object
1619 3078108a Sofia Papagiannaki
        self.client.create_zero_length_object(c, dest)
1620 3078108a Sofia Papagiannaki
        source_object = '/%s/%s' % (c, src)
1621 3078108a Sofia Papagiannaki
        self.client.update_from_other_source(c, dest, source_object)
1622 3078108a Sofia Papagiannaki
        dest_data = self.client.retrieve_object(c, src)
1623 3078108a Sofia Papagiannaki
        dest_meta = self.client.retrieve_object_metadata(c, dest)
1624 fd9f505c Antony Chazapis
        dest_hash = self.client.retrieve_object_hashmap(c, src)["hashes"]
1625 3078108a Sofia Papagiannaki
        self.assertEqual(source_data, dest_data)
1626 3078108a Sofia Papagiannaki
        self.assertEqual(source_hash, dest_hash)
1627 7067193f Kostas Papadimitriou
1628 3078108a Sofia Papagiannaki
        #test append
1629 3078108a Sofia Papagiannaki
        self.client.update_from_other_source(c, dest, source_object)
1630 3078108a Sofia Papagiannaki
        content = self.client.retrieve_object(c, dest)
1631 3078108a Sofia Papagiannaki
        self.assertEqual(source_data * 2, content)
1632 7067193f Kostas Papadimitriou
1633 3078108a Sofia Papagiannaki
    def test_update_range_from_other_object(self):
1634 3078108a Sofia Papagiannaki
        c = self.containers[0]
1635 3078108a Sofia Papagiannaki
        dest = 'object'
1636 7067193f Kostas Papadimitriou
1637 3078108a Sofia Papagiannaki
        #test update range
1638 3078108a Sofia Papagiannaki
        src = self.obj[1]['name']
1639 3078108a Sofia Papagiannaki
        src_data = self.client.retrieve_object(c, src)
1640 7067193f Kostas Papadimitriou
1641 3078108a Sofia Papagiannaki
        #update zero length object
1642 3078108a Sofia Papagiannaki
        prev_data = self.upload_random_data(c, dest, length=4*1024*1024+10)['data']
1643 3078108a Sofia Papagiannaki
        source_object = '/%s/%s' % (c, src)
1644 3078108a Sofia Papagiannaki
        first_byte_pos = 4*1024*1024+1
1645 3078108a Sofia Papagiannaki
        last_byte_pos = 4*1024*1024+4
1646 3078108a Sofia Papagiannaki
        range = 'bytes %d-%d/*' %(first_byte_pos, last_byte_pos)
1647 3078108a Sofia Papagiannaki
        self.client.update_from_other_source(c, dest, source_object,
1648 3078108a Sofia Papagiannaki
                                             content_range=range)
1649 3078108a Sofia Papagiannaki
        content = self.client.retrieve_object(c, dest)
1650 3078108a Sofia Papagiannaki
        self.assertEqual(content[:first_byte_pos], prev_data[:first_byte_pos])
1651 3078108a Sofia Papagiannaki
        self.assertEqual(content[first_byte_pos:last_byte_pos+1], src_data[:last_byte_pos - first_byte_pos + 1])
1652 3078108a Sofia Papagiannaki
        self.assertEqual(content[last_byte_pos+1:], prev_data[last_byte_pos+1:])
1653 7067193f Kostas Papadimitriou
1654 3078108a Sofia Papagiannaki
    def test_update_hashes_from_other_object(self):
1655 3078108a Sofia Papagiannaki
        c = self.containers[0]
1656 3078108a Sofia Papagiannaki
        dest = 'object'
1657 7067193f Kostas Papadimitriou
1658 3078108a Sofia Papagiannaki
        #test update range
1659 3078108a Sofia Papagiannaki
        src_data = self.upload_random_data(c, o_names[0], length=1024*1024+10)['data']
1660 7067193f Kostas Papadimitriou
1661 3078108a Sofia Papagiannaki
        #update zero length object
1662 3078108a Sofia Papagiannaki
        prev_data = self.upload_random_data(c, dest, length=5*1024*1024+10)['data']
1663 3078108a Sofia Papagiannaki
        source_object = '/%s/%s' % (c, o_names[0])
1664 3078108a Sofia Papagiannaki
        first_byte_pos = 4*1024*1024
1665 3078108a Sofia Papagiannaki
        last_byte_pos = 5*1024*1024
1666 3078108a Sofia Papagiannaki
        range = 'bytes %d-%d/*' %(first_byte_pos, last_byte_pos)
1667 3078108a Sofia Papagiannaki
        self.client.update_from_other_source(c, dest, source_object,
1668 3078108a Sofia Papagiannaki
                                             content_range=range)
1669 3078108a Sofia Papagiannaki
        content = self.client.retrieve_object(c, dest)
1670 3078108a Sofia Papagiannaki
        self.assertEqual(content[:first_byte_pos], prev_data[:first_byte_pos])
1671 3078108a Sofia Papagiannaki
        self.assertEqual(content[first_byte_pos:last_byte_pos+1], src_data[:last_byte_pos - first_byte_pos + 1])
1672 3078108a Sofia Papagiannaki
        self.assertEqual(content[last_byte_pos+1:], prev_data[last_byte_pos+1:])
1673 7067193f Kostas Papadimitriou
1674 7067193f Kostas Papadimitriou
1675 3078108a Sofia Papagiannaki
    def test_update_zero_length_object(self):
1676 3078108a Sofia Papagiannaki
        c = self.containers[0]
1677 3078108a Sofia Papagiannaki
        o = 'object'
1678 3078108a Sofia Papagiannaki
        other = 'other'
1679 3078108a Sofia Papagiannaki
        zero = self.client.create_zero_length_object(c, o)
1680 7067193f Kostas Papadimitriou
1681 3078108a Sofia Papagiannaki
        data = get_random_data()
1682 3078108a Sofia Papagiannaki
        self.client.update_object(c, o, StringIO(data))
1683 3078108a Sofia Papagiannaki
        self.client.create_object(c, other, StringIO(data))
1684 7067193f Kostas Papadimitriou
1685 3078108a Sofia Papagiannaki
        self.assertEqual(self.client.retrieve_object(c, o),
1686 3078108a Sofia Papagiannaki
                         self.client.retrieve_object(c, other))
1687 7067193f Kostas Papadimitriou
1688 fd9f505c Antony Chazapis
        self.assertEqual(self.client.retrieve_object_hashmap(c, o)["hashes"],
1689 fd9f505c Antony Chazapis
                         self.client.retrieve_object_hashmap(c, other)["hashes"])
1690 7067193f Kostas Papadimitriou
1691 d1e43d6f Sofia Papagiannaki
class ObjectDelete(BaseTestCase):
1692 b09c9aaa Sofia Papagiannaki
    def setUp(self):
1693 b09c9aaa Sofia Papagiannaki
        BaseTestCase.setUp(self)
1694 b09c9aaa Sofia Papagiannaki
        self.containers = ['c1', 'c2']
1695 b09c9aaa Sofia Papagiannaki
        for c in self.containers:
1696 25c3841c Sofia Papagiannaki
            self.client.create_container(c)
1697 23028d31 Sofia Papagiannaki
        self.obj = self.upload_random_data(self.containers[0], o_names[0])
1698 7067193f Kostas Papadimitriou
1699 b09c9aaa Sofia Papagiannaki
    def test_delete(self):
1700 b09c9aaa Sofia Papagiannaki
        #perform delete object
1701 23028d31 Sofia Papagiannaki
        self.client.delete_object(self.containers[0], self.obj['name'])[0]
1702 7067193f Kostas Papadimitriou
1703 b09c9aaa Sofia Papagiannaki
    def test_delete_invalid(self):
1704 23028d31 Sofia Papagiannaki
        #assert item not found
1705 23028d31 Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.delete_object, self.containers[1],
1706 23028d31 Sofia Papagiannaki
                                 self.obj['name'])
1707 b09c9aaa Sofia Papagiannaki
1708 ae75584f Sofia Papagiannaki
class ListSharing(BaseTestCase):
1709 ae75584f Sofia Papagiannaki
    def setUp(self):
1710 ae75584f Sofia Papagiannaki
        BaseTestCase.setUp(self)
1711 8d964102 Sofia Papagiannaki
        for i in range(2):
1712 8d964102 Sofia Papagiannaki
            self.client.create_container('c%s' %i)
1713 ae75584f Sofia Papagiannaki
        self.client.create_container('c')
1714 ae75584f Sofia Papagiannaki
        for i in range(2):
1715 8d964102 Sofia Papagiannaki
            self.upload_random_data('c1', 'o%s' %i)
1716 ae75584f Sofia Papagiannaki
        accounts = OTHER_ACCOUNTS.copy()
1717 ae75584f Sofia Papagiannaki
        self.o1_sharing_with = accounts.popitem()
1718 ae75584f Sofia Papagiannaki
        self.o1_sharing = [self.o1_sharing_with[1]]
1719 8d964102 Sofia Papagiannaki
        self.client.share_object('c1', 'o1', self.o1_sharing, read=True)
1720 7067193f Kostas Papadimitriou
1721 ae75584f Sofia Papagiannaki
        l = []
1722 ae75584f Sofia Papagiannaki
        for i in range(2):
1723 ae75584f Sofia Papagiannaki
            l.append(accounts.popitem())
1724 7067193f Kostas Papadimitriou
1725 8d964102 Sofia Papagiannaki
    def test_list_other_shared(self):
1726 43cc6f76 Sofia Papagiannaki
        self.other = Pithos_Client(get_url(),
1727 ae75584f Sofia Papagiannaki
                              self.o1_sharing_with[0],
1728 43cc6f76 Sofia Papagiannaki
                              self.o1_sharing_with[1])
1729 a607181b Sofia Papagiannaki
        self.assertTrue(get_user() in self.other.list_shared_by_others())
1730 7067193f Kostas Papadimitriou
1731 8d964102 Sofia Papagiannaki
    def test_list_my_shared(self):
1732 8d964102 Sofia Papagiannaki
        my_shared_containers = self.client.list_containers(shared=True)
1733 8d964102 Sofia Papagiannaki
        self.assertTrue('c1' in my_shared_containers)
1734 8d964102 Sofia Papagiannaki
        self.assertTrue('c2' not in my_shared_containers)
1735 7067193f Kostas Papadimitriou
1736 8d964102 Sofia Papagiannaki
        my_shared_objects = self.client.list_objects('c1', shared=True)
1737 8d964102 Sofia Papagiannaki
        self.assertTrue('o1' in my_shared_objects)
1738 8d964102 Sofia Papagiannaki
        self.assertTrue('o2' not in my_shared_objects)
1739 7067193f Kostas Papadimitriou
1740 2535deff Sofia Papagiannaki
class List(BaseTestCase):
1741 2535deff Sofia Papagiannaki
    def setUp(self):
1742 2535deff Sofia Papagiannaki
        BaseTestCase.setUp(self)
1743 2535deff Sofia Papagiannaki
        for i in range(1, 5):
1744 2535deff Sofia Papagiannaki
            c = 'c%s' % i
1745 2535deff Sofia Papagiannaki
            self.client.create_container(c)
1746 2535deff Sofia Papagiannaki
            for j in range(1, 3):
1747 2535deff Sofia Papagiannaki
                o = 'o%s' % j
1748 2535deff Sofia Papagiannaki
                self.upload_random_data(c, o)
1749 2535deff Sofia Papagiannaki
            if i < 3:
1750 2535deff Sofia Papagiannaki
                self.client.share_object(c, 'o1', ['papagian'], read=True)
1751 2535deff Sofia Papagiannaki
            if i%2 != 0:
1752 2535deff Sofia Papagiannaki
                self.client.publish_object(c, 'o2')
1753 2535deff Sofia Papagiannaki
    
1754 2535deff Sofia Papagiannaki
    def test_shared_public(self):
1755 e53e90da Sofia Papagiannaki
        func, kwargs = self.client.list_containers, {'shared':True}
1756 e53e90da Sofia Papagiannaki
        l = func(**kwargs)
1757 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['c1', 'c2'])
1758 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(format='json', **kwargs)])
1759 2535deff Sofia Papagiannaki
        
1760 e53e90da Sofia Papagiannaki
        func, kwargs = self.client.list_containers, {'public':True}
1761 e53e90da Sofia Papagiannaki
        l = func(**kwargs)
1762 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['c1', 'c3'])
1763 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(format='json', **kwargs)])
1764 2535deff Sofia Papagiannaki
        
1765 e53e90da Sofia Papagiannaki
        func, kwargs = self.client.list_containers, {'shared':True, 'public':True}
1766 e53e90da Sofia Papagiannaki
        l = func(**kwargs)
1767 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['c1', 'c2', 'c3'])
1768 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(format='json', **kwargs)])
1769 2535deff Sofia Papagiannaki
        
1770 2535deff Sofia Papagiannaki
        
1771 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c1'], {'shared':True}
1772 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1773 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['o1'])
1774 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(*args, format='json', **kwargs)])
1775 e53e90da Sofia Papagiannaki
        
1776 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c1'], {'public':True}
1777 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1778 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['o2'])
1779 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(*args, format='json', **kwargs)])
1780 e53e90da Sofia Papagiannaki
        
1781 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c1'], {'shared':True, 'public':True}
1782 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1783 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['o1', 'o2'])
1784 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(*args, format='json', **kwargs)])
1785 e53e90da Sofia Papagiannaki
        
1786 e53e90da Sofia Papagiannaki
        
1787 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c2'], {'shared':True}
1788 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1789 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['o1'])
1790 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(*args, format='json', **kwargs)])
1791 e53e90da Sofia Papagiannaki
        
1792 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c2'], {'public':True}
1793 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1794 e53e90da Sofia Papagiannaki
        self.assertEqual(l, '')
1795 e53e90da Sofia Papagiannaki
        self.assertEqual([], func(*args, format='json', **kwargs))
1796 e53e90da Sofia Papagiannaki
        
1797 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c2'], {'shared':True, 'public':True}
1798 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1799 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['o1'])
1800 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(*args, format='json', **kwargs)])
1801 e53e90da Sofia Papagiannaki
        
1802 e53e90da Sofia Papagiannaki
        
1803 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c3'], {'shared':True}
1804 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1805 e53e90da Sofia Papagiannaki
        self.assertEqual(l, '')
1806 e53e90da Sofia Papagiannaki
        self.assertEqual([], func(*args, format='json', **kwargs))
1807 e53e90da Sofia Papagiannaki
        
1808 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c3'], {'public':True}
1809 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1810 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['o2'])
1811 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(*args, format='json', **kwargs)])
1812 e53e90da Sofia Papagiannaki
        
1813 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c3'], {'shared':True, 'public':True}
1814 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1815 e53e90da Sofia Papagiannaki
        self.assertEqual(l, ['o2'])
1816 e53e90da Sofia Papagiannaki
        self.assertEqual(l, [e['name'] for e in func(*args, format='json', **kwargs)])
1817 e53e90da Sofia Papagiannaki
        
1818 e53e90da Sofia Papagiannaki
        
1819 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c4'], {'shared':True}
1820 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1821 e53e90da Sofia Papagiannaki
        self.assertEqual(l, '')
1822 e53e90da Sofia Papagiannaki
        self.assertEqual([], func(*args, format='json', **kwargs))
1823 e53e90da Sofia Papagiannaki
        
1824 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c4'], {'public':True}
1825 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1826 e53e90da Sofia Papagiannaki
        self.assertEqual(l, '')
1827 e53e90da Sofia Papagiannaki
        self.assertEqual([], func(*args, format='json', **kwargs))
1828 e53e90da Sofia Papagiannaki
        
1829 e53e90da Sofia Papagiannaki
        func, args, kwargs = self.client.list_objects, ['c4'], {'shared':True, 'public':True}
1830 e53e90da Sofia Papagiannaki
        l = func(*args, **kwargs)
1831 e53e90da Sofia Papagiannaki
        self.assertEqual(l, '')
1832 e53e90da Sofia Papagiannaki
        self.assertEqual([], func(*args, format='json', **kwargs))
1833 2535deff Sofia Papagiannaki
1834 ae75584f Sofia Papagiannaki
class TestGreek(BaseTestCase):
1835 ae75584f Sofia Papagiannaki
    def test_create_container(self):
1836 ae75584f Sofia Papagiannaki
        self.client.create_container('φάκελος')
1837 ae75584f Sofia Papagiannaki
        self.assert_container_exists('φάκελος')
1838 7067193f Kostas Papadimitriou
1839 e7b51248 Sofia Papagiannaki
        self.assertTrue('φάκελος' in self.client.list_containers())
1840 7067193f Kostas Papadimitriou
1841 ae75584f Sofia Papagiannaki
    def test_create_object(self):
1842 ae75584f Sofia Papagiannaki
        self.client.create_container('φάκελος')
1843 ae75584f Sofia Papagiannaki
        self.upload_random_data('φάκελος', 'αντικείμενο')
1844 7067193f Kostas Papadimitriou
1845 ae75584f Sofia Papagiannaki
        self.assert_object_exists('φάκελος', 'αντικείμενο')
1846 e7b51248 Sofia Papagiannaki
        self.assertTrue('αντικείμενο' in self.client.list_objects('φάκελος'))
1847 7067193f Kostas Papadimitriou
1848 ae75584f Sofia Papagiannaki
    def test_copy_object(self):
1849 e7b51248 Sofia Papagiannaki
        src_container = 'φάκελος'
1850 e7b51248 Sofia Papagiannaki
        src_object = 'αντικείμενο'
1851 e7b51248 Sofia Papagiannaki
        dest_container = 'αντίγραφα'
1852 e7b51248 Sofia Papagiannaki
        dest_object = 'ασφαλές-αντίγραφο'
1853 7067193f Kostas Papadimitriou
1854 e7b51248 Sofia Papagiannaki
        self.client.create_container(src_container)
1855 e7b51248 Sofia Papagiannaki
        self.upload_random_data(src_container, src_object)
1856 7067193f Kostas Papadimitriou
1857 e7b51248 Sofia Papagiannaki
        self.client.create_container(dest_container)
1858 e7b51248 Sofia Papagiannaki
        self.client.copy_object(src_container, src_object, dest_container,
1859 e7b51248 Sofia Papagiannaki
                                dest_object)
1860 7067193f Kostas Papadimitriou
1861 e7b51248 Sofia Papagiannaki
        self.assert_object_exists(src_container, src_object)
1862 e7b51248 Sofia Papagiannaki
        self.assert_object_exists(dest_container, dest_object)
1863 e7b51248 Sofia Papagiannaki
        self.assertTrue(dest_object in self.client.list_objects(dest_container))
1864 7067193f Kostas Papadimitriou
1865 ae75584f Sofia Papagiannaki
    def test_move_object(self):
1866 e7b51248 Sofia Papagiannaki
        src_container = 'φάκελος'
1867 e7b51248 Sofia Papagiannaki
        src_object = 'αντικείμενο'
1868 e7b51248 Sofia Papagiannaki
        dest_container = 'αντίγραφα'
1869 e7b51248 Sofia Papagiannaki
        dest_object = 'ασφαλές-αντίγραφο'
1870 7067193f Kostas Papadimitriou
1871 e7b51248 Sofia Papagiannaki
        self.client.create_container(src_container)
1872 e7b51248 Sofia Papagiannaki
        self.upload_random_data(src_container, src_object)
1873 7067193f Kostas Papadimitriou
1874 e7b51248 Sofia Papagiannaki
        self.client.create_container(dest_container)
1875 e7b51248 Sofia Papagiannaki
        self.client.move_object(src_container, src_object, dest_container,
1876 e7b51248 Sofia Papagiannaki
                                dest_object)
1877 7067193f Kostas Papadimitriou
1878 e7b51248 Sofia Papagiannaki
        self.assert_object_not_exists(src_container, src_object)
1879 e7b51248 Sofia Papagiannaki
        self.assert_object_exists(dest_container, dest_object)
1880 e7b51248 Sofia Papagiannaki
        self.assertTrue(dest_object in self.client.list_objects(dest_container))
1881 7067193f Kostas Papadimitriou
1882 ae75584f Sofia Papagiannaki
    def test_delete_object(self):
1883 e7b51248 Sofia Papagiannaki
        self.client.create_container('φάκελος')
1884 e7b51248 Sofia Papagiannaki
        self.upload_random_data('φάκελος', 'αντικείμενο')
1885 e7b51248 Sofia Papagiannaki
        self.assert_object_exists('φάκελος', 'αντικείμενο')
1886 7067193f Kostas Papadimitriou
1887 e7b51248 Sofia Papagiannaki
        self.client.delete_object('φάκελος', 'αντικείμενο')
1888 e7b51248 Sofia Papagiannaki
        self.assert_object_not_exists('φάκελος', 'αντικείμενο')
1889 e7b51248 Sofia Papagiannaki
        self.assertTrue('αντικείμενο' not in self.client.list_objects('φάκελος'))
1890 7067193f Kostas Papadimitriou
1891 e7b51248 Sofia Papagiannaki
    def test_delete_container(self):
1892 e7b51248 Sofia Papagiannaki
        self.client.create_container('φάκελος')
1893 e7b51248 Sofia Papagiannaki
        self.assert_container_exists('φάκελος')
1894 7067193f Kostas Papadimitriou
1895 e7b51248 Sofia Papagiannaki
        self.client.delete_container('φάκελος')
1896 e7b51248 Sofia Papagiannaki
        self.assert_container_not_exists('φάκελος')
1897 e7b51248 Sofia Papagiannaki
        self.assertTrue('φάκελος' not in self.client.list_containers())
1898 e7b51248 Sofia Papagiannaki
1899 ae75584f Sofia Papagiannaki
    def test_account_meta(self):
1900 e7b51248 Sofia Papagiannaki
        meta = {'ποιότητα':'ΑΑΑ'}
1901 e7b51248 Sofia Papagiannaki
        self.client.update_account_metadata(**meta)
1902 e7b51248 Sofia Papagiannaki
        meta = self.client.retrieve_account_metadata(restricted=True)
1903 e7b51248 Sofia Papagiannaki
        self.assertTrue('ποιότητα' in meta.keys())
1904 e7b51248 Sofia Papagiannaki
        self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
1905 7067193f Kostas Papadimitriou
1906 ae75584f Sofia Papagiannaki
    def test_container_meta(self):
1907 e7b51248 Sofia Papagiannaki
        meta = {'ποιότητα':'ΑΑΑ'}
1908 a4897037 Kostas Papadimitriou
        self.client.create_container('φάκελος', meta=meta)
1909 7067193f Kostas Papadimitriou
1910 e7b51248 Sofia Papagiannaki
        meta = self.client.retrieve_container_metadata('φάκελος', restricted=True)
1911 e7b51248 Sofia Papagiannaki
        self.assertTrue('ποιότητα' in meta.keys())
1912 e7b51248 Sofia Papagiannaki
        self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
1913 7067193f Kostas Papadimitriou
1914 e7b51248 Sofia Papagiannaki
    def test_object_meta(self):
1915 e7b51248 Sofia Papagiannaki
        self.client.create_container('φάκελος')
1916 e7b51248 Sofia Papagiannaki
        meta = {'ποιότητα':'ΑΑΑ'}
1917 e7b51248 Sofia Papagiannaki
        self.upload_random_data('φάκελος', 'αντικείμενο', **meta)
1918 7067193f Kostas Papadimitriou
1919 e7b51248 Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata('φάκελος', 'αντικείμενο',
1920 e7b51248 Sofia Papagiannaki
                                                    restricted=True)
1921 e7b51248 Sofia Papagiannaki
        self.assertTrue('ποιότητα' in meta.keys())
1922 7067193f Kostas Papadimitriou
        self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
1923 7067193f Kostas Papadimitriou
1924 ae75584f Sofia Papagiannaki
    def test_list_meta_filtering(self):
1925 e7b51248 Sofia Papagiannaki
        self.client.create_container('φάκελος')
1926 e7b51248 Sofia Papagiannaki
        meta = {'ποιότητα':'ΑΑΑ'}
1927 e7b51248 Sofia Papagiannaki
        self.upload_random_data('φάκελος', 'ο1', **meta)
1928 e7b51248 Sofia Papagiannaki
        self.upload_random_data('φάκελος', 'ο2')
1929 e7b51248 Sofia Papagiannaki
        self.upload_random_data('φάκελος', 'ο3')
1930 7067193f Kostas Papadimitriou
1931 e7b51248 Sofia Papagiannaki
        meta = {'ποσότητα':'μεγάλη'}
1932 e7b51248 Sofia Papagiannaki
        self.client.update_object_metadata('φάκελος', 'ο2', **meta)
1933 e7b51248 Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='ποιότητα, ποσότητα')
1934 3d13f97a Sofia Papagiannaki
        self.assertEquals(objects, ['ο1', 'ο2'])
1935 7067193f Kostas Papadimitriou
1936 3d13f97a Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='!ποιότητα')
1937 3d13f97a Sofia Papagiannaki
        self.assertEquals(objects, ['ο2', 'ο3'])
1938 7067193f Kostas Papadimitriou
1939 3d13f97a Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='!ποιότητα, !ποσότητα')
1940 3d13f97a Sofia Papagiannaki
        self.assertEquals(objects, ['ο3'])
1941 7067193f Kostas Papadimitriou
1942 3d13f97a Sofia Papagiannaki
        meta = {'ποιότητα':'ΑΒ'}
1943 3d13f97a Sofia Papagiannaki
        self.client.update_object_metadata('φάκελος', 'ο2', **meta)
1944 f897bea9 Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='ποιότητα=ΑΑΑ')
1945 3d13f97a Sofia Papagiannaki
        self.assertEquals(objects, ['ο1'])
1946 3d13f97a Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='ποιότητα!=ΑΑΑ')
1947 3d13f97a Sofia Papagiannaki
        self.assertEquals(objects, ['ο2'])
1948 7067193f Kostas Papadimitriou
1949 3d13f97a Sofia Papagiannaki
        meta = {'έτος':'2011'}
1950 3d13f97a Sofia Papagiannaki
        self.client.update_object_metadata('φάκελος', 'ο3', **meta)
1951 3d13f97a Sofia Papagiannaki
        meta = {'έτος':'2012'}
1952 3d13f97a Sofia Papagiannaki
        self.client.update_object_metadata('φάκελος', 'ο2', **meta)
1953 3d13f97a Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='έτος<2012')
1954 f897bea9 Sofia Papagiannaki
        self.assertEquals(objects, ['ο3'])
1955 3d13f97a Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='έτος<=2012')
1956 f897bea9 Sofia Papagiannaki
        self.assertEquals(objects, ['ο2', 'ο3'])
1957 f897bea9 Sofia Papagiannaki
        objects = self.client.list_objects('φάκελος', meta='έτος<2012,έτος!=2011')
1958 f897bea9 Sofia Papagiannaki
        self.assertEquals(objects, '')
1959 7067193f Kostas Papadimitriou
1960 ae75584f Sofia Papagiannaki
    def test_groups(self):
1961 e7b51248 Sofia Papagiannaki
        #create a group
1962 95e92490 Sofia Papagiannaki
        groups = {'σεφς':'chazapis,διογένης'}
1963 e7b51248 Sofia Papagiannaki
        self.client.set_account_groups(**groups)
1964 e7b51248 Sofia Papagiannaki
        groups.update(self.initial_groups)
1965 e7b51248 Sofia Papagiannaki
        self.assertEqual(groups['σεφς'],
1966 e7b51248 Sofia Papagiannaki
                         self.client.retrieve_account_groups()['σεφς'])
1967 7067193f Kostas Papadimitriou
1968 95e92490 Sofia Papagiannaki
        #check read access
1969 95e92490 Sofia Papagiannaki
        self.client.create_container('φάκελος')
1970 95e92490 Sofia Papagiannaki
        o = self.upload_random_data('φάκελος', 'ο1')
1971 a607181b Sofia Papagiannaki
        self.client.share_object('φάκελος', 'ο1', ['%s:σεφς' % get_user()])
1972 a06e2ad6 Sofia Papagiannaki
        chef = Pithos_Client(get_url(),
1973 95e92490 Sofia Papagiannaki
                            '0009',
1974 96738a78 Sofia Papagiannaki
                            'διογένης')
1975 297513ba Antony Chazapis
        self.assert_not_raises_fault(403, chef.retrieve_object_metadata,
1976 a5149fd0 Sofia Papagiannaki
                                     'φάκελος', 'ο1', account=get_user())
1977 7067193f Kostas Papadimitriou
1978 95e92490 Sofia Papagiannaki
        #check write access
1979 95e92490 Sofia Papagiannaki
        self.client.share_object('φάκελος', 'ο1', ['διογένης'], read=False)
1980 95e92490 Sofia Papagiannaki
        new_data = get_random_data()
1981 297513ba Antony Chazapis
        self.assert_not_raises_fault(403, chef.update_object,
1982 95e92490 Sofia Papagiannaki
                                     'φάκελος', 'ο1', StringIO(new_data),
1983 a5149fd0 Sofia Papagiannaki
                                     account=get_user())
1984 7067193f Kostas Papadimitriou
1985 95e92490 Sofia Papagiannaki
        server_data = self.client.retrieve_object('φάκελος', 'ο1')
1986 95e92490 Sofia Papagiannaki
        self.assertEqual(server_data[:len(o['data'])], o['data'])
1987 95e92490 Sofia Papagiannaki
        self.assertEqual(server_data[len(o['data']):], new_data)
1988 7067193f Kostas Papadimitriou
1989 95e92490 Sofia Papagiannaki
    def test_manifestation(self):
1990 95e92490 Sofia Papagiannaki
        self.client.create_container('κουβάς')
1991 95e92490 Sofia Papagiannaki
        prefix = 'μέρη/'
1992 95e92490 Sofia Papagiannaki
        data = ''
1993 95e92490 Sofia Papagiannaki
        for i in range(5):
1994 95e92490 Sofia Papagiannaki
            part = '%s%d' %(prefix, i)
1995 95e92490 Sofia Papagiannaki
            o = self.upload_random_data('κουβάς', part)
1996 95e92490 Sofia Papagiannaki
            data += o['data']
1997 7067193f Kostas Papadimitriou
1998 95e92490 Sofia Papagiannaki
        self.client.create_container('φάκελος')
1999 95e92490 Sofia Papagiannaki
        manifest = '%s/%s' %('κουβάς', prefix)
2000 95e92490 Sofia Papagiannaki
        self.client.create_manifestation('φάκελος', 'άπαντα', manifest)
2001 7067193f Kostas Papadimitriou
2002 95e92490 Sofia Papagiannaki
        self.assert_object_exists('φάκελος', 'άπαντα')
2003 95e92490 Sofia Papagiannaki
        self.assertEqual(data, self.client.retrieve_object('φάκελος',
2004 95e92490 Sofia Papagiannaki
                                                           'άπαντα'))
2005 7067193f Kostas Papadimitriou
2006 95e92490 Sofia Papagiannaki
        #wrong manifestation
2007 95e92490 Sofia Papagiannaki
        self.client.create_manifestation('φάκελος', 'άπαντα', 'κουβάς/άκυρο')
2008 95e92490 Sofia Papagiannaki
        self.assertEqual('', self.client.retrieve_object('φάκελος', 'άπαντα'))
2009 7067193f Kostas Papadimitriou
2010 952f4da1 Sofia Papagiannaki
    def test_update_from_another_object(self):
2011 a5149fd0 Sofia Papagiannaki
        self.client.create_container('κουβάς')
2012 a5149fd0 Sofia Papagiannaki
        src_data = self.upload_random_data('κουβάς', 'πηγή')['data']
2013 a5149fd0 Sofia Papagiannaki
        initial_data = self.upload_random_data('κουβάς', 'νέο')['data']
2014 a5149fd0 Sofia Papagiannaki
        source_object = '/%s/%s' % ('κουβάς', 'πηγή')
2015 a5149fd0 Sofia Papagiannaki
        self.client.update_from_other_source('κουβάς', 'νέο', source_object)
2016 7067193f Kostas Papadimitriou
2017 a5149fd0 Sofia Papagiannaki
        self.assertEqual(
2018 a5149fd0 Sofia Papagiannaki
            self.client.retrieve_object('κουβάς', 'νέο'),
2019 a5149fd0 Sofia Papagiannaki
            '%s%s' % (initial_data, self.client.retrieve_object('κουβάς', 'πηγή')))
2020 952f4da1 Sofia Papagiannaki
2021 95e92490 Sofia Papagiannaki
class TestPermissions(BaseTestCase):
2022 95e92490 Sofia Papagiannaki
    def setUp(self):
2023 95e92490 Sofia Papagiannaki
        BaseTestCase.setUp(self)
2024 7067193f Kostas Papadimitriou
2025 95e92490 Sofia Papagiannaki
        #create a group
2026 ad7e4bea Sofia Papagiannaki
        self.authorized = ['chazapis', 'verigak', 'gtsouk']
2027 95e92490 Sofia Papagiannaki
        groups = {'pithosdev':','.join(self.authorized)}
2028 95e92490 Sofia Papagiannaki
        self.client.set_account_groups(**groups)
2029 7067193f Kostas Papadimitriou
2030 236b1575 Sofia Papagiannaki
        self.container = 'c'
2031 236b1575 Sofia Papagiannaki
        self.object = 'o'
2032 236b1575 Sofia Papagiannaki
        self.client.create_container(self.container)
2033 236b1575 Sofia Papagiannaki
        self.upload_random_data(self.container, self.object)
2034 236b1575 Sofia Papagiannaki
        self.upload_random_data(self.container, self.object+'/')
2035 236b1575 Sofia Papagiannaki
        self.upload_random_data(self.container, self.object+'/a')
2036 236b1575 Sofia Papagiannaki
        self.upload_random_data(self.container, self.object+'a')
2037 236b1575 Sofia Papagiannaki
        self.upload_random_data(self.container, self.object+'a/')
2038 236b1575 Sofia Papagiannaki
        self.dir_content_types = ('application/directory', 'application/folder')
2039 7067193f Kostas Papadimitriou
2040 236b1575 Sofia Papagiannaki
    def assert_read(self, authorized=[], any=False, depth=0):
2041 95e92490 Sofia Papagiannaki
        for token, account in OTHER_ACCOUNTS.items():
2042 96738a78 Sofia Papagiannaki
            cl = Pithos_Client(get_url(), token, account)
2043 ad7e4bea Sofia Papagiannaki
            if account in authorized or any:
2044 297513ba Antony Chazapis
                self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
2045 236b1575 Sofia Papagiannaki
                                             self.container, self.object,
2046 236b1575 Sofia Papagiannaki
                                             account=get_user())
2047 95e92490 Sofia Papagiannaki
            else:
2048 297513ba Antony Chazapis
                self.assert_raises_fault(403, cl.retrieve_object_metadata,
2049 236b1575 Sofia Papagiannaki
                                         self.container, self.object,
2050 236b1575 Sofia Papagiannaki
                                         account=get_user())
2051 7067193f Kostas Papadimitriou
2052 8d964102 Sofia Papagiannaki
        #check inheritance
2053 236b1575 Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata(self.container, self.object)
2054 236b1575 Sofia Papagiannaki
        type = meta['content-type']
2055 236b1575 Sofia Papagiannaki
        derivatives = self.client.list_objects(self.container, prefix=self.object)
2056 236b1575 Sofia Papagiannaki
        #exclude the self.object
2057 236b1575 Sofia Papagiannaki
        del derivatives[derivatives.index(self.object)]
2058 236b1575 Sofia Papagiannaki
        for o in derivatives:
2059 236b1575 Sofia Papagiannaki
            for token, account in OTHER_ACCOUNTS.items():
2060 236b1575 Sofia Papagiannaki
                cl = Pithos_Client(get_url(), token, account)
2061 236b1575 Sofia Papagiannaki
                prefix = self.object if self.object.endswith('/') else self.object+'/'
2062 236b1575 Sofia Papagiannaki
                if (account in authorized or any) and \
2063 236b1575 Sofia Papagiannaki
                (type in self.dir_content_types) and \
2064 236b1575 Sofia Papagiannaki
                o.startswith(prefix):
2065 236b1575 Sofia Papagiannaki
                    self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
2066 236b1575 Sofia Papagiannaki
                                             self.container, o, account=get_user())
2067 236b1575 Sofia Papagiannaki
                else:
2068 236b1575 Sofia Papagiannaki
                    self.assert_raises_fault(403, cl.retrieve_object_metadata,
2069 236b1575 Sofia Papagiannaki
                                         self.container, o, account=get_user())
2070 7067193f Kostas Papadimitriou
2071 236b1575 Sofia Papagiannaki
    def assert_write(self, authorized=[], any=False):
2072 236b1575 Sofia Papagiannaki
        o_data = self.client.retrieve_object(self.container, self.object)
2073 8d964102 Sofia Papagiannaki
        for token, account in OTHER_ACCOUNTS.items():
2074 96738a78 Sofia Papagiannaki
            cl = Pithos_Client(get_url(), token, account)
2075 86186593 Sofia Papagiannaki
            new_data = get_random_data()
2076 ad7e4bea Sofia Papagiannaki
            if account in authorized or any:
2077 ad7e4bea Sofia Papagiannaki
                # test write access
2078 297513ba Antony Chazapis
                self.assert_not_raises_fault(403, cl.update_object,
2079 236b1575 Sofia Papagiannaki
                                             self.container, self.object, StringIO(new_data),
2080 86186593 Sofia Papagiannaki
                                             account=get_user())
2081 ad7e4bea Sofia Papagiannaki
                try:
2082 ad7e4bea Sofia Papagiannaki
                    # test read access
2083 236b1575 Sofia Papagiannaki
                    server_data = cl.retrieve_object(self.container, self.object, account=get_user())
2084 ad7e4bea Sofia Papagiannaki
                    self.assertEqual(o_data, server_data[:len(o_data)])
2085 ad7e4bea Sofia Papagiannaki
                    self.assertEqual(new_data, server_data[len(o_data):])
2086 ad7e4bea Sofia Papagiannaki
                    o_data = server_data
2087 ad7e4bea Sofia Papagiannaki
                except Fault, f:
2088 297513ba Antony Chazapis
                    self.failIf(f.status == 403)
2089 86186593 Sofia Papagiannaki
            else:
2090 297513ba Antony Chazapis
                self.assert_raises_fault(403, cl.update_object,
2091 236b1575 Sofia Papagiannaki
                                             self.container, self.object, StringIO(new_data),
2092 86186593 Sofia Papagiannaki
                                             account=get_user())
2093 8d964102 Sofia Papagiannaki
        #check inheritance
2094 236b1575 Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata(self.container, self.object)
2095 236b1575 Sofia Papagiannaki
        type = meta['content-type']
2096 236b1575 Sofia Papagiannaki
        derivatives = self.client.list_objects(self.container, prefix=self.object)
2097 236b1575 Sofia Papagiannaki
        #exclude the object
2098 236b1575 Sofia Papagiannaki
        del derivatives[derivatives.index(self.object)]
2099 236b1575 Sofia Papagiannaki
        for o in derivatives:
2100 236b1575 Sofia Papagiannaki
            for token, account in OTHER_ACCOUNTS.items():
2101 236b1575 Sofia Papagiannaki
                prefix = self.object if self.object.endswith('/') else self.object+'/'
2102 236b1575 Sofia Papagiannaki
                cl = Pithos_Client(get_url(), token, account)
2103 236b1575 Sofia Papagiannaki
                new_data = get_random_data()
2104 236b1575 Sofia Papagiannaki
                if (account in authorized or any) and \
2105 236b1575 Sofia Papagiannaki
                (type in self.dir_content_types) and \
2106 236b1575 Sofia Papagiannaki
                o.startswith(prefix):
2107 236b1575 Sofia Papagiannaki
                    # test write access
2108 236b1575 Sofia Papagiannaki
                    self.assert_not_raises_fault(403, cl.update_object,
2109 236b1575 Sofia Papagiannaki
                                                 self.container, o,
2110 236b1575 Sofia Papagiannaki
                                                 StringIO(new_data),
2111 236b1575 Sofia Papagiannaki
                                                 account=get_user())
2112 236b1575 Sofia Papagiannaki
                    try:
2113 236b1575 Sofia Papagiannaki
                        server_data = cl.retrieve_object(self.container, o, account=get_user())
2114 236b1575 Sofia Papagiannaki
                        self.assertEqual(new_data, server_data[-len(new_data):])
2115 236b1575 Sofia Papagiannaki
                    except Fault, f:
2116 236b1575 Sofia Papagiannaki
                        self.failIf(f.status == 403)
2117 236b1575 Sofia Papagiannaki
                else:
2118 236b1575 Sofia Papagiannaki
                    self.assert_raises_fault(403, cl.update_object,
2119 236b1575 Sofia Papagiannaki
                                                 self.container, o,
2120 236b1575 Sofia Papagiannaki
                                                 StringIO(new_data),
2121 236b1575 Sofia Papagiannaki
                                                 account=get_user())
2122 7067193f Kostas Papadimitriou
2123 ad7e4bea Sofia Papagiannaki
    def test_group_read(self):
2124 236b1575 Sofia Papagiannaki
        self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()])
2125 ad7e4bea Sofia Papagiannaki
        self.assert_read(authorized=self.authorized)
2126 7067193f Kostas Papadimitriou
2127 ad7e4bea Sofia Papagiannaki
    def test_read_many(self):
2128 236b1575 Sofia Papagiannaki
        self.client.share_object(self.container, self.object, self.authorized)
2129 ad7e4bea Sofia Papagiannaki
        self.assert_read(authorized=self.authorized)
2130 7067193f Kostas Papadimitriou
2131 ad7e4bea Sofia Papagiannaki
    def test_read_by_everyone(self):
2132 236b1575 Sofia Papagiannaki
        self.client.share_object(self.container, self.object, ['*'])
2133 ad7e4bea Sofia Papagiannaki
        self.assert_read(any=True)
2134 7067193f Kostas Papadimitriou
2135 236b1575 Sofia Papagiannaki
    def test_read_directory(self):
2136 236b1575 Sofia Papagiannaki
        for type in self.dir_content_types:
2137 236b1575 Sofia Papagiannaki
            #change content type
2138 236b1575 Sofia Papagiannaki
            self.client.move_object(self.container, self.object, self.container, self.object, content_type=type)
2139 236b1575 Sofia Papagiannaki
            self.client.share_object(self.container, self.object, ['*'])
2140 236b1575 Sofia Papagiannaki
            self.assert_read(any=True)
2141 236b1575 Sofia Papagiannaki
            self.client.share_object(self.container, self.object, self.authorized)
2142 236b1575 Sofia Papagiannaki
            self.assert_read(authorized=self.authorized)
2143 236b1575 Sofia Papagiannaki
            self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()])
2144 236b1575 Sofia Papagiannaki
            self.assert_read(authorized=self.authorized)
2145 7067193f Kostas Papadimitriou
2146 ad7e4bea Sofia Papagiannaki
    def test_group_write(self):
2147 236b1575 Sofia Papagiannaki
        self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()], read=False)
2148 236b1575 Sofia Papagiannaki
        self.assert_write(authorized=self.authorized)
2149 7067193f Kostas Papadimitriou
2150 ad7e4bea Sofia Papagiannaki
    def test_write_many(self):
2151 236b1575 Sofia Papagiannaki
        self.client.share_object(self.container, self.object, self.authorized, read=False)
2152 236b1575 Sofia Papagiannaki
        self.assert_write(authorized=self.authorized)
2153 7067193f Kostas Papadimitriou
2154 ad7e4bea Sofia Papagiannaki
    def test_write_by_everyone(self):
2155 236b1575 Sofia Papagiannaki
        self.client.share_object(self.container, self.object, ['*'], read=False)
2156 236b1575 Sofia Papagiannaki
        self.assert_write(any=True)
2157 7067193f Kostas Papadimitriou
2158 236b1575 Sofia Papagiannaki
    def test_write_directory(self):
2159 236b1575 Sofia Papagiannaki
        dir_content_types = ('application/directory', 'application/foler')
2160 236b1575 Sofia Papagiannaki
        for type in dir_content_types:
2161 236b1575 Sofia Papagiannaki
            #change content type
2162 236b1575 Sofia Papagiannaki
            self.client.move_object(self.container, self.object, self.container, self.object, content_type='application/folder')
2163 236b1575 Sofia Papagiannaki
            self.client.share_object(self.container, self.object, ['*'], read=False)
2164 236b1575 Sofia Papagiannaki
            self.assert_write(any=True)
2165 236b1575 Sofia Papagiannaki
            self.client.share_object(self.container, self.object, self.authorized, read=False)
2166 236b1575 Sofia Papagiannaki
            self.assert_write(authorized=self.authorized)
2167 236b1575 Sofia Papagiannaki
            self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()], read=False)
2168 236b1575 Sofia Papagiannaki
            self.assert_write(authorized=self.authorized)
2169 7067193f Kostas Papadimitriou
2170 236b1575 Sofia Papagiannaki
    def test_shared_listing(self):
2171 236b1575 Sofia Papagiannaki
        self.client.share_object(self.container, self.object, self.authorized)
2172 7067193f Kostas Papadimitriou
2173 236b1575 Sofia Papagiannaki
        my_shared_containers = self.client.list_containers(shared=True)
2174 236b1575 Sofia Papagiannaki
        self.assertEqual(['c'], my_shared_containers)
2175 236b1575 Sofia Papagiannaki
        my_shared_objects = self.client.list_objects('c', shared=True)
2176 236b1575 Sofia Papagiannaki
        self.assertEqual(['o'], my_shared_objects)
2177 7067193f Kostas Papadimitriou
2178 236b1575 Sofia Papagiannaki
        dir_content_types = ('application/directory', 'application/foler')
2179 236b1575 Sofia Papagiannaki
        for type in dir_content_types:
2180 236b1575 Sofia Papagiannaki
            #change content type
2181 236b1575 Sofia Papagiannaki
            self.client.move_object(self.container, self.object, self.container, self.object, content_type='application/folder')
2182 236b1575 Sofia Papagiannaki
            my_shared_objects = self.client.list_objects('c', shared=True)
2183 236b1575 Sofia Papagiannaki
            self.assertEqual(['o', 'o/', 'o/a'], my_shared_objects)
2184 7067193f Kostas Papadimitriou
2185 236b1575 Sofia Papagiannaki
        for token, account in OTHER_ACCOUNTS.items():
2186 236b1575 Sofia Papagiannaki
            if account in self.authorized:
2187 236b1575 Sofia Papagiannaki
                self.other = Pithos_Client(get_url(), token, account)
2188 236b1575 Sofia Papagiannaki
                self.assertTrue(get_user() in self.other.list_shared_by_others())
2189 7067193f Kostas Papadimitriou
2190 ad7e4bea Sofia Papagiannaki
class TestPublish(BaseTestCase):
2191 ad7e4bea Sofia Papagiannaki
    def test_publish(self):
2192 ad7e4bea Sofia Papagiannaki
        self.client.create_container('c')
2193 ad7e4bea Sofia Papagiannaki
        o_data = self.upload_random_data('c', 'o')['data']
2194 ad7e4bea Sofia Papagiannaki
        self.client.publish_object('c', 'o')
2195 ad7e4bea Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata('c', 'o')
2196 ad7e4bea Sofia Papagiannaki
        self.assertTrue('x-object-public' in meta)
2197 b5dc1bda Sofia Papagiannaki
        url = meta['x-object-public']
2198 7067193f Kostas Papadimitriou
2199 96738a78 Sofia Papagiannaki
        p = urlparse(get_url())
2200 96738a78 Sofia Papagiannaki
        if p.scheme == 'http':
2201 96738a78 Sofia Papagiannaki
            conn = HTTPConnection(p.netloc)
2202 96738a78 Sofia Papagiannaki
        elif p.scheme == 'https':
2203 96738a78 Sofia Papagiannaki
            conn = HTTPSConnection(p.netloc)
2204 96738a78 Sofia Papagiannaki
        else:
2205 96738a78 Sofia Papagiannaki
            raise Exception('Unknown URL scheme')
2206 7067193f Kostas Papadimitriou
2207 96738a78 Sofia Papagiannaki
        conn.request('GET', url)
2208 96738a78 Sofia Papagiannaki
        resp = conn.getresponse()
2209 96738a78 Sofia Papagiannaki
        length = resp.getheader('content-length', None)
2210 96738a78 Sofia Papagiannaki
        data = resp.read(length)
2211 ad7e4bea Sofia Papagiannaki
        self.assertEqual(o_data, data)
2212 952f4da1 Sofia Papagiannaki
2213 5a8dc30c Sofia Papagiannaki
class TestPolicies(BaseTestCase):
2214 5a8dc30c Sofia Papagiannaki
    def test_none_versioning(self):
2215 5a8dc30c Sofia Papagiannaki
        self.client.create_container('c', policies={'versioning':'none'})
2216 5a8dc30c Sofia Papagiannaki
        o = self.upload_random_data('c', 'o')
2217 5a8dc30c Sofia Papagiannaki
        meta = self.client.retrieve_object_metadata('c', 'o')
2218 5a8dc30c Sofia Papagiannaki
        v = meta['x-object-version']
2219 5a8dc30c Sofia Papagiannaki
        more_data = get_random_data()
2220 5a8dc30c Sofia Papagiannaki
        self.client.update_object('c', 'o', StringIO(more_data))
2221 5a8dc30c Sofia Papagiannaki
        vlist = self.client.retrieve_object_versionlist('c', 'o')
2222 5a8dc30c Sofia Papagiannaki
        self.assert_raises_fault(404, self.client.retrieve_object_version,
2223 5a8dc30c Sofia Papagiannaki
                                 'c', 'o', v)
2224 5a8dc30c Sofia Papagiannaki
        data = self.client.retrieve_object('c', 'o')
2225 5a8dc30c Sofia Papagiannaki
        end = len(o['data'])
2226 5a8dc30c Sofia Papagiannaki
        self.assertEqual(data[:end], o['data'])
2227 5a8dc30c Sofia Papagiannaki
        self.assertEqual(data[end:], more_data)
2228 7067193f Kostas Papadimitriou
2229 5a8dc30c Sofia Papagiannaki
    def test_quota(self):
2230 5a8dc30c Sofia Papagiannaki
        self.client.create_container('c', policies={'quota':'1'})
2231 5a8dc30c Sofia Papagiannaki
        meta = self.client.retrieve_container_metadata('c')
2232 5a8dc30c Sofia Papagiannaki
        self.assertEqual(meta['x-container-policy-quota'], '1')
2233 5a8dc30c Sofia Papagiannaki
        self.assert_raises_fault(413, self.upload_random_data, 'c', 'o',
2234 5a8dc30c Sofia Papagiannaki
                                 length=1024*1024+1)
2235 7067193f Kostas Papadimitriou
2236 5a8dc30c Sofia Papagiannaki
    def test_quota_none(self):
2237 5a8dc30c Sofia Papagiannaki
        self.client.create_container('c', policies={'quota':'0'})
2238 5a8dc30c Sofia Papagiannaki
        meta = self.client.retrieve_container_metadata('c')
2239 5a8dc30c Sofia Papagiannaki
        self.assertEqual(meta['x-container-policy-quota'], '0')
2240 5a8dc30c Sofia Papagiannaki
        self.assert_not_raises_fault(413, self.upload_random_data, 'c', 'o',
2241 5a8dc30c Sofia Papagiannaki
                                 length=1024*1024+1)
2242 5a8dc30c Sofia Papagiannaki
2243 95e0d8ee Sofia Papagiannaki
class AssertUUidInvariant(object):
2244 95e0d8ee Sofia Papagiannaki
    def __init__(self, callable, *args, **kwargs):
2245 95e0d8ee Sofia Papagiannaki
        self.callable = callable
2246 95e0d8ee Sofia Papagiannaki
        self.args = args
2247 95e0d8ee Sofia Papagiannaki
        self.kwargs = kwargs
2248 7067193f Kostas Papadimitriou
2249 95e0d8ee Sofia Papagiannaki
    def __enter__(self):
2250 95e0d8ee Sofia Papagiannaki
        self.map = self.callable(*self.args, **self.kwargs)
2251 95e0d8ee Sofia Papagiannaki
        assert('x-object-uuid' in self.map)
2252 95e0d8ee Sofia Papagiannaki
        self.uuid = self.map['x-object-uuid']
2253 95e0d8ee Sofia Papagiannaki
        return self.map
2254 7067193f Kostas Papadimitriou
2255 95e0d8ee Sofia Papagiannaki
    def __exit__(self, type, value, tb):
2256 95e0d8ee Sofia Papagiannaki
        map = self.callable(*self.args, **self.kwargs)
2257 95e0d8ee Sofia Papagiannaki
        assert('x-object-uuid' in self.map)
2258 95e0d8ee Sofia Papagiannaki
        uuid = map['x-object-uuid']
2259 95e0d8ee Sofia Papagiannaki
        assert(uuid == self.uuid)
2260 95e0d8ee Sofia Papagiannaki
2261 23028d31 Sofia Papagiannaki
class AssertMappingInvariant(object):
2262 b09c9aaa Sofia Papagiannaki
    def __init__(self, callable, *args, **kwargs):
2263 b09c9aaa Sofia Papagiannaki
        self.callable = callable
2264 b09c9aaa Sofia Papagiannaki
        self.args = args
2265 b09c9aaa Sofia Papagiannaki
        self.kwargs = kwargs
2266 7067193f Kostas Papadimitriou
2267 b09c9aaa Sofia Papagiannaki
    def __enter__(self):
2268 23028d31 Sofia Papagiannaki
        self.map = self.callable(*self.args, **self.kwargs)
2269 23028d31 Sofia Papagiannaki
        return self.map
2270 7067193f Kostas Papadimitriou
2271 b09c9aaa Sofia Papagiannaki
    def __exit__(self, type, value, tb):
2272 23028d31 Sofia Papagiannaki
        map = self.callable(*self.args, **self.kwargs)
2273 95e0d8ee Sofia Papagiannaki
        for k, v in self.map.items():
2274 95e0d8ee Sofia Papagiannaki
            if is_date(v):
2275 23028d31 Sofia Papagiannaki
                continue
2276 f2a3d5a3 Antony Chazapis
            #print '#', k, v, map[k]
2277 95e0d8ee Sofia Papagiannaki
            assert(k in map)
2278 95e0d8ee Sofia Papagiannaki
            assert v == map[k]
2279 7067193f Kostas Papadimitriou
2280 33ffca25 Sofia Papagiannaki
class AssertContentInvariant(object):
2281 33ffca25 Sofia Papagiannaki
    def __init__(self, callable, *args, **kwargs):
2282 33ffca25 Sofia Papagiannaki
        self.callable = callable
2283 33ffca25 Sofia Papagiannaki
        self.args = args
2284 33ffca25 Sofia Papagiannaki
        self.kwargs = kwargs
2285 7067193f Kostas Papadimitriou
2286 33ffca25 Sofia Papagiannaki
    def __enter__(self):
2287 23028d31 Sofia Papagiannaki
        self.content = self.callable(*self.args, **self.kwargs)[2]
2288 33ffca25 Sofia Papagiannaki
        return self.content
2289 7067193f Kostas Papadimitriou
2290 33ffca25 Sofia Papagiannaki
    def __exit__(self, type, value, tb):
2291 23028d31 Sofia Papagiannaki
        content = self.callable(*self.args, **self.kwargs)[2]
2292 33ffca25 Sofia Papagiannaki
        assert self.content == content
2293 33ffca25 Sofia Papagiannaki
2294 b09c9aaa Sofia Papagiannaki
def get_content_splitted(response):
2295 b09c9aaa Sofia Papagiannaki
    if response:
2296 b09c9aaa Sofia Papagiannaki
        return response.content.split('\n')
2297 b09c9aaa Sofia Papagiannaki
2298 d1e43d6f Sofia Papagiannaki
def compute_md5_hash(data):
2299 b09c9aaa Sofia Papagiannaki
    md5 = hashlib.md5()
2300 b09c9aaa Sofia Papagiannaki
    offset = 0
2301 b09c9aaa Sofia Papagiannaki
    md5.update(data)
2302 b09c9aaa Sofia Papagiannaki
    return md5.hexdigest().lower()
2303 b09c9aaa Sofia Papagiannaki
2304 33ffca25 Sofia Papagiannaki
def compute_block_hash(data, algorithm):
2305 33ffca25 Sofia Papagiannaki
    h = hashlib.new(algorithm)
2306 d1e43d6f Sofia Papagiannaki
    h.update(data.rstrip('\x00'))
2307 d1e43d6f Sofia Papagiannaki
    return h.hexdigest()
2308 d1e43d6f Sofia Papagiannaki
2309 bd8a3026 Sofia Papagiannaki
def get_random_data(length=500):
2310 33ffca25 Sofia Papagiannaki
    char_set = string.ascii_uppercase + string.digits
2311 5a8dc30c Sofia Papagiannaki
    return ''.join(random.choice(char_set) for x in xrange(length))
2312 33ffca25 Sofia Papagiannaki
2313 23028d31 Sofia Papagiannaki
def is_date(date):
2314 23028d31 Sofia Papagiannaki
    MONTHS = 'jan feb mar apr may jun jul aug sep oct nov dec'.split()
2315 23028d31 Sofia Papagiannaki
    __D = r'(?P<day>\d{2})'
2316 23028d31 Sofia Papagiannaki
    __D2 = r'(?P<day>[ \d]\d)'
2317 23028d31 Sofia Papagiannaki
    __M = r'(?P<mon>\w{3})'
2318 23028d31 Sofia Papagiannaki
    __Y = r'(?P<year>\d{4})'
2319 23028d31 Sofia Papagiannaki
    __Y2 = r'(?P<year>\d{2})'
2320 23028d31 Sofia Papagiannaki
    __T = r'(?P<hour>\d{2}):(?P<min>\d{2}):(?P<sec>\d{2})'
2321 23028d31 Sofia Papagiannaki
    RFC1123_DATE = re.compile(r'^\w{3}, %s %s %s %s GMT$' % (__D, __M, __Y, __T))
2322 23028d31 Sofia Papagiannaki
    RFC850_DATE = re.compile(r'^\w{6,9}, %s-%s-%s %s GMT$' % (__D, __M, __Y2, __T))
2323 23028d31 Sofia Papagiannaki
    ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y))
2324 23028d31 Sofia Papagiannaki
    for regex in RFC1123_DATE, RFC850_DATE, ASCTIME_DATE:
2325 23028d31 Sofia Papagiannaki
        m = regex.match(date)
2326 23028d31 Sofia Papagiannaki
        if m is not None:
2327 23028d31 Sofia Papagiannaki
            return True
2328 23028d31 Sofia Papagiannaki
    return False
2329 23028d31 Sofia Papagiannaki
2330 b09c9aaa Sofia Papagiannaki
o_names = ['kate.jpg',
2331 b09c9aaa Sofia Papagiannaki
           'kate_beckinsale.jpg',
2332 b09c9aaa Sofia Papagiannaki
           'How To Win Friends And Influence People.pdf',
2333 b09c9aaa Sofia Papagiannaki
           'moms_birthday.jpg',
2334 b09c9aaa Sofia Papagiannaki
           'poodle_strut.mov',
2335 b09c9aaa Sofia Papagiannaki
           'Disturbed - Down With The Sickness.mp3',
2336 b09c9aaa Sofia Papagiannaki
           'army_of_darkness.avi',
2337 b09c9aaa Sofia Papagiannaki
           'the_mad.avi',
2338 b09c9aaa Sofia Papagiannaki
           'photos/animals/dogs/poodle.jpg',
2339 b09c9aaa Sofia Papagiannaki
           'photos/animals/dogs/terrier.jpg',
2340 b09c9aaa Sofia Papagiannaki
           'photos/animals/cats/persian.jpg',
2341 b09c9aaa Sofia Papagiannaki
           'photos/animals/cats/siamese.jpg',
2342 b09c9aaa Sofia Papagiannaki
           'photos/plants/fern.jpg',
2343 b09c9aaa Sofia Papagiannaki
           'photos/plants/rose.jpg',
2344 0a425890 Antony Chazapis
           'photos/me.jpg']
2345 23028d31 Sofia Papagiannaki
2346 9e826a59 Kostas Papadimitriou
2347 9e826a59 Kostas Papadimitriou
def main():
2348 d7eb5499 Sofia Papagiannaki
    if get_user() == 'test':
2349 7067193f Kostas Papadimitriou
        unittest.main(module='pithos.tools.test')
2350 dc080673 Antony Chazapis
    else:
2351 dc080673 Antony Chazapis
        print 'Will not run tests as any other user except \'test\' (current user: %s).' % get_user()
2352 9e826a59 Kostas Papadimitriou
2353 9e826a59 Kostas Papadimitriou
2354 9e826a59 Kostas Papadimitriou
if __name__ == "__main__":
2355 9e826a59 Kostas Papadimitriou
    main()