~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2005, 2006, 2009, 2011 Canonical Ltd
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
17
18
"""Tests for the behaviour of the Transaction concept in bzr."""
19
20
#import bzrlib specific imports here
21
import bzrlib.errors as errors
5579.3.1 by Jelmer Vernooij
Remove unused imports.
22
from bzrlib.tests import TestCase
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
23
import bzrlib.transactions as transactions
24
25
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
26
class DummyWeave(object):
27
    """A class that can be instantiated and compared."""
28
29
    def __init__(self, message):
30
        self._message = message
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
31
        self.finished = False
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
32
33
    def __eq__(self, other):
34
        if other is None:
35
            return False
36
        return self._message == other._message
37
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
38
    def transaction_finished(self):
39
        self.finished = True
40
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
41
42
class TestSymbols(TestCase):
43
1417.1.12 by Robert Collins
cache revision history during read transactions
44
    def test_public_symbols(self):
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
45
        from bzrlib.transactions import ReadOnlyTransaction
46
        from bzrlib.transactions import PassThroughTransaction
47
48
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
49
class TestReadOnlyTransaction(TestCase):
50
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
51
    def setUp(self):
52
        self.transaction = transactions.ReadOnlyTransaction()
53
        super(TestReadOnlyTransaction, self).setUp()
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
54
55
    def test_register_clean(self):
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
56
        self.transaction.register_clean("anobject")
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
57
58
    def test_register_dirty_raises(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
59
        self.assertRaises(errors.ReadOnlyError,
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
60
                          self.transaction.register_dirty,"anobject")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
61
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
62
    def test_map(self):
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
63
        self.assertNotEqual(None, getattr(self.transaction, "map", None))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
64
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
65
    def test_add_and_get(self):
66
        weave = "a weave"
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
67
        self.transaction.map.add_weave("id", weave)
68
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
69
70
    def test_finish_returns(self):
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
71
        self.transaction.finish()
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
72
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
73
    def test_finish_does_not_tell_versioned_file_finished(self):
74
        # read only transactions never write, so theres no
75
        # need to inform versioned files about finishing
76
        weave = DummyWeave('a weave')
77
        self.transaction.finish()
78
        self.assertFalse(weave.finished)
79
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
80
    def test_zero_size_cache(self):
81
        self.transaction.set_cache_size(0)
82
        weave = DummyWeave('a weave')
83
        self.transaction.map.add_weave("id", weave)
84
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
85
        weave = None
86
        # add an object, should fall right out if there are no references
87
        self.transaction.register_clean(self.transaction.map.find_weave("id"))
88
        self.assertEqual(None, self.transaction.map.find_weave("id"))
89
        # but if we have a reference it should stick around
90
        weave = DummyWeave("another weave")
91
        self.transaction.map.add_weave("id", weave)
92
        self.transaction.register_clean(self.transaction.map.find_weave("id"))
93
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
94
        del weave
95
        # its not a weakref system
96
        self.assertEqual(DummyWeave("another weave"),
97
                         self.transaction.map.find_weave("id"))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
98
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
99
    def test_small_cache(self):
100
        self.transaction.set_cache_size(1)
101
        # add an object, should not fall right out if there are no references
102
        #sys.getrefcounts(foo)
103
        self.transaction.map.add_weave("id", DummyWeave("a weave"))
104
        self.transaction.register_clean(self.transaction.map.find_weave("id"))
105
        self.assertEqual(DummyWeave("a weave"),
106
                         self.transaction.map.find_weave("id"))
107
        self.transaction.map.add_weave("id2", DummyWeave("a weave also"))
108
        self.transaction.register_clean(self.transaction.map.find_weave("id2"))
109
        # currently a fifo
110
        self.assertEqual(None, self.transaction.map.find_weave("id"))
111
        self.assertEqual(DummyWeave("a weave also"),
112
                         self.transaction.map.find_weave("id2"))
113
114
    def test_small_cache_with_references(self):
115
        # if we have a reference it should stick around
116
        weave = "a weave"
117
        weave2 = "another weave"
118
        self.transaction.map.add_weave("id", weave)
119
        self.transaction.map.add_weave("id2", weave2)
120
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
121
        self.assertEqual(weave2, self.transaction.map.find_weave("id2"))
122
        weave = None
123
        # its not a weakref system
124
        self.assertEqual("a weave", self.transaction.map.find_weave("id"))
125
126
    def test_precious_with_zero_size_cache(self):
127
        self.transaction.set_cache_size(0)
128
        weave = DummyWeave('a weave')
129
        self.transaction.map.add_weave("id", weave)
130
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
131
        weave = None
132
        # add an object, should not fall out even with no references.
133
        self.transaction.register_clean(self.transaction.map.find_weave("id"),
134
                                        precious=True)
135
        self.assertEqual(DummyWeave('a weave'),
136
                         self.transaction.map.find_weave("id"))
137
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
138
    def test_writable(self):
139
        self.assertFalse(self.transaction.writeable())
140
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
141
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
142
class TestPassThroughTransaction(TestCase):
143
144
    def test_construct(self):
145
        transactions.PassThroughTransaction()
146
147
    def test_register_clean(self):
148
        transaction = transactions.PassThroughTransaction()
149
        transaction.register_clean("anobject")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
150
1417.1.8 by Robert Collins
use transactions in the weave store interface, which enables caching for log
151
    def test_register_dirty(self):
152
        transaction = transactions.PassThroughTransaction()
153
        transaction.register_dirty("anobject")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
154
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
155
    def test_map(self):
156
        transaction = transactions.PassThroughTransaction()
157
        self.assertNotEqual(None, getattr(transaction, "map", None))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
158
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
159
    def test_add_and_get(self):
160
        transaction = transactions.PassThroughTransaction()
161
        weave = "a weave"
162
        transaction.map.add_weave("id", weave)
163
        self.assertEqual(None, transaction.map.find_weave("id"))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
164
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
165
    def test_finish_returns(self):
166
        transaction = transactions.PassThroughTransaction()
167
        transaction.finish()
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
168
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
169
    def test_finish_tells_versioned_file_finished(self):
170
        # pass through transactions allow writes so they
171
        # need to inform versioned files about finishing
172
        weave = DummyWeave('a weave')
173
        transaction = transactions.PassThroughTransaction()
174
        transaction.register_dirty(weave)
175
        transaction.finish()
176
        self.assertTrue(weave.finished)
177
1417.1.10 by Robert Collins
add a cache bound to Transactions, and a precious facility, so that we keep inventory.weave in memory, but can discard weaves for other such files.
178
    def test_cache_is_ignored(self):
179
        transaction = transactions.PassThroughTransaction()
180
        transaction.set_cache_size(100)
181
        weave = "a weave"
182
        transaction.map.add_weave("id", weave)
183
        self.assertEqual(None, transaction.map.find_weave("id"))
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
184
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
185
    def test_writable(self):
186
        transaction = transactions.PassThroughTransaction()
187
        self.assertTrue(transaction.writeable())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
188
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
189
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
190
class TestWriteTransaction(TestCase):
191
192
    def setUp(self):
193
        self.transaction = transactions.WriteTransaction()
194
        super(TestWriteTransaction, self).setUp()
195
196
    def test_register_clean(self):
197
        self.transaction.register_clean("anobject")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
198
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
199
    def test_register_dirty(self):
200
        self.transaction.register_dirty("anobject")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
201
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
202
    def test_map(self):
203
        self.assertNotEqual(None, getattr(self.transaction, "map", None))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
204
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
205
    def test_add_and_get(self):
206
        weave = "a weave"
207
        self.transaction.map.add_weave("id", weave)
208
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
209
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
210
    def test_finish_returns(self):
211
        self.transaction.finish()
212
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
213
    def test_finish_tells_versioned_file_finished(self):
214
        # write transactions allow writes so they
215
        # need to inform versioned files about finishing
216
        weave = DummyWeave('a weave')
217
        self.transaction.register_dirty(weave)
218
        self.transaction.finish()
219
        self.assertTrue(weave.finished)
220
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
221
    def test_zero_size_cache(self):
222
        self.transaction.set_cache_size(0)
223
        # add an object, should fall right out if there are no references
224
        weave = DummyWeave('a weave')
225
        self.transaction.map.add_weave("id", weave)
226
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
227
        weave = None
228
        self.transaction.register_clean(self.transaction.map.find_weave("id"))
229
        self.assertEqual(None, self.transaction.map.find_weave("id"))
230
        # but if we have a reference to a clean object it should stick around
231
        weave = DummyWeave("another weave")
232
        self.transaction.map.add_weave("id", weave)
233
        self.transaction.register_clean(self.transaction.map.find_weave("id"))
234
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
235
        del weave
236
        # its not a weakref system
237
        self.assertEqual(DummyWeave("another weave"),
238
                         self.transaction.map.find_weave("id"))
239
240
    def test_zero_size_cache_dirty_objects(self):
241
        self.transaction.set_cache_size(0)
242
        # add a dirty object, which should not fall right out.
243
        weave = DummyWeave('a weave')
244
        self.transaction.map.add_weave("id", weave)
245
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
246
        weave = None
247
        self.transaction.register_dirty(self.transaction.map.find_weave("id"))
248
        self.assertNotEqual(None, self.transaction.map.find_weave("id"))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
249
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
250
    def test_clean_to_dirty(self):
251
        # a clean object may become dirty.
252
        weave = DummyWeave('A weave')
253
        self.transaction.map.add_weave("id", weave)
254
        self.transaction.register_clean(weave)
255
        self.transaction.register_dirty(weave)
256
        self.assertTrue(self.transaction.is_dirty(weave))
257
        self.assertFalse(self.transaction.is_clean(weave))
258
259
    def test_small_cache(self):
260
        self.transaction.set_cache_size(1)
261
        # add an object, should not fall right out if there are no references
262
        #sys.getrefcounts(foo)
263
        self.transaction.map.add_weave("id", DummyWeave("a weave"))
264
        self.transaction.register_clean(self.transaction.map.find_weave("id"))
265
        self.assertEqual(DummyWeave("a weave"),
266
                         self.transaction.map.find_weave("id"))
267
        self.transaction.map.add_weave("id2", DummyWeave("a weave also"))
268
        self.transaction.register_clean(self.transaction.map.find_weave("id2"))
269
        # currently a fifo
270
        self.assertEqual(None, self.transaction.map.find_weave("id"))
271
        self.assertEqual(DummyWeave("a weave also"),
272
                         self.transaction.map.find_weave("id2"))
273
274
    def test_small_cache_with_references(self):
275
        # if we have a reference it should stick around
276
        weave = "a weave"
277
        weave2 = "another weave"
278
        self.transaction.map.add_weave("id", weave)
279
        self.transaction.map.add_weave("id2", weave2)
280
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
281
        self.assertEqual(weave2, self.transaction.map.find_weave("id2"))
282
        weave = None
283
        # its not a weakref system
284
        self.assertEqual("a weave", self.transaction.map.find_weave("id"))
285
286
    def test_precious_with_zero_size_cache(self):
287
        self.transaction.set_cache_size(0)
288
        weave = DummyWeave('a weave')
289
        self.transaction.map.add_weave("id", weave)
290
        self.assertEqual(weave, self.transaction.map.find_weave("id"))
291
        weave = None
292
        # add an object, should not fall out even with no references.
293
        self.transaction.register_clean(self.transaction.map.find_weave("id"),
294
                                        precious=True)
295
        self.assertEqual(DummyWeave('a weave'),
296
                         self.transaction.map.find_weave("id"))
1594.2.20 by Robert Collins
Add finished() notifications to transactions.
297
298
    def test_writable(self):
299
        self.assertTrue(self.transaction.writeable())