/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/repository_implementations/test_commit_builder.py

  • Committer: Robert Collins
  • Date: 2007-09-04 03:53:07 UTC
  • mto: (2592.3.126 repository)
  • mto: This revision was merged to the branch mainline in revision 2795.
  • Revision ID: robertc@robertcollins.net-20070904035307-y5jacs7zl15v2nvo
Add reasonably comprehensive tests for path last modified and per file graph behaviour.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests for repository commit builder."""
18
18
 
 
19
from errno import EISDIR
 
20
import os
 
21
 
19
22
from bzrlib import inventory
20
23
from bzrlib.errors import NonAsciiRevisionId, CannotSetRevisionId
21
24
from bzrlib.repository import CommitBuilder
173
176
        self.addCleanup(basis_tree.unlock)
174
177
        self.assertEqual(rev_id, basis_tree.inventory.root.revision)
175
178
 
 
179
    def _get_revtrees(self, tree, revision_ids):
 
180
        trees = list(tree.branch.repository.revision_trees(revision_ids))
 
181
        for tree in trees:
 
182
            tree.lock_read()
 
183
            self.addCleanup(tree.unlock)
 
184
        return trees
 
185
 
 
186
    def test_last_modified_revision_after_commit_root_unchanged(self):
 
187
        # commiting without changing the root does not change the 
 
188
        # last modified except on non-rich-root-repositories.
 
189
        tree = self.make_branch_and_tree('.')
 
190
        rev1 = tree.commit('')
 
191
        rev2 = tree.commit('')
 
192
        tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
 
193
        self.assertEqual(rev1, tree1.inventory.root.revision)
 
194
        if tree.branch.repository.supports_rich_root():
 
195
            self.assertEqual(rev1, tree2.inventory.root.revision)
 
196
        else:
 
197
            self.assertEqual(rev2, tree2.inventory.root.revision)
 
198
 
 
199
    def _add_commit_check_unchanged(self, tree, name):
 
200
        tree.add([name], [name + 'id'])
 
201
        rev1 = tree.commit('')
 
202
        rev2 = tree.commit('')
 
203
        tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
 
204
        self.assertEqual(rev1, tree1.inventory[name + 'id'].revision)
 
205
        self.assertEqual(rev1, tree2.inventory[name + 'id'].revision)
 
206
        self.assertFileAncestry([rev1], tree, name)
 
207
 
 
208
    def test_last_modified_revision_after_commit_dir_unchanged(self):
 
209
        # committing without changing a dir does not change the last modified.
 
210
        tree = self.make_branch_and_tree('.')
 
211
        self.build_tree(['dir/'])
 
212
        self._add_commit_check_unchanged(tree, 'dir')
 
213
 
 
214
    def test_last_modified_revision_after_commit_dir_contents_unchanged(self):
 
215
        # committing without changing a dir does not change the last modified
 
216
        # of the dir even the dirs contents are changed.
 
217
        tree = self.make_branch_and_tree('.')
 
218
        self.build_tree(['dir/'])
 
219
        tree.add(['dir'], ['dirid'])
 
220
        rev1 = tree.commit('')
 
221
        self.build_tree(['dir/content'])
 
222
        tree.add(['dir/content'], ['contentid'])
 
223
        rev2 = tree.commit('')
 
224
        tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
 
225
        self.assertEqual(rev1, tree1.inventory['dirid'].revision)
 
226
        self.assertEqual(rev1, tree2.inventory['dirid'].revision)
 
227
        self.assertFileAncestry([rev1], tree, 'dir')
 
228
 
 
229
    def test_last_modified_revision_after_commit_file_unchanged(self):
 
230
        # committing without changing a file does not change the last modified.
 
231
        tree = self.make_branch_and_tree('.')
 
232
        self.build_tree(['file'])
 
233
        self._add_commit_check_unchanged(tree, 'file')
 
234
 
 
235
    def test_last_modified_revision_after_commit_link_unchanged(self):
 
236
        # committing without changing a link does not change the last modified.
 
237
        self.requireFeature(tests.SymlinkFeature)
 
238
        tree = self.make_branch_and_tree('.')
 
239
        os.symlink('target', 'link')
 
240
        self._add_commit_check_unchanged(tree, 'link')
 
241
 
 
242
    def _add_commit_renamed_check_changed(self, tree, name):
 
243
        def rename():
 
244
            tree.rename_one(name, 'new_' + name)
 
245
        self._add_commit_change_check_changed(tree, name, rename)
 
246
 
 
247
    def test_last_modified_revision_after_rename_dir_changes(self):
 
248
        # renaming a dir changes the last modified.
 
249
        tree = self.make_branch_and_tree('.')
 
250
        self.build_tree(['dir/'])
 
251
        self._add_commit_renamed_check_changed(tree, 'dir')
 
252
 
 
253
    def test_last_modified_revision_after_rename_file_changes(self):
 
254
        # renaming a file changes the last modified.
 
255
        tree = self.make_branch_and_tree('.')
 
256
        self.build_tree(['file'])
 
257
        self._add_commit_renamed_check_changed(tree, 'file')
 
258
 
 
259
    def test_last_modified_revision_after_rename_link_changes(self):
 
260
        # renaming a link changes the last modified.
 
261
        self.requireFeature(tests.SymlinkFeature)
 
262
        tree = self.make_branch_and_tree('.')
 
263
        os.symlink('target', 'link')
 
264
        self._add_commit_renamed_check_changed(tree, 'link')
 
265
 
 
266
    def _add_commit_reparent_check_changed(self, tree, name):
 
267
        self.build_tree(['newparent/'])
 
268
        tree.add(['newparent'])
 
269
        def reparent():
 
270
            tree.rename_one(name, 'newparent/new_' + name)
 
271
        self._add_commit_change_check_changed(tree, name, reparent)
 
272
 
 
273
    def test_last_modified_revision_after_reparent_dir_changes(self):
 
274
        # reparenting a dir changes the last modified.
 
275
        tree = self.make_branch_and_tree('.')
 
276
        self.build_tree(['dir/'])
 
277
        self._add_commit_reparent_check_changed(tree, 'dir')
 
278
 
 
279
    def test_last_modified_revision_after_reparent_file_changes(self):
 
280
        # reparenting a file changes the last modified.
 
281
        tree = self.make_branch_and_tree('.')
 
282
        self.build_tree(['file'])
 
283
        self._add_commit_reparent_check_changed(tree, 'file')
 
284
 
 
285
    def test_last_modified_revision_after_reparent_link_changes(self):
 
286
        # reparenting a link changes the last modified.
 
287
        self.requireFeature(tests.SymlinkFeature)
 
288
        tree = self.make_branch_and_tree('.')
 
289
        os.symlink('target', 'link')
 
290
        self._add_commit_reparent_check_changed(tree, 'link')
 
291
 
 
292
    def _add_commit_change_check_changed(self, tree, name, changer):
 
293
        tree.add([name], [name + 'id'])
 
294
        rev1 = tree.commit('')
 
295
        changer()
 
296
        rev2 = tree.commit('')
 
297
        tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
 
298
        self.assertEqual(rev1, tree1.inventory[name + 'id'].revision)
 
299
        self.assertEqual(rev2, tree2.inventory[name + 'id'].revision)
 
300
        self.assertFileAncestry([rev1, rev2], tree, name)
 
301
 
 
302
    def assertFileAncestry(self, ancestry, tree, name, alt_ancestry=None):
 
303
        # all the changes that have occured should be in the ancestry
 
304
        # (closest to a public per-file graph API we have today)
 
305
        tree.lock_read()
 
306
        self.addCleanup(tree.unlock)
 
307
        vw = tree.branch.repository.weave_store.get_weave(name + 'id',
 
308
            tree.branch.repository.get_transaction())
 
309
        result = vw.get_ancestry([ancestry[-1]])
 
310
        if alt_ancestry is None:
 
311
            self.assertEqual(ancestry, result)
 
312
        else:
 
313
            self.assertSubset([tuple(result)],
 
314
                [tuple(ancestry), tuple(alt_ancestry)])
 
315
 
 
316
    def test_last_modified_revision_after_content_file_changes(self):
 
317
        # altering a file changes the last modified.
 
318
        tree = self.make_branch_and_tree('.')
 
319
        self.build_tree(['file'])
 
320
        def change_file():
 
321
            tree.put_file_bytes_non_atomic('fileid', 'new content')
 
322
        self._add_commit_change_check_changed(tree, 'file', change_file)
 
323
 
 
324
    def test_last_modified_revision_after_content_link_changes(self):
 
325
        # changing a link changes the last modified.
 
326
        self.requireFeature(tests.SymlinkFeature)
 
327
        tree = self.make_branch_and_tree('.')
 
328
        os.symlink('target', 'link')
 
329
        def change_link():
 
330
            os.unlink('link')
 
331
            os.symlink('newtarget', 'link')
 
332
        self._add_commit_change_check_changed(tree, 'link', change_link)
 
333
 
 
334
    def _commit_sprout(self, tree, name):
 
335
        tree.add([name], [name + 'id'])
 
336
        rev_id = tree.commit('')
 
337
        return rev_id, tree.bzrdir.sprout('t2').open_workingtree()
 
338
 
 
339
    def _rename_in_tree(self, tree, name):
 
340
        tree.rename_one(name, 'new_' + name)
 
341
        return tree.commit('')
 
342
 
 
343
    def _commit_sprout_rename_merge(self, tree1, name):
 
344
        rev1, tree2 = self._commit_sprout(tree1, name)
 
345
        # change both sides equally
 
346
        rev2 = self._rename_in_tree(tree1, name)
 
347
        rev3 = self._rename_in_tree(tree2, name)
 
348
        tree1.merge_from_branch(tree2.branch)
 
349
        rev4 = tree1.commit('')
 
350
        tree3, = self._get_revtrees(tree1, [rev4])
 
351
        self.assertEqual(rev4, tree3.inventory[name + 'id'].revision)
 
352
        self.assertFileAncestry([rev1, rev2, rev3, rev4], tree1, name,
 
353
            [rev1, rev3, rev2, rev4])
 
354
 
 
355
    def test_last_modified_revision_after_merge_dir_changes(self):
 
356
        # merge a dir changes the last modified.
 
357
        tree1 = self.make_branch_and_tree('t1')
 
358
        self.build_tree(['t1/dir/'])
 
359
        self._commit_sprout_rename_merge(tree1, 'dir')
 
360
 
 
361
    def test_last_modified_revision_after_merge_file_changes(self):
 
362
        # merge a file changes the last modified.
 
363
        tree1 = self.make_branch_and_tree('t1')
 
364
        self.build_tree(['t1/file'])
 
365
        self._commit_sprout_rename_merge(tree1, 'file')
 
366
 
 
367
    def test_last_modified_revision_after_merge_link_changes(self):
 
368
        # merge a link changes the last modified.
 
369
        self.requireFeature(tests.SymlinkFeature)
 
370
        tree1 = self.make_branch_and_tree('t1')
 
371
        os.symlink('target', 't1/link')
 
372
        self._commit_sprout_rename_merge(tree1, 'link')
 
373
 
 
374
    def _commit_sprout_rename_merge_converged(self, tree1, name):
 
375
        rev1, tree2 = self._commit_sprout(tree1, name)
 
376
        # change on the other side to merge back
 
377
        rev2 = self._rename_in_tree(tree2, name)
 
378
        tree1.merge_from_branch(tree2.branch)
 
379
        rev3 = tree1.commit('')
 
380
        tree3, = self._get_revtrees(tree1, [rev2])
 
381
        self.assertEqual(rev2, tree3.inventory[name + 'id'].revision)
 
382
        self.assertFileAncestry([rev1, rev2], tree1, name)
 
383
 
 
384
    def test_last_modified_revision_after_converged_merge_dir_changes(self):
 
385
        # merge a dir changes the last modified.
 
386
        tree1 = self.make_branch_and_tree('t1')
 
387
        self.build_tree(['t1/dir/'])
 
388
        self._commit_sprout_rename_merge_converged(tree1, 'dir')
 
389
 
 
390
    def test_last_modified_revision_after_converged_merge_file_changes(self):
 
391
        # merge a file changes the last modified.
 
392
        tree1 = self.make_branch_and_tree('t1')
 
393
        self.build_tree(['t1/file'])
 
394
        self._commit_sprout_rename_merge_converged(tree1, 'file')
 
395
 
 
396
    def test_last_modified_revision_after_converged_merge_link_changes(self):
 
397
        # merge a link changes the last modified.
 
398
        self.requireFeature(tests.SymlinkFeature)
 
399
        tree1 = self.make_branch_and_tree('t1')
 
400
        os.symlink('target', 't1/link')
 
401
        self._commit_sprout_rename_merge_converged(tree1, 'link')
 
402
 
 
403
    def make_dir(self, name):
 
404
        self.build_tree([name + '/'])
 
405
 
 
406
    def make_file(self, name):
 
407
        self.build_tree([name])
 
408
 
 
409
    def make_link(self, name):
 
410
        self.requireFeature(tests.SymlinkFeature)
 
411
        os.symlink('target', name)
 
412
 
 
413
    def _check_kind_change(self, make_before, make_after):
 
414
        tree = self.make_branch_and_tree('.')
 
415
        path = 'name'
 
416
        make_before(path)
 
417
        def change_kind():
 
418
            try:
 
419
                os.unlink(path)
 
420
            except OSError, e:
 
421
                if e.errno != EISDIR:
 
422
                    raise
 
423
                os.rmdir(path)
 
424
            make_after(path)
 
425
        self._add_commit_change_check_changed(tree, path, change_kind)
 
426
 
 
427
    def test_last_modified_dir_file(self):
 
428
        self._check_kind_change(self.make_dir, self.make_file)
 
429
 
 
430
    def test_last_modified_dir_link(self):
 
431
        self._check_kind_change(self.make_dir, self.make_link)
 
432
 
 
433
    def test_last_modified_link_file(self):
 
434
        self._check_kind_change(self.make_link, self.make_file)
 
435
 
 
436
    def test_last_modified_link_dir(self):
 
437
        self._check_kind_change(self.make_link, self.make_dir)
 
438
 
 
439
    def test_last_modified_file_dir(self):
 
440
        self._check_kind_change(self.make_file, self.make_dir)
 
441
 
 
442
    def test_last_modified_file_link(self):
 
443
        self._check_kind_change(self.make_file, self.make_link)