~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_transform.py

  • Committer: John Arbash Meinel
  • Date: 2006-09-22 19:37:57 UTC
  • mto: This revision was merged to the branch mainline in revision 2032.
  • Revision ID: john@arbash-meinel.com-20060922193757-a8341ac119f0d33c
Create a 'read_stanza_unicode' to handle unicode processing

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
import stat
 
19
import sys
18
20
 
 
21
from bzrlib import (
 
22
    tests,
 
23
    urlutils,
 
24
    )
19
25
from bzrlib.bzrdir import BzrDir
20
26
from bzrlib.conflicts import (DuplicateEntry, DuplicateID, MissingParent,
21
 
                              UnversionedParent, ParentLoop)
 
27
                              UnversionedParent, ParentLoop, DeletingParent,)
22
28
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
23
29
                           ReusingTransform, CantMoveRoot, 
24
30
                           PathsNotVersionedError, ExistingLimbo,
29
35
from bzrlib.transform import (TreeTransform, ROOT_PARENT, FinalPaths, 
30
36
                              resolve_conflicts, cook_conflicts, 
31
37
                              find_interesting, build_tree, get_backup_name)
32
 
import bzrlib.urlutils as urlutils
 
38
 
33
39
 
34
40
class TestTreeTransform(TestCaseInTempDir):
35
41
 
387
393
                                         'dorothy-id')
388
394
        old_dorothy = conflicts.trans_id_tree_file_id('dorothy-id')
389
395
        oz = conflicts.trans_id_tree_file_id('oz-id')
390
 
        # set up missing, unversioned parent
 
396
        # set up DeletedParent parent conflict
391
397
        conflicts.delete_versioned(oz)
392
398
        emerald = conflicts.trans_id_tree_file_id('emerald-id')
 
399
        # set up MissingParent conflict
 
400
        munchkincity = conflicts.trans_id_file_id('munchkincity-id')
 
401
        conflicts.adjust_path('munchkincity', root, munchkincity)
 
402
        conflicts.new_directory('auntem', munchkincity, 'auntem-id')
393
403
        # set up parent loop
394
404
        conflicts.adjust_path('emeraldcity', emerald, emerald)
395
405
        return conflicts, emerald, oz, old_dorothy, new_dorothy
416
426
                                   'dorothy.moved', 'dorothy', None,
417
427
                                   'dorothy-id')
418
428
        self.assertEqual(cooked_conflicts[1], duplicate_id)
419
 
        missing_parent = MissingParent('Not deleting', 'oz', 'oz-id')
 
429
        missing_parent = MissingParent('Created directory', 'munchkincity',
 
430
                                       'munchkincity-id')
 
431
        deleted_parent = DeletingParent('Not deleting', 'oz', 'oz-id')
420
432
        self.assertEqual(cooked_conflicts[2], missing_parent)
421
 
        unversioned_parent = UnversionedParent('Versioned directory', 'oz',
 
433
        unversioned_parent = UnversionedParent('Versioned directory',
 
434
                                               'munchkincity',
 
435
                                               'munchkincity-id')
 
436
        unversioned_parent2 = UnversionedParent('Versioned directory', 'oz',
422
437
                                               'oz-id')
423
438
        self.assertEqual(cooked_conflicts[3], unversioned_parent)
424
439
        parent_loop = ParentLoop('Cancelled move', 'oz/emeraldcity', 
425
440
                                 'oz/emeraldcity', 'emerald-id', 'emerald-id')
426
 
        self.assertEqual(cooked_conflicts[4], parent_loop)
427
 
        self.assertEqual(len(cooked_conflicts), 5)
 
441
        self.assertEqual(cooked_conflicts[4], deleted_parent)
 
442
        self.assertEqual(cooked_conflicts[5], unversioned_parent2)
 
443
        self.assertEqual(cooked_conflicts[6], parent_loop)
 
444
        self.assertEqual(len(cooked_conflicts), 7)
428
445
        tt.finalize()
429
446
 
430
447
    def test_string_conflicts(self):
440
457
        self.assertEqual(conflicts_s[1], 'Conflict adding id to dorothy.  '
441
458
                                         'Unversioned existing file '
442
459
                                         'dorothy.moved.')
443
 
        self.assertEqual(conflicts_s[2], 'Conflict adding files to oz.  '
444
 
                                         'Not deleting.')
445
 
        self.assertEqual(conflicts_s[3], 'Conflict adding versioned files to '
446
 
                                         'oz.  Versioned directory.')
447
 
        self.assertEqual(conflicts_s[4], 'Conflict moving oz/emeraldcity into'
 
460
        self.assertEqual(conflicts_s[2], 'Conflict adding files to'
 
461
                                         ' munchkincity.  Created directory.')
 
462
        self.assertEqual(conflicts_s[3], 'Conflict because munchkincity is not'
 
463
                                         ' versioned, but has versioned'
 
464
                                         ' children.  Versioned directory.')
 
465
        self.assertEqualDiff(conflicts_s[4], "Conflict: can't delete oz because it"
 
466
                                         " is not empty.  Not deleting.")
 
467
        self.assertEqual(conflicts_s[5], 'Conflict because oz is not'
 
468
                                         ' versioned, but has versioned'
 
469
                                         ' children.  Versioned directory.')
 
470
        self.assertEqual(conflicts_s[6], 'Conflict moving oz/emeraldcity into'
448
471
                                         ' oz/emeraldcity.  Cancelled move.')
449
472
 
450
473
    def test_moving_versioned_directories(self):
517
540
        self.assertTrue(wt.is_executable('soc'))
518
541
        self.assertTrue(wt.is_executable('sac'))
519
542
 
 
543
    def test__set_mode_stats_correctly(self):
 
544
        """_set_mode stats to determine file mode."""
 
545
        if sys.platform == 'win32':
 
546
            raise TestSkipped('chmod has no effect on win32')
 
547
 
 
548
        stat_paths = []
 
549
        real_stat = os.stat
 
550
        def instrumented_stat(path):
 
551
            stat_paths.append(path)
 
552
            return real_stat(path)
 
553
 
 
554
        transform, root = self.get_transform()
 
555
 
 
556
        bar1_id = transform.new_file('bar', root, 'bar contents 1\n',
 
557
                                     file_id='bar-id-1', executable=False)
 
558
        transform.apply()
 
559
 
 
560
        transform, root = self.get_transform()
 
561
        bar1_id = transform.trans_id_tree_path('bar')
 
562
        bar2_id = transform.trans_id_tree_path('bar2')
 
563
        try:
 
564
            os.stat = instrumented_stat
 
565
            transform.create_file('bar2 contents\n', bar2_id, mode_id=bar1_id)
 
566
        finally:
 
567
            os.stat = real_stat
 
568
            transform.finalize()
 
569
 
 
570
        bar1_abspath = self.wt.abspath('bar')
 
571
        self.assertEqual([bar1_abspath], stat_paths)
 
572
 
520
573
 
521
574
class TransformGroup(object):
522
575
    def __init__(self, dirname):
713
766
        self.assertIs(os.path.lexists(this.wt.abspath('b/h1.OTHER')), False)
714
767
        self.assertEqual(this.wt.id2path('i'), pathjoin('b/i1.OTHER'))
715
768
 
716
 
class TestBuildTree(TestCaseInTempDir):
 
769
 
 
770
class TestBuildTree(tests.TestCaseWithTransport):
 
771
 
717
772
    def test_build_tree(self):
718
773
        if not has_symlinks():
719
774
            raise TestSkipped('Test requires symlink support')
729
784
        self.assertIs(os.path.isdir('b/foo'), True)
730
785
        self.assertEqual(file('b/foo/bar', 'rb').read(), "contents")
731
786
        self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
 
787
 
 
788
    def test_file_conflict_handling(self):
 
789
        """Ensure that when building trees, conflict handling is done"""
 
790
        source = self.make_branch_and_tree('source')
 
791
        target = self.make_branch_and_tree('target')
 
792
        self.build_tree(['source/file', 'target/file'])
 
793
        source.add('file', 'new-file')
 
794
        source.commit('added file')
 
795
        build_tree(source.basis_tree(), target)
 
796
        self.assertEqual([DuplicateEntry('Moved existing file to',
 
797
                          'file.moved', 'file', None, 'new-file')],
 
798
                         target.conflicts())
 
799
        target2 = self.make_branch_and_tree('target2')
 
800
        target_file = file('target2/file', 'wb')
 
801
        try:
 
802
            source_file = file('source/file', 'rb')
 
803
            try:
 
804
                target_file.write(source_file.read())
 
805
            finally:
 
806
                source_file.close()
 
807
        finally:
 
808
            target_file.close()
 
809
        build_tree(source.basis_tree(), target2)
 
810
        self.assertEqual([], target2.conflicts())
 
811
 
 
812
    def test_symlink_conflict_handling(self):
 
813
        """Ensure that when building trees, conflict handling is done"""
 
814
        if not has_symlinks():
 
815
            raise TestSkipped('Test requires symlink support')
 
816
        source = self.make_branch_and_tree('source')
 
817
        os.symlink('foo', 'source/symlink')
 
818
        source.add('symlink', 'new-symlink')
 
819
        source.commit('added file')
 
820
        target = self.make_branch_and_tree('target')
 
821
        os.symlink('bar', 'target/symlink')
 
822
        build_tree(source.basis_tree(), target)
 
823
        self.assertEqual([DuplicateEntry('Moved existing file to',
 
824
            'symlink.moved', 'symlink', None, 'new-symlink')],
 
825
            target.conflicts())
 
826
        target = self.make_branch_and_tree('target2')
 
827
        os.symlink('foo', 'target2/symlink')
 
828
        build_tree(source.basis_tree(), target)
 
829
        self.assertEqual([], target.conflicts())
732
830
        
 
831
    def test_directory_conflict_handling(self):
 
832
        """Ensure that when building trees, conflict handling is done"""
 
833
        source = self.make_branch_and_tree('source')
 
834
        target = self.make_branch_and_tree('target')
 
835
        self.build_tree(['source/dir1/', 'source/dir1/file', 'target/dir1/'])
 
836
        source.add(['dir1', 'dir1/file'], ['new-dir1', 'new-file'])
 
837
        source.commit('added file')
 
838
        build_tree(source.basis_tree(), target)
 
839
        self.assertEqual([], target.conflicts())
 
840
        self.failUnlessExists('target/dir1/file')
 
841
 
 
842
        # Ensure contents are merged
 
843
        target = self.make_branch_and_tree('target2')
 
844
        self.build_tree(['target2/dir1/', 'target2/dir1/file2'])
 
845
        build_tree(source.basis_tree(), target)
 
846
        self.assertEqual([], target.conflicts())
 
847
        self.failUnlessExists('target2/dir1/file2')
 
848
        self.failUnlessExists('target2/dir1/file')
 
849
 
 
850
        # Ensure new contents are suppressed for existing branches
 
851
        target = self.make_branch_and_tree('target3')
 
852
        self.make_branch('target3/dir1')
 
853
        self.build_tree(['target3/dir1/file2'])
 
854
        build_tree(source.basis_tree(), target)
 
855
        self.failIfExists('target3/dir1/file')
 
856
        self.failUnlessExists('target3/dir1/file2')
 
857
        self.failUnlessExists('target3/dir1.diverted/file')
 
858
        self.assertEqual([DuplicateEntry('Diverted to',
 
859
            'dir1.diverted', 'dir1', 'new-dir1', None)],
 
860
            target.conflicts())
 
861
 
 
862
        target = self.make_branch_and_tree('target4')
 
863
        self.build_tree(['target4/dir1/'])
 
864
        self.make_branch('target4/dir1/file')
 
865
        build_tree(source.basis_tree(), target)
 
866
        self.failUnlessExists('target4/dir1/file')
 
867
        self.assertEqual('directory', file_kind('target4/dir1/file'))
 
868
        self.failUnlessExists('target4/dir1/file.diverted')
 
869
        self.assertEqual([DuplicateEntry('Diverted to',
 
870
            'dir1/file.diverted', 'dir1/file', 'new-file', None)],
 
871
            target.conflicts())
 
872
 
 
873
    def test_mixed_conflict_handling(self):
 
874
        """Ensure that when building trees, conflict handling is done"""
 
875
        source = self.make_branch_and_tree('source')
 
876
        target = self.make_branch_and_tree('target')
 
877
        self.build_tree(['source/name', 'target/name/'])
 
878
        source.add('name', 'new-name')
 
879
        source.commit('added file')
 
880
        build_tree(source.basis_tree(), target)
 
881
        self.assertEqual([DuplicateEntry('Moved existing file to',
 
882
            'name.moved', 'name', None, 'new-name')], target.conflicts())
 
883
 
 
884
    def test_raises_in_populated(self):
 
885
        source = self.make_branch_and_tree('source')
 
886
        self.build_tree(['source/name'])
 
887
        source.add('name')
 
888
        source.commit('added name')
 
889
        target = self.make_branch_and_tree('target')
 
890
        self.build_tree(['target/name'])
 
891
        target.add('name')
 
892
        self.assertRaises(AssertionError, build_tree, source.basis_tree(),
 
893
                          target)
 
894
 
 
895
 
733
896
class MockTransform(object):
734
897
 
735
898
    def has_named_child(self, by_parent, parent_id, name):