143
142
b2 = self.make_branch('b2')
144
143
b1.tags.merge_to(b2.tags)
145
def test_read_lock_caches_tags(self):
146
"""Tags are read from a branch only once during a read-lock."""
147
# Open the same branch twice. Read-lock one, and then mutate the tags
148
# in the second. The read-locked branch never re-reads the tags, so it
149
# never observes the changed/new tags.
150
b1 = self.make_branch('b')
151
b1.tags.set_tag('one', 'rev-1')
152
b2 = b1.bzrdir.open_branch()
154
self.assertEqual({'one': 'rev-1'}, b1.tags.get_tag_dict())
155
# Add a tag and modify a tag in b2. b1 is read-locked and has already
156
# read the tags, so it is unaffected.
157
b2.tags.set_tag('one', 'rev-1-changed')
158
b2.tags.set_tag('two', 'rev-2')
159
self.assertEqual({'one': 'rev-1'}, b1.tags.get_tag_dict())
161
# Once unlocked the cached value is forgotten, so now the latest tags
164
{'one': 'rev-1-changed', 'two': 'rev-2'}, b1.tags.get_tag_dict())
166
def test_unlocked_does_not_cache_tags(self):
167
"""Unlocked branches do not cache tags."""
168
# Open the same branch twice.
169
b1 = self.make_branch('b')
170
b1.tags.set_tag('one', 'rev-1')
171
b2 = b1.bzrdir.open_branch()
172
self.assertEqual({'one': 'rev-1'}, b1.tags.get_tag_dict())
173
# Add a tag and modify a tag in b2. b1 isn't locked, so it will
174
# immediately return the new tags too.
175
b2.tags.set_tag('one', 'rev-1-changed')
176
b2.tags.set_tag('two', 'rev-2')
178
{'one': 'rev-1-changed', 'two': 'rev-2'}, b1.tags.get_tag_dict())
180
def test_cached_tag_dict_not_accidentally_mutable(self):
181
"""When there's a cached version of the tags, b.tags.get_tag_dict
182
returns a copy of the cached data so that callers cannot accidentally
185
b = self.make_branch('b')
186
b.tags.set_tag('one', 'rev-1')
187
self.addCleanup(b.lock_read().unlock)
188
# The first time the data returned will not be in the cache
189
tags_dict = b.tags.get_tag_dict()
190
tags_dict['two'] = 'rev-2'
191
# The second time the data comes from the cache
192
tags_dict = b.tags.get_tag_dict()
193
tags_dict['three'] = 'rev-3'
194
# The get_tag_dict() result should still be unchanged, even though we
195
# mutated its earlier return values.
196
self.assertEqual({'one': 'rev-1'}, b.tags.get_tag_dict())
198
def make_write_locked_branch_with_one_tag(self):
199
b = self.make_branch('b')
200
b.tags.set_tag('one', 'rev-1')
201
self.addCleanup(b.lock_write().unlock)
203
b.tags.get_tag_dict()
206
def test_set_tag_invalides_cache(self):
207
b = self.make_write_locked_branch_with_one_tag()
208
b.tags.set_tag('one', 'rev-1-changed')
209
self.assertEqual({'one': 'rev-1-changed'}, b.tags.get_tag_dict())
211
def test_delete_tag_invalides_cache(self):
212
b = self.make_write_locked_branch_with_one_tag()
213
b.tags.delete_tag('one')
214
self.assertEqual({}, b.tags.get_tag_dict())
216
def test_merge_to_invalides_cache(self):
217
b1 = self.make_write_locked_branch_with_one_tag()
218
b2 = self.make_branch('b2')
219
b2.tags.set_tag('two', 'rev-2')
220
b2.tags.merge_to(b1.tags)
222
{'one': 'rev-1', 'two': 'rev-2'}, b1.tags.get_tag_dict())
224
def test_rename_revisions_invalides_cache(self):
225
b = self.make_write_locked_branch_with_one_tag()
226
b.tags.rename_revisions({'rev-1': 'rev-1-changed'})
227
self.assertEqual({'one': 'rev-1-changed'}, b.tags.get_tag_dict())
147
230
class TestUnsupportedTags(per_branch.TestCaseWithBranch):
148
231
"""Formats that don't support tags should give reasonable errors."""