/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1
# Copyright (C) 2006-2012, 2016 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1534.7.106 by Aaron Bentley
Cleaned up imports, added copyright statements
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1534.7.106 by Aaron Bentley
Cleaned up imports, added copyright statements
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1534.7.106 by Aaron Bentley
Cleaned up imports, added copyright statements
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1534.7.106 by Aaron Bentley
Cleaned up imports, added copyright statements
16
7045.4.24 by Jelmer Vernooij
Fix a test_transform test.
17
import codecs
5582.8.1 by Martin
Make bt.test_transform.TestTreeTransform.test_rename_fails not care about the exact stringification of the exception instance
18
import errno
7122.6.1 by Jelmer Vernooij
merge Parth's work into Breezy
19
from io import BytesIO, StringIO
1534.7.106 by Aaron Bentley
Cleaned up imports, added copyright statements
20
import os
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
21
import sys
4934.1.1 by John Arbash Meinel
Basic implementation for windows and bug #488724.
22
import time
1558.1.3 by Aaron Bentley
Fixed deprecated op use in test suite
23
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
24
from .. import (
2694.5.4 by Jelmer Vernooij
Move bzrlib.util.bencode to bzrlib._bencode_py.
25
    bencode,
2090.2.1 by Martin Pool
Fix some code which relies on assertions and breaks under python -O
26
    errors,
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
27
    filters,
3199.1.4 by Vincent Ladeuil
Fix 16 leaked tmp dirs. Probably indicates a lock handling problem with TransformPreview
28
    osutils,
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
29
    revision as _mod_revision,
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
30
    rules,
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
31
    tests,
5409.1.17 by Vincent Ladeuil
Ensures we fallback to the default policy if a bogus one is specified.
32
    trace,
5409.1.7 by Vincent Ladeuil
First orphaning implementation (some tests lacking).
33
    transform,
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
34
    urlutils,
35
    )
7265.5.1 by Jelmer Vernooij
Move generate_ids to breezy.bzr.
36
from ..bzr import (
37
    generate_ids,
38
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
39
from ..conflicts import (
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
40
    DeletingParent,
41
    DuplicateEntry,
42
    DuplicateID,
43
    MissingParent,
44
    NonDirectoryParent,
45
    ParentLoop,
46
    UnversionedParent,
47
)
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
48
from ..controldir import ControlDir
49
from ..diff import show_diff_trees
50
from ..errors import (
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
51
    DuplicateKey,
52
    ExistingLimbo,
53
    ExistingPendingDeletion,
54
    ImmortalLimbo,
55
    ImmortalPendingDeletion,
56
    LockError,
57
    MalformedTransform,
58
    ReusingTransform,
59
)
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
60
from ..osutils import (
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
61
    file_kind,
62
    pathjoin,
63
)
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
64
from ..merge import Merge3Merger, Merger
65
from ..mutabletree import MutableTree
66
from . import (
5050.44.1 by Vincent Ladeuil
One more fixed test related to bug #646133
67
    features,
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
68
    TestCaseInTempDir,
69
    TestSkipped,
70
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
71
from .features import (
3136.1.1 by Aaron Bentley
Add support for hardlinks to TreeTransform
72
    HardlinkFeature,
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
73
    SymlinkFeature,
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
74
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
75
from ..transform import (
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
76
    build_tree,
77
    create_from_tree,
78
    cook_conflicts,
79
    _FileMover,
80
    FinalPaths,
81
    resolve_conflicts,
82
    resolve_checkout,
83
    ROOT_PARENT,
84
    TransformPreview,
85
    TreeTransform,
86
)
0.13.13 by Aaron Bentley
Add direct test of serialization records
87
1534.7.1 by Aaron Bentley
Got creation of a versioned file working
88
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
89
class TestTreeTransform(tests.TestCaseWithTransport):
1740.2.4 by Aaron Bentley
Update transform tests and docs
90
1534.7.59 by Aaron Bentley
Simplified tests
91
    def setUp(self):
92
        super(TestTreeTransform, self).setUp()
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
93
        self.wt = self.make_branch_and_tree('.', format='development-subtree')
1534.7.161 by Aaron Bentley
Used appropriate control_files
94
        os.chdir('..')
1534.7.59 by Aaron Bentley
Simplified tests
95
96
    def get_transform(self):
97
        transform = TreeTransform(self.wt)
3453.2.7 by Aaron Bentley
Remove test kipple
98
        self.addCleanup(transform.finalize)
1731.1.33 by Aaron Bentley
Revert no-special-root changes
99
        return transform, transform.root
1534.7.59 by Aaron Bentley
Simplified tests
100
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
101
    def get_transform_for_sha1_test(self):
102
        trans, root = self.get_transform()
103
        self.wt.lock_tree_write()
104
        self.addCleanup(self.wt.unlock)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
105
        contents = [b'just some content\n']
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
106
        sha1 = osutils.sha_strings(contents)
107
        # Roll back the clock
108
        trans._creation_mtime = time.time() - 20.0
109
        return trans, root, contents, sha1
110
1534.7.162 by Aaron Bentley
Handle failures creating/deleting the Limbo directory
111
    def test_existing_limbo(self):
112
        transform, root = self.get_transform()
2733.2.6 by Aaron Bentley
Make TreeTransform commits rollbackable
113
        limbo_name = transform._limbodir
114
        deletion_path = transform._deletiondir
1534.7.176 by abentley
Fixed up tests for Windows
115
        os.mkdir(pathjoin(limbo_name, 'hehe'))
1534.7.162 by Aaron Bentley
Handle failures creating/deleting the Limbo directory
116
        self.assertRaises(ImmortalLimbo, transform.apply)
117
        self.assertRaises(LockError, self.wt.unlock)
118
        self.assertRaises(ExistingLimbo, self.get_transform)
119
        self.assertRaises(LockError, self.wt.unlock)
1534.7.176 by abentley
Fixed up tests for Windows
120
        os.rmdir(pathjoin(limbo_name, 'hehe'))
1534.7.162 by Aaron Bentley
Handle failures creating/deleting the Limbo directory
121
        os.rmdir(limbo_name)
2733.2.6 by Aaron Bentley
Make TreeTransform commits rollbackable
122
        os.rmdir(deletion_path)
1534.7.162 by Aaron Bentley
Handle failures creating/deleting the Limbo directory
123
        transform, root = self.get_transform()
124
        transform.apply()
1534.7.59 by Aaron Bentley
Simplified tests
125
2733.2.11 by Aaron Bentley
Detect irregularities with the pending-deletion directory
126
    def test_existing_pending_deletion(self):
127
        transform, root = self.get_transform()
128
        deletion_path = self._limbodir = urlutils.local_path_from_url(
3407.2.8 by Martin Pool
Deprecate LockableFiles.controlfilename
129
            transform._tree._transport.abspath('pending-deletion'))
2733.2.11 by Aaron Bentley
Detect irregularities with the pending-deletion directory
130
        os.mkdir(pathjoin(deletion_path, 'blocking-directory'))
131
        self.assertRaises(ImmortalPendingDeletion, transform.apply)
132
        self.assertRaises(LockError, self.wt.unlock)
133
        self.assertRaises(ExistingPendingDeletion, self.get_transform)
134
1534.7.1 by Aaron Bentley
Got creation of a versioned file working
135
    def test_build(self):
3034.2.1 by Aaron Bentley
Fix is_executable tests for win32
136
        transform, root = self.get_transform()
137
        self.wt.lock_tree_write()
138
        self.addCleanup(self.wt.unlock)
1534.7.59 by Aaron Bentley
Simplified tests
139
        self.assertIs(transform.get_tree_parent(root), ROOT_PARENT)
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
140
        imaginary_id = transform.trans_id_tree_path('imaginary')
1534.10.32 by Aaron Bentley
Test and fix case where name has trailing slash
141
        imaginary_id2 = transform.trans_id_tree_path('imaginary/')
142
        self.assertEqual(imaginary_id, imaginary_id2)
4597.9.7 by Vincent Ladeuil
transform.final_kind() now returns None instead of raising NoSuchFile.
143
        self.assertEqual(root, transform.get_tree_parent(imaginary_id))
144
        self.assertEqual('directory', transform.final_kind(root))
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
145
        self.assertEqual(self.wt.path2id(''), transform.final_file_id(root))
1534.7.59 by Aaron Bentley
Simplified tests
146
        trans_id = transform.create_path('name', root)
147
        self.assertIs(transform.final_file_id(trans_id), None)
4597.9.7 by Vincent Ladeuil
transform.final_kind() now returns None instead of raising NoSuchFile.
148
        self.assertIs(None, transform.final_kind(trans_id))
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
149
        transform.create_file([b'contents'], trans_id)
1534.7.59 by Aaron Bentley
Simplified tests
150
        transform.set_executability(True, trans_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
151
        transform.version_file(b'my_pretties', trans_id)
1534.7.59 by Aaron Bentley
Simplified tests
152
        self.assertRaises(DuplicateKey, transform.version_file,
6973.10.1 by Jelmer Vernooij
Fix some tests.
153
                          b'my_pretties', trans_id)
154
        self.assertEqual(transform.final_file_id(trans_id), b'my_pretties')
1534.7.59 by Aaron Bentley
Simplified tests
155
        self.assertEqual(transform.final_parent(trans_id), root)
156
        self.assertIs(transform.final_parent(root), ROOT_PARENT)
157
        self.assertIs(transform.get_tree_parent(root), ROOT_PARENT)
158
        oz_id = transform.create_path('oz', root)
159
        transform.create_directory(oz_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
160
        transform.version_file(b'ozzie', oz_id)
1534.7.59 by Aaron Bentley
Simplified tests
161
        trans_id2 = transform.create_path('name2', root)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
162
        transform.create_file([b'contents'], trans_id2)
1534.7.59 by Aaron Bentley
Simplified tests
163
        transform.set_executability(False, trans_id2)
6973.10.1 by Jelmer Vernooij
Fix some tests.
164
        transform.version_file(b'my_pretties2', trans_id2)
1534.7.191 by Aaron Bentley
Got transform.apply to list modified paths
165
        modified_paths = transform.apply().modified_paths
6973.10.1 by Jelmer Vernooij
Fix some tests.
166
        with self.wt.get_file('name') as f:
167
            self.assertEqual(b'contents', f.read())
168
        self.assertEqual(self.wt.path2id('name'), b'my_pretties')
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
169
        self.assertIs(self.wt.is_executable('name'), True)
170
        self.assertIs(self.wt.is_executable('name2'), False)
1534.7.100 by Aaron Bentley
Fixed path-relative test cases
171
        self.assertEqual('directory', file_kind(self.wt.abspath('oz')))
1534.7.191 by Aaron Bentley
Got transform.apply to list modified paths
172
        self.assertEqual(len(modified_paths), 3)
6883.7.6 by Jelmer Vernooij
Remove uses of id2path.
173
        tree_mod_paths = [self.wt.abspath(self.wt.id2path(f)) for f in
6973.10.1 by Jelmer Vernooij
Fix some tests.
174
                          (b'ozzie', b'my_pretties', b'my_pretties2')]
1534.7.191 by Aaron Bentley
Got transform.apply to list modified paths
175
        self.assertSubset(tree_mod_paths, modified_paths)
1534.7.1 by Aaron Bentley
Got creation of a versioned file working
176
        # is it safe to finalize repeatedly?
177
        transform.finalize()
1534.7.59 by Aaron Bentley
Simplified tests
178
        transform.finalize()
1534.7.2 by Aaron Bentley
Added convenience function
179
5752.3.6 by John Arbash Meinel
More direct tests of TreeTransform behavior wrt _observed_sha1s
180
    def test_apply_informs_tree_of_observed_sha1(self):
181
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
6973.10.1 by Jelmer Vernooij
Fix some tests.
182
        trans_id = trans.new_file('file1', root, contents, file_id=b'file1-id',
5752.3.6 by John Arbash Meinel
More direct tests of TreeTransform behavior wrt _observed_sha1s
183
                                  sha1=sha1)
184
        calls = []
185
        orig = self.wt._observed_sha1
7143.15.2 by Jelmer Vernooij
Run autopep8.
186
5752.3.6 by John Arbash Meinel
More direct tests of TreeTransform behavior wrt _observed_sha1s
187
        def _observed_sha1(*args):
188
            calls.append(args)
189
            orig(*args)
190
        self.wt._observed_sha1 = _observed_sha1
191
        trans.apply()
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
192
        self.assertEqual([('file1', trans._observed_sha1s[trans_id])],
5752.3.6 by John Arbash Meinel
More direct tests of TreeTransform behavior wrt _observed_sha1s
193
                         calls)
194
5752.3.1 by John Arbash Meinel
Merge up from 2.4-windows-lfstat
195
    def test_create_file_caches_sha1(self):
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
196
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
5752.3.1 by John Arbash Meinel
Merge up from 2.4-windows-lfstat
197
        trans_id = trans.create_path('file1', root)
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
198
        trans.create_file(contents, trans_id, sha1=sha1)
5752.3.1 by John Arbash Meinel
Merge up from 2.4-windows-lfstat
199
        st_val = osutils.lstat(trans._limbo_name(trans_id))
200
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
201
        self.assertEqual(o_sha1, sha1)
202
        self.assertEqualStat(o_st_val, st_val)
203
204
    def test__apply_insertions_updates_sha1(self):
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
205
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
5752.3.1 by John Arbash Meinel
Merge up from 2.4-windows-lfstat
206
        trans_id = trans.create_path('file1', root)
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
207
        trans.create_file(contents, trans_id, sha1=sha1)
5752.3.1 by John Arbash Meinel
Merge up from 2.4-windows-lfstat
208
        st_val = osutils.lstat(trans._limbo_name(trans_id))
209
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
210
        self.assertEqual(o_sha1, sha1)
211
        self.assertEqualStat(o_st_val, st_val)
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
212
        creation_mtime = trans._creation_mtime + 10.0
5752.3.1 by John Arbash Meinel
Merge up from 2.4-windows-lfstat
213
        # We fake a time difference from when the file was created until now it
214
        # is being renamed by using os.utime. Note that the change we actually
215
        # want to see is the real ctime change from 'os.rename()', but as long
216
        # as we observe a new stat value, we should be fine.
217
        os.utime(trans._limbo_name(trans_id), (creation_mtime, creation_mtime))
218
        trans.apply()
219
        new_st_val = osutils.lstat(self.wt.abspath('file1'))
220
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
221
        self.assertEqual(o_sha1, sha1)
222
        self.assertEqualStat(o_st_val, new_st_val)
223
        self.assertNotEqual(st_val.st_mtime, new_st_val.st_mtime)
224
5752.3.4 by John Arbash Meinel
Add new_file(sha1=XXX) and pass that down to create_file.
225
    def test_new_file_caches_sha1(self):
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
226
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
6973.10.1 by Jelmer Vernooij
Fix some tests.
227
        trans_id = trans.new_file('file1', root, contents, file_id=b'file1-id',
5752.3.4 by John Arbash Meinel
Add new_file(sha1=XXX) and pass that down to create_file.
228
                                  sha1=sha1)
229
        st_val = osutils.lstat(trans._limbo_name(trans_id))
230
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
231
        self.assertEqual(o_sha1, sha1)
232
        self.assertEqualStat(o_st_val, st_val)
233
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
234
    def test_cancel_creation_removes_observed_sha1(self):
235
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
6973.10.1 by Jelmer Vernooij
Fix some tests.
236
        trans_id = trans.new_file('file1', root, contents, file_id=b'file1-id',
5752.3.5 by John Arbash Meinel
Refactor tests into a common helper.
237
                                  sha1=sha1)
238
        self.assertTrue(trans_id in trans._observed_sha1s)
239
        trans.cancel_creation(trans_id)
240
        self.assertFalse(trans_id in trans._observed_sha1s)
241
4934.1.1 by John Arbash Meinel
Basic implementation for windows and bug #488724.
242
    def test_create_files_same_timestamp(self):
243
        transform, root = self.get_transform()
244
        self.wt.lock_tree_write()
245
        self.addCleanup(self.wt.unlock)
246
        # Roll back the clock, so that we know everything is being set to the
247
        # exact time
4934.1.10 by John Arbash Meinel
Rework the tests a bit.
248
        transform._creation_mtime = creation_mtime = time.time() - 20.0
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
249
        transform.create_file([b'content-one'],
4934.1.1 by John Arbash Meinel
Basic implementation for windows and bug #488724.
250
                              transform.create_path('one', root))
7143.15.2 by Jelmer Vernooij
Run autopep8.
251
        time.sleep(1)  # *ugly*
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
252
        transform.create_file([b'content-two'],
4934.1.1 by John Arbash Meinel
Basic implementation for windows and bug #488724.
253
                              transform.create_path('two', root))
254
        transform.apply()
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
255
        fo, st1 = self.wt.get_file_with_stat('one', filtered=False)
4934.1.1 by John Arbash Meinel
Basic implementation for windows and bug #488724.
256
        fo.close()
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
257
        fo, st2 = self.wt.get_file_with_stat('two', filtered=False)
4934.1.1 by John Arbash Meinel
Basic implementation for windows and bug #488724.
258
        fo.close()
4934.2.2 by Martin
Rearrange osutils.fset_mtime tests a little and make them robust on FAT filesystems
259
        # We only guarantee 2s resolution
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
260
        self.assertTrue(
261
            abs(creation_mtime - st1.st_mtime) < 2.0,
262
            "%s != %s within 2 seconds" % (creation_mtime, st1.st_mtime))
4934.1.6 by John Arbash Meinel
It turns out that with os/python/C buffering, we need to flush
263
        # But if we have more than that, all files should get the same result
4934.1.1 by John Arbash Meinel
Basic implementation for windows and bug #488724.
264
        self.assertEqual(st1.st_mtime, st2.st_mtime)
265
4634.122.2 by Aaron Bentley, John Arbash Meinel
Bring the fixup_new_roots code from the nested-trees code.
266
    def test_change_root_id(self):
267
        transform, root = self.get_transform()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
268
        self.assertNotEqual(b'new-root-id', self.wt.path2id(''))
6855.4.1 by Jelmer Vernooij
Yet more bees.
269
        transform.new_directory('', ROOT_PARENT, b'new-root-id')
4634.122.2 by Aaron Bentley, John Arbash Meinel
Bring the fixup_new_roots code from the nested-trees code.
270
        transform.delete_contents(root)
271
        transform.unversion_file(root)
272
        transform.fixup_new_roots()
273
        transform.apply()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
274
        self.assertEqual(b'new-root-id', self.wt.path2id(''))
4634.122.2 by Aaron Bentley, John Arbash Meinel
Bring the fixup_new_roots code from the nested-trees code.
275
276
    def test_change_root_id_add_files(self):
277
        transform, root = self.get_transform()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
278
        self.assertNotEqual(b'new-root-id', self.wt.path2id(''))
6855.4.1 by Jelmer Vernooij
Yet more bees.
279
        new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
6973.10.1 by Jelmer Vernooij
Fix some tests.
280
        transform.new_file('file', new_trans_id, [b'new-contents\n'],
281
                           b'new-file-id')
4634.122.2 by Aaron Bentley, John Arbash Meinel
Bring the fixup_new_roots code from the nested-trees code.
282
        transform.delete_contents(root)
283
        transform.unversion_file(root)
284
        transform.fixup_new_roots()
285
        transform.apply()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
286
        self.assertEqual(b'new-root-id', self.wt.path2id(''))
6855.4.1 by Jelmer Vernooij
Yet more bees.
287
        self.assertEqual(b'new-file-id', self.wt.path2id('file'))
6973.10.1 by Jelmer Vernooij
Fix some tests.
288
        self.assertFileEqual(b'new-contents\n', self.wt.abspath('file'))
4634.122.2 by Aaron Bentley, John Arbash Meinel
Bring the fixup_new_roots code from the nested-trees code.
289
290
    def test_add_two_roots(self):
291
        transform, root = self.get_transform()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
292
        transform.new_directory('', ROOT_PARENT, b'new-root-id')
293
        transform.new_directory('', ROOT_PARENT, b'alt-root-id')
4634.122.2 by Aaron Bentley, John Arbash Meinel
Bring the fixup_new_roots code from the nested-trees code.
294
        self.assertRaises(ValueError, transform.fixup_new_roots)
295
6011.1.1 by Aaron Bentley
Merging an unrelated tree retains root.
296
    def test_retain_existing_root(self):
297
        tt, root = self.get_transform()
298
        with tt:
6855.4.1 by Jelmer Vernooij
Yet more bees.
299
            tt.new_directory('', ROOT_PARENT, b'new-root-id')
6011.1.1 by Aaron Bentley
Merging an unrelated tree retains root.
300
            tt.fixup_new_roots()
6855.4.1 by Jelmer Vernooij
Yet more bees.
301
            self.assertNotEqual(b'new-root-id', tt.final_file_id(tt.root))
6011.1.1 by Aaron Bentley
Merging an unrelated tree retains root.
302
303
    def test_retain_existing_root_added_file(self):
304
        tt, root = self.get_transform()
6855.4.1 by Jelmer Vernooij
Yet more bees.
305
        new_trans_id = tt.new_directory('', ROOT_PARENT, b'new-root-id')
306
        child = tt.new_directory('child', new_trans_id, b'child-id')
6011.1.1 by Aaron Bentley
Merging an unrelated tree retains root.
307
        tt.fixup_new_roots()
308
        self.assertEqual(tt.root, tt.final_parent(child))
309
5954.4.7 by Aaron Bentley
Add test for unversioned roots.
310
    def test_add_unversioned_root(self):
311
        transform, root = self.get_transform()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
312
        transform.new_directory('', ROOT_PARENT, None)
6011.1.1 by Aaron Bentley
Merging an unrelated tree retains root.
313
        transform.delete_contents(transform.root)
5954.4.7 by Aaron Bentley
Add test for unversioned roots.
314
        transform.fixup_new_roots()
5954.4.11 by Aaron Bentley
Eschew testtools.testcase.ExpectedException from too-new testtools.
315
        self.assertNotIn(transform.root, transform._new_id)
5954.4.7 by Aaron Bentley
Add test for unversioned roots.
316
5993.2.3 by Jelmer Vernooij
Update NEWS, consistently use require_tree_root as argument everywhere.
317
    def test_remove_root_fixup(self):
318
        transform, root = self.get_transform()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
319
        old_root_id = self.wt.path2id('')
6855.4.1 by Jelmer Vernooij
Yet more bees.
320
        self.assertNotEqual(b'new-root-id', old_root_id)
5993.2.3 by Jelmer Vernooij
Update NEWS, consistently use require_tree_root as argument everywhere.
321
        transform.delete_contents(root)
322
        transform.unversion_file(root)
5993.2.4 by Jelmer Vernooij
Remove feature flag.
323
        transform.fixup_new_roots()
5993.2.3 by Jelmer Vernooij
Update NEWS, consistently use require_tree_root as argument everywhere.
324
        transform.apply()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
325
        self.assertEqual(old_root_id, self.wt.path2id(''))
5993.2.3 by Jelmer Vernooij
Update NEWS, consistently use require_tree_root as argument everywhere.
326
327
        transform, root = self.get_transform()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
328
        transform.new_directory('', ROOT_PARENT, b'new-root-id')
329
        transform.new_directory('', ROOT_PARENT, b'alt-root-id')
5993.2.3 by Jelmer Vernooij
Update NEWS, consistently use require_tree_root as argument everywhere.
330
        self.assertRaises(ValueError, transform.fixup_new_roots)
331
6024.1.1 by Aaron Bentley
Move empty-tree prevention into TreeTransform.apply.
332
    def test_fixup_new_roots_permits_empty_tree(self):
333
        transform, root = self.get_transform()
334
        transform.delete_contents(root)
335
        transform.unversion_file(root)
336
        transform.fixup_new_roots()
337
        self.assertIs(None, transform.final_kind(root))
338
        self.assertIs(None, transform.final_file_id(root))
339
5954.4.1 by Aaron Bentley
Never attempt to delete the tree root.
340
    def test_apply_retains_root_directory(self):
341
        # Do not attempt to delete the physical root directory, because that
342
        # is impossible.
343
        transform, root = self.get_transform()
344
        with transform:
345
            transform.delete_contents(root)
5954.4.12 by Aaron Bentley
Eschew more ExpectedException.
346
            e = self.assertRaises(AssertionError, self.assertRaises,
347
                                  errors.TransformRenameFailed,
348
                                  transform.apply)
349
        self.assertContainsRe('TransformRenameFailed not raised', str(e))
5954.4.1 by Aaron Bentley
Never attempt to delete the tree root.
350
6024.1.1 by Aaron Bentley
Move empty-tree prevention into TreeTransform.apply.
351
    def test_apply_retains_file_id(self):
352
        transform, root = self.get_transform()
353
        old_root_id = transform.tree_file_id(root)
354
        transform.unversion_file(root)
355
        transform.apply()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
356
        self.assertEqual(old_root_id, self.wt.path2id(''))
6024.1.1 by Aaron Bentley
Move empty-tree prevention into TreeTransform.apply.
357
3136.1.1 by Aaron Bentley
Add support for hardlinks to TreeTransform
358
    def test_hardlink(self):
359
        self.requireFeature(HardlinkFeature)
360
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
361
        transform.new_file('file1', root, [b'contents'])
3136.1.1 by Aaron Bentley
Add support for hardlinks to TreeTransform
362
        transform.apply()
363
        target = self.make_branch_and_tree('target')
364
        target_transform = TreeTransform(target)
365
        trans_id = target_transform.create_path('file1', target_transform.root)
366
        target_transform.create_hardlink(self.wt.abspath('file1'), trans_id)
367
        target_transform.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
368
        self.assertPathExists('target/file1')
3136.1.1 by Aaron Bentley
Add support for hardlinks to TreeTransform
369
        source_stat = os.stat(self.wt.abspath('file1'))
370
        target_stat = os.stat('target/file1')
371
        self.assertEqual(source_stat, target_stat)
372
1534.7.2 by Aaron Bentley
Added convenience function
373
    def test_convenience(self):
1534.7.59 by Aaron Bentley
Simplified tests
374
        transform, root = self.get_transform()
3034.2.1 by Aaron Bentley
Fix is_executable tests for win32
375
        self.wt.lock_tree_write()
376
        self.addCleanup(self.wt.unlock)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
377
        transform.new_file('name', root, [b'contents'], b'my_pretties', True)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
378
        oz = transform.new_directory('oz', root, b'oz-id')
6973.10.1 by Jelmer Vernooij
Fix some tests.
379
        dorothy = transform.new_directory('dorothy', oz, b'dorothy-id')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
380
        transform.new_file('toto', dorothy, [b'toto-contents'], b'toto-id',
381
                           False)
1534.7.59 by Aaron Bentley
Simplified tests
382
383
        self.assertEqual(len(transform.find_conflicts()), 0)
384
        transform.apply()
385
        self.assertRaises(ReusingTransform, transform.find_conflicts)
6973.7.5 by Jelmer Vernooij
s/file/open.
386
        with open(self.wt.abspath('name'), 'r') as f:
387
            self.assertEqual('contents', f.read())
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
388
        self.assertEqual(self.wt.path2id('name'), b'my_pretties')
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
389
        self.assertIs(self.wt.is_executable('name'), True)
6973.10.1 by Jelmer Vernooij
Fix some tests.
390
        self.assertEqual(self.wt.path2id('oz'), b'oz-id')
391
        self.assertEqual(self.wt.path2id('oz/dorothy'), b'dorothy-id')
392
        self.assertEqual(self.wt.path2id('oz/dorothy/toto'), b'toto-id')
1534.7.59 by Aaron Bentley
Simplified tests
393
6973.10.1 by Jelmer Vernooij
Fix some tests.
394
        self.assertEqual(b'toto-contents',
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
395
                         self.wt.get_file('oz/dorothy/toto').read())
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
396
        self.assertIs(self.wt.is_executable('oz/dorothy/toto'), False)
1534.7.6 by Aaron Bentley
Added conflict handling
397
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
398
    def test_tree_reference(self):
399
        transform, root = self.get_transform()
400
        tree = transform._tree
6973.13.2 by Jelmer Vernooij
Fix some more tests.
401
        trans_id = transform.new_directory('reference', root, b'subtree-id')
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
402
        transform.set_tree_reference(b'subtree-revision', trans_id)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
403
        transform.apply()
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
404
        tree.lock_read()
405
        self.addCleanup(tree.unlock)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
406
        self.assertEqual(
407
            b'subtree-revision',
408
            tree.root_inventory.get_entry(b'subtree-id').reference_revision)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
409
1534.7.6 by Aaron Bentley
Added conflict handling
410
    def test_conflicts(self):
1534.7.59 by Aaron Bentley
Simplified tests
411
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
412
        trans_id = transform.new_file('name', root, [b'contents'],
413
                                      b'my_pretties')
1534.7.59 by Aaron Bentley
Simplified tests
414
        self.assertEqual(len(transform.find_conflicts()), 0)
6973.10.1 by Jelmer Vernooij
Fix some tests.
415
        trans_id2 = transform.new_file('name', root, [b'Crontents'], b'toto')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
416
        self.assertEqual(transform.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
417
                         [('duplicate', trans_id, trans_id2, 'name')])
418
        self.assertRaises(MalformedTransform, transform.apply)
419
        transform.adjust_path('name', trans_id, trans_id2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
420
        self.assertEqual(transform.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
421
                         [('non-directory parent', trans_id)])
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
422
        tinman_id = transform.trans_id_tree_path('tinman')
1534.7.59 by Aaron Bentley
Simplified tests
423
        transform.adjust_path('name', tinman_id, trans_id2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
424
        self.assertEqual(transform.find_conflicts(),
425
                         [('unversioned parent', tinman_id),
1534.7.59 by Aaron Bentley
Simplified tests
426
                          ('missing parent', tinman_id)])
427
        lion_id = transform.create_path('lion', root)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
428
        self.assertEqual(transform.find_conflicts(),
429
                         [('unversioned parent', tinman_id),
1534.7.59 by Aaron Bentley
Simplified tests
430
                          ('missing parent', tinman_id)])
431
        transform.adjust_path('name', lion_id, trans_id2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
432
        self.assertEqual(transform.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
433
                         [('unversioned parent', lion_id),
434
                          ('missing parent', lion_id)])
7045.2.12 by Jelmer Vernooij
Fix some mail client tests.
435
        transform.version_file(b"Courage", lion_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
436
        self.assertEqual(transform.find_conflicts(),
437
                         [('missing parent', lion_id),
1534.7.59 by Aaron Bentley
Simplified tests
438
                          ('versioning no contents', lion_id)])
439
        transform.adjust_path('name2', root, trans_id2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
440
        self.assertEqual(transform.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
441
                         [('versioning no contents', lion_id)])
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
442
        transform.create_file([b'Contents, okay?'], lion_id)
1534.7.59 by Aaron Bentley
Simplified tests
443
        transform.adjust_path('name2', trans_id2, trans_id2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
444
        self.assertEqual(transform.find_conflicts(),
445
                         [('parent loop', trans_id2),
1534.7.59 by Aaron Bentley
Simplified tests
446
                          ('non-directory parent', trans_id2)])
447
        transform.adjust_path('name2', root, trans_id2)
448
        oz_id = transform.new_directory('oz', root)
449
        transform.set_executability(True, oz_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
450
        self.assertEqual(transform.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
451
                         [('unversioned executability', oz_id)])
6973.10.1 by Jelmer Vernooij
Fix some tests.
452
        transform.version_file(b'oz-id', oz_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
453
        self.assertEqual(transform.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
454
                         [('non-file executability', oz_id)])
455
        transform.set_executability(None, oz_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
456
        tip_id = transform.new_file('tip', oz_id, [b'ozma'], b'tip-id')
1534.7.59 by Aaron Bentley
Simplified tests
457
        transform.apply()
6973.10.1 by Jelmer Vernooij
Fix some tests.
458
        self.assertEqual(self.wt.path2id('name'), b'my_pretties')
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
459
        with open(self.wt.abspath('name'), 'rb') as f:
6973.10.1 by Jelmer Vernooij
Fix some tests.
460
            self.assertEqual(b'contents', f.read())
1534.7.59 by Aaron Bentley
Simplified tests
461
        transform2, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
462
        oz_id = transform2.trans_id_tree_path('oz')
6973.10.1 by Jelmer Vernooij
Fix some tests.
463
        newtip = transform2.new_file('tip', oz_id, [b'other'], b'tip-id')
1534.7.59 by Aaron Bentley
Simplified tests
464
        result = transform2.find_conflicts()
1534.7.135 by Aaron Bentley
Fixed deletion handling
465
        fp = FinalPaths(transform2)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
466
        self.assertTrue('oz/tip' in transform2._tree_path_ids)
1534.7.176 by abentley
Fixed up tests for Windows
467
        self.assertEqual(fp.get_path(newtip), pathjoin('oz', 'tip'))
1534.7.59 by Aaron Bentley
Simplified tests
468
        self.assertEqual(len(result), 2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
469
        self.assertEqual((result[0][0], result[0][1]),
1534.7.59 by Aaron Bentley
Simplified tests
470
                         ('duplicate', newtip))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
471
        self.assertEqual((result[1][0], result[1][2]),
1534.7.59 by Aaron Bentley
Simplified tests
472
                         ('duplicate id', newtip))
1534.7.73 by Aaron Bentley
Changed model again. Now iterator is used immediately.
473
        transform2.finalize()
1534.7.59 by Aaron Bentley
Simplified tests
474
        transform3 = TreeTransform(self.wt)
475
        self.addCleanup(transform3.finalize)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
476
        oz_id = transform3.trans_id_tree_path('oz')
1534.7.59 by Aaron Bentley
Simplified tests
477
        transform3.delete_contents(oz_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
478
        self.assertEqual(transform3.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
479
                         [('missing parent', oz_id)])
1731.1.33 by Aaron Bentley
Revert no-special-root changes
480
        root_id = transform3.root
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
481
        tip_id = transform3.trans_id_tree_path('oz/tip')
1534.7.59 by Aaron Bentley
Simplified tests
482
        transform3.adjust_path('tip', root_id, tip_id)
483
        transform3.apply()
1534.7.36 by Aaron Bentley
Added rename tests
484
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
485
    def test_conflict_on_case_insensitive(self):
486
        tree = self.make_branch_and_tree('tree')
487
        # Don't try this at home, kids!
488
        # Force the tree to report that it is case sensitive, for conflict
489
        # resolution tests
490
        tree.case_sensitive = True
491
        transform = TreeTransform(tree)
492
        self.addCleanup(transform.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
493
        transform.new_file('file', transform.root, [b'content'])
494
        transform.new_file('FiLe', transform.root, [b'content'])
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
495
        result = transform.find_conflicts()
496
        self.assertEqual([], result)
3008.1.15 by Aaron Bentley
Make case_sensitive an aspect of the transform, not the source tree
497
        transform.finalize()
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
498
        # Force the tree to report that it is case insensitive, for conflict
499
        # generation tests
500
        tree.case_sensitive = False
3008.1.15 by Aaron Bentley
Make case_sensitive an aspect of the transform, not the source tree
501
        transform = TreeTransform(tree)
502
        self.addCleanup(transform.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
503
        transform.new_file('file', transform.root, [b'content'])
504
        transform.new_file('FiLe', transform.root, [b'content'])
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
505
        result = transform.find_conflicts()
506
        self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
507
3034.4.7 by Aaron Bentley
Add test for filename conflicts with existing files
508
    def test_conflict_on_case_insensitive_existing(self):
509
        tree = self.make_branch_and_tree('tree')
510
        self.build_tree(['tree/FiLe'])
511
        # Don't try this at home, kids!
512
        # Force the tree to report that it is case sensitive, for conflict
513
        # resolution tests
514
        tree.case_sensitive = True
515
        transform = TreeTransform(tree)
516
        self.addCleanup(transform.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
517
        transform.new_file('file', transform.root, [b'content'])
3034.4.7 by Aaron Bentley
Add test for filename conflicts with existing files
518
        result = transform.find_conflicts()
519
        self.assertEqual([], result)
3008.1.15 by Aaron Bentley
Make case_sensitive an aspect of the transform, not the source tree
520
        transform.finalize()
3034.4.7 by Aaron Bentley
Add test for filename conflicts with existing files
521
        # Force the tree to report that it is case insensitive, for conflict
522
        # generation tests
523
        tree.case_sensitive = False
3008.1.15 by Aaron Bentley
Make case_sensitive an aspect of the transform, not the source tree
524
        transform = TreeTransform(tree)
525
        self.addCleanup(transform.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
526
        transform.new_file('file', transform.root, [b'content'])
3034.4.7 by Aaron Bentley
Add test for filename conflicts with existing files
527
        result = transform.find_conflicts()
528
        self.assertEqual([('duplicate', 'new-1', 'new-2', 'file')], result)
529
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
530
    def test_resolve_case_insensitive_conflict(self):
531
        tree = self.make_branch_and_tree('tree')
532
        # Don't try this at home, kids!
533
        # Force the tree to report that it is case insensitive, for conflict
534
        # resolution tests
535
        tree.case_sensitive = False
536
        transform = TreeTransform(tree)
537
        self.addCleanup(transform.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
538
        transform.new_file('file', transform.root, [b'content'])
539
        transform.new_file('FiLe', transform.root, [b'content'])
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
540
        resolve_conflicts(transform)
541
        transform.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
542
        self.assertPathExists('tree/file')
543
        self.assertPathExists('tree/FiLe.moved')
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
544
3034.4.2 by Aaron Bentley
Get conflict handling and case-insensitive tree creation under test
545
    def test_resolve_checkout_case_conflict(self):
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
546
        tree = self.make_branch_and_tree('tree')
547
        # Don't try this at home, kids!
548
        # Force the tree to report that it is case insensitive, for conflict
549
        # resolution tests
550
        tree.case_sensitive = False
551
        transform = TreeTransform(tree)
552
        self.addCleanup(transform.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
553
        transform.new_file('file', transform.root, [b'content'])
554
        transform.new_file('FiLe', transform.root, [b'content'])
3034.4.2 by Aaron Bentley
Get conflict handling and case-insensitive tree creation under test
555
        resolve_conflicts(transform,
556
                          pass_func=lambda t, c: resolve_checkout(t, c, []))
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
557
        transform.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
558
        self.assertPathExists('tree/file')
559
        self.assertPathExists('tree/FiLe.moved')
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
560
3034.4.2 by Aaron Bentley
Get conflict handling and case-insensitive tree creation under test
561
    def test_apply_case_conflict(self):
3034.4.6 by Aaron Bentley
Update apply_case_conflict tests
562
        """Ensure that a transform with case conflicts can always be applied"""
3034.4.2 by Aaron Bentley
Get conflict handling and case-insensitive tree creation under test
563
        tree = self.make_branch_and_tree('tree')
564
        transform = TreeTransform(tree)
565
        self.addCleanup(transform.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
566
        transform.new_file('file', transform.root, [b'content'])
567
        transform.new_file('FiLe', transform.root, [b'content'])
3034.4.6 by Aaron Bentley
Update apply_case_conflict tests
568
        dir = transform.new_directory('dir', transform.root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
569
        transform.new_file('dirfile', dir, [b'content'])
570
        transform.new_file('dirFiLe', dir, [b'content'])
3034.4.6 by Aaron Bentley
Update apply_case_conflict tests
571
        resolve_conflicts(transform)
3034.4.2 by Aaron Bentley
Get conflict handling and case-insensitive tree creation under test
572
        transform.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
573
        self.assertPathExists('tree/file')
3034.4.3 by Aaron Bentley
Add case-sensitivity handling to WorkingTree
574
        if not os.path.exists('tree/FiLe.moved'):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
575
            self.assertPathExists('tree/FiLe')
576
        self.assertPathExists('tree/dir/dirfile')
3034.4.6 by Aaron Bentley
Update apply_case_conflict tests
577
        if not os.path.exists('tree/dir/dirFiLe.moved'):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
578
            self.assertPathExists('tree/dir/dirFiLe')
3034.4.2 by Aaron Bentley
Get conflict handling and case-insensitive tree creation under test
579
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
580
    def test_case_insensitive_limbo(self):
581
        tree = self.make_branch_and_tree('tree')
582
        # Don't try this at home, kids!
583
        # Force the tree to report that it is case insensitive
584
        tree.case_sensitive = False
585
        transform = TreeTransform(tree)
586
        self.addCleanup(transform.finalize)
587
        dir = transform.new_directory('dir', transform.root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
588
        first = transform.new_file('file', dir, [b'content'])
589
        second = transform.new_file('FiLe', dir, [b'content'])
3034.4.1 by Aaron Bentley
Start handling case-insensitivity
590
        self.assertContainsRe(transform._limbo_name(first), 'new-1/file')
591
        self.assertNotContainsRe(transform._limbo_name(second), 'new-1/FiLe')
592
4634.78.1 by Aaron Bentley
adjust_path updatest limbo paths.
593
    def test_adjust_path_updates_child_limbo_names(self):
594
        tree = self.make_branch_and_tree('tree')
595
        transform = TreeTransform(tree)
596
        self.addCleanup(transform.finalize)
597
        foo_id = transform.new_directory('foo', transform.root)
598
        bar_id = transform.new_directory('bar', foo_id)
599
        baz_id = transform.new_directory('baz', bar_id)
600
        qux_id = transform.new_directory('qux', baz_id)
601
        transform.adjust_path('quxx', foo_id, bar_id)
602
        self.assertStartsWith(transform._limbo_name(qux_id),
603
                              transform._limbo_name(bar_id))
604
1558.7.11 by Aaron Bentley
Avoid spurious conflict on add/delete
605
    def test_add_del(self):
606
        start, root = self.get_transform()
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
607
        start.new_directory('a', root, b'a')
1558.7.11 by Aaron Bentley
Avoid spurious conflict on add/delete
608
        start.apply()
609
        transform, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
610
        transform.delete_versioned(transform.trans_id_tree_path('a'))
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
611
        transform.new_directory('a', root, b'a')
1558.7.11 by Aaron Bentley
Avoid spurious conflict on add/delete
612
        transform.apply()
613
1534.7.46 by Aaron Bentley
Ensured a conflict when parents of versioned files are unversioned
614
    def test_unversioning(self):
1534.7.59 by Aaron Bentley
Simplified tests
615
        create_tree, root = self.get_transform()
6855.4.1 by Jelmer Vernooij
Yet more bees.
616
        parent_id = create_tree.new_directory('parent', root, b'parent-id')
6973.10.1 by Jelmer Vernooij
Fix some tests.
617
        create_tree.new_file('child', parent_id, [b'child'], b'child-id')
1534.7.59 by Aaron Bentley
Simplified tests
618
        create_tree.apply()
619
        unversion = TreeTransform(self.wt)
620
        self.addCleanup(unversion.finalize)
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
621
        parent = unversion.trans_id_tree_path('parent')
1534.7.59 by Aaron Bentley
Simplified tests
622
        unversion.unversion_file(parent)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
623
        self.assertEqual(unversion.find_conflicts(),
1534.7.59 by Aaron Bentley
Simplified tests
624
                         [('unversioned parent', parent_id)])
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
625
        file_id = unversion.trans_id_tree_path('parent/child')
1534.7.59 by Aaron Bentley
Simplified tests
626
        unversion.unversion_file(file_id)
627
        unversion.apply()
1534.7.46 by Aaron Bentley
Ensured a conflict when parents of versioned files are unversioned
628
1534.7.36 by Aaron Bentley
Added rename tests
629
    def test_name_invariants(self):
1534.7.59 by Aaron Bentley
Simplified tests
630
        create_tree, root = self.get_transform()
631
        # prepare tree
1731.1.33 by Aaron Bentley
Revert no-special-root changes
632
        root = create_tree.root
6973.10.1 by Jelmer Vernooij
Fix some tests.
633
        create_tree.new_file('name1', root, [b'hello1'], b'name1')
634
        create_tree.new_file('name2', root, [b'hello2'], b'name2')
635
        ddir = create_tree.new_directory('dying_directory', root, b'ddir')
636
        create_tree.new_file('dying_file', ddir, [b'goodbye1'], b'dfile')
637
        create_tree.new_file('moving_file', ddir, [b'later1'], b'mfile')
638
        create_tree.new_file('moving_file2', root, [b'later2'], b'mfile2')
1534.7.59 by Aaron Bentley
Simplified tests
639
        create_tree.apply()
640
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
641
        mangle_tree, root = self.get_transform()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
642
        root = mangle_tree.root
7143.15.2 by Jelmer Vernooij
Run autopep8.
643
        # swap names
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
644
        name1 = mangle_tree.trans_id_tree_path('name1')
645
        name2 = mangle_tree.trans_id_tree_path('name2')
1534.7.59 by Aaron Bentley
Simplified tests
646
        mangle_tree.adjust_path('name2', root, name1)
647
        mangle_tree.adjust_path('name1', root, name2)
648
7143.15.2 by Jelmer Vernooij
Run autopep8.
649
        # tests for deleting parent directories
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
650
        ddir = mangle_tree.trans_id_tree_path('dying_directory')
1534.7.59 by Aaron Bentley
Simplified tests
651
        mangle_tree.delete_contents(ddir)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
652
        dfile = mangle_tree.trans_id_tree_path('dying_directory/dying_file')
1534.7.59 by Aaron Bentley
Simplified tests
653
        mangle_tree.delete_versioned(dfile)
654
        mangle_tree.unversion_file(dfile)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
655
        mfile = mangle_tree.trans_id_tree_path('dying_directory/moving_file')
1534.7.59 by Aaron Bentley
Simplified tests
656
        mangle_tree.adjust_path('mfile', root, mfile)
657
7143.15.2 by Jelmer Vernooij
Run autopep8.
658
        # tests for adding parent directories
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
659
        newdir = mangle_tree.new_directory('new_directory', root, b'newdir')
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
660
        mfile2 = mangle_tree.trans_id_tree_path('moving_file2')
1534.7.59 by Aaron Bentley
Simplified tests
661
        mangle_tree.adjust_path('mfile2', newdir, mfile2)
6973.10.1 by Jelmer Vernooij
Fix some tests.
662
        mangle_tree.new_file('newfile', newdir, [b'hello3'], b'dfile')
663
        self.assertEqual(mangle_tree.final_file_id(mfile2), b'mfile2')
1534.7.59 by Aaron Bentley
Simplified tests
664
        self.assertEqual(mangle_tree.final_parent(mfile2), newdir)
6973.10.1 by Jelmer Vernooij
Fix some tests.
665
        self.assertEqual(mangle_tree.final_file_id(mfile2), b'mfile2')
1534.7.59 by Aaron Bentley
Simplified tests
666
        mangle_tree.apply()
6973.7.5 by Jelmer Vernooij
s/file/open.
667
        with open(self.wt.abspath('name1'), 'r') as f:
668
            self.assertEqual(f.read(), 'hello2')
669
        with open(self.wt.abspath('name2'), 'r') as f:
670
            self.assertEqual(f.read(), 'hello1')
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
671
        mfile2_path = self.wt.abspath(pathjoin('new_directory', 'mfile2'))
1534.7.41 by Aaron Bentley
Got inventory ID movement working
672
        self.assertEqual(mangle_tree.final_parent(mfile2), newdir)
6973.7.5 by Jelmer Vernooij
s/file/open.
673
        with open(mfile2_path, 'r') as f:
674
            self.assertEqual(f.read(), 'later2')
6855.4.1 by Jelmer Vernooij
Yet more bees.
675
        self.assertEqual(self.wt.id2path(b'mfile2'), 'new_directory/mfile2')
676
        self.assertEqual(self.wt.path2id('new_directory/mfile2'), b'mfile2')
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
677
        newfile_path = self.wt.abspath(pathjoin('new_directory', 'newfile'))
6973.7.5 by Jelmer Vernooij
s/file/open.
678
        with open(newfile_path, 'r') as f:
679
            self.assertEqual(f.read(), 'hello3')
6855.4.1 by Jelmer Vernooij
Yet more bees.
680
        self.assertEqual(self.wt.path2id('dying_directory'), b'ddir')
1534.7.59 by Aaron Bentley
Simplified tests
681
        self.assertIs(self.wt.path2id('dying_directory/dying_file'), None)
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
682
        mfile2_path = self.wt.abspath(pathjoin('new_directory', 'mfile2'))
1534.7.43 by abentley
Fixed some Windows bugs, introduced a conflicts bug
683
1534.7.150 by Aaron Bentley
Handled simultaneous renames of parent and child better
684
    def test_both_rename(self):
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
685
        create_tree, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
686
        newdir = create_tree.new_directory('selftest', root, b'selftest-id')
7143.15.2 by Jelmer Vernooij
Run autopep8.
687
        create_tree.new_file('blackbox.py', newdir, [
688
                             b'hello1'], b'blackbox-id')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
689
        create_tree.apply()
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
690
        mangle_tree, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
691
        selftest = mangle_tree.trans_id_tree_path('selftest')
692
        blackbox = mangle_tree.trans_id_tree_path('selftest/blackbox.py')
1534.7.150 by Aaron Bentley
Handled simultaneous renames of parent and child better
693
        mangle_tree.adjust_path('test', root, selftest)
694
        mangle_tree.adjust_path('test_too_much', root, selftest)
695
        mangle_tree.set_executability(True, blackbox)
696
        mangle_tree.apply()
697
698
    def test_both_rename2(self):
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
699
        create_tree, root = self.get_transform()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
700
        breezy = create_tree.new_directory('breezy', root, b'breezy-id')
701
        tests = create_tree.new_directory('tests', breezy, b'tests-id')
702
        blackbox = create_tree.new_directory('blackbox', tests, b'blackbox-id')
6973.10.1 by Jelmer Vernooij
Fix some tests.
703
        create_tree.new_file('test_too_much.py', blackbox, [b'hello1'],
704
                             b'test_too_much-id')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
705
        create_tree.apply()
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
706
        mangle_tree, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
707
        breezy = mangle_tree.trans_id_tree_path('breezy')
708
        tests = mangle_tree.trans_id_tree_path('breezy/tests')
7143.15.2 by Jelmer Vernooij
Run autopep8.
709
        test_too_much = mangle_tree.trans_id_tree_path(
710
            'breezy/tests/blackbox/test_too_much.py')
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
711
        mangle_tree.adjust_path('selftest', breezy, tests)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
712
        mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
1534.7.150 by Aaron Bentley
Handled simultaneous renames of parent and child better
713
        mangle_tree.set_executability(True, test_too_much)
714
        mangle_tree.apply()
715
716
    def test_both_rename3(self):
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
717
        create_tree, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
718
        tests = create_tree.new_directory('tests', root, b'tests-id')
719
        create_tree.new_file('test_too_much.py', tests, [b'hello1'],
720
                             b'test_too_much-id')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
721
        create_tree.apply()
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
722
        mangle_tree, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
723
        tests = mangle_tree.trans_id_tree_path('tests')
7143.15.2 by Jelmer Vernooij
Run autopep8.
724
        test_too_much = mangle_tree.trans_id_tree_path(
725
            'tests/test_too_much.py')
1534.7.150 by Aaron Bentley
Handled simultaneous renames of parent and child better
726
        mangle_tree.adjust_path('selftest', root, tests)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
727
        mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
1534.7.150 by Aaron Bentley
Handled simultaneous renames of parent and child better
728
        mangle_tree.set_executability(True, test_too_much)
729
        mangle_tree.apply()
730
1534.7.48 by Aaron Bentley
Ensured we can move/rename dangling inventory entries
731
    def test_move_dangling_ie(self):
1534.7.59 by Aaron Bentley
Simplified tests
732
        create_tree, root = self.get_transform()
733
        # prepare tree
1731.1.33 by Aaron Bentley
Revert no-special-root changes
734
        root = create_tree.root
6973.10.1 by Jelmer Vernooij
Fix some tests.
735
        create_tree.new_file('name1', root, [b'hello1'], b'name1')
1534.7.59 by Aaron Bentley
Simplified tests
736
        create_tree.apply()
737
        delete_contents, root = self.get_transform()
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
738
        file = delete_contents.trans_id_tree_path('name1')
1534.7.59 by Aaron Bentley
Simplified tests
739
        delete_contents.delete_contents(file)
740
        delete_contents.apply()
741
        move_id, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
742
        name1 = move_id.trans_id_tree_path('name1')
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
743
        newdir = move_id.new_directory('dir', root, b'newdir')
1534.7.59 by Aaron Bentley
Simplified tests
744
        move_id.adjust_path('name2', newdir, name1)
745
        move_id.apply()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
746
1534.7.50 by Aaron Bentley
Detect duplicate inventory ids
747
    def test_replace_dangling_ie(self):
1534.7.59 by Aaron Bentley
Simplified tests
748
        create_tree, root = self.get_transform()
749
        # prepare tree
1731.1.33 by Aaron Bentley
Revert no-special-root changes
750
        root = create_tree.root
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
751
        create_tree.new_file('name1', root, [b'hello1'], b'name1')
1534.7.59 by Aaron Bentley
Simplified tests
752
        create_tree.apply()
753
        delete_contents = TreeTransform(self.wt)
754
        self.addCleanup(delete_contents.finalize)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
755
        file = delete_contents.trans_id_tree_path('name1')
1534.7.59 by Aaron Bentley
Simplified tests
756
        delete_contents.delete_contents(file)
757
        delete_contents.apply()
758
        delete_contents.finalize()
759
        replace = TreeTransform(self.wt)
760
        self.addCleanup(replace.finalize)
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
761
        name2 = replace.new_file('name2', root, [b'hello2'], b'name1')
1534.7.59 by Aaron Bentley
Simplified tests
762
        conflicts = replace.find_conflicts()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
763
        name1 = replace.trans_id_tree_path('name1')
1534.7.59 by Aaron Bentley
Simplified tests
764
        self.assertEqual(conflicts, [('duplicate id', name1, name2)])
765
        resolve_conflicts(replace)
766
        replace.apply()
1534.7.48 by Aaron Bentley
Ensured we can move/rename dangling inventory entries
767
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
768
    def _test_symlinks(self, link_name1, link_target1,
4241.14.17 by Vincent Ladeuil
Add more tests for unicode symlinks to test_transform.
769
                       link_name2, link_target2):
770
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
771
        def ozpath(p):
772
            return 'oz/' + p
4241.14.17 by Vincent Ladeuil
Add more tests for unicode symlinks to test_transform.
773
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
774
        self.requireFeature(SymlinkFeature)
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
775
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
776
        oz_id = transform.new_directory('oz', root, b'oz-id')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
777
        transform.new_symlink(link_name1, oz_id, link_target1, b'wizard-id')
4241.14.17 by Vincent Ladeuil
Add more tests for unicode symlinks to test_transform.
778
        wiz_id = transform.create_path(link_name2, oz_id)
779
        transform.create_symlink(link_target2, wiz_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
780
        transform.version_file(b'wiz-id2', wiz_id)
1534.7.71 by abentley
All tests pass under Windows
781
        transform.set_executability(True, wiz_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
782
        self.assertEqual(transform.find_conflicts(),
1534.7.71 by abentley
All tests pass under Windows
783
                         [('non-file executability', wiz_id)])
784
        transform.set_executability(None, wiz_id)
1534.7.59 by Aaron Bentley
Simplified tests
785
        transform.apply()
6973.10.1 by Jelmer Vernooij
Fix some tests.
786
        self.assertEqual(self.wt.path2id(ozpath(link_name1)), b'wizard-id')
4241.14.17 by Vincent Ladeuil
Add more tests for unicode symlinks to test_transform.
787
        self.assertEqual('symlink',
788
                         file_kind(self.wt.abspath(ozpath(link_name1))))
789
        self.assertEqual(link_target2,
790
                         osutils.readlink(self.wt.abspath(ozpath(link_name2))))
791
        self.assertEqual(link_target1,
792
                         osutils.readlink(self.wt.abspath(ozpath(link_name1))))
793
794
    def test_symlinks(self):
795
        self._test_symlinks('wizard', 'wizard-target',
796
                            'wizard2', 'behind_curtain')
797
798
    def test_symlinks_unicode(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
799
        self.requireFeature(features.UnicodeFilenameFeature)
4241.14.17 by Vincent Ladeuil
Add more tests for unicode symlinks to test_transform.
800
        self._test_symlinks(u'\N{Euro Sign}wizard',
801
                            u'wizard-targ\N{Euro Sign}t',
802
                            u'\N{Euro Sign}wizard2',
803
                            u'b\N{Euro Sign}hind_curtain')
1534.7.60 by Aaron Bentley
Tested existing conflict resolution functionality
804
6469.1.8 by Parth Malwankar
test to ensure no conflicts when symlinks are unsupported
805
    def test_unsupported_symlink_no_conflict(self):
3006.2.2 by Alexander Belchenko
tests added.
806
        def tt_helper():
807
            wt = self.make_branch_and_tree('.')
6469.1.8 by Parth Malwankar
test to ensure no conflicts when symlinks are unsupported
808
            tt = TreeTransform(wt)
809
            self.addCleanup(tt.finalize)
810
            tt.new_symlink('foo', tt.root, 'bar')
811
            result = tt.find_conflicts()
812
            self.assertEqual([], result)
3006.2.2 by Alexander Belchenko
tests added.
813
        os_symlink = getattr(os, 'symlink', None)
814
        os.symlink = None
815
        try:
6469.1.8 by Parth Malwankar
test to ensure no conflicts when symlinks are unsupported
816
            tt_helper()
3006.2.2 by Alexander Belchenko
tests added.
817
        finally:
818
            if os_symlink:
819
                os.symlink = os_symlink
820
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
821
    def get_conflicted(self):
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
822
        create, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
823
        create.new_file('dorothy', root, [b'dorothy'], b'dorothy-id')
824
        oz = create.new_directory('oz', root, b'oz-id')
825
        create.new_directory('emeraldcity', oz, b'emerald-id')
1534.7.60 by Aaron Bentley
Tested existing conflict resolution functionality
826
        create.apply()
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
827
        conflicts, root = self.get_transform()
1534.7.65 by Aaron Bentley
Text cleaup/docs
828
        # set up duplicate entry, duplicate id
6973.10.1 by Jelmer Vernooij
Fix some tests.
829
        new_dorothy = conflicts.new_file('dorothy', root, [b'dorothy'],
830
                                         b'dorothy-id')
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
831
        old_dorothy = conflicts.trans_id_tree_path('dorothy')
832
        oz = conflicts.trans_id_tree_path('oz')
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
833
        # set up DeletedParent parent conflict
1534.7.65 by Aaron Bentley
Text cleaup/docs
834
        conflicts.delete_versioned(oz)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
835
        emerald = conflicts.trans_id_tree_path('oz/emeraldcity')
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
836
        # set up MissingParent conflict
6973.10.1 by Jelmer Vernooij
Fix some tests.
837
        munchkincity = conflicts.trans_id_file_id(b'munchkincity-id')
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
838
        conflicts.adjust_path('munchkincity', root, munchkincity)
6973.10.1 by Jelmer Vernooij
Fix some tests.
839
        conflicts.new_directory('auntem', munchkincity, b'auntem-id')
1534.7.65 by Aaron Bentley
Text cleaup/docs
840
        # set up parent loop
1534.7.61 by Aaron Bentley
Handled parent loops, missing parents, unversioned parents
841
        conflicts.adjust_path('emeraldcity', emerald, emerald)
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
842
        return conflicts, emerald, oz, old_dorothy, new_dorothy
843
844
    def test_conflict_resolution(self):
845
        conflicts, emerald, oz, old_dorothy, new_dorothy =\
846
            self.get_conflicted()
1534.7.60 by Aaron Bentley
Tested existing conflict resolution functionality
847
        resolve_conflicts(conflicts)
848
        self.assertEqual(conflicts.final_name(old_dorothy), 'dorothy.moved')
849
        self.assertIs(conflicts.final_file_id(old_dorothy), None)
850
        self.assertEqual(conflicts.final_name(new_dorothy), 'dorothy')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
851
        self.assertEqual(conflicts.final_file_id(new_dorothy), b'dorothy-id')
1534.7.64 by Aaron Bentley
Extra testing
852
        self.assertEqual(conflicts.final_parent(emerald), oz)
1534.7.63 by Aaron Bentley
Ensure transform can be applied after resolution
853
        conflicts.apply()
1534.7.62 by Aaron Bentley
Fixed moving versioned directories
854
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
855
    def test_cook_conflicts(self):
856
        tt, emerald, oz, old_dorothy, new_dorothy = self.get_conflicted()
857
        raw_conflicts = resolve_conflicts(tt)
858
        cooked_conflicts = cook_conflicts(raw_conflicts, tt)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
859
        duplicate = DuplicateEntry('Moved existing file to', 'dorothy.moved',
6973.10.1 by Jelmer Vernooij
Fix some tests.
860
                                   'dorothy', None, b'dorothy-id')
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
861
        self.assertEqual(cooked_conflicts[0], duplicate)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
862
        duplicate_id = DuplicateID('Unversioned existing file',
1534.10.20 by Aaron Bentley
Got all tests passing
863
                                   'dorothy.moved', 'dorothy', None,
6973.10.1 by Jelmer Vernooij
Fix some tests.
864
                                   b'dorothy-id')
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
865
        self.assertEqual(cooked_conflicts[1], duplicate_id)
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
866
        missing_parent = MissingParent('Created directory', 'munchkincity',
6973.10.1 by Jelmer Vernooij
Fix some tests.
867
                                       b'munchkincity-id')
868
        deleted_parent = DeletingParent('Not deleting', 'oz', b'oz-id')
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
869
        self.assertEqual(cooked_conflicts[2], missing_parent)
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
870
        unversioned_parent = UnversionedParent('Versioned directory',
871
                                               'munchkincity',
6973.10.1 by Jelmer Vernooij
Fix some tests.
872
                                               b'munchkincity-id')
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
873
        unversioned_parent2 = UnversionedParent('Versioned directory', 'oz',
7143.15.2 by Jelmer Vernooij
Run autopep8.
874
                                                b'oz-id')
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
875
        self.assertEqual(cooked_conflicts[3], unversioned_parent)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
876
        parent_loop = ParentLoop(
877
            'Cancelled move', 'oz/emeraldcity',
878
            'oz/emeraldcity', b'emerald-id', b'emerald-id')
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
879
        self.assertEqual(cooked_conflicts[4], deleted_parent)
880
        self.assertEqual(cooked_conflicts[5], unversioned_parent2)
881
        self.assertEqual(cooked_conflicts[6], parent_loop)
882
        self.assertEqual(len(cooked_conflicts), 7)
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
883
        tt.finalize()
884
885
    def test_string_conflicts(self):
886
        tt, emerald, oz, old_dorothy, new_dorothy = self.get_conflicted()
887
        raw_conflicts = resolve_conflicts(tt)
888
        cooked_conflicts = cook_conflicts(raw_conflicts, tt)
889
        tt.finalize()
7479.2.1 by Jelmer Vernooij
Drop python2 support.
890
        conflicts_s = [str(c) for c in cooked_conflicts]
1534.7.171 by Aaron Bentley
Implemented stringifying filesystem conflicts
891
        self.assertEqual(len(cooked_conflicts), len(conflicts_s))
892
        self.assertEqual(conflicts_s[0], 'Conflict adding file dorothy.  '
893
                                         'Moved existing file to '
894
                                         'dorothy.moved.')
895
        self.assertEqual(conflicts_s[1], 'Conflict adding id to dorothy.  '
896
                                         'Unversioned existing file '
897
                                         'dorothy.moved.')
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
898
        self.assertEqual(conflicts_s[2], 'Conflict adding files to'
899
                                         ' munchkincity.  Created directory.')
900
        self.assertEqual(conflicts_s[3], 'Conflict because munchkincity is not'
901
                                         ' versioned, but has versioned'
902
                                         ' children.  Versioned directory.')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
903
        self.assertEqualDiff(
904
            conflicts_s[4], "Conflict: can't delete oz because it"
905
                            " is not empty.  Not deleting.")
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
906
        self.assertEqual(conflicts_s[5], 'Conflict because oz is not'
907
                                         ' versioned, but has versioned'
908
                                         ' children.  Versioned directory.')
909
        self.assertEqual(conflicts_s[6], 'Conflict moving oz/emeraldcity into'
4597.8.11 by Vincent Ladeuil
The ParentLoop.format has been updated, fix fallouts.
910
                                         ' oz/emeraldcity. Cancelled move.')
1534.7.170 by Aaron Bentley
Cleaned up filesystem conflict handling
911
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
912
    def prepare_wrong_parent_kind(self):
913
        tt, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
914
        tt.new_file('parent', root, [b'contents'], b'parent-id')
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
915
        tt.apply()
916
        tt, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
917
        parent_id = tt.trans_id_file_id(b'parent-id')
918
        tt.new_file('child,', parent_id, [b'contents2'], b'file-id')
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
919
        return tt
920
3144.4.1 by Aaron Bentley
Handle trying to list parents of a non-directory
921
    def test_find_conflicts_wrong_parent_kind(self):
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
922
        tt = self.prepare_wrong_parent_kind()
3144.4.1 by Aaron Bentley
Handle trying to list parents of a non-directory
923
        tt.find_conflicts()
924
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
925
    def test_resolve_conflicts_wrong_existing_parent_kind(self):
926
        tt = self.prepare_wrong_parent_kind()
927
        raw_conflicts = resolve_conflicts(tt)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
928
        self.assertEqual({('non-directory parent', 'Created directory',
7143.15.2 by Jelmer Vernooij
Run autopep8.
929
                           'new-3')}, raw_conflicts)
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
930
        cooked_conflicts = cook_conflicts(raw_conflicts, tt)
931
        self.assertEqual([NonDirectoryParent('Created directory', 'parent.new',
7143.15.2 by Jelmer Vernooij
Run autopep8.
932
                                             b'parent-id')], cooked_conflicts)
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
933
        tt.apply()
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
934
        self.assertFalse(self.wt.is_versioned('parent'))
6973.13.2 by Jelmer Vernooij
Fix some more tests.
935
        self.assertEqual(b'parent-id', self.wt.path2id('parent.new'))
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
936
937
    def test_resolve_conflicts_wrong_new_parent_kind(self):
938
        tt, root = self.get_transform()
6855.4.1 by Jelmer Vernooij
Yet more bees.
939
        parent_id = tt.new_directory('parent', root, b'parent-id')
6973.10.1 by Jelmer Vernooij
Fix some tests.
940
        tt.new_file('child,', parent_id, [b'contents2'], b'file-id')
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
941
        tt.apply()
942
        tt, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
943
        parent_id = tt.trans_id_file_id(b'parent-id')
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
944
        tt.delete_contents(parent_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
945
        tt.create_file([b'contents'], parent_id)
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
946
        raw_conflicts = resolve_conflicts(tt)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
947
        self.assertEqual({('non-directory parent', 'Created directory',
7143.15.2 by Jelmer Vernooij
Run autopep8.
948
                           'new-3')}, raw_conflicts)
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
949
        tt.apply()
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
950
        self.assertFalse(self.wt.is_versioned('parent'))
6973.10.1 by Jelmer Vernooij
Fix some tests.
951
        self.assertEqual(b'parent-id', self.wt.path2id('parent.new'))
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
952
953
    def test_resolve_conflicts_wrong_parent_kind_unversioned(self):
954
        tt, root = self.get_transform()
955
        parent_id = tt.new_directory('parent', root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
956
        tt.new_file('child,', parent_id, [b'contents2'])
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
957
        tt.apply()
958
        tt, root = self.get_transform()
959
        parent_id = tt.trans_id_tree_path('parent')
960
        tt.delete_contents(parent_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
961
        tt.create_file([b'contents'], parent_id)
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
962
        resolve_conflicts(tt)
963
        tt.apply()
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
964
        self.assertFalse(self.wt.is_versioned('parent'))
965
        self.assertFalse(self.wt.is_versioned('parent.new'))
3144.4.2 by Aaron Bentley
Handle non-directory parent conflicts (abentley, #177390)
966
5409.5.1 by Vincent Ladeuil
Tweak test_resolve_conflicts_missing_parent (renamed from test_resolve_no_parent), puttinh it in the right place.
967
    def test_resolve_conflicts_missing_parent(self):
968
        wt = self.make_branch_and_tree('.')
969
        tt = TreeTransform(wt)
970
        self.addCleanup(tt.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
971
        parent = tt.trans_id_file_id(b'parent-id')
972
        tt.new_file('file', parent, [b'Contents'])
5409.5.1 by Vincent Ladeuil
Tweak test_resolve_conflicts_missing_parent (renamed from test_resolve_no_parent), puttinh it in the right place.
973
        raw_conflicts = resolve_conflicts(tt)
5409.6.2 by Vincent Ladeuil
Fix typo in the comment.
974
        # Since the directory doesn't exist it's seen as 'missing'.  So
975
        # 'resolve_conflicts' create a conflict asking for it to be created.
5409.5.1 by Vincent Ladeuil
Tweak test_resolve_conflicts_missing_parent (renamed from test_resolve_no_parent), puttinh it in the right place.
976
        self.assertLength(1, raw_conflicts)
977
        self.assertEqual(('missing parent', 'Created directory', 'new-1'),
978
                         raw_conflicts.pop())
5409.6.1 by Vincent Ladeuil
Clarify test intent and behaviour.
979
        # apply fail since the missing directory doesn't exist
980
        self.assertRaises(errors.NoFinalPath, tt.apply)
5409.5.1 by Vincent Ladeuil
Tweak test_resolve_conflicts_missing_parent (renamed from test_resolve_no_parent), puttinh it in the right place.
981
1534.7.62 by Aaron Bentley
Fixed moving versioned directories
982
    def test_moving_versioned_directories(self):
983
        create, root = self.get_transform()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
984
        kansas = create.new_directory('kansas', root, b'kansas-id')
985
        create.new_directory('house', kansas, b'house-id')
986
        create.new_directory('oz', root, b'oz-id')
1534.7.62 by Aaron Bentley
Fixed moving versioned directories
987
        create.apply()
988
        cyclone, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
989
        oz = cyclone.trans_id_tree_path('oz')
990
        house = cyclone.trans_id_tree_path('house')
1534.7.62 by Aaron Bentley
Fixed moving versioned directories
991
        cyclone.adjust_path('house', oz, house)
992
        cyclone.apply()
1534.7.66 by Aaron Bentley
Ensured we don't accidentally move the root directory
993
994
    def test_moving_root(self):
1534.7.68 by Aaron Bentley
Got semi-reasonable root directory renaming working
995
        create, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
996
        fun = create.new_directory('fun', root, b'fun-id')
997
        create.new_directory('sun', root, b'sun-id')
998
        create.new_directory('moon', root, b'moon')
1534.7.68 by Aaron Bentley
Got semi-reasonable root directory renaming working
999
        create.apply()
1534.7.66 by Aaron Bentley
Ensured we don't accidentally move the root directory
1000
        transform, root = self.get_transform()
1534.7.68 by Aaron Bentley
Got semi-reasonable root directory renaming working
1001
        transform.adjust_root_path('oldroot', fun)
4634.122.2 by Aaron Bentley, John Arbash Meinel
Bring the fixup_new_roots code from the nested-trees code.
1002
        new_root = transform.trans_id_tree_path('')
6973.10.1 by Jelmer Vernooij
Fix some tests.
1003
        transform.version_file(b'new-root', new_root)
1534.7.68 by Aaron Bentley
Got semi-reasonable root directory renaming working
1004
        transform.apply()
1534.7.93 by Aaron Bentley
Added text merge test
1005
1534.7.114 by Aaron Bentley
Added file renaming test case
1006
    def test_renames(self):
1007
        create, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1008
        old = create.new_directory('old-parent', root, b'old-id')
1009
        intermediate = create.new_directory('intermediate', old, b'im-id')
1010
        myfile = create.new_file('myfile', intermediate, [b'myfile-text'],
1011
                                 b'myfile-id')
1534.7.114 by Aaron Bentley
Added file renaming test case
1012
        create.apply()
1013
        rename, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1014
        old = rename.trans_id_file_id(b'old-id')
1534.7.114 by Aaron Bentley
Added file renaming test case
1015
        rename.adjust_path('new', root, old)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1016
        myfile = rename.trans_id_file_id(b'myfile-id')
1534.7.114 by Aaron Bentley
Added file renaming test case
1017
        rename.set_executability(True, myfile)
1018
        rename.apply()
1019
5186.2.4 by Martin Pool
Add failing specific test for 491763
1020
    def test_rename_fails(self):
5050.43.1 by Vincent Ladeuil
Fix one more failure when the test suite is run as root.
1021
        self.requireFeature(features.not_running_as_root)
5186.2.4 by Martin Pool
Add failing specific test for 491763
1022
        # see https://bugs.launchpad.net/bzr/+bug/491763
1023
        create, root_id = self.get_transform()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1024
        create.new_directory('first-dir', root_id, b'first-id')
1025
        create.new_file('myfile', root_id, [b'myfile-text'], b'myfile-id')
5186.2.4 by Martin Pool
Add failing specific test for 491763
1026
        create.apply()
5050.15.2 by Martin
Correct bt.test_transform.TestTreeTransform.test_rename_fails on non-posix platforms
1027
        if os.name == "posix" and sys.platform != "cygwin":
1028
            # posix filesystems fail on renaming if the readonly bit is set
1029
            osutils.make_readonly(self.wt.abspath('first-dir'))
1030
        elif os.name == "nt":
1031
            # windows filesystems fail on renaming open files
6973.7.5 by Jelmer Vernooij
s/file/open.
1032
            self.addCleanup(open(self.wt.abspath('myfile')).close)
5050.15.2 by Martin
Correct bt.test_transform.TestTreeTransform.test_rename_fails on non-posix platforms
1033
        else:
6622.4.1 by Martin
Use skipTest rather than deprecated skip method
1034
            self.skipTest("Can't force a permissions error on rename")
5186.2.4 by Martin Pool
Add failing specific test for 491763
1035
        # now transform to rename
1036
        rename_transform, root_id = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1037
        file_trans_id = rename_transform.trans_id_file_id(b'myfile-id')
1038
        dir_id = rename_transform.trans_id_file_id(b'first-id')
5186.2.4 by Martin Pool
Add failing specific test for 491763
1039
        rename_transform.adjust_path('newname', dir_id, file_trans_id)
5186.2.5 by Martin Pool
Raise a specific clearer error when a rename fails inside transform
1040
        e = self.assertRaises(errors.TransformRenameFailed,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1041
                              rename_transform.apply)
1042
        # On nix looks like:
5186.2.5 by Martin Pool
Raise a specific clearer error when a rename fails inside transform
1043
        # "Failed to rename .../work/.bzr/checkout/limbo/new-1
1044
        # to .../first-dir/newname: [Errno 13] Permission denied"
5050.15.2 by Martin
Correct bt.test_transform.TestTreeTransform.test_rename_fails on non-posix platforms
1045
        # On windows looks like:
7143.15.2 by Jelmer Vernooij
Run autopep8.
1046
        # "Failed to rename .../work/myfile to
5050.15.2 by Martin
Correct bt.test_transform.TestTreeTransform.test_rename_fails on non-posix platforms
1047
        # .../work/.bzr/checkout/limbo/new-1: [Errno 13] Permission denied"
5582.8.1 by Martin
Make bt.test_transform.TestTreeTransform.test_rename_fails not care about the exact stringification of the exception instance
1048
        # This test isn't concerned with exactly what the error looks like,
1049
        # and the strerror will vary across OS and locales, but the assert
1050
        # that the exeception attributes are what we expect
1051
        self.assertEqual(e.errno, errno.EACCES)
1052
        if os.name == "posix":
1053
            self.assertEndsWith(e.to_path, "/first-dir/newname")
1054
        else:
1055
            self.assertEqual(os.path.basename(e.from_path), "myfile")
5186.2.4 by Martin Pool
Add failing specific test for 491763
1056
1740.2.4 by Aaron Bentley
Update transform tests and docs
1057
    def test_set_executability_order(self):
1058
        """Ensure that executability behaves the same, no matter what order.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1059
1740.2.4 by Aaron Bentley
Update transform tests and docs
1060
        - create file and set executability simultaneously
1061
        - create file and set executability afterward
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1062
        - unsetting the executability of a file whose executability has not
1063
          been
1740.2.4 by Aaron Bentley
Update transform tests and docs
1064
        declared should throw an exception (this may happen when a
1065
        merge attempts to create a file with a duplicate ID)
1066
        """
1067
        transform, root = self.get_transform()
1068
        wt = transform._tree
3034.2.1 by Aaron Bentley
Fix is_executable tests for win32
1069
        wt.lock_read()
1070
        self.addCleanup(wt.unlock)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1071
        transform.new_file('set_on_creation', root, [b'Set on creation'],
1072
                           b'soc', True)
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
1073
        sac = transform.new_file('set_after_creation', root,
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
1074
                                 [b'Set after creation'], b'sac')
1740.2.4 by Aaron Bentley
Update transform tests and docs
1075
        transform.set_executability(True, sac)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1076
        uws = transform.new_file('unset_without_set', root, [b'Unset badly'],
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
1077
                                 b'uws')
1740.2.4 by Aaron Bentley
Update transform tests and docs
1078
        self.assertRaises(KeyError, transform.set_executability, None, uws)
1079
        transform.apply()
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
1080
        self.assertTrue(wt.is_executable('set_on_creation'))
1081
        self.assertTrue(wt.is_executable('set_after_creation'))
1740.2.4 by Aaron Bentley
Update transform tests and docs
1082
1534.12.2 by Aaron Bentley
Added test for preserving file mode
1083
    def test_preserve_mode(self):
1084
        """File mode is preserved when replacing content"""
1085
        if sys.platform == 'win32':
1086
            raise TestSkipped('chmod has no effect on win32')
1087
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1088
        transform.new_file('file1', root, [b'contents'], b'file1-id', True)
1534.12.2 by Aaron Bentley
Added test for preserving file mode
1089
        transform.apply()
3146.4.12 by Aaron Bentley
Add needed write lock to test
1090
        self.wt.lock_write()
1091
        self.addCleanup(self.wt.unlock)
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
1092
        self.assertTrue(self.wt.is_executable('file1'))
1534.12.2 by Aaron Bentley
Added test for preserving file mode
1093
        transform, root = self.get_transform()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
1094
        file1_id = transform.trans_id_tree_path('file1')
1534.12.2 by Aaron Bentley
Added test for preserving file mode
1095
        transform.delete_contents(file1_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1096
        transform.create_file([b'contents2'], file1_id)
1534.12.2 by Aaron Bentley
Added test for preserving file mode
1097
        transform.apply()
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
1098
        self.assertTrue(self.wt.is_executable('file1'))
1534.12.2 by Aaron Bentley
Added test for preserving file mode
1099
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
1100
    def test__set_mode_stats_correctly(self):
1101
        """_set_mode stats to determine file mode."""
1102
        if sys.platform == 'win32':
1103
            raise TestSkipped('chmod has no effect on win32')
1104
1105
        stat_paths = []
1106
        real_stat = os.stat
7143.15.2 by Jelmer Vernooij
Run autopep8.
1107
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
1108
        def instrumented_stat(path):
1109
            stat_paths.append(path)
1110
            return real_stat(path)
1111
1112
        transform, root = self.get_transform()
1113
6973.10.1 by Jelmer Vernooij
Fix some tests.
1114
        bar1_id = transform.new_file('bar', root, [b'bar contents 1\n'],
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1115
                                     file_id=b'bar-id-1', executable=False)
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
1116
        transform.apply()
1117
1118
        transform, root = self.get_transform()
1119
        bar1_id = transform.trans_id_tree_path('bar')
1120
        bar2_id = transform.trans_id_tree_path('bar2')
1121
        try:
1122
            os.stat = instrumented_stat
7143.15.2 by Jelmer Vernooij
Run autopep8.
1123
            transform.create_file([b'bar2 contents\n'],
1124
                                  bar2_id, mode_id=bar1_id)
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
1125
        finally:
1126
            os.stat = real_stat
1127
            transform.finalize()
1128
1129
        bar1_abspath = self.wt.abspath('bar')
1130
        self.assertEqual([bar1_abspath], stat_paths)
1131
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1132
    def test_iter_changes(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
1133
        self.wt.set_root_id(b'eert_toor')
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1134
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1135
        transform.new_file('old', root, [b'blah'], b'id-1', True)
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1136
        transform.apply()
1137
        transform, root = self.get_transform()
1138
        try:
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1139
            self.assertEqual([], list(transform.iter_changes()))
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
1140
            old = transform.trans_id_tree_path('old')
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1141
            transform.unversion_file(old)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1142
            self.assertEqual([(b'id-1', ('old', None), False, (True, False),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1143
                               (b'eert_toor', b'eert_toor'),
1144
                               ('old', 'old'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1145
                               (True, True), False)],
1146
                             list(transform.iter_changes()))
6973.10.1 by Jelmer Vernooij
Fix some tests.
1147
            transform.new_directory('new', root, b'id-1')
1148
            self.assertEqual([(b'id-1', ('old', 'new'), True, (True, True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1149
                               (b'eert_toor', b'eert_toor'), ('old', 'new'),
1150
                               ('file', 'directory'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1151
                               (True, False), False)],
1152
                             list(transform.iter_changes()))
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1153
        finally:
1154
            transform.finalize()
1155
1156
    def test_iter_changes_new(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
1157
        self.wt.set_root_id(b'eert_toor')
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1158
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1159
        transform.new_file('old', root, [b'blah'])
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1160
        transform.apply()
1161
        transform, root = self.get_transform()
1162
        try:
1163
            old = transform.trans_id_tree_path('old')
6973.10.1 by Jelmer Vernooij
Fix some tests.
1164
            transform.version_file(b'id-1', old)
1165
            self.assertEqual([(b'id-1', (None, 'old'), False, (False, True),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1166
                               (b'eert_toor', b'eert_toor'),
1167
                               ('old', 'old'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1168
                               (False, False), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1169
                             list(transform.iter_changes()))
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1170
        finally:
1171
            transform.finalize()
1172
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1173
    def test_iter_changes_modifications(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
1174
        self.wt.set_root_id(b'eert_toor')
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1175
        transform, root = self.get_transform()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1176
        transform.new_file('old', root, [b'blah'], b'id-1')
6973.10.1 by Jelmer Vernooij
Fix some tests.
1177
        transform.new_file('new', root, [b'blah'])
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1178
        transform.new_directory('subdir', root, b'subdir-id')
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1179
        transform.apply()
1180
        transform, root = self.get_transform()
1181
        try:
1182
            old = transform.trans_id_tree_path('old')
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
1183
            subdir = transform.trans_id_tree_path('subdir')
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1184
            new = transform.trans_id_tree_path('new')
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1185
            self.assertEqual([], list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1186
7143.15.2 by Jelmer Vernooij
Run autopep8.
1187
            # content deletion
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1188
            transform.delete_contents(old)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1189
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1190
                               (b'eert_toor', b'eert_toor'),
1191
                               ('old', 'old'), ('file', None),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1192
                               (False, False), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1193
                             list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1194
7143.15.2 by Jelmer Vernooij
Run autopep8.
1195
            # content change
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1196
            transform.create_file([b'blah'], old)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1197
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1198
                               (b'eert_toor', b'eert_toor'),
1199
                               ('old', 'old'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1200
                               (False, False), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1201
                             list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1202
            transform.cancel_deletion(old)
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
1203
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1204
                               (b'eert_toor', b'eert_toor'),
1205
                               ('old', 'old'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1206
                               (False, False), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1207
                             list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1208
            transform.cancel_creation(old)
1209
1210
            # move file_id to a different file
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1211
            self.assertEqual([], list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1212
            transform.unversion_file(old)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1213
            transform.version_file(b'id-1', new)
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1214
            transform.adjust_path('old', root, new)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1215
            self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1216
                               (b'eert_toor', b'eert_toor'),
1217
                               ('old', 'old'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1218
                               (False, False), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1219
                             list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1220
            transform.cancel_versioning(new)
1221
            transform._removed_id = set()
1222
7143.15.2 by Jelmer Vernooij
Run autopep8.
1223
            # execute bit
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1224
            self.assertEqual([], list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1225
            transform.set_executability(True, old)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1226
            self.assertEqual([(b'id-1', ('old', 'old'), False, (True, True),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1227
                               (b'eert_toor', b'eert_toor'),
1228
                               ('old', 'old'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1229
                               (False, True), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1230
                             list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1231
            transform.set_executability(None, old)
1232
1233
            # filename
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1234
            self.assertEqual([], list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1235
            transform.adjust_path('new', root, old)
1236
            transform._new_parent = {}
6973.10.1 by Jelmer Vernooij
Fix some tests.
1237
            self.assertEqual([(b'id-1', ('old', 'new'), False, (True, True),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1238
                               (b'eert_toor', b'eert_toor'),
1239
                               ('old', 'new'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1240
                               (False, False), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1241
                             list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1242
            transform._new_name = {}
1243
1244
            # parent directory
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1245
            self.assertEqual([], list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1246
            transform.adjust_path('new', subdir, old)
1247
            transform._new_name = {}
6973.10.1 by Jelmer Vernooij
Fix some tests.
1248
            self.assertEqual([(b'id-1', ('old', 'subdir/old'), False,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1249
                               (True, True), (b'eert_toor',
1250
                                              b'subdir-id'), ('old', 'old'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1251
                               ('file', 'file'), (False, False), False)],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1252
                             list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1253
            transform._new_path = {}
1254
1255
        finally:
1256
            transform.finalize()
1257
1551.11.7 by Aaron Bentley
Stop modified flag bleeding into later changes
1258
    def test_iter_changes_modified_bleed(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
1259
        self.wt.set_root_id(b'eert_toor')
1551.11.7 by Aaron Bentley
Stop modified flag bleeding into later changes
1260
        """Modified flag should not bleed from one change to another"""
1261
        # unfortunately, we have no guarantee that file1 (which is modified)
1262
        # will be applied before file2.  And if it's applied after file2, it
1263
        # obviously can't bleed into file2's change output.  But for now, it
1264
        # works.
1265
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1266
        transform.new_file('file1', root, [b'blah'], b'id-1')
1267
        transform.new_file('file2', root, [b'blah'], b'id-2')
1551.11.7 by Aaron Bentley
Stop modified flag bleeding into later changes
1268
        transform.apply()
1269
        transform, root = self.get_transform()
1270
        try:
6973.10.1 by Jelmer Vernooij
Fix some tests.
1271
            transform.delete_contents(transform.trans_id_file_id(b'id-1'))
1551.11.7 by Aaron Bentley
Stop modified flag bleeding into later changes
1272
            transform.set_executability(True,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1273
                                        transform.trans_id_file_id(b'id-2'))
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1274
            self.assertEqual(
1275
                [(b'id-1', (u'file1', u'file1'), True, (True, True),
1276
                 (b'eert_toor', b'eert_toor'), ('file1', u'file1'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1277
                 ('file', None), (False, False), False),
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1278
                 (b'id-2', (u'file2', u'file2'), False, (True, True),
1279
                 (b'eert_toor', b'eert_toor'), ('file2', u'file2'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1280
                 ('file', 'file'), (False, True), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1281
                list(transform.iter_changes()))
1551.11.7 by Aaron Bentley
Stop modified flag bleeding into later changes
1282
        finally:
1283
            transform.finalize()
1284
1551.10.37 by Aaron Bentley
recommit of TreeTransform._iter_changes fix with missing files
1285
    def test_iter_changes_move_missing(self):
1286
        """Test moving ids with no files around"""
6855.4.1 by Jelmer Vernooij
Yet more bees.
1287
        self.wt.set_root_id(b'toor_eert')
1551.10.37 by Aaron Bentley
recommit of TreeTransform._iter_changes fix with missing files
1288
        # Need two steps because versioning a non-existant file is a conflict.
1289
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1290
        transform.new_directory('floater', root, b'floater-id')
1551.10.37 by Aaron Bentley
recommit of TreeTransform._iter_changes fix with missing files
1291
        transform.apply()
1292
        transform, root = self.get_transform()
1293
        transform.delete_contents(transform.trans_id_tree_path('floater'))
1294
        transform.apply()
1295
        transform, root = self.get_transform()
1296
        floater = transform.trans_id_tree_path('floater')
1297
        try:
1298
            transform.adjust_path('flitter', root, floater)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1299
            self.assertEqual([(b'floater-id', ('floater', 'flitter'), False,
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1300
                               (True, True),
1301
                               (b'toor_eert', b'toor_eert'),
1302
                               ('floater', 'flitter'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
1303
                               (None, None), (False, False), False)],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1304
                             list(transform.iter_changes()))
1551.10.37 by Aaron Bentley
recommit of TreeTransform._iter_changes fix with missing files
1305
        finally:
1306
            transform.finalize()
1307
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1308
    def test_iter_changes_pointless(self):
1309
        """Ensure that no-ops are not treated as modifications"""
6855.4.1 by Jelmer Vernooij
Yet more bees.
1310
        self.wt.set_root_id(b'eert_toor')
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1311
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1312
        transform.new_file('old', root, [b'blah'], b'id-1')
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1313
        transform.new_directory('subdir', root, b'subdir-id')
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1314
        transform.apply()
1315
        transform, root = self.get_transform()
1316
        try:
1317
            old = transform.trans_id_tree_path('old')
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
1318
            subdir = transform.trans_id_tree_path('subdir')
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1319
            self.assertEqual([], list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1320
            transform.delete_contents(subdir)
1321
            transform.create_directory(subdir)
1322
            transform.set_executability(False, old)
1323
            transform.unversion_file(old)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1324
            transform.version_file(b'id-1', old)
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1325
            transform.adjust_path('old', root, old)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
1326
            self.assertEqual([], list(transform.iter_changes()))
1551.11.2 by Aaron Bentley
Get kind change detection working for iter_changes
1327
        finally:
1328
            transform.finalize()
1534.7.93 by Aaron Bentley
Added text merge test
1329
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
1330
    def test_rename_count(self):
1331
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1332
        transform.new_file('name1', root, [b'contents'])
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
1333
        self.assertEqual(transform.rename_count, 0)
1334
        transform.apply()
1335
        self.assertEqual(transform.rename_count, 1)
1336
        transform2, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1337
        transform2.adjust_path('name2', root,
1338
                               transform2.trans_id_tree_path('name1'))
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
1339
        self.assertEqual(transform2.rename_count, 0)
1340
        transform2.apply()
1341
        self.assertEqual(transform2.rename_count, 2)
1342
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1343
    def test_change_parent(self):
2502.1.8 by Aaron Bentley
Updates from review comments
1344
        """Ensure that after we change a parent, the results are still right.
1345
1346
        Renames and parent changes on pending transforms can happen as part
1347
        of conflict resolution, and are explicitly permitted by the
1348
        TreeTransform API.
1349
1350
        This test ensures they work correctly with the rename-avoidance
1351
        optimization.
1352
        """
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1353
        transform, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1354
        parent1 = transform.new_directory('parent1', root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1355
        child1 = transform.new_file('child1', parent1, [b'contents'])
2502.1.8 by Aaron Bentley
Updates from review comments
1356
        parent2 = transform.new_directory('parent2', root)
1357
        transform.adjust_path('child1', parent2, child1)
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1358
        transform.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1359
        self.assertPathDoesNotExist(self.wt.abspath('parent1/child1'))
1360
        self.assertPathExists(self.wt.abspath('parent2/child1'))
2502.1.8 by Aaron Bentley
Updates from review comments
1361
        # rename limbo/new-1 => parent1, rename limbo/new-3 => parent2
1362
        # no rename for child1 (counting only renames during apply)
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
1363
        self.assertEqual(2, transform.rename_count)
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1364
1365
    def test_cancel_parent(self):
1366
        """Cancelling a parent doesn't cause deletion of a non-empty directory
1367
1368
        This is like the test_change_parent, except that we cancel the parent
1369
        before adjusting the path.  The transform must detect that the
1370
        directory is non-empty, and move children to safe locations.
1371
        """
1372
        transform, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1373
        parent1 = transform.new_directory('parent1', root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1374
        child1 = transform.new_file('child1', parent1, [b'contents'])
1375
        child2 = transform.new_file('child2', parent1, [b'contents'])
2502.1.8 by Aaron Bentley
Updates from review comments
1376
        try:
1377
            transform.cancel_creation(parent1)
1378
        except OSError:
1379
            self.fail('Failed to move child1 before deleting parent1')
1380
        transform.cancel_creation(child2)
1381
        transform.create_directory(parent1)
1382
        try:
1383
            transform.cancel_creation(parent1)
1384
        # If the transform incorrectly believes that child2 is still in
1385
        # parent1's limbo directory, it will try to rename it and fail
1386
        # because was already moved by the first cancel_creation.
1387
        except OSError:
1388
            self.fail('Transform still thinks child2 is a child of parent1')
1389
        parent2 = transform.new_directory('parent2', root)
1390
        transform.adjust_path('child1', parent2, child1)
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1391
        transform.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1392
        self.assertPathDoesNotExist(self.wt.abspath('parent1'))
1393
        self.assertPathExists(self.wt.abspath('parent2/child1'))
2502.1.8 by Aaron Bentley
Updates from review comments
1394
        # rename limbo/new-3 => parent2, rename limbo/new-2 => child1
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
1395
        self.assertEqual(2, transform.rename_count)
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1396
1397
    def test_adjust_and_cancel(self):
2502.1.8 by Aaron Bentley
Updates from review comments
1398
        """Make sure adjust_path keeps track of limbo children properly"""
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1399
        transform, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1400
        parent1 = transform.new_directory('parent1', root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1401
        child1 = transform.new_file('child1', parent1, [b'contents'])
2502.1.8 by Aaron Bentley
Updates from review comments
1402
        parent2 = transform.new_directory('parent2', root)
1403
        transform.adjust_path('child1', parent2, child1)
1404
        transform.cancel_creation(child1)
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1405
        try:
2502.1.8 by Aaron Bentley
Updates from review comments
1406
            transform.cancel_creation(parent1)
1407
        # if the transform thinks child1 is still in parent1's limbo
1408
        # directory, it will attempt to move it and fail.
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1409
        except OSError:
2502.1.8 by Aaron Bentley
Updates from review comments
1410
            self.fail('Transform still thinks child1 is a child of parent1')
2502.1.2 by Aaron Bentley
Make the limited-renames functionality safer in the general case
1411
        transform.finalize()
1412
2502.1.3 by Aaron Bentley
Don't cause errors when creating contents for trans_ids with no parent/name
1413
    def test_noname_contents(self):
2502.1.8 by Aaron Bentley
Updates from review comments
1414
        """TreeTransform should permit deferring naming files."""
2502.1.3 by Aaron Bentley
Don't cause errors when creating contents for trans_ids with no parent/name
1415
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1416
        parent = transform.trans_id_file_id(b'parent-id')
2502.1.3 by Aaron Bentley
Don't cause errors when creating contents for trans_ids with no parent/name
1417
        try:
2502.1.8 by Aaron Bentley
Updates from review comments
1418
            transform.create_directory(parent)
2502.1.3 by Aaron Bentley
Don't cause errors when creating contents for trans_ids with no parent/name
1419
        except KeyError:
1420
            self.fail("Can't handle contents with no name")
1421
        transform.finalize()
1422
2502.1.9 by Aaron Bentley
Add additional test for no-name contents
1423
    def test_noname_contents_nested(self):
1424
        """TreeTransform should permit deferring naming files."""
1425
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1426
        parent = transform.trans_id_file_id(b'parent-id')
2502.1.9 by Aaron Bentley
Add additional test for no-name contents
1427
        try:
1428
            transform.create_directory(parent)
1429
        except KeyError:
1430
            self.fail("Can't handle contents with no name")
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1431
        transform.new_directory('child', parent)
2502.1.9 by Aaron Bentley
Add additional test for no-name contents
1432
        transform.adjust_path('parent', root, parent)
1433
        transform.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1434
        self.assertPathExists(self.wt.abspath('parent/child'))
2502.1.9 by Aaron Bentley
Add additional test for no-name contents
1435
        self.assertEqual(1, transform.rename_count)
1436
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1437
    def test_reuse_name(self):
1438
        """Avoid reusing the same limbo name for different files"""
1439
        transform, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1440
        parent = transform.new_directory('parent', root)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1441
        transform.new_directory('child', parent)
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1442
        try:
2502.1.8 by Aaron Bentley
Updates from review comments
1443
            child2 = transform.new_directory('child', parent)
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1444
        except OSError:
1445
            self.fail('Tranform tried to use the same limbo name twice')
2502.1.8 by Aaron Bentley
Updates from review comments
1446
        transform.adjust_path('child2', parent, child2)
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1447
        transform.apply()
2502.1.8 by Aaron Bentley
Updates from review comments
1448
        # limbo/new-1 => parent, limbo/new-3 => parent/child2
1449
        # child2 is put into top-level limbo because child1 has already
1450
        # claimed the direct limbo path when child2 is created.  There is no
1451
        # advantage in renaming files once they're in top-level limbo, except
1452
        # as part of apply.
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1453
        self.assertEqual(2, transform.rename_count)
1454
1455
    def test_reuse_when_first_moved(self):
1456
        """Don't avoid direct paths when it is safe to use them"""
1457
        transform, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1458
        parent = transform.new_directory('parent', root)
1459
        child1 = transform.new_directory('child', parent)
1460
        transform.adjust_path('child1', parent, child1)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1461
        transform.new_directory('child', parent)
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1462
        transform.apply()
2502.1.8 by Aaron Bentley
Updates from review comments
1463
        # limbo/new-1 => parent
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1464
        self.assertEqual(1, transform.rename_count)
1465
1466
    def test_reuse_after_cancel(self):
1467
        """Don't avoid direct paths when it is safe to use them"""
1468
        transform, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1469
        parent2 = transform.new_directory('parent2', root)
1470
        child1 = transform.new_directory('child1', parent2)
1471
        transform.cancel_creation(parent2)
1472
        transform.create_directory(parent2)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1473
        transform.new_directory('child1', parent2)
2502.1.8 by Aaron Bentley
Updates from review comments
1474
        transform.adjust_path('child2', parent2, child1)
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1475
        transform.apply()
2502.1.8 by Aaron Bentley
Updates from review comments
1476
        # limbo/new-1 => parent2, limbo/new-2 => parent2/child1
2502.1.4 by Aaron Bentley
Ensure we only reuse limbo names appropriately
1477
        self.assertEqual(2, transform.rename_count)
1478
2502.1.7 by Aaron Bentley
Fix finalize deletion ordering
1479
    def test_finalize_order(self):
2502.1.8 by Aaron Bentley
Updates from review comments
1480
        """Finalize must be done in child-to-parent order"""
2502.1.7 by Aaron Bentley
Fix finalize deletion ordering
1481
        transform, root = self.get_transform()
2502.1.8 by Aaron Bentley
Updates from review comments
1482
        parent = transform.new_directory('parent', root)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1483
        transform.new_directory('child', parent)
2502.1.7 by Aaron Bentley
Fix finalize deletion ordering
1484
        try:
1485
            transform.finalize()
1486
        except OSError:
2502.1.8 by Aaron Bentley
Updates from review comments
1487
            self.fail('Tried to remove parent before child1')
2502.1.7 by Aaron Bentley
Fix finalize deletion ordering
1488
2502.1.13 by Aaron Bentley
Updates from review
1489
    def test_cancel_with_cancelled_child_should_succeed(self):
2502.1.12 by Aaron Bentley
Avoid renaming children with no content
1490
        transform, root = self.get_transform()
1491
        parent = transform.new_directory('parent', root)
1492
        child = transform.new_directory('child', parent)
1493
        transform.cancel_creation(child)
2502.1.13 by Aaron Bentley
Updates from review
1494
        transform.cancel_creation(parent)
2502.1.12 by Aaron Bentley
Avoid renaming children with no content
1495
        transform.finalize()
1496
3638.3.15 by Vincent Ladeuil
Fix test_case_insensitive_clash to pass on all platforms (renamed too).
1497
    def test_rollback_on_directory_clash(self):
3063.1.1 by Alexander Belchenko
Catch OSError 17 (file exists) in final phase of tree transform and show filename to user (#111758).
1498
        def tt_helper():
3638.3.17 by Vincent Ladeuil
Fixed as per Aaron's review.
1499
            wt = self.make_branch_and_tree('.')
3063.1.1 by Alexander Belchenko
Catch OSError 17 (file exists) in final phase of tree transform and show filename to user (#111758).
1500
            tt = TreeTransform(wt)  # TreeTransform obtains write lock
1501
            try:
3638.3.15 by Vincent Ladeuil
Fix test_case_insensitive_clash to pass on all platforms (renamed too).
1502
                foo = tt.new_directory('foo', tt.root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1503
                tt.new_file('bar', foo, [b'foobar'])
3638.3.15 by Vincent Ladeuil
Fix test_case_insensitive_clash to pass on all platforms (renamed too).
1504
                baz = tt.new_directory('baz', tt.root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1505
                tt.new_file('qux', baz, [b'quux'])
3638.3.15 by Vincent Ladeuil
Fix test_case_insensitive_clash to pass on all platforms (renamed too).
1506
                # Ask for a rename 'foo' -> 'baz'
1507
                tt.adjust_path('baz', tt.root, foo)
3063.1.3 by Aaron Bentley
Update for Linux
1508
                # Lie to tt that we've already resolved all conflicts.
3063.1.1 by Alexander Belchenko
Catch OSError 17 (file exists) in final phase of tree transform and show filename to user (#111758).
1509
                tt.apply(no_conflicts=True)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1510
            except BaseException:
3063.1.1 by Alexander Belchenko
Catch OSError 17 (file exists) in final phase of tree transform and show filename to user (#111758).
1511
                wt.unlock()
3063.1.3 by Aaron Bentley
Update for Linux
1512
                raise
3638.3.17 by Vincent Ladeuil
Fixed as per Aaron's review.
1513
        # The rename will fail because the target directory is not empty (but
1514
        # raises FileExists anyway).
3063.1.1 by Alexander Belchenko
Catch OSError 17 (file exists) in final phase of tree transform and show filename to user (#111758).
1515
        err = self.assertRaises(errors.FileExists, tt_helper)
6269.1.1 by Martin Packman
Only assert FileExists path in test_transform directory clash tests to avoid stringification fallout
1516
        self.assertEndsWith(err.path, "/baz")
3063.1.1 by Alexander Belchenko
Catch OSError 17 (file exists) in final phase of tree transform and show filename to user (#111758).
1517
3063.1.2 by Alexander Belchenko
test for two directories clash
1518
    def test_two_directories_clash(self):
1519
        def tt_helper():
1520
            wt = self.make_branch_and_tree('.')
1521
            tt = TreeTransform(wt)  # TreeTransform obtains write lock
1522
            try:
3063.1.3 by Aaron Bentley
Update for Linux
1523
                foo_1 = tt.new_directory('foo', tt.root)
1524
                tt.new_directory('bar', foo_1)
3638.3.15 by Vincent Ladeuil
Fix test_case_insensitive_clash to pass on all platforms (renamed too).
1525
                # Adding the same directory with a different content
3063.1.3 by Aaron Bentley
Update for Linux
1526
                foo_2 = tt.new_directory('foo', tt.root)
1527
                tt.new_directory('baz', foo_2)
1528
                # Lie to tt that we've already resolved all conflicts.
3063.1.2 by Alexander Belchenko
test for two directories clash
1529
                tt.apply(no_conflicts=True)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1530
            except BaseException:
3063.1.2 by Alexander Belchenko
test for two directories clash
1531
                wt.unlock()
3063.1.3 by Aaron Bentley
Update for Linux
1532
                raise
3063.1.2 by Alexander Belchenko
test for two directories clash
1533
        err = self.assertRaises(errors.FileExists, tt_helper)
6269.1.1 by Martin Packman
Only assert FileExists path in test_transform directory clash tests to avoid stringification fallout
1534
        self.assertEndsWith(err.path, "/foo")
3063.1.2 by Alexander Belchenko
test for two directories clash
1535
3100.1.1 by Aaron Bentley
Fix ImmortalLimbo errors when transforms fail
1536
    def test_two_directories_clash_finalize(self):
1537
        def tt_helper():
1538
            wt = self.make_branch_and_tree('.')
1539
            tt = TreeTransform(wt)  # TreeTransform obtains write lock
1540
            try:
1541
                foo_1 = tt.new_directory('foo', tt.root)
1542
                tt.new_directory('bar', foo_1)
3638.3.15 by Vincent Ladeuil
Fix test_case_insensitive_clash to pass on all platforms (renamed too).
1543
                # Adding the same directory with a different content
3100.1.1 by Aaron Bentley
Fix ImmortalLimbo errors when transforms fail
1544
                foo_2 = tt.new_directory('foo', tt.root)
1545
                tt.new_directory('baz', foo_2)
1546
                # Lie to tt that we've already resolved all conflicts.
1547
                tt.apply(no_conflicts=True)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1548
            except BaseException:
3100.1.1 by Aaron Bentley
Fix ImmortalLimbo errors when transforms fail
1549
                tt.finalize()
1550
                raise
1551
        err = self.assertRaises(errors.FileExists, tt_helper)
6269.1.1 by Martin Packman
Only assert FileExists path in test_transform directory clash tests to avoid stringification fallout
1552
        self.assertEndsWith(err.path, "/foo")
3100.1.1 by Aaron Bentley
Fix ImmortalLimbo errors when transforms fail
1553
3535.6.1 by James Westby
Handle a file turning in to a directory in TreeTransform.
1554
    def test_file_to_directory(self):
1555
        wt = self.make_branch_and_tree('.')
3535.6.2 by James Westby
Fixes from review. Thanks Aaron and John.
1556
        self.build_tree(['foo'])
3535.6.1 by James Westby
Handle a file turning in to a directory in TreeTransform.
1557
        wt.add(['foo'])
3590.3.1 by James Westby
Make TreeTransform update the inventory with new kind information.
1558
        wt.commit("one")
3535.6.1 by James Westby
Handle a file turning in to a directory in TreeTransform.
1559
        tt = TreeTransform(wt)
3535.6.2 by James Westby
Fixes from review. Thanks Aaron and John.
1560
        self.addCleanup(tt.finalize)
3535.6.3 by James Westby
Fix the test to not create transform conflicts.
1561
        foo_trans_id = tt.trans_id_tree_path("foo")
1562
        tt.delete_contents(foo_trans_id)
1563
        tt.create_directory(foo_trans_id)
1564
        bar_trans_id = tt.trans_id_tree_path("foo/bar")
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1565
        tt.create_file([b"aa\n"], bar_trans_id)
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
1566
        tt.version_file(b"bar-1", bar_trans_id)
3535.6.2 by James Westby
Fixes from review. Thanks Aaron and John.
1567
        tt.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1568
        self.assertPathExists("foo/bar")
3590.3.2 by James Westby
Handle ->symlink changes as well.
1569
        wt.lock_read()
1570
        try:
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1571
            self.assertEqual(wt.kind("foo"), "directory")
3590.3.2 by James Westby
Handle ->symlink changes as well.
1572
        finally:
1573
            wt.unlock()
3590.3.1 by James Westby
Make TreeTransform update the inventory with new kind information.
1574
        wt.commit("two")
1575
        changes = wt.changes_from(wt.basis_tree())
1576
        self.assertFalse(changes.has_changed(), changes)
3535.6.1 by James Westby
Handle a file turning in to a directory in TreeTransform.
1577
3590.3.2 by James Westby
Handle ->symlink changes as well.
1578
    def test_file_to_symlink(self):
3590.3.3 by James Westby
Make ->file changes work as well.
1579
        self.requireFeature(SymlinkFeature)
3590.3.2 by James Westby
Handle ->symlink changes as well.
1580
        wt = self.make_branch_and_tree('.')
1581
        self.build_tree(['foo'])
1582
        wt.add(['foo'])
1583
        wt.commit("one")
1584
        tt = TreeTransform(wt)
1585
        self.addCleanup(tt.finalize)
1586
        foo_trans_id = tt.trans_id_tree_path("foo")
1587
        tt.delete_contents(foo_trans_id)
1588
        tt.create_symlink("bar", foo_trans_id)
1589
        tt.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1590
        self.assertPathExists("foo")
3590.3.2 by James Westby
Handle ->symlink changes as well.
1591
        wt.lock_read()
1592
        self.addCleanup(wt.unlock)
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1593
        self.assertEqual(wt.kind("foo"), "symlink")
3590.3.2 by James Westby
Handle ->symlink changes as well.
1594
6469.1.15 by Parth Malwankar
added test. warning now explicit
1595
    def test_file_to_symlink_unsupported(self):
1596
        wt = self.make_branch_and_tree('.')
1597
        self.build_tree(['foo'])
1598
        wt.add(['foo'])
1599
        wt.commit("one")
7122.6.6 by Jelmer Vernooij
Fix more tests.
1600
        self.overrideAttr(osutils, 'supports_symlinks', lambda p: False)
6469.1.15 by Parth Malwankar
added test. warning now explicit
1601
        tt = TreeTransform(wt)
1602
        self.addCleanup(tt.finalize)
1603
        foo_trans_id = tt.trans_id_tree_path("foo")
1604
        tt.delete_contents(foo_trans_id)
7122.6.1 by Jelmer Vernooij
merge Parth's work into Breezy
1605
        log = BytesIO()
6469.1.15 by Parth Malwankar
added test. warning now explicit
1606
        trace.push_log_file(log)
7122.6.6 by Jelmer Vernooij
Fix more tests.
1607
        tt.create_symlink("bar", foo_trans_id)
1608
        tt.apply()
6469.1.16 by Parth Malwankar
added diff test
1609
        self.assertContainsRe(
1610
            log.getvalue(),
7122.6.12 by Jelmer Vernooij
Fix more python3 tests.
1611
            b'Unable to create symlink "foo" on this filesystem')
6469.1.15 by Parth Malwankar
added test. warning now explicit
1612
3590.3.3 by James Westby
Make ->file changes work as well.
1613
    def test_dir_to_file(self):
1614
        wt = self.make_branch_and_tree('.')
1615
        self.build_tree(['foo/', 'foo/bar'])
1616
        wt.add(['foo', 'foo/bar'])
1617
        wt.commit("one")
1618
        tt = TreeTransform(wt)
1619
        self.addCleanup(tt.finalize)
1620
        foo_trans_id = tt.trans_id_tree_path("foo")
1621
        bar_trans_id = tt.trans_id_tree_path("foo/bar")
1622
        tt.delete_contents(foo_trans_id)
1623
        tt.delete_versioned(bar_trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1624
        tt.create_file([b"aa\n"], foo_trans_id)
3590.3.3 by James Westby
Make ->file changes work as well.
1625
        tt.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1626
        self.assertPathExists("foo")
3590.3.3 by James Westby
Make ->file changes work as well.
1627
        wt.lock_read()
1628
        self.addCleanup(wt.unlock)
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1629
        self.assertEqual(wt.kind("foo"), "file")
3590.3.3 by James Westby
Make ->file changes work as well.
1630
3590.3.4 by James Westby
Add a test for creating hardlinks as well.
1631
    def test_dir_to_hardlink(self):
3590.3.5 by James Westby
Use HardlinkFeature for the hardlink test.
1632
        self.requireFeature(HardlinkFeature)
3590.3.4 by James Westby
Add a test for creating hardlinks as well.
1633
        wt = self.make_branch_and_tree('.')
1634
        self.build_tree(['foo/', 'foo/bar'])
1635
        wt.add(['foo', 'foo/bar'])
1636
        wt.commit("one")
1637
        tt = TreeTransform(wt)
1638
        self.addCleanup(tt.finalize)
1639
        foo_trans_id = tt.trans_id_tree_path("foo")
1640
        bar_trans_id = tt.trans_id_tree_path("foo/bar")
1641
        tt.delete_contents(foo_trans_id)
1642
        tt.delete_versioned(bar_trans_id)
1643
        self.build_tree(['baz'])
1644
        tt.create_hardlink("baz", foo_trans_id)
1645
        tt.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1646
        self.assertPathExists("foo")
1647
        self.assertPathExists("baz")
3590.3.4 by James Westby
Add a test for creating hardlinks as well.
1648
        wt.lock_read()
1649
        self.addCleanup(wt.unlock)
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1650
        self.assertEqual(wt.kind("foo"), "file")
3590.3.4 by James Westby
Add a test for creating hardlinks as well.
1651
3619.2.10 by Aaron Bentley
Compensate for stale entries in TT._needs_rename
1652
    def test_no_final_path(self):
1653
        transform, root = self.get_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1654
        trans_id = transform.trans_id_file_id(b'foo')
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1655
        transform.create_file([b'bar'], trans_id)
3619.2.10 by Aaron Bentley
Compensate for stale entries in TT._needs_rename
1656
        transform.cancel_creation(trans_id)
1657
        transform.apply()
1658
3363.17.24 by Aaron Bentley
Implement create_by_tree
1659
    def test_create_from_tree(self):
1660
        tree1 = self.make_branch_and_tree('tree1')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1661
        self.build_tree_contents([('tree1/foo/',), ('tree1/bar', b'baz')])
1662
        tree1.add(['foo', 'bar'], [b'foo-id', b'bar-id'])
3363.17.24 by Aaron Bentley
Implement create_by_tree
1663
        tree2 = self.make_branch_and_tree('tree2')
1664
        tt = TreeTransform(tree2)
1665
        foo_trans_id = tt.create_path('foo', tt.root)
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1666
        create_from_tree(tt, foo_trans_id, tree1, 'foo')
3363.17.24 by Aaron Bentley
Implement create_by_tree
1667
        bar_trans_id = tt.create_path('bar', tt.root)
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1668
        create_from_tree(tt, bar_trans_id, tree1, 'bar')
3363.17.24 by Aaron Bentley
Implement create_by_tree
1669
        tt.apply()
1670
        self.assertEqual('directory', osutils.file_kind('tree2/foo'))
6973.10.1 by Jelmer Vernooij
Fix some tests.
1671
        self.assertFileEqual(b'baz', 'tree2/bar')
3363.17.24 by Aaron Bentley
Implement create_by_tree
1672
3363.17.25 by Aaron Bentley
remove get_inventory_entry, replace with create_from_tree
1673
    def test_create_from_tree_bytes(self):
1674
        """Provided lines are used instead of tree content."""
1675
        tree1 = self.make_branch_and_tree('tree1')
7143.15.2 by Jelmer Vernooij
Run autopep8.
1676
        self.build_tree_contents([('tree1/foo', b'bar'), ])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1677
        tree1.add('foo', b'foo-id')
3363.17.25 by Aaron Bentley
remove get_inventory_entry, replace with create_from_tree
1678
        tree2 = self.make_branch_and_tree('tree2')
1679
        tt = TreeTransform(tree2)
1680
        foo_trans_id = tt.create_path('foo', tt.root)
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1681
        create_from_tree(tt, foo_trans_id, tree1, 'foo', chunks=[b'qux'])
3363.17.25 by Aaron Bentley
remove get_inventory_entry, replace with create_from_tree
1682
        tt.apply()
6973.10.1 by Jelmer Vernooij
Fix some tests.
1683
        self.assertFileEqual(b'qux', 'tree2/foo')
3363.17.25 by Aaron Bentley
remove get_inventory_entry, replace with create_from_tree
1684
1685
    def test_create_from_tree_symlink(self):
3363.17.24 by Aaron Bentley
Implement create_by_tree
1686
        self.requireFeature(SymlinkFeature)
1687
        tree1 = self.make_branch_and_tree('tree1')
1688
        os.symlink('bar', 'tree1/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1689
        tree1.add('foo', b'foo-id')
3363.17.24 by Aaron Bentley
Implement create_by_tree
1690
        tt = TreeTransform(self.make_branch_and_tree('tree2'))
1691
        foo_trans_id = tt.create_path('foo', tt.root)
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1692
        create_from_tree(tt, foo_trans_id, tree1, 'foo')
3363.17.24 by Aaron Bentley
Implement create_by_tree
1693
        tt.apply()
1694
        self.assertEqual('bar', os.readlink('tree2/foo'))
1695
2502.1.3 by Aaron Bentley
Don't cause errors when creating contents for trans_ids with no parent/name
1696
1534.7.93 by Aaron Bentley
Added text merge test
1697
class TransformGroup(object):
3063.1.1 by Alexander Belchenko
Catch OSError 17 (file exists) in final phase of tree transform and show filename to user (#111758).
1698
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1699
    def __init__(self, dirname, root_id):
1534.7.101 by Aaron Bentley
Got conflicts on symlinks working properly
1700
        self.name = dirname
1534.7.93 by Aaron Bentley
Added text merge test
1701
        os.mkdir(dirname)
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
1702
        self.wt = ControlDir.create_standalone_workingtree(dirname)
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1703
        self.wt.set_root_id(root_id)
1558.1.3 by Aaron Bentley
Fixed deprecated op use in test suite
1704
        self.b = self.wt.branch
1534.7.93 by Aaron Bentley
Added text merge test
1705
        self.tt = TreeTransform(self.wt)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
1706
        self.root = self.tt.trans_id_tree_path('')
1534.7.93 by Aaron Bentley
Added text merge test
1707
1551.11.1 by Aaron Bentley
Initial work on converting TreeTransform to iter_changes format
1708
1534.7.95 by Aaron Bentley
Added more text merge tests
1709
def conflict_text(tree, merge):
6973.10.1 by Jelmer Vernooij
Fix some tests.
1710
    template = b'%s TREE\n%s%s\n%s%s MERGE-SOURCE\n'
1711
    return template % (b'<' * 7, tree, b'=' * 7, merge, b'>' * 7)
1534.7.95 by Aaron Bentley
Added more text merge tests
1712
1534.7.93 by Aaron Bentley
Added text merge test
1713
5954.2.2 by Aaron Bentley
Include parent id changes for changed inventory entries.
1714
class TestInventoryAltered(tests.TestCaseWithTransport):
1715
1716
    def test_inventory_altered_unchanged(self):
1717
        tree = self.make_branch_and_tree('tree')
1718
        self.build_tree(['tree/foo'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1719
        tree.add('foo', b'foo-id')
5954.2.2 by Aaron Bentley
Include parent id changes for changed inventory entries.
1720
        with TransformPreview(tree) as tt:
1721
            self.assertEqual([], tt._inventory_altered())
1722
1723
    def test_inventory_altered_changed_parent_id(self):
1724
        tree = self.make_branch_and_tree('tree')
1725
        self.build_tree(['tree/foo'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1726
        tree.add('foo', b'foo-id')
5954.2.2 by Aaron Bentley
Include parent id changes for changed inventory entries.
1727
        with TransformPreview(tree) as tt:
1728
            tt.unversion_file(tt.root)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1729
            tt.version_file(b'new-id', tt.root)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
1730
            foo_trans_id = tt.trans_id_tree_path('foo')
5954.2.2 by Aaron Bentley
Include parent id changes for changed inventory entries.
1731
            foo_tuple = ('foo', foo_trans_id)
1732
            root_tuple = ('', tt.root)
1733
            self.assertEqual([root_tuple, foo_tuple], tt._inventory_altered())
1734
1735
    def test_inventory_altered_noop_changed_parent_id(self):
1736
        tree = self.make_branch_and_tree('tree')
1737
        self.build_tree(['tree/foo'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
1738
        tree.add('foo', b'foo-id')
5954.2.2 by Aaron Bentley
Include parent id changes for changed inventory entries.
1739
        with TransformPreview(tree) as tt:
1740
            tt.unversion_file(tt.root)
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1741
            tt.version_file(tree.path2id(''), tt.root)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1742
            tt.trans_id_tree_path('foo')
5954.2.2 by Aaron Bentley
Include parent id changes for changed inventory entries.
1743
            self.assertEqual([], tt._inventory_altered())
1744
1745
1534.7.93 by Aaron Bentley
Added text merge test
1746
class TestTransformMerge(TestCaseInTempDir):
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
1747
1534.7.93 by Aaron Bentley
Added text merge test
1748
    def test_text_merge(self):
2116.4.1 by John Arbash Meinel
Update file and revision id generators.
1749
        root_id = generate_ids.gen_root_id()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1750
        base = TransformGroup("base", root_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1751
        base.tt.new_file('a', base.root, [b'a\nb\nc\nd\be\n'], b'a')
1752
        base.tt.new_file('b', base.root, [b'b1'], b'b')
1753
        base.tt.new_file('c', base.root, [b'c'], b'c')
1754
        base.tt.new_file('d', base.root, [b'd'], b'd')
1755
        base.tt.new_file('e', base.root, [b'e'], b'e')
1756
        base.tt.new_file('f', base.root, [b'f'], b'f')
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1757
        base.tt.new_directory('g', base.root, b'g')
1758
        base.tt.new_directory('h', base.root, b'h')
1534.7.93 by Aaron Bentley
Added text merge test
1759
        base.tt.apply()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1760
        other = TransformGroup("other", root_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1761
        other.tt.new_file('a', other.root, [b'y\nb\nc\nd\be\n'], b'a')
1762
        other.tt.new_file('b', other.root, [b'b2'], b'b')
1763
        other.tt.new_file('c', other.root, [b'c2'], b'c')
1764
        other.tt.new_file('d', other.root, [b'd'], b'd')
1765
        other.tt.new_file('e', other.root, [b'e2'], b'e')
1766
        other.tt.new_file('f', other.root, [b'f'], b'f')
1767
        other.tt.new_file('g', other.root, [b'g'], b'g')
1768
        other.tt.new_file('h', other.root, [b'h\ni\nj\nk\n'], b'h')
1769
        other.tt.new_file('i', other.root, [b'h\ni\nj\nk\n'], b'i')
1534.7.93 by Aaron Bentley
Added text merge test
1770
        other.tt.apply()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1771
        this = TransformGroup("this", root_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
1772
        this.tt.new_file('a', this.root, [b'a\nb\nc\nd\bz\n'], b'a')
1773
        this.tt.new_file('b', this.root, [b'b'], b'b')
1774
        this.tt.new_file('c', this.root, [b'c'], b'c')
1775
        this.tt.new_file('d', this.root, [b'd2'], b'd')
1776
        this.tt.new_file('e', this.root, [b'e2'], b'e')
1777
        this.tt.new_file('f', this.root, [b'f'], b'f')
1778
        this.tt.new_file('g', this.root, [b'g'], b'g')
1779
        this.tt.new_file('h', this.root, [b'1\n2\n3\n4\n'], b'h')
1780
        this.tt.new_file('i', this.root, [b'1\n2\n3\n4\n'], b'i')
1534.7.93 by Aaron Bentley
Added text merge test
1781
        this.tt.apply()
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
1782
        Merge3Merger(this.wt, this.wt, base.wt, other.wt)
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
1783
1534.7.95 by Aaron Bentley
Added more text merge tests
1784
        # textual merge
6973.10.1 by Jelmer Vernooij
Fix some tests.
1785
        with this.wt.get_file(this.wt.id2path(b'a')) as f:
1786
            self.assertEqual(f.read(), b'y\nb\nc\nd\bz\n')
1534.7.95 by Aaron Bentley
Added more text merge tests
1787
        # three-way text conflict
6973.10.1 by Jelmer Vernooij
Fix some tests.
1788
        with this.wt.get_file(this.wt.id2path(b'b')) as f:
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
1789
            self.assertEqual(f.read(), conflict_text(b'b', b'b2'))
1534.7.95 by Aaron Bentley
Added more text merge tests
1790
        # OTHER wins
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1791
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'c')).read(), b'c2')
1534.7.95 by Aaron Bentley
Added more text merge tests
1792
        # THIS wins
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1793
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'd')).read(), b'd2')
1534.7.95 by Aaron Bentley
Added more text merge tests
1794
        # Ambigious clean merge
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1795
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'e')).read(), b'e2')
1534.7.95 by Aaron Bentley
Added more text merge tests
1796
        # No change
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1797
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'f')).read(), b'f')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1798
        # Correct correct results when THIS == OTHER
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1799
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'g')).read(), b'g')
1534.7.97 by Aaron Bentley
Ensured foo.BASE is a directory if there's a conflict
1800
        # Text conflict when THIS & OTHER are text and BASE is dir
6855.4.1 by Jelmer Vernooij
Yet more bees.
1801
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'h')).read(),
6973.10.1 by Jelmer Vernooij
Fix some tests.
1802
                         conflict_text(b'1\n2\n3\n4\n', b'h\ni\nj\nk\n'))
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1803
        self.assertEqual(this.wt.get_file('h.THIS').read(),
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1804
                         b'1\n2\n3\n4\n')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1805
        self.assertEqual(this.wt.get_file('h.OTHER').read(),
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1806
                         b'h\ni\nj\nk\n')
1534.7.97 by Aaron Bentley
Ensured foo.BASE is a directory if there's a conflict
1807
        self.assertEqual(file_kind(this.wt.abspath('h.BASE')), 'directory')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1808
        self.assertEqual(this.wt.get_file(this.wt.id2path(b'i')).read(),
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1809
                         conflict_text(b'1\n2\n3\n4\n', b'h\ni\nj\nk\n'))
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1810
        self.assertEqual(this.wt.get_file('i.THIS').read(),
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1811
                         b'1\n2\n3\n4\n')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1812
        self.assertEqual(this.wt.get_file('i.OTHER').read(),
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1813
                         b'h\ni\nj\nk\n')
1534.7.99 by Aaron Bentley
Handle non-existent BASE properly
1814
        self.assertEqual(os.path.exists(this.wt.abspath('i.BASE')), False)
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1815
        modified = ['a', 'b', 'c', 'h', 'i']
1534.7.192 by Aaron Bentley
Record hashes produced by merges
1816
        merge_modified = this.wt.merge_modified()
1817
        self.assertSubset(merge_modified, modified)
1818
        self.assertEqual(len(merge_modified), len(modified))
7143.15.2 by Jelmer Vernooij
Run autopep8.
1819
        with open(this.wt.abspath(this.wt.id2path(b'a')), 'wb') as f:
1820
            f.write(b'booga')
1534.7.192 by Aaron Bentley
Record hashes produced by merges
1821
        modified.pop(0)
1822
        merge_modified = this.wt.merge_modified()
1823
        self.assertSubset(merge_modified, modified)
1824
        self.assertEqual(len(merge_modified), len(modified))
1558.12.10 by Aaron Bentley
Be robust when merge_hash file_id not in inventory
1825
        this.wt.remove('b')
2796.1.4 by Aaron Bentley
Fix up various test cases
1826
        this.wt.revert()
1534.7.101 by Aaron Bentley
Got conflicts on symlinks working properly
1827
1828
    def test_file_merge(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1829
        self.requireFeature(SymlinkFeature)
2116.4.1 by John Arbash Meinel
Update file and revision id generators.
1830
        root_id = generate_ids.gen_root_id()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1831
        base = TransformGroup("BASE", root_id)
1832
        this = TransformGroup("THIS", root_id)
1833
        other = TransformGroup("OTHER", root_id)
1534.7.101 by Aaron Bentley
Got conflicts on symlinks working properly
1834
        for tg in this, base, other:
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1835
            tg.tt.new_directory('a', tg.root, b'a')
6973.10.1 by Jelmer Vernooij
Fix some tests.
1836
            tg.tt.new_symlink('b', tg.root, 'b', b'b')
1837
            tg.tt.new_file('c', tg.root, [b'c'], b'c')
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1838
            tg.tt.new_symlink('d', tg.root, tg.name, b'd')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1839
        targets = ((base, 'base-e', 'base-f', None, None),
1840
                   (this, 'other-e', 'this-f', 'other-g', 'this-h'),
1534.7.104 by Aaron Bentley
Fixed set_versioned, enhanced conflict testing
1841
                   (other, 'other-e', None, 'other-g', 'other-h'))
1842
        for tg, e_target, f_target, g_target, h_target in targets:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1843
            for link, target in (('e', e_target), ('f', f_target),
1534.7.104 by Aaron Bentley
Fixed set_versioned, enhanced conflict testing
1844
                                 ('g', g_target), ('h', h_target)):
1845
                if target is not None:
7143.15.2 by Jelmer Vernooij
Run autopep8.
1846
                    tg.tt.new_symlink(link, tg.root, target,
1847
                                      link.encode('ascii'))
1534.7.102 by Aaron Bentley
Deleted old pre-conflict contents
1848
1849
        for tg in this, base, other:
1534.7.101 by Aaron Bentley
Got conflicts on symlinks working properly
1850
            tg.tt.apply()
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
1851
        Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1534.7.101 by Aaron Bentley
Got conflicts on symlinks working properly
1852
        self.assertIs(os.path.isdir(this.wt.abspath('a')), True)
1853
        self.assertIs(os.path.islink(this.wt.abspath('b')), True)
1854
        self.assertIs(os.path.isfile(this.wt.abspath('c')), True)
1855
        for suffix in ('THIS', 'BASE', 'OTHER'):
7143.15.2 by Jelmer Vernooij
Run autopep8.
1856
            self.assertEqual(os.readlink(
1857
                this.wt.abspath('d.' + suffix)), suffix)
1534.7.102 by Aaron Bentley
Deleted old pre-conflict contents
1858
        self.assertIs(os.path.lexists(this.wt.abspath('d')), False)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1859
        self.assertEqual(this.wt.id2path(b'd'), 'd.OTHER')
1860
        self.assertEqual(this.wt.id2path(b'f'), 'f.THIS')
1534.7.102 by Aaron Bentley
Deleted old pre-conflict contents
1861
        self.assertEqual(os.readlink(this.wt.abspath('e')), 'other-e')
1862
        self.assertIs(os.path.lexists(this.wt.abspath('e.THIS')), False)
1863
        self.assertIs(os.path.lexists(this.wt.abspath('e.OTHER')), False)
1864
        self.assertIs(os.path.lexists(this.wt.abspath('e.BASE')), False)
1534.7.104 by Aaron Bentley
Fixed set_versioned, enhanced conflict testing
1865
        self.assertIs(os.path.lexists(this.wt.abspath('g')), True)
1866
        self.assertIs(os.path.lexists(this.wt.abspath('g.BASE')), False)
1867
        self.assertIs(os.path.lexists(this.wt.abspath('h')), False)
1868
        self.assertIs(os.path.lexists(this.wt.abspath('h.BASE')), False)
1869
        self.assertIs(os.path.lexists(this.wt.abspath('h.THIS')), True)
1870
        self.assertIs(os.path.lexists(this.wt.abspath('h.OTHER')), True)
1534.7.105 by Aaron Bentley
Got merge with rename working
1871
1872
    def test_filename_merge(self):
2116.4.1 by John Arbash Meinel
Update file and revision id generators.
1873
        root_id = generate_ids.gen_root_id()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1874
        base = TransformGroup("BASE", root_id)
1875
        this = TransformGroup("THIS", root_id)
1876
        other = TransformGroup("OTHER", root_id)
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
1877
        base_a, this_a, other_a = [t.tt.new_directory('a', t.root, b'a')
1878
                                   for t in [base, this, other]]
1879
        base_b, this_b, other_b = [t.tt.new_directory('b', t.root, b'b')
1880
                                   for t in [base, this, other]]
1881
        base.tt.new_directory('c', base_a, b'c')
1882
        this.tt.new_directory('c1', this_a, b'c')
1883
        other.tt.new_directory('c', other_b, b'c')
1884
1885
        base.tt.new_directory('d', base_a, b'd')
1886
        this.tt.new_directory('d1', this_b, b'd')
1887
        other.tt.new_directory('d', other_a, b'd')
1888
1889
        base.tt.new_directory('e', base_a, b'e')
1890
        this.tt.new_directory('e', this_a, b'e')
1891
        other.tt.new_directory('e1', other_b, b'e')
1892
1893
        base.tt.new_directory('f', base_a, b'f')
1894
        this.tt.new_directory('f1', this_b, b'f')
1895
        other.tt.new_directory('f1', other_b, b'f')
1534.7.105 by Aaron Bentley
Got merge with rename working
1896
1897
        for tg in [this, base, other]:
1898
            tg.tt.apply()
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
1899
        Merge3Merger(this.wt, this.wt, base.wt, other.wt)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1900
        self.assertEqual(this.wt.id2path(b'c'), pathjoin('b/c1'))
1901
        self.assertEqual(this.wt.id2path(b'd'), pathjoin('b/d1'))
1902
        self.assertEqual(this.wt.id2path(b'e'), pathjoin('b/e1'))
1903
        self.assertEqual(this.wt.id2path(b'f'), pathjoin('b/f1'))
1534.7.105 by Aaron Bentley
Got merge with rename working
1904
1905
    def test_filename_merge_conflicts(self):
2116.4.1 by John Arbash Meinel
Update file and revision id generators.
1906
        root_id = generate_ids.gen_root_id()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1907
        base = TransformGroup("BASE", root_id)
1908
        this = TransformGroup("THIS", root_id)
1909
        other = TransformGroup("OTHER", root_id)
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
1910
        base_a, this_a, other_a = [t.tt.new_directory('a', t.root, b'a')
1534.7.105 by Aaron Bentley
Got merge with rename working
1911
                                   for t in [base, this, other]]
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
1912
        base_b, this_b, other_b = [t.tt.new_directory('b', t.root, b'b')
1534.7.105 by Aaron Bentley
Got merge with rename working
1913
                                   for t in [base, this, other]]
1914
6973.10.1 by Jelmer Vernooij
Fix some tests.
1915
        base.tt.new_file('g', base_a, [b'g'], b'g')
1916
        other.tt.new_file('g1', other_b, [b'g1'], b'g')
1917
1918
        base.tt.new_file('h', base_a, [b'h'], b'h')
1919
        this.tt.new_file('h1', this_b, [b'h1'], b'h')
1920
1921
        base.tt.new_file('i', base.root, [b'i'], b'i')
1922
        other.tt.new_directory('i1', this_b, b'i')
1534.7.105 by Aaron Bentley
Got merge with rename working
1923
1924
        for tg in [this, base, other]:
1925
            tg.tt.apply()
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
1926
        Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1534.7.105 by Aaron Bentley
Got merge with rename working
1927
6855.4.1 by Jelmer Vernooij
Yet more bees.
1928
        self.assertEqual(this.wt.id2path(b'g'), pathjoin('b/g1.OTHER'))
1534.7.105 by Aaron Bentley
Got merge with rename working
1929
        self.assertIs(os.path.lexists(this.wt.abspath('b/g1.BASE')), True)
1930
        self.assertIs(os.path.lexists(this.wt.abspath('b/g1.THIS')), False)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1931
        self.assertEqual(this.wt.id2path(b'h'), pathjoin('b/h1.THIS'))
1534.7.105 by Aaron Bentley
Got merge with rename working
1932
        self.assertIs(os.path.lexists(this.wt.abspath('b/h1.BASE')), True)
1933
        self.assertIs(os.path.lexists(this.wt.abspath('b/h1.OTHER')), False)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1934
        self.assertEqual(this.wt.id2path(b'i'), pathjoin('b/i1.OTHER'))
1534.7.183 by Aaron Bentley
Fixed build_tree with symlinks
1935
2027.1.1 by John Arbash Meinel
Fix bug #56549, and write a direct test that the right path is being statted
1936
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1937
class TestBuildTree(tests.TestCaseWithTransport):
1938
3006.2.2 by Alexander Belchenko
tests added.
1939
    def test_build_tree_with_symlinks(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1940
        self.requireFeature(SymlinkFeature)
1534.7.183 by Aaron Bentley
Fixed build_tree with symlinks
1941
        os.mkdir('a')
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
1942
        a = ControlDir.create_standalone_workingtree('a')
1534.7.183 by Aaron Bentley
Fixed build_tree with symlinks
1943
        os.mkdir('a/foo')
7143.15.2 by Jelmer Vernooij
Run autopep8.
1944
        with open('a/foo/bar', 'wb') as f:
1945
            f.write(b'contents')
1534.7.183 by Aaron Bentley
Fixed build_tree with symlinks
1946
        os.symlink('a/foo/bar', 'a/foo/baz')
1947
        a.add(['foo', 'foo/bar', 'foo/baz'])
1948
        a.commit('initial commit')
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
1949
        b = ControlDir.create_standalone_workingtree('b')
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
1950
        basis = a.basis_tree()
1951
        basis.lock_read()
1952
        self.addCleanup(basis.unlock)
1953
        build_tree(basis, b)
1534.7.183 by Aaron Bentley
Fixed build_tree with symlinks
1954
        self.assertIs(os.path.isdir('b/foo'), True)
6973.7.5 by Jelmer Vernooij
s/file/open.
1955
        with open('b/foo/bar', 'rb') as f:
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
1956
            self.assertEqual(f.read(), b"contents")
1534.7.183 by Aaron Bentley
Fixed build_tree with symlinks
1957
        self.assertEqual(os.readlink('b/foo/baz'), 'a/foo/bar')
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1958
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
1959
    def test_build_with_references(self):
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
1960
        tree = self.make_branch_and_tree('source',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1961
                                         format='development-subtree')
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
1962
        subtree = self.make_branch_and_tree('source/subtree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1963
                                            format='development-subtree')
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
1964
        tree.add_reference(subtree)
1965
        tree.commit('a revision')
1966
        tree.branch.create_checkout('target')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1967
        self.assertPathExists('target')
1968
        self.assertPathExists('target/subtree')
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
1969
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1970
    def test_file_conflict_handling(self):
1971
        """Ensure that when building trees, conflict handling is done"""
1972
        source = self.make_branch_and_tree('source')
1973
        target = self.make_branch_and_tree('target')
1974
        self.build_tree(['source/file', 'target/file'])
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1975
        source.add('file', b'new-file')
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1976
        source.commit('added file')
1977
        build_tree(source.basis_tree(), target)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1978
        self.assertEqual(
1979
            [DuplicateEntry('Moved existing file to', 'file.moved',
1980
                            'file', None, 'new-file')],
1981
            target.conflicts())
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1982
        target2 = self.make_branch_and_tree('target2')
6973.7.5 by Jelmer Vernooij
s/file/open.
1983
        with open('target2/file', 'wb') as target_file, \
1984
                open('source/file', 'rb') as source_file:
1985
            target_file.write(source_file.read())
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1986
        build_tree(source.basis_tree(), target2)
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
1987
        self.assertEqual([], target2.conflicts())
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1988
1989
    def test_symlink_conflict_handling(self):
1990
        """Ensure that when building trees, conflict handling is done"""
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1991
        self.requireFeature(SymlinkFeature)
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1992
        source = self.make_branch_and_tree('source')
1993
        os.symlink('foo', 'source/symlink')
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
1994
        source.add('symlink', b'new-symlink')
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
1995
        source.commit('added file')
1996
        target = self.make_branch_and_tree('target')
1997
        os.symlink('bar', 'target/symlink')
1998
        build_tree(source.basis_tree(), target)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
1999
        self.assertEqual(
2000
            [DuplicateEntry('Moved existing file to', 'symlink.moved',
2001
                            'symlink', None, 'new-symlink')],
2002
            target.conflicts())
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2003
        target = self.make_branch_and_tree('target2')
2004
        os.symlink('foo', 'target2/symlink')
2005
        build_tree(source.basis_tree(), target)
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2006
        self.assertEqual([], target.conflicts())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2007
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2008
    def test_directory_conflict_handling(self):
2009
        """Ensure that when building trees, conflict handling is done"""
2010
        source = self.make_branch_and_tree('source')
2011
        target = self.make_branch_and_tree('target')
2012
        self.build_tree(['source/dir1/', 'source/dir1/file', 'target/dir1/'])
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
2013
        source.add(['dir1', 'dir1/file'], [b'new-dir1', b'new-file'])
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2014
        source.commit('added file')
2015
        build_tree(source.basis_tree(), target)
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2016
        self.assertEqual([], target.conflicts())
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2017
        self.assertPathExists('target/dir1/file')
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2018
2019
        # Ensure contents are merged
2020
        target = self.make_branch_and_tree('target2')
2021
        self.build_tree(['target2/dir1/', 'target2/dir1/file2'])
2022
        build_tree(source.basis_tree(), target)
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2023
        self.assertEqual([], target.conflicts())
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2024
        self.assertPathExists('target2/dir1/file2')
2025
        self.assertPathExists('target2/dir1/file')
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2026
2027
        # Ensure new contents are suppressed for existing branches
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2028
        target = self.make_branch_and_tree('target3')
2029
        self.make_branch('target3/dir1')
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2030
        self.build_tree(['target3/dir1/file2'])
2031
        build_tree(source.basis_tree(), target)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2032
        self.assertPathDoesNotExist('target3/dir1/file')
2033
        self.assertPathExists('target3/dir1/file2')
2034
        self.assertPathExists('target3/dir1.diverted/file')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2035
        self.assertEqual(
2036
            [DuplicateEntry('Diverted to', 'dir1.diverted',
2037
                            'dir1', 'new-dir1', None)],
2038
            target.conflicts())
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2039
2040
        target = self.make_branch_and_tree('target4')
2041
        self.build_tree(['target4/dir1/'])
2042
        self.make_branch('target4/dir1/file')
2043
        build_tree(source.basis_tree(), target)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2044
        self.assertPathExists('target4/dir1/file')
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2045
        self.assertEqual('directory', file_kind('target4/dir1/file'))
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2046
        self.assertPathExists('target4/dir1/file.diverted')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2047
        self.assertEqual(
2048
            [DuplicateEntry('Diverted to', 'dir1/file.diverted',
2049
                            'dir1/file', 'new-file', None)],
2050
            target.conflicts())
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2051
2052
    def test_mixed_conflict_handling(self):
2053
        """Ensure that when building trees, conflict handling is done"""
2054
        source = self.make_branch_and_tree('source')
2055
        target = self.make_branch_and_tree('target')
2056
        self.build_tree(['source/name', 'target/name/'])
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
2057
        source.add('name', b'new-name')
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2058
        source.commit('added file')
2059
        build_tree(source.basis_tree(), target)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2060
        self.assertEqual(
2061
            [DuplicateEntry('Moved existing file to',
2062
                            'name.moved', 'name', None, 'new-name')],
2063
            target.conflicts())
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2064
2065
    def test_raises_in_populated(self):
2066
        source = self.make_branch_and_tree('source')
2067
        self.build_tree(['source/name'])
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2068
        source.add('name')
1966.1.2 by Aaron Bentley
Divert files instead of failing to create them, update from review
2069
        source.commit('added name')
2070
        target = self.make_branch_and_tree('target')
2071
        self.build_tree(['target/name'])
2072
        target.add('name')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2073
        self.assertRaises(errors.WorkingTreeAlreadyPopulated,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2074
                          build_tree, source.basis_tree(), target)
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2075
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
2076
    def test_build_tree_rename_count(self):
2077
        source = self.make_branch_and_tree('source')
2078
        self.build_tree(['source/file1', 'source/dir1/'])
2079
        source.add(['file1', 'dir1'])
2080
        source.commit('add1')
2081
        target1 = self.make_branch_and_tree('target1')
2502.1.6 by Aaron Bentley
Update from review comments
2082
        transform_result = build_tree(source.basis_tree(), target1)
2083
        self.assertEqual(2, transform_result.rename_count)
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
2084
2085
        self.build_tree(['source/dir1/file2'])
2086
        source.add(['dir1/file2'])
2087
        source.commit('add3')
2088
        target2 = self.make_branch_and_tree('target2')
2502.1.6 by Aaron Bentley
Update from review comments
2089
        transform_result = build_tree(source.basis_tree(), target2)
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
2090
        # children of non-root directories should not be renamed
2502.1.6 by Aaron Bentley
Update from review comments
2091
        self.assertEqual(2, transform_result.rename_count)
2502.1.1 by Aaron Bentley
Ensure renames only root children are renamed when building trees
2092
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2093
    def create_ab_tree(self):
2094
        """Create a committed test tree with two files"""
2095
        source = self.make_branch_and_tree('source')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2096
        self.build_tree_contents([('source/file1', b'A')])
2097
        self.build_tree_contents([('source/file2', b'B')])
2098
        source.add(['file1', 'file2'], [b'file1-id', b'file2-id'])
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2099
        source.commit('commit files')
2100
        source.lock_write()
2101
        self.addCleanup(source.unlock)
2102
        return source
2103
3123.5.1 by Aaron Bentley
Make build-tree able to use an additional 'accelerator' tree
2104
    def test_build_tree_accelerator_tree(self):
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2105
        source = self.create_ab_tree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2106
        self.build_tree_contents([('source/file2', b'C')])
3123.5.1 by Aaron Bentley
Make build-tree able to use an additional 'accelerator' tree
2107
        calls = []
2108
        real_source_get_file = source.get_file
7143.15.2 by Jelmer Vernooij
Run autopep8.
2109
7192.5.1 by Jelmer Vernooij
Remove more file ids.
2110
        def get_file(path):
2111
            calls.append(path)
2112
            return real_source_get_file(path)
3123.5.1 by Aaron Bentley
Make build-tree able to use an additional 'accelerator' tree
2113
        source.get_file = get_file
2114
        target = self.make_branch_and_tree('target')
3123.5.19 by Aaron Bentley
Ensure content is exactly the same, when accelerator used
2115
        revision_tree = source.basis_tree()
2116
        revision_tree.lock_read()
2117
        self.addCleanup(revision_tree.unlock)
2118
        build_tree(revision_tree, target, source)
7192.5.1 by Jelmer Vernooij
Remove more file ids.
2119
        self.assertEqual(['file1'], calls)
3123.5.19 by Aaron Bentley
Ensure content is exactly the same, when accelerator used
2120
        target.lock_read()
2121
        self.addCleanup(target.unlock)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2122
        self.assertEqual([], list(target.iter_changes(revision_tree)))
3123.5.1 by Aaron Bentley
Make build-tree able to use an additional 'accelerator' tree
2123
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2124
    def test_build_tree_accelerator_tree_observes_sha1(self):
2125
        source = self.create_ab_tree()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2126
        sha1 = osutils.sha_string(b'A')
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2127
        target = self.make_branch_and_tree('target')
2128
        target.lock_write()
2129
        self.addCleanup(target.unlock)
2130
        state = target.current_dirstate()
2131
        state._cutoff_time = time.time() + 60
2132
        build_tree(source.basis_tree(), target, source)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2133
        entry = state._get_entry(0, path_utf8=b'file1')
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2134
        self.assertEqual(sha1, entry[1][0][1])
2135
3123.5.4 by Aaron Bentley
Use an accelerator tree when branching, handle no-such-id correctly
2136
    def test_build_tree_accelerator_tree_missing_file(self):
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2137
        source = self.create_ab_tree()
3123.5.4 by Aaron Bentley
Use an accelerator tree when branching, handle no-such-id correctly
2138
        os.unlink('source/file1')
2139
        source.remove(['file2'])
2140
        target = self.make_branch_and_tree('target')
3123.5.19 by Aaron Bentley
Ensure content is exactly the same, when accelerator used
2141
        revision_tree = source.basis_tree()
2142
        revision_tree.lock_read()
2143
        self.addCleanup(revision_tree.unlock)
2144
        build_tree(revision_tree, target, source)
2145
        target.lock_read()
2146
        self.addCleanup(target.unlock)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2147
        self.assertEqual([], list(target.iter_changes(revision_tree)))
3123.5.4 by Aaron Bentley
Use an accelerator tree when branching, handle no-such-id correctly
2148
3123.5.16 by Aaron Bentley
Test handling of conversion to non-file
2149
    def test_build_tree_accelerator_wrong_kind(self):
3146.4.8 by Aaron Bentley
Add missing symlink requirement
2150
        self.requireFeature(SymlinkFeature)
3123.5.16 by Aaron Bentley
Test handling of conversion to non-file
2151
        source = self.make_branch_and_tree('source')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2152
        self.build_tree_contents([('source/file1', b'')])
2153
        self.build_tree_contents([('source/file2', b'')])
2154
        source.add(['file1', 'file2'], [b'file1-id', b'file2-id'])
3123.5.16 by Aaron Bentley
Test handling of conversion to non-file
2155
        source.commit('commit files')
2156
        os.unlink('source/file2')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2157
        self.build_tree_contents([('source/file2/', b'C')])
3123.5.16 by Aaron Bentley
Test handling of conversion to non-file
2158
        os.unlink('source/file1')
2159
        os.symlink('file2', 'source/file1')
2160
        calls = []
2161
        real_source_get_file = source.get_file
7143.15.2 by Jelmer Vernooij
Run autopep8.
2162
7192.5.1 by Jelmer Vernooij
Remove more file ids.
2163
        def get_file(path):
2164
            calls.append(path)
2165
            return real_source_get_file(path)
3123.5.16 by Aaron Bentley
Test handling of conversion to non-file
2166
        source.get_file = get_file
2167
        target = self.make_branch_and_tree('target')
3123.5.19 by Aaron Bentley
Ensure content is exactly the same, when accelerator used
2168
        revision_tree = source.basis_tree()
2169
        revision_tree.lock_read()
2170
        self.addCleanup(revision_tree.unlock)
2171
        build_tree(revision_tree, target, source)
3123.5.16 by Aaron Bentley
Test handling of conversion to non-file
2172
        self.assertEqual([], calls)
3123.5.19 by Aaron Bentley
Ensure content is exactly the same, when accelerator used
2173
        target.lock_read()
2174
        self.addCleanup(target.unlock)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2175
        self.assertEqual([], list(target.iter_changes(revision_tree)))
3123.5.16 by Aaron Bentley
Test handling of conversion to non-file
2176
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2177
    def test_build_tree_hardlink(self):
2178
        self.requireFeature(HardlinkFeature)
2179
        source = self.create_ab_tree()
2180
        target = self.make_branch_and_tree('target')
2181
        revision_tree = source.basis_tree()
2182
        revision_tree.lock_read()
2183
        self.addCleanup(revision_tree.unlock)
2184
        build_tree(revision_tree, target, source, hardlink=True)
2185
        target.lock_read()
2186
        self.addCleanup(target.unlock)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2187
        self.assertEqual([], list(target.iter_changes(revision_tree)))
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2188
        source_stat = os.stat('source/file1')
2189
        target_stat = os.stat('target/file1')
2190
        self.assertEqual(source_stat, target_stat)
2191
2192
        # Explicitly disallowing hardlinks should prevent them.
2193
        target2 = self.make_branch_and_tree('target2')
2194
        build_tree(revision_tree, target2, source, hardlink=False)
2195
        target2.lock_read()
2196
        self.addCleanup(target2.unlock)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2197
        self.assertEqual([], list(target2.iter_changes(revision_tree)))
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2198
        source_stat = os.stat('source/file1')
2199
        target2_stat = os.stat('target2/file1')
2200
        self.assertNotEqual(source_stat, target2_stat)
2201
3137.1.1 by Aaron Bentley
Fix build_tree acceleration when file is moved in accelerator_tree
2202
    def test_build_tree_accelerator_tree_moved(self):
2203
        source = self.make_branch_and_tree('source')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2204
        self.build_tree_contents([('source/file1', b'A')])
2205
        source.add(['file1'], [b'file1-id'])
3137.1.1 by Aaron Bentley
Fix build_tree acceleration when file is moved in accelerator_tree
2206
        source.commit('commit files')
2207
        source.rename_one('file1', 'file2')
2208
        source.lock_read()
2209
        self.addCleanup(source.unlock)
2210
        target = self.make_branch_and_tree('target')
2211
        revision_tree = source.basis_tree()
2212
        revision_tree.lock_read()
2213
        self.addCleanup(revision_tree.unlock)
2214
        build_tree(revision_tree, target, source)
2215
        target.lock_read()
2216
        self.addCleanup(target.unlock)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2217
        self.assertEqual([], list(target.iter_changes(revision_tree)))
3137.1.1 by Aaron Bentley
Fix build_tree acceleration when file is moved in accelerator_tree
2218
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2219
    def test_build_tree_hardlinks_preserve_execute(self):
2220
        self.requireFeature(HardlinkFeature)
2221
        source = self.create_ab_tree()
2222
        tt = TreeTransform(source)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
2223
        trans_id = tt.trans_id_tree_path('file1')
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2224
        tt.set_executability(True, trans_id)
2225
        tt.apply()
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
2226
        self.assertTrue(source.is_executable('file1'))
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2227
        target = self.make_branch_and_tree('target')
2228
        revision_tree = source.basis_tree()
2229
        revision_tree.lock_read()
2230
        self.addCleanup(revision_tree.unlock)
2231
        build_tree(revision_tree, target, source, hardlink=True)
2232
        target.lock_read()
2233
        self.addCleanup(target.unlock)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2234
        self.assertEqual([], list(target.iter_changes(revision_tree)))
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
2235
        self.assertTrue(source.is_executable('file1'))
3136.1.2 by Aaron Bentley
Implement hard-linking for build_tree
2236
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2237
    def install_rot13_content_filter(self, pattern):
4985.2.1 by Vincent Ladeuil
Deploy addAttrCleanup on the whole test suite.
2238
        # We could use
2239
        # self.addCleanup(filters._reset_registry, filters._reset_registry())
2240
        # below, but that looks a bit... hard to read even if it's exactly
2241
        # the same thing.
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2242
        original_registry = filters._reset_registry()
7143.15.2 by Jelmer Vernooij
Run autopep8.
2243
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2244
        def restore_registry():
2245
            filters._reset_registry(original_registry)
2246
        self.addCleanup(restore_registry)
7143.15.2 by Jelmer Vernooij
Run autopep8.
2247
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2248
        def rot13(chunks, context=None):
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2249
            return [
2250
                codecs.encode(chunk.decode('ascii'), 'rot13').encode('ascii')
2251
                for chunk in chunks]
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2252
        rot13filter = filters.ContentFilter(rot13, rot13)
6498.5.3 by Jelmer Vernooij
Fix tests.
2253
        filters.filter_stacks_registry.register(
2254
            'rot13', {'yes': [rot13filter]}.get)
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2255
        os.mkdir(self.test_home_dir + '/.bazaar')
2256
        rules_filename = self.test_home_dir + '/.bazaar/rules'
6973.7.5 by Jelmer Vernooij
s/file/open.
2257
        with open(rules_filename, 'wb') as f:
2258
            f.write(b'[name %s]\nrot13=yes\n' % (pattern,))
7143.15.2 by Jelmer Vernooij
Run autopep8.
2259
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2260
        def uninstall_rules():
2261
            os.remove(rules_filename)
2262
            rules.reset_rules()
2263
        self.addCleanup(uninstall_rules)
2264
        rules.reset_rules()
2265
2266
    def test_build_tree_content_filtered_files_are_not_hardlinked(self):
2267
        """build_tree will not hardlink files that have content filtering rules
2268
        applied to them (but will still hardlink other files from the same tree
2269
        if it can).
2270
        """
2271
        self.requireFeature(HardlinkFeature)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2272
        self.install_rot13_content_filter(b'file1')
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2273
        source = self.create_ab_tree()
2274
        target = self.make_branch_and_tree('target')
2275
        revision_tree = source.basis_tree()
2276
        revision_tree.lock_read()
2277
        self.addCleanup(revision_tree.unlock)
2278
        build_tree(revision_tree, target, source, hardlink=True)
2279
        target.lock_read()
2280
        self.addCleanup(target.unlock)
2281
        self.assertEqual([], list(target.iter_changes(revision_tree)))
2282
        source_stat = os.stat('source/file1')
2283
        target_stat = os.stat('target/file1')
2284
        self.assertNotEqual(source_stat, target_stat)
2285
        source_stat = os.stat('source/file2')
2286
        target_stat = os.stat('target/file2')
4826.1.8 by Andrew Bennetts
Tweaks suggested by John.
2287
        self.assertEqualStat(source_stat, target_stat)
4826.1.5 by Andrew Bennetts
Add test that content filtered files are not hardlinked by build_tree.
2288
3453.2.4 by Aaron Bentley
Disable fast-path when conflicts are encountered
2289
    def test_case_insensitive_build_tree_inventory(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
2290
        if (features.CaseInsensitiveFilesystemFeature.available()
7143.15.2 by Jelmer Vernooij
Run autopep8.
2291
                or features.CaseInsCasePresFilenameFeature.available()):
4241.9.4 by Vincent Ladeuil
Fix test_case_insensitive_build_tree_inventory failure on OSX.
2292
            raise tests.UnavailableFeature('Fully case sensitive filesystem')
3453.2.4 by Aaron Bentley
Disable fast-path when conflicts are encountered
2293
        source = self.make_branch_and_tree('source')
2294
        self.build_tree(['source/file', 'source/FILE'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
2295
        source.add(['file', 'FILE'], [b'lower-id', b'upper-id'])
3453.2.4 by Aaron Bentley
Disable fast-path when conflicts are encountered
2296
        source.commit('added files')
2297
        # Don't try this at home, kids!
2298
        # Force the tree to report that it is case insensitive
2299
        target = self.make_branch_and_tree('target')
2300
        target.case_sensitive = False
3453.2.6 by Aaron Bentley
Rename mutate_tree to delta_from_tree, add comment
2301
        build_tree(source.basis_tree(), target, source, delta_from_tree=True)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2302
        self.assertEqual('file.moved', target.id2path(b'lower-id'))
2303
        self.assertEqual('FILE', target.id2path(b'upper-id'))
3453.2.4 by Aaron Bentley
Disable fast-path when conflicts are encountered
2304
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2305
    def test_build_tree_observes_sha(self):
2306
        source = self.make_branch_and_tree('source')
2307
        self.build_tree(['source/file1', 'source/dir/', 'source/dir/file2'])
2308
        source.add(['file1', 'dir', 'dir/file2'],
6855.4.1 by Jelmer Vernooij
Yet more bees.
2309
                   [b'file1-id', b'dir-id', b'file2-id'])
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2310
        source.commit('new files')
2311
        target = self.make_branch_and_tree('target')
2312
        target.lock_write()
2313
        self.addCleanup(target.unlock)
2314
        # We make use of the fact that DirState caches its cutoff time. So we
2315
        # set the 'safe' time to one minute in the future.
2316
        state = target.current_dirstate()
2317
        state._cutoff_time = time.time() + 60
2318
        build_tree(source.basis_tree(), target)
2319
        entry1_sha = osutils.sha_file_by_name('source/file1')
2320
        entry2_sha = osutils.sha_file_by_name('source/dir/file2')
2321
        # entry[1] is the state information, entry[1][0] is the state of the
2322
        # working tree, entry[1][0][1] is the sha value for the current working
2323
        # tree
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
2324
        entry1 = state._get_entry(0, path_utf8=b'file1')
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2325
        self.assertEqual(entry1_sha, entry1[1][0][1])
2326
        # The 'size' field must also be set.
2327
        self.assertEqual(25, entry1[1][0][2])
2328
        entry1_state = entry1[1][0]
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
2329
        entry2 = state._get_entry(0, path_utf8=b'dir/file2')
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2330
        self.assertEqual(entry2_sha, entry2[1][0][1])
2331
        self.assertEqual(29, entry2[1][0][2])
2332
        entry2_state = entry2[1][0]
2333
        # Now, make sure that we don't have to re-read the content. The
2334
        # packed_stat should match exactly.
7141.7.2 by Jelmer Vernooij
Fix more tests.
2335
        self.assertEqual(entry1_sha, target.get_file_sha1('file1'))
2336
        self.assertEqual(entry2_sha, target.get_file_sha1('dir/file2'))
5752.5.1 by John Arbash Meinel
Merge up transform-create-file
2337
        self.assertEqual(entry1_state, entry1[1][0])
2338
        self.assertEqual(entry2_state, entry2[1][0])
2339
1966.1.1 by Aaron Bentley
Implement disk-content merge and conflict resolution for build_tree
2340
4526.8.1 by Aaron Bentley
Support committing a TreeTransform to a branch.
2341
class TestCommitTransform(tests.TestCaseWithTransport):
2342
2343
    def get_branch(self):
2344
        tree = self.make_branch_and_tree('tree')
2345
        tree.lock_write()
2346
        self.addCleanup(tree.unlock)
2347
        tree.commit('empty commit')
2348
        return tree.branch
2349
2350
    def get_branch_and_transform(self):
2351
        branch = self.get_branch()
2352
        tt = TransformPreview(branch.basis_tree())
2353
        self.addCleanup(tt.finalize)
2354
        return branch, tt
2355
2356
    def test_commit_wrong_basis(self):
2357
        branch = self.get_branch()
2358
        basis = branch.repository.revision_tree(
2359
            _mod_revision.NULL_REVISION)
2360
        tt = TransformPreview(basis)
2361
        self.addCleanup(tt.finalize)
4526.8.5 by Aaron Bentley
Updates from review.
2362
        e = self.assertRaises(ValueError, tt.commit, branch, '')
4526.8.1 by Aaron Bentley
Support committing a TreeTransform to a branch.
2363
        self.assertEqual('TreeTransform not based on branch basis: null:',
2364
                         str(e))
2365
2366
    def test_empy_commit(self):
2367
        branch, tt = self.get_branch_and_transform()
2368
        rev = tt.commit(branch, 'my message')
2369
        self.assertEqual(2, branch.revno())
2370
        repo = branch.repository
2371
        self.assertEqual('my message', repo.get_revision(rev).message)
2372
2373
    def test_merge_parents(self):
2374
        branch, tt = self.get_branch_and_transform()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2375
        tt.commit(branch, 'my message', [b'rev1b', b'rev1c'])
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
2376
        self.assertEqual([b'rev1b', b'rev1c'],
4526.8.1 by Aaron Bentley
Support committing a TreeTransform to a branch.
2377
                         branch.basis_tree().get_parent_ids()[1:])
2378
4526.8.3 by Aaron Bentley
Clean up merge parent handling.
2379
    def test_first_commit(self):
2380
        branch = self.make_branch('branch')
2381
        branch.lock_write()
2382
        self.addCleanup(branch.unlock)
2383
        tt = TransformPreview(branch.basis_tree())
4659.2.4 by Vincent Ladeuil
Cleanup remaining bzr-limbo-XXXXXX leaks in /tmp during selftest.
2384
        self.addCleanup(tt.finalize)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
2385
        tt.new_directory('', ROOT_PARENT, b'TREE_ROOT')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2386
        tt.commit(branch, 'my message')
4526.8.3 by Aaron Bentley
Clean up merge parent handling.
2387
        self.assertEqual([], branch.basis_tree().get_parent_ids())
4526.8.5 by Aaron Bentley
Updates from review.
2388
        self.assertNotEqual(_mod_revision.NULL_REVISION,
2389
                            branch.last_revision())
4526.8.3 by Aaron Bentley
Clean up merge parent handling.
2390
4526.8.5 by Aaron Bentley
Updates from review.
2391
    def test_first_commit_with_merge_parents(self):
4526.8.3 by Aaron Bentley
Clean up merge parent handling.
2392
        branch = self.make_branch('branch')
2393
        branch.lock_write()
2394
        self.addCleanup(branch.unlock)
2395
        tt = TransformPreview(branch.basis_tree())
4659.2.4 by Vincent Ladeuil
Cleanup remaining bzr-limbo-XXXXXX leaks in /tmp during selftest.
2396
        self.addCleanup(tt.finalize)
4526.8.5 by Aaron Bentley
Updates from review.
2397
        e = self.assertRaises(ValueError, tt.commit, branch,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2398
                              'my message', [b'rev1b-id'])
4526.8.5 by Aaron Bentley
Updates from review.
2399
        self.assertEqual('Cannot supply merge parents for first commit.',
2400
                         str(e))
2401
        self.assertEqual(_mod_revision.NULL_REVISION, branch.last_revision())
4526.8.3 by Aaron Bentley
Clean up merge parent handling.
2402
4526.8.1 by Aaron Bentley
Support committing a TreeTransform to a branch.
2403
    def test_add_files(self):
2404
        branch, tt = self.get_branch_and_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2405
        tt.new_file('file', tt.root, [b'contents'], b'file-id')
2406
        trans_id = tt.new_directory('dir', tt.root, b'dir-id')
4789.25.2 by John Arbash Meinel
Fix 3 tests that meant to skip exec or symlink testing on win32
2407
        if SymlinkFeature.available():
6973.10.1 by Jelmer Vernooij
Fix some tests.
2408
            tt.new_symlink('symlink', trans_id, 'target', b'symlink-id')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2409
        tt.commit(branch, 'message')
4526.8.1 by Aaron Bentley
Support committing a TreeTransform to a branch.
2410
        tree = branch.basis_tree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2411
        self.assertEqual('file', tree.id2path(b'file-id'))
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
2412
        self.assertEqual(b'contents', tree.get_file_text('file'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2413
        self.assertEqual('dir', tree.id2path(b'dir-id'))
4789.25.2 by John Arbash Meinel
Fix 3 tests that meant to skip exec or symlink testing on win32
2414
        if SymlinkFeature.available():
6855.4.1 by Jelmer Vernooij
Yet more bees.
2415
            self.assertEqual('dir/symlink', tree.id2path(b'symlink-id'))
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2416
            self.assertEqual('target', tree.get_symlink_target('dir/symlink'))
4526.8.1 by Aaron Bentley
Support committing a TreeTransform to a branch.
2417
4526.8.2 by Aaron Bentley
Proved strict commit handling.
2418
    def test_add_unversioned(self):
2419
        branch, tt = self.get_branch_and_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2420
        tt.new_file('file', tt.root, [b'contents'])
4526.8.2 by Aaron Bentley
Proved strict commit handling.
2421
        self.assertRaises(errors.StrictCommitFailed, tt.commit, branch,
2422
                          'message', strict=True)
2423
2424
    def test_modify_strict(self):
2425
        branch, tt = self.get_branch_and_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2426
        tt.new_file('file', tt.root, [b'contents'], b'file-id')
4526.8.2 by Aaron Bentley
Proved strict commit handling.
2427
        tt.commit(branch, 'message', strict=True)
2428
        tt = TransformPreview(branch.basis_tree())
4659.2.4 by Vincent Ladeuil
Cleanup remaining bzr-limbo-XXXXXX leaks in /tmp during selftest.
2429
        self.addCleanup(tt.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2430
        trans_id = tt.trans_id_file_id(b'file-id')
4526.8.2 by Aaron Bentley
Proved strict commit handling.
2431
        tt.delete_contents(trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
2432
        tt.create_file([b'contents'], trans_id)
4526.8.2 by Aaron Bentley
Proved strict commit handling.
2433
        tt.commit(branch, 'message', strict=True)
2434
4526.8.6 by Aaron Bentley
Check for malformed transforms before committing.
2435
    def test_commit_malformed(self):
2436
        """Committing a malformed transform should raise an exception.
2437
2438
        In this case, we are adding a file without adding its parent.
2439
        """
2440
        branch, tt = self.get_branch_and_transform()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2441
        parent_id = tt.trans_id_file_id(b'parent-id')
2442
        tt.new_file('file', parent_id, [b'contents'], b'file-id')
4526.8.6 by Aaron Bentley
Check for malformed transforms before committing.
2443
        self.assertRaises(errors.MalformedTransform, tt.commit, branch,
2444
                          'message')
2445
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
2446
    def test_commit_rich_revision_data(self):
2447
        branch, tt = self.get_branch_and_transform()
5162.4.3 by Aaron Bentley
Fix failing test.
2448
        rev_id = tt.commit(branch, 'message', timestamp=1, timezone=43201,
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
2449
                           committer='me <me@example.com>',
6973.12.5 by Jelmer Vernooij
Add some u's for revision property names.
2450
                           revprops={u'foo': 'bar'}, revision_id=b'revid-1',
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
2451
                           authors=['Author1 <author1@example.com>',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2452
                                    'Author2 <author2@example.com>',
2453
                                    ])
6973.10.1 by Jelmer Vernooij
Fix some tests.
2454
        self.assertEqual(b'revid-1', rev_id)
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
2455
        revision = branch.repository.get_revision(rev_id)
2456
        self.assertEqual(1, revision.timestamp)
5162.4.3 by Aaron Bentley
Fix failing test.
2457
        self.assertEqual(43201, revision.timezone)
5162.4.1 by Aaron Bentley
TreeTransform supports normal commit parameters and includes branch nick.
2458
        self.assertEqual('me <me@example.com>', revision.committer)
2459
        self.assertEqual(['Author1 <author1@example.com>',
2460
                          'Author2 <author2@example.com>'],
2461
                         revision.get_apparent_authors())
2462
        del revision.properties['authors']
2463
        self.assertEqual({'foo': 'bar',
2464
                          'branch-nick': 'tree'},
2465
                         revision.properties)
2466
2467
    def test_no_explicit_revprops(self):
2468
        branch, tt = self.get_branch_and_transform()
2469
        rev_id = tt.commit(branch, 'message', authors=[
2470
            'Author1 <author1@example.com>',
2471
            'Author2 <author2@example.com>', ])
2472
        revision = branch.repository.get_revision(rev_id)
2473
        self.assertEqual(['Author1 <author1@example.com>',
2474
                          'Author2 <author2@example.com>'],
2475
                         revision.get_apparent_authors())
2476
        self.assertEqual('tree', revision.properties['branch-nick'])
2477
4526.8.1 by Aaron Bentley
Support committing a TreeTransform to a branch.
2478
2733.2.1 by Aaron Bentley
Implement FileMover, to support TreeTransform rollback
2479
class TestFileMover(tests.TestCaseWithTransport):
2480
2481
    def test_file_mover(self):
2482
        self.build_tree(['a/', 'a/b', 'c/', 'c/d'])
2483
        mover = _FileMover()
2484
        mover.rename('a', 'q')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2485
        self.assertPathExists('q')
2486
        self.assertPathDoesNotExist('a')
2487
        self.assertPathExists('q/b')
2488
        self.assertPathExists('c')
2489
        self.assertPathExists('c/d')
2733.2.1 by Aaron Bentley
Implement FileMover, to support TreeTransform rollback
2490
2733.2.5 by Aaron Bentley
Implement FileMover.pre_delete and FileMover.apply_deletions
2491
    def test_pre_delete_rollback(self):
2492
        self.build_tree(['a/'])
2493
        mover = _FileMover()
2494
        mover.pre_delete('a', 'q')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2495
        self.assertPathExists('q')
2496
        self.assertPathDoesNotExist('a')
2733.2.5 by Aaron Bentley
Implement FileMover.pre_delete and FileMover.apply_deletions
2497
        mover.rollback()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2498
        self.assertPathDoesNotExist('q')
2499
        self.assertPathExists('a')
2733.2.5 by Aaron Bentley
Implement FileMover.pre_delete and FileMover.apply_deletions
2500
2501
    def test_apply_deletions(self):
2733.2.12 by Aaron Bentley
Updates from review
2502
        self.build_tree(['a/', 'b/'])
2733.2.5 by Aaron Bentley
Implement FileMover.pre_delete and FileMover.apply_deletions
2503
        mover = _FileMover()
2504
        mover.pre_delete('a', 'q')
2733.2.12 by Aaron Bentley
Updates from review
2505
        mover.pre_delete('b', 'r')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2506
        self.assertPathExists('q')
2507
        self.assertPathExists('r')
2508
        self.assertPathDoesNotExist('a')
2509
        self.assertPathDoesNotExist('b')
2733.2.5 by Aaron Bentley
Implement FileMover.pre_delete and FileMover.apply_deletions
2510
        mover.apply_deletions()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2511
        self.assertPathDoesNotExist('q')
2512
        self.assertPathDoesNotExist('r')
2513
        self.assertPathDoesNotExist('a')
2514
        self.assertPathDoesNotExist('b')
2733.2.5 by Aaron Bentley
Implement FileMover.pre_delete and FileMover.apply_deletions
2515
2733.2.1 by Aaron Bentley
Implement FileMover, to support TreeTransform rollback
2516
    def test_file_mover_rollback(self):
2517
        self.build_tree(['a/', 'a/b', 'c/', 'c/d/', 'c/e/'])
2518
        mover = _FileMover()
2519
        mover.rename('c/d', 'c/f')
2520
        mover.rename('c/e', 'c/d')
2521
        try:
2522
            mover.rename('a', 'c')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2523
        except errors.FileExists:
2733.2.1 by Aaron Bentley
Implement FileMover, to support TreeTransform rollback
2524
            mover.rollback()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2525
        self.assertPathExists('a')
2526
        self.assertPathExists('c/d')
2733.2.3 by Aaron Bentley
Test tranform rollback
2527
2528
2529
class Bogus(Exception):
2530
    pass
2531
2532
2533
class TestTransformRollback(tests.TestCaseWithTransport):
2534
2535
    class ExceptionFileMover(_FileMover):
2536
2733.2.4 by Aaron Bentley
Test transform rollback when renaming into place
2537
        def __init__(self, bad_source=None, bad_target=None):
2538
            _FileMover.__init__(self)
2539
            self.bad_source = bad_source
2540
            self.bad_target = bad_target
2541
2733.2.3 by Aaron Bentley
Test tranform rollback
2542
        def rename(self, source, target):
2733.2.4 by Aaron Bentley
Test transform rollback when renaming into place
2543
            if (self.bad_source is not None and
7143.15.2 by Jelmer Vernooij
Run autopep8.
2544
                    source.endswith(self.bad_source)):
2733.2.4 by Aaron Bentley
Test transform rollback when renaming into place
2545
                raise Bogus
2546
            elif (self.bad_target is not None and
7143.15.2 by Jelmer Vernooij
Run autopep8.
2547
                  target.endswith(self.bad_target)):
2733.2.3 by Aaron Bentley
Test tranform rollback
2548
                raise Bogus
2549
            else:
2550
                _FileMover.rename(self, source, target)
2551
2552
    def test_rollback_rename(self):
2553
        tree = self.make_branch_and_tree('.')
2554
        self.build_tree(['a/', 'a/b'])
2555
        tt = TreeTransform(tree)
2556
        self.addCleanup(tt.finalize)
2557
        a_id = tt.trans_id_tree_path('a')
2558
        tt.adjust_path('c', tt.root, a_id)
2559
        tt.adjust_path('d', a_id, tt.trans_id_tree_path('a/b'))
2733.2.4 by Aaron Bentley
Test transform rollback when renaming into place
2560
        self.assertRaises(Bogus, tt.apply,
2561
                          _mover=self.ExceptionFileMover(bad_source='a'))
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2562
        self.assertPathExists('a')
2563
        self.assertPathExists('a/b')
2733.2.4 by Aaron Bentley
Test transform rollback when renaming into place
2564
        tt.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2565
        self.assertPathExists('c')
2566
        self.assertPathExists('c/d')
2733.2.4 by Aaron Bentley
Test transform rollback when renaming into place
2567
2568
    def test_rollback_rename_into_place(self):
2569
        tree = self.make_branch_and_tree('.')
2570
        self.build_tree(['a/', 'a/b'])
2571
        tt = TreeTransform(tree)
2572
        self.addCleanup(tt.finalize)
2573
        a_id = tt.trans_id_tree_path('a')
2574
        tt.adjust_path('c', tt.root, a_id)
2575
        tt.adjust_path('d', a_id, tt.trans_id_tree_path('a/b'))
2576
        self.assertRaises(Bogus, tt.apply,
2577
                          _mover=self.ExceptionFileMover(bad_target='c/d'))
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2578
        self.assertPathExists('a')
2579
        self.assertPathExists('a/b')
2733.2.4 by Aaron Bentley
Test transform rollback when renaming into place
2580
        tt.apply()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2581
        self.assertPathExists('c')
2582
        self.assertPathExists('c/d')
2733.2.6 by Aaron Bentley
Make TreeTransform commits rollbackable
2583
2584
    def test_rollback_deletion(self):
2585
        tree = self.make_branch_and_tree('.')
2586
        self.build_tree(['a/', 'a/b'])
2587
        tt = TreeTransform(tree)
2588
        self.addCleanup(tt.finalize)
2589
        a_id = tt.trans_id_tree_path('a')
2590
        tt.delete_contents(a_id)
2591
        tt.adjust_path('d', tt.root, tt.trans_id_tree_path('a/b'))
2592
        self.assertRaises(Bogus, tt.apply,
2593
                          _mover=self.ExceptionFileMover(bad_target='d'))
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
2594
        self.assertPathExists('a')
2595
        self.assertPathExists('a/b')
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2596
2597
5876.3.3 by Martin
Use better test class name
2598
class TestFinalizeRobustness(tests.TestCaseWithTransport):
2599
    """Ensure treetransform creation errors can be safely cleaned up after"""
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2600
2601
    def _override_globals_in_method(self, instance, method_name, globals):
2602
        """Replace method on instance with one with updated globals"""
2603
        import types
6619.3.24 by Jelmer Vernooij
Run 2to3 methodattrs fixer.
2604
        func = getattr(instance, method_name).__func__
6619.3.16 by Jelmer Vernooij
Run 2to3 funcattrs fixer.
2605
        new_globals = dict(func.__globals__)
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2606
        new_globals.update(globals)
6619.3.16 by Jelmer Vernooij
Run 2to3 funcattrs fixer.
2607
        new_func = types.FunctionType(func.__code__, new_globals,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2608
                                      func.__name__, func.__defaults__)
7479.2.1 by Jelmer Vernooij
Drop python2 support.
2609
        setattr(instance, method_name,
2610
                types.MethodType(new_func, instance))
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2611
        self.addCleanup(delattr, instance, method_name)
2612
2613
    @staticmethod
2614
    def _fake_open_raises_before(name, mode):
2615
        """Like open() but raises before doing anything"""
2616
        raise RuntimeError
2617
2618
    @staticmethod
2619
    def _fake_open_raises_after(name, mode):
2620
        """Like open() but raises after creating file without returning"""
2621
        open(name, mode).close()
2622
        raise RuntimeError
2623
2624
    def create_transform_and_root_trans_id(self):
2625
        """Setup a transform creating a file in limbo"""
2626
        tree = self.make_branch_and_tree('.')
2627
        tt = TreeTransform(tree)
2628
        return tt, tt.create_path("a", tt.root)
2629
2630
    def create_transform_and_subdir_trans_id(self):
2631
        """Setup a transform creating a directory containing a file in limbo"""
2632
        tree = self.make_branch_and_tree('.')
2633
        tt = TreeTransform(tree)
2634
        d_trans_id = tt.create_path("d", tt.root)
2635
        tt.create_directory(d_trans_id)
2636
        f_trans_id = tt.create_path("a", d_trans_id)
2637
        tt.adjust_path("a", d_trans_id, f_trans_id)
2638
        return tt, f_trans_id
2639
2640
    def test_root_create_file_open_raises_before_creation(self):
2641
        tt, trans_id = self.create_transform_and_root_trans_id()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2642
        self._override_globals_in_method(
2643
            tt, "create_file", {"open": self._fake_open_raises_before})
7143.15.2 by Jelmer Vernooij
Run autopep8.
2644
        self.assertRaises(RuntimeError, tt.create_file,
2645
                          [b"contents"], trans_id)
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2646
        path = tt._limbo_name(trans_id)
2647
        self.assertPathDoesNotExist(path)
2648
        tt.finalize()
2649
        self.assertPathDoesNotExist(tt._limbodir)
2650
2651
    def test_root_create_file_open_raises_after_creation(self):
2652
        tt, trans_id = self.create_transform_and_root_trans_id()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2653
        self._override_globals_in_method(
2654
            tt, "create_file", {"open": self._fake_open_raises_after})
7143.15.2 by Jelmer Vernooij
Run autopep8.
2655
        self.assertRaises(RuntimeError, tt.create_file,
2656
                          [b"contents"], trans_id)
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2657
        path = tt._limbo_name(trans_id)
2658
        self.assertPathExists(path)
5876.3.2 by Martin
Change test that expects ImmortalLimbo to want the sensible thing instead, and fail for now
2659
        tt.finalize()
2660
        self.assertPathDoesNotExist(path)
2661
        self.assertPathDoesNotExist(tt._limbodir)
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2662
2663
    def test_subdir_create_file_open_raises_before_creation(self):
2664
        tt, trans_id = self.create_transform_and_subdir_trans_id()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2665
        self._override_globals_in_method(
2666
            tt, "create_file", {"open": self._fake_open_raises_before})
7143.15.2 by Jelmer Vernooij
Run autopep8.
2667
        self.assertRaises(RuntimeError, tt.create_file,
2668
                          [b"contents"], trans_id)
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2669
        path = tt._limbo_name(trans_id)
2670
        self.assertPathDoesNotExist(path)
2671
        tt.finalize()
2672
        self.assertPathDoesNotExist(tt._limbodir)
2673
2674
    def test_subdir_create_file_open_raises_after_creation(self):
2675
        tt, trans_id = self.create_transform_and_subdir_trans_id()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2676
        self._override_globals_in_method(
2677
            tt, "create_file", {"open": self._fake_open_raises_after})
7143.15.2 by Jelmer Vernooij
Run autopep8.
2678
        self.assertRaises(RuntimeError, tt.create_file,
2679
                          [b"contents"], trans_id)
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2680
        path = tt._limbo_name(trans_id)
2681
        self.assertPathExists(path)
2682
        tt.finalize()
2683
        self.assertPathDoesNotExist(path)
2684
        self.assertPathDoesNotExist(tt._limbodir)
2685
5876.4.4 by Andrew Bennetts
Fix edge cases in handling interrupts during _rename_in_limbo, with messy tests
2686
    def test_rename_in_limbo_rename_raises_after_rename(self):
2687
        tt, trans_id = self.create_transform_and_root_trans_id()
2688
        parent1 = tt.new_directory('parent1', tt.root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2689
        child1 = tt.new_file('child1', parent1, [b'contents'])
5876.4.4 by Andrew Bennetts
Fix edge cases in handling interrupts during _rename_in_limbo, with messy tests
2690
        parent2 = tt.new_directory('parent2', tt.root)
2691
2692
        class FakeOSModule(object):
2693
            def rename(self, old, new):
2694
                os.rename(old, new)
2695
                raise RuntimeError
2696
        self._override_globals_in_method(tt, "_rename_in_limbo",
7143.15.2 by Jelmer Vernooij
Run autopep8.
2697
                                         {"os": FakeOSModule()})
5876.4.4 by Andrew Bennetts
Fix edge cases in handling interrupts during _rename_in_limbo, with messy tests
2698
        self.assertRaises(
2699
            RuntimeError, tt.adjust_path, "child1", parent2, child1)
2700
        path = osutils.pathjoin(tt._limbo_name(parent2), "child1")
2701
        self.assertPathExists(path)
2702
        tt.finalize()
2703
        self.assertPathDoesNotExist(path)
2704
        self.assertPathDoesNotExist(tt._limbodir)
2705
2706
    def test_rename_in_limbo_rename_raises_before_rename(self):
2707
        tt, trans_id = self.create_transform_and_root_trans_id()
2708
        parent1 = tt.new_directory('parent1', tt.root)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2709
        child1 = tt.new_file('child1', parent1, [b'contents'])
5876.4.4 by Andrew Bennetts
Fix edge cases in handling interrupts during _rename_in_limbo, with messy tests
2710
        parent2 = tt.new_directory('parent2', tt.root)
2711
2712
        class FakeOSModule(object):
2713
            def rename(self, old, new):
2714
                raise RuntimeError
2715
        self._override_globals_in_method(tt, "_rename_in_limbo",
7143.15.2 by Jelmer Vernooij
Run autopep8.
2716
                                         {"os": FakeOSModule()})
5876.4.4 by Andrew Bennetts
Fix edge cases in handling interrupts during _rename_in_limbo, with messy tests
2717
        self.assertRaises(
2718
            RuntimeError, tt.adjust_path, "child1", parent2, child1)
2719
        path = osutils.pathjoin(tt._limbo_name(parent1), "child1")
2720
        self.assertPathExists(path)
2721
        tt.finalize()
2722
        self.assertPathDoesNotExist(path)
2723
        self.assertPathDoesNotExist(tt._limbodir)
2724
5876.3.1 by Martin
Tests for DiskTreeTransform.finalize issues when create_file is interrupted
2725
5409.1.6 by Vincent Ladeuil
Add failing tests for bug #323111.
2726
class TestTransformMissingParent(tests.TestCaseWithTransport):
2727
5409.7.4 by Vincent Ladeuil
Take jam's review comments into account.
2728
    def make_tt_with_versioned_dir(self):
5409.1.6 by Vincent Ladeuil
Add failing tests for bug #323111.
2729
        wt = self.make_branch_and_tree('.')
7143.15.2 by Jelmer Vernooij
Run autopep8.
2730
        self.build_tree(['dir/', ])
6855.4.1 by Jelmer Vernooij
Yet more bees.
2731
        wt.add(['dir'], [b'dir-id'])
5409.1.6 by Vincent Ladeuil
Add failing tests for bug #323111.
2732
        wt.commit('Create dir')
2733
        tt = TreeTransform(wt)
2734
        self.addCleanup(tt.finalize)
2735
        return wt, tt
2736
2737
    def test_resolve_create_parent_for_versioned_file(self):
5409.7.4 by Vincent Ladeuil
Take jam's review comments into account.
2738
        wt, tt = self.make_tt_with_versioned_dir()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
2739
        dir_tid = tt.trans_id_tree_path('dir')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2740
        tt.new_file('file', dir_tid, [b'Contents'], file_id=b'file-id')
5409.1.6 by Vincent Ladeuil
Add failing tests for bug #323111.
2741
        tt.delete_contents(dir_tid)
2742
        tt.unversion_file(dir_tid)
2743
        conflicts = resolve_conflicts(tt)
2744
        # one conflict for the missing directory, one for the unversioned
2745
        # parent
2746
        self.assertLength(2, conflicts)
2747
5409.1.20 by Vincent Ladeuil
Revert to 'conflict' being the default orphaning policy and fix fallouts.
2748
    def test_non_versioned_file_create_conflict(self):
5409.7.4 by Vincent Ladeuil
Take jam's review comments into account.
2749
        wt, tt = self.make_tt_with_versioned_dir()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
2750
        dir_tid = tt.trans_id_tree_path('dir')
6973.10.1 by Jelmer Vernooij
Fix some tests.
2751
        tt.new_file('file', dir_tid, [b'Contents'])
5409.1.6 by Vincent Ladeuil
Add failing tests for bug #323111.
2752
        tt.delete_contents(dir_tid)
2753
        tt.unversion_file(dir_tid)
2754
        conflicts = resolve_conflicts(tt)
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
2755
        # no conflicts or rather: orphaning 'file' resolve the 'dir' conflict
5409.1.20 by Vincent Ladeuil
Revert to 'conflict' being the default orphaning policy and fix fallouts.
2756
        self.assertLength(1, conflicts)
2757
        self.assertEqual(('deleting parent', 'Not deleting', 'new-1'),
2758
                         conflicts.pop())
5409.1.6 by Vincent Ladeuil
Add failing tests for bug #323111.
2759
2760
6973.10.1 by Jelmer Vernooij
Fix some tests.
2761
A_ENTRY = (b'a-id', ('a', 'a'), True, (True, True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2762
           (b'TREE_ROOT', b'TREE_ROOT'), ('a', 'a'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
2763
           (False, False), False)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2764
ROOT_ENTRY = (b'TREE_ROOT', ('', ''), False, (True, True), (None, None),
7358.17.5 by Jelmer Vernooij
Fix more tests.
2765
              ('', ''), ('directory', 'directory'), (False, False), False)
3363.19.1 by Aaron Bentley
Make PreviewTree.iter_changes accept all options.
2766
2767
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2768
class TestTransformPreview(tests.TestCaseWithTransport):
2769
2770
    def create_tree(self):
2771
        tree = self.make_branch_and_tree('.')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2772
        self.build_tree_contents([('a', b'content 1')])
2773
        tree.set_root_id(b'TREE_ROOT')
2774
        tree.add('a', b'a-id')
2775
        tree.commit('rev1', rev_id=b'rev1')
6973.5.2 by Jelmer Vernooij
Add more bees.
2776
        return tree.branch.repository.revision_tree(b'rev1')
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2777
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2778
    def get_empty_preview(self):
2779
        repository = self.make_repository('repo')
2780
        tree = repository.revision_tree(_mod_revision.NULL_REVISION)
3199.1.4 by Vincent Ladeuil
Fix 16 leaked tmp dirs. Probably indicates a lock handling problem with TransformPreview
2781
        preview = TransformPreview(tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2782
        self.addCleanup(preview.finalize)
3199.1.4 by Vincent Ladeuil
Fix 16 leaked tmp dirs. Probably indicates a lock handling problem with TransformPreview
2783
        return preview
2784
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2785
    def test_transform_preview(self):
2786
        revision_tree = self.create_tree()
2787
        preview = TransformPreview(revision_tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2788
        self.addCleanup(preview.finalize)
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2789
2790
    def test_transform_preview_tree(self):
2791
        revision_tree = self.create_tree()
2792
        preview = TransformPreview(revision_tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2793
        self.addCleanup(preview.finalize)
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2794
        preview.get_preview_tree()
2795
3008.1.5 by Michael Hudson
a more precise test
2796
    def test_transform_new_file(self):
2797
        revision_tree = self.create_tree()
2798
        preview = TransformPreview(revision_tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2799
        self.addCleanup(preview.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2800
        preview.new_file('file2', preview.root, [b'content B\n'], b'file2-id')
3008.1.5 by Michael Hudson
a more precise test
2801
        preview_tree = preview.get_preview_tree()
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2802
        self.assertEqual(preview_tree.kind('file2'), 'file')
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
2803
        with preview_tree.get_file('file2') as f:
6973.10.1 by Jelmer Vernooij
Fix some tests.
2804
            self.assertEqual(f.read(), b'content B\n')
3008.1.5 by Michael Hudson
a more precise test
2805
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2806
    def test_diff_preview_tree(self):
2807
        revision_tree = self.create_tree()
2808
        preview = TransformPreview(revision_tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2809
        self.addCleanup(preview.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2810
        preview.new_file('file2', preview.root, [b'content B\n'], b'file2-id')
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2811
        preview_tree = preview.get_preview_tree()
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
2812
        out = BytesIO()
3008.1.1 by Aaron Bentley
Start work allowing previews of transforms
2813
        show_diff_trees(revision_tree, preview_tree, out)
3008.1.4 by Michael Hudson
Merge test enhancements
2814
        lines = out.getvalue().splitlines()
7045.4.1 by Jelmer Vernooij
Some brz-git fixes.
2815
        self.assertEqual(lines[0], b"=== added file 'file2'")
3008.1.4 by Michael Hudson
Merge test enhancements
2816
        # 3 lines of diff administrivia
7045.4.1 by Jelmer Vernooij
Some brz-git fixes.
2817
        self.assertEqual(lines[4], b"+content B")
3008.2.1 by Aaron Bentley
Ensure conflict resolution works
2818
6469.1.18 by Parth Malwankar
renamed test
2819
    def test_unsupported_symlink_diff(self):
6469.1.16 by Parth Malwankar
added diff test
2820
        self.requireFeature(SymlinkFeature)
2821
        tree = self.make_branch_and_tree('.')
2822
        self.build_tree_contents([('a', 'content 1')])
7122.6.12 by Jelmer Vernooij
Fix more python3 tests.
2823
        tree.set_root_id(b'TREE_ROOT')
2824
        tree.add('a', b'a-id')
6469.1.16 by Parth Malwankar
added diff test
2825
        os.symlink('a', 'foo')
7122.6.12 by Jelmer Vernooij
Fix more python3 tests.
2826
        tree.add('foo', b'foo-id')
2827
        tree.commit('rev1', rev_id=b'rev1')
2828
        revision_tree = tree.branch.repository.revision_tree(b'rev1')
6469.1.16 by Parth Malwankar
added diff test
2829
        preview = TransformPreview(revision_tree)
2830
        self.addCleanup(preview.finalize)
2831
        preview.delete_versioned(preview.trans_id_tree_path('foo'))
2832
        preview_tree = preview.get_preview_tree()
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
2833
        out = BytesIO()
7122.6.1 by Jelmer Vernooij
merge Parth's work into Breezy
2834
        log = BytesIO()
6469.1.16 by Parth Malwankar
added diff test
2835
        trace.push_log_file(log)
2836
        os_symlink = getattr(os, 'symlink', None)
2837
        os.symlink = None
2838
        try:
2839
            show_diff_trees(revision_tree, preview_tree, out)
2840
            lines = out.getvalue().splitlines()
2841
        finally:
7322.1.7 by Jelmer Vernooij
Fix remaining tests.
2842
            os.symlink = os_symlink
6469.1.16 by Parth Malwankar
added diff test
2843
        self.assertContainsRe(
2844
            log.getvalue(),
7122.6.12 by Jelmer Vernooij
Fix more python3 tests.
2845
            b'Ignoring "foo" as symlinks are not supported on this filesystem')
6469.1.16 by Parth Malwankar
added diff test
2846
3008.2.1 by Aaron Bentley
Ensure conflict resolution works
2847
    def test_transform_conflicts(self):
2848
        revision_tree = self.create_tree()
2849
        preview = TransformPreview(revision_tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2850
        self.addCleanup(preview.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2851
        preview.new_file('a', preview.root, [b'content 2'])
3008.2.1 by Aaron Bentley
Ensure conflict resolution works
2852
        resolve_conflicts(preview)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2853
        trans_id = preview.trans_id_file_id(b'a-id')
3008.2.1 by Aaron Bentley
Ensure conflict resolution works
2854
        self.assertEqual('a.moved', preview.final_name(trans_id))
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2855
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2856
    def get_tree_and_preview_tree(self):
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2857
        revision_tree = self.create_tree()
2858
        preview = TransformPreview(revision_tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2859
        self.addCleanup(preview.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2860
        a_trans_id = preview.trans_id_file_id(b'a-id')
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2861
        preview.delete_contents(a_trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
2862
        preview.create_file([b'b content'], a_trans_id)
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2863
        preview_tree = preview.get_preview_tree()
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2864
        return revision_tree, preview_tree
2865
2866
    def test_iter_changes(self):
2867
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
2868
        root = revision_tree.path2id('')
6973.10.1 by Jelmer Vernooij
Fix some tests.
2869
        self.assertEqual([(b'a-id', ('a', 'a'), True, (True, True),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2870
                           (root, root), ('a', 'a'), ('file', 'file'),
7358.17.5 by Jelmer Vernooij
Fix more tests.
2871
                           (False, False), False)],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2872
                         list(preview_tree.iter_changes(revision_tree)))
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2873
3363.19.1 by Aaron Bentley
Make PreviewTree.iter_changes accept all options.
2874
    def test_include_unchanged_succeeds(self):
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2875
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
3363.19.1 by Aaron Bentley
Make PreviewTree.iter_changes accept all options.
2876
        changes = preview_tree.iter_changes(revision_tree,
2877
                                            include_unchanged=True)
2878
        self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2879
2880
    def test_specific_files(self):
2881
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
3363.19.1 by Aaron Bentley
Make PreviewTree.iter_changes accept all options.
2882
        changes = preview_tree.iter_changes(revision_tree,
2883
                                            specific_files=[''])
5050.57.1 by Aaron Bentley
Make is_executable treat symlinks and directories the same across tree types.
2884
        self.assertEqual([A_ENTRY], list(changes))
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2885
3363.19.1 by Aaron Bentley
Make PreviewTree.iter_changes accept all options.
2886
    def test_want_unversioned(self):
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2887
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
3363.19.1 by Aaron Bentley
Make PreviewTree.iter_changes accept all options.
2888
        changes = preview_tree.iter_changes(revision_tree,
2889
                                            want_unversioned=True)
5050.57.1 by Aaron Bentley
Make is_executable treat symlinks and directories the same across tree types.
2890
        self.assertEqual([A_ENTRY], list(changes))
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2891
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2892
    def test_ignore_extra_trees_no_specific_files(self):
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2893
        # extra_trees is harmless without specific_files, so we'll silently
2894
        # accept it, even though we won't use it.
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2895
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2896
        preview_tree.iter_changes(revision_tree, extra_trees=[preview_tree])
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2897
2898
    def test_ignore_require_versioned_no_specific_files(self):
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2899
        # require_versioned is meaningless without specific_files.
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2900
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
2901
        preview_tree.iter_changes(revision_tree, require_versioned=False)
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2902
2903
    def test_ignore_pb(self):
3008.1.17 by Aaron Bentley
Test unused parameters of preview_tree._iter_changes
2904
        # pb could be supported, but TT.iter_changes doesn't support it.
3008.1.31 by Aaron Bentley
Split PreviewTree._iter_changes parameter tests into smaller tests
2905
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
4961.2.9 by Martin Pool
Rip out most remaining uses of DummyProgressBar
2906
        preview_tree.iter_changes(revision_tree)
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2907
2908
    def test_kind(self):
2909
        revision_tree = self.create_tree()
2910
        preview = TransformPreview(revision_tree)
3199.1.5 by Vincent Ladeuil
Fix two more leaking tmp dirs, by reworking TransformPreview lock handling.
2911
        self.addCleanup(preview.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
2912
        preview.new_file('file', preview.root, [b'contents'], b'file-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
2913
        preview.new_directory('directory', preview.root, b'dir-id')
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2914
        preview_tree = preview.get_preview_tree()
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2915
        self.assertEqual('file', preview_tree.kind('file'))
2916
        self.assertEqual('directory', preview_tree.kind('directory'))
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2917
2918
    def test_get_file_mtime(self):
2919
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2920
        file_trans_id = preview.new_file('file', preview.root, [b'contents'],
6855.4.2 by Jelmer Vernooij
Fix test.
2921
                                         b'file-id')
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2922
        limbo_path = preview._limbo_name(file_trans_id)
2923
        preview_tree = preview.get_preview_tree()
2924
        self.assertEqual(os.stat(limbo_path).st_mtime,
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
2925
                         preview_tree.get_file_mtime('file'))
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2926
4635.1.1 by Aaron Bentley
Fix OSError with renamed files in PreviewTree.
2927
    def test_get_file_mtime_renamed(self):
2928
        work_tree = self.make_branch_and_tree('tree')
2929
        self.build_tree(['tree/file'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
2930
        work_tree.add('file', b'file-id')
4635.1.1 by Aaron Bentley
Fix OSError with renamed files in PreviewTree.
2931
        preview = TransformPreview(work_tree)
2932
        self.addCleanup(preview.finalize)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
2933
        file_trans_id = preview.trans_id_tree_path('file')
4635.1.1 by Aaron Bentley
Fix OSError with renamed files in PreviewTree.
2934
        preview.adjust_path('renamed', preview.root, file_trans_id)
2935
        preview_tree = preview.get_preview_tree()
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
2936
        preview_mtime = preview_tree.get_file_mtime('renamed')
7141.7.2 by Jelmer Vernooij
Fix more tests.
2937
        work_mtime = work_tree.get_file_mtime('file')
4635.1.1 by Aaron Bentley
Fix OSError with renamed files in PreviewTree.
2938
5809.3.6 by Aaron Bentley
Fix PreviewTree.get_file_size.
2939
    def test_get_file_size(self):
2940
        work_tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2941
        self.build_tree_contents([('tree/old', b'old')])
2942
        work_tree.add('old', b'old-id')
5809.3.6 by Aaron Bentley
Fix PreviewTree.get_file_size.
2943
        preview = TransformPreview(work_tree)
2944
        self.addCleanup(preview.finalize)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
2945
        preview.new_file('name', preview.root, [b'contents'], b'new-id',
2946
                         'executable')
5809.3.6 by Aaron Bentley
Fix PreviewTree.get_file_size.
2947
        tree = preview.get_preview_tree()
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
2948
        self.assertEqual(len('old'), tree.get_file_size('old'))
2949
        self.assertEqual(len('contents'), tree.get_file_size('name'))
5809.3.6 by Aaron Bentley
Fix PreviewTree.get_file_size.
2950
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2951
    def test_get_file(self):
2952
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2953
        preview.new_file('file', preview.root, [b'contents'], b'file-id')
3008.1.18 by Aaron Bentley
Get supported PreviewTree functionality under test
2954
        preview_tree = preview.get_preview_tree()
6973.10.1 by Jelmer Vernooij
Fix some tests.
2955
        with preview_tree.get_file('file') as tree_file:
2956
            self.assertEqual(b'contents', tree_file.read())
3228.1.2 by James Henstridge
Simplify test, and move it down to be next to the other _PreviewTree tests.
2957
2958
    def test_get_symlink_target(self):
2959
        self.requireFeature(SymlinkFeature)
2960
        preview = self.get_empty_preview()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
2961
        preview.new_symlink('symlink', preview.root, 'target', b'symlink-id')
3228.1.2 by James Henstridge
Simplify test, and move it down to be next to the other _PreviewTree tests.
2962
        preview_tree = preview.get_preview_tree()
2963
        self.assertEqual('target',
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2964
                         preview_tree.get_symlink_target('symlink'))
3363.2.18 by Aaron Bentley
Implement correct all_file_ids for PreviewTree
2965
2966
    def test_all_file_ids(self):
2967
        tree = self.make_branch_and_tree('tree')
2968
        self.build_tree(['tree/a', 'tree/b', 'tree/c'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
2969
        tree.add(['a', 'b', 'c'], [b'a-id', b'b-id', b'c-id'])
3363.2.18 by Aaron Bentley
Implement correct all_file_ids for PreviewTree
2970
        preview = TransformPreview(tree)
2971
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2972
        preview.unversion_file(preview.trans_id_file_id(b'b-id'))
2973
        c_trans_id = preview.trans_id_file_id(b'c-id')
3363.2.18 by Aaron Bentley
Implement correct all_file_ids for PreviewTree
2974
        preview.unversion_file(c_trans_id)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2975
        preview.version_file(b'c-id', c_trans_id)
3363.2.18 by Aaron Bentley
Implement correct all_file_ids for PreviewTree
2976
        preview_tree = preview.get_preview_tree()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
2977
        self.assertEqual({b'a-id', b'c-id', tree.path2id('')},
3363.2.18 by Aaron Bentley
Implement correct all_file_ids for PreviewTree
2978
                         preview_tree.all_file_ids())
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
2979
2980
    def test_path2id_deleted_unchanged(self):
2981
        tree = self.make_branch_and_tree('tree')
2982
        self.build_tree(['tree/unchanged', 'tree/deleted'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
2983
        tree.add(['unchanged', 'deleted'], [b'unchanged-id', b'deleted-id'])
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
2984
        preview = TransformPreview(tree)
2985
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2986
        preview.unversion_file(preview.trans_id_file_id(b'deleted-id'))
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
2987
        preview_tree = preview.get_preview_tree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2988
        self.assertEqual(b'unchanged-id', preview_tree.path2id('unchanged'))
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
2989
        self.assertFalse(preview_tree.is_versioned('deleted'))
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
2990
2991
    def test_path2id_created(self):
2992
        tree = self.make_branch_and_tree('tree')
2993
        self.build_tree(['tree/unchanged'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
2994
        tree.add(['unchanged'], [b'unchanged-id'])
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
2995
        preview = TransformPreview(tree)
2996
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2997
        preview.new_file('new', preview.trans_id_file_id(b'unchanged-id'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2998
                         [b'contents'], b'new-id')
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
2999
        preview_tree = preview.get_preview_tree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
3000
        self.assertEqual(b'new-id', preview_tree.path2id('unchanged/new'))
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
3001
3002
    def test_path2id_moved(self):
3003
        tree = self.make_branch_and_tree('tree')
3004
        self.build_tree(['tree/old_parent/', 'tree/old_parent/child'])
3005
        tree.add(['old_parent', 'old_parent/child'],
6855.4.1 by Jelmer Vernooij
Yet more bees.
3006
                 [b'old_parent-id', b'child-id'])
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
3007
        preview = TransformPreview(tree)
3008
        self.addCleanup(preview.finalize)
3009
        new_parent = preview.new_directory('new_parent', preview.root,
6855.4.1 by Jelmer Vernooij
Yet more bees.
3010
                                           b'new_parent-id')
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
3011
        preview.adjust_path('child', new_parent,
6855.4.1 by Jelmer Vernooij
Yet more bees.
3012
                            preview.trans_id_file_id(b'child-id'))
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
3013
        preview_tree = preview.get_preview_tree()
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
3014
        self.assertFalse(preview_tree.is_versioned('old_parent/child'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
3015
        self.assertEqual(b'child-id', preview_tree.path2id('new_parent/child'))
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
3016
3017
    def test_path2id_renamed_parent(self):
3018
        tree = self.make_branch_and_tree('tree')
3019
        self.build_tree(['tree/old_name/', 'tree/old_name/child'])
3020
        tree.add(['old_name', 'old_name/child'],
6855.4.1 by Jelmer Vernooij
Yet more bees.
3021
                 [b'parent-id', b'child-id'])
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
3022
        preview = TransformPreview(tree)
3023
        self.addCleanup(preview.finalize)
3024
        preview.adjust_path('new_name', preview.root,
6855.4.1 by Jelmer Vernooij
Yet more bees.
3025
                            preview.trans_id_file_id(b'parent-id'))
3363.2.19 by Aaron Bentley
Make PreviewTree.path2id correct
3026
        preview_tree = preview.get_preview_tree()
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
3027
        self.assertFalse(preview_tree.is_versioned('old_name/child'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
3028
        self.assertEqual(b'child-id', preview_tree.path2id('new_name/child'))
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3029
6885.6.1 by Jelmer Vernooij
Support specific_files argument to Tree.iter_entries_by_dir.
3030
    def assertMatchingIterEntries(self, tt, specific_files=None):
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3031
        preview_tree = tt.get_preview_tree()
3032
        preview_result = list(preview_tree.iter_entries_by_dir(
6885.6.1 by Jelmer Vernooij
Support specific_files argument to Tree.iter_entries_by_dir.
3033
                              specific_files=specific_files))
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3034
        tree = tt._tree
3035
        tt.apply()
6885.6.2 by Jelmer Vernooij
Use specific_files.
3036
        actual_result = list(tree.iter_entries_by_dir(
3037
            specific_files=specific_files))
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3038
        self.assertEqual(actual_result, preview_result)
3039
3040
    def test_iter_entries_by_dir_new(self):
3041
        tree = self.make_branch_and_tree('tree')
3042
        tt = TreeTransform(tree)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3043
        tt.new_file('new', tt.root, [b'contents'], b'new-id')
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3044
        self.assertMatchingIterEntries(tt)
3045
3046
    def test_iter_entries_by_dir_deleted(self):
3047
        tree = self.make_branch_and_tree('tree')
3048
        self.build_tree(['tree/deleted'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3049
        tree.add('deleted', b'deleted-id')
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3050
        tt = TreeTransform(tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3051
        tt.delete_contents(tt.trans_id_file_id(b'deleted-id'))
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3052
        self.assertMatchingIterEntries(tt)
3053
3054
    def test_iter_entries_by_dir_unversioned(self):
3055
        tree = self.make_branch_and_tree('tree')
3056
        self.build_tree(['tree/removed'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3057
        tree.add('removed', b'removed-id')
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3058
        tt = TreeTransform(tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3059
        tt.unversion_file(tt.trans_id_file_id(b'removed-id'))
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3060
        self.assertMatchingIterEntries(tt)
3061
3062
    def test_iter_entries_by_dir_moved(self):
3063
        tree = self.make_branch_and_tree('tree')
3064
        self.build_tree(['tree/moved', 'tree/new_parent/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3065
        tree.add(['moved', 'new_parent'], [b'moved-id', b'new_parent-id'])
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3066
        tt = TreeTransform(tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3067
        tt.adjust_path('moved', tt.trans_id_file_id(b'new_parent-id'),
3068
                       tt.trans_id_file_id(b'moved-id'))
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3069
        self.assertMatchingIterEntries(tt)
3070
6885.6.4 by Jelmer Vernooij
Tree transform - avoid iter_entries_by_dir(specific_file_ids=).
3071
    def test_iter_entries_by_dir_specific_files(self):
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3072
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3073
        tree.set_root_id(b'tree-root-id')
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3074
        self.build_tree(['tree/parent/', 'tree/parent/child'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3075
        tree.add(['parent', 'parent/child'], [b'parent-id', b'child-id'])
3363.2.21 by Aaron Bentley
Implement iter_entries_by_dir
3076
        tt = TreeTransform(tree)
6885.6.1 by Jelmer Vernooij
Support specific_files argument to Tree.iter_entries_by_dir.
3077
        self.assertMatchingIterEntries(tt, ['', 'parent/child'])
3363.2.26 by Aaron Bentley
Get symlinks working
3078
3079
    def test_symlink_content_summary(self):
3080
        self.requireFeature(SymlinkFeature)
3081
        preview = self.get_empty_preview()
6855.4.1 by Jelmer Vernooij
Yet more bees.
3082
        preview.new_symlink('path', preview.root, 'target', b'path-id')
3363.2.26 by Aaron Bentley
Get symlinks working
3083
        summary = preview.get_preview_tree().path_content_summary('path')
3084
        self.assertEqual(('symlink', None, None, 'target'), summary)
3363.2.27 by Aaron Bentley
Make path_content_summary a core API
3085
3086
    def test_missing_content_summary(self):
3087
        preview = self.get_empty_preview()
3088
        summary = preview.get_preview_tree().path_content_summary('path')
3089
        self.assertEqual(('missing', None, None, None), summary)
3090
3091
    def test_deleted_content_summary(self):
3092
        tree = self.make_branch_and_tree('tree')
3093
        self.build_tree(['tree/path/'])
3094
        tree.add('path')
3095
        preview = TransformPreview(tree)
3096
        self.addCleanup(preview.finalize)
3097
        preview.delete_contents(preview.trans_id_tree_path('path'))
3098
        summary = preview.get_preview_tree().path_content_summary('path')
3099
        self.assertEqual(('missing', None, None, None), summary)
3100
3363.2.30 by Aaron Bentley
Improve execute bit testing
3101
    def test_file_content_summary_executable(self):
3102
        preview = self.get_empty_preview()
7143.15.2 by Jelmer Vernooij
Run autopep8.
3103
        path_id = preview.new_file('path', preview.root, [
3104
                                   b'contents'], b'path-id')
3363.2.30 by Aaron Bentley
Improve execute bit testing
3105
        preview.set_executability(True, path_id)
3106
        summary = preview.get_preview_tree().path_content_summary('path')
3107
        self.assertEqual(4, len(summary))
3108
        self.assertEqual('file', summary[0])
3109
        # size must be known
3110
        self.assertEqual(len('contents'), summary[1])
3111
        # executable
3112
        self.assertEqual(True, summary[2])
3363.2.31 by Aaron Bentley
Tweak tests
3113
        # will not have hash (not cheap to determine)
3114
        self.assertIs(None, summary[3])
3363.2.30 by Aaron Bentley
Improve execute bit testing
3115
3116
    def test_change_executability(self):
3117
        tree = self.make_branch_and_tree('tree')
3118
        self.build_tree(['tree/path'])
3119
        tree.add('path')
3120
        preview = TransformPreview(tree)
3121
        self.addCleanup(preview.finalize)
3122
        path_id = preview.trans_id_tree_path('path')
3123
        preview.set_executability(True, path_id)
3124
        summary = preview.get_preview_tree().path_content_summary('path')
3125
        self.assertEqual(True, summary[2])
3126
3363.2.27 by Aaron Bentley
Make path_content_summary a core API
3127
    def test_file_content_summary_non_exec(self):
3128
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3129
        preview.new_file('path', preview.root, [b'contents'], b'path-id')
3363.2.27 by Aaron Bentley
Make path_content_summary a core API
3130
        summary = preview.get_preview_tree().path_content_summary('path')
3131
        self.assertEqual(4, len(summary))
3132
        self.assertEqual('file', summary[0])
3133
        # size must be known
3363.2.30 by Aaron Bentley
Improve execute bit testing
3134
        self.assertEqual(len('contents'), summary[1])
3363.2.27 by Aaron Bentley
Make path_content_summary a core API
3135
        # not executable
4789.15.3 by John Arbash Meinel
PreviewTree now returns False for exec bit properly.
3136
        self.assertEqual(False, summary[2])
3363.2.31 by Aaron Bentley
Tweak tests
3137
        # will not have hash (not cheap to determine)
3138
        self.assertIs(None, summary[3])
3363.2.27 by Aaron Bentley
Make path_content_summary a core API
3139
3140
    def test_dir_content_summary(self):
3141
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3142
        preview.new_directory('path', preview.root, b'path-id')
3363.2.27 by Aaron Bentley
Make path_content_summary a core API
3143
        summary = preview.get_preview_tree().path_content_summary('path')
3144
        self.assertEqual(('directory', None, None, None), summary)
3145
3146
    def test_tree_content_summary(self):
3147
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3148
        path = preview.new_directory('path', preview.root, b'path-id')
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
3149
        preview.set_tree_reference(b'rev-1', path)
3363.2.27 by Aaron Bentley
Make path_content_summary a core API
3150
        summary = preview.get_preview_tree().path_content_summary('path')
3151
        self.assertEqual(4, len(summary))
3152
        self.assertEqual('tree-reference', summary[0])
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3153
3154
    def test_annotate(self):
3155
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3156
        self.build_tree_contents([('tree/file', b'a\n')])
3157
        tree.add('file', b'file-id')
3158
        tree.commit('a', rev_id=b'one')
3159
        self.build_tree_contents([('tree/file', b'a\nb\n')])
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3160
        preview = TransformPreview(tree)
3161
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3162
        file_trans_id = preview.trans_id_file_id(b'file-id')
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3163
        preview.delete_contents(file_trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
3164
        preview.create_file([b'a\nb\nc\n'], file_trans_id)
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3165
        preview_tree = preview.get_preview_tree()
3166
        expected = [
6973.10.1 by Jelmer Vernooij
Fix some tests.
3167
            (b'one', b'a\n'),
3168
            (b'me:', b'b\n'),
3169
            (b'me:', b'c\n'),
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3170
        ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
3171
        annotation = preview_tree.annotate_iter(
3172
            'file', default_revision=b'me:')
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3173
        self.assertEqual(expected, annotation)
3174
3175
    def test_annotate_missing(self):
3176
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3177
        preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3178
        preview_tree = preview.get_preview_tree()
3179
        expected = [
6973.10.1 by Jelmer Vernooij
Fix some tests.
3180
            (b'me:', b'a\n'),
3181
            (b'me:', b'b\n'),
3182
            (b'me:', b'c\n'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3183
            ]
3184
        annotation = preview_tree.annotate_iter(
3185
            'file', default_revision=b'me:')
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3186
        self.assertEqual(expected, annotation)
3187
3363.7.3 by Aaron Bentley
Add test that annotate correctly handles renames
3188
    def test_annotate_rename(self):
3189
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3190
        self.build_tree_contents([('tree/file', b'a\n')])
3191
        tree.add('file', b'file-id')
3192
        tree.commit('a', rev_id=b'one')
3363.7.3 by Aaron Bentley
Add test that annotate correctly handles renames
3193
        preview = TransformPreview(tree)
3194
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3195
        file_trans_id = preview.trans_id_file_id(b'file-id')
3363.7.3 by Aaron Bentley
Add test that annotate correctly handles renames
3196
        preview.adjust_path('newname', preview.root, file_trans_id)
3197
        preview_tree = preview.get_preview_tree()
3198
        expected = [
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
3199
            (b'one', b'a\n'),
3363.7.3 by Aaron Bentley
Add test that annotate correctly handles renames
3200
        ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
3201
        annotation = preview_tree.annotate_iter(
3202
            'file', default_revision=b'me:')
3363.7.3 by Aaron Bentley
Add test that annotate correctly handles renames
3203
        self.assertEqual(expected, annotation)
3204
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3205
    def test_annotate_deleted(self):
3206
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3207
        self.build_tree_contents([('tree/file', b'a\n')])
3208
        tree.add('file', b'file-id')
3209
        tree.commit('a', rev_id=b'one')
3210
        self.build_tree_contents([('tree/file', b'a\nb\n')])
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3211
        preview = TransformPreview(tree)
3212
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3213
        file_trans_id = preview.trans_id_file_id(b'file-id')
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3214
        preview.delete_contents(file_trans_id)
3215
        preview_tree = preview.get_preview_tree()
7143.15.2 by Jelmer Vernooij
Run autopep8.
3216
        annotation = preview_tree.annotate_iter(
3217
            'file', default_revision=b'me:')
3363.2.33 by Aaron Bentley
Implement PreviewTree.annotate_iter
3218
        self.assertIs(None, annotation)
3219
3363.2.36 by Aaron Bentley
Fix PreviewTree.stored_kind
3220
    def test_stored_kind(self):
3221
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3222
        preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
3363.2.36 by Aaron Bentley
Fix PreviewTree.stored_kind
3223
        preview_tree = preview.get_preview_tree()
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
3224
        self.assertEqual('file', preview_tree.stored_kind('file'))
3363.2.37 by Aaron Bentley
Fix is_executable
3225
3226
    def test_is_executable(self):
3227
        preview = self.get_empty_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3228
        preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3229
        preview.set_executability(True, preview.trans_id_file_id(b'file-id'))
3363.2.37 by Aaron Bentley
Fix is_executable
3230
        preview_tree = preview.get_preview_tree()
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
3231
        self.assertEqual(True, preview_tree.is_executable('file'))
3363.9.1 by Aaron Bentley
Implement plan_merge, refactoring various bits
3232
3571.1.1 by Aaron Bentley
Allow set/get of parent_ids in PreviewTree
3233
    def test_get_set_parent_ids(self):
3234
        revision_tree, preview_tree = self.get_tree_and_preview_tree()
3235
        self.assertEqual([], preview_tree.get_parent_ids())
6855.4.1 by Jelmer Vernooij
Yet more bees.
3236
        preview_tree.set_parent_ids([b'rev-1'])
3237
        self.assertEqual([b'rev-1'], preview_tree.get_parent_ids())
3571.1.1 by Aaron Bentley
Allow set/get of parent_ids in PreviewTree
3238
3363.9.1 by Aaron Bentley
Implement plan_merge, refactoring various bits
3239
    def test_plan_file_merge(self):
3240
        work_a = self.make_branch_and_tree('wta')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3241
        self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
3242
        work_a.add('file', b'file-id')
3363.9.7 by Aaron Bentley
Fix up to use set_parent_ids
3243
        base_id = work_a.commit('base version')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
3244
        tree_b = work_a.controldir.sprout('wtb').open_workingtree()
3363.9.1 by Aaron Bentley
Implement plan_merge, refactoring various bits
3245
        preview = TransformPreview(work_a)
3246
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3247
        trans_id = preview.trans_id_file_id(b'file-id')
3363.9.1 by Aaron Bentley
Implement plan_merge, refactoring various bits
3248
        preview.delete_contents(trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
3249
        preview.create_file([b'b\nc\nd\ne\n'], trans_id)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3250
        self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
3363.9.1 by Aaron Bentley
Implement plan_merge, refactoring various bits
3251
        tree_a = preview.get_preview_tree()
3363.9.7 by Aaron Bentley
Fix up to use set_parent_ids
3252
        tree_a.set_parent_ids([base_id])
3363.9.1 by Aaron Bentley
Implement plan_merge, refactoring various bits
3253
        self.assertEqual([
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
3254
            ('killed-a', b'a\n'),
3255
            ('killed-b', b'b\n'),
3256
            ('unchanged', b'c\n'),
3257
            ('unchanged', b'd\n'),
3258
            ('new-a', b'e\n'),
3259
            ('new-b', b'f\n'),
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
3260
        ], list(tree_a.plan_file_merge('file', tree_b)))
3363.9.8 by Aaron Bentley
Ensure plan_file_merge works with a RevisionTree as the basis
3261
3262
    def test_plan_file_merge_revision_tree(self):
3263
        work_a = self.make_branch_and_tree('wta')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3264
        self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
3265
        work_a.add('file', b'file-id')
3363.9.8 by Aaron Bentley
Ensure plan_file_merge works with a RevisionTree as the basis
3266
        base_id = work_a.commit('base version')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
3267
        tree_b = work_a.controldir.sprout('wtb').open_workingtree()
3363.9.8 by Aaron Bentley
Ensure plan_file_merge works with a RevisionTree as the basis
3268
        preview = TransformPreview(work_a.basis_tree())
3269
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3270
        trans_id = preview.trans_id_file_id(b'file-id')
3363.9.8 by Aaron Bentley
Ensure plan_file_merge works with a RevisionTree as the basis
3271
        preview.delete_contents(trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
3272
        preview.create_file([b'b\nc\nd\ne\n'], trans_id)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3273
        self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
3363.9.8 by Aaron Bentley
Ensure plan_file_merge works with a RevisionTree as the basis
3274
        tree_a = preview.get_preview_tree()
3275
        tree_a.set_parent_ids([base_id])
3276
        self.assertEqual([
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
3277
            ('killed-a', b'a\n'),
3278
            ('killed-b', b'b\n'),
3279
            ('unchanged', b'c\n'),
3280
            ('unchanged', b'd\n'),
3281
            ('new-a', b'e\n'),
3282
            ('new-b', b'f\n'),
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
3283
        ], list(tree_a.plan_file_merge('file', tree_b)))
3363.9.9 by Aaron Bentley
Implement walkdirs in terms of TreeTransform
3284
3285
    def test_walkdirs(self):
3286
        preview = self.get_empty_preview()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3287
        preview.new_directory('', ROOT_PARENT, b'tree-root')
4634.57.3 by Aaron Bentley
Fix failing test.
3288
        # FIXME: new_directory should mark root.
4634.122.6 by John Arbash Meinel
Fix a test that used 'adjust_path' to set the root.
3289
        preview.fixup_new_roots()
3363.9.9 by Aaron Bentley
Implement walkdirs in terms of TreeTransform
3290
        preview_tree = preview.get_preview_tree()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3291
        preview.new_file('a', preview.root, [b'contents'], b'a-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3292
        expected = [(('', b'tree-root'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3293
                     [('a', 'a', 'file', None, b'a-id', 'file')])]
3363.9.9 by Aaron Bentley
Implement walkdirs in terms of TreeTransform
3294
        self.assertEqual(expected, list(preview_tree.walkdirs()))
3363.13.2 by Aaron Bentley
Test specific cases for PreviewTree.extras
3295
3296
    def test_extras(self):
3297
        work_tree = self.make_branch_and_tree('tree')
3298
        self.build_tree(['tree/removed-file', 'tree/existing-file',
3299
                         'tree/not-removed-file'])
3300
        work_tree.add(['removed-file', 'not-removed-file'])
3301
        preview = TransformPreview(work_tree)
3363.13.3 by Aaron Bentley
Add cleanup
3302
        self.addCleanup(preview.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3303
        preview.new_file('new-file', preview.root, [b'contents'])
3304
        preview.new_file('new-versioned-file', preview.root, [b'contents'],
6855.4.1 by Jelmer Vernooij
Yet more bees.
3305
                         b'new-versioned-id')
3363.13.2 by Aaron Bentley
Test specific cases for PreviewTree.extras
3306
        tree = preview.get_preview_tree()
3307
        preview.unversion_file(preview.trans_id_tree_path('removed-file'))
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
3308
        self.assertEqual({'new-file', 'removed-file', 'existing-file'},
3363.13.2 by Aaron Bentley
Test specific cases for PreviewTree.extras
3309
                         set(tree.extras()))
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
3310
3363.17.2 by Aaron Bentley
Add text checking
3311
    def test_merge_into_preview(self):
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
3312
        work_tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3313
        self.build_tree_contents([('tree/file', b'b\n')])
3314
        work_tree.add('file', b'file-id')
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
3315
        work_tree.commit('first commit')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
3316
        child_tree = work_tree.controldir.sprout('child').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
3317
        self.build_tree_contents([('child/file', b'b\nc\n')])
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
3318
        child_tree.commit('child commit')
3319
        child_tree.lock_write()
3320
        self.addCleanup(child_tree.unlock)
3321
        work_tree.lock_write()
3322
        self.addCleanup(work_tree.unlock)
3323
        preview = TransformPreview(work_tree)
3324
        self.addCleanup(preview.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3325
        file_trans_id = preview.trans_id_file_id(b'file-id')
3363.17.6 by Aaron Bentley
Improve test scenario
3326
        preview.delete_contents(file_trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
3327
        preview.create_file([b'a\nb\n'], file_trans_id)
4634.57.2 by Aaron Bentley
Fix failing test.
3328
        preview_tree = preview.get_preview_tree()
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
3329
        merger = Merger.from_revision_ids(preview_tree,
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
3330
                                          child_tree.branch.last_revision(),
3331
                                          other_branch=child_tree.branch,
3332
                                          tree_branch=work_tree.branch)
3333
        merger.merge_type = Merge3Merger
3334
        tt = merger.make_merger().make_preview_transform()
3363.17.2 by Aaron Bentley
Add text checking
3335
        self.addCleanup(tt.finalize)
3336
        final_tree = tt.get_preview_tree()
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
3337
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
3338
            b'a\nb\nc\n',
3339
            final_tree.get_file_text(final_tree.id2path(b'file-id')))
3363.17.17 by Aaron Bentley
Start testing merging PreviewTree as OTHER
3340
3341
    def test_merge_preview_into_workingtree(self):
3342
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3343
        tree.set_root_id(b'TREE_ROOT')
3363.17.17 by Aaron Bentley
Start testing merging PreviewTree as OTHER
3344
        tt = TransformPreview(tree)
3345
        self.addCleanup(tt.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3346
        tt.new_file('name', tt.root, [b'content'], b'file-id')
3363.17.17 by Aaron Bentley
Start testing merging PreviewTree as OTHER
3347
        tree2 = self.make_branch_and_tree('tree2')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3348
        tree2.set_root_id(b'TREE_ROOT')
3363.17.17 by Aaron Bentley
Start testing merging PreviewTree as OTHER
3349
        merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
3350
                                         tree.basis_tree())
3363.17.17 by Aaron Bentley
Start testing merging PreviewTree as OTHER
3351
        merger.merge_type = Merge3Merger
3352
        merger.do_merge()
3363.17.18 by Aaron Bentley
Fix is_executable for PreviewTree
3353
3363.17.21 by Aaron Bentley
Conflicts are handled when merging from preview trees
3354
    def test_merge_preview_into_workingtree_handles_conflicts(self):
3355
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3356
        self.build_tree_contents([('tree/foo', b'bar')])
3357
        tree.add('foo', b'foo-id')
3363.17.21 by Aaron Bentley
Conflicts are handled when merging from preview trees
3358
        tree.commit('foo')
3359
        tt = TransformPreview(tree)
3360
        self.addCleanup(tt.finalize)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3361
        trans_id = tt.trans_id_file_id(b'foo-id')
3363.17.21 by Aaron Bentley
Conflicts are handled when merging from preview trees
3362
        tt.delete_contents(trans_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
3363
        tt.create_file([b'baz'], trans_id)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
3364
        tree2 = tree.controldir.sprout('tree2').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
3365
        self.build_tree_contents([('tree2/foo', b'qux')])
3363.17.21 by Aaron Bentley
Conflicts are handled when merging from preview trees
3366
        merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
3367
                                         tree.basis_tree())
3363.17.21 by Aaron Bentley
Conflicts are handled when merging from preview trees
3368
        merger.merge_type = Merge3Merger
3369
        merger.do_merge()
3370
5809.3.2 by Aaron Bentley
Support PreviewTree.has_filename.
3371
    def test_has_filename(self):
3372
        wt = self.make_branch_and_tree('tree')
3373
        self.build_tree(['tree/unmodified', 'tree/removed', 'tree/modified'])
3374
        tt = TransformPreview(wt)
3375
        removed_id = tt.trans_id_tree_path('removed')
3376
        tt.delete_contents(removed_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3377
        tt.new_file('new', tt.root, [b'contents'])
5809.3.2 by Aaron Bentley
Support PreviewTree.has_filename.
3378
        modified_id = tt.trans_id_tree_path('modified')
3379
        tt.delete_contents(modified_id)
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
3380
        tt.create_file([b'modified-contents'], modified_id)
5809.3.2 by Aaron Bentley
Support PreviewTree.has_filename.
3381
        self.addCleanup(tt.finalize)
3382
        tree = tt.get_preview_tree()
3383
        self.assertTrue(tree.has_filename('unmodified'))
3384
        self.assertFalse(tree.has_filename('not-present'))
3385
        self.assertFalse(tree.has_filename('removed'))
3386
        self.assertTrue(tree.has_filename('new'))
3387
        self.assertTrue(tree.has_filename('modified'))
3388
3363.17.18 by Aaron Bentley
Fix is_executable for PreviewTree
3389
    def test_is_executable(self):
3390
        tree = self.make_branch_and_tree('tree')
3391
        preview = TransformPreview(tree)
3392
        self.addCleanup(preview.finalize)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3393
        preview.new_file('foo', preview.root, [b'bar'], b'baz-id')
3363.17.18 by Aaron Bentley
Fix is_executable for PreviewTree
3394
        preview_tree = preview.get_preview_tree()
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
3395
        self.assertEqual(False, preview_tree.is_executable('tree/foo'))
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3396
4354.4.4 by Aaron Bentley
Simplify by using CommitBuilder directly
3397
    def test_commit_preview_tree(self):
3398
        tree = self.make_branch_and_tree('tree')
3399
        rev_id = tree.commit('rev1')
3400
        tree.branch.lock_write()
3401
        self.addCleanup(tree.branch.unlock)
3402
        tt = TransformPreview(tree)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3403
        tt.new_file('file', tt.root, [b'contents'], b'file_id')
4354.4.4 by Aaron Bentley
Simplify by using CommitBuilder directly
3404
        self.addCleanup(tt.finalize)
3405
        preview = tt.get_preview_tree()
3406
        preview.set_parent_ids([rev_id])
3407
        builder = tree.branch.get_commit_builder([rev_id])
3408
        list(builder.record_iter_changes(preview, rev_id, tt.iter_changes()))
3409
        builder.finish_inventory()
3410
        rev2_id = builder.commit('rev2')
3411
        rev2_tree = tree.branch.repository.revision_tree(rev2_id)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
3412
        self.assertEqual(b'contents', rev2_tree.get_file_text('file'))
4354.4.4 by Aaron Bentley
Simplify by using CommitBuilder directly
3413
4634.79.1 by Aaron Bentley
TransformPreview uses ascii-only filenames.
3414
    def test_ascii_limbo_paths(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
3415
        self.requireFeature(features.UnicodeFilenameFeature)
4634.79.1 by Aaron Bentley
TransformPreview uses ascii-only filenames.
3416
        branch = self.make_branch('any')
3417
        tree = branch.repository.revision_tree(_mod_revision.NULL_REVISION)
3418
        tt = TransformPreview(tree)
4789.25.7 by John Arbash Meinel
We can run the executable tests.
3419
        self.addCleanup(tt.finalize)
4634.79.1 by Aaron Bentley
TransformPreview uses ascii-only filenames.
3420
        foo_id = tt.new_directory('', ROOT_PARENT)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3421
        bar_id = tt.new_file(u'\u1234bar', foo_id, [b'contents'])
4634.79.1 by Aaron Bentley
TransformPreview uses ascii-only filenames.
3422
        limbo_path = tt._limbo_name(bar_id)
6973.10.1 by Jelmer Vernooij
Fix some tests.
3423
        self.assertEqual(limbo_path, limbo_path)
4634.79.1 by Aaron Bentley
TransformPreview uses ascii-only filenames.
3424
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3425
0.13.13 by Aaron Bentley
Add direct test of serialization records
3426
class FakeSerializer(object):
3427
    """Serializer implementation that simply returns the input.
3428
3429
    The input is returned in the order used by pack.ContainerPushParser.
3430
    """
3431
    @staticmethod
3432
    def bytes_record(bytes, names):
3433
        return names, bytes
3434
3435
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3436
class TestSerializeTransform(tests.TestCaseWithTransport):
3437
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
3438
    _test_needs_features = [features.UnicodeFilenameFeature]
0.13.22 by Aaron Bentley
More unicodeness for Shelf tests
3439
0.13.17 by Aaron Bentley
Convert roundtrip destruction test to serialization/deserialization pair
3440
    def get_preview(self, tree=None):
3441
        if tree is None:
3442
            tree = self.make_branch_and_tree('tree')
0.13.14 by Aaron Bentley
Add deserialization test, remove roundtrip test.
3443
        tt = TransformPreview(tree)
3444
        self.addCleanup(tt.finalize)
3445
        return tt
3446
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3447
    def assertSerializesTo(self, expected, tt):
3448
        records = list(tt.serialize(FakeSerializer()))
3449
        self.assertEqual(expected, records)
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3450
0.13.13 by Aaron Bentley
Add direct test of serialization records
3451
    @staticmethod
3452
    def default_attribs():
3453
        return {
6973.10.1 by Jelmer Vernooij
Fix some tests.
3454
            b'_id_number': 1,
3455
            b'_new_name': {},
3456
            b'_new_parent': {},
3457
            b'_new_executability': {},
3458
            b'_new_id': {},
3459
            b'_tree_path_ids': {b'': b'new-0'},
3460
            b'_removed_id': [],
3461
            b'_removed_contents': [],
3462
            b'_non_present_ids': {},
0.13.13 by Aaron Bentley
Add direct test of serialization records
3463
            }
3464
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3465
    def make_records(self, attribs, contents):
3466
        records = [
7045.4.1 by Jelmer Vernooij
Some brz-git fixes.
3467
            ((((b'attribs'),),), bencode.bencode(attribs))]
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3468
        records.extend([(((n, k),), c) for n, k, c in contents])
3469
        return records
3470
0.13.13 by Aaron Bentley
Add direct test of serialization records
3471
    def creation_records(self):
3472
        attribs = self.default_attribs()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3473
        attribs[b'_id_number'] = 3
3474
        attribs[b'_new_name'] = {
3475
            b'new-1': u'foo\u1234'.encode('utf-8'), b'new-2': b'qux'}
3476
        attribs[b'_new_id'] = {b'new-1': b'baz', b'new-2': b'quxx'}
3477
        attribs[b'_new_parent'] = {b'new-1': b'new-0', b'new-2': b'new-0'}
3478
        attribs[b'_new_executability'] = {b'new-1': 1}
0.13.13 by Aaron Bentley
Add direct test of serialization records
3479
        contents = [
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3480
            (b'new-1', b'file', b'i 1\nbar\n'),
3481
            (b'new-2', b'directory', b''),
0.13.13 by Aaron Bentley
Add direct test of serialization records
3482
            ]
3483
        return self.make_records(attribs, contents)
3484
3485
    def test_serialize_creation(self):
0.13.14 by Aaron Bentley
Add deserialization test, remove roundtrip test.
3486
        tt = self.get_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3487
        tt.new_file(u'foo\u1234', tt.root, [b'bar'], b'baz', True)
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3488
        tt.new_directory('qux', tt.root, b'quxx')
0.13.21 by Aaron Bentley
Use assertSerializesTo in more places
3489
        self.assertSerializesTo(self.creation_records(), tt)
0.13.13 by Aaron Bentley
Add direct test of serialization records
3490
0.13.14 by Aaron Bentley
Add deserialization test, remove roundtrip test.
3491
    def test_deserialize_creation(self):
3492
        tt = self.get_preview()
3493
        tt.deserialize(iter(self.creation_records()))
3494
        self.assertEqual(3, tt._id_number)
3495
        self.assertEqual({'new-1': u'foo\u1234',
3496
                          'new-2': 'qux'}, tt._new_name)
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3497
        self.assertEqual({'new-1': b'baz', 'new-2': b'quxx'}, tt._new_id)
0.13.14 by Aaron Bentley
Add deserialization test, remove roundtrip test.
3498
        self.assertEqual({'new-1': tt.root, 'new-2': tt.root}, tt._new_parent)
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3499
        self.assertEqual({b'baz': 'new-1', b'quxx': 'new-2'}, tt._r_new_id)
0.13.14 by Aaron Bentley
Add deserialization test, remove roundtrip test.
3500
        self.assertEqual({'new-1': True}, tt._new_executability)
3501
        self.assertEqual({'new-1': 'file',
3502
                          'new-2': 'directory'}, tt._new_contents)
3503
        foo_limbo = open(tt._limbo_name('new-1'), 'rb')
3504
        try:
3505
            foo_content = foo_limbo.read()
3506
        finally:
3507
            foo_limbo.close()
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3508
        self.assertEqual(b'bar', foo_content)
0.13.14 by Aaron Bentley
Add deserialization test, remove roundtrip test.
3509
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3510
    def symlink_creation_records(self):
3511
        attribs = self.default_attribs()
7045.4.9 by Jelmer Vernooij
Fix some transform tests.
3512
        attribs[b'_id_number'] = 2
3513
        attribs[b'_new_name'] = {b'new-1': u'foo\u1234'.encode('utf-8')}
3514
        attribs[b'_new_parent'] = {b'new-1': b'new-0'}
7045.4.1 by Jelmer Vernooij
Some brz-git fixes.
3515
        contents = [(b'new-1', b'symlink', u'bar\u1234'.encode('utf-8'))]
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3516
        return self.make_records(attribs, contents)
3517
0.13.15 by Aaron Bentley
Convert symlink tests to avoid roundtripping
3518
    def test_serialize_symlink_creation(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
3519
        self.requireFeature(features.SymlinkFeature)
0.13.15 by Aaron Bentley
Convert symlink tests to avoid roundtripping
3520
        tt = self.get_preview()
0.13.16 by Aaron Bentley
Add unicode symlink targets to tests
3521
        tt.new_symlink(u'foo\u1234', tt.root, u'bar\u1234')
0.13.21 by Aaron Bentley
Use assertSerializesTo in more places
3522
        self.assertSerializesTo(self.symlink_creation_records(), tt)
0.13.15 by Aaron Bentley
Convert symlink tests to avoid roundtripping
3523
3524
    def test_deserialize_symlink_creation(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
3525
        self.requireFeature(features.SymlinkFeature)
0.13.15 by Aaron Bentley
Convert symlink tests to avoid roundtripping
3526
        tt = self.get_preview()
3527
        tt.deserialize(iter(self.symlink_creation_records()))
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
3528
        abspath = tt._limbo_name('new-1')
4241.14.17 by Vincent Ladeuil
Add more tests for unicode symlinks to test_transform.
3529
        foo_content = osutils.readlink(abspath)
0.13.22 by Aaron Bentley
More unicodeness for Shelf tests
3530
        self.assertEqual(u'bar\u1234', foo_content)
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3531
0.13.19 by Aaron Bentley
Clean up serialization tests
3532
    def make_destruction_preview(self):
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3533
        tree = self.make_branch_and_tree('.')
3534
        self.build_tree([u'foo\u1234', 'bar'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3535
        tree.add([u'foo\u1234', 'bar'], [b'foo-id', b'bar-id'])
0.13.19 by Aaron Bentley
Clean up serialization tests
3536
        return self.get_preview(tree)
0.13.17 by Aaron Bentley
Convert roundtrip destruction test to serialization/deserialization pair
3537
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3538
    def destruction_records(self):
3539
        attribs = self.default_attribs()
7045.4.9 by Jelmer Vernooij
Fix some transform tests.
3540
        attribs[b'_id_number'] = 3
3541
        attribs[b'_removed_id'] = [b'new-1']
3542
        attribs[b'_removed_contents'] = [b'new-2']
3543
        attribs[b'_tree_path_ids'] = {
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3544
            b'': b'new-0',
3545
            u'foo\u1234'.encode('utf-8'): b'new-1',
3546
            b'bar': b'new-2',
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3547
            }
3548
        return self.make_records(attribs, [])
3549
0.13.17 by Aaron Bentley
Convert roundtrip destruction test to serialization/deserialization pair
3550
    def test_serialize_destruction(self):
0.13.19 by Aaron Bentley
Clean up serialization tests
3551
        tt = self.make_destruction_preview()
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
3552
        foo_trans_id = tt.trans_id_tree_path(u'foo\u1234')
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3553
        tt.unversion_file(foo_trans_id)
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
3554
        bar_trans_id = tt.trans_id_tree_path('bar')
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3555
        tt.delete_contents(bar_trans_id)
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3556
        self.assertSerializesTo(self.destruction_records(), tt)
0.13.17 by Aaron Bentley
Convert roundtrip destruction test to serialization/deserialization pair
3557
3558
    def test_deserialize_destruction(self):
0.13.19 by Aaron Bentley
Clean up serialization tests
3559
        tt = self.make_destruction_preview()
0.13.17 by Aaron Bentley
Convert roundtrip destruction test to serialization/deserialization pair
3560
        tt.deserialize(iter(self.destruction_records()))
3561
        self.assertEqual({u'foo\u1234': 'new-1',
3562
                          'bar': 'new-2',
3563
                          '': tt.root}, tt._tree_path_ids)
3564
        self.assertEqual({'new-1': u'foo\u1234',
3565
                          'new-2': 'bar',
3566
                          tt.root: ''}, tt._tree_id_paths)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
3567
        self.assertEqual({'new-1'}, tt._removed_id)
3568
        self.assertEqual({'new-2'}, tt._removed_contents)
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3569
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3570
    def missing_records(self):
3571
        attribs = self.default_attribs()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3572
        attribs[b'_id_number'] = 2
3573
        attribs[b'_non_present_ids'] = {
7143.15.2 by Jelmer Vernooij
Run autopep8.
3574
            b'boo': b'new-1', }
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3575
        return self.make_records(attribs, [])
3576
3577
    def test_serialize_missing(self):
3578
        tt = self.get_preview()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3579
        tt.trans_id_file_id(b'boo')
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3580
        self.assertSerializesTo(self.missing_records(), tt)
3581
3582
    def test_deserialize_missing(self):
3583
        tt = self.get_preview()
3584
        tt.deserialize(iter(self.missing_records()))
7045.3.1 by Jelmer Vernooij
Fix another ~500 tests.
3585
        self.assertEqual({b'boo': 'new-1'}, tt._non_present_ids)
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3586
3587
    def make_modification_preview(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
3588
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
3589
        LINES_TWO = b'z\nbb\nx\ndd\n'
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3590
        tree = self.make_branch_and_tree('tree')
3591
        self.build_tree_contents([('tree/file', LINES_ONE)])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3592
        tree.add('file', b'file-id')
7045.4.1 by Jelmer Vernooij
Some brz-git fixes.
3593
        return self.get_preview(tree), [LINES_TWO]
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3594
3595
    def modification_records(self):
3596
        attribs = self.default_attribs()
7045.4.9 by Jelmer Vernooij
Fix some transform tests.
3597
        attribs[b'_id_number'] = 2
3598
        attribs[b'_tree_path_ids'] = {
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3599
            b'file': b'new-1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
3600
            b'': b'new-0', }
7045.4.9 by Jelmer Vernooij
Fix some transform tests.
3601
        attribs[b'_removed_contents'] = [b'new-1']
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3602
        contents = [(b'new-1', b'file',
7045.4.1 by Jelmer Vernooij
Some brz-git fixes.
3603
                     b'i 1\nz\n\nc 0 1 1 1\ni 1\nx\n\nc 0 3 3 1\n')]
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3604
        return self.make_records(attribs, contents)
3605
3606
    def test_serialize_modification(self):
3607
        tt, LINES = self.make_modification_preview()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3608
        trans_id = tt.trans_id_file_id(b'file-id')
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3609
        tt.delete_contents(trans_id)
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3610
        tt.create_file(LINES, trans_id)
3611
        self.assertSerializesTo(self.modification_records(), tt)
3612
3613
    def test_deserialize_modification(self):
3614
        tt, LINES = self.make_modification_preview()
3615
        tt.deserialize(iter(self.modification_records()))
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3616
        self.assertFileEqual(b''.join(LINES), tt._limbo_name('new-1'))
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3617
3618
    def make_kind_change_preview(self):
6973.10.1 by Jelmer Vernooij
Fix some tests.
3619
        LINES = b'a\nb\nc\nd\n'
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3620
        tree = self.make_branch_and_tree('tree')
3621
        self.build_tree(['tree/foo/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3622
        tree.add('foo', b'foo-id')
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3623
        return self.get_preview(tree), [LINES]
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3624
3625
    def kind_change_records(self):
3626
        attribs = self.default_attribs()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3627
        attribs[b'_id_number'] = 2
3628
        attribs[b'_tree_path_ids'] = {
3629
            b'foo': b'new-1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
3630
            b'': b'new-0', }
6973.10.1 by Jelmer Vernooij
Fix some tests.
3631
        attribs[b'_removed_contents'] = [b'new-1']
7045.3.1 by Jelmer Vernooij
Fix another ~500 tests.
3632
        contents = [(b'new-1', b'file',
6973.10.1 by Jelmer Vernooij
Fix some tests.
3633
                     b'i 4\na\nb\nc\nd\n\n')]
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3634
        return self.make_records(attribs, contents)
3635
3636
    def test_serialize_kind_change(self):
3637
        tt, LINES = self.make_kind_change_preview()
6855.4.1 by Jelmer Vernooij
Yet more bees.
3638
        trans_id = tt.trans_id_file_id(b'foo-id')
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3639
        tt.delete_contents(trans_id)
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3640
        tt.create_file(LINES, trans_id)
3641
        self.assertSerializesTo(self.kind_change_records(), tt)
3642
3643
    def test_deserialize_kind_change(self):
3644
        tt, LINES = self.make_kind_change_preview()
3645
        tt.deserialize(iter(self.kind_change_records()))
7045.4.7 by Jelmer Vernooij
Fix remaining tests.
3646
        self.assertFileEqual(b''.join(LINES), tt._limbo_name('new-1'))
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3647
3648
    def make_add_contents_preview(self):
6973.10.1 by Jelmer Vernooij
Fix some tests.
3649
        LINES = b'a\nb\nc\nd\n'
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3650
        tree = self.make_branch_and_tree('tree')
3651
        self.build_tree(['tree/foo'])
3652
        tree.add('foo')
3653
        os.unlink('tree/foo')
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3654
        return self.get_preview(tree), LINES
3655
3656
    def add_contents_records(self):
3657
        attribs = self.default_attribs()
6973.10.1 by Jelmer Vernooij
Fix some tests.
3658
        attribs[b'_id_number'] = 2
3659
        attribs[b'_tree_path_ids'] = {
3660
            b'foo': b'new-1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
3661
            b'': b'new-0', }
7045.3.1 by Jelmer Vernooij
Fix another ~500 tests.
3662
        contents = [(b'new-1', b'file',
6973.10.1 by Jelmer Vernooij
Fix some tests.
3663
                     b'i 4\na\nb\nc\nd\n\n')]
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3664
        return self.make_records(attribs, contents)
3665
3666
    def test_serialize_add_contents(self):
3667
        tt, LINES = self.make_add_contents_preview()
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3668
        trans_id = tt.trans_id_tree_path('foo')
6973.10.1 by Jelmer Vernooij
Fix some tests.
3669
        tt.create_file([LINES], trans_id)
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3670
        self.assertSerializesTo(self.add_contents_records(), tt)
3671
3672
    def test_deserialize_add_contents(self):
3673
        tt, LINES = self.make_add_contents_preview()
3674
        tt.deserialize(iter(self.add_contents_records()))
3675
        self.assertFileEqual(LINES, tt._limbo_name('new-1'))
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3676
3677
    def test_get_parents_lines(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
3678
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3679
        tree = self.make_branch_and_tree('tree')
3680
        self.build_tree_contents([('tree/file', LINES_ONE)])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3681
        tree.add('file', b'file-id')
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3682
        tt = self.get_preview(tree)
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3683
        trans_id = tt.trans_id_tree_path('file')
6973.10.1 by Jelmer Vernooij
Fix some tests.
3684
        self.assertEqual(([b'aa\n', b'bb\n', b'cc\n', b'dd\n'],),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3685
                         tt._get_parents_lines(trans_id))
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3686
3687
    def test_get_parents_texts(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
3688
        LINES_ONE = b'aa\nbb\ncc\ndd\n'
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3689
        tree = self.make_branch_and_tree('tree')
3690
        self.build_tree_contents([('tree/file', LINES_ONE)])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3691
        tree.add('file', b'file-id')
0.13.18 by Aaron Bentley
Finish converting tests to direct serialize/deserialize tests, clean up
3692
        tt = self.get_preview(tree)
0.13.8 by Aaron Bentley
Integrate serialization into TreeTransforms
3693
        trans_id = tt.trans_id_tree_path('file')
3694
        self.assertEqual((LINES_ONE,),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3695
                         tt._get_parents_texts(trans_id))
5409.1.7 by Vincent Ladeuil
First orphaning implementation (some tests lacking).
3696
3697
3698
class TestOrphan(tests.TestCaseWithTransport):
3699
3700
    def test_no_orphan_for_transform_preview(self):
3701
        tree = self.make_branch_and_tree('tree')
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
3702
        tt = transform.TransformPreview(tree)
5409.1.7 by Vincent Ladeuil
First orphaning implementation (some tests lacking).
3703
        self.addCleanup(tt.finalize)
3704
        self.assertRaises(NotImplementedError, tt.new_orphan, 'foo', 'bar')
3705
5409.1.16 by Vincent Ladeuil
Add ``bzrlib.transform.orphan_policy`` and allows ``never`` to restore the previous behaviour.
3706
    def _set_orphan_policy(self, wt, policy):
6883.13.1 by Jelmer Vernooij
Rename bzr.transform.orphan_policy -> transform.orphan_policy.
3707
        wt.branch.get_config_stack().set('transform.orphan_policy',
7143.15.2 by Jelmer Vernooij
Run autopep8.
3708
                                         policy)
5409.1.16 by Vincent Ladeuil
Add ``bzrlib.transform.orphan_policy`` and allows ``never`` to restore the previous behaviour.
3709
3710
    def _prepare_orphan(self, wt):
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3711
        self.build_tree(['dir/', 'dir/file', 'dir/foo'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3712
        wt.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3713
        wt.commit('add dir and file ignoring foo')
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
3714
        tt = transform.TreeTransform(wt)
3715
        self.addCleanup(tt.finalize)
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3716
        # dir and bar are deleted
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
3717
        dir_tid = tt.trans_id_tree_path('dir')
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3718
        file_tid = tt.trans_id_tree_path('dir/file')
5409.1.16 by Vincent Ladeuil
Add ``bzrlib.transform.orphan_policy`` and allows ``never`` to restore the previous behaviour.
3719
        orphan_tid = tt.trans_id_tree_path('dir/foo')
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3720
        tt.delete_contents(file_tid)
3721
        tt.unversion_file(file_tid)
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
3722
        tt.delete_contents(dir_tid)
3723
        tt.unversion_file(dir_tid)
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3724
        # There should be a conflict because dir still contain foo
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
3725
        raw_conflicts = tt.find_conflicts()
3726
        self.assertLength(1, raw_conflicts)
3727
        self.assertEqual(('missing parent', 'new-1'), raw_conflicts[0])
5409.1.16 by Vincent Ladeuil
Add ``bzrlib.transform.orphan_policy`` and allows ``never`` to restore the previous behaviour.
3728
        return tt, orphan_tid
3729
3730
    def test_new_orphan_created(self):
3731
        wt = self.make_branch_and_tree('.')
5409.1.20 by Vincent Ladeuil
Revert to 'conflict' being the default orphaning policy and fix fallouts.
3732
        self._set_orphan_policy(wt, 'move')
5409.1.16 by Vincent Ladeuil
Add ``bzrlib.transform.orphan_policy`` and allows ``never`` to restore the previous behaviour.
3733
        tt, orphan_tid = self._prepare_orphan(wt)
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3734
        warnings = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
3735
5540.3.1 by Vincent Ladeuil
Fix spurious orphan reports.
3736
        def warning(*args):
3737
            warnings.append(args[0] % args[1:])
3738
        self.overrideAttr(trace, 'warning', warning)
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
3739
        remaining_conflicts = resolve_conflicts(tt)
6681.2.10 by Jelmer Vernooij
Fix failures.
3740
        self.assertEqual(['dir/foo has been orphaned in brz-orphans'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
3741
                         warnings)
5409.7.2 by Vincent Ladeuil
Add NEWS entry, a missing test and some cleanup.
3742
        # Yeah for resolved conflicts !
3743
        self.assertLength(0, remaining_conflicts)
3744
        # We have a new orphan
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
3745
        self.assertEqual('foo.~1~', tt.final_name(orphan_tid))
6681.2.10 by Jelmer Vernooij
Fix failures.
3746
        self.assertEqual('brz-orphans',
7143.15.2 by Jelmer Vernooij
Run autopep8.
3747
                         tt.final_name(tt.final_parent(orphan_tid)))
5409.1.16 by Vincent Ladeuil
Add ``bzrlib.transform.orphan_policy`` and allows ``never`` to restore the previous behaviour.
3748
3749
    def test_never_orphan(self):
3750
        wt = self.make_branch_and_tree('.')
5409.1.20 by Vincent Ladeuil
Revert to 'conflict' being the default orphaning policy and fix fallouts.
3751
        self._set_orphan_policy(wt, 'conflict')
5409.1.16 by Vincent Ladeuil
Add ``bzrlib.transform.orphan_policy`` and allows ``never`` to restore the previous behaviour.
3752
        tt, orphan_tid = self._prepare_orphan(wt)
3753
        remaining_conflicts = resolve_conflicts(tt)
3754
        self.assertLength(1, remaining_conflicts)
3755
        self.assertEqual(('deleting parent', 'Not deleting', 'new-1'),
3756
                         remaining_conflicts.pop())
3757
3758
    def test_orphan_error(self):
3759
        def bogus_orphan(tt, orphan_id, parent_id):
3760
            raise transform.OrphaningError(tt.final_name(orphan_id),
3761
                                           tt.final_name(parent_id))
3762
        transform.orphaning_registry.register('bogus', bogus_orphan,
3763
                                              'Raise an error when orphaning')
3764
        wt = self.make_branch_and_tree('.')
3765
        self._set_orphan_policy(wt, 'bogus')
3766
        tt, orphan_tid = self._prepare_orphan(wt)
3767
        remaining_conflicts = resolve_conflicts(tt)
3768
        self.assertLength(1, remaining_conflicts)
3769
        self.assertEqual(('deleting parent', 'Not deleting', 'new-1'),
3770
                         remaining_conflicts.pop())
5409.1.17 by Vincent Ladeuil
Ensures we fallback to the default policy if a bogus one is specified.
3771
3772
    def test_unknown_orphan_policy(self):
3773
        wt = self.make_branch_and_tree('.')
3774
        # Set a fictional policy nobody ever implemented
3775
        self._set_orphan_policy(wt, 'donttouchmypreciouuus')
3776
        tt, orphan_tid = self._prepare_orphan(wt)
3777
        warnings = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
3778
5409.1.17 by Vincent Ladeuil
Ensures we fallback to the default policy if a bogus one is specified.
3779
        def warning(*args):
3780
            warnings.append(args[0] % args[1:])
3781
        self.overrideAttr(trace, 'warning', warning)
3782
        remaining_conflicts = resolve_conflicts(tt)
5409.1.20 by Vincent Ladeuil
Revert to 'conflict' being the default orphaning policy and fix fallouts.
3783
        # We fallback to the default policy which create a conflict
3784
        self.assertLength(1, remaining_conflicts)
3785
        self.assertEqual(('deleting parent', 'Not deleting', 'new-1'),
3786
                         remaining_conflicts.pop())
3787
        self.assertLength(1, warnings)
6449.6.7 by Jelmer Vernooij
Fix tests.
3788
        self.assertStartsWith(warnings[0], 'Value "donttouchmypreciouuus" ')
6434.2.2 by Jelmer Vernooij
Add hooks for tree transforms.
3789
3790
3791
class TestTransformHooks(tests.TestCaseWithTransport):
3792
3793
    def setUp(self):
3794
        super(TestTransformHooks, self).setUp()
3795
        self.wt = self.make_branch_and_tree('.')
3796
        os.chdir('..')
3797
3798
    def get_transform(self):
3799
        transform = TreeTransform(self.wt)
3800
        self.addCleanup(transform.finalize)
3801
        return transform, transform.root
3802
3803
    def test_pre_commit_hooks(self):
3804
        calls = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
3805
6434.2.2 by Jelmer Vernooij
Add hooks for tree transforms.
3806
        def record_pre_transform(tree, tt):
3807
            calls.append((tree, tt))
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3808
        MutableTree.hooks.install_named_hook(
3809
            'pre_transform', record_pre_transform, "Pre transform")
6434.2.2 by Jelmer Vernooij
Add hooks for tree transforms.
3810
        transform, root = self.get_transform()
3811
        old_root_id = transform.tree_file_id(root)
3812
        transform.apply()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
3813
        self.assertEqual(old_root_id, self.wt.path2id(''))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
3814
        self.assertEqual([(self.wt, transform)], calls)
6434.2.2 by Jelmer Vernooij
Add hooks for tree transforms.
3815
3816
    def test_post_commit_hooks(self):
3817
        calls = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
3818
6434.2.2 by Jelmer Vernooij
Add hooks for tree transforms.
3819
        def record_post_transform(tree, tt):
3820
            calls.append((tree, tt))
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3821
        MutableTree.hooks.install_named_hook(
3822
            'post_transform', record_post_transform, "Post transform")
6434.2.2 by Jelmer Vernooij
Add hooks for tree transforms.
3823
        transform, root = self.get_transform()
3824
        old_root_id = transform.tree_file_id(root)
3825
        transform.apply()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
3826
        self.assertEqual(old_root_id, self.wt.path2id(''))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
3827
        self.assertEqual([(self.wt, transform)], calls)
6652.1.1 by Jelmer Vernooij
Bundle the link-tree command.
3828
3829
3830
class TestLinkTree(tests.TestCaseWithTransport):
3831
3832
    _test_needs_features = [HardlinkFeature]
3833
3834
    def setUp(self):
3835
        tests.TestCaseWithTransport.setUp(self)
3836
        self.parent_tree = self.make_branch_and_tree('parent')
3837
        self.parent_tree.lock_write()
3838
        self.addCleanup(self.parent_tree.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
3839
        self.build_tree_contents([('parent/foo', b'bar')])
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
3840
        self.parent_tree.add('foo')
6652.1.1 by Jelmer Vernooij
Bundle the link-tree command.
3841
        self.parent_tree.commit('added foo')
6652.1.4 by Jelmer Vernooij
Fix test.
3842
        child_controldir = self.parent_tree.controldir.sprout('child')
3843
        self.child_tree = child_controldir.open_workingtree()
6652.1.1 by Jelmer Vernooij
Bundle the link-tree command.
3844
3845
    def hardlinked(self):
3846
        parent_stat = os.lstat(self.parent_tree.abspath('foo'))
3847
        child_stat = os.lstat(self.child_tree.abspath('foo'))
3848
        return parent_stat.st_ino == child_stat.st_ino
3849
3850
    def test_link_fails_if_modified(self):
3851
        """If the file to be linked has modified text, don't link."""
6855.4.1 by Jelmer Vernooij
Yet more bees.
3852
        self.build_tree_contents([('child/foo', b'baz')])
6652.1.1 by Jelmer Vernooij
Bundle the link-tree command.
3853
        transform.link_tree(self.child_tree, self.parent_tree)
3854
        self.assertFalse(self.hardlinked())
3855
3856
    def test_link_fails_if_execute_bit_changed(self):
3857
        """If the file to be linked has modified execute bit, don't link."""
3858
        tt = TreeTransform(self.child_tree)
3859
        try:
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
3860
            trans_id = tt.trans_id_tree_path('foo')
6652.1.1 by Jelmer Vernooij
Bundle the link-tree command.
3861
            tt.set_executability(True, trans_id)
3862
            tt.apply()
3863
        finally:
3864
            tt.finalize()
3865
        transform.link_tree(self.child_tree, self.parent_tree)
3866
        self.assertFalse(self.hardlinked())
3867
3868
    def test_link_succeeds_if_unmodified(self):
3869
        """If the file to be linked is unmodified, link"""
3870
        transform.link_tree(self.child_tree, self.parent_tree)
3871
        self.assertTrue(self.hardlinked())