/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2007-2012, 2016 Canonical Ltd
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
2
# Authors:  Robert Collins <robert.collins@canonical.com>
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
17
18
"""Tests for WorkingTreeFormat4"""
19
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
20
import os
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
21
import time
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
22
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
23
from .. import (
6670.4.1 by Jelmer Vernooij
Update imports.
24
    errors,
25
    osutils,
26
    )
27
from ..bzr import (
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
28
    bzrdir,
29
    dirstate,
1551.15.6 by Aaron Bentley
Use ROOT_ID when the repository supports old clients (Bug #107168)
30
    inventory,
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
31
    workingtree_4,
32
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
33
from ..lockdir import LockDir
34
from . import TestCaseWithTransport, TestSkipped, features
35
from ..tree import InterTree
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
36
37
38
class TestWorkingTreeFormat4(TestCaseWithTransport):
39
    """Tests specific to WorkingTreeFormat4."""
40
41
    def test_disk_layout(self):
42
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
43
        control.create_repository()
44
        control.create_branch()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
45
        workingtree_4.WorkingTreeFormat4().initialize(control)
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
46
        # we want:
47
        # format 'Bazaar Working Tree format 4'
48
        # stat-cache = ??
49
        t = control.get_workingtree_transport(None)
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
50
        self.assertEqualDiff(b'Bazaar Working Tree Format 4 (bzr 0.15)\n',
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
51
                             t.get('format').read())
52
        self.assertFalse(t.has('inventory.basis'))
53
        # no last-revision file means 'None' or 'NULLREVISION'
54
        self.assertFalse(t.has('last-revision'))
55
        state = dirstate.DirState.on_file(t.local_abspath('dirstate'))
56
        state.lock_read()
57
        try:
58
            self.assertEqual([], state.get_parent_ids())
59
        finally:
60
            state.unlock()
61
5900.1.1 by Jelmer Vernooij
Make sure only the last unlock resets the cached ignore glob.
62
    def test_resets_ignores_on_last_unlock(self):
63
        # Only the last unlock call will actually reset the
64
        # ignores. (bug #785671)
65
        tree = self.make_workingtree()
66
        tree.lock_read()
67
        try:
68
            tree.lock_read()
69
            try:
70
                tree.is_ignored("foo")
71
            finally:
72
                tree.unlock()
73
            self.assertIsNot(None, tree._ignoreglobster)
74
        finally:
75
            tree.unlock()
76
        self.assertIs(None, tree._ignoreglobster)
77
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
78
    def test_uses_lockdir(self):
79
        """WorkingTreeFormat4 uses its own LockDir:
2255.10.1 by John Arbash Meinel
Update WorkingTree4 so that it doesn't use a HashCache,
80
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
81
            - lock is a directory
82
            - when the WorkingTree is locked, LockDir can see that
83
        """
84
        # this test could be factored into a subclass of tests common to both
4285.2.1 by Vincent Ladeuil
Cleanup test imports and use features to better track skipped tests.
85
        # format 3 and 4, but for now its not much of an issue as there is only
86
        # one in common.
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
87
        t = self.get_transport()
88
        tree = self.make_workingtree()
89
        self.assertIsDirectory('.bzr', t)
90
        self.assertIsDirectory('.bzr/checkout', t)
91
        self.assertIsDirectory('.bzr/checkout/lock', t)
92
        our_lock = LockDir(t, '.bzr/checkout/lock')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
93
        self.assertEqual(our_lock.peek(), None)
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
94
        tree.lock_write()
95
        self.assertTrue(our_lock.peek())
96
        tree.unlock()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
97
        self.assertEqual(our_lock.peek(), None)
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
98
99
    def make_workingtree(self, relpath=''):
100
        url = self.get_url(relpath)
101
        if relpath:
102
            self.build_tree([relpath + '/'])
103
        dir = bzrdir.BzrDirMetaFormat1().initialize(url)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
104
        dir.create_repository()
105
        dir.create_branch()
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
106
        try:
107
            return workingtree_4.WorkingTreeFormat4().initialize(dir)
108
        except errors.NotLocalUrl:
109
            raise TestSkipped('Not a local URL')
110
111
    def test_dirstate_stores_all_parent_inventories(self):
112
        tree = self.make_workingtree()
113
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
114
        # We're going to build in tree a working tree
115
        # with three parent trees, with some files in common.
116
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
117
        # We really don't want to do commit or merge in the new dirstate-based
118
        # tree, because that might not work yet.  So instead we build
119
        # revisions elsewhere and pull them across, doing by hand part of the
120
        # work that merge would do.
121
122
        subtree = self.make_branch_and_tree('subdir')
123
        # writelock the tree so its repository doesn't get readlocked by
124
        # the revision tree locks. This works around the bug where we dont
125
        # permit lock upgrading.
126
        subtree.lock_write()
127
        self.addCleanup(subtree.unlock)
7143.15.2 by Jelmer Vernooij
Run autopep8.
128
        self.build_tree(['subdir/file-a', ])
7007.1.9 by Jelmer Vernooij
Fix more dirstate tests.
129
        subtree.add(['file-a'], [b'id-a'])
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
130
        rev1 = subtree.commit('commit in subdir')
131
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
132
        subtree2 = subtree.controldir.sprout('subdir2').open_workingtree()
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
133
        self.build_tree(['subdir2/file-b'])
7007.1.9 by Jelmer Vernooij
Fix more dirstate tests.
134
        subtree2.add(['file-b'], [b'id-b'])
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
135
        rev2 = subtree2.commit('commit in subdir2')
136
137
        subtree.flush()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
138
        subtree3 = subtree.controldir.sprout('subdir3').open_workingtree()
3462.1.7 by John Arbash Meinel
fix a test that assumed WT4.set_parent_trees() wouldn't filter the list.
139
        rev3 = subtree3.commit('merge from subdir2')
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
140
141
        repo = tree.branch.repository
3462.1.7 by John Arbash Meinel
fix a test that assumed WT4.set_parent_trees() wouldn't filter the list.
142
        repo.fetch(subtree.branch.repository, rev1)
143
        repo.fetch(subtree2.branch.repository, rev2)
144
        repo.fetch(subtree3.branch.repository, rev3)
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
145
        # will also pull the others...
146
147
        # create repository based revision trees
3462.1.7 by John Arbash Meinel
fix a test that assumed WT4.set_parent_trees() wouldn't filter the list.
148
        rev1_revtree = repo.revision_tree(rev1)
149
        rev2_revtree = repo.revision_tree(rev2)
150
        rev3_revtree = repo.revision_tree(rev3)
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
151
        # tree doesn't contain a text merge yet but we'll just
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
152
        # set the parents as if a merge had taken place.
153
        # this should cause the tree data to be folded into the
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
154
        # dirstate.
155
        tree.set_parent_trees([
156
            (rev1, rev1_revtree),
157
            (rev2, rev2_revtree),
158
            (rev3, rev3_revtree), ])
159
160
        # create tree-sourced revision trees
161
        rev1_tree = tree.revision_tree(rev1)
162
        rev1_tree.lock_read()
163
        self.addCleanup(rev1_tree.unlock)
164
        rev2_tree = tree.revision_tree(rev2)
165
        rev2_tree.lock_read()
166
        self.addCleanup(rev2_tree.unlock)
167
        rev3_tree = tree.revision_tree(rev3)
168
        rev3_tree.lock_read()
169
        self.addCleanup(rev3_tree.unlock)
170
171
        # now we should be able to get them back out
172
        self.assertTreesEqual(rev1_revtree, rev1_tree)
173
        self.assertTreesEqual(rev2_revtree, rev2_tree)
174
        self.assertTreesEqual(rev3_revtree, rev3_tree)
175
176
    def test_dirstate_doesnt_read_parents_from_repo_when_setting(self):
177
        """Setting parent trees on a dirstate working tree takes
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
178
        the trees it's given and doesn't need to read them from the
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
179
        repository.
180
        """
181
        tree = self.make_workingtree()
182
183
        subtree = self.make_branch_and_tree('subdir')
184
        rev1 = subtree.commit('commit in subdir')
185
        rev1_tree = subtree.basis_tree()
186
        rev1_tree.lock_read()
187
        self.addCleanup(rev1_tree.unlock)
188
189
        tree.branch.pull(subtree.branch)
190
191
        # break the repository's legs to make sure it only uses the trees
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
192
        # it's given; any calls to forbidden methods will raise an
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
193
        # AssertionError
194
        repo = tree.branch.repository
5340.15.1 by John Arbash Meinel
supersede exc-info branch
195
        self.overrideAttr(repo, "get_revision", self.fail)
196
        self.overrideAttr(repo, "get_inventory", self.fail)
197
        self.overrideAttr(repo, "_get_inventory_xml", self.fail)
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
198
        # try to set the parent trees.
199
        tree.set_parent_trees([(rev1, rev1_tree)])
200
201
    def test_dirstate_doesnt_read_from_repo_when_returning_cache_tree(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
202
        """Getting parent trees from a dirstate tree does not read from the
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
203
        repos inventory store. This is an important part of the dirstate
204
        performance optimisation work.
205
        """
206
        tree = self.make_workingtree()
207
208
        subtree = self.make_branch_and_tree('subdir')
209
        # writelock the tree so its repository doesn't get readlocked by
210
        # the revision tree locks. This works around the bug where we dont
211
        # permit lock upgrading.
212
        subtree.lock_write()
213
        self.addCleanup(subtree.unlock)
214
        rev1 = subtree.commit('commit in subdir')
215
        rev1_tree = subtree.basis_tree()
216
        rev1_tree.lock_read()
6405.2.12 by Jelmer Vernooij
Fix tests.
217
        rev1_tree.root_inventory
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
218
        self.addCleanup(rev1_tree.unlock)
219
        rev2 = subtree.commit('second commit in subdir', allow_pointless=True)
220
        rev2_tree = subtree.basis_tree()
221
        rev2_tree.lock_read()
6405.2.12 by Jelmer Vernooij
Fix tests.
222
        rev2_tree.root_inventory
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
223
        self.addCleanup(rev2_tree.unlock)
224
225
        tree.branch.pull(subtree.branch)
226
227
        # break the repository's legs to make sure it only uses the trees
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
228
        # it's given; any calls to forbidden methods will raise an
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
229
        # AssertionError
230
        repo = tree.branch.repository
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
231
        # dont uncomment this: the revision object must be accessed to
232
        # answer 'get_parent_ids' for the revision tree- dirstate does not
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
233
        # cache the parents of a parent tree at this point.
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
234
        # repo.get_revision = self.fail
5340.15.1 by John Arbash Meinel
supersede exc-info branch
235
        self.overrideAttr(repo, "get_inventory", self.fail)
236
        self.overrideAttr(repo, "_get_inventory_xml", self.fail)
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
237
        # set the parent trees.
238
        tree.set_parent_trees([(rev1, rev1_tree), (rev2, rev2_tree)])
239
        # read the first tree
240
        result_rev1_tree = tree.revision_tree(rev1)
241
        # read the second
242
        result_rev2_tree = tree.revision_tree(rev2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
243
        # compare - there should be no differences between the handed and
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
244
        # returned trees
245
        self.assertTreesEqual(rev1_tree, result_rev1_tree)
246
        self.assertTreesEqual(rev2_tree, result_rev2_tree)
247
248
    def test_dirstate_doesnt_cache_non_parent_trees(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
249
        """Getting parent trees from a dirstate tree does not read from the
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
250
        repos inventory store. This is an important part of the dirstate
251
        performance optimisation work.
252
        """
253
        tree = self.make_workingtree()
254
255
        # make a tree that we can try for, which is able to be returned but
256
        # must not be
257
        subtree = self.make_branch_and_tree('subdir')
258
        rev1 = subtree.commit('commit in subdir')
259
        tree.branch.pull(subtree.branch)
260
        # check it fails
261
        self.assertRaises(errors.NoSuchRevision, tree.revision_tree, rev1)
262
263
    def test_no_dirstate_outside_lock(self):
264
        # temporary test until the code is mature enough to test from outside.
265
        """Getting a dirstate object fails if there is no lock."""
266
        def lock_and_call_current_dirstate(tree, lock_method):
267
            getattr(tree, lock_method)()
268
            tree.current_dirstate()
269
            tree.unlock()
270
        tree = self.make_workingtree()
271
        self.assertRaises(errors.ObjectNotLocked, tree.current_dirstate)
272
        lock_and_call_current_dirstate(tree, 'lock_read')
273
        self.assertRaises(errors.ObjectNotLocked, tree.current_dirstate)
274
        lock_and_call_current_dirstate(tree, 'lock_write')
275
        self.assertRaises(errors.ObjectNotLocked, tree.current_dirstate)
276
        lock_and_call_current_dirstate(tree, 'lock_tree_write')
277
        self.assertRaises(errors.ObjectNotLocked, tree.current_dirstate)
278
5847.4.1 by John Arbash Meinel
When WT4.set_parent_trees() is called, sometimes we can use
279
    def test_set_parent_trees_uses_update_basis_by_delta(self):
280
        builder = self.make_branch_builder('source')
281
        builder.start_series()
282
        self.addCleanup(builder.finish_series)
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
283
        builder.build_snapshot([], [
6973.6.2 by Jelmer Vernooij
Fix more tests.
284
            ('add', ('', b'root-id', 'directory', None)),
285
            ('add', ('a', b'a-id', 'file', b'content\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
286
            revision_id=b'A')
6973.6.2 by Jelmer Vernooij
Fix more tests.
287
        builder.build_snapshot([b'A'], [
288
            ('modify', ('a', b'new content\nfor a\n')),
289
            ('add', ('b', b'b-id', 'file', b'b-content\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
290
            revision_id=b'B')
5847.4.1 by John Arbash Meinel
When WT4.set_parent_trees() is called, sometimes we can use
291
        tree = self.make_workingtree('tree')
292
        source_branch = builder.get_branch()
6973.6.2 by Jelmer Vernooij
Fix more tests.
293
        tree.branch.repository.fetch(source_branch.repository, b'B')
294
        tree.pull(source_branch, stop_revision=b'A')
5847.4.1 by John Arbash Meinel
When WT4.set_parent_trees() is called, sometimes we can use
295
        tree.lock_write()
296
        self.addCleanup(tree.unlock)
297
        state = tree.current_dirstate()
298
        called = []
299
        orig_update = state.update_basis_by_delta
7143.15.2 by Jelmer Vernooij
Run autopep8.
300
5847.4.1 by John Arbash Meinel
When WT4.set_parent_trees() is called, sometimes we can use
301
        def log_update_basis_by_delta(delta, new_revid):
302
            called.append(new_revid)
303
            return orig_update(delta, new_revid)
304
        state.update_basis_by_delta = log_update_basis_by_delta
305
        basis = tree.basis_tree()
6973.6.2 by Jelmer Vernooij
Fix more tests.
306
        self.assertEqual(b'a-id', basis.path2id('a'))
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
307
        self.assertFalse(basis.is_versioned('b'))
7143.15.2 by Jelmer Vernooij
Run autopep8.
308
5847.4.1 by John Arbash Meinel
When WT4.set_parent_trees() is called, sometimes we can use
309
        def fail_set_parent_trees(trees, ghosts):
310
            raise AssertionError('dirstate.set_parent_trees() was called')
311
        state.set_parent_trees = fail_set_parent_trees
6973.6.2 by Jelmer Vernooij
Fix more tests.
312
        tree.pull(source_branch, stop_revision=b'B')
313
        self.assertEqual([b'B'], called)
5847.4.1 by John Arbash Meinel
When WT4.set_parent_trees() is called, sometimes we can use
314
        basis = tree.basis_tree()
6973.6.2 by Jelmer Vernooij
Fix more tests.
315
        self.assertEqual(b'a-id', basis.path2id('a'))
316
        self.assertEqual(b'b-id', basis.path2id('b'))
5847.4.1 by John Arbash Meinel
When WT4.set_parent_trees() is called, sometimes we can use
317
5847.4.10 by John Arbash Meinel
A few more bug fixes.
318
    def test_set_parent_trees_handles_missing_basis(self):
319
        builder = self.make_branch_builder('source')
320
        builder.start_series()
321
        self.addCleanup(builder.finish_series)
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
322
        builder.build_snapshot([], [
6973.6.2 by Jelmer Vernooij
Fix more tests.
323
            ('add', ('', b'root-id', 'directory', None)),
324
            ('add', ('a', b'a-id', 'file', b'content\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
325
            revision_id=b'A')
6973.6.2 by Jelmer Vernooij
Fix more tests.
326
        builder.build_snapshot([b'A'], [
327
            ('modify', ('a', b'new content\nfor a\n')),
328
            ('add', ('b', b'b-id', 'file', b'b-content\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
329
            revision_id=b'B')
6973.6.2 by Jelmer Vernooij
Fix more tests.
330
        builder.build_snapshot([b'A'], [
331
            ('add', ('c', b'c-id', 'file', b'c-content\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
332
            revision_id=b'C')
5847.4.10 by John Arbash Meinel
A few more bug fixes.
333
        b_c = self.make_branch('branch_with_c')
6973.6.2 by Jelmer Vernooij
Fix more tests.
334
        b_c.pull(builder.get_branch(), stop_revision=b'C')
5847.4.10 by John Arbash Meinel
A few more bug fixes.
335
        b_b = self.make_branch('branch_with_b')
6973.6.2 by Jelmer Vernooij
Fix more tests.
336
        b_b.pull(builder.get_branch(), stop_revision=b'B')
5847.4.10 by John Arbash Meinel
A few more bug fixes.
337
        # This is reproducing some of what 'switch' does, just to isolate the
338
        # set_parent_trees() step.
339
        wt = b_b.create_checkout('tree', lightweight=True)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
340
        fmt = wt.controldir.find_branch_format()
341
        fmt.set_reference(wt.controldir, None, b_c)
5847.4.10 by John Arbash Meinel
A few more bug fixes.
342
        # Re-open with the new reference
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
343
        wt = wt.controldir.open_workingtree()
6973.6.2 by Jelmer Vernooij
Fix more tests.
344
        wt.set_parent_trees([(b'C', b_c.repository.revision_tree(b'C'))])
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
345
        self.assertFalse(wt.basis_tree().is_versioned('b'))
5847.4.10 by John Arbash Meinel
A few more bug fixes.
346
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
347
    def test_new_dirstate_on_new_lock(self):
348
        # until we have detection for when a dirstate can be reused, we
349
        # want to reparse dirstate on every new lock.
350
        known_dirstates = set()
7143.15.2 by Jelmer Vernooij
Run autopep8.
351
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
352
        def lock_and_compare_all_current_dirstate(tree, lock_method):
353
            getattr(tree, lock_method)()
354
            state = tree.current_dirstate()
355
            self.assertFalse(state in known_dirstates)
356
            known_dirstates.add(state)
357
            tree.unlock()
358
        tree = self.make_workingtree()
359
        # lock twice with each type to prevent silly per-lock-type bugs.
360
        # each lock and compare looks for a unique state object.
361
        lock_and_compare_all_current_dirstate(tree, 'lock_read')
362
        lock_and_compare_all_current_dirstate(tree, 'lock_read')
363
        lock_and_compare_all_current_dirstate(tree, 'lock_tree_write')
364
        lock_and_compare_all_current_dirstate(tree, 'lock_tree_write')
365
        lock_and_compare_all_current_dirstate(tree, 'lock_write')
366
        lock_and_compare_all_current_dirstate(tree, 'lock_write')
367
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
368
    def test_constructing_invalid_interdirstate_raises(self):
369
        tree = self.make_workingtree()
370
        rev_id = tree.commit('first post')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
371
        tree.commit('second post')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
372
        rev_tree = tree.branch.repository.revision_tree(rev_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
373
        # Exception is not a great thing to raise, but this test is
374
        # very short, and code is used to sanity check other tests, so
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
375
        # a full error object is YAGNI.
376
        self.assertRaises(
377
            Exception, workingtree_4.InterDirStateTree, rev_tree, tree)
378
        self.assertRaises(
379
            Exception, workingtree_4.InterDirStateTree, tree, rev_tree)
380
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
381
    def test_revtree_to_revtree_not_interdirstate(self):
382
        # we should not get a dirstate optimiser for two repository sourced
383
        # revtrees. we can't prove a negative, so we dont do exhaustive tests
384
        # of all formats; though that could be written in the future it doesn't
385
        # seem well worth it.
386
        tree = self.make_workingtree()
387
        rev_id = tree.commit('first post')
388
        rev_id2 = tree.commit('second post')
389
        rev_tree = tree.branch.repository.revision_tree(rev_id)
390
        rev_tree2 = tree.branch.repository.revision_tree(rev_id2)
391
        optimiser = InterTree.get(rev_tree, rev_tree2)
392
        self.assertIsInstance(optimiser, InterTree)
7143.15.2 by Jelmer Vernooij
Run autopep8.
393
        self.assertFalse(isinstance(
394
            optimiser, workingtree_4.InterDirStateTree))
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
395
        optimiser = InterTree.get(rev_tree2, rev_tree)
396
        self.assertIsInstance(optimiser, InterTree)
7143.15.2 by Jelmer Vernooij
Run autopep8.
397
        self.assertFalse(isinstance(
398
            optimiser, workingtree_4.InterDirStateTree))
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
399
400
    def test_revtree_not_in_dirstate_to_dirstate_not_interdirstate(self):
401
        # we should not get a dirstate optimiser when the revision id for of
402
        # the source is not in the dirstate of the target.
403
        tree = self.make_workingtree()
404
        rev_id = tree.commit('first post')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
405
        tree.commit('second post')
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
406
        rev_tree = tree.branch.repository.revision_tree(rev_id)
407
        tree.lock_read()
408
        optimiser = InterTree.get(rev_tree, tree)
409
        self.assertIsInstance(optimiser, InterTree)
7143.15.2 by Jelmer Vernooij
Run autopep8.
410
        self.assertFalse(isinstance(
411
            optimiser, workingtree_4.InterDirStateTree))
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
412
        optimiser = InterTree.get(tree, rev_tree)
413
        self.assertIsInstance(optimiser, InterTree)
7143.15.2 by Jelmer Vernooij
Run autopep8.
414
        self.assertFalse(isinstance(
415
            optimiser, workingtree_4.InterDirStateTree))
2255.2.121 by John Arbash Meinel
split out the WorkingTreeFormat4 tests into a separate test file
416
        tree.unlock()
417
418
    def test_empty_basis_to_dirstate_tree(self):
419
        # we should get a InterDirStateTree for doing
420
        # 'changes_from' from the first basis dirstate revision tree to a
421
        # WorkingTree4.
422
        tree = self.make_workingtree()
423
        tree.lock_read()
424
        basis_tree = tree.basis_tree()
425
        basis_tree.lock_read()
426
        optimiser = InterTree.get(basis_tree, tree)
427
        tree.unlock()
428
        basis_tree.unlock()
429
        self.assertIsInstance(optimiser, workingtree_4.InterDirStateTree)
430
431
    def test_nonempty_basis_to_dirstate_tree(self):
432
        # we should get a InterDirStateTree for doing
433
        # 'changes_from' from a non-null basis dirstate revision tree to a
434
        # WorkingTree4.
435
        tree = self.make_workingtree()
436
        tree.commit('first post')
437
        tree.lock_read()
438
        basis_tree = tree.basis_tree()
439
        basis_tree.lock_read()
440
        optimiser = InterTree.get(basis_tree, tree)
441
        tree.unlock()
442
        basis_tree.unlock()
443
        self.assertIsInstance(optimiser, workingtree_4.InterDirStateTree)
444
445
    def test_empty_basis_revtree_to_dirstate_tree(self):
446
        # we should get a InterDirStateTree for doing
447
        # 'changes_from' from an empty repository based rev tree to a
448
        # WorkingTree4.
449
        tree = self.make_workingtree()
450
        tree.lock_read()
451
        basis_tree = tree.branch.repository.revision_tree(tree.last_revision())
452
        basis_tree.lock_read()
453
        optimiser = InterTree.get(basis_tree, tree)
454
        tree.unlock()
455
        basis_tree.unlock()
456
        self.assertIsInstance(optimiser, workingtree_4.InterDirStateTree)
457
458
    def test_nonempty_basis_revtree_to_dirstate_tree(self):
459
        # we should get a InterDirStateTree for doing
460
        # 'changes_from' from a non-null repository based rev tree to a
461
        # WorkingTree4.
462
        tree = self.make_workingtree()
463
        tree.commit('first post')
464
        tree.lock_read()
465
        basis_tree = tree.branch.repository.revision_tree(tree.last_revision())
466
        basis_tree.lock_read()
467
        optimiser = InterTree.get(basis_tree, tree)
468
        tree.unlock()
469
        basis_tree.unlock()
470
        self.assertIsInstance(optimiser, workingtree_4.InterDirStateTree)
471
472
    def test_tree_to_basis_in_other_tree(self):
473
        # we should get a InterDirStateTree when
474
        # the source revid is in the dirstate object of the target and
475
        # the dirstates are different. This is largely covered by testing
476
        # with repository revtrees, so is just for extra confidence.
477
        tree = self.make_workingtree('a')
478
        tree.commit('first post')
479
        tree2 = self.make_workingtree('b')
480
        tree2.pull(tree.branch)
481
        basis_tree = tree.basis_tree()
482
        tree2.lock_read()
483
        basis_tree.lock_read()
484
        optimiser = InterTree.get(basis_tree, tree2)
485
        tree2.unlock()
486
        basis_tree.unlock()
487
        self.assertIsInstance(optimiser, workingtree_4.InterDirStateTree)
488
489
    def test_merged_revtree_to_tree(self):
490
        # we should get a InterDirStateTree when
491
        # the source tree is a merged tree present in the dirstate of target.
492
        tree = self.make_workingtree('a')
493
        tree.commit('first post')
494
        tree.commit('tree 1 commit 2')
495
        tree2 = self.make_workingtree('b')
496
        tree2.pull(tree.branch)
497
        tree2.commit('tree 2 commit 2')
498
        tree.merge_from_branch(tree2.branch)
499
        second_parent_tree = tree.revision_tree(tree.get_parent_ids()[1])
500
        second_parent_tree.lock_read()
501
        tree.lock_read()
502
        optimiser = InterTree.get(second_parent_tree, tree)
503
        tree.unlock()
504
        second_parent_tree.unlock()
505
        self.assertIsInstance(optimiser, workingtree_4.InterDirStateTree)
2255.2.144 by John Arbash Meinel
Simplify update_minimal a bit more, by making id_index a
506
507
    def test_id2path(self):
508
        tree = self.make_workingtree('tree')
2255.2.147 by John Arbash Meinel
Move fast id => path lookups down into DirState
509
        self.build_tree(['tree/a', 'tree/b'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
510
        tree.add(['a'], [b'a-id'])
511
        self.assertEqual(u'a', tree.id2path(b'a-id'))
2255.11.5 by Martin Pool
Tree.id2path should raise NoSuchId, not return None.
512
        self.assertRaises(errors.NoSuchId, tree.id2path, 'a')
2255.2.144 by John Arbash Meinel
Simplify update_minimal a bit more, by making id_index a
513
        tree.commit('a')
6855.4.1 by Jelmer Vernooij
Yet more bees.
514
        tree.add(['b'], [b'b-id'])
2255.2.144 by John Arbash Meinel
Simplify update_minimal a bit more, by making id_index a
515
2321.1.2 by Robert Collins
Skip new tests that depend on unicode file paths.
516
        try:
2825.6.1 by Robert Collins
* ``WorkingTree.rename_one`` will now raise an error if normalisation of the
517
            new_path = u'b\u03bcrry'
518
            tree.rename_one('a', new_path)
2321.1.2 by Robert Collins
Skip new tests that depend on unicode file paths.
519
        except UnicodeEncodeError:
520
            # support running the test on non-unicode platforms
521
            new_path = 'c'
2825.6.1 by Robert Collins
* ``WorkingTree.rename_one`` will now raise an error if normalisation of the
522
            tree.rename_one('a', new_path)
6855.4.1 by Jelmer Vernooij
Yet more bees.
523
        self.assertEqual(new_path, tree.id2path(b'a-id'))
2255.2.144 by John Arbash Meinel
Simplify update_minimal a bit more, by making id_index a
524
        tree.commit(u'b\xb5rry')
6809.4.25 by Jelmer Vernooij
Add paths argument to .unversion.
525
        tree.unversion([new_path])
6855.4.1 by Jelmer Vernooij
Yet more bees.
526
        self.assertRaises(errors.NoSuchId, tree.id2path, b'a-id')
527
        self.assertEqual('b', tree.id2path(b'b-id'))
528
        self.assertRaises(errors.NoSuchId, tree.id2path, b'c-id')
2255.2.166 by Martin Pool
(broken) Add Tree.get_root_id() & test
529
530
    def test_unique_root_id_per_tree(self):
531
        # each time you initialize a new tree, it gets a different root id
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
532
        format_name = 'development-subtree'
2255.2.166 by Martin Pool
(broken) Add Tree.get_root_id() & test
533
        tree1 = self.make_branch_and_tree('tree1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
534
                                          format=format_name)
2255.2.166 by Martin Pool
(broken) Add Tree.get_root_id() & test
535
        tree2 = self.make_branch_and_tree('tree2',
7143.15.2 by Jelmer Vernooij
Run autopep8.
536
                                          format=format_name)
2255.2.166 by Martin Pool
(broken) Add Tree.get_root_id() & test
537
        self.assertNotEqual(tree1.get_root_id(), tree2.get_root_id())
538
        # when you branch, it inherits the same root id
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
539
        tree1.commit('first post')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
540
        tree3 = tree1.controldir.sprout('tree3').open_workingtree()
2255.2.166 by Martin Pool
(broken) Add Tree.get_root_id() & test
541
        self.assertEqual(tree3.get_root_id(), tree1.get_root_id())
542
2255.11.2 by Martin Pool
Add more dirstate root-id-changing tests
543
    def test_set_root_id(self):
544
        # similar to some code that fails in the dirstate-plus-subtree branch
545
        # -- setting the root id while adding a parent seems to scramble the
546
        # dirstate invariants. -- mbp 20070303
547
        def validate():
548
            wt.lock_read()
549
            try:
550
                wt.current_dirstate()._validate()
551
            finally:
552
                wt.unlock()
553
        wt = self.make_workingtree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
554
        wt.set_root_id(b'TREE-ROOTID')
2255.11.2 by Martin Pool
Add more dirstate root-id-changing tests
555
        validate()
556
        wt.commit('somenthing')
557
        validate()
558
        # now switch and commit again
6855.4.1 by Jelmer Vernooij
Yet more bees.
559
        wt.set_root_id(b'tree-rootid')
2255.11.2 by Martin Pool
Add more dirstate root-id-changing tests
560
        validate()
561
        wt.commit('again')
562
        validate()
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
563
1551.15.6 by Aaron Bentley
Use ROOT_ID when the repository supports old clients (Bug #107168)
564
    def test_default_root_id(self):
565
        tree = self.make_branch_and_tree('tag', format='dirstate-tags')
566
        self.assertEqual(inventory.ROOT_ID, tree.get_root_id())
567
        tree = self.make_branch_and_tree('subtree',
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
568
                                         format='development-subtree')
1551.15.6 by Aaron Bentley
Use ROOT_ID when the repository supports old clients (Bug #107168)
569
        self.assertNotEqual(inventory.ROOT_ID, tree.get_root_id())
570
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
571
    def test_non_subtree_with_nested_trees(self):
572
        # prior to dirstate, st/diff/commit ignored nested trees.
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
573
        # dirstate, as opposed to development-subtree, should
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
574
        # behave the same way.
575
        tree = self.make_branch_and_tree('.', format='dirstate')
576
        self.assertFalse(tree.supports_tree_reference())
577
        self.build_tree(['dir/'])
578
        # for testing easily.
6855.4.1 by Jelmer Vernooij
Yet more bees.
579
        tree.set_root_id(b'root')
580
        tree.add(['dir'], [b'dir-id'])
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
581
        self.make_branch_and_tree('dir')
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
582
        # the most primitive operation: kind
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
583
        self.assertEqual('directory', tree.kind('dir'))
4570.2.8 by Robert Collins
Adjust WorkingTree4 specific test to deal with iter_changes reporting required directories.
584
        # a diff against the basis should give us a directory and the root (as
585
        # the root is new too).
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
586
        tree.lock_read()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
587
        expected = [(b'dir-id',
7143.15.2 by Jelmer Vernooij
Run autopep8.
588
                     (None, u'dir'),
589
                     True,
590
                     (False, True),
591
                     (None, b'root'),
592
                     (None, u'dir'),
593
                     (None, 'directory'),
594
                     (None, False)),
595
                    (b'root', (None, u''), True, (False, True), (None, None),
596
                     (None, u''), (None, 'directory'), (None, 0))]
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
597
        self.assertEqual(
598
            expected,
599
            list(tree.iter_changes(tree.basis_tree(), specific_files=['dir'])))
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
600
        tree.unlock()
601
        # do a commit, we want to trigger the dirstate fast-path too
602
        tree.commit('first post')
603
        # change the path for the subdir, which will trigger getting all
604
        # its data:
605
        os.rename('dir', 'also-dir')
606
        # now the diff will use the fast path
607
        tree.lock_read()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
608
        expected = [(b'dir-id',
7143.15.2 by Jelmer Vernooij
Run autopep8.
609
                     (u'dir', u'dir'),
610
                     True,
611
                     (True, True),
612
                     (b'root', b'root'),
613
                     ('dir', 'dir'),
614
                     ('directory', None),
615
                     (False, False))]
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
616
        self.assertEqual(expected, list(tree.iter_changes(tree.basis_tree())))
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
617
        tree.unlock()
618
619
    def test_with_subtree_supports_tree_references(self):
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
620
        # development-subtree should support tree-references.
621
        tree = self.make_branch_and_tree('.', format='development-subtree')
2255.2.232 by Robert Collins
Make WorkingTree4 report support for references based on the repositories capabilities.
622
        self.assertTrue(tree.supports_tree_reference())
623
        # having checked this is on, the tree interface, and intertree
624
        # interface tests, will proceed to test the subtree support of
625
        # workingtree_4.
2466.4.1 by John Arbash Meinel
Add a (failing) test that exposes how _iter_changes is accidentally walking into unversioned directories.
626
627
    def test_iter_changes_ignores_unversioned_dirs(self):
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
628
        """iter_changes should not descend into unversioned directories."""
2466.4.1 by John Arbash Meinel
Add a (failing) test that exposes how _iter_changes is accidentally walking into unversioned directories.
629
        tree = self.make_branch_and_tree('.', format='dirstate')
630
        # We have an unversioned directory at the root, a versioned one with
631
        # other versioned files and an unversioned directory, and another
632
        # versioned dir with nothing but an unversioned directory.
633
        self.build_tree(['unversioned/',
634
                         'unversioned/a',
635
                         'unversioned/b/',
636
                         'versioned/',
637
                         'versioned/unversioned/',
638
                         'versioned/unversioned/a',
639
                         'versioned/unversioned/b/',
640
                         'versioned2/',
641
                         'versioned2/a',
642
                         'versioned2/unversioned/',
643
                         'versioned2/unversioned/a',
644
                         'versioned2/unversioned/b/',
7143.15.2 by Jelmer Vernooij
Run autopep8.
645
                         ])
2466.4.1 by John Arbash Meinel
Add a (failing) test that exposes how _iter_changes is accidentally walking into unversioned directories.
646
        tree.add(['versioned', 'versioned2', 'versioned2/a'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
647
        tree.commit('one', rev_id=b'rev-1')
2466.4.1 by John Arbash Meinel
Add a (failing) test that exposes how _iter_changes is accidentally walking into unversioned directories.
648
        # Trap osutils._walkdirs_utf8 to spy on what dirs have been accessed.
649
        returned = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
650
2466.4.1 by John Arbash Meinel
Add a (failing) test that exposes how _iter_changes is accidentally walking into unversioned directories.
651
        def walkdirs_spy(*args, **kwargs):
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
652
            for val in orig(*args, **kwargs):
2466.4.1 by John Arbash Meinel
Add a (failing) test that exposes how _iter_changes is accidentally walking into unversioned directories.
653
                returned.append(val[0][0])
654
                yield val
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
655
        orig = self.overrideAttr(osutils, '_walkdirs_utf8', walkdirs_spy)
2466.4.1 by John Arbash Meinel
Add a (failing) test that exposes how _iter_changes is accidentally walking into unversioned directories.
656
657
        basis = tree.basis_tree()
658
        tree.lock_read()
659
        self.addCleanup(tree.unlock)
660
        basis.lock_read()
661
        self.addCleanup(basis.unlock)
2466.4.2 by John Arbash Meinel
Clean up the (failing) test so that the last thing
662
        changes = [c[1] for c in
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
663
                   tree.iter_changes(basis, want_unversioned=True)]
2466.4.2 by John Arbash Meinel
Clean up the (failing) test so that the last thing
664
        self.assertEqual([(None, 'unversioned'),
665
                          (None, 'versioned/unversioned'),
666
                          (None, 'versioned2/unversioned'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
667
                          ], changes)
7045.2.13 by Jelmer Vernooij
Fix some workingtree_4 tests.
668
        self.assertEqual([b'', b'versioned', b'versioned2'], returned)
7143.15.2 by Jelmer Vernooij
Run autopep8.
669
        del returned[:]  # reset
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
670
        changes = [c[1] for c in tree.iter_changes(basis)]
2466.4.2 by John Arbash Meinel
Clean up the (failing) test so that the last thing
671
        self.assertEqual([], changes)
7045.2.13 by Jelmer Vernooij
Fix some workingtree_4 tests.
672
        self.assertEqual([b'', b'versioned', b'versioned2'], returned)
3207.2.1 by jameinel
Add a test that _iter_changes raises a clearer error when we encounter an invalid rename.
673
4496.2.1 by Ian Clatworthy
(igc) Improve paths are not versioned reporting (Benoît PIERRE)
674
    def test_iter_changes_unversioned_error(self):
675
        """ Check if a PathsNotVersionedError is correctly raised and the
676
            paths list contains all unversioned entries only.
677
        """
678
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
679
        self.build_tree_contents([('tree/bar', b'')])
680
        tree.add(['bar'], [b'bar-id'])
4496.2.1 by Ian Clatworthy
(igc) Improve paths are not versioned reporting (Benoît PIERRE)
681
        tree.lock_read()
682
        self.addCleanup(tree.unlock)
7143.15.2 by Jelmer Vernooij
Run autopep8.
683
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
684
        def tree_iter_changes(files):
685
            return [
686
                c for c in tree.iter_changes(
687
                    tree.basis_tree(), specific_files=files,
688
                    require_versioned=True)]
4496.2.1 by Ian Clatworthy
(igc) Improve paths are not versioned reporting (Benoît PIERRE)
689
        e = self.assertRaises(errors.PathsNotVersionedError,
690
                              tree_iter_changes, ['bar', 'foo'])
691
        self.assertEqual(e.paths, ['foo'])
692
6345.1.2 by Martin Packman
Add targetted working tree tests for places that raise PathsNotVersionedError
693
    def test_iter_changes_unversioned_non_ascii(self):
694
        """Unversioned non-ascii paths should be reported as unicode"""
695
        self.requireFeature(features.UnicodeFilenameFeature)
696
        tree = self.make_branch_and_tree('.')
6855.4.1 by Jelmer Vernooij
Yet more bees.
697
        self.build_tree_contents([('f', b'')])
698
        tree.add(['f'], [b'f-id'])
7143.15.2 by Jelmer Vernooij
Run autopep8.
699
6345.1.2 by Martin Packman
Add targetted working tree tests for places that raise PathsNotVersionedError
700
        def tree_iter_changes(tree, files):
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
701
            return list(tree.iter_changes(
702
                tree.basis_tree(), specific_files=files,
703
                require_versioned=True))
6345.1.2 by Martin Packman
Add targetted working tree tests for places that raise PathsNotVersionedError
704
        tree.lock_read()
705
        self.addCleanup(tree.unlock)
706
        e = self.assertRaises(errors.PathsNotVersionedError,
7143.15.2 by Jelmer Vernooij
Run autopep8.
707
                              tree_iter_changes, tree, [u'\xa7', u'\u03c0'])
6973.10.6 by Jelmer Vernooij
Fix tests.
708
        self.assertEqual(set(e.paths), set([u'\xa7', u'\u03c0']))
6345.1.2 by Martin Packman
Add targetted working tree tests for places that raise PathsNotVersionedError
709
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
710
    def get_tree_with_cachable_file_foo(self):
711
        tree = self.make_branch_and_tree('.')
5755.1.1 by John Arbash Meinel
Change WT._observed_sha1 to also update st.st_size.
712
        tree.lock_write()
713
        self.addCleanup(tree.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
714
        self.build_tree_contents([('foo', b'a bit of content for foo\n')])
715
        tree.add(['foo'], [b'foo-id'])
5755.1.1 by John Arbash Meinel
Change WT._observed_sha1 to also update st.st_size.
716
        tree.current_dirstate()._cutoff_time = time.time() + 60
3207.2.1 by jameinel
Add a test that _iter_changes raises a clearer error when we encounter an invalid rename.
717
        return tree
718
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
719
    def test_commit_updates_hash_cache(self):
720
        tree = self.get_tree_with_cachable_file_foo()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
721
        tree.commit('a commit')
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
722
        # tree's dirstate should now have a valid stat entry for foo.
723
        entry = tree._get_entry(path='foo')
724
        expected_sha1 = osutils.sha_file_by_name('foo')
725
        self.assertEqual(expected_sha1, entry[1][0][1])
5755.1.2 by John Arbash Meinel
use soft constants rather than '25'
726
        self.assertEqual(len('a bit of content for foo\n'), entry[1][0][2])
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
727
728
    def test_observed_sha1_cachable(self):
729
        tree = self.get_tree_with_cachable_file_foo()
730
        expected_sha1 = osutils.sha_file_by_name('foo')
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
731
        statvalue = os.lstat("foo")
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
732
        tree._observed_sha1("foo", (expected_sha1, statvalue))
5755.1.1 by John Arbash Meinel
Change WT._observed_sha1 to also update st.st_size.
733
        entry = tree._get_entry(path="foo")
734
        entry_state = entry[1][0]
735
        self.assertEqual(expected_sha1, entry_state[1])
5755.1.2 by John Arbash Meinel
use soft constants rather than '25'
736
        self.assertEqual(statvalue.st_size, entry_state[2])
5755.1.1 by John Arbash Meinel
Change WT._observed_sha1 to also update st.st_size.
737
        tree.unlock()
738
        tree.lock_read()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
739
        tree = tree.controldir.open_workingtree()
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
740
        tree.lock_read()
3207.2.1 by jameinel
Add a test that _iter_changes raises a clearer error when we encounter an invalid rename.
741
        self.addCleanup(tree.unlock)
5755.1.1 by John Arbash Meinel
Change WT._observed_sha1 to also update st.st_size.
742
        entry = tree._get_entry(path="foo")
743
        entry_state = entry[1][0]
744
        self.assertEqual(expected_sha1, entry_state[1])
5755.1.2 by John Arbash Meinel
use soft constants rather than '25'
745
        self.assertEqual(statvalue.st_size, entry_state[2])
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
746
747
    def test_observed_sha1_new_file(self):
748
        tree = self.make_branch_and_tree('.')
749
        self.build_tree(['foo'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
750
        tree.add(['foo'], [b'foo-id'])
6969.3.2 by Jelmer Vernooij
Use context managers for locking.
751
        with tree.lock_read():
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
752
            current_sha1 = tree._get_entry(path="foo")[1][0][1]
6969.3.2 by Jelmer Vernooij
Use context managers for locking.
753
        with tree.lock_write():
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
754
            tree._observed_sha1(
7143.15.15 by Jelmer Vernooij
Merge trunk.
755
                "foo", (osutils.sha_file_by_name('foo'), os.lstat("foo")))
3709.3.1 by Robert Collins
First cut - make it work - at updating the tree stat cache during commit.
756
            # Must not have changed
757
            self.assertEqual(current_sha1,
7143.15.2 by Jelmer Vernooij
Run autopep8.
758
                             tree._get_entry(path="foo")[1][0][1])
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
759
760
    def test_get_file_with_stat_id_only(self):
761
        # Explicit test to ensure we get a lstat value from WT4 trees.
762
        tree = self.make_branch_and_tree('.')
763
        self.build_tree(['foo'])
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
764
        tree.add(['foo'])
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
765
        tree.lock_read()
766
        self.addCleanup(tree.unlock)
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
767
        file_obj, statvalue = tree.get_file_with_stat('foo')
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
768
        expected = os.lstat('foo')
4807.2.2 by John Arbash Meinel
Move all the stat comparison and platform checkning code to assertEqualStat.
769
        self.assertEqualStat(expected, statvalue)
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
770
        self.assertEqual([b"contents of foo\n"], file_obj.readlines())
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
771
772
773
class TestCorruptDirstate(TestCaseWithTransport):
774
    """Tests for how we handle when the dirstate has been corrupted."""
775
776
    def create_wt4(self):
777
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
778
        control.create_repository()
779
        control.create_branch()
780
        tree = workingtree_4.WorkingTreeFormat4().initialize(control)
781
        return tree
782
783
    def test_invalid_rename(self):
784
        tree = self.create_wt4()
785
        # Create a corrupted dirstate
6969.3.2 by Jelmer Vernooij
Use context managers for locking.
786
        with tree.lock_write():
4285.2.1 by Vincent Ladeuil
Cleanup test imports and use features to better track skipped tests.
787
            # We need a parent, or we always compare with NULL
788
            tree.commit('init')
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
789
            state = tree.current_dirstate()
790
            state._read_dirblocks_if_needed()
791
            # Now add in an invalid entry, a rename with a dangling pointer
7045.2.13 by Jelmer Vernooij
Fix some workingtree_4 tests.
792
            state._dirblocks[1][1].append(((b'', b'foo', b'foo-id'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
793
                                           [(b'f', b'', 0, False, b''),
794
                                            (b'r', b'bar', 0, False, b'')]))
6744 by Jelmer Vernooij
Merge lp:~jelmer/brz/move-errors-knit.
795
            self.assertListRaises(dirstate.DirstateCorrupt,
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
796
                                  tree.iter_changes, tree.basis_tree())
797
798
    def get_simple_dirblocks(self, state):
799
        """Extract the simple information from the DirState.
800
801
        This returns the dirblocks, only with the sha1sum and stat details
802
        filtered out.
803
        """
804
        simple_blocks = []
805
        for block in state._dirblocks:
806
            simple_block = (block[0], [])
807
            for entry in block[1]:
808
                # Include the key for each entry, and for each parent include
809
                # just the minikind, so we know if it was
810
                # present/absent/renamed/etc
811
                simple_block[1].append((entry[0], [i[0] for i in entry[1]]))
812
            simple_blocks.append(simple_block)
813
        return simple_blocks
814
815
    def test_update_basis_with_invalid_delta(self):
816
        """When given an invalid delta, it should abort, and not be saved."""
817
        self.build_tree(['dir/', 'dir/file'])
818
        tree = self.create_wt4()
819
        tree.lock_write()
820
        self.addCleanup(tree.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
821
        tree.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
822
        first_revision_id = tree.commit('init')
823
824
        root_id = tree.path2id('')
825
        state = tree.current_dirstate()
826
        state._read_dirblocks_if_needed()
827
        self.assertEqual([
7045.1.13 by Jelmer Vernooij
Fix a few more tests.
828
            (b'', [((b'', b'', root_id), [b'd', b'd'])]),
829
            (b'', [((b'', b'dir', b'dir-id'), [b'd', b'd'])]),
830
            (b'dir', [((b'dir', b'file', b'file-id'), [b'f', b'f'])]),
7143.15.2 by Jelmer Vernooij
Run autopep8.
831
        ], self.get_simple_dirblocks(state))
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
832
833
        tree.remove(['dir/file'])
834
        self.assertEqual([
7045.1.13 by Jelmer Vernooij
Fix a few more tests.
835
            (b'', [((b'', b'', root_id), [b'd', b'd'])]),
836
            (b'', [((b'', b'dir', b'dir-id'), [b'd', b'd'])]),
837
            (b'dir', [((b'dir', b'file', b'file-id'), [b'a', b'f'])]),
7143.15.2 by Jelmer Vernooij
Run autopep8.
838
        ], self.get_simple_dirblocks(state))
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
839
        # Make sure the removal is written to disk
840
        tree.flush()
841
842
        # self.assertRaises(Exception, tree.update_basis_by_delta,
6855.4.1 by Jelmer Vernooij
Yet more bees.
843
        new_dir = inventory.InventoryDirectory(b'dir-id', 'new-dir', root_id)
844
        new_dir.revision = b'new-revision-id'
845
        new_file = inventory.InventoryFile(b'file-id', 'new-file', root_id)
846
        new_file.revision = b'new-revision-id'
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
847
        self.assertRaises(
848
            errors.InconsistentDelta,
849
            tree.update_basis_by_delta, b'new-revision-id',
850
            [('dir', 'new-dir', b'dir-id', new_dir),
851
             ('dir/file', 'new-dir/new-file', b'file-id', new_file),
7143.16.6 by Jelmer Vernooij
Fix E124.
852
             ])
3709.3.2 by Robert Collins
Race-free stat-fingerprint updating during commit via a new method get_file_with_stat.
853
        del state
854
855
        # Now when we re-read the file it should not have been modified
856
        tree.unlock()
857
        tree.lock_read()
858
        self.assertEqual(first_revision_id, tree.last_revision())
859
        state = tree.current_dirstate()
860
        state._read_dirblocks_if_needed()
861
        self.assertEqual([
7045.2.13 by Jelmer Vernooij
Fix some workingtree_4 tests.
862
            (b'', [((b'', b'', root_id), [b'd', b'd'])]),
863
            (b'', [((b'', b'dir', b'dir-id'), [b'd', b'd'])]),
864
            (b'dir', [((b'dir', b'file', b'file-id'), [b'a', b'f'])]),
7143.15.2 by Jelmer Vernooij
Run autopep8.
865
        ], self.get_simple_dirblocks(state))
4634.156.1 by Vincent Ladeuil
Don't traceback when unversioning a directory.
866
867
868
class TestInventoryCoherency(TestCaseWithTransport):
869
870
    def test_inventory_is_synced_when_unversioning_a_dir(self):
871
        """Unversioning the root of a subtree unversions the entire subtree."""
872
        tree = self.make_branch_and_tree('.')
873
        self.build_tree(['a/', 'a/b', 'c/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
874
        tree.add(['a', 'a/b', 'c'], [b'a-id', b'b-id', b'c-id'])
4634.156.1 by Vincent Ladeuil
Don't traceback when unversioning a directory.
875
        # within a lock unversion should take effect
876
        tree.lock_write()
877
        self.addCleanup(tree.unlock)
878
        # Force access to the in memory inventory to trigger bug #494221: try
879
        # maintaining the in-memory inventory
6405.2.10 by Jelmer Vernooij
Fix more tests.
880
        inv = tree.root_inventory
6973.7.5 by Jelmer Vernooij
s/file/open.
881
        self.assertTrue(inv.has_id(b'a-id'))
882
        self.assertTrue(inv.has_id(b'b-id'))
6809.4.25 by Jelmer Vernooij
Add paths argument to .unversion.
883
        tree.unversion(['a', 'a/b'])
6973.7.5 by Jelmer Vernooij
s/file/open.
884
        self.assertFalse(inv.has_id(b'a-id'))
885
        self.assertFalse(inv.has_id(b'b-id'))