/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 breezy/tests/per_workingtree/test_workingtree.py

  • Committer: Jelmer Vernooij
  • Date: 2019-03-04 00:16:27 UTC
  • mfrom: (7293 work)
  • mto: This revision was merged to the branch mainline in revision 7318.
  • Revision ID: jelmer@jelmer.uk-20190304001627-v6u7o6pf97tukhek
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
    TestSkipped,
49
49
    TestNotApplicable,
50
50
    )
51
 
from .  import TestCaseWithWorkingTree
 
51
from . import TestCaseWithWorkingTree
52
52
from ...bzr.workingtree import (
53
53
    InventoryWorkingTree,
54
54
    )
72
72
            # if there is a working tree now, this is not supported.
73
73
            test_branch.controldir.open_workingtree()
74
74
            raise TestNotApplicable("only on trees that can be separate"
75
 
                " from their branch.")
 
75
                                    " from their branch.")
76
76
        except (errors.NoWorkingTree, errors.NotLocalUrl):
77
77
            pass
78
78
 
89
89
        tree.lock_read()
90
90
        files = list(tree.list_files())
91
91
        tree.unlock()
92
 
        self.assertEqual(files.pop(0), ('dir', '?', 'directory', None, TreeDirectory()))
93
 
        self.assertEqual(files.pop(0), ('file', '?', 'file', None, TreeFile()))
 
92
        self.assertEqual(
 
93
            files.pop(0), ('dir', '?', 'directory', TreeDirectory()))
 
94
        self.assertEqual(files.pop(0), ('file', '?', 'file', TreeFile()))
94
95
        if has_symlinks():
95
 
            self.assertEqual(files.pop(0), ('symlink', '?', 'symlink', None, TreeLink()))
 
96
            self.assertEqual(
 
97
                files.pop(0), ('symlink', '?', 'symlink', TreeLink()))
96
98
 
97
99
    def test_list_files_sorted(self):
98
100
        tree = self.make_branch_and_tree('.')
99
101
        self.build_tree(['dir/', 'file', 'dir/file', 'dir/b',
100
102
                         'dir/subdir/', 'a', 'dir/subfile',
101
103
                         'zz_dir/', 'zz_dir/subfile'])
102
 
        tree.lock_read()
103
 
        files = [(path, kind) for (path, v, kind, file_id, entry)
104
 
                               in tree.list_files()]
105
 
        tree.unlock()
 
104
        with tree.lock_read():
 
105
            files = [(path, kind) for (path, v, kind, entry)
 
106
                     in tree.list_files()]
106
107
        self.assertEqual([
107
108
            ('a', 'file'),
108
109
            ('dir', 'directory'),
113
114
        with tree.lock_write():
114
115
            if tree.has_versioned_directories():
115
116
                tree.add(['dir', 'zz_dir'])
116
 
                files = [(path, kind) for (path, v, kind, file_id, entry)
117
 
                                       in tree.list_files()]
 
117
                files = [(path, kind) for (path, v, kind, entry)
 
118
                         in tree.list_files()]
118
119
                self.assertEqual([
119
120
                    ('a', 'file'),
120
121
                    ('dir', 'directory'),
128
129
                    ], files)
129
130
            else:
130
131
                tree.add(['dir/b'])
131
 
                files = [(path, kind) for (path, v, kind, file_id, entry)
132
 
                                       in tree.list_files()]
 
132
                files = [(path, kind) for (path, v, kind, entry)
 
133
                         in tree.list_files()]
133
134
                self.assertEqual([
134
135
                    ('a', 'file'),
135
136
                    ('dir', 'directory'),
153
154
        self.assertEqual(1, len(result))
154
155
        if tree.has_versioned_directories():
155
156
            self.assertEqual(
156
 
                    ('filename', 'V', 'directory', tree.path2id('filename')),
157
 
                    result[0][:4])
 
157
                ('filename', 'V', 'directory', tree.path2id('filename')),
 
158
                (result[0][0], result[0][1], result[0][2],
 
159
                    getattr(result[0][3], 'file_id', None)))
158
160
        else:
159
161
            self.assertEqual(
160
 
                    ('filename', '?', 'directory', None),
161
 
                    result[0][:4])
 
162
                ('filename', '?', 'directory', None),
 
163
                (result[0][0], result[0][1], result[0][2],
 
164
                    getattr(result[0][3], 'file_id', None)))
162
165
 
163
166
    def test_get_config_stack(self):
164
167
        # Smoke test that all working trees succeed getting a config
196
199
        # can even be a url: finds '.' and relpath of 'foo'
197
200
        wt, relpath = WorkingTree.open_containing('./foo')
198
201
        wt, relpath = WorkingTree.open_containing(
199
 
                    urlutils.local_path_to_url(getcwd() + '/foo'))
 
202
            urlutils.local_path_to_url(getcwd() + '/foo'))
200
203
        self.assertEqual('foo', relpath)
201
204
        self.assertEqual(wt.basedir + '/', local_base)
202
205
 
223
226
        tree = self.make_branch_and_tree('.')
224
227
 
225
228
        self.build_tree(['hello.txt'])
226
 
        with open('hello.txt', 'w') as f: f.write('initial hello')
 
229
        with open('hello.txt', 'w') as f:
 
230
            f.write('initial hello')
227
231
 
228
232
        self.assertRaises(PathsNotVersionedError,
229
233
                          tree.revert, ['hello.txt'])
231
235
        tree.commit('create initial hello.txt')
232
236
 
233
237
        self.check_file_contents('hello.txt', b'initial hello')
234
 
        with open('hello.txt', 'w') as f: f.write('new hello')
 
238
        with open('hello.txt', 'w') as f:
 
239
            f.write('new hello')
235
240
        self.check_file_contents('hello.txt', b'new hello')
236
241
 
237
242
        # revert file modified since last revision
245
250
        self.check_file_contents('hello.txt.~1~', b'new hello')
246
251
 
247
252
        # backup files are numbered
248
 
        with open('hello.txt', 'w') as f: f.write('new hello2')
 
253
        with open('hello.txt', 'w') as f:
 
254
            f.write('new hello2')
249
255
        tree.revert(['hello.txt'])
250
256
        self.check_file_contents('hello.txt', b'initial hello')
251
257
        self.check_file_contents('hello.txt.~1~', b'new hello')
254
260
    def test_revert_missing(self):
255
261
        # Revert a file that has been deleted since last commit
256
262
        tree = self.make_branch_and_tree('.')
257
 
        with open('hello.txt', 'w') as f: f.write('initial hello')
 
263
        with open('hello.txt', 'w') as f:
 
264
            f.write('initial hello')
258
265
        tree.add('hello.txt')
259
266
        tree.commit('added hello.txt')
260
267
        os.unlink('hello.txt')
267
274
        self.build_tree(['hello.txt'])
268
275
        tree.add('hello.txt')
269
276
        self.assertEqual(list(tree.unknowns()),
270
 
                          [])
 
277
                         [])
271
278
 
272
279
    def test_unknowns(self):
273
280
        tree = self.make_branch_and_tree('.')
276
283
        self.build_tree_contents([('.bzrignore', b'*.~*\n')])
277
284
        tree.add('.bzrignore')
278
285
        self.assertEqual(list(tree.unknowns()),
279
 
                          ['hello.txt'])
 
286
                         ['hello.txt'])
 
287
 
 
288
    def test_unknowns_empty_dir(self):
 
289
        tree = self.make_branch_and_tree('.')
 
290
        self.build_tree(['subdir/', 'subdir/somefile'])
 
291
        if tree.has_versioned_directories():
 
292
            self.assertEqual(list(tree.unknowns()), ['subdir'])
 
293
        else:
 
294
            self.assertEqual(list(tree.unknowns()), ['subdir/somefile'])
280
295
 
281
296
    def test_initialize(self):
282
297
        # initialize should create a working tree and branch in an existing dir
309
324
 
310
325
        wt.lock_read()
311
326
        self.check_tree_shape(wt,
312
 
                                   ['newdir/', 'newdir/sub/', 'newdir/sub/file'])
 
327
                              ['newdir/', 'newdir/sub/', 'newdir/sub/file'])
313
328
        wt.unlock()
314
329
        wt.rename_one('newdir/sub', 'newdir/newsub')
315
330
        wt.lock_read()
316
331
        self.check_tree_shape(wt, ['newdir/', 'newdir/newsub/',
317
 
                                    'newdir/newsub/file'])
 
332
                                   'newdir/newsub/file'])
318
333
        wt.unlock()
319
334
 
320
335
    def test_add_in_unversioned(self):
340
355
        self.assertRaises(errors.NoSuchFile, wt.add, 'fpp')
341
356
 
342
357
    def test_remove_verbose(self):
343
 
        #FIXME the remove api should not print or otherwise depend on the
 
358
        # FIXME the remove api should not print or otherwise depend on the
344
359
        # text UI - RBC 20060124
345
360
        wt = self.make_branch_and_tree('.')
346
361
        self.build_tree(['hello'])
363
378
 
364
379
    def test_clone_empty(self):
365
380
        wt = self.make_branch_and_tree('source')
366
 
        cloned_dir = wt.controldir.clone('target', revision_id=_mod_revision.NULL_REVISION)
 
381
        cloned_dir = wt.controldir.clone(
 
382
            'target', revision_id=_mod_revision.NULL_REVISION)
367
383
        cloned = cloned_dir.open_workingtree()
368
384
        self.assertEqual(cloned.get_parent_ids(), wt.get_parent_ids())
369
385
 
489
505
        source.branch.repository.clone(made_control)
490
506
        source.branch.clone(made_control)
491
507
        made_tree = self.workingtree_format.initialize(made_control,
492
 
            revision_id=a)
 
508
                                                       revision_id=a)
493
509
        self.assertEqual([a], made_tree.get_parent_ids())
494
510
 
495
511
    def test_post_build_tree_hook(self):
496
512
        calls = []
 
513
 
497
514
        def track_post_build_tree(tree):
498
515
            calls.append(tree.last_revision())
499
516
        source = self.make_branch_and_tree('source')
504
521
        source.branch.repository.clone(made_control)
505
522
        source.branch.clone(made_control)
506
523
        MutableTree.hooks.install_named_hook("post_build_tree",
507
 
            track_post_build_tree, "Test")
 
524
                                             track_post_build_tree, "Test")
508
525
        made_tree = self.workingtree_format.initialize(made_control,
509
 
            revision_id=a)
 
526
                                                       revision_id=a)
510
527
        self.assertEqual([a], calls)
511
528
 
512
529
    def test_update_sets_last_revision(self):
560
577
        wt = self.make_branch_and_tree('tree')
561
578
        if not wt._format.supports_setting_file_ids:
562
579
            self.assertRaises(SettingFileIdUnsupported, wt.set_root_id,
563
 
                    'first_root_id')
 
580
                              'first_root_id')
564
581
            return
565
582
        wt.set_root_id(b'first_root_id')
566
583
        self.assertEqual(b'first_root_id', wt.get_root_id())
604
621
    def test_merge_revert(self):
605
622
        from breezy.merge import merge_inner
606
623
        this = self.make_branch_and_tree('b1')
607
 
        self.build_tree_contents([('b1/a', b'a test\n'), ('b1/b', b'b test\n')])
 
624
        self.build_tree_contents(
 
625
            [('b1/a', b'a test\n'), ('b1/b', b'b test\n')])
608
626
        this.add(['a', 'b'])
609
627
        this.commit(message='')
610
628
        base = this.controldir.clone('b2').open_workingtree()
611
629
        self.build_tree_contents([('b2/a', b'b test\n')])
612
630
        other = this.controldir.clone('b3').open_workingtree()
613
 
        self.build_tree_contents([('b3/a', b'c test\n'), ('b3/c', b'c test\n')])
 
631
        self.build_tree_contents(
 
632
            [('b3/a', b'c test\n'), ('b3/c', b'c test\n')])
614
633
        other.add('c')
615
634
 
616
 
        self.build_tree_contents([('b1/b', b'q test\n'), ('b1/d', b'd test\n')])
 
635
        self.build_tree_contents(
 
636
            [('b1/b', b'q test\n'), ('b1/d', b'd test\n')])
617
637
        # Note: If we don't lock this before calling merge_inner, then we get a
618
638
        #       lock-contention failure. This probably indicates something
619
639
        #       weird going on inside merge_inner. Probably something about
701
721
        tree = self.make_branch_and_tree('master')
702
722
        if not isinstance(tree, InventoryWorkingTree):
703
723
            raise TestNotApplicable("merge-hashes is specific to bzr "
704
 
                "working trees")
 
724
                                    "working trees")
705
725
        tree._transport.put_bytes('merge-hashes', b'asdfasdf')
706
726
        self.assertRaises(errors.MergeModifiedFormatError, tree.merge_modified)
707
727
 
749
769
    def make_merge_conflicts(self):
750
770
        from breezy.merge import merge_inner
751
771
        tree = self.make_branch_and_tree('mine')
752
 
        with open('mine/bloo', 'wb') as f: f.write(b'one')
753
 
        with open('mine/blo', 'wb') as f: f.write(b'on')
 
772
        with open('mine/bloo', 'wb') as f:
 
773
            f.write(b'one')
 
774
        with open('mine/blo', 'wb') as f:
 
775
            f.write(b'on')
754
776
        tree.add(['bloo', 'blo'])
755
777
        tree.commit("blah", allow_pointless=False)
756
778
        base = tree.branch.repository.revision_tree(tree.last_revision())
757
779
        controldir.ControlDir.open("mine").sprout("other")
758
 
        with open('other/bloo', 'wb') as f: f.write(b'two')
 
780
        with open('other/bloo', 'wb') as f:
 
781
            f.write(b'two')
759
782
        othertree = WorkingTree.open('other')
760
783
        othertree.commit('blah', allow_pointless=False)
761
 
        with open('mine/bloo', 'wb') as f: f.write(b'three')
 
784
        with open('mine/bloo', 'wb') as f:
 
785
            f.write(b'three')
762
786
        tree.commit("blah", allow_pointless=False)
763
787
        merge_inner(tree.branch, othertree, base, this_tree=tree)
764
788
        return tree
819
843
    def test_format_leftmost_parent_id_as_ghost(self):
820
844
        tree = self.make_branch_and_tree('tree')
821
845
        self.assertIn(
822
 
                tree._format.supports_leftmost_parent_id_as_ghost, (True, False))
 
846
            tree._format.supports_leftmost_parent_id_as_ghost, (True, False))
823
847
 
824
848
    def test_branch_attribute_is_not_settable(self):
825
849
        # the branch attribute is an aspect of the working tree, not a
826
850
        # configurable attribute
827
851
        tree = self.make_branch_and_tree('tree')
 
852
 
828
853
        def set_branch():
829
854
            tree.branch = tree.branch
830
855
        self.assertRaises(AttributeError, set_branch)
840
865
        tree.lock_read()
841
866
        files = sorted(list(tree.list_files()))
842
867
        tree.unlock()
843
 
        self.assertEqual((u'.bzrignore', '?', 'file', None), files[0][:-1])
844
 
        self.assertEqual((u'foo.pyc', 'V', 'file', anid), files[1][:-1])
 
868
        self.assertEqual(
 
869
            (u'.bzrignore', '?', 'file', None),
 
870
            (files[0][0], files[0][1], files[0][2],
 
871
                getattr(files[0][3], 'file_id', None)))
 
872
        self.assertEqual(
 
873
            (u'foo.pyc', 'V', 'file', anid),
 
874
            (files[1][0], files[1][1], files[1][2], files[1][3].file_id))
845
875
        self.assertEqual(2, len(files))
846
876
 
847
877
    def test_non_normalized_add_accessible(self):
854
884
        osutils.normalized_filename = osutils._accessible_normalized_filename
855
885
        try:
856
886
            tree.add([u'a\u030a'])
857
 
            tree.lock_read()
858
 
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
859
 
                    [(path, ie.kind) for path, ie in
860
 
                                tree.iter_entries_by_dir()])
861
 
            tree.unlock()
 
887
            with tree.lock_read():
 
888
                self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
 
889
                                 [(path, ie.kind) for path, ie in
 
890
                                  tree.iter_entries_by_dir()])
862
891
        finally:
863
892
            osutils.normalized_filename = orig
864
893
 
872
901
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
873
902
        try:
874
903
            self.assertRaises(errors.InvalidNormalization,
875
 
                tree.add, [u'a\u030a'])
 
904
                              tree.add, [u'a\u030a'])
876
905
        finally:
877
906
            osutils.normalized_filename = orig
878
907
 
879
908
    def test__write_inventory(self):
880
 
        # The private interface _write_inventory is currently used by transform.
 
909
        # The private interface _write_inventory is currently used by
 
910
        # transform.
881
911
        tree = self.make_branch_and_tree('.')
882
912
        if not isinstance(tree, InventoryWorkingTree):
883
913
            raise TestNotApplicable("_write_inventory does not exist on "
884
 
                "non-inventory working trees")
 
914
                                    "non-inventory working trees")
885
915
        # if we write write an inventory then do a walkdirs we should get back
886
916
        # missing entries, and actual, and unknowns as appropriate.
887
917
        self.build_tree(['present', 'unknown'])
893
923
        tree.lock_write()
894
924
        tree._write_inventory(inventory)
895
925
        tree.unlock()
896
 
        tree.lock_read()
897
 
        try:
 
926
        with tree.lock_read():
898
927
            present_stat = os.lstat('present')
899
928
            unknown_stat = os.lstat('unknown')
900
929
            expected_results = [
901
930
                (('', tree.get_root_id()),
902
931
                 [('missing', 'missing', 'unknown', None, b'missing-id', 'file'),
903
 
                  ('present', 'present', 'file', present_stat, b'present-id', 'file'),
 
932
                  ('present', 'present', 'file',
 
933
                   present_stat, b'present-id', 'file'),
904
934
                  ('unknown', 'unknown', 'file', unknown_stat, None, None),
905
 
                 ]
906
 
                )]
 
935
                  ]
 
936
                 )]
907
937
            self.assertEqual(expected_results, list(tree.walkdirs()))
908
 
        finally:
909
 
            tree.unlock()
910
938
 
911
939
    def test_path2id(self):
912
940
        # smoke test for path2id
915
943
        if tree.supports_setting_file_ids():
916
944
            tree.add(['foo'], [b'foo-id'])
917
945
            self.assertEqual(b'foo-id', tree.path2id('foo'))
918
 
            # the next assertion is for backwards compatability with
 
946
            # the next assertion is for backwards compatibility with
919
947
            # WorkingTree3, though its probably a bad idea, it makes things
920
948
            # work. Perhaps it should raise a deprecation warning?
921
949
            self.assertEqual(b'foo-id', tree.path2id('foo/'))
930
958
        # smoke test for filter_unversioned_files
931
959
        tree = self.make_branch_and_tree('.')
932
960
        paths = ['here-and-versioned', 'here-and-not-versioned',
933
 
            'not-here-and-versioned', 'not-here-and-not-versioned']
 
961
                 'not-here-and-versioned', 'not-here-and-not-versioned']
934
962
        tree.add(['here-and-versioned', 'not-here-and-versioned'],
935
 
            kinds=['file', 'file'])
 
963
                 kinds=['file', 'file'])
936
964
        self.build_tree(['here-and-versioned', 'here-and-not-versioned'])
937
965
        tree.lock_read()
938
966
        self.addCleanup(tree.unlock)
961
989
        # move them around so the names no longer correspond to the types
962
990
        os.rename(names[0], 'tmp')
963
991
        for i in range(1, len(names)):
964
 
            os.rename(names[i], names[i-1])
 
992
            os.rename(names[i], names[i - 1])
965
993
        os.rename('tmp', names[-1])
966
994
        # now look and expect to see the correct types again
967
995
        for i in range(len(names)):
968
 
            actual_kind = tree.kind(names[i-1])
 
996
            actual_kind = tree.kind(names[i - 1])
969
997
            expected_kind = names[i]
970
998
            self.assertEqual(expected_kind, actual_kind)
971
999
 
1058
1086
        self.build_tree(['tree/a', 'tree/b'])
1059
1087
        tree.add(['a', 'b'])
1060
1088
        os.unlink('tree/a')
1061
 
        self.assertEqual(
 
1089
        try:
 
1090
            self.assertEqual(
1062
1091
                {'a', 'b', ''},
1063
1092
                set(tree.all_versioned_paths()))
 
1093
        except errors.UnsupportedOperation:
 
1094
            raise TestNotApplicable('tree does not support all_file_ids')
1064
1095
 
1065
1096
    def test_sprout_hardlink(self):
1066
1097
        real_os_link = getattr(os, 'link', None)
1070
1101
        self.build_tree(['source/file'])
1071
1102
        source.add('file')
1072
1103
        source.commit('added file')
 
1104
 
1073
1105
        def fake_link(source, target):
1074
1106
            raise OSError(errno.EPERM, 'Operation not permitted')
1075
1107
        os.link = fake_link
1079
1111
            # HardLinkNotSupported
1080
1112
            try:
1081
1113
                source.controldir.sprout('target', accelerator_tree=source,
1082
 
                                     hardlink=True)
 
1114
                                         hardlink=True)
1083
1115
            except errors.HardLinkNotSupported:
1084
1116
                pass
1085
1117
        finally:
1135
1167
        final_branch = builder.get_branch()
1136
1168
        # The master branch
1137
1169
        master = final_branch.controldir.sprout(master_path,
1138
 
                                            master_revid).open_branch()
 
1170
                                                master_revid).open_branch()
1139
1171
        # The checkout
1140
1172
        wt = self.make_branch_and_tree(wt_path)
1141
1173
        wt.pull(final_branch, stop_revision=wt_revid)
1142
 
        wt.branch.pull(final_branch, stop_revision=branch_revid, overwrite=True)
 
1174
        wt.branch.pull(
 
1175
            final_branch, stop_revision=branch_revid, overwrite=True)
1143
1176
        try:
1144
1177
            wt.branch.bind(master)
1145
1178
        except errors.UpgradeRequired:
1266
1299
        conf.set('bzr.workingtree.worth_saving_limit', 'a')
1267
1300
        # If the config entry is invalid, default to 10
1268
1301
        warnings = []
 
1302
 
1269
1303
        def warning(*args):
1270
1304
            warnings.append(args[0] % args[1:])
1271
1305
        self.overrideAttr(trace, 'warning', warning)
1272
1306
        self.assertEqual(10, wt._worth_saving_limit())
1273
1307
        self.assertLength(1, warnings)
1274
1308
        self.assertEqual('Value "a" is not valid for'
1275
 
                          ' "bzr.workingtree.worth_saving_limit"',
1276
 
                          warnings[0])
 
1309
                         ' "bzr.workingtree.worth_saving_limit"',
 
1310
                         warnings[0])
1277
1311
 
1278
1312
 
1279
1313
class TestFormatAttributes(TestCaseWithWorkingTree):