~jelmer/ubuntu/maverick/bzr/2.2.5

« back to all changes in this revision

Viewing changes to bzrlib/tests/workingtree_implementations/test_workingtree.py

ImportĀ upstreamĀ versionĀ 1.13~rc1

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
import os
22
22
import sys
23
23
 
24
 
import bzrlib
25
 
from bzrlib import branch, bzrdir, errors, osutils, urlutils, workingtree
 
24
from bzrlib import (
 
25
    branch,
 
26
    bzrdir,
 
27
    errors,
 
28
    osutils,
 
29
    tests,
 
30
    urlutils,
 
31
    workingtree,
 
32
    )
26
33
from bzrlib.errors import (NotBranchError, NotVersionedError,
27
34
                           UnsupportedOperation, PathsNotVersionedError)
28
35
from bzrlib.inventory import Inventory
29
36
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
30
 
from bzrlib.tests import TestSkipped
 
37
from bzrlib.tests import TestSkipped, TestNotApplicable
31
38
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
32
39
from bzrlib.trace import mutter
33
40
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
144
151
        self.assertEqual('w', tree.branch.peek_lock_mode())
145
152
        tree.unlock()
146
153
        self.assertEqual(None, tree.branch.peek_lock_mode())
147
 
 
 
154
 
148
155
    def test_revert(self):
149
156
        """Test selected-file revert"""
150
157
        tree = self.make_branch_and_tree('.')
170
177
        tree.revert(['hello.txt'])
171
178
        self.check_file_contents('hello.txt', 'initial hello')
172
179
        self.check_file_contents('hello.txt.~1~', 'new hello')
173
 
        
 
180
 
174
181
        # backup files are numbered
175
182
        file('hello.txt', 'w').write('new hello2')
176
183
        tree.revert(['hello.txt'])
227
234
 
228
235
        revid = b.revision_history()[0]
229
236
        self.log('first revision_id is {%s}' % revid)
230
 
        
 
237
 
231
238
        inv = b.repository.get_revision_inventory(revid)
232
239
        self.log('contents of inventory: %r' % inv.entries())
233
240
 
322
329
 
323
330
    def test_set_last_revision_different_to_branch(self):
324
331
        # working tree formats from the meta-dir format and newer support
325
 
        # setting the last revision on a tree independently of that on the 
326
 
        # branch. Its concievable that some future formats may want to 
 
332
        # setting the last revision on a tree independently of that on the
 
333
        # branch. Its concievable that some future formats may want to
327
334
        # couple them again (i.e. because its really a smart server and
328
335
        # the working tree will always match the branch). So we test
329
 
        # that formats where initialising a branch does not initialise a 
330
 
        # tree - and thus have separable entities - support skewing the 
 
336
        # that formats where initialising a branch does not initialise a
 
337
        # tree - and thus have separable entities - support skewing the
331
338
        # two things.
332
339
        branch = self.make_branch('tree')
333
340
        try:
371
378
        self.assertEqual('added', cloned.path2id('added'))
372
379
        self.assertEqual(None, cloned.path2id('deleted'))
373
380
        self.assertEqual(None, cloned.path2id('notadded'))
374
 
        
 
381
 
375
382
    def test_basis_tree_returns_last_revision(self):
376
383
        wt = self.make_branch_and_tree('.')
377
384
        self.build_tree(['foo'])
403
410
        # not change between two revisions, and another that does -
404
411
        # if the changed one is not changed, fail,
405
412
        # if the one that did not change has lost a local change, fail.
406
 
        # 
 
413
        #
407
414
        raise TestSkipped('revision limiting is not implemented yet.')
408
415
 
409
416
    def test_initialize_with_revision_id(self):
420
427
 
421
428
    def test_update_sets_last_revision(self):
422
429
        # working tree formats from the meta-dir format and newer support
423
 
        # setting the last revision on a tree independently of that on the 
424
 
        # branch. Its concievable that some future formats may want to 
 
430
        # setting the last revision on a tree independently of that on the
 
431
        # branch. Its concievable that some future formats may want to
425
432
        # couple them again (i.e. because its really a smart server and
426
433
        # the working tree will always match the branch). So we test
427
 
        # that formats where initialising a branch does not initialise a 
428
 
        # tree - and thus have separable entities - support skewing the 
 
434
        # that formats where initialising a branch does not initialise a
 
435
        # tree - and thus have separable entities - support skewing the
429
436
        # two things.
430
437
        main_branch = self.make_branch('tree')
431
438
        try:
451
458
 
452
459
    def test_update_sets_root_id(self):
453
460
        """Ensure tree root is set properly by update.
454
 
        
 
461
 
455
462
        Since empty trees don't have root_ids, but workingtrees do,
456
463
        an update of a checkout of revision 0 to a new revision,  should set
457
464
        the root id.
465
472
        # now commit to 'tree'
466
473
        wt.add('file')
467
474
        wt.commit('A', rev_id='A')
468
 
        # and update checkout 
 
475
        # and update checkout
469
476
        self.assertEqual(0, checkout.update())
470
477
        self.failUnlessExists('checkout/file')
471
478
        self.assertEqual(wt.get_root_id(), checkout.get_root_id())
473
480
 
474
481
    def test_update_returns_conflict_count(self):
475
482
        # working tree formats from the meta-dir format and newer support
476
 
        # setting the last revision on a tree independently of that on the 
477
 
        # branch. Its concievable that some future formats may want to 
 
483
        # setting the last revision on a tree independently of that on the
 
484
        # branch. Its concievable that some future formats may want to
478
485
        # couple them again (i.e. because its really a smart server and
479
486
        # the working tree will always match the branch). So we test
480
 
        # that formats where initialising a branch does not initialise a 
481
 
        # tree - and thus have separable entities - support skewing the 
 
487
        # that formats where initialising a branch does not initialise a
 
488
        # tree - and thus have separable entities - support skewing the
482
489
        # two things.
483
490
        main_branch = self.make_branch('tree')
484
491
        try:
546
553
 
547
554
    def test_update_turns_local_commit_into_merge(self):
548
555
        # doing an update with a few local commits and no master commits
549
 
        # makes pending-merges. 
 
556
        # makes pending-merges.
550
557
        # this is done so that 'bzr update; bzr revert' will always produce
551
558
        # an exact copy of the 'logical branch' - the referenced branch for
552
559
        # a checkout, and the master for a bound branch.
579
586
        # FIXME: This doesn't really test that it works; also this is not
580
587
        # implementation-independent. mbp 20070226
581
588
        tree = self.make_branch_and_tree('master')
582
 
        tree._control_files.put('merge-hashes', StringIO('asdfasdf'))
 
589
        tree._transport.put_bytes('merge-hashes', 'asdfasdf')
583
590
        self.assertRaises(errors.MergeModifiedFormatError, tree.merge_modified)
584
591
 
585
592
    def test_merge_modified(self):
605
612
            tree.set_conflicts(example_conflicts)
606
613
        except UnsupportedOperation:
607
614
            raise TestSkipped('set_conflicts not supported')
608
 
            
 
615
 
609
616
        tree2 = WorkingTree.open('master')
610
617
        self.assertEqual(tree2.conflicts(), example_conflicts)
611
 
        tree2._control_files.put('conflicts', StringIO(''))
612
 
        self.assertRaises(errors.ConflictFormatError, 
 
618
        tree2._transport.put_bytes('conflicts', '')
 
619
        self.assertRaises(errors.ConflictFormatError,
613
620
                          tree2.conflicts)
614
 
        tree2._control_files.put('conflicts', StringIO('a'))
615
 
        self.assertRaises(errors.ConflictFormatError, 
 
621
        tree2._transport.put_bytes('conflicts', 'a')
 
622
        self.assertRaises(errors.ConflictFormatError,
616
623
                          tree2.conflicts)
617
624
 
618
625
    def make_merge_conflicts(self):
654
661
        self.assertEqual(ConflictList([TextConflict('path_a')]),
655
662
                         tree.conflicts())
656
663
        tree.add_conflicts([TextConflict('path_a')])
657
 
        self.assertEqual(ConflictList([TextConflict('path_a')]), 
 
664
        self.assertEqual(ConflictList([TextConflict('path_a')]),
658
665
                         tree.conflicts())
659
666
        tree.add_conflicts([ContentsConflict('path_a')])
660
 
        self.assertEqual(ConflictList([ContentsConflict('path_a'), 
 
667
        self.assertEqual(ConflictList([ContentsConflict('path_a'),
661
668
                                       TextConflict('path_a')]),
662
669
                         tree.conflicts())
663
670
        tree.add_conflicts([TextConflict('path_b')])
664
 
        self.assertEqual(ConflictList([ContentsConflict('path_a'), 
 
671
        self.assertEqual(ConflictList([ContentsConflict('path_a'),
665
672
                                       TextConflict('path_a'),
666
673
                                       TextConflict('path_b')]),
667
674
                         tree.conflicts())
719
726
            tree.add([u'a\u030a'])
720
727
            tree.lock_read()
721
728
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
722
 
                    [(path, ie.kind) for path,ie in 
 
729
                    [(path, ie.kind) for path,ie in
723
730
                                tree.inventory.iter_entries()])
724
731
            tree.unlock()
725
732
        finally:
887
894
                         tree.all_file_ids())
888
895
 
889
896
    def test_sprout_hardlink(self):
 
897
        real_os_link = getattr(os, 'link', None)
 
898
        if real_os_link is None:
 
899
            raise TestNotApplicable("This platform doesn't provide os.link")
890
900
        source = self.make_branch_and_tree('source')
891
901
        self.build_tree(['source/file'])
892
902
        source.add('file')
893
903
        source.commit('added file')
894
904
        def fake_link(source, target):
895
905
            raise OSError(errno.EPERM, 'Operation not permitted')
896
 
        real_os_link = os.link
897
906
        os.link = fake_link
898
907
        try:
899
908
            # Hard-link support is optional, so supplying hardlink=True may
906
915
                pass
907
916
        finally:
908
917
            os.link = real_os_link
 
918
 
 
919
 
 
920
class TestIllegalPaths(TestCaseWithWorkingTree):
 
921
 
 
922
    def test_bad_fs_path(self):
 
923
        if osutils.normalizes_filenames():
 
924
            # You *can't* create an illegal filename on OSX.
 
925
            raise tests.TestNotApplicable('OSX normalizes filenames')
 
926
        self.requireFeature(tests.UTF8Filesystem)
 
927
        # We require a UTF8 filesystem, because otherwise we would need to get
 
928
        # tricky to figure out how to create an illegal filename.
 
929
        # \xb5 is an illegal path because it should be \xc2\xb5 for UTF-8
 
930
        tree = self.make_branch_and_tree('tree')
 
931
        self.build_tree(['tree/subdir/'])
 
932
        tree.add('subdir')
 
933
 
 
934
        f = open('tree/subdir/m\xb5', 'wb')
 
935
        try:
 
936
            f.write('trivial\n')
 
937
        finally:
 
938
            f.close()
 
939
 
 
940
        tree.lock_read()
 
941
        self.addCleanup(tree.unlock)
 
942
        basis = tree.basis_tree()
 
943
        basis.lock_read()
 
944
        self.addCleanup(basis.unlock)
 
945
 
 
946
        e = self.assertListRaises(errors.BadFilenameEncoding,
 
947
                                  tree.iter_changes, tree.basis_tree(),
 
948
                                                     want_unversioned=True)
 
949
        # We should display the relative path
 
950
        self.assertEqual('subdir/m\xb5', e.filename)
 
951
        self.assertEqual(osutils._fs_enc, e.fs_encoding)