root / snf-pithos-app / pithos / api / test / __init__.py @ 95b36144
History | View | Annotate | Download (18.4 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 | f3787696 | Sofia Papagiannaki | |
40 | f3787696 | Sofia Papagiannaki | from snf_django.utils.testing import with_settings, astakos_user |
41 | f3787696 | Sofia Papagiannaki | |
42 | f3787696 | Sofia Papagiannaki | from pithos.api import settings as pithos_settings |
43 | bc4f25c0 | Sofia Papagiannaki | from pithos.api.test.util import is_date, get_random_data, get_random_name |
44 | bc4f25c0 | Sofia Papagiannaki | from pithos.backends.migrate import initialize_db |
45 | f3787696 | Sofia Papagiannaki | |
46 | d6a92fa0 | Sofia Papagiannaki | from synnefo.lib.services import get_service_path |
47 | d6a92fa0 | Sofia Papagiannaki | from synnefo.lib import join_urls |
48 | d6a92fa0 | Sofia Papagiannaki | |
49 | f3787696 | Sofia Papagiannaki | from django.test import TestCase |
50 | bc4f25c0 | Sofia Papagiannaki | from django.test.simple import DjangoTestSuiteRunner |
51 | 7c36f3fb | Sofia Papagiannaki | from django.conf import settings |
52 | f3787696 | Sofia Papagiannaki | from django.utils.http import urlencode |
53 | bc4f25c0 | Sofia Papagiannaki | from django.db.backends.creation import TEST_DATABASE_PREFIX |
54 | f3787696 | Sofia Papagiannaki | |
55 | f3787696 | Sofia Papagiannaki | import django.utils.simplejson as json |
56 | f3787696 | Sofia Papagiannaki | |
57 | f3787696 | Sofia Papagiannaki | import random |
58 | f3787696 | Sofia Papagiannaki | import functools |
59 | f3787696 | Sofia Papagiannaki | |
60 | 3a19e99b | Sofia Papagiannaki | |
61 | f3787696 | Sofia Papagiannaki | pithos_test_settings = functools.partial(with_settings, pithos_settings) |
62 | f3787696 | Sofia Papagiannaki | |
63 | f3787696 | Sofia Papagiannaki | DATE_FORMATS = ["%a %b %d %H:%M:%S %Y",
|
64 | f3787696 | Sofia Papagiannaki | "%A, %d-%b-%y %H:%M:%S GMT",
|
65 | f3787696 | Sofia Papagiannaki | "%a, %d %b %Y %H:%M:%S GMT"]
|
66 | f3787696 | Sofia Papagiannaki | |
67 | f3787696 | Sofia Papagiannaki | o_names = ['kate.jpg',
|
68 | f3787696 | Sofia Papagiannaki | 'kate_beckinsale.jpg',
|
69 | f3787696 | Sofia Papagiannaki | 'How To Win Friends And Influence People.pdf',
|
70 | f3787696 | Sofia Papagiannaki | 'moms_birthday.jpg',
|
71 | f3787696 | Sofia Papagiannaki | 'poodle_strut.mov',
|
72 | f3787696 | Sofia Papagiannaki | 'Disturbed - Down With The Sickness.mp3',
|
73 | f3787696 | Sofia Papagiannaki | 'army_of_darkness.avi',
|
74 | f3787696 | Sofia Papagiannaki | 'the_mad.avi',
|
75 | f3787696 | Sofia Papagiannaki | 'photos/animals/dogs/poodle.jpg',
|
76 | f3787696 | Sofia Papagiannaki | 'photos/animals/dogs/terrier.jpg',
|
77 | f3787696 | Sofia Papagiannaki | 'photos/animals/cats/persian.jpg',
|
78 | f3787696 | Sofia Papagiannaki | 'photos/animals/cats/siamese.jpg',
|
79 | f3787696 | Sofia Papagiannaki | 'photos/plants/fern.jpg',
|
80 | f3787696 | Sofia Papagiannaki | 'photos/plants/rose.jpg',
|
81 | f3787696 | Sofia Papagiannaki | 'photos/me.jpg']
|
82 | f3787696 | Sofia Papagiannaki | |
83 | f3787696 | Sofia Papagiannaki | details = {'container': ('name', 'count', 'bytes', 'last_modified', |
84 | f3787696 | Sofia Papagiannaki | 'x_container_policy'),
|
85 | f3787696 | Sofia Papagiannaki | 'object': ('name', 'hash', 'bytes', 'content_type', |
86 | f3787696 | Sofia Papagiannaki | 'content_encoding', 'last_modified',)} |
87 | f3787696 | Sofia Papagiannaki | |
88 | 5fe43b8c | Sofia Papagiannaki | TEST_BLOCK_SIZE = 1024
|
89 | 5fe43b8c | Sofia Papagiannaki | TEST_HASH_ALGORITHM = 'sha256'
|
90 | 5fe43b8c | Sofia Papagiannaki | |
91 | bc4f25c0 | Sofia Papagiannaki | print 'backend module:', pithos_settings.BACKEND_DB_MODULE |
92 | bc4f25c0 | Sofia Papagiannaki | print 'backend database engine:', settings.DATABASES['default']['ENGINE'] |
93 | bc4f25c0 | Sofia Papagiannaki | print 'update md5:', pithos_settings.UPDATE_MD5 |
94 | 65f480f5 | Sofia Papagiannaki | |
95 | 65f480f5 | Sofia Papagiannaki | |
96 | bc4f25c0 | Sofia Papagiannaki | django_sqlalchemy_engines = { |
97 | bc4f25c0 | Sofia Papagiannaki | 'django.db.backends.postgresql_psycopg2': 'postgresql+psycopg2', |
98 | bc4f25c0 | Sofia Papagiannaki | 'django.db.backends.postgresql': 'postgresql', |
99 | bc4f25c0 | Sofia Papagiannaki | 'django.db.backends.mysql': '', |
100 | bc4f25c0 | Sofia Papagiannaki | 'django.db.backends.sqlite3': 'mssql', |
101 | bc4f25c0 | Sofia Papagiannaki | 'django.db.backends.oracle': 'oracle'} |
102 | 65f480f5 | Sofia Papagiannaki | |
103 | 65f480f5 | Sofia Papagiannaki | |
104 | bc4f25c0 | Sofia Papagiannaki | def prepate_db_connection(): |
105 | bc4f25c0 | Sofia Papagiannaki | """Build pithos backend connection string from django default database"""
|
106 | bc4f25c0 | Sofia Papagiannaki | |
107 | 65f480f5 | Sofia Papagiannaki | db = settings.DATABASES['default']
|
108 | bc4f25c0 | Sofia Papagiannaki | name = db.get('TEST_NAME', TEST_DATABASE_PREFIX + db['NAME']) |
109 | bc4f25c0 | Sofia Papagiannaki | |
110 | bc4f25c0 | Sofia Papagiannaki | if (pithos_settings.BACKEND_DB_MODULE == 'pithos.backends.lib.sqlalchemy'): |
111 | bc4f25c0 | Sofia Papagiannaki | if db['ENGINE'] == 'django.db.backends.sqlite3': |
112 | bc4f25c0 | Sofia Papagiannaki | db_connection = 'sqlite:///%s' % name
|
113 | bc4f25c0 | Sofia Papagiannaki | else:
|
114 | bc4f25c0 | Sofia Papagiannaki | d = dict(scheme=django_sqlalchemy_engines.get(db['ENGINE']), |
115 | bc4f25c0 | Sofia Papagiannaki | user=db['USER'],
|
116 | bc4f25c0 | Sofia Papagiannaki | pwd=db['PASSWORD'],
|
117 | bc4f25c0 | Sofia Papagiannaki | host=db['HOST'].lower(),
|
118 | bc4f25c0 | Sofia Papagiannaki | port=int(db['PORT']) if db['PORT'] != '' else '', |
119 | bc4f25c0 | Sofia Papagiannaki | name=name) |
120 | bc4f25c0 | Sofia Papagiannaki | db_connection = ( |
121 | bc4f25c0 | Sofia Papagiannaki | '%(scheme)s://%(user)s:%(pwd)s@%(host)s:%(port)s/%(name)s' % d)
|
122 | bc4f25c0 | Sofia Papagiannaki | |
123 | bc4f25c0 | Sofia Papagiannaki | # initialize pithos database
|
124 | bc4f25c0 | Sofia Papagiannaki | initialize_db(db_connection) |
125 | 65f480f5 | Sofia Papagiannaki | else:
|
126 | bc4f25c0 | Sofia Papagiannaki | db_connection = name |
127 | bc4f25c0 | Sofia Papagiannaki | pithos_settings.BACKEND_DB_CONNECTION = db_connection |
128 | bc4f25c0 | Sofia Papagiannaki | |
129 | bc4f25c0 | Sofia Papagiannaki | |
130 | bc4f25c0 | Sofia Papagiannaki | class PithosTestSuiteRunner(DjangoTestSuiteRunner): |
131 | bc4f25c0 | Sofia Papagiannaki | def setup_databases(self, **kwargs): |
132 | bc4f25c0 | Sofia Papagiannaki | old_names, mirrors = super(PithosTestSuiteRunner,
|
133 | bc4f25c0 | Sofia Papagiannaki | self).setup_databases(**kwargs)
|
134 | bc4f25c0 | Sofia Papagiannaki | prepate_db_connection() |
135 | bc4f25c0 | Sofia Papagiannaki | return old_names, mirrors
|
136 | 65f480f5 | Sofia Papagiannaki | |
137 | f3787696 | Sofia Papagiannaki | |
138 | f3787696 | Sofia Papagiannaki | class PithosAPITest(TestCase): |
139 | f3787696 | Sofia Papagiannaki | def setUp(self): |
140 | 369a7b41 | Sofia Papagiannaki | # Override default block size to spead up tests
|
141 | 5fe43b8c | Sofia Papagiannaki | pithos_settings.BACKEND_BLOCK_SIZE = TEST_BLOCK_SIZE |
142 | 5fe43b8c | Sofia Papagiannaki | pithos_settings.BACKEND_HASH_ALGORITHM = TEST_HASH_ALGORITHM |
143 | 369a7b41 | Sofia Papagiannaki | |
144 | f3787696 | Sofia Papagiannaki | self.user = 'user' |
145 | d6a92fa0 | Sofia Papagiannaki | self.pithos_path = join_urls(get_service_path(
|
146 | d6a92fa0 | Sofia Papagiannaki | pithos_settings.pithos_services, 'object-store'))
|
147 | f3787696 | Sofia Papagiannaki | |
148 | f3787696 | Sofia Papagiannaki | def tearDown(self): |
149 | f3787696 | Sofia Papagiannaki | #delete additionally created metadata
|
150 | f3787696 | Sofia Papagiannaki | meta = self.get_account_meta()
|
151 | f3787696 | Sofia Papagiannaki | self.delete_account_meta(meta)
|
152 | f3787696 | Sofia Papagiannaki | |
153 | f3787696 | Sofia Papagiannaki | #delete additionally created groups
|
154 | f3787696 | Sofia Papagiannaki | groups = self.get_account_groups()
|
155 | f3787696 | Sofia Papagiannaki | self.delete_account_groups(groups)
|
156 | f3787696 | Sofia Papagiannaki | |
157 | f3787696 | Sofia Papagiannaki | self._clean_account()
|
158 | f3787696 | Sofia Papagiannaki | |
159 | 65f480f5 | Sofia Papagiannaki | def _clean_account(self): |
160 | 65f480f5 | Sofia Papagiannaki | for c in self.list_containers(): |
161 | 65f480f5 | Sofia Papagiannaki | self.delete_container_content(c['name']) |
162 | 65f480f5 | Sofia Papagiannaki | self.delete_container(c['name']) |
163 | 65f480f5 | Sofia Papagiannaki | |
164 | f3787696 | Sofia Papagiannaki | def head(self, url, user='user', *args, **kwargs): |
165 | f3787696 | Sofia Papagiannaki | with astakos_user(user):
|
166 | f3787696 | Sofia Papagiannaki | response = self.client.head(url, *args, **kwargs)
|
167 | f3787696 | Sofia Papagiannaki | return response
|
168 | f3787696 | Sofia Papagiannaki | |
169 | f3787696 | Sofia Papagiannaki | def get(self, url, user='user', *args, **kwargs): |
170 | f3787696 | Sofia Papagiannaki | with astakos_user(user):
|
171 | f3787696 | Sofia Papagiannaki | response = self.client.get(url, *args, **kwargs)
|
172 | f3787696 | Sofia Papagiannaki | return response
|
173 | f3787696 | Sofia Papagiannaki | |
174 | f3787696 | Sofia Papagiannaki | def delete(self, url, user='user', *args, **kwargs): |
175 | f3787696 | Sofia Papagiannaki | with astakos_user(user):
|
176 | f3787696 | Sofia Papagiannaki | response = self.client.delete(url, *args, **kwargs)
|
177 | f3787696 | Sofia Papagiannaki | return response
|
178 | f3787696 | Sofia Papagiannaki | |
179 | f3787696 | Sofia Papagiannaki | def post(self, url, user='user', *args, **kwargs): |
180 | f3787696 | Sofia Papagiannaki | with astakos_user(user):
|
181 | f3787696 | Sofia Papagiannaki | kwargs.setdefault('content_type', 'application/octet-stream') |
182 | f3787696 | Sofia Papagiannaki | response = self.client.post(url, *args, **kwargs)
|
183 | f3787696 | Sofia Papagiannaki | return response
|
184 | f3787696 | Sofia Papagiannaki | |
185 | f3787696 | Sofia Papagiannaki | def put(self, url, user='user', *args, **kwargs): |
186 | f3787696 | Sofia Papagiannaki | with astakos_user(user):
|
187 | f3787696 | Sofia Papagiannaki | kwargs.setdefault('content_type', 'application/octet-stream') |
188 | f3787696 | Sofia Papagiannaki | response = self.client.put(url, *args, **kwargs)
|
189 | f3787696 | Sofia Papagiannaki | return response
|
190 | f3787696 | Sofia Papagiannaki | |
191 | f3787696 | Sofia Papagiannaki | def update_account_meta(self, meta): |
192 | f3787696 | Sofia Papagiannaki | kwargs = dict(
|
193 | f3787696 | Sofia Papagiannaki | ('HTTP_X_ACCOUNT_META_%s' % k, str(v)) for k, v in meta.items()) |
194 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user) |
195 | d6a92fa0 | Sofia Papagiannaki | r = self.post('%s?update=' % url, **kwargs) |
196 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 202) |
197 | f3787696 | Sofia Papagiannaki | account_meta = self.get_account_meta()
|
198 | f3787696 | Sofia Papagiannaki | (self.assertTrue('X-Account-Meta-%s' % k in account_meta) for |
199 | f3787696 | Sofia Papagiannaki | k in meta.keys())
|
200 | f3787696 | Sofia Papagiannaki | (self.assertEqual(account_meta['X-Account-Meta-%s' % k], v) for |
201 | f3787696 | Sofia Papagiannaki | k, v in meta.items())
|
202 | f3787696 | Sofia Papagiannaki | |
203 | f3787696 | Sofia Papagiannaki | def reset_account_meta(self, meta): |
204 | f3787696 | Sofia Papagiannaki | kwargs = dict(
|
205 | f3787696 | Sofia Papagiannaki | ('HTTP_X_ACCOUNT_META_%s' % k, str(v)) for k, v in meta.items()) |
206 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user) |
207 | d6a92fa0 | Sofia Papagiannaki | r = self.post(url, **kwargs)
|
208 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 202) |
209 | f3787696 | Sofia Papagiannaki | account_meta = self.get_account_meta()
|
210 | f3787696 | Sofia Papagiannaki | (self.assertTrue('X-Account-Meta-%s' % k in account_meta) for |
211 | f3787696 | Sofia Papagiannaki | k in meta.keys())
|
212 | f3787696 | Sofia Papagiannaki | (self.assertEqual(account_meta['X-Account-Meta-%s' % k], v) for |
213 | f3787696 | Sofia Papagiannaki | k, v in meta.items())
|
214 | f3787696 | Sofia Papagiannaki | |
215 | f3787696 | Sofia Papagiannaki | def delete_account_meta(self, meta): |
216 | f3787696 | Sofia Papagiannaki | transform = lambda k: 'HTTP_%s' % k.replace('-', '_').upper() |
217 | f3787696 | Sofia Papagiannaki | kwargs = dict((transform(k), '') for k, v in meta.items()) |
218 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user) |
219 | d6a92fa0 | Sofia Papagiannaki | r = self.post('%s?update=' % url, **kwargs) |
220 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 202) |
221 | f3787696 | Sofia Papagiannaki | account_meta = self.get_account_meta()
|
222 | f3787696 | Sofia Papagiannaki | (self.assertTrue('X-Account-Meta-%s' % k not in account_meta) for |
223 | f3787696 | Sofia Papagiannaki | k in meta.keys())
|
224 | f3787696 | Sofia Papagiannaki | return r
|
225 | f3787696 | Sofia Papagiannaki | |
226 | f3787696 | Sofia Papagiannaki | def delete_account_groups(self, groups): |
227 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user) |
228 | d6a92fa0 | Sofia Papagiannaki | r = self.post('%s?update=' % url, **groups) |
229 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 202) |
230 | f3787696 | Sofia Papagiannaki | return r
|
231 | f3787696 | Sofia Papagiannaki | |
232 | f3787696 | Sofia Papagiannaki | def get_account_info(self, until=None): |
233 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user) |
234 | f3787696 | Sofia Papagiannaki | if until is not None: |
235 | f3787696 | Sofia Papagiannaki | parts = list(urlsplit(url))
|
236 | f3787696 | Sofia Papagiannaki | parts[3] = urlencode({
|
237 | f3787696 | Sofia Papagiannaki | 'until': until
|
238 | f3787696 | Sofia Papagiannaki | }) |
239 | f3787696 | Sofia Papagiannaki | url = urlunsplit(parts) |
240 | f3787696 | Sofia Papagiannaki | r = self.head(url)
|
241 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 204) |
242 | f3787696 | Sofia Papagiannaki | return r
|
243 | f3787696 | Sofia Papagiannaki | |
244 | f3787696 | Sofia Papagiannaki | def get_account_meta(self, until=None): |
245 | f3787696 | Sofia Papagiannaki | r = self.get_account_info(until=until)
|
246 | f3787696 | Sofia Papagiannaki | headers = dict(r._headers.values())
|
247 | f3787696 | Sofia Papagiannaki | map(headers.pop,
|
248 | f3787696 | Sofia Papagiannaki | [k for k in headers.keys() |
249 | f3787696 | Sofia Papagiannaki | if not k.startswith('X-Account-Meta-')]) |
250 | f3787696 | Sofia Papagiannaki | return headers
|
251 | f3787696 | Sofia Papagiannaki | |
252 | f3787696 | Sofia Papagiannaki | def get_account_groups(self, until=None): |
253 | f3787696 | Sofia Papagiannaki | r = self.get_account_info(until=until)
|
254 | f3787696 | Sofia Papagiannaki | headers = dict(r._headers.values())
|
255 | f3787696 | Sofia Papagiannaki | map(headers.pop,
|
256 | f3787696 | Sofia Papagiannaki | [k for k in headers.keys() |
257 | f3787696 | Sofia Papagiannaki | if not k.startswith('X-Account-Group-')]) |
258 | f3787696 | Sofia Papagiannaki | return headers
|
259 | f3787696 | Sofia Papagiannaki | |
260 | 3a19e99b | Sofia Papagiannaki | def get_container_info(self, container, until=None): |
261 | 3a19e99b | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, container) |
262 | 3a19e99b | Sofia Papagiannaki | if until is not None: |
263 | 3a19e99b | Sofia Papagiannaki | parts = list(urlsplit(url))
|
264 | 3a19e99b | Sofia Papagiannaki | parts[3] = urlencode({
|
265 | 3a19e99b | Sofia Papagiannaki | 'until': until
|
266 | 3a19e99b | Sofia Papagiannaki | }) |
267 | 3a19e99b | Sofia Papagiannaki | url = urlunsplit(parts) |
268 | 3a19e99b | Sofia Papagiannaki | r = self.head(url)
|
269 | 3a19e99b | Sofia Papagiannaki | self.assertEqual(r.status_code, 204) |
270 | 3a19e99b | Sofia Papagiannaki | return r
|
271 | 3a19e99b | Sofia Papagiannaki | |
272 | 3a19e99b | Sofia Papagiannaki | def get_container_meta(self, container, until=None): |
273 | 3a19e99b | Sofia Papagiannaki | r = self.get_container_info(container, until=until)
|
274 | 3a19e99b | Sofia Papagiannaki | headers = dict(r._headers.values())
|
275 | 3a19e99b | Sofia Papagiannaki | map(headers.pop,
|
276 | 3a19e99b | Sofia Papagiannaki | [k for k in headers.keys() |
277 | 3a19e99b | Sofia Papagiannaki | if not k.startswith('X-Container-Meta-')]) |
278 | 3a19e99b | Sofia Papagiannaki | return headers
|
279 | 3a19e99b | Sofia Papagiannaki | |
280 | 3a19e99b | Sofia Papagiannaki | def update_container_meta(self, container, meta): |
281 | 3a19e99b | Sofia Papagiannaki | kwargs = dict(
|
282 | 3a19e99b | Sofia Papagiannaki | ('HTTP_X_CONTAINER_META_%s' % k, str(v)) for k, v in meta.items()) |
283 | 3a19e99b | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, container) |
284 | 3a19e99b | Sofia Papagiannaki | r = self.post('%s?update=' % url, **kwargs) |
285 | 3a19e99b | Sofia Papagiannaki | self.assertEqual(r.status_code, 202) |
286 | 3a19e99b | Sofia Papagiannaki | container_meta = self.get_container_meta(container)
|
287 | 3a19e99b | Sofia Papagiannaki | (self.assertTrue('X-Container-Meta-%s' % k in container_meta) for |
288 | 3a19e99b | Sofia Papagiannaki | k in meta.keys())
|
289 | 3a19e99b | Sofia Papagiannaki | (self.assertEqual(container_meta['X-Container-Meta-%s' % k], v) for |
290 | 3a19e99b | Sofia Papagiannaki | k, v in meta.items())
|
291 | 3a19e99b | Sofia Papagiannaki | |
292 | f3787696 | Sofia Papagiannaki | def list_containers(self, format='json', headers={}, **params): |
293 | d6a92fa0 | Sofia Papagiannaki | _url = join_urls(self.pithos_path, self.user) |
294 | d6a92fa0 | Sofia Papagiannaki | parts = list(urlsplit(_url))
|
295 | f3787696 | Sofia Papagiannaki | params['format'] = format
|
296 | f3787696 | Sofia Papagiannaki | parts[3] = urlencode(params)
|
297 | f3787696 | Sofia Papagiannaki | url = urlunsplit(parts) |
298 | f3787696 | Sofia Papagiannaki | _headers = dict(('HTTP_%s' % k.upper(), str(v)) |
299 | f3787696 | Sofia Papagiannaki | for k, v in headers.items()) |
300 | f3787696 | Sofia Papagiannaki | r = self.get(url, **_headers)
|
301 | f3787696 | Sofia Papagiannaki | |
302 | f3787696 | Sofia Papagiannaki | if format is None: |
303 | f3787696 | Sofia Papagiannaki | containers = r.content.split('\n')
|
304 | f3787696 | Sofia Papagiannaki | if '' in containers: |
305 | f3787696 | Sofia Papagiannaki | containers.remove('')
|
306 | f3787696 | Sofia Papagiannaki | return containers
|
307 | f3787696 | Sofia Papagiannaki | elif format == 'json': |
308 | f3787696 | Sofia Papagiannaki | try:
|
309 | f3787696 | Sofia Papagiannaki | containers = json.loads(r.content) |
310 | f3787696 | Sofia Papagiannaki | except:
|
311 | f3787696 | Sofia Papagiannaki | self.fail('json format expected') |
312 | f3787696 | Sofia Papagiannaki | return containers
|
313 | f3787696 | Sofia Papagiannaki | elif format == 'xml': |
314 | f3787696 | Sofia Papagiannaki | return minidom.parseString(r.content)
|
315 | f3787696 | Sofia Papagiannaki | |
316 | f3787696 | Sofia Papagiannaki | def delete_container_content(self, cname): |
317 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, cname) |
318 | d6a92fa0 | Sofia Papagiannaki | r = self.delete('%s?delimiter=/' % url) |
319 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 204) |
320 | f3787696 | Sofia Papagiannaki | return r
|
321 | f3787696 | Sofia Papagiannaki | |
322 | f3787696 | Sofia Papagiannaki | def delete_container(self, cname): |
323 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, cname) |
324 | d6a92fa0 | Sofia Papagiannaki | r = self.delete(url)
|
325 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 204) |
326 | f3787696 | Sofia Papagiannaki | return r
|
327 | f3787696 | Sofia Papagiannaki | |
328 | 95b36144 | Sofia Papagiannaki | def create_container(self, cname=None): |
329 | 95b36144 | Sofia Papagiannaki | cname = cname or get_random_name()
|
330 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, cname) |
331 | d6a92fa0 | Sofia Papagiannaki | r = self.put(url, data='') |
332 | f3787696 | Sofia Papagiannaki | self.assertTrue(r.status_code in (202, 201)) |
333 | 95b36144 | Sofia Papagiannaki | return cname, r
|
334 | f3787696 | Sofia Papagiannaki | |
335 | 5fe43b8c | Sofia Papagiannaki | def upload_object(self, cname, oname=None, length=None, verify=True, |
336 | 3a19e99b | Sofia Papagiannaki | **meta): |
337 | bc4f25c0 | Sofia Papagiannaki | oname = oname or get_random_name()
|
338 | 5fe43b8c | Sofia Papagiannaki | length = length or random.randint(TEST_BLOCK_SIZE, 2 * TEST_BLOCK_SIZE) |
339 | 3a19e99b | Sofia Papagiannaki | data = get_random_data(length=length) |
340 | f3787696 | Sofia Papagiannaki | headers = dict(('HTTP_X_OBJECT_META_%s' % k.upper(), v) |
341 | f3787696 | Sofia Papagiannaki | for k, v in meta.iteritems()) |
342 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, cname, oname) |
343 | d6a92fa0 | Sofia Papagiannaki | r = self.put(url, data=data, **headers)
|
344 | 3a19e99b | Sofia Papagiannaki | if verify:
|
345 | 3a19e99b | Sofia Papagiannaki | self.assertEqual(r.status_code, 201) |
346 | 3a19e99b | Sofia Papagiannaki | return oname, data, r
|
347 | 3a19e99b | Sofia Papagiannaki | |
348 | 3a19e99b | Sofia Papagiannaki | def update_object_data(self, cname, oname=None, length=None, |
349 | 3a19e99b | Sofia Papagiannaki | content_type=None, content_range=None, |
350 | 3a19e99b | Sofia Papagiannaki | verify=True, **meta):
|
351 | bc4f25c0 | Sofia Papagiannaki | oname = oname or get_random_name()
|
352 | 5fe43b8c | Sofia Papagiannaki | length = length or random.randint(TEST_BLOCK_SIZE, 2 * TEST_BLOCK_SIZE) |
353 | 3a19e99b | Sofia Papagiannaki | content_type = content_type or 'application/octet-stream' |
354 | 3a19e99b | Sofia Papagiannaki | data = get_random_data(length=length) |
355 | 3a19e99b | Sofia Papagiannaki | headers = dict(('HTTP_X_OBJECT_META_%s' % k.upper(), v) |
356 | 3a19e99b | Sofia Papagiannaki | for k, v in meta.iteritems()) |
357 | 3a19e99b | Sofia Papagiannaki | if content_range:
|
358 | 3a19e99b | Sofia Papagiannaki | headers['HTTP_CONTENT_RANGE'] = content_range
|
359 | 3a19e99b | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, cname, oname) |
360 | 3a19e99b | Sofia Papagiannaki | r = self.post(url, data=data, content_type=content_type, **headers)
|
361 | 3a19e99b | Sofia Papagiannaki | if verify:
|
362 | 3a19e99b | Sofia Papagiannaki | self.assertEqual(r.status_code, 204) |
363 | f3787696 | Sofia Papagiannaki | return oname, data, r
|
364 | f3787696 | Sofia Papagiannaki | |
365 | 3a19e99b | Sofia Papagiannaki | def append_object_data(self, cname, oname=None, length=None, |
366 | 3a19e99b | Sofia Papagiannaki | content_type=None):
|
367 | 3a19e99b | Sofia Papagiannaki | return self.update_object_data(cname, oname=oname, |
368 | 3a19e99b | Sofia Papagiannaki | length=length, |
369 | 3a19e99b | Sofia Papagiannaki | content_type=content_type, |
370 | 3a19e99b | Sofia Papagiannaki | content_range='bytes */*')
|
371 | 3a19e99b | Sofia Papagiannaki | |
372 | 3a19e99b | Sofia Papagiannaki | def create_folder(self, cname, oname=None, **headers): |
373 | bc4f25c0 | Sofia Papagiannaki | oname = oname or get_random_name()
|
374 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, cname, oname) |
375 | d6a92fa0 | Sofia Papagiannaki | r = self.put(url, data='', content_type='application/directory', |
376 | d6a92fa0 | Sofia Papagiannaki | **headers) |
377 | f3787696 | Sofia Papagiannaki | self.assertEqual(r.status_code, 201) |
378 | f3787696 | Sofia Papagiannaki | return oname, r
|
379 | f3787696 | Sofia Papagiannaki | |
380 | 3a19e99b | Sofia Papagiannaki | def list_objects(self, cname, prefix=None): |
381 | d6a92fa0 | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, cname) |
382 | 3a19e99b | Sofia Papagiannaki | path = '%s?format=json' % url
|
383 | 3a19e99b | Sofia Papagiannaki | if prefix is not None: |
384 | 3a19e99b | Sofia Papagiannaki | path = '%s&prefix=%s' % (path, prefix)
|
385 | 3a19e99b | Sofia Papagiannaki | r = self.get(path)
|
386 | f3787696 | Sofia Papagiannaki | self.assertTrue(r.status_code in (200, 204)) |
387 | f3787696 | Sofia Papagiannaki | try:
|
388 | f3787696 | Sofia Papagiannaki | objects = json.loads(r.content) |
389 | f3787696 | Sofia Papagiannaki | except:
|
390 | f3787696 | Sofia Papagiannaki | self.fail('json format expected') |
391 | f3787696 | Sofia Papagiannaki | return objects
|
392 | f3787696 | Sofia Papagiannaki | |
393 | 3a19e99b | Sofia Papagiannaki | def get_object_info(self, container, object, version=None, until=None): |
394 | 3a19e99b | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, container, object) |
395 | 3a19e99b | Sofia Papagiannaki | if until is not None: |
396 | 3a19e99b | Sofia Papagiannaki | parts = list(urlsplit(url))
|
397 | 3a19e99b | Sofia Papagiannaki | parts[3] = urlencode({
|
398 | 3a19e99b | Sofia Papagiannaki | 'until': until
|
399 | 3a19e99b | Sofia Papagiannaki | }) |
400 | 3a19e99b | Sofia Papagiannaki | url = urlunsplit(parts) |
401 | 3a19e99b | Sofia Papagiannaki | if version:
|
402 | 3a19e99b | Sofia Papagiannaki | url = '%s?version=%s' % (url, version)
|
403 | 3a19e99b | Sofia Papagiannaki | r = self.head(url)
|
404 | 3a19e99b | Sofia Papagiannaki | self.assertEqual(r.status_code, 200) |
405 | 3a19e99b | Sofia Papagiannaki | return r
|
406 | 3a19e99b | Sofia Papagiannaki | |
407 | 3a19e99b | Sofia Papagiannaki | def get_object_meta(self, container, object, version=None, until=None): |
408 | 3a19e99b | Sofia Papagiannaki | r = self.get_object_info(container, object, version, until=until) |
409 | 3a19e99b | Sofia Papagiannaki | headers = dict(r._headers.values())
|
410 | 3a19e99b | Sofia Papagiannaki | map(headers.pop,
|
411 | 3a19e99b | Sofia Papagiannaki | [k for k in headers.keys() |
412 | 3a19e99b | Sofia Papagiannaki | if not k.startswith('X-Object-Meta-')]) |
413 | 3a19e99b | Sofia Papagiannaki | return headers
|
414 | 3a19e99b | Sofia Papagiannaki | |
415 | 3a19e99b | Sofia Papagiannaki | def update_object_meta(self, container, object, meta): |
416 | 3a19e99b | Sofia Papagiannaki | kwargs = dict(
|
417 | 3a19e99b | Sofia Papagiannaki | ('HTTP_X_OBJECT_META_%s' % k, str(v)) for k, v in meta.items()) |
418 | 3a19e99b | Sofia Papagiannaki | url = join_urls(self.pithos_path, self.user, container, object) |
419 | 3a19e99b | Sofia Papagiannaki | r = self.post('%s?update=' % url, content_type='', **kwargs) |
420 | 3a19e99b | Sofia Papagiannaki | self.assertEqual(r.status_code, 202) |
421 | 3a19e99b | Sofia Papagiannaki | object_meta = self.get_object_meta(container, object) |
422 | 3a19e99b | Sofia Papagiannaki | (self.assertTrue('X-Objecr-Meta-%s' % k in object_meta) for |
423 | 3a19e99b | Sofia Papagiannaki | k in meta.keys())
|
424 | 3a19e99b | Sofia Papagiannaki | (self.assertEqual(object_meta['X-Object-Meta-%s' % k], v) for |
425 | 3a19e99b | Sofia Papagiannaki | k, v in meta.items())
|
426 | 3a19e99b | Sofia Papagiannaki | |
427 | f3787696 | Sofia Papagiannaki | def assert_extended(self, data, format, type, size=10000): |
428 | f3787696 | Sofia Papagiannaki | if format == 'xml': |
429 | f3787696 | Sofia Papagiannaki | self._assert_xml(data, type, size) |
430 | f3787696 | Sofia Papagiannaki | elif format == 'json': |
431 | f3787696 | Sofia Papagiannaki | self._assert_json(data, type, size) |
432 | f3787696 | Sofia Papagiannaki | |
433 | f3787696 | Sofia Papagiannaki | def _assert_json(self, data, type, size): |
434 | f3787696 | Sofia Papagiannaki | convert = lambda s: s.lower()
|
435 | f3787696 | Sofia Papagiannaki | info = [convert(elem) for elem in details[type]] |
436 | f3787696 | Sofia Papagiannaki | self.assertTrue(len(data) <= size) |
437 | f3787696 | Sofia Papagiannaki | for item in info: |
438 | f3787696 | Sofia Papagiannaki | for i in data: |
439 | f3787696 | Sofia Papagiannaki | if 'subdir' in i.keys(): |
440 | f3787696 | Sofia Papagiannaki | continue
|
441 | f3787696 | Sofia Papagiannaki | self.assertTrue(item in i.keys()) |
442 | f3787696 | Sofia Papagiannaki | |
443 | f3787696 | Sofia Papagiannaki | def _assert_xml(self, data, type, size): |
444 | f3787696 | Sofia Papagiannaki | convert = lambda s: s.lower()
|
445 | f3787696 | Sofia Papagiannaki | info = [convert(elem) for elem in details[type]] |
446 | f3787696 | Sofia Papagiannaki | try:
|
447 | f3787696 | Sofia Papagiannaki | info.remove('content_encoding')
|
448 | f3787696 | Sofia Papagiannaki | except ValueError: |
449 | f3787696 | Sofia Papagiannaki | pass
|
450 | f3787696 | Sofia Papagiannaki | xml = data |
451 | f3787696 | Sofia Papagiannaki | entities = xml.getElementsByTagName(type)
|
452 | f3787696 | Sofia Papagiannaki | self.assertTrue(len(entities) <= size) |
453 | f3787696 | Sofia Papagiannaki | for e in entities: |
454 | f3787696 | Sofia Papagiannaki | for item in info: |
455 | f3787696 | Sofia Papagiannaki | self.assertTrue(e.getElementsByTagName(item))
|
456 | f3787696 | Sofia Papagiannaki | |
457 | f3787696 | Sofia Papagiannaki | |
458 | f3787696 | Sofia Papagiannaki | class AssertMappingInvariant(object): |
459 | f3787696 | Sofia Papagiannaki | def __init__(self, callable, *args, **kwargs): |
460 | f3787696 | Sofia Papagiannaki | self.callable = callable |
461 | f3787696 | Sofia Papagiannaki | self.args = args
|
462 | f3787696 | Sofia Papagiannaki | self.kwargs = kwargs
|
463 | f3787696 | Sofia Papagiannaki | |
464 | f3787696 | Sofia Papagiannaki | def __enter__(self): |
465 | f3787696 | Sofia Papagiannaki | self.map = self.callable(*self.args, **self.kwargs) |
466 | f3787696 | Sofia Papagiannaki | return self.map |
467 | f3787696 | Sofia Papagiannaki | |
468 | f3787696 | Sofia Papagiannaki | def __exit__(self, type, value, tb): |
469 | f3787696 | Sofia Papagiannaki | map = self.callable(*self.args, **self.kwargs) |
470 | f3787696 | Sofia Papagiannaki | for k, v in self.map.items(): |
471 | f3787696 | Sofia Papagiannaki | if is_date(v):
|
472 | f3787696 | Sofia Papagiannaki | continue
|
473 | f3787696 | Sofia Papagiannaki | |
474 | f3787696 | Sofia Papagiannaki | assert(k in map), '%s not in map' % k |
475 | f3787696 | Sofia Papagiannaki | assert v == map[k] |
476 | f3787696 | Sofia Papagiannaki | |
477 | 3a19e99b | Sofia Papagiannaki | |
478 | 3a19e99b | Sofia Papagiannaki | class AssertUUidInvariant(object): |
479 | 3a19e99b | Sofia Papagiannaki | def __init__(self, callable, *args, **kwargs): |
480 | 3a19e99b | Sofia Papagiannaki | self.callable = callable |
481 | 3a19e99b | Sofia Papagiannaki | self.args = args
|
482 | 3a19e99b | Sofia Papagiannaki | self.kwargs = kwargs
|
483 | 3a19e99b | Sofia Papagiannaki | |
484 | 3a19e99b | Sofia Papagiannaki | def __enter__(self): |
485 | 3a19e99b | Sofia Papagiannaki | self.map = self.callable(*self.args, **self.kwargs) |
486 | 3a19e99b | Sofia Papagiannaki | assert('x-object-uuid' in self.map) |
487 | 3a19e99b | Sofia Papagiannaki | self.uuid = self.map['x-object-uuid'] |
488 | 3a19e99b | Sofia Papagiannaki | return self.map |
489 | 3a19e99b | Sofia Papagiannaki | |
490 | 3a19e99b | Sofia Papagiannaki | def __exit__(self, type, value, tb): |
491 | 3a19e99b | Sofia Papagiannaki | map = self.callable(*self.args, **self.kwargs) |
492 | 3a19e99b | Sofia Papagiannaki | assert('x-object-uuid' in self.map) |
493 | 3a19e99b | Sofia Papagiannaki | uuid = map['x-object-uuid'] |
494 | 3a19e99b | Sofia Papagiannaki | assert(uuid == self.uuid) |