1
# Copyright (C) 2005 by Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
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.
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.
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
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
"""Tests for the behaviour of the Transaction concept in bzr."""
20
# import system imports here
24
#import bzrlib specific imports here
25
import bzrlib.errors as errors
26
from bzrlib.tests import TestCase, TestCaseInTempDir
27
import bzrlib.transactions as transactions
30
class DummyWeave(object):
31
"""A class that can be instantiated and compared."""
33
def __init__(self, message):
34
self._message = message
37
def __eq__(self, other):
40
return self._message == other._message
42
def transaction_finished(self):
46
class TestSymbols(TestCase):
48
def test_public_symbols(self):
49
from bzrlib.transactions import ReadOnlyTransaction
50
from bzrlib.transactions import PassThroughTransaction
53
class TestReadOnlyTransaction(TestCase):
56
self.transaction = transactions.ReadOnlyTransaction()
57
super(TestReadOnlyTransaction, self).setUp()
59
def test_register_clean(self):
60
self.transaction.register_clean("anobject")
62
def test_register_dirty_raises(self):
63
self.assertRaises(errors.ReadOnlyError,
64
self.transaction.register_dirty,"anobject")
67
self.assertNotEqual(None, getattr(self.transaction, "map", None))
69
def test_add_and_get(self):
71
self.transaction.map.add_weave("id", weave)
72
self.assertEqual(weave, self.transaction.map.find_weave("id"))
74
def test_finish_returns(self):
75
self.transaction.finish()
77
def test_finish_does_not_tell_versioned_file_finished(self):
78
# read only transactions never write, so theres no
79
# need to inform versioned files about finishing
80
weave = DummyWeave('a weave')
81
self.transaction.finish()
82
self.assertFalse(weave.finished)
84
def test_zero_size_cache(self):
85
self.transaction.set_cache_size(0)
86
weave = DummyWeave('a weave')
87
self.transaction.map.add_weave("id", weave)
88
self.assertEqual(weave, self.transaction.map.find_weave("id"))
90
# add an object, should fall right out if there are no references
91
self.transaction.register_clean(self.transaction.map.find_weave("id"))
92
self.assertEqual(None, self.transaction.map.find_weave("id"))
93
# but if we have a reference it should stick around
94
weave = DummyWeave("another weave")
95
self.transaction.map.add_weave("id", weave)
96
self.transaction.register_clean(self.transaction.map.find_weave("id"))
97
self.assertEqual(weave, self.transaction.map.find_weave("id"))
99
# its not a weakref system
100
self.assertEqual(DummyWeave("another weave"),
101
self.transaction.map.find_weave("id"))
103
def test_small_cache(self):
104
self.transaction.set_cache_size(1)
105
# add an object, should not fall right out if there are no references
106
#sys.getrefcounts(foo)
107
self.transaction.map.add_weave("id", DummyWeave("a weave"))
108
self.transaction.register_clean(self.transaction.map.find_weave("id"))
109
self.assertEqual(DummyWeave("a weave"),
110
self.transaction.map.find_weave("id"))
111
self.transaction.map.add_weave("id2", DummyWeave("a weave also"))
112
self.transaction.register_clean(self.transaction.map.find_weave("id2"))
114
self.assertEqual(None, self.transaction.map.find_weave("id"))
115
self.assertEqual(DummyWeave("a weave also"),
116
self.transaction.map.find_weave("id2"))
118
def test_small_cache_with_references(self):
119
# if we have a reference it should stick around
121
weave2 = "another weave"
122
self.transaction.map.add_weave("id", weave)
123
self.transaction.map.add_weave("id2", weave2)
124
self.assertEqual(weave, self.transaction.map.find_weave("id"))
125
self.assertEqual(weave2, self.transaction.map.find_weave("id2"))
127
# its not a weakref system
128
self.assertEqual("a weave", self.transaction.map.find_weave("id"))
130
def test_precious_with_zero_size_cache(self):
131
self.transaction.set_cache_size(0)
132
weave = DummyWeave('a weave')
133
self.transaction.map.add_weave("id", weave)
134
self.assertEqual(weave, self.transaction.map.find_weave("id"))
136
# add an object, should not fall out even with no references.
137
self.transaction.register_clean(self.transaction.map.find_weave("id"),
139
self.assertEqual(DummyWeave('a weave'),
140
self.transaction.map.find_weave("id"))
142
def test_precious_revision_history(self):
143
"""Disabled test until revision-history is a real object."""
144
print "Disabled: test_precious_revision_history"
146
self.transaction.set_cache_size(0)
148
self.transaction.map.add_revision_history(history)
149
self.assertEqual(history, self.transaction.map.find_revision_history())
151
# add an object, should not fall out even with no references.
152
self.transaction.register_clean(
153
self.transaction.map.find_revision_history(), precious=True)
154
self.assertEqual([], self.transaction.map.find_revision_history())
156
def test_writable(self):
157
self.assertFalse(self.transaction.writeable())
160
class TestPassThroughTransaction(TestCase):
162
def test_construct(self):
163
transactions.PassThroughTransaction()
165
def test_register_clean(self):
166
transaction = transactions.PassThroughTransaction()
167
transaction.register_clean("anobject")
169
def test_register_dirty(self):
170
transaction = transactions.PassThroughTransaction()
171
transaction.register_dirty("anobject")
174
transaction = transactions.PassThroughTransaction()
175
self.assertNotEqual(None, getattr(transaction, "map", None))
177
def test_add_and_get(self):
178
transaction = transactions.PassThroughTransaction()
180
transaction.map.add_weave("id", weave)
181
self.assertEqual(None, transaction.map.find_weave("id"))
183
def test_finish_returns(self):
184
transaction = transactions.PassThroughTransaction()
187
def test_finish_tells_versioned_file_finished(self):
188
# pass through transactions allow writes so they
189
# need to inform versioned files about finishing
190
weave = DummyWeave('a weave')
191
transaction = transactions.PassThroughTransaction()
192
transaction.register_dirty(weave)
194
self.assertTrue(weave.finished)
196
def test_cache_is_ignored(self):
197
transaction = transactions.PassThroughTransaction()
198
transaction.set_cache_size(100)
200
transaction.map.add_weave("id", weave)
201
self.assertEqual(None, transaction.map.find_weave("id"))
203
def test_writable(self):
204
transaction = transactions.PassThroughTransaction()
205
self.assertTrue(transaction.writeable())
208
class TestWriteTransaction(TestCase):
211
self.transaction = transactions.WriteTransaction()
212
super(TestWriteTransaction, self).setUp()
214
def test_register_clean(self):
215
self.transaction.register_clean("anobject")
217
def test_register_dirty(self):
218
self.transaction.register_dirty("anobject")
221
self.assertNotEqual(None, getattr(self.transaction, "map", None))
223
def test_add_and_get(self):
225
self.transaction.map.add_weave("id", weave)
226
self.assertEqual(weave, self.transaction.map.find_weave("id"))
228
def test_finish_returns(self):
229
self.transaction.finish()
231
def test_finish_tells_versioned_file_finished(self):
232
# write transactions allow writes so they
233
# need to inform versioned files about finishing
234
weave = DummyWeave('a weave')
235
self.transaction.register_dirty(weave)
236
self.transaction.finish()
237
self.assertTrue(weave.finished)
239
def test_zero_size_cache(self):
240
self.transaction.set_cache_size(0)
241
# add an object, should fall right out if there are no references
242
weave = DummyWeave('a weave')
243
self.transaction.map.add_weave("id", weave)
244
self.assertEqual(weave, self.transaction.map.find_weave("id"))
246
self.transaction.register_clean(self.transaction.map.find_weave("id"))
247
self.assertEqual(None, self.transaction.map.find_weave("id"))
248
# but if we have a reference to a clean object it should stick around
249
weave = DummyWeave("another weave")
250
self.transaction.map.add_weave("id", weave)
251
self.transaction.register_clean(self.transaction.map.find_weave("id"))
252
self.assertEqual(weave, self.transaction.map.find_weave("id"))
254
# its not a weakref system
255
self.assertEqual(DummyWeave("another weave"),
256
self.transaction.map.find_weave("id"))
258
def test_zero_size_cache_dirty_objects(self):
259
self.transaction.set_cache_size(0)
260
# add a dirty object, which should not fall right out.
261
weave = DummyWeave('a weave')
262
self.transaction.map.add_weave("id", weave)
263
self.assertEqual(weave, self.transaction.map.find_weave("id"))
265
self.transaction.register_dirty(self.transaction.map.find_weave("id"))
266
self.assertNotEqual(None, self.transaction.map.find_weave("id"))
268
def test_clean_to_dirty(self):
269
# a clean object may become dirty.
270
weave = DummyWeave('A weave')
271
self.transaction.map.add_weave("id", weave)
272
self.transaction.register_clean(weave)
273
self.transaction.register_dirty(weave)
274
self.assertTrue(self.transaction.is_dirty(weave))
275
self.assertFalse(self.transaction.is_clean(weave))
277
def test_small_cache(self):
278
self.transaction.set_cache_size(1)
279
# add an object, should not fall right out if there are no references
280
#sys.getrefcounts(foo)
281
self.transaction.map.add_weave("id", DummyWeave("a weave"))
282
self.transaction.register_clean(self.transaction.map.find_weave("id"))
283
self.assertEqual(DummyWeave("a weave"),
284
self.transaction.map.find_weave("id"))
285
self.transaction.map.add_weave("id2", DummyWeave("a weave also"))
286
self.transaction.register_clean(self.transaction.map.find_weave("id2"))
288
self.assertEqual(None, self.transaction.map.find_weave("id"))
289
self.assertEqual(DummyWeave("a weave also"),
290
self.transaction.map.find_weave("id2"))
292
def test_small_cache_with_references(self):
293
# if we have a reference it should stick around
295
weave2 = "another weave"
296
self.transaction.map.add_weave("id", weave)
297
self.transaction.map.add_weave("id2", weave2)
298
self.assertEqual(weave, self.transaction.map.find_weave("id"))
299
self.assertEqual(weave2, self.transaction.map.find_weave("id2"))
301
# its not a weakref system
302
self.assertEqual("a weave", self.transaction.map.find_weave("id"))
304
def test_precious_with_zero_size_cache(self):
305
self.transaction.set_cache_size(0)
306
weave = DummyWeave('a weave')
307
self.transaction.map.add_weave("id", weave)
308
self.assertEqual(weave, self.transaction.map.find_weave("id"))
310
# add an object, should not fall out even with no references.
311
self.transaction.register_clean(self.transaction.map.find_weave("id"),
313
self.assertEqual(DummyWeave('a weave'),
314
self.transaction.map.find_weave("id"))
316
def test_writable(self):
317
self.assertTrue(self.transaction.writeable())