~bzr-pqm/bzr/bzr.dev

974.1.44 by aaron.bentley at utoronto
Added test of double-add in ImmutableStore
1
# Copyright (C) 2005 by Canonical Development Ltd
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
17
"""Test Store implementations."""
18
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
19
from cStringIO import StringIO
1185.1.46 by Robert Collins
Aarons branch --basis patch
20
import os
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
21
import gzip
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
22
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
23
from bzrlib.errors import BzrError, UnlistableStore, NoSuchFile
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
24
from bzrlib.transport.local import LocalTransport
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
25
from bzrlib.store.text import TextStore
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
26
from bzrlib.tests import TestCase, TestCaseInTempDir
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
27
import bzrlib.store as store
28
import bzrlib.transport as transport
1442.1.46 by Robert Collins
test simple has_id
29
from bzrlib.transport.memory import MemoryTransport
974.1.44 by aaron.bentley at utoronto
Added test of double-add in ImmutableStore
30
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
31
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
32
class TestStores(object):
1185.16.146 by Martin Pool
Fix up assert with sideeffects in CompressedTextStore._copy_one
33
    """Mixin template class that provides some common tests for stores"""
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
34
35
    def check_content(self, store, fileid, value):
1442.1.35 by Robert Collins
convert all users of __getitem__ into TransportStores to use .get instead
36
        f = store.get(fileid)
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
37
        self.assertEqual(f.read(), value)
38
39
    def fill_store(self, store):
40
        store.add(StringIO('hello'), 'a')
41
        store.add(StringIO('other'), 'b')
42
        store.add(StringIO('something'), 'c')
43
        store.add(StringIO('goodbye'), '123123')
44
45
    def test_copy_all(self):
46
        """Test copying"""
47
        os.mkdir('a')
48
        store_a = self.get_store('a')
49
        store_a.add('foo', '1')
50
        os.mkdir('b')
51
        store_b = self.get_store('b')
1563.2.35 by Robert Collins
cleanup deprecation warnings and finish conversion so the inventory is knit based too.
52
        store_b.copy_all_ids(store_a)
1442.1.35 by Robert Collins
convert all users of __getitem__ into TransportStores to use .get instead
53
        self.assertEqual(store_a.get('1').read(), 'foo')
54
        self.assertEqual(store_b.get('1').read(), 'foo')
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
55
        # TODO: Switch the exception form UnlistableStore to
56
        #       or make Stores throw UnlistableStore if their
57
        #       Transport doesn't support listing
58
        # store_c = RemoteStore('http://example.com/')
59
        # self.assertRaises(UnlistableStore, copy_all, store_c, store_b)
60
61
    def test_get(self):
62
        store = self.get_store()
63
        self.fill_store(store)
64
    
65
        self.check_content(store, 'a', 'hello')
66
        self.check_content(store, 'b', 'other')
67
        self.check_content(store, 'c', 'something')
68
    
69
        # Make sure that requesting a non-existing file fails
70
        self.assertRaises(KeyError, self.check_content, store, 'd', None)
71
974.1.44 by aaron.bentley at utoronto
Added test of double-add in ImmutableStore
72
    def test_multiple_add(self):
73
        """Multiple add with same ID should raise a BzrError"""
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
74
        store = self.get_store()
75
        self.fill_store(store)
76
        self.assertRaises(BzrError, store.add, StringIO('goodbye'), '123123')
77
78
79
class TestCompressedTextStore(TestCaseInTempDir, TestStores):
80
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
81
    def get_store(self, path=u'.'):
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
82
        t = LocalTransport(path)
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
83
        return TextStore(t, compressed=True)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
84
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
85
    def test_total_size(self):
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
86
        store = self.get_store(u'.')
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
87
        store.register_suffix('dsc')
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
88
        store.add(StringIO('goodbye'), '123123')
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
89
        store.add(StringIO('goodbye2'), '123123', 'dsc')
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
90
        # these get gzipped - content should be stable
91
        self.assertEqual(store.total_size(), (2, 55))
92
        
1442.1.32 by Robert Collins
Teach CompressedTextStore._relpath to support file suffixes too.
93
    def test__relpath_suffixed(self):
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
94
        my_store = TextStore(MockTransport(),
95
                             prefixed=True, compressed=True)
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
96
        my_store.register_suffix('dsc')
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
97
        self.assertEqual('45/foo.dsc', my_store._relpath('foo', ['dsc']))
1442.1.32 by Robert Collins
Teach CompressedTextStore._relpath to support file suffixes too.
98
1404 by Robert Collins
only pull remote text weaves once per fetch operation
99
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
100
class TestMemoryStore(TestCase):
101
    
102
    def get_store(self):
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
103
        return store.ImmutableMemoryStore()
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
104
    
105
    def test_imports(self):
106
        from bzrlib.store import ImmutableMemoryStore
107
108
    def test_add_and_retrieve(self):
109
        store = self.get_store()
110
        store.add(StringIO('hello'), 'aa')
1442.1.35 by Robert Collins
convert all users of __getitem__ into TransportStores to use .get instead
111
        self.assertNotEqual(store.get('aa'), None)
112
        self.assertEqual(store.get('aa').read(), 'hello')
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
113
        store.add(StringIO('hello world'), 'bb')
1442.1.35 by Robert Collins
convert all users of __getitem__ into TransportStores to use .get instead
114
        self.assertNotEqual(store.get('bb'), None)
115
        self.assertEqual(store.get('bb').read(), 'hello world')
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
116
117
    def test_missing_is_absent(self):
118
        store = self.get_store()
119
        self.failIf('aa' in store)
120
121
    def test_adding_fails_when_present(self):
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
122
        my_store = self.get_store()
123
        my_store.add(StringIO('hello'), 'aa')
1442.1.44 by Robert Collins
Many transport related tweaks:
124
        self.assertRaises(BzrError,
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
125
                          my_store.add, StringIO('hello'), 'aa')
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
126
127
    def test_total_size(self):
128
        store = self.get_store()
129
        store.add(StringIO('goodbye'), '123123')
130
        store.add(StringIO('goodbye2'), '123123.dsc')
131
        self.assertEqual(store.total_size(), (2, 15))
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
132
        # TODO: Switch the exception form UnlistableStore to
133
        #       or make Stores throw UnlistableStore if their
134
        #       Transport doesn't support listing
135
        # store_c = RemoteStore('http://example.com/')
136
        # self.assertRaises(UnlistableStore, copy_all, store_c, store_b)
137
1404 by Robert Collins
only pull remote text weaves once per fetch operation
138
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
139
class TestTextStore(TestCaseInTempDir, TestStores):
140
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
141
    def get_store(self, path=u'.'):
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
142
        t = LocalTransport(path)
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
143
        return TextStore(t, compressed=False)
1442.1.34 by Robert Collins
Remove the Store.get multiple-get interface which was not used, and remove much spurious duplication in teststore.py.
144
145
    def test_total_size(self):
146
        store = self.get_store()
147
        store.add(StringIO('goodbye'), '123123')
148
        store.add(StringIO('goodbye2'), '123123.dsc')
149
        self.assertEqual(store.total_size(), (2, 15))
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
150
        # TODO: Switch the exception form UnlistableStore to
151
        #       or make Stores throw UnlistableStore if their
152
        #       Transport doesn't support listing
153
        # store_c = RemoteStore('http://example.com/')
154
        # self.assertRaises(UnlistableStore, copy_all, store_c, store_b)
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
155
156
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
157
class TestMixedTextStore(TestCaseInTempDir, TestStores):
158
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
159
    def get_store(self, path=u'.', compressed=True):
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
160
        t = LocalTransport(path)
161
        return TextStore(t, compressed=compressed)
162
163
    def test_get_mixed(self):
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
164
        cs = self.get_store(u'.', compressed=True)
165
        s = self.get_store(u'.', compressed=False)
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
166
        cs.add(StringIO('hello there'), 'a')
167
168
        self.failUnlessExists('a.gz')
169
        self.failIf(os.path.lexists('a'))
170
171
        self.assertEquals(gzip.GzipFile('a.gz').read(), 'hello there')
172
173
        self.assertEquals(cs.has_id('a'), True)
174
        self.assertEquals(s.has_id('a'), True)
175
        self.assertEquals(cs.get('a').read(), 'hello there')
176
        self.assertEquals(s.get('a').read(), 'hello there')
177
        
178
        self.assertRaises(BzrError, s.add, StringIO('goodbye'), 'a')
179
180
        s.add(StringIO('goodbye'), 'b')
181
        self.failUnlessExists('b')
182
        self.failIf(os.path.lexists('b.gz'))
183
        self.assertEquals(open('b').read(), 'goodbye')
184
185
        self.assertEquals(cs.has_id('b'), True)
186
        self.assertEquals(s.has_id('b'), True)
187
        self.assertEquals(cs.get('b').read(), 'goodbye')
188
        self.assertEquals(s.get('b').read(), 'goodbye')
189
        
190
        self.assertRaises(BzrError, cs.add, StringIO('again'), 'b')
191
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
192
class MockTransport(transport.Transport):
193
    """A fake transport for testing with."""
194
1442.1.30 by Robert Collins
Add stuf has and mkdir to MockTransport to enable testing store adds
195
    def has(self, filename):
196
        return False
197
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
198
    def __init__(self, url=None):
199
        if url is None:
200
            url = "http://example.com"
201
        super(MockTransport, self).__init__(url)
202
1442.1.30 by Robert Collins
Add stuf has and mkdir to MockTransport to enable testing store adds
203
    def mkdir(self, filename):
204
        return
205
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
206
1442.1.29 by Robert Collins
create an instrumented transport store for testing common logic.
207
class InstrumentedTransportStore(store.TransportStore):
208
    """An instrumented TransportStore.
209
210
    Here we replace template method worker methods with calls that record the
211
    expected results.
212
    """
213
214
    def _add(self, filename, file):
215
        self._calls.append(("_add", filename, file))
216
217
    def __init__(self, transport, prefixed=False):
218
        super(InstrumentedTransportStore, self).__init__(transport, prefixed)
219
        self._calls = []
220
221
222
class TestInstrumentedTransportStore(TestCase):
223
224
    def test__add_records(self):
225
        my_store = InstrumentedTransportStore(MockTransport())
1442.1.30 by Robert Collins
Add stuf has and mkdir to MockTransport to enable testing store adds
226
        my_store._add("filename", "file")
1442.1.29 by Robert Collins
create an instrumented transport store for testing common logic.
227
        self.assertEqual([("_add", "filename", "file")], my_store._calls)
228
229
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
230
class TestMockTransport(TestCase):
231
232
    def test_isinstance(self):
233
        self.failUnless(isinstance(MockTransport(), transport.Transport))
234
1442.1.30 by Robert Collins
Add stuf has and mkdir to MockTransport to enable testing store adds
235
    def test_has(self):
236
        self.assertEqual(False, MockTransport().has('foo'))
237
238
    def test_mkdir(self):
239
        MockTransport().mkdir('45')
240
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
241
242
class TestTransportStore(TestCase):
243
    
244
    def test__relpath_invalid(self):
245
        my_store = store.TransportStore(MockTransport())
246
        self.assertRaises(ValueError, my_store._relpath, '/foo')
247
        self.assertRaises(ValueError, my_store._relpath, 'foo/')
248
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
249
    def test_register_invalid_suffixes(self):
250
        my_store = store.TransportStore(MockTransport())
251
        self.assertRaises(ValueError, my_store.register_suffix, '/')
252
        self.assertRaises(ValueError, my_store.register_suffix, '.gz/bar')
253
254
    def test__relpath_unregister_suffixes(self):
255
        my_store = store.TransportStore(MockTransport())
256
        self.assertRaises(ValueError, my_store._relpath, 'foo', ['gz'])
257
        self.assertRaises(ValueError, my_store._relpath, 'foo', ['dsc', 'gz'])
1442.1.27 by Robert Collins
Check that file suffixes in TransportStore are also valid
258
1442.1.25 by Robert Collins
Test TransportStore._relpath for simple cases: pull up _prefixed attribute as a result.
259
    def test__relpath_simple(self):
260
        my_store = store.TransportStore(MockTransport())
261
        self.assertEqual("foo", my_store._relpath('foo'))
1442.1.26 by Robert Collins
Pull up _relpath with gz suffix for CompressedTextStore into TransportStore
262
263
    def test__relpath_prefixed(self):
264
        my_store = store.TransportStore(MockTransport(), True)
265
        self.assertEqual('45/foo', my_store._relpath('foo'))
266
267
    def test__relpath_simple_suffixed(self):
268
        my_store = store.TransportStore(MockTransport())
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
269
        my_store.register_suffix('bar')
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
270
        my_store.register_suffix('baz')
271
        self.assertEqual('foo.baz', my_store._relpath('foo', ['baz']))
272
        self.assertEqual('foo.bar.baz', my_store._relpath('foo', ['bar', 'baz']))
1442.1.27 by Robert Collins
Check that file suffixes in TransportStore are also valid
273
274
    def test__relpath_prefixed_suffixed(self):
275
        my_store = store.TransportStore(MockTransport(), True)
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
276
        my_store.register_suffix('bar')
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
277
        my_store.register_suffix('baz')
278
        self.assertEqual('45/foo.baz', my_store._relpath('foo', ['baz']))
279
        self.assertEqual('45/foo.bar.baz',
280
                         my_store._relpath('foo', ['bar', 'baz']))
1442.1.27 by Robert Collins
Check that file suffixes in TransportStore are also valid
281
1442.1.31 by Robert Collins
test that TransportStore.add calls _add appropriately.
282
    def test_add_simple(self):
283
        stream = StringIO("content")
284
        my_store = InstrumentedTransportStore(MockTransport())
285
        my_store.add(stream, "foo")
286
        self.assertEqual([("_add", "foo", stream)], my_store._calls)
287
288
    def test_add_prefixed(self):
289
        stream = StringIO("content")
290
        my_store = InstrumentedTransportStore(MockTransport(), True)
291
        my_store.add(stream, "foo")
292
        self.assertEqual([("_add", "45/foo", stream)], my_store._calls)
1442.1.33 by Robert Collins
teach TransportStore.add to accept an optional file suffix, which does not alter the fileid.
293
294
    def test_add_simple_suffixed(self):
295
        stream = StringIO("content")
296
        my_store = InstrumentedTransportStore(MockTransport())
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
297
        my_store.register_suffix('dsc')
1442.1.33 by Robert Collins
teach TransportStore.add to accept an optional file suffix, which does not alter the fileid.
298
        my_store.add(stream, "foo", 'dsc')
299
        self.assertEqual([("_add", "foo.dsc", stream)], my_store._calls)
300
        
301
    def test_add_simple_suffixed(self):
302
        stream = StringIO("content")
303
        my_store = InstrumentedTransportStore(MockTransport(), True)
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
304
        my_store.register_suffix('dsc')
1442.1.33 by Robert Collins
teach TransportStore.add to accept an optional file suffix, which does not alter the fileid.
305
        my_store.add(stream, "foo", 'dsc')
306
        self.assertEqual([("_add", "45/foo.dsc", stream)], my_store._calls)
1442.1.46 by Robert Collins
test simple has_id
307
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
308
    def get_populated_store(self, prefixed=False,
1185.16.159 by John Arbash Meinel
Updated the stores, all tests pass, and a store doesn't have to be 100% compressed
309
            store_class=TextStore, compressed=False):
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
310
        my_store = store_class(MemoryTransport(), prefixed,
311
                               compressed=compressed)
1442.1.46 by Robert Collins
test simple has_id
312
        my_store.register_suffix('sig')
1442.1.48 by Robert Collins
test that the presence of a signature does not make a missing base file magically appear present
313
        stream = StringIO("signature")
1442.1.46 by Robert Collins
test simple has_id
314
        my_store.add(stream, "foo", 'sig')
315
        stream = StringIO("content")
316
        my_store.add(stream, "foo")
1442.1.48 by Robert Collins
test that the presence of a signature does not make a missing base file magically appear present
317
        stream = StringIO("signature for missing base")
318
        my_store.add(stream, "missing", 'sig')
1442.1.46 by Robert Collins
test simple has_id
319
        return my_store
320
        
321
    def test_has_simple(self):
322
        my_store = self.get_populated_store()
323
        self.assertEqual(True, my_store.has_id('foo'))
1442.1.47 by Robert Collins
test for has with suffixed files
324
        my_store = self.get_populated_store(True)
325
        self.assertEqual(True, my_store.has_id('foo'))
326
327
    def test_has_suffixed(self):
328
        my_store = self.get_populated_store()
329
        self.assertEqual(True, my_store.has_id('foo', 'sig'))
330
        my_store = self.get_populated_store(True)
331
        self.assertEqual(True, my_store.has_id('foo', 'sig'))
1442.1.48 by Robert Collins
test that the presence of a signature does not make a missing base file magically appear present
332
333
    def test_has_suffixed_no_base(self):
334
        my_store = self.get_populated_store()
335
        self.assertEqual(False, my_store.has_id('missing'))
336
        my_store = self.get_populated_store(True)
337
        self.assertEqual(False, my_store.has_id('missing'))
1442.1.50 by Robert Collins
test get with suffixes
338
339
    def test_get_simple(self):
340
        my_store = self.get_populated_store()
341
        self.assertEqual('content', my_store.get('foo').read())
342
        my_store = self.get_populated_store(True)
343
        self.assertEqual('content', my_store.get('foo').read())
344
345
    def test_get_suffixed(self):
346
        my_store = self.get_populated_store()
347
        self.assertEqual('signature', my_store.get('foo', 'sig').read())
348
        my_store = self.get_populated_store(True)
349
        self.assertEqual('signature', my_store.get('foo', 'sig').read())
350
351
    def test_get_suffixed_no_base(self):
352
        my_store = self.get_populated_store()
353
        self.assertEqual('signature for missing base',
354
                         my_store.get('missing', 'sig').read())
355
        my_store = self.get_populated_store(True)
356
        self.assertEqual('signature for missing base',
357
                         my_store.get('missing', 'sig').read())
1442.1.51 by Robert Collins
teach iter about suffixes
358
359
    def test___iter__no_suffix(self):
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
360
        my_store = TextStore(MemoryTransport(),
361
                             prefixed=False, compressed=False)
1442.1.51 by Robert Collins
teach iter about suffixes
362
        stream = StringIO("content")
363
        my_store.add(stream, "foo")
364
        self.assertEqual(set(['foo']),
365
                         set(my_store.__iter__()))
366
367
    def test___iter__(self):
368
        self.assertEqual(set(['foo']),
369
                         set(self.get_populated_store().__iter__()))
370
        self.assertEqual(set(['foo']),
371
                         set(self.get_populated_store(True).__iter__()))
372
373
    def test___iter__compressed(self):
374
        self.assertEqual(set(['foo']),
375
                         set(self.get_populated_store(
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
376
                             compressed=True).__iter__()))
1442.1.51 by Robert Collins
teach iter about suffixes
377
        self.assertEqual(set(['foo']),
378
                         set(self.get_populated_store(
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
379
                             True, compressed=True).__iter__()))
1442.1.51 by Robert Collins
teach iter about suffixes
380
381
    def test___len__(self):
382
        self.assertEqual(1, len(self.get_populated_store()))
1442.1.54 by Robert Collins
Teach store.copy_all about fileid suffixes
383
384
    def test_copy_suffixes(self):
385
        from_store = self.get_populated_store()
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
386
        to_store = TextStore(MemoryTransport(),
387
                             prefixed=True, compressed=True)
1442.1.54 by Robert Collins
Teach store.copy_all about fileid suffixes
388
        to_store.register_suffix('sig')
1563.2.35 by Robert Collins
cleanup deprecation warnings and finish conversion so the inventory is knit based too.
389
        to_store.copy_all_ids(from_store)
1442.1.54 by Robert Collins
Teach store.copy_all about fileid suffixes
390
        self.assertEqual(1, len(to_store))
391
        self.assertEqual(set(['foo']), set(to_store.__iter__()))
392
        self.assertEqual('content', to_store.get('foo').read())
393
        self.assertEqual('signature', to_store.get('foo', 'sig').read())
394
        self.assertRaises(KeyError, to_store.get, 'missing', 'sig')
1469 by Robert Collins
Change Transport.* to work with URL's.
395
396
    def test_relpath_escaped(self):
397
        my_store = store.TransportStore(MemoryTransport())
398
        self.assertEqual('%25', my_store._relpath('%'))