~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.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
21
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
22
from bzrlib.errors import BzrError, UnlistableStore
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
23
from bzrlib.store import copy_all
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
25
from bzrlib.transport import NoSuchFile
26
from bzrlib.store.compressed_text import CompressedTextStore
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
27
from bzrlib.store.text import TextStore
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
28
from bzrlib.selftest import TestCase, TestCaseInTempDir
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
29
import bzrlib.store as store
30
import bzrlib.transport as transport
974.1.44 by aaron.bentley at utoronto
Added test of double-add in ImmutableStore
31
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
32
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
33
def fill_store(store):
34
    store.add(StringIO('hello'), 'a')
35
    store.add(StringIO('other'), 'b')
36
    store.add(StringIO('something'), 'c')
37
    store.add(StringIO('goodbye'), '123123')
38
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
39
1185.11.16 by John Arbash Meinel
Fixed teststore with correct parameter name.
40
def check_equals(tester, store, files, values, permit_failure=False):
41
    files = store.get(files, permit_failure=permit_failure)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
42
    count = 0
43
    for f, v in zip(files, values):
44
        count += 1
45
        if v is None:
46
            tester.assert_(f is None)
47
        else:
48
            tester.assertEquals(f.read(), v)
49
    tester.assertEquals(count, len(values))
50
    # We need to check to make sure there are no more
51
    # files to be returned, I'm using a cheezy way
52
    # Convert to a list, and there shouldn't be any left
53
    tester.assertEquals(len(list(files)), 0)
54
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
55
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
56
def test_multiple_add(tester, store):
57
    fill_store(store)
58
    tester.assertRaises(BzrError, store.add, StringIO('goodbye'), '123123')
59
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
60
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
61
def test_get(tester, store):
62
    fill_store(store)
63
64
    check_equals(tester, store, ['a'], ['hello'])
65
    check_equals(tester, store, ['b', 'c'], ['other', 'something'])
66
67
    # Make sure that requesting a non-existing file fails
68
    tester.assertRaises(NoSuchFile, check_equals, tester, store,
69
            ['d'], [None])
70
    tester.assertRaises(NoSuchFile, check_equals, tester, store,
71
            ['a', 'd'], ['hello', None])
72
    tester.assertRaises(NoSuchFile, check_equals, tester, store,
73
            ['d', 'a'], [None, 'hello'])
74
    tester.assertRaises(NoSuchFile, check_equals, tester, store,
75
            ['d', 'd', 'd'], [None, None, None])
76
    tester.assertRaises(NoSuchFile, check_equals, tester, store,
77
            ['a', 'd', 'b'], ['hello', None, 'other'])
78
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
79
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
80
def test_ignore_get(tester, store):
81
    fill_store(store)
82
1185.11.16 by John Arbash Meinel
Fixed teststore with correct parameter name.
83
    files = store.get(['d'], permit_failure=True)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
84
    files = list(files)
85
    tester.assertEquals(len(files), 1)
86
    tester.assert_(files[0] is None)
87
88
    check_equals(tester, store, ['a', 'd'], ['hello', None],
1185.11.16 by John Arbash Meinel
Fixed teststore with correct parameter name.
89
            permit_failure=True)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
90
    check_equals(tester, store, ['d', 'a'], [None, 'hello'],
1185.11.16 by John Arbash Meinel
Fixed teststore with correct parameter name.
91
            permit_failure=True)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
92
    check_equals(tester, store, ['d', 'd'], [None, None],
1185.11.16 by John Arbash Meinel
Fixed teststore with correct parameter name.
93
            permit_failure=True)
94
    check_equals(tester, store, ['a', 'd', 'b'], ['hello', None, 'other'],
95
            permit_failure=True)
96
    check_equals(tester, store, ['a', 'd', 'b'], ['hello', None, 'other'],
97
            permit_failure=True)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
98
    check_equals(tester, store, ['b', 'd', 'c'], ['other', None, 'something'],
1185.11.16 by John Arbash Meinel
Fixed teststore with correct parameter name.
99
            permit_failure=True)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
100
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
101
1393.2.4 by John Arbash Meinel
All tests pass.
102
def get_compressed_store(path='.'):
103
    t = LocalTransport(path)
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
104
    return CompressedTextStore(t)
105
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
106
1393.2.4 by John Arbash Meinel
All tests pass.
107
def get_text_store(path='.'):
108
    t = LocalTransport(path)
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
109
    return TextStore(t)
110
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
111
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
112
class TestCompressedTextStore(TestCaseInTempDir):
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
113
974.1.44 by aaron.bentley at utoronto
Added test of double-add in ImmutableStore
114
    def test_multiple_add(self):
115
        """Multiple add with same ID should raise a BzrError"""
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
116
        store = get_compressed_store()
117
        test_multiple_add(self, store)
118
119
    def test_get(self):
120
        store = get_compressed_store()
121
        test_get(self, store)
122
123
    def test_ignore_get(self):
124
        store = get_compressed_store()
125
        test_ignore_get(self, store)
126
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
127
    def test_total_size(self):
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
128
        store = get_compressed_store('.')
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
129
        store.add(StringIO('goodbye'), '123123')
130
        store.add(StringIO('goodbye2'), '123123.dsc')
131
        # these get gzipped - content should be stable
132
        self.assertEqual(store.total_size(), (2, 55))
133
        
1185.10.1 by Aaron Bentley
Added --basis option to bzr branch
134
    def test_copy_all(self):
135
        """Test copying"""
136
        os.mkdir('a')
1393.2.4 by John Arbash Meinel
All tests pass.
137
        store_a = get_text_store('a')
1185.10.1 by Aaron Bentley
Added --basis option to bzr branch
138
        store_a.add('foo', '1')
139
        os.mkdir('b')
1393.2.4 by John Arbash Meinel
All tests pass.
140
        store_b = get_text_store('b')
1185.10.1 by Aaron Bentley
Added --basis option to bzr branch
141
        copy_all(store_a, store_b)
142
        self.assertEqual(store_a['1'].read(), 'foo')
143
        self.assertEqual(store_b['1'].read(), 'foo')
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
144
1404 by Robert Collins
only pull remote text weaves once per fetch operation
145
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
146
class TestMemoryStore(TestCase):
147
    
148
    def get_store(self):
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
149
        return store.ImmutableMemoryStore()
1092.2.1 by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations
150
    
151
    def test_imports(self):
152
        from bzrlib.store import ImmutableMemoryStore
153
154
    def test_add_and_retrieve(self):
155
        store = self.get_store()
156
        store.add(StringIO('hello'), 'aa')
157
        self.assertNotEqual(store['aa'], None)
158
        self.assertEqual(store['aa'].read(), 'hello')
159
        store.add(StringIO('hello world'), 'bb')
160
        self.assertNotEqual(store['bb'], None)
161
        self.assertEqual(store['bb'].read(), 'hello world')
162
163
    def test_missing_is_absent(self):
164
        store = self.get_store()
165
        self.failIf('aa' in store)
166
167
    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
168
        my_store = self.get_store()
169
        my_store.add(StringIO('hello'), 'aa')
170
        self.assertRaises(store.StoreError,
171
                          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
172
173
    def test_total_size(self):
174
        store = self.get_store()
175
        store.add(StringIO('goodbye'), '123123')
176
        store.add(StringIO('goodbye2'), '123123.dsc')
177
        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.
178
        # TODO: Switch the exception form UnlistableStore to
179
        #       or make Stores throw UnlistableStore if their
180
        #       Transport doesn't support listing
181
        # store_c = RemoteStore('http://example.com/')
182
        # self.assertRaises(UnlistableStore, copy_all, store_c, store_b)
183
1404 by Robert Collins
only pull remote text weaves once per fetch operation
184
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
185
class TestTextStore(TestCaseInTempDir):
186
    def test_multiple_add(self):
187
        """Multiple add with same ID should raise a BzrError"""
188
        store = get_text_store()
189
        test_multiple_add(self, store)
190
191
    def test_get(self):
192
        store = get_text_store()
193
        test_get(self, store)
194
195
    def test_ignore_get(self):
196
        store = get_text_store()
197
        test_ignore_get(self, store)
198
199
    def test_copy_all(self):
200
        """Test copying"""
201
        os.mkdir('a')
1393.2.4 by John Arbash Meinel
All tests pass.
202
        store_a = get_text_store('a')
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
203
        store_a.add('foo', '1')
204
        os.mkdir('b')
1393.2.4 by John Arbash Meinel
All tests pass.
205
        store_b = get_text_store('b')
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
206
        copy_all(store_a, store_b)
207
        self.assertEqual(store_a['1'].read(), 'foo')
208
        self.assertEqual(store_b['1'].read(), 'foo')
209
        # TODO: Switch the exception form UnlistableStore to
210
        #       or make Stores throw UnlistableStore if their
211
        #       Transport doesn't support listing
212
        # store_c = RemoteStore('http://example.com/')
213
        # 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
214
215
216
class MockTransport(transport.Transport):
217
    """A fake transport for testing with."""
218
219
    def __init__(self, url=None):
220
        if url is None:
221
            url = "http://example.com"
222
        super(MockTransport, self).__init__(url)
223
224
225
class TestMockTransport(TestCase):
226
227
    def test_isinstance(self):
228
        self.failUnless(isinstance(MockTransport(), transport.Transport))
229
230
231
class TestTransportStore(TestCase):
232
    
233
    def test__relpath_invalid(self):
234
        my_store = store.TransportStore(MockTransport())
235
        self.assertRaises(ValueError, my_store._relpath, '/foo')
236
        self.assertRaises(ValueError, my_store._relpath, 'foo/')
237