1
# Copyright (C) 2005, 2006, 2009, 2011 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
"""Tests for the behaviour of the Transaction concept in bzr."""
20
#import bzrlib specific imports here
21
import bzrlib.errors as errors
22
from bzrlib.tests import TestCase
23
import bzrlib.transactions as transactions
26
class DummyWeave(object):
27
"""A class that can be instantiated and compared."""
29
def __init__(self, message):
30
self._message = message
33
def __eq__(self, other):
36
return self._message == other._message
38
def transaction_finished(self):
42
class TestSymbols(TestCase):
44
def test_public_symbols(self):
45
from bzrlib.transactions import ReadOnlyTransaction
46
from bzrlib.transactions import PassThroughTransaction
49
class TestReadOnlyTransaction(TestCase):
52
self.transaction = transactions.ReadOnlyTransaction()
53
super(TestReadOnlyTransaction, self).setUp()
55
def test_register_clean(self):
56
self.transaction.register_clean("anobject")
58
def test_register_dirty_raises(self):
59
self.assertRaises(errors.ReadOnlyError,
60
self.transaction.register_dirty,"anobject")
63
self.assertNotEqual(None, getattr(self.transaction, "map", None))
65
def test_add_and_get(self):
67
self.transaction.map.add_weave("id", weave)
68
self.assertEqual(weave, self.transaction.map.find_weave("id"))
70
def test_finish_returns(self):
71
self.transaction.finish()
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)
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"))
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"))
95
# its not a weakref system
96
self.assertEqual(DummyWeave("another weave"),
97
self.transaction.map.find_weave("id"))
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"))
110
self.assertEqual(None, self.transaction.map.find_weave("id"))
111
self.assertEqual(DummyWeave("a weave also"),
112
self.transaction.map.find_weave("id2"))
114
def test_small_cache_with_references(self):
115
# if we have a reference it should stick around
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"))
123
# its not a weakref system
124
self.assertEqual("a weave", self.transaction.map.find_weave("id"))
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"))
132
# add an object, should not fall out even with no references.
133
self.transaction.register_clean(self.transaction.map.find_weave("id"),
135
self.assertEqual(DummyWeave('a weave'),
136
self.transaction.map.find_weave("id"))
138
def test_writable(self):
139
self.assertFalse(self.transaction.writeable())
142
class TestPassThroughTransaction(TestCase):
144
def test_construct(self):
145
transactions.PassThroughTransaction()
147
def test_register_clean(self):
148
transaction = transactions.PassThroughTransaction()
149
transaction.register_clean("anobject")
151
def test_register_dirty(self):
152
transaction = transactions.PassThroughTransaction()
153
transaction.register_dirty("anobject")
156
transaction = transactions.PassThroughTransaction()
157
self.assertNotEqual(None, getattr(transaction, "map", None))
159
def test_add_and_get(self):
160
transaction = transactions.PassThroughTransaction()
162
transaction.map.add_weave("id", weave)
163
self.assertEqual(None, transaction.map.find_weave("id"))
165
def test_finish_returns(self):
166
transaction = transactions.PassThroughTransaction()
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)
176
self.assertTrue(weave.finished)
178
def test_cache_is_ignored(self):
179
transaction = transactions.PassThroughTransaction()
180
transaction.set_cache_size(100)
182
transaction.map.add_weave("id", weave)
183
self.assertEqual(None, transaction.map.find_weave("id"))
185
def test_writable(self):
186
transaction = transactions.PassThroughTransaction()
187
self.assertTrue(transaction.writeable())
190
class TestWriteTransaction(TestCase):
193
self.transaction = transactions.WriteTransaction()
194
super(TestWriteTransaction, self).setUp()
196
def test_register_clean(self):
197
self.transaction.register_clean("anobject")
199
def test_register_dirty(self):
200
self.transaction.register_dirty("anobject")
203
self.assertNotEqual(None, getattr(self.transaction, "map", None))
205
def test_add_and_get(self):
207
self.transaction.map.add_weave("id", weave)
208
self.assertEqual(weave, self.transaction.map.find_weave("id"))
210
def test_finish_returns(self):
211
self.transaction.finish()
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)
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"))
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"))
236
# its not a weakref system
237
self.assertEqual(DummyWeave("another weave"),
238
self.transaction.map.find_weave("id"))
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"))
247
self.transaction.register_dirty(self.transaction.map.find_weave("id"))
248
self.assertNotEqual(None, self.transaction.map.find_weave("id"))
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))
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"))
270
self.assertEqual(None, self.transaction.map.find_weave("id"))
271
self.assertEqual(DummyWeave("a weave also"),
272
self.transaction.map.find_weave("id2"))
274
def test_small_cache_with_references(self):
275
# if we have a reference it should stick around
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"))
283
# its not a weakref system
284
self.assertEqual("a weave", self.transaction.map.find_weave("id"))
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"))
292
# add an object, should not fall out even with no references.
293
self.transaction.register_clean(self.transaction.map.find_weave("id"),
295
self.assertEqual(DummyWeave('a weave'),
296
self.transaction.map.find_weave("id"))
298
def test_writable(self):
299
self.assertTrue(self.transaction.writeable())