Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / dulwich / contrib / test_swift.py @ 959

History | View | Annotate | Download (24.1 KB)

1
# test_swift.py -- Unittests for the Swift backend.
2
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
3
#
4
# Author: Fabien Boucher <fabien.boucher@enovance.com>
5
#
6
# Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
7
# General Public License as public by the Free Software Foundation; version 2.0
8
# or (at your option) any later version. You can redistribute it and/or
9
# modify it under the terms of either of these two licenses.
10
#
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
16
#
17
# You should have received a copy of the licenses; if not, see
18
# <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
19
# and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
20
# License, Version 2.0.
21
#
22

    
23
"""Tests for dulwich.contrib.swift."""
24

    
25
import posixpath
26

    
27
from time import time
28
from io import BytesIO
29
try:
30
    from StringIO import StringIO
31
except ImportError:
32
    from io import StringIO
33

    
34
import sys
35
from unittest import skipIf
36

    
37
from dulwich.tests import (
38
    TestCase,
39
    )
40
from dulwich.tests.test_object_store import (
41
    ObjectStoreTests,
42
    )
43
from dulwich.tests.utils import (
44
    build_pack,
45
    )
46
from dulwich.objects import (
47
    Blob,
48
    Commit,
49
    Tree,
50
    Tag,
51
    parse_timezone,
52
    )
53
from dulwich.pack import (
54
    REF_DELTA,
55
    write_pack_index_v2,
56
    PackData,
57
    load_pack_index_file,
58
    )
59

    
60
try:
61
    from simplejson import dumps as json_dumps
62
except ImportError:
63
    from json import dumps as json_dumps
64

    
65
missing_libs = []
66

    
67
try:
68
    import gevent
69
except ImportError:
70
    missing_libs.append("gevent")
71

    
72
try:
73
    import geventhttpclient
74
except ImportError:
75
    missing_libs.append("geventhttpclient")
76

    
77
try:
78
    from mock import patch
79
except ImportError:
80
    missing_libs.append("mock")
81

    
82
skipmsg = "Required libraries are not installed (%r)" % missing_libs
83

    
84
skipIfPY3 = skipIf(sys.version_info[0] == 3, "SWIFT module not yet ported to python3.")
85

    
86
if not missing_libs:
87
    from dulwich.contrib import swift
88

    
89
config_file = """[swift]
90
auth_url = http://127.0.0.1:8080/auth/%(version_str)s
91
auth_ver = %(version_int)s
92
username = test;tester
93
password = testing
94
region_name = %(region_name)s
95
endpoint_type = %(endpoint_type)s
96
concurrency = %(concurrency)s
97
chunk_length = %(chunk_length)s
98
cache_length = %(cache_length)s
99
http_pool_length = %(http_pool_length)s
100
http_timeout = %(http_timeout)s
101
"""
102

    
103
def_config_file = {'version_str': 'v1.0',
104
                   'version_int': 1,
105
                   'concurrency': 1,
106
                   'chunk_length': 12228,
107
                   'cache_length': 1,
108
                   'region_name': 'test',
109
                   'endpoint_type': 'internalURL',
110
                   'http_pool_length': 1,
111
                   'http_timeout': 1}
112

    
113

    
114
def create_swift_connector(store={}):
115
    return lambda root, conf: FakeSwiftConnector(root,
116
                                                 conf=conf,
117
                                                 store=store)
118

    
119

    
120
class Response(object):
121

    
122
    def __init__(self, headers={}, status=200, content=None):
123
        self.headers = headers
124
        self.status_code = status
125
        self.content = content
126

    
127
    def __getitem__(self, key):
128
        return self.headers[key]
129

    
130
    def items(self):
131
        return self.headers.items()
132

    
133
    def read(self):
134
        return self.content
135

    
136

    
137
def fake_auth_request_v1(*args, **kwargs):
138
    ret = Response({'X-Storage-Url':
139
                    'http://127.0.0.1:8080/v1.0/AUTH_fakeuser',
140
                    'X-Auth-Token': '12' * 10},
141
                   200)
142
    return ret
143

    
144

    
145
def fake_auth_request_v1_error(*args, **kwargs):
146
    ret = Response({},
147
                   401)
148
    return ret
149

    
150

    
151
def fake_auth_request_v2(*args, **kwargs):
152
    s_url = 'http://127.0.0.1:8080/v1.0/AUTH_fakeuser'
153
    resp = {'access': {'token': {'id': '12' * 10},
154
                       'serviceCatalog':
155
                       [
156
                           {'type': 'object-store',
157
                            'endpoints': [{'region': 'test',
158
                                          'internalURL': s_url,
159
                                           },
160
                                          ]
161
                            },
162
                       ]
163
                       }
164
            }
165
    ret = Response(status=200, content=json_dumps(resp))
166
    return ret
167

    
168

    
169
def create_commit(data, marker=b'Default', blob=None):
170
    if not blob:
171
        blob = Blob.from_string(b'The blob content ' + marker)
172
    tree = Tree()
173
    tree.add(b"thefile_" + marker, 0o100644, blob.id)
174
    cmt = Commit()
175
    if data:
176
        assert isinstance(data[-1], Commit)
177
        cmt.parents = [data[-1].id]
178
    cmt.tree = tree.id
179
    author = b"John Doe " + marker + b" <john@doe.net>"
180
    cmt.author = cmt.committer = author
181
    tz = parse_timezone(b'-0200')[0]
182
    cmt.commit_time = cmt.author_time = int(time())
183
    cmt.commit_timezone = cmt.author_timezone = tz
184
    cmt.encoding = b"UTF-8"
185
    cmt.message = b"The commit message " + marker
186
    tag = Tag()
187
    tag.tagger = b"john@doe.net"
188
    tag.message = b"Annotated tag"
189
    tag.tag_timezone = parse_timezone(b'-0200')[0]
190
    tag.tag_time = cmt.author_time
191
    tag.object = (Commit, cmt.id)
192
    tag.name = b"v_" + marker + b"_0.1"
193
    return blob, tree, tag, cmt
194

    
195

    
196
def create_commits(length=1, marker=b'Default'):
197
    data = []
198
    for i in range(0, length):
199
        _marker = ("%s_%s" % (marker, i)).encode()
200
        blob, tree, tag, cmt = create_commit(data, _marker)
201
        data.extend([blob, tree, tag, cmt])
202
    return data
203

    
204
@skipIf(missing_libs, skipmsg)
205
class FakeSwiftConnector(object):
206

    
207
    def __init__(self, root, conf, store=None):
208
        if store:
209
            self.store = store
210
        else:
211
            self.store = {}
212
        self.conf = conf
213
        self.root = root
214
        self.concurrency = 1
215
        self.chunk_length = 12228
216
        self.cache_length = 1
217

    
218
    def put_object(self, name, content):
219
        name = posixpath.join(self.root, name)
220
        if hasattr(content, 'seek'):
221
            content.seek(0)
222
            content = content.read()
223
        self.store[name] = content
224

    
225
    def get_object(self, name, range=None):
226
        name = posixpath.join(self.root, name)
227
        if not range:
228
            try:
229
                return BytesIO(self.store[name])
230
            except KeyError:
231
                return None
232
        else:
233
            l, r = range.split('-')
234
            try:
235
                if not l:
236
                    r = -int(r)
237
                    return self.store[name][r:]
238
                else:
239
                    return self.store[name][int(l):int(r)]
240
            except KeyError:
241
                return None
242

    
243
    def get_container_objects(self):
244
        return [{'name': k.replace(self.root + '/', '')}
245
                for k in self.store]
246

    
247
    def create_root(self):
248
        if self.root in self.store.keys():
249
            pass
250
        else:
251
            self.store[self.root] = ''
252

    
253
    def get_object_stat(self, name):
254
        name = posixpath.join(self.root, name)
255
        if not name in self.store:
256
            return None
257
        return {'content-length': len(self.store[name])}
258

    
259

    
260
@skipIf(missing_libs, skipmsg)
261
@skipIfPY3
262
class TestSwiftObjectStore(TestCase):
263

    
264
    def setUp(self):
265
        super(TestSwiftObjectStore, self).setUp()
266
        self.conf = swift.load_conf(file=StringIO(config_file %
267
                                                  def_config_file))
268
        self.fsc = FakeSwiftConnector('fakerepo', conf=self.conf)
269

    
270
    def _put_pack(self, sos, commit_amount=1, marker='Default'):
271
        odata = create_commits(length=commit_amount, marker=marker)
272
        data = [(d.type_num, d.as_raw_string()) for d in odata]
273
        f = BytesIO()
274
        build_pack(f, data, store=sos)
275
        sos.add_thin_pack(f.read, None)
276
        return odata
277

    
278
    def test_load_packs(self):
279
        store = {'fakerepo/objects/pack/pack-'+'1'*40+'.idx': '',
280
                 'fakerepo/objects/pack/pack-'+'1'*40+'.pack': '',
281
                 'fakerepo/objects/pack/pack-'+'1'*40+'.info': '',
282
                 'fakerepo/objects/pack/pack-'+'2'*40+'.idx': '',
283
                 'fakerepo/objects/pack/pack-'+'2'*40+'.pack': '',
284
                 'fakerepo/objects/pack/pack-'+'2'*40+'.info': ''}
285
        fsc = FakeSwiftConnector('fakerepo', conf=self.conf, store=store)
286
        sos = swift.SwiftObjectStore(fsc)
287
        packs = sos._load_packs()
288
        self.assertEqual(len(packs), 2)
289
        for pack in packs:
290
            self.assertTrue(isinstance(pack, swift.SwiftPack))
291

    
292
    def test_add_thin_pack(self):
293
        sos = swift.SwiftObjectStore(self.fsc)
294
        self._put_pack(sos, 1, 'Default')
295
        self.assertEqual(len(self.fsc.store), 3)
296

    
297
    def test_find_missing_objects(self):
298
        commit_amount = 3
299
        sos = swift.SwiftObjectStore(self.fsc)
300
        odata = self._put_pack(sos, commit_amount, 'Default')
301
        head = odata[-1].id
302
        i = sos.iter_shas(sos.find_missing_objects([],
303
                                                   [head, ],
304
                                                   progress=None,
305
                                                   get_tagged=None))
306
        self.assertEqual(len(i), commit_amount * 3)
307
        shas = [d.id for d in odata]
308
        for sha, path in i:
309
            self.assertIn(sha.id, shas)
310

    
311
    def test_find_missing_objects_with_tag(self):
312
        commit_amount = 3
313
        sos = swift.SwiftObjectStore(self.fsc)
314
        odata = self._put_pack(sos, commit_amount, 'Default')
315
        head = odata[-1].id
316
        peeled_sha = dict([(sha.object[1], sha.id)
317
                           for sha in odata if isinstance(sha, Tag)])
318
        get_tagged = lambda: peeled_sha
319
        i = sos.iter_shas(sos.find_missing_objects([],
320
                                                   [head, ],
321
                                                   progress=None,
322
                                                   get_tagged=get_tagged))
323
        self.assertEqual(len(i), commit_amount * 4)
324
        shas = [d.id for d in odata]
325
        for sha, path in i:
326
            self.assertIn(sha.id, shas)
327

    
328
    def test_find_missing_objects_with_common(self):
329
        commit_amount = 3
330
        sos = swift.SwiftObjectStore(self.fsc)
331
        odata = self._put_pack(sos, commit_amount, 'Default')
332
        head = odata[-1].id
333
        have = odata[7].id
334
        i = sos.iter_shas(sos.find_missing_objects([have, ],
335
                                                   [head, ],
336
                                                   progress=None,
337
                                                   get_tagged=None))
338
        self.assertEqual(len(i), 3)
339

    
340
    def test_find_missing_objects_multiple_packs(self):
341
        sos = swift.SwiftObjectStore(self.fsc)
342
        commit_amount_a = 3
343
        odataa = self._put_pack(sos, commit_amount_a, 'Default1')
344
        heada = odataa[-1].id
345
        commit_amount_b = 2
346
        odatab = self._put_pack(sos, commit_amount_b, 'Default2')
347
        headb = odatab[-1].id
348
        i = sos.iter_shas(sos.find_missing_objects([],
349
                                                   [heada, headb],
350
                                                   progress=None,
351
                                                   get_tagged=None))
352
        self.assertEqual(len(self.fsc.store), 6)
353
        self.assertEqual(len(i),
354
                         commit_amount_a * 3 +
355
                         commit_amount_b * 3)
356
        shas = [d.id for d in odataa]
357
        shas.extend([d.id for d in odatab])
358
        for sha, path in i:
359
            self.assertIn(sha.id, shas)
360

    
361
    def test_add_thin_pack_ext_ref(self):
362
        sos = swift.SwiftObjectStore(self.fsc)
363
        odata = self._put_pack(sos, 1, 'Default1')
364
        ref_blob_content = odata[0].as_raw_string()
365
        ref_blob_id = odata[0].id
366
        new_blob = Blob.from_string(ref_blob_content.replace('blob',
367
                                                             'yummy blob'))
368
        blob, tree, tag, cmt = \
369
            create_commit([], marker='Default2', blob=new_blob)
370
        data = [(REF_DELTA, (ref_blob_id, blob.as_raw_string())),
371
                (tree.type_num, tree.as_raw_string()),
372
                (cmt.type_num, cmt.as_raw_string()),
373
                (tag.type_num, tag.as_raw_string())]
374
        f = BytesIO()
375
        build_pack(f, data, store=sos)
376
        sos.add_thin_pack(f.read, None)
377
        self.assertEqual(len(self.fsc.store), 6)
378

    
379

    
380
@skipIf(missing_libs, skipmsg)
381
class TestSwiftRepo(TestCase):
382

    
383
    def setUp(self):
384
        super(TestSwiftRepo, self).setUp()
385
        self.conf = swift.load_conf(file=StringIO(config_file %
386
                                                  def_config_file))
387

    
388
    def test_init(self):
389
        store = {'fakerepo/objects/pack': ''}
390
        with patch('dulwich.contrib.swift.SwiftConnector',
391
                   new_callable=create_swift_connector,
392
                   store=store):
393
            swift.SwiftRepo('fakerepo', conf=self.conf)
394

    
395
    def test_init_no_data(self):
396
        with patch('dulwich.contrib.swift.SwiftConnector',
397
                   new_callable=create_swift_connector):
398
            self.assertRaises(Exception, swift.SwiftRepo,
399
                              'fakerepo', self.conf)
400

    
401
    def test_init_bad_data(self):
402
        store = {'fakerepo/.git/objects/pack': ''}
403
        with patch('dulwich.contrib.swift.SwiftConnector',
404
                   new_callable=create_swift_connector,
405
                   store=store):
406
            self.assertRaises(Exception, swift.SwiftRepo,
407
                              'fakerepo', self.conf)
408

    
409
    def test_put_named_file(self):
410
        store = {'fakerepo/objects/pack': ''}
411
        with patch('dulwich.contrib.swift.SwiftConnector',
412
                   new_callable=create_swift_connector,
413
                   store=store):
414
            repo = swift.SwiftRepo('fakerepo', conf=self.conf)
415
            desc = b'Fake repo'
416
            repo._put_named_file('description', desc)
417
        self.assertEqual(repo.scon.store['fakerepo/description'],
418
                         desc)
419

    
420
    def test_init_bare(self):
421
        fsc = FakeSwiftConnector('fakeroot', conf=self.conf)
422
        with patch('dulwich.contrib.swift.SwiftConnector',
423
                   new_callable=create_swift_connector,
424
                   store=fsc.store):
425
            swift.SwiftRepo.init_bare(fsc, conf=self.conf)
426
        self.assertIn('fakeroot/objects/pack', fsc.store)
427
        self.assertIn('fakeroot/info/refs', fsc.store)
428
        self.assertIn('fakeroot/description', fsc.store)
429

    
430

    
431
@skipIf(missing_libs, skipmsg)
432
@skipIfPY3
433
class TestPackInfoLoadDump(TestCase):
434

    
435
    def setUp(self):
436
        super(TestPackInfoLoadDump, self).setUp()
437
        conf = swift.load_conf(file=StringIO(config_file %
438
                                             def_config_file))
439
        sos = swift.SwiftObjectStore(
440
            FakeSwiftConnector('fakerepo', conf=conf))
441
        commit_amount = 10
442
        self.commits = create_commits(length=commit_amount, marker="m")
443
        data = [(d.type_num, d.as_raw_string()) for d in self.commits]
444
        f = BytesIO()
445
        fi = BytesIO()
446
        expected = build_pack(f, data, store=sos)
447
        entries = [(sha, ofs, checksum) for
448
                   ofs, _, _, sha, checksum in expected]
449
        self.pack_data = PackData.from_file(file=f, size=None)
450
        write_pack_index_v2(
451
            fi, entries, self.pack_data.calculate_checksum())
452
        fi.seek(0)
453
        self.pack_index = load_pack_index_file('', fi)
454

    
455
#    def test_pack_info_perf(self):
456
#        dump_time = []
457
#        load_time = []
458
#        for i in range(0, 100):
459
#            start = time()
460
#            dumps = swift.pack_info_create(self.pack_data, self.pack_index)
461
#            dump_time.append(time() - start)
462
#        for i in range(0, 100):
463
#            start = time()
464
#            pack_infos = swift.load_pack_info('', file=BytesIO(dumps))
465
#            load_time.append(time() - start)
466
#        print sum(dump_time) / float(len(dump_time))
467
#        print sum(load_time) / float(len(load_time))
468

    
469
    def test_pack_info(self):
470
        dumps = swift.pack_info_create(self.pack_data, self.pack_index)
471
        pack_infos = swift.load_pack_info('', file=BytesIO(dumps))
472
        for obj in self.commits:
473
            self.assertIn(obj.id, pack_infos)
474

    
475

    
476
@skipIf(missing_libs, skipmsg)
477
class TestSwiftInfoRefsContainer(TestCase):
478

    
479
    def setUp(self):
480
        super(TestSwiftInfoRefsContainer, self).setUp()
481
        content = \
482
            b"22effb216e3a82f97da599b8885a6cadb488b4c5\trefs/heads/master\n" + \
483
            b"cca703b0e1399008b53a1a236d6b4584737649e4\trefs/heads/dev"
484
        self.store = {'fakerepo/info/refs': content}
485
        self.conf = swift.load_conf(file=StringIO(config_file %
486
                                                  def_config_file))
487
        self.fsc = FakeSwiftConnector('fakerepo', conf=self.conf)
488
        self.object_store = {}
489

    
490
    def test_init(self):
491
        """info/refs does not exists"""
492
        irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
493
        self.assertEqual(len(irc._refs), 0)
494
        self.fsc.store = self.store
495
        irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
496
        self.assertIn(b'refs/heads/dev', irc.allkeys())
497
        self.assertIn(b'refs/heads/master', irc.allkeys())
498

    
499
    def test_set_if_equals(self):
500
        self.fsc.store = self.store
501
        irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
502
        irc.set_if_equals(b'refs/heads/dev',
503
                          b"cca703b0e1399008b53a1a236d6b4584737649e4", b'1'*40)
504
        self.assertEqual(irc[b'refs/heads/dev'], b'1'*40)
505

    
506
    def test_remove_if_equals(self):
507
        self.fsc.store = self.store
508
        irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
509
        irc.remove_if_equals(b'refs/heads/dev',
510
                             b"cca703b0e1399008b53a1a236d6b4584737649e4")
511
        self.assertNotIn(b'refs/heads/dev', irc.allkeys())
512

    
513

    
514
@skipIf(missing_libs, skipmsg)
515
class TestSwiftConnector(TestCase):
516

    
517
    def setUp(self):
518
        super(TestSwiftConnector, self).setUp()
519
        self.conf = swift.load_conf(file=StringIO(config_file %
520
                                                  def_config_file))
521
        with patch('geventhttpclient.HTTPClient.request',
522
                   fake_auth_request_v1):
523
            self.conn = swift.SwiftConnector('fakerepo', conf=self.conf)
524

    
525
    def test_init_connector(self):
526
        self.assertEqual(self.conn.auth_ver, '1')
527
        self.assertEqual(self.conn.auth_url,
528
                         'http://127.0.0.1:8080/auth/v1.0')
529
        self.assertEqual(self.conn.user, 'test:tester')
530
        self.assertEqual(self.conn.password, 'testing')
531
        self.assertEqual(self.conn.root, 'fakerepo')
532
        self.assertEqual(self.conn.storage_url,
533
                         'http://127.0.0.1:8080/v1.0/AUTH_fakeuser')
534
        self.assertEqual(self.conn.token, '12' * 10)
535
        self.assertEqual(self.conn.http_timeout, 1)
536
        self.assertEqual(self.conn.http_pool_length, 1)
537
        self.assertEqual(self.conn.concurrency, 1)
538
        self.conf.set('swift', 'auth_ver', '2')
539
        self.conf.set('swift', 'auth_url', 'http://127.0.0.1:8080/auth/v2.0')
540
        with patch('geventhttpclient.HTTPClient.request',
541
                   fake_auth_request_v2):
542
            conn = swift.SwiftConnector('fakerepo', conf=self.conf)
543
        self.assertEqual(conn.user, 'tester')
544
        self.assertEqual(conn.tenant, 'test')
545
        self.conf.set('swift', 'auth_ver', '1')
546
        self.conf.set('swift', 'auth_url', 'http://127.0.0.1:8080/auth/v1.0')
547
        with patch('geventhttpclient.HTTPClient.request',
548
                   fake_auth_request_v1_error):
549
            self.assertRaises(swift.SwiftException,
550
                              lambda: swift.SwiftConnector('fakerepo',
551
                                                           conf=self.conf))
552

    
553
    def test_root_exists(self):
554
        with patch('geventhttpclient.HTTPClient.request',
555
                   lambda *args: Response()):
556
            self.assertEqual(self.conn.test_root_exists(), True)
557

    
558
    def test_root_not_exists(self):
559
        with patch('geventhttpclient.HTTPClient.request',
560
                   lambda *args: Response(status=404)):
561
            self.assertEqual(self.conn.test_root_exists(), None)
562

    
563
    def test_create_root(self):
564
        with patch('dulwich.contrib.swift.SwiftConnector.test_root_exists',
565
                lambda *args: None):
566
            with patch('geventhttpclient.HTTPClient.request',
567
                lambda *args: Response()):
568
                self.assertEqual(self.conn.create_root(), None)
569

    
570
    def test_create_root_fails(self):
571
        with patch('dulwich.contrib.swift.SwiftConnector.test_root_exists',
572
                   lambda *args: None):
573
            with patch('geventhttpclient.HTTPClient.request',
574
                       lambda *args: Response(status=404)):
575
                self.assertRaises(swift.SwiftException,
576
                                  lambda: self.conn.create_root())
577

    
578
    def test_get_container_objects(self):
579
        with patch('geventhttpclient.HTTPClient.request',
580
                   lambda *args: Response(content=json_dumps(
581
                       (({'name': 'a'}, {'name': 'b'}))))):
582
            self.assertEqual(len(self.conn.get_container_objects()), 2)
583

    
584
    def test_get_container_objects_fails(self):
585
        with patch('geventhttpclient.HTTPClient.request',
586
                   lambda *args: Response(status=404)):
587
            self.assertEqual(self.conn.get_container_objects(), None)
588

    
589
    def test_get_object_stat(self):
590
        with patch('geventhttpclient.HTTPClient.request',
591
                   lambda *args: Response(headers={'content-length': '10'})):
592
            self.assertEqual(self.conn.get_object_stat('a')['content-length'],
593
                             '10')
594

    
595
    def test_get_object_stat_fails(self):
596
        with patch('geventhttpclient.HTTPClient.request',
597
                   lambda *args: Response(status=404)):
598
            self.assertEqual(self.conn.get_object_stat('a'), None)
599

    
600
    def test_put_object(self):
601
        with patch('geventhttpclient.HTTPClient.request',
602
                   lambda *args, **kwargs: Response()):
603
            self.assertEqual(self.conn.put_object('a', BytesIO(b'content')),
604
                             None)
605

    
606
    def test_put_object_fails(self):
607
        with patch('geventhttpclient.HTTPClient.request',
608
                   lambda *args, **kwargs: Response(status=400)):
609
            self.assertRaises(swift.SwiftException,
610
                              lambda: self.conn.put_object(
611
                                  'a', BytesIO(b'content')))
612

    
613
    def test_get_object(self):
614
        with patch('geventhttpclient.HTTPClient.request',
615
                   lambda *args, **kwargs: Response(content=b'content')):
616
            self.assertEqual(self.conn.get_object('a').read(), b'content')
617
        with patch('geventhttpclient.HTTPClient.request',
618
                   lambda *args, **kwargs: Response(content=b'content')):
619
            self.assertEqual(self.conn.get_object('a', range='0-6'), b'content')
620

    
621
    def test_get_object_fails(self):
622
        with patch('geventhttpclient.HTTPClient.request',
623
                   lambda *args, **kwargs: Response(status=404)):
624
            self.assertEqual(self.conn.get_object('a'), None)
625

    
626
    def test_del_object(self):
627
        with patch('geventhttpclient.HTTPClient.request',
628
                   lambda *args: Response()):
629
            self.assertEqual(self.conn.del_object('a'), None)
630

    
631
    def test_del_root(self):
632
        with patch('dulwich.contrib.swift.SwiftConnector.del_object',
633
                   lambda *args: None):
634
            with patch('dulwich.contrib.swift.SwiftConnector.'
635
                       'get_container_objects',
636
                       lambda *args: ({'name': 'a'}, {'name': 'b'})):
637
                with patch('geventhttpclient.HTTPClient.request',
638
                           lambda *args: Response()):
639
                    self.assertEqual(self.conn.del_root(), None)
640

    
641

    
642
@skipIf(missing_libs, skipmsg)
643
class SwiftObjectStoreTests(ObjectStoreTests, TestCase):
644

    
645
    def setUp(self):
646
        TestCase.setUp(self)
647
        conf = swift.load_conf(file=StringIO(config_file %
648
                               def_config_file))
649
        fsc = FakeSwiftConnector('fakerepo', conf=conf)
650
        self.store = swift.SwiftObjectStore(fsc)