/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/test_transform.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-09-16 01:57:02 UTC
  • mfrom: (2014.1.1 update-deprecated)
  • Revision ID: pqm@pqm.ubuntu.com-20060916015702-d6561b23f958bfdd
(jam) don't use deprecated pending_merges for 'bzr update'

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2006 Canonical Ltd
2
 
 
 
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
 
 
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import os
18
18
 
 
19
from bzrlib import tests
19
20
from bzrlib.bzrdir import BzrDir
20
21
from bzrlib.conflicts import (DuplicateEntry, DuplicateID, MissingParent,
21
 
                              UnversionedParent, ParentLoop)
 
22
                              UnversionedParent, ParentLoop, DeletingParent,)
22
23
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
23
 
                           ReusingTransform, CantMoveRoot, NotVersionedError,
24
 
                           ExistingLimbo, ImmortalLimbo, LockError)
 
24
                           ReusingTransform, CantMoveRoot, 
 
25
                           PathsNotVersionedError, ExistingLimbo,
 
26
                           ImmortalLimbo, LockError)
25
27
from bzrlib.osutils import file_kind, has_symlinks, pathjoin
26
28
from bzrlib.merge import Merge3Merger
27
29
from bzrlib.tests import TestCaseInTempDir, TestSkipped, TestCase
28
30
from bzrlib.transform import (TreeTransform, ROOT_PARENT, FinalPaths, 
29
31
                              resolve_conflicts, cook_conflicts, 
30
32
                              find_interesting, build_tree, get_backup_name)
 
33
import bzrlib.urlutils as urlutils
31
34
 
32
35
class TestTreeTransform(TestCaseInTempDir):
 
36
 
33
37
    def setUp(self):
34
38
        super(TestTreeTransform, self).setUp()
35
39
        self.wt = BzrDir.create_standalone_workingtree('.')
41
45
        return transform, transform.trans_id_tree_file_id(self.wt.get_root_id())
42
46
 
43
47
    def test_existing_limbo(self):
44
 
        limbo_name = self.wt._control_files.controlfilename('limbo')
 
48
        limbo_name = urlutils.local_path_from_url(
 
49
            self.wt._control_files.controlfilename('limbo'))
45
50
        transform, root = self.get_transform()
46
51
        os.mkdir(pathjoin(limbo_name, 'hehe'))
47
52
        self.assertRaises(ImmortalLimbo, transform.apply)
57
62
        transform, root = self.get_transform() 
58
63
        self.assertIs(transform.get_tree_parent(root), ROOT_PARENT)
59
64
        imaginary_id = transform.trans_id_tree_path('imaginary')
 
65
        imaginary_id2 = transform.trans_id_tree_path('imaginary/')
 
66
        self.assertEqual(imaginary_id, imaginary_id2)
60
67
        self.assertEqual(transform.get_tree_parent(imaginary_id), root)
61
68
        self.assertEqual(transform.final_kind(root), 'directory')
62
69
        self.assertEqual(transform.final_file_id(root), self.wt.get_root_id())
381
388
                                         'dorothy-id')
382
389
        old_dorothy = conflicts.trans_id_tree_file_id('dorothy-id')
383
390
        oz = conflicts.trans_id_tree_file_id('oz-id')
384
 
        # set up missing, unversioned parent
 
391
        # set up DeletedParent parent conflict
385
392
        conflicts.delete_versioned(oz)
386
393
        emerald = conflicts.trans_id_tree_file_id('emerald-id')
 
394
        # set up MissingParent conflict
 
395
        munchkincity = conflicts.trans_id_file_id('munchkincity-id')
 
396
        conflicts.adjust_path('munchkincity', root, munchkincity)
 
397
        conflicts.new_directory('auntem', munchkincity, 'auntem-id')
387
398
        # set up parent loop
388
399
        conflicts.adjust_path('emeraldcity', emerald, emerald)
389
400
        return conflicts, emerald, oz, old_dorothy, new_dorothy
410
421
                                   'dorothy.moved', 'dorothy', None,
411
422
                                   'dorothy-id')
412
423
        self.assertEqual(cooked_conflicts[1], duplicate_id)
413
 
        missing_parent = MissingParent('Not deleting', 'oz', 'oz-id')
 
424
        missing_parent = MissingParent('Created directory', 'munchkincity',
 
425
                                       'munchkincity-id')
 
426
        deleted_parent = DeletingParent('Not deleting', 'oz', 'oz-id')
414
427
        self.assertEqual(cooked_conflicts[2], missing_parent)
415
 
        unversioned_parent = UnversionedParent('Versioned directory', 'oz',
 
428
        unversioned_parent = UnversionedParent('Versioned directory',
 
429
                                               'munchkincity',
 
430
                                               'munchkincity-id')
 
431
        unversioned_parent2 = UnversionedParent('Versioned directory', 'oz',
416
432
                                               'oz-id')
417
433
        self.assertEqual(cooked_conflicts[3], unversioned_parent)
418
434
        parent_loop = ParentLoop('Cancelled move', 'oz/emeraldcity', 
419
435
                                 'oz/emeraldcity', 'emerald-id', 'emerald-id')
420
 
        self.assertEqual(cooked_conflicts[4], parent_loop)
421
 
        self.assertEqual(len(cooked_conflicts), 5)
 
436
        self.assertEqual(cooked_conflicts[4], deleted_parent)
 
437
        self.assertEqual(cooked_conflicts[5], unversioned_parent2)
 
438
        self.assertEqual(cooked_conflicts[6], parent_loop)
 
439
        self.assertEqual(len(cooked_conflicts), 7)
422
440
        tt.finalize()
423
441
 
424
442
    def test_string_conflicts(self):
434
452
        self.assertEqual(conflicts_s[1], 'Conflict adding id to dorothy.  '
435
453
                                         'Unversioned existing file '
436
454
                                         'dorothy.moved.')
437
 
        self.assertEqual(conflicts_s[2], 'Conflict adding files to oz.  '
438
 
                                         'Not deleting.')
439
 
        self.assertEqual(conflicts_s[3], 'Conflict adding versioned files to '
440
 
                                         'oz.  Versioned directory.')
441
 
        self.assertEqual(conflicts_s[4], 'Conflict moving oz/emeraldcity into'
 
455
        self.assertEqual(conflicts_s[2], 'Conflict adding files to'
 
456
                                         ' munchkincity.  Created directory.')
 
457
        self.assertEqual(conflicts_s[3], 'Conflict because munchkincity is not'
 
458
                                         ' versioned, but has versioned'
 
459
                                         ' children.  Versioned directory.')
 
460
        self.assertEqualDiff(conflicts_s[4], "Conflict: can't delete oz because it"
 
461
                                         " is not empty.  Not deleting.")
 
462
        self.assertEqual(conflicts_s[5], 'Conflict because oz is not'
 
463
                                         ' versioned, but has versioned'
 
464
                                         ' children.  Versioned directory.')
 
465
        self.assertEqual(conflicts_s[6], 'Conflict moving oz/emeraldcity into'
442
466
                                         ' oz/emeraldcity.  Cancelled move.')
443
467
 
444
468
    def test_moving_versioned_directories(self):
487
511
        create.apply()
488
512
        self.assertEqual(find_interesting(wt, wt, ['vfile']),
489
513
                         set(['myfile-id']))
490
 
        self.assertRaises(NotVersionedError, find_interesting, wt, wt,
 
514
        self.assertRaises(PathsNotVersionedError, find_interesting, wt, wt,
491
515
                          ['uvfile'])
492
516
 
 
517
    def test_set_executability_order(self):
 
518
        """Ensure that executability behaves the same, no matter what order.
 
519
        
 
520
        - create file and set executability simultaneously
 
521
        - create file and set executability afterward
 
522
        - unsetting the executability of a file whose executability has not been
 
523
        declared should throw an exception (this may happen when a
 
524
        merge attempts to create a file with a duplicate ID)
 
525
        """
 
526
        transform, root = self.get_transform()
 
527
        wt = transform._tree
 
528
        transform.new_file('set_on_creation', root, 'Set on creation', 'soc',
 
529
                           True)
 
530
        sac = transform.new_file('set_after_creation', root, 'Set after creation', 'sac')
 
531
        transform.set_executability(True, sac)
 
532
        uws = transform.new_file('unset_without_set', root, 'Unset badly', 'uws')
 
533
        self.assertRaises(KeyError, transform.set_executability, None, uws)
 
534
        transform.apply()
 
535
        self.assertTrue(wt.is_executable('soc'))
 
536
        self.assertTrue(wt.is_executable('sac'))
 
537
 
493
538
 
494
539
class TransformGroup(object):
495
540
    def __init__(self, dirname):
686
731
        self.assertIs(os.path.lexists(this.wt.abspath('b/h1.OTHER')), False)
687
732
        self.assertEqual(this.wt.id2path('i'), pathjoin('b/i1.OTHER'))
688
733
 
689
 
class TestBuildTree(TestCaseInTempDir):
 
734
class TestBuildTree(tests.TestCaseWithTransport):
 
735
 
690
736
    def test_build_tree(self):
691
737
        if not has_symlinks():
692
738
            raise TestSkipped('Test requires symlink support')
702
748
        self.assertIs(os.path.isdir('b/foo'), True)
703
749
        self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
704
750
        self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
 
751
 
 
752
    def test_file_conflict_handling(self):
 
753
        """Ensure that when building trees, conflict handling is done"""
 
754
        source = self.make_branch_and_tree('source')
 
755
        target = self.make_branch_and_tree('target')
 
756
        self.build_tree(['source/file', 'target/file'])
 
757
        source.add('file', 'new-file')
 
758
        source.commit('added file')
 
759
        build_tree(source.basis_tree(), target)
 
760
        self.assertEqual([DuplicateEntry('Moved existing file to',
 
761
                          'file.moved', 'file', None, 'new-file')],
 
762
                         target.conflicts())
 
763
        target2 = self.make_branch_and_tree('target2')
 
764
        target_file = file('target2/file', 'wb')
 
765
        try:
 
766
            source_file = file('source/file', 'rb')
 
767
            try:
 
768
                target_file.write(source_file.read())
 
769
            finally:
 
770
                source_file.close()
 
771
        finally:
 
772
            target_file.close()
 
773
        build_tree(source.basis_tree(), target2)
 
774
        self.assertEqual([], target2.conflicts())
 
775
 
 
776
    def test_symlink_conflict_handling(self):
 
777
        """Ensure that when building trees, conflict handling is done"""
 
778
        if not has_symlinks():
 
779
            raise TestSkipped('Test requires symlink support')
 
780
        source = self.make_branch_and_tree('source')
 
781
        os.symlink('foo', 'source/symlink')
 
782
        source.add('symlink', 'new-symlink')
 
783
        source.commit('added file')
 
784
        target = self.make_branch_and_tree('target')
 
785
        os.symlink('bar', 'target/symlink')
 
786
        build_tree(source.basis_tree(), target)
 
787
        self.assertEqual([DuplicateEntry('Moved existing file to',
 
788
            'symlink.moved', 'symlink', None, 'new-symlink')],
 
789
            target.conflicts())
 
790
        target = self.make_branch_and_tree('target2')
 
791
        os.symlink('foo', 'target2/symlink')
 
792
        build_tree(source.basis_tree(), target)
 
793
        self.assertEqual([], target.conflicts())
705
794
        
 
795
    def test_directory_conflict_handling(self):
 
796
        """Ensure that when building trees, conflict handling is done"""
 
797
        source = self.make_branch_and_tree('source')
 
798
        target = self.make_branch_and_tree('target')
 
799
        self.build_tree(['source/dir1/', 'source/dir1/file', 'target/dir1/'])
 
800
        source.add(['dir1', 'dir1/file'], ['new-dir1', 'new-file'])
 
801
        source.commit('added file')
 
802
        build_tree(source.basis_tree(), target)
 
803
        self.assertEqual([], target.conflicts())
 
804
        self.failUnlessExists('target/dir1/file')
 
805
 
 
806
        # Ensure contents are merged
 
807
        target = self.make_branch_and_tree('target2')
 
808
        self.build_tree(['target2/dir1/', 'target2/dir1/file2'])
 
809
        build_tree(source.basis_tree(), target)
 
810
        self.assertEqual([], target.conflicts())
 
811
        self.failUnlessExists('target2/dir1/file2')
 
812
        self.failUnlessExists('target2/dir1/file')
 
813
 
 
814
        # Ensure new contents are suppressed for existing branches
 
815
        target = self.make_branch_and_tree('target3')
 
816
        self.make_branch('target3/dir1')
 
817
        self.build_tree(['target3/dir1/file2'])
 
818
        build_tree(source.basis_tree(), target)
 
819
        self.failIfExists('target3/dir1/file')
 
820
        self.failUnlessExists('target3/dir1/file2')
 
821
        self.failUnlessExists('target3/dir1.diverted/file')
 
822
        self.assertEqual([DuplicateEntry('Diverted to',
 
823
            'dir1.diverted', 'dir1', 'new-dir1', None)],
 
824
            target.conflicts())
 
825
 
 
826
        target = self.make_branch_and_tree('target4')
 
827
        self.build_tree(['target4/dir1/'])
 
828
        self.make_branch('target4/dir1/file')
 
829
        build_tree(source.basis_tree(), target)
 
830
        self.failUnlessExists('target4/dir1/file')
 
831
        self.assertEqual('directory', file_kind('target4/dir1/file'))
 
832
        self.failUnlessExists('target4/dir1/file.diverted')
 
833
        self.assertEqual([DuplicateEntry('Diverted to',
 
834
            'dir1/file.diverted', 'dir1/file', 'new-file', None)],
 
835
            target.conflicts())
 
836
 
 
837
    def test_mixed_conflict_handling(self):
 
838
        """Ensure that when building trees, conflict handling is done"""
 
839
        source = self.make_branch_and_tree('source')
 
840
        target = self.make_branch_and_tree('target')
 
841
        self.build_tree(['source/name', 'target/name/'])
 
842
        source.add('name', 'new-name')
 
843
        source.commit('added file')
 
844
        build_tree(source.basis_tree(), target)
 
845
        self.assertEqual([DuplicateEntry('Moved existing file to',
 
846
            'name.moved', 'name', None, 'new-name')], target.conflicts())
 
847
 
 
848
    def test_raises_in_populated(self):
 
849
        source = self.make_branch_and_tree('source')
 
850
        self.build_tree(['source/name'])
 
851
        source.add('name')
 
852
        source.commit('added name')
 
853
        target = self.make_branch_and_tree('target')
 
854
        self.build_tree(['target/name'])
 
855
        target.add('name')
 
856
        self.assertRaises(AssertionError, build_tree, source.basis_tree(),
 
857
                          target)
 
858
 
 
859
 
706
860
class MockTransform(object):
707
861
 
708
862
    def has_named_child(self, by_parent, parent_id, name):