Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-app / pithos / api / test / __init__.py @ 6e7e6b21

History | View | Annotate | Download (21.1 kB)

1 f3787696 Sofia Papagiannaki
#!/usr/bin/env python
2 f3787696 Sofia Papagiannaki
#coding=utf8
3 f3787696 Sofia Papagiannaki
4 f3787696 Sofia Papagiannaki
# Copyright 2011-2013 GRNET S.A. All rights reserved.
5 f3787696 Sofia Papagiannaki
#
6 f3787696 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
7 f3787696 Sofia Papagiannaki
# without modification, are permitted provided that the following
8 f3787696 Sofia Papagiannaki
# conditions are met:
9 f3787696 Sofia Papagiannaki
#
10 f3787696 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
11 f3787696 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
12 f3787696 Sofia Papagiannaki
#      disclaimer.
13 f3787696 Sofia Papagiannaki
#
14 f3787696 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
15 f3787696 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
16 f3787696 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
17 f3787696 Sofia Papagiannaki
#      provided with the distribution.
18 f3787696 Sofia Papagiannaki
#
19 f3787696 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
20 f3787696 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 f3787696 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 f3787696 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
23 f3787696 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 f3787696 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 f3787696 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 f3787696 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 f3787696 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 f3787696 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 f3787696 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 f3787696 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
31 f3787696 Sofia Papagiannaki
#
32 f3787696 Sofia Papagiannaki
# The views and conclusions contained in the software and
33 f3787696 Sofia Papagiannaki
# documentation are those of the authors and should not be
34 f3787696 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
35 f3787696 Sofia Papagiannaki
# or implied, of GRNET S.A.
36 f3787696 Sofia Papagiannaki
37 f3787696 Sofia Papagiannaki
from urlparse import urlunsplit, urlsplit
38 f3787696 Sofia Papagiannaki
from xml.dom import minidom
39 6ee6677e Sofia Papagiannaki
from urllib import quote, unquote
40 f3787696 Sofia Papagiannaki
41 f3787696 Sofia Papagiannaki
from snf_django.utils.testing import with_settings, astakos_user
42 f3787696 Sofia Papagiannaki
43 f3787696 Sofia Papagiannaki
from pithos.api import settings as pithos_settings
44 bc4f25c0 Sofia Papagiannaki
from pithos.api.test.util import is_date, get_random_data, get_random_name
45 bc4f25c0 Sofia Papagiannaki
from pithos.backends.migrate import initialize_db
46 f3787696 Sofia Papagiannaki
47 d6a92fa0 Sofia Papagiannaki
from synnefo.lib.services import get_service_path
48 d6a92fa0 Sofia Papagiannaki
from synnefo.lib import join_urls
49 d6a92fa0 Sofia Papagiannaki
50 f3787696 Sofia Papagiannaki
from django.test import TestCase
51 bc4f25c0 Sofia Papagiannaki
from django.test.simple import DjangoTestSuiteRunner
52 7c36f3fb Sofia Papagiannaki
from django.conf import settings
53 f3787696 Sofia Papagiannaki
from django.utils.http import urlencode
54 bc4f25c0 Sofia Papagiannaki
from django.db.backends.creation import TEST_DATABASE_PREFIX
55 f3787696 Sofia Papagiannaki
56 f3787696 Sofia Papagiannaki
import django.utils.simplejson as json
57 f3787696 Sofia Papagiannaki
58 f3787696 Sofia Papagiannaki
import random
59 f3787696 Sofia Papagiannaki
import functools
60 f3787696 Sofia Papagiannaki
61 3a19e99b Sofia Papagiannaki
62 f3787696 Sofia Papagiannaki
pithos_test_settings = functools.partial(with_settings, pithos_settings)
63 f3787696 Sofia Papagiannaki
64 f3787696 Sofia Papagiannaki
DATE_FORMATS = ["%a %b %d %H:%M:%S %Y",
65 f3787696 Sofia Papagiannaki
                "%A, %d-%b-%y %H:%M:%S GMT",
66 f3787696 Sofia Papagiannaki
                "%a, %d %b %Y %H:%M:%S GMT"]
67 f3787696 Sofia Papagiannaki
68 f3787696 Sofia Papagiannaki
o_names = ['kate.jpg',
69 f3787696 Sofia Papagiannaki
           'kate_beckinsale.jpg',
70 f3787696 Sofia Papagiannaki
           'How To Win Friends And Influence People.pdf',
71 f3787696 Sofia Papagiannaki
           'moms_birthday.jpg',
72 f3787696 Sofia Papagiannaki
           'poodle_strut.mov',
73 f3787696 Sofia Papagiannaki
           'Disturbed - Down With The Sickness.mp3',
74 f3787696 Sofia Papagiannaki
           'army_of_darkness.avi',
75 f3787696 Sofia Papagiannaki
           'the_mad.avi',
76 f3787696 Sofia Papagiannaki
           'photos/animals/dogs/poodle.jpg',
77 f3787696 Sofia Papagiannaki
           'photos/animals/dogs/terrier.jpg',
78 f3787696 Sofia Papagiannaki
           'photos/animals/cats/persian.jpg',
79 f3787696 Sofia Papagiannaki
           'photos/animals/cats/siamese.jpg',
80 f3787696 Sofia Papagiannaki
           'photos/plants/fern.jpg',
81 f3787696 Sofia Papagiannaki
           'photos/plants/rose.jpg',
82 f3787696 Sofia Papagiannaki
           'photos/me.jpg']
83 f3787696 Sofia Papagiannaki
84 f3787696 Sofia Papagiannaki
details = {'container': ('name', 'count', 'bytes', 'last_modified',
85 f3787696 Sofia Papagiannaki
                         'x_container_policy'),
86 f3787696 Sofia Papagiannaki
           'object': ('name', 'hash', 'bytes', 'content_type',
87 f3787696 Sofia Papagiannaki
                      'content_encoding', 'last_modified',)}
88 f3787696 Sofia Papagiannaki
89 5fe43b8c Sofia Papagiannaki
TEST_BLOCK_SIZE = 1024
90 5fe43b8c Sofia Papagiannaki
TEST_HASH_ALGORITHM = 'sha256'
91 5fe43b8c Sofia Papagiannaki
92 bc4f25c0 Sofia Papagiannaki
print 'backend module:', pithos_settings.BACKEND_DB_MODULE
93 bc4f25c0 Sofia Papagiannaki
print 'backend database engine:', settings.DATABASES['default']['ENGINE']
94 bc4f25c0 Sofia Papagiannaki
print 'update md5:', pithos_settings.UPDATE_MD5
95 65f480f5 Sofia Papagiannaki
96 65f480f5 Sofia Papagiannaki
97 bc4f25c0 Sofia Papagiannaki
django_sqlalchemy_engines = {
98 bc4f25c0 Sofia Papagiannaki
    'django.db.backends.postgresql_psycopg2': 'postgresql+psycopg2',
99 bc4f25c0 Sofia Papagiannaki
    'django.db.backends.postgresql': 'postgresql',
100 bc4f25c0 Sofia Papagiannaki
    'django.db.backends.mysql': '',
101 bc4f25c0 Sofia Papagiannaki
    'django.db.backends.sqlite3': 'mssql',
102 bc4f25c0 Sofia Papagiannaki
    'django.db.backends.oracle': 'oracle'}
103 65f480f5 Sofia Papagiannaki
104 65f480f5 Sofia Papagiannaki
105 565414a9 Sofia Papagiannaki
def prepare_db_connection():
106 bc4f25c0 Sofia Papagiannaki
    """Build pithos backend connection string from django default database"""
107 bc4f25c0 Sofia Papagiannaki
108 65f480f5 Sofia Papagiannaki
    db = settings.DATABASES['default']
109 bc4f25c0 Sofia Papagiannaki
    name = db.get('TEST_NAME', TEST_DATABASE_PREFIX + db['NAME'])
110 bc4f25c0 Sofia Papagiannaki
111 bc4f25c0 Sofia Papagiannaki
    if (pithos_settings.BACKEND_DB_MODULE == 'pithos.backends.lib.sqlalchemy'):
112 bc4f25c0 Sofia Papagiannaki
        if db['ENGINE'] == 'django.db.backends.sqlite3':
113 bc4f25c0 Sofia Papagiannaki
            db_connection = 'sqlite:///%s' % name
114 bc4f25c0 Sofia Papagiannaki
        else:
115 bc4f25c0 Sofia Papagiannaki
            d = dict(scheme=django_sqlalchemy_engines.get(db['ENGINE']),
116 bc4f25c0 Sofia Papagiannaki
                     user=db['USER'],
117 bc4f25c0 Sofia Papagiannaki
                     pwd=db['PASSWORD'],
118 bc4f25c0 Sofia Papagiannaki
                     host=db['HOST'].lower(),
119 bc4f25c0 Sofia Papagiannaki
                     port=int(db['PORT']) if db['PORT'] != '' else '',
120 bc4f25c0 Sofia Papagiannaki
                     name=name)
121 bc4f25c0 Sofia Papagiannaki
            db_connection = (
122 bc4f25c0 Sofia Papagiannaki
                '%(scheme)s://%(user)s:%(pwd)s@%(host)s:%(port)s/%(name)s' % d)
123 bc4f25c0 Sofia Papagiannaki
124 bc4f25c0 Sofia Papagiannaki
            # initialize pithos database
125 bc4f25c0 Sofia Papagiannaki
            initialize_db(db_connection)
126 65f480f5 Sofia Papagiannaki
    else:
127 bc4f25c0 Sofia Papagiannaki
        db_connection = name
128 bc4f25c0 Sofia Papagiannaki
    pithos_settings.BACKEND_DB_CONNECTION = db_connection
129 bc4f25c0 Sofia Papagiannaki
130 bc4f25c0 Sofia Papagiannaki
131 6ee6677e Sofia Papagiannaki
def filter_headers(headers, prefix):
132 6ee6677e Sofia Papagiannaki
    meta = {}
133 6ee6677e Sofia Papagiannaki
    for k, v in headers.iteritems():
134 6ee6677e Sofia Papagiannaki
        if not k.startswith(prefix):
135 6ee6677e Sofia Papagiannaki
            continue
136 6ee6677e Sofia Papagiannaki
        meta[unquote(k[len(prefix):])] = unquote(v)
137 6ee6677e Sofia Papagiannaki
    return meta
138 6ee6677e Sofia Papagiannaki
139 6ee6677e Sofia Papagiannaki
140 bc4f25c0 Sofia Papagiannaki
class PithosTestSuiteRunner(DjangoTestSuiteRunner):
141 bc4f25c0 Sofia Papagiannaki
    def setup_databases(self, **kwargs):
142 bc4f25c0 Sofia Papagiannaki
        old_names, mirrors = super(PithosTestSuiteRunner,
143 bc4f25c0 Sofia Papagiannaki
                                   self).setup_databases(**kwargs)
144 565414a9 Sofia Papagiannaki
        prepare_db_connection()
145 bc4f25c0 Sofia Papagiannaki
        return old_names, mirrors
146 65f480f5 Sofia Papagiannaki
147 82b125c8 Sofia Papagiannaki
    def teardown_databases(self, old_config, **kwargs):
148 6e7e6b21 Sofia Papagiannaki
        from pithos.api.util import (_pithos_storage_backend_pool,
149 6e7e6b21 Sofia Papagiannaki
                                     _pithos_public_backend_pool)
150 6e7e6b21 Sofia Papagiannaki
        _pithos_storage_backend_pool.shutdown()
151 6e7e6b21 Sofia Papagiannaki
        _pithos_public_backend_pool.shutdown()
152 82b125c8 Sofia Papagiannaki
        super(PithosTestSuiteRunner, self).teardown_databases(old_config,
153 82b125c8 Sofia Papagiannaki
                                                              **kwargs)
154 82b125c8 Sofia Papagiannaki
155 f3787696 Sofia Papagiannaki
156 f3787696 Sofia Papagiannaki
class PithosAPITest(TestCase):
157 f3787696 Sofia Papagiannaki
    def setUp(self):
158 369a7b41 Sofia Papagiannaki
        # Override default block size to spead up tests
159 5fe43b8c Sofia Papagiannaki
        pithos_settings.BACKEND_BLOCK_SIZE = TEST_BLOCK_SIZE
160 5fe43b8c Sofia Papagiannaki
        pithos_settings.BACKEND_HASH_ALGORITHM = TEST_HASH_ALGORITHM
161 369a7b41 Sofia Papagiannaki
162 f3787696 Sofia Papagiannaki
        self.user = 'user'
163 d6a92fa0 Sofia Papagiannaki
        self.pithos_path = join_urls(get_service_path(
164 d6a92fa0 Sofia Papagiannaki
            pithos_settings.pithos_services, 'object-store'))
165 f3787696 Sofia Papagiannaki
166 f3787696 Sofia Papagiannaki
    def tearDown(self):
167 f3787696 Sofia Papagiannaki
        #delete additionally created metadata
168 f3787696 Sofia Papagiannaki
        meta = self.get_account_meta()
169 f3787696 Sofia Papagiannaki
        self.delete_account_meta(meta)
170 f3787696 Sofia Papagiannaki
171 f3787696 Sofia Papagiannaki
        #delete additionally created groups
172 f3787696 Sofia Papagiannaki
        groups = self.get_account_groups()
173 f3787696 Sofia Papagiannaki
        self.delete_account_groups(groups)
174 f3787696 Sofia Papagiannaki
175 f3787696 Sofia Papagiannaki
        self._clean_account()
176 f3787696 Sofia Papagiannaki
177 65f480f5 Sofia Papagiannaki
    def _clean_account(self):
178 65f480f5 Sofia Papagiannaki
        for c in self.list_containers():
179 65f480f5 Sofia Papagiannaki
            self.delete_container_content(c['name'])
180 65f480f5 Sofia Papagiannaki
            self.delete_container(c['name'])
181 65f480f5 Sofia Papagiannaki
182 25b6d04e Sofia Papagiannaki
    def head(self, url, user='user', token='DummyToken', data={}, follow=False,
183 25b6d04e Sofia Papagiannaki
             **extra):
184 f3787696 Sofia Papagiannaki
        with astakos_user(user):
185 6ee6677e Sofia Papagiannaki
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
186 25b6d04e Sofia Papagiannaki
            if token:
187 25b6d04e Sofia Papagiannaki
                extra['HTTP_X_AUTH_TOKEN'] = token
188 6ee6677e Sofia Papagiannaki
            response = self.client.head(url, data, follow, **extra)
189 f3787696 Sofia Papagiannaki
        return response
190 f3787696 Sofia Papagiannaki
191 25b6d04e Sofia Papagiannaki
    def get(self, url, user='user', token='DummyToken', data={}, follow=False,
192 25b6d04e Sofia Papagiannaki
            **extra):
193 f3787696 Sofia Papagiannaki
        with astakos_user(user):
194 6ee6677e Sofia Papagiannaki
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
195 25b6d04e Sofia Papagiannaki
            if token:
196 25b6d04e Sofia Papagiannaki
                extra['HTTP_X_AUTH_TOKEN'] = token
197 6ee6677e Sofia Papagiannaki
            response = self.client.get(url, data, follow, **extra)
198 f3787696 Sofia Papagiannaki
        return response
199 f3787696 Sofia Papagiannaki
200 25b6d04e Sofia Papagiannaki
    def delete(self, url, user='user', token='DummyToken', data={},
201 25b6d04e Sofia Papagiannaki
               follow=False, **extra):
202 f3787696 Sofia Papagiannaki
        with astakos_user(user):
203 6ee6677e Sofia Papagiannaki
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
204 25b6d04e Sofia Papagiannaki
            if token:
205 25b6d04e Sofia Papagiannaki
                extra['HTTP_X_AUTH_TOKEN'] = token
206 6ee6677e Sofia Papagiannaki
            response = self.client.delete(url, data, follow, **extra)
207 f3787696 Sofia Papagiannaki
        return response
208 f3787696 Sofia Papagiannaki
209 25b6d04e Sofia Papagiannaki
    def post(self, url, user='user', token='DummyToken', data={},
210 6ee6677e Sofia Papagiannaki
             content_type='application/octet-stream', follow=False, **extra):
211 f3787696 Sofia Papagiannaki
        with astakos_user(user):
212 6ee6677e Sofia Papagiannaki
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
213 25b6d04e Sofia Papagiannaki
            if token:
214 25b6d04e Sofia Papagiannaki
                extra['HTTP_X_AUTH_TOKEN'] = token
215 6ee6677e Sofia Papagiannaki
            response = self.client.post(url, data, content_type, follow,
216 6ee6677e Sofia Papagiannaki
                                        **extra)
217 f3787696 Sofia Papagiannaki
        return response
218 f3787696 Sofia Papagiannaki
219 25b6d04e Sofia Papagiannaki
    def put(self, url, user='user', token='DummyToken', data={},
220 6ee6677e Sofia Papagiannaki
            content_type='application/octet-stream', follow=False, **extra):
221 f3787696 Sofia Papagiannaki
        with astakos_user(user):
222 6ee6677e Sofia Papagiannaki
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
223 25b6d04e Sofia Papagiannaki
            if token:
224 25b6d04e Sofia Papagiannaki
                extra['HTTP_X_AUTH_TOKEN'] = token
225 6ee6677e Sofia Papagiannaki
            response = self.client.put(url, data, content_type, follow,
226 6ee6677e Sofia Papagiannaki
                                       **extra)
227 f3787696 Sofia Papagiannaki
        return response
228 f3787696 Sofia Papagiannaki
229 6ee6677e Sofia Papagiannaki
    def update_account_meta(self, meta, user=None):
230 6ee6677e Sofia Papagiannaki
        user = user or self.user
231 f3787696 Sofia Papagiannaki
        kwargs = dict(
232 f3787696 Sofia Papagiannaki
            ('HTTP_X_ACCOUNT_META_%s' % k, str(v)) for k, v in meta.items())
233 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user)
234 6ee6677e Sofia Papagiannaki
        r = self.post('%s?update=' % url, user=user, **kwargs)
235 f3787696 Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
236 25b6d04e Sofia Papagiannaki
        account_meta = self.get_account_meta(user=user)
237 25b6d04e Sofia Papagiannaki
        (self.assertTrue('X-Account-Meta-%s' % k in account_meta) for
238 25b6d04e Sofia Papagiannaki
            k in meta.keys())
239 25b6d04e Sofia Papagiannaki
        (self.assertEqual(account_meta['X-Account-Meta-%s' % k], v) for
240 25b6d04e Sofia Papagiannaki
            k, v in meta.items())
241 25b6d04e Sofia Papagiannaki
242 25b6d04e Sofia Papagiannaki
    def reset_account_meta(self, meta, user=None):
243 25b6d04e Sofia Papagiannaki
        user = user or self.user
244 25b6d04e Sofia Papagiannaki
        kwargs = dict(
245 25b6d04e Sofia Papagiannaki
            ('HTTP_X_ACCOUNT_META_%s' % k, str(v)) for k, v in meta.items())
246 25b6d04e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user)
247 25b6d04e Sofia Papagiannaki
        r = self.post(url, user=user, **kwargs)
248 25b6d04e Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
249 25b6d04e Sofia Papagiannaki
        account_meta = self.get_account_meta(user=user)
250 25b6d04e Sofia Papagiannaki
        (self.assertTrue('X-Account-Meta-%s' % k in account_meta) for
251 25b6d04e Sofia Papagiannaki
            k in meta.keys())
252 25b6d04e Sofia Papagiannaki
        (self.assertEqual(account_meta['X-Account-Meta-%s' % k], v) for
253 25b6d04e Sofia Papagiannaki
            k, v in meta.items())
254 f3787696 Sofia Papagiannaki
255 6ee6677e Sofia Papagiannaki
    def delete_account_meta(self, meta, user=None):
256 6ee6677e Sofia Papagiannaki
        user = user or self.user
257 25b6d04e Sofia Papagiannaki
        transform = lambda k: 'HTTP_%s' % k.replace('-', '_').upper()
258 f3787696 Sofia Papagiannaki
        kwargs = dict((transform(k), '') for k, v in meta.items())
259 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user)
260 6ee6677e Sofia Papagiannaki
        r = self.post('%s?update=' % url, user=user, **kwargs)
261 f3787696 Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
262 25b6d04e Sofia Papagiannaki
        account_meta = self.get_account_meta(user=user)
263 25b6d04e Sofia Papagiannaki
        (self.assertTrue('X-Account-Meta-%s' % k not in account_meta) for
264 25b6d04e Sofia Papagiannaki
            k in meta.keys())
265 f3787696 Sofia Papagiannaki
        return r
266 f3787696 Sofia Papagiannaki
267 6ee6677e Sofia Papagiannaki
    def delete_account_groups(self, groups, user=None):
268 6ee6677e Sofia Papagiannaki
        user = user or self.user
269 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user)
270 25b6d04e Sofia Papagiannaki
        r = self.post('%s?update=' % url, user=user, **groups)
271 f3787696 Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
272 6ee6677e Sofia Papagiannaki
        account_groups = self.get_account_groups()
273 6ee6677e Sofia Papagiannaki
        (self.assertTrue(k not in account_groups) for k in groups.keys())
274 f3787696 Sofia Papagiannaki
        return r
275 f3787696 Sofia Papagiannaki
276 6ee6677e Sofia Papagiannaki
    def get_account_info(self, until=None, user=None):
277 6ee6677e Sofia Papagiannaki
        user = user or self.user
278 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user)
279 f3787696 Sofia Papagiannaki
        if until is not None:
280 f3787696 Sofia Papagiannaki
            parts = list(urlsplit(url))
281 f3787696 Sofia Papagiannaki
            parts[3] = urlencode({
282 f3787696 Sofia Papagiannaki
                'until': until
283 f3787696 Sofia Papagiannaki
            })
284 f3787696 Sofia Papagiannaki
            url = urlunsplit(parts)
285 6ee6677e Sofia Papagiannaki
        r = self.head(url, user=user)
286 f3787696 Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
287 f3787696 Sofia Papagiannaki
        return r
288 f3787696 Sofia Papagiannaki
289 6ee6677e Sofia Papagiannaki
    def get_account_meta(self, until=None, user=None):
290 6ee6677e Sofia Papagiannaki
        prefix = 'X-Account-Meta-'
291 6ee6677e Sofia Papagiannaki
        r = self.get_account_info(until=until, user=user)
292 f3787696 Sofia Papagiannaki
        headers = dict(r._headers.values())
293 6ee6677e Sofia Papagiannaki
        return filter_headers(headers, prefix)
294 f3787696 Sofia Papagiannaki
295 6ee6677e Sofia Papagiannaki
    def get_account_groups(self, until=None, user=None):
296 6ee6677e Sofia Papagiannaki
        prefix = 'X-Account-Group-'
297 6ee6677e Sofia Papagiannaki
        r = self.get_account_info(until=until, user=user)
298 f3787696 Sofia Papagiannaki
        headers = dict(r._headers.values())
299 6ee6677e Sofia Papagiannaki
        return filter_headers(headers, prefix)
300 f3787696 Sofia Papagiannaki
301 6ee6677e Sofia Papagiannaki
    def get_container_info(self, container, until=None, user=None):
302 6ee6677e Sofia Papagiannaki
        user = user or self.user
303 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, container)
304 3a19e99b Sofia Papagiannaki
        if until is not None:
305 3a19e99b Sofia Papagiannaki
            parts = list(urlsplit(url))
306 3a19e99b Sofia Papagiannaki
            parts[3] = urlencode({
307 3a19e99b Sofia Papagiannaki
                'until': until
308 3a19e99b Sofia Papagiannaki
            })
309 3a19e99b Sofia Papagiannaki
            url = urlunsplit(parts)
310 6ee6677e Sofia Papagiannaki
        r = self.head(url, user=user)
311 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
312 3a19e99b Sofia Papagiannaki
        return r
313 3a19e99b Sofia Papagiannaki
314 6ee6677e Sofia Papagiannaki
    def get_container_meta(self, container, until=None, user=None):
315 6ee6677e Sofia Papagiannaki
        prefix = 'X-Container-Meta-'
316 6ee6677e Sofia Papagiannaki
        r = self.get_container_info(container, until=until, user=user)
317 3a19e99b Sofia Papagiannaki
        headers = dict(r._headers.values())
318 6ee6677e Sofia Papagiannaki
        return filter_headers(headers, prefix)
319 3a19e99b Sofia Papagiannaki
320 6ee6677e Sofia Papagiannaki
    def update_container_meta(self, container, meta, user=None):
321 6ee6677e Sofia Papagiannaki
        user = user or self.user
322 3a19e99b Sofia Papagiannaki
        kwargs = dict(
323 3a19e99b Sofia Papagiannaki
            ('HTTP_X_CONTAINER_META_%s' % k, str(v)) for k, v in meta.items())
324 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, container)
325 6ee6677e Sofia Papagiannaki
        r = self.post('%s?update=' % url, user=user, **kwargs)
326 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
327 6e0f3e65 Sofia Papagiannaki
        container_meta = self.get_container_meta(container, user=user)
328 3a19e99b Sofia Papagiannaki
        (self.assertTrue('X-Container-Meta-%s' % k in container_meta) for
329 3a19e99b Sofia Papagiannaki
            k in meta.keys())
330 3a19e99b Sofia Papagiannaki
        (self.assertEqual(container_meta['X-Container-Meta-%s' % k], v) for
331 3a19e99b Sofia Papagiannaki
            k, v in meta.items())
332 3a19e99b Sofia Papagiannaki
333 6ee6677e Sofia Papagiannaki
    def list_containers(self, format='json', headers={}, user=None, **params):
334 6ee6677e Sofia Papagiannaki
        user = user or self.user
335 6ee6677e Sofia Papagiannaki
        _url = join_urls(self.pithos_path, user)
336 d6a92fa0 Sofia Papagiannaki
        parts = list(urlsplit(_url))
337 f3787696 Sofia Papagiannaki
        params['format'] = format
338 f3787696 Sofia Papagiannaki
        parts[3] = urlencode(params)
339 f3787696 Sofia Papagiannaki
        url = urlunsplit(parts)
340 f3787696 Sofia Papagiannaki
        _headers = dict(('HTTP_%s' % k.upper(), str(v))
341 f3787696 Sofia Papagiannaki
                        for k, v in headers.items())
342 6ee6677e Sofia Papagiannaki
        r = self.get(url, user=user, **_headers)
343 f3787696 Sofia Papagiannaki
344 f3787696 Sofia Papagiannaki
        if format is None:
345 f3787696 Sofia Papagiannaki
            containers = r.content.split('\n')
346 f3787696 Sofia Papagiannaki
            if '' in containers:
347 f3787696 Sofia Papagiannaki
                containers.remove('')
348 f3787696 Sofia Papagiannaki
            return containers
349 f3787696 Sofia Papagiannaki
        elif format == 'json':
350 f3787696 Sofia Papagiannaki
            try:
351 f3787696 Sofia Papagiannaki
                containers = json.loads(r.content)
352 f3787696 Sofia Papagiannaki
            except:
353 f3787696 Sofia Papagiannaki
                self.fail('json format expected')
354 f3787696 Sofia Papagiannaki
            return containers
355 f3787696 Sofia Papagiannaki
        elif format == 'xml':
356 f3787696 Sofia Papagiannaki
            return minidom.parseString(r.content)
357 f3787696 Sofia Papagiannaki
358 6ee6677e Sofia Papagiannaki
    def delete_container_content(self, cname, user=None):
359 6ee6677e Sofia Papagiannaki
        user = user or self.user
360 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, cname)
361 6ee6677e Sofia Papagiannaki
        r = self.delete('%s?delimiter=/' % url, user=user)
362 f3787696 Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
363 f3787696 Sofia Papagiannaki
        return r
364 f3787696 Sofia Papagiannaki
365 6ee6677e Sofia Papagiannaki
    def delete_container(self, cname, user=None):
366 6ee6677e Sofia Papagiannaki
        user = user or self.user
367 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, cname)
368 6ee6677e Sofia Papagiannaki
        r = self.delete(url, user=user)
369 f3787696 Sofia Papagiannaki
        self.assertEqual(r.status_code, 204)
370 f3787696 Sofia Papagiannaki
        return r
371 f3787696 Sofia Papagiannaki
372 6ee6677e Sofia Papagiannaki
    def create_container(self, cname=None, user=None):
373 95b36144 Sofia Papagiannaki
        cname = cname or get_random_name()
374 6ee6677e Sofia Papagiannaki
        user = user or self.user
375 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, cname)
376 6ee6677e Sofia Papagiannaki
        r = self.put(url, user=user, data='')
377 f3787696 Sofia Papagiannaki
        self.assertTrue(r.status_code in (202, 201))
378 95b36144 Sofia Papagiannaki
        return cname, r
379 f3787696 Sofia Papagiannaki
380 5fe43b8c Sofia Papagiannaki
    def upload_object(self, cname, oname=None, length=None, verify=True,
381 6ee6677e Sofia Papagiannaki
                      user=None, **meta):
382 bc4f25c0 Sofia Papagiannaki
        oname = oname or get_random_name()
383 5fe43b8c Sofia Papagiannaki
        length = length or random.randint(TEST_BLOCK_SIZE, 2 * TEST_BLOCK_SIZE)
384 6ee6677e Sofia Papagiannaki
        user = user or self.user
385 3a19e99b Sofia Papagiannaki
        data = get_random_data(length=length)
386 f3787696 Sofia Papagiannaki
        headers = dict(('HTTP_X_OBJECT_META_%s' % k.upper(), v)
387 f3787696 Sofia Papagiannaki
                       for k, v in meta.iteritems())
388 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, cname, oname)
389 6ee6677e Sofia Papagiannaki
        r = self.put(url, user=user, data=data, **headers)
390 3a19e99b Sofia Papagiannaki
        if verify:
391 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 201)
392 3a19e99b Sofia Papagiannaki
        return oname, data, r
393 3a19e99b Sofia Papagiannaki
394 3a19e99b Sofia Papagiannaki
    def update_object_data(self, cname, oname=None, length=None,
395 3a19e99b Sofia Papagiannaki
                           content_type=None, content_range=None,
396 6ee6677e Sofia Papagiannaki
                           verify=True, user=None, **meta):
397 bc4f25c0 Sofia Papagiannaki
        oname = oname or get_random_name()
398 5fe43b8c Sofia Papagiannaki
        length = length or random.randint(TEST_BLOCK_SIZE, 2 * TEST_BLOCK_SIZE)
399 3a19e99b Sofia Papagiannaki
        content_type = content_type or 'application/octet-stream'
400 6ee6677e Sofia Papagiannaki
        user = user or self.user
401 3a19e99b Sofia Papagiannaki
        data = get_random_data(length=length)
402 3a19e99b Sofia Papagiannaki
        headers = dict(('HTTP_X_OBJECT_META_%s' % k.upper(), v)
403 3a19e99b Sofia Papagiannaki
                       for k, v in meta.iteritems())
404 3a19e99b Sofia Papagiannaki
        if content_range:
405 3a19e99b Sofia Papagiannaki
            headers['HTTP_CONTENT_RANGE'] = content_range
406 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, cname, oname)
407 6ee6677e Sofia Papagiannaki
        r = self.post(url, user=user, data=data, content_type=content_type,
408 6ee6677e Sofia Papagiannaki
                      **headers)
409 3a19e99b Sofia Papagiannaki
        if verify:
410 3a19e99b Sofia Papagiannaki
            self.assertEqual(r.status_code, 204)
411 f3787696 Sofia Papagiannaki
        return oname, data, r
412 f3787696 Sofia Papagiannaki
413 3a19e99b Sofia Papagiannaki
    def append_object_data(self, cname, oname=None, length=None,
414 6ee6677e Sofia Papagiannaki
                           content_type=None, user=None):
415 3a19e99b Sofia Papagiannaki
        return self.update_object_data(cname, oname=oname,
416 3a19e99b Sofia Papagiannaki
                                       length=length,
417 3a19e99b Sofia Papagiannaki
                                       content_type=content_type,
418 6ee6677e Sofia Papagiannaki
                                       content_range='bytes */*',
419 6ee6677e Sofia Papagiannaki
                                       user=user)
420 3a19e99b Sofia Papagiannaki
421 6ee6677e Sofia Papagiannaki
    def create_folder(self, cname, oname=None, user=None, **headers):
422 6ee6677e Sofia Papagiannaki
        user = user or self.user
423 bc4f25c0 Sofia Papagiannaki
        oname = oname or get_random_name()
424 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, cname, oname)
425 6ee6677e Sofia Papagiannaki
        r = self.put(url, user=user, data='',
426 6ee6677e Sofia Papagiannaki
                     content_type='application/directory', **headers)
427 f3787696 Sofia Papagiannaki
        self.assertEqual(r.status_code, 201)
428 f3787696 Sofia Papagiannaki
        return oname, r
429 f3787696 Sofia Papagiannaki
430 6ee6677e Sofia Papagiannaki
    def list_objects(self, cname, prefix=None, user=None):
431 6ee6677e Sofia Papagiannaki
        user = user or self.user
432 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, cname)
433 3a19e99b Sofia Papagiannaki
        path = '%s?format=json' % url
434 3a19e99b Sofia Papagiannaki
        if prefix is not None:
435 3a19e99b Sofia Papagiannaki
            path = '%s&prefix=%s' % (path, prefix)
436 6ee6677e Sofia Papagiannaki
        r = self.get(path, user=user)
437 f3787696 Sofia Papagiannaki
        self.assertTrue(r.status_code in (200, 204))
438 f3787696 Sofia Papagiannaki
        try:
439 f3787696 Sofia Papagiannaki
            objects = json.loads(r.content)
440 f3787696 Sofia Papagiannaki
        except:
441 f3787696 Sofia Papagiannaki
            self.fail('json format expected')
442 f3787696 Sofia Papagiannaki
        return objects
443 f3787696 Sofia Papagiannaki
444 6ee6677e Sofia Papagiannaki
    def get_object_info(self, container, object, version=None, until=None,
445 6ee6677e Sofia Papagiannaki
                        user=None):
446 6ee6677e Sofia Papagiannaki
        user = user or self.user
447 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, container, object)
448 3a19e99b Sofia Papagiannaki
        if until is not None:
449 3a19e99b Sofia Papagiannaki
            parts = list(urlsplit(url))
450 3a19e99b Sofia Papagiannaki
            parts[3] = urlencode({
451 3a19e99b Sofia Papagiannaki
                'until': until
452 3a19e99b Sofia Papagiannaki
            })
453 3a19e99b Sofia Papagiannaki
            url = urlunsplit(parts)
454 3a19e99b Sofia Papagiannaki
        if version:
455 3a19e99b Sofia Papagiannaki
            url = '%s?version=%s' % (url, version)
456 6ee6677e Sofia Papagiannaki
        r = self.head(url, user=user)
457 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 200)
458 3a19e99b Sofia Papagiannaki
        return r
459 3a19e99b Sofia Papagiannaki
460 6ee6677e Sofia Papagiannaki
    def get_object_meta(self, container, object, version=None, until=None,
461 6ee6677e Sofia Papagiannaki
                        user=None):
462 6ee6677e Sofia Papagiannaki
        prefix = 'X-Object-Meta-'
463 25b6d04e Sofia Papagiannaki
        user = user or self.user
464 6ee6677e Sofia Papagiannaki
        r = self.get_object_info(container, object, version, until=until,
465 6ee6677e Sofia Papagiannaki
                                 user=user)
466 3a19e99b Sofia Papagiannaki
        headers = dict(r._headers.values())
467 6ee6677e Sofia Papagiannaki
        return filter_headers(headers, prefix)
468 3a19e99b Sofia Papagiannaki
469 6ee6677e Sofia Papagiannaki
    def update_object_meta(self, container, object, meta, user=None):
470 6ee6677e Sofia Papagiannaki
        user = user or self.user
471 3a19e99b Sofia Papagiannaki
        kwargs = dict(
472 3a19e99b Sofia Papagiannaki
            ('HTTP_X_OBJECT_META_%s' % k, str(v)) for k, v in meta.items())
473 6ee6677e Sofia Papagiannaki
        url = join_urls(self.pithos_path, user, container, object)
474 6ee6677e Sofia Papagiannaki
        r = self.post('%s?update=' % url, user=user, content_type='', **kwargs)
475 3a19e99b Sofia Papagiannaki
        self.assertEqual(r.status_code, 202)
476 6e0f3e65 Sofia Papagiannaki
        object_meta = self.get_object_meta(container, object, user=user)
477 3a19e99b Sofia Papagiannaki
        (self.assertTrue('X-Objecr-Meta-%s' % k in object_meta) for
478 3a19e99b Sofia Papagiannaki
            k in meta.keys())
479 3a19e99b Sofia Papagiannaki
        (self.assertEqual(object_meta['X-Object-Meta-%s' % k], v) for
480 3a19e99b Sofia Papagiannaki
            k, v in meta.items())
481 3a19e99b Sofia Papagiannaki
482 f3787696 Sofia Papagiannaki
    def assert_extended(self, data, format, type, size=10000):
483 f3787696 Sofia Papagiannaki
        if format == 'xml':
484 f3787696 Sofia Papagiannaki
            self._assert_xml(data, type, size)
485 f3787696 Sofia Papagiannaki
        elif format == 'json':
486 f3787696 Sofia Papagiannaki
            self._assert_json(data, type, size)
487 f3787696 Sofia Papagiannaki
488 f3787696 Sofia Papagiannaki
    def _assert_json(self, data, type, size):
489 f3787696 Sofia Papagiannaki
        convert = lambda s: s.lower()
490 f3787696 Sofia Papagiannaki
        info = [convert(elem) for elem in details[type]]
491 f3787696 Sofia Papagiannaki
        self.assertTrue(len(data) <= size)
492 f3787696 Sofia Papagiannaki
        for item in info:
493 f3787696 Sofia Papagiannaki
            for i in data:
494 f3787696 Sofia Papagiannaki
                if 'subdir' in i.keys():
495 f3787696 Sofia Papagiannaki
                    continue
496 f3787696 Sofia Papagiannaki
                self.assertTrue(item in i.keys())
497 f3787696 Sofia Papagiannaki
498 f3787696 Sofia Papagiannaki
    def _assert_xml(self, data, type, size):
499 f3787696 Sofia Papagiannaki
        convert = lambda s: s.lower()
500 f3787696 Sofia Papagiannaki
        info = [convert(elem) for elem in details[type]]
501 f3787696 Sofia Papagiannaki
        try:
502 f3787696 Sofia Papagiannaki
            info.remove('content_encoding')
503 f3787696 Sofia Papagiannaki
        except ValueError:
504 f3787696 Sofia Papagiannaki
            pass
505 f3787696 Sofia Papagiannaki
        xml = data
506 f3787696 Sofia Papagiannaki
        entities = xml.getElementsByTagName(type)
507 f3787696 Sofia Papagiannaki
        self.assertTrue(len(entities) <= size)
508 f3787696 Sofia Papagiannaki
        for e in entities:
509 f3787696 Sofia Papagiannaki
            for item in info:
510 f3787696 Sofia Papagiannaki
                self.assertTrue(e.getElementsByTagName(item))
511 f3787696 Sofia Papagiannaki
512 f3787696 Sofia Papagiannaki
513 f3787696 Sofia Papagiannaki
class AssertMappingInvariant(object):
514 f3787696 Sofia Papagiannaki
    def __init__(self, callable, *args, **kwargs):
515 f3787696 Sofia Papagiannaki
        self.callable = callable
516 f3787696 Sofia Papagiannaki
        self.args = args
517 f3787696 Sofia Papagiannaki
        self.kwargs = kwargs
518 f3787696 Sofia Papagiannaki
519 f3787696 Sofia Papagiannaki
    def __enter__(self):
520 f3787696 Sofia Papagiannaki
        self.map = self.callable(*self.args, **self.kwargs)
521 f3787696 Sofia Papagiannaki
        return self.map
522 f3787696 Sofia Papagiannaki
523 f3787696 Sofia Papagiannaki
    def __exit__(self, type, value, tb):
524 f3787696 Sofia Papagiannaki
        map = self.callable(*self.args, **self.kwargs)
525 f3787696 Sofia Papagiannaki
        for k, v in self.map.items():
526 f3787696 Sofia Papagiannaki
            if is_date(v):
527 f3787696 Sofia Papagiannaki
                continue
528 f3787696 Sofia Papagiannaki
529 f3787696 Sofia Papagiannaki
            assert(k in map), '%s not in map' % k
530 f3787696 Sofia Papagiannaki
            assert v == map[k]
531 f3787696 Sofia Papagiannaki
532 3a19e99b Sofia Papagiannaki
533 3a19e99b Sofia Papagiannaki
class AssertUUidInvariant(object):
534 3a19e99b Sofia Papagiannaki
    def __init__(self, callable, *args, **kwargs):
535 3a19e99b Sofia Papagiannaki
        self.callable = callable
536 3a19e99b Sofia Papagiannaki
        self.args = args
537 3a19e99b Sofia Papagiannaki
        self.kwargs = kwargs
538 3a19e99b Sofia Papagiannaki
539 3a19e99b Sofia Papagiannaki
    def __enter__(self):
540 3a19e99b Sofia Papagiannaki
        self.map = self.callable(*self.args, **self.kwargs)
541 3a19e99b Sofia Papagiannaki
        assert('x-object-uuid' in self.map)
542 3a19e99b Sofia Papagiannaki
        self.uuid = self.map['x-object-uuid']
543 3a19e99b Sofia Papagiannaki
        return self.map
544 3a19e99b Sofia Papagiannaki
545 3a19e99b Sofia Papagiannaki
    def __exit__(self, type, value, tb):
546 3a19e99b Sofia Papagiannaki
        map = self.callable(*self.args, **self.kwargs)
547 3a19e99b Sofia Papagiannaki
        assert('x-object-uuid' in self.map)
548 3a19e99b Sofia Papagiannaki
        uuid = map['x-object-uuid']
549 3a19e99b Sofia Papagiannaki
        assert(uuid == self.uuid)