/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2005-2012, 2016 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
963 by Martin Pool
- add the start of a test for inventory file-id matching
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
#
963 by Martin Pool
- add the start of a test for inventory file-id matching
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
#
963 by Martin Pool
- add the start of a test for inventory file-id matching
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
963 by Martin Pool
- add the start of a test for inventory file-id matching
16
2729.2.5 by Martin Pool
Move per-inventory tests from test_inv to tests.inventory_implementations
17
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
18
from .. import (
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
19
    errors,
20
    osutils,
21
    repository,
22
    revision,
4634.51.1 by John Arbash Meinel
Switch away from creating a whole repository just to get a VF.
23
    tests,
5662.3.1 by Jelmer Vernooij
Add WorkingTreeFormatRegistry.
24
    workingtree,
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
25
    )
6973.6.2 by Jelmer Vernooij
Fix more tests.
26
from ..sixish import text_type
6670.4.1 by Jelmer Vernooij
Update imports.
27
from ..bzr import (
28
    chk_map,
29
    groupcompress,
30
    inventory,
31
    )
32
from ..bzr.inventory import (
5579.3.1 by Jelmer Vernooij
Remove unused imports.
33
    CHKInventory,
34
    Inventory,
35
    ROOT_ID,
36
    InventoryFile,
37
    InventoryDirectory,
38
    InventoryEntry,
39
    TreeReference,
5802.1.2 by Jelmer Vernooij
Add test for mutable_inventory_from_tree.
40
    mutable_inventory_from_tree,
5579.3.1 by Jelmer Vernooij
Remove unused imports.
41
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
42
from . import (
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
43
    TestCase,
44
    TestCaseWithTransport,
45
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
46
from .scenarios import load_tests_apply_scenarios
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
47
48
49
load_tests = load_tests_apply_scenarios
50
51
52
def delta_application_scenarios():
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
53
    scenarios = [
54
        ('Inventory', {'apply_delta':apply_inventory_Inventory}),
55
        ]
56
    # Working tree basis delta application
57
    # Repository add_inv_by_delta.
58
    # Reduce form of the per_repository test logic - that logic needs to be
59
    # be able to get /just/ repositories whereas these tests are fine with
60
    # just creating trees.
61
    formats = set()
62
    for _, format in repository.format_registry.iteritems():
5718.3.1 by Jelmer Vernooij
Skip more tests for repository formats that don't support the full
63
        if format.supports_full_versioned_files:
64
            scenarios.append((str(format.__name__), {
65
                'apply_delta':apply_inventory_Repository_add_inventory_by_delta,
66
                'format':format}))
7002.1.1 by Martin
Avoid import error from test_inv without dulwich
67
    for getter in workingtree.format_registry._get_all_lazy():
68
        try:
69
            format = getter()
70
            if callable(format):
71
                format = format()
72
        except ImportError:
73
            pass  # Format with unmet dependency
6746.2.1 by Jelmer Vernooij
Rename matchingbzrdir to matchingcontroldir.
74
        repo_fmt = format._matchingcontroldir.repository_format
5718.3.1 by Jelmer Vernooij
Skip more tests for repository formats that don't support the full
75
        if not repo_fmt.supports_full_versioned_files:
76
            continue
4526.9.2 by Robert Collins
Handle deltas with new paths not matching the actual path.
77
        scenarios.append(
78
            (str(format.__class__.__name__) + ".update_basis_by_delta", {
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
79
            'apply_delta':apply_inventory_WT_basis,
80
            'format':format}))
4526.9.2 by Robert Collins
Handle deltas with new paths not matching the actual path.
81
        scenarios.append(
82
            (str(format.__class__.__name__) + ".apply_inventory_delta", {
4526.9.1 by Robert Collins
Add WorkingTree.apply_inventory_delta to the set of delta implementations interface tested.
83
            'apply_delta':apply_inventory_WT,
84
            'format':format}))
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
85
    return scenarios
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
86
87
4634.35.19 by Andrew Bennetts
Fix test_inv.
88
def create_texts_for_inv(repo, inv):
89
    for path, ie in inv.iter_entries():
90
        if ie.text_size:
91
            lines = ['a' * ie.text_size]
92
        else:
93
            lines = []
94
        repo.texts.add_lines((ie.file_id, ie.revision), [], lines)
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
95
5718.3.1 by Jelmer Vernooij
Skip more tests for repository formats that don't support the full
96
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
97
def apply_inventory_Inventory(self, basis, delta, invalid_delta=True):
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
98
    """Apply delta to basis and return the result.
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
99
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
100
    :param basis: An inventory to be used as the basis.
101
    :param delta: The inventory delta to apply:
102
    :return: An inventory resulting from the application.
103
    """
104
    basis.apply_delta(delta)
105
    return basis
106
107
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
108
def apply_inventory_WT(self, basis, delta, invalid_delta=True):
4526.9.1 by Robert Collins
Add WorkingTree.apply_inventory_delta to the set of delta implementations interface tested.
109
    """Apply delta to basis and return the result.
110
111
    This sets the tree state to be basis, and then calls apply_inventory_delta.
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
112
4526.9.1 by Robert Collins
Add WorkingTree.apply_inventory_delta to the set of delta implementations interface tested.
113
    :param basis: An inventory to be used as the basis.
114
    :param delta: The inventory delta to apply:
115
    :return: An inventory resulting from the application.
116
    """
6746.2.1 by Jelmer Vernooij
Rename matchingbzrdir to matchingcontroldir.
117
    control = self.make_controldir('tree', format=self.format._matchingcontroldir)
4526.9.1 by Robert Collins
Add WorkingTree.apply_inventory_delta to the set of delta implementations interface tested.
118
    control.create_repository()
119
    control.create_branch()
120
    tree = self.format.initialize(control)
121
    tree.lock_write()
122
    try:
123
        tree._write_inventory(basis)
124
    finally:
125
        tree.unlock()
126
    # Fresh object, reads disk again.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
127
    tree = tree.controldir.open_workingtree()
4526.9.1 by Robert Collins
Add WorkingTree.apply_inventory_delta to the set of delta implementations interface tested.
128
    tree.lock_write()
129
    try:
130
        tree.apply_inventory_delta(delta)
131
    finally:
132
        tree.unlock()
133
    # reload tree - ensure we get what was written.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
134
    tree = tree.controldir.open_workingtree()
4526.9.1 by Robert Collins
Add WorkingTree.apply_inventory_delta to the set of delta implementations interface tested.
135
    tree.lock_read()
136
    self.addCleanup(tree.unlock)
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
137
    if not invalid_delta:
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
138
        tree._validate()
6405.2.9 by Jelmer Vernooij
More test fixes.
139
    return tree.root_inventory
4526.9.1 by Robert Collins
Add WorkingTree.apply_inventory_delta to the set of delta implementations interface tested.
140
141
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
142
def _create_repo_revisions(repo, basis, delta, invalid_delta):
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
143
    repo.start_write_group()
144
    try:
145
        rev = revision.Revision('basis', timestamp=0, timezone=None,
146
            message="", committer="foo@example.com")
147
        basis.revision_id = 'basis'
148
        create_texts_for_inv(repo, basis)
149
        repo.add_revision('basis', rev, basis)
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
150
        if invalid_delta:
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
151
            # We don't want to apply the delta to the basis, because we expect
152
            # the delta is invalid.
153
            result_inv = basis
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
154
            result_inv.revision_id = b'result'
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
155
            target_entries = None
156
        else:
157
            result_inv = basis.create_by_apply_delta(delta, 'result')
158
            create_texts_for_inv(repo, result_inv)
159
            target_entries = list(result_inv.iter_entries_by_dir())
160
        rev = revision.Revision('result', timestamp=0, timezone=None,
161
            message="", committer="foo@example.com")
162
        repo.add_revision('result', rev, result_inv)
163
        repo.commit_write_group()
164
    except:
165
        repo.abort_write_group()
166
        raise
167
    return target_entries
168
169
170
def _get_basis_entries(tree):
171
    basis_tree = tree.basis_tree()
172
    basis_tree.lock_read()
173
    basis_tree_entries = list(basis_tree.inventory.iter_entries_by_dir())
174
    basis_tree.unlock()
175
    return basis_tree_entries
176
177
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
178
def _populate_different_tree(tree, basis, delta):
179
    """Put all entries into tree, but at a unique location."""
180
    added_ids = set()
181
    added_paths = set()
6855.4.1 by Jelmer Vernooij
Yet more bees.
182
    tree.add(['unique-dir'], [b'unique-dir-id'], ['directory'])
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
183
    for path, ie in basis.iter_entries_by_dir():
184
        if ie.file_id in added_ids:
185
            continue
186
        # We want a unique path for each of these, we use the file-id
187
        tree.add(['unique-dir/' + ie.file_id], [ie.file_id], [ie.kind])
188
        added_ids.add(ie.file_id)
189
    for old_path, new_path, file_id, ie in delta:
190
        if file_id in added_ids:
191
            continue
192
        tree.add(['unique-dir/' + file_id], [file_id], [ie.kind])
193
194
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
195
def apply_inventory_WT_basis(test, basis, delta, invalid_delta=True):
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
196
    """Apply delta to basis and return the result.
197
198
    This sets the parent and then calls update_basis_by_delta.
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
199
    It also puts the basis in the repository under both 'basis' and 'result' to
200
    allow safety checks made by the WT to succeed, and finally ensures that all
201
    items in the delta with a new path are present in the WT before calling
202
    update_basis_by_delta.
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
203
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
204
    :param basis: An inventory to be used as the basis.
205
    :param delta: The inventory delta to apply:
206
    :return: An inventory resulting from the application.
207
    """
6746.2.1 by Jelmer Vernooij
Rename matchingbzrdir to matchingcontroldir.
208
    control = test.make_controldir('tree', format=test.format._matchingcontroldir)
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
209
    control.create_repository()
210
    control.create_branch()
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
211
    tree = test.format.initialize(control)
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
212
    tree.lock_write()
213
    try:
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
214
        target_entries = _create_repo_revisions(tree.branch.repository, basis,
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
215
                                                delta, invalid_delta)
4505.5.5 by Robert Collins
Parents used in a delta must be directories.
216
        # Set the basis state as the trees current state
217
        tree._write_inventory(basis)
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
218
        # This reads basis from the repo and puts it into the tree's local
219
        # cache, if it has one.
6973.10.6 by Jelmer Vernooij
Fix tests.
220
        tree.set_parent_ids([b'basis'])
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
221
    finally:
222
        tree.unlock()
223
    # Fresh lock, reads disk again.
6973.10.6 by Jelmer Vernooij
Fix tests.
224
    with tree.lock_write():
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
225
        tree.update_basis_by_delta('result', delta)
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
226
        if not invalid_delta:
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
227
            tree._validate()
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
228
    # reload tree - ensure we get what was written.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
229
    tree = tree.controldir.open_workingtree()
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
230
    basis_tree = tree.basis_tree()
231
    basis_tree.lock_read()
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
232
    test.addCleanup(basis_tree.unlock)
6405.2.10 by Jelmer Vernooij
Fix more tests.
233
    basis_inv = basis_tree.root_inventory
5847.4.12 by John Arbash Meinel
(broken) Expand the test coverage for cases we care about.
234
    if target_entries:
235
        basis_entries = list(basis_inv.iter_entries_by_dir())
236
        test.assertEqual(target_entries, basis_entries)
237
    return basis_inv
238
239
240
def apply_inventory_Repository_add_inventory_by_delta(self, basis, delta,
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
241
                                                      invalid_delta=True):
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
242
    """Apply delta to basis and return the result.
243
    
244
    This inserts basis as a whole inventory and then uses
245
    add_inventory_by_delta to add delta.
246
247
    :param basis: An inventory to be used as the basis.
248
    :param delta: The inventory delta to apply:
249
    :return: An inventory resulting from the application.
250
    """
251
    format = self.format()
6746.2.1 by Jelmer Vernooij
Rename matchingbzrdir to matchingcontroldir.
252
    control = self.make_controldir('tree', format=format._matchingcontroldir)
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
253
    repo = format.initialize(control)
254
    repo.lock_write()
255
    try:
256
        repo.start_write_group()
257
        try:
6973.5.2 by Jelmer Vernooij
Add more bees.
258
            rev = revision.Revision(b'basis', timestamp=0, timezone=None,
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
259
                message="", committer="foo@example.com")
6973.5.2 by Jelmer Vernooij
Add more bees.
260
            basis.revision_id = b'basis'
4634.35.19 by Andrew Bennetts
Fix test_inv.
261
            create_texts_for_inv(repo, basis)
6973.5.2 by Jelmer Vernooij
Add more bees.
262
            repo.add_revision(b'basis', rev, basis)
4634.35.19 by Andrew Bennetts
Fix test_inv.
263
            repo.commit_write_group()
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
264
        except:
265
            repo.abort_write_group()
266
            raise
267
    finally:
268
        repo.unlock()
269
    repo.lock_write()
270
    try:
271
        repo.start_write_group()
272
        try:
6973.5.2 by Jelmer Vernooij
Add more bees.
273
            inv_sha1 = repo.add_inventory_by_delta(b'basis', delta,
274
                b'result', [b'basis'])
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
275
        except:
276
            repo.abort_write_group()
277
            raise
278
        else:
279
            repo.commit_write_group()
280
    finally:
281
        repo.unlock()
282
    # Fresh lock, reads disk again.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
283
    repo = repo.controldir.open_repository()
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
284
    repo.lock_read()
285
    self.addCleanup(repo.unlock)
6973.5.2 by Jelmer Vernooij
Add more bees.
286
    return repo.get_inventory(b'result')
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
287
288
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
289
class TestInventoryUpdates(TestCase):
290
291
    def test_creation_from_root_id(self):
292
        # iff a root id is passed to the constructor, a root directory is made
6684.1.4 by Martin
Start making inventory tests pass on Python 3
293
        inv = inventory.Inventory(root_id=b'tree-root')
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
294
        self.assertNotEqual(None, inv.root)
6684.1.4 by Martin
Start making inventory tests pass on Python 3
295
        self.assertEqual(b'tree-root', inv.root.file_id)
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
296
297
    def test_add_path_of_root(self):
298
        # if no root id is given at creation time, there is no root directory
299
        inv = inventory.Inventory(root_id=None)
300
        self.assertIs(None, inv.root)
301
        # add a root entry by adding its path
6684.1.4 by Martin
Start making inventory tests pass on Python 3
302
        ie = inv.add_path(u"", "directory", b"my-root")
303
        ie.revision = b'test-rev'
304
        self.assertEqual(b"my-root", ie.file_id)
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
305
        self.assertIs(ie, inv.root)
306
307
    def test_add_path(self):
6684.1.4 by Martin
Start making inventory tests pass on Python 3
308
        inv = inventory.Inventory(root_id=b'tree_root')
309
        ie = inv.add_path(u'hello', 'file', b'hello-id')
310
        self.assertEqual(b'hello-id', ie.file_id)
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
311
        self.assertEqual('file', ie.kind)
312
313
    def test_copy(self):
314
        """Make sure copy() works and creates a deep copy."""
6684.1.4 by Martin
Start making inventory tests pass on Python 3
315
        inv = inventory.Inventory(root_id=b'some-tree-root')
316
        ie = inv.add_path(u'hello', 'file', b'hello-id')
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
317
        inv2 = inv.copy()
6684.1.4 by Martin
Start making inventory tests pass on Python 3
318
        inv.root.file_id = b'some-new-root'
319
        ie.name = u'file2'
320
        self.assertEqual(b'some-tree-root', inv2.root.file_id)
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
321
        self.assertEqual(u'hello', inv2.get_entry(b'hello-id').name)
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
322
323
    def test_copy_empty(self):
324
        """Make sure an empty inventory can be copied."""
325
        inv = inventory.Inventory(root_id=None)
326
        inv2 = inv.copy()
327
        self.assertIs(None, inv2.root)
328
329
    def test_copy_copies_root_revision(self):
330
        """Make sure the revision of the root gets copied."""
6684.1.4 by Martin
Start making inventory tests pass on Python 3
331
        inv = inventory.Inventory(root_id=b'someroot')
332
        inv.root.revision = b'therev'
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
333
        inv2 = inv.copy()
6684.1.4 by Martin
Start making inventory tests pass on Python 3
334
        self.assertEqual(b'someroot', inv2.root.file_id)
335
        self.assertEqual(b'therev', inv2.root.revision)
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
336
337
    def test_create_tree_reference(self):
6684.1.4 by Martin
Start making inventory tests pass on Python 3
338
        inv = inventory.Inventory(b'tree-root-123')
339
        inv.add(TreeReference(
340
            b'nested-id', 'nested', parent_id=b'tree-root-123',
341
            revision=b'rev', reference_revision=b'rev2'))
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
342
343
    def test_error_encoding(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
344
        inv = inventory.Inventory(b'tree-root')
345
        inv.add(InventoryFile(b'a-id', u'\u1234', b'tree-root'))
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
346
        e = self.assertRaises(errors.InconsistentDelta, inv.add,
6855.4.1 by Jelmer Vernooij
Yet more bees.
347
            InventoryFile(b'b-id', u'\u1234', b'tree-root'))
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
348
        self.assertContainsRe(str(e), r'\\u1234')
349
350
    def test_add_recursive(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
351
        parent = InventoryDirectory(b'src-id', 'src', b'tree-root')
352
        child = InventoryFile(b'hello-id', 'hello.c', b'src-id')
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
353
        parent.children[child.file_id] = child
6855.4.1 by Jelmer Vernooij
Yet more bees.
354
        inv = inventory.Inventory(b'tree-root')
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
355
        inv.add(parent)
6855.4.1 by Jelmer Vernooij
Yet more bees.
356
        self.assertEqual('src/hello.c', inv.id2path(b'hello-id'))
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
357
358
359
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
360
class TestDeltaApplication(TestCaseWithTransport):
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
361
362
    scenarios = delta_application_scenarios()
7002.1.1 by Martin
Avoid import error from test_inv without dulwich
363
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
364
    def get_empty_inventory(self, reference_inv=None):
365
        """Get an empty inventory.
366
367
        Note that tests should not depend on the revision of the root for
368
        setting up test conditions, as it has to be flexible to accomodate non
369
        rich root repositories.
370
371
        :param reference_inv: If not None, get the revision for the root from
372
            this inventory. This is useful for dealing with older repositories
373
            that routinely discarded the root entry data. If None, the root's
374
            revision is set to 'basis'.
375
        """
376
        inv = inventory.Inventory()
377
        if reference_inv is not None:
378
            inv.root.revision = reference_inv.root.revision
379
        else:
380
            inv.root.revision = 'basis'
381
        return inv
382
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
383
    def make_file_ie(self, file_id=b'file-id', name='name', parent_id=None):
5847.4.10 by John Arbash Meinel
A few more bug fixes.
384
        ie_file = inventory.InventoryFile(file_id, name, parent_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
385
        ie_file.revision = b'result'
5847.4.10 by John Arbash Meinel
A few more bug fixes.
386
        ie_file.text_size = 0
387
        ie_file.text_sha1 = ''
388
        return ie_file
389
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
390
    def test_empty_delta(self):
391
        inv = self.get_empty_inventory()
392
        delta = []
393
        inv = self.apply_delta(self, inv, delta)
394
        inv2 = self.get_empty_inventory(inv)
395
        self.assertEqual([], inv2._make_delta(inv))
396
4526.9.22 by Robert Collins
Check fileids in inventory deltas are not None and are strings.
397
    def test_None_file_id(self):
398
        inv = self.get_empty_inventory()
399
        dir1 = inventory.InventoryDirectory(None, 'dir1', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
400
        dir1.revision = b'result'
4526.9.22 by Robert Collins
Check fileids in inventory deltas are not None and are strings.
401
        delta = [(None, u'dir1', None, dir1)]
402
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
403
            inv, delta)
404
405
    def test_unicode_file_id(self):
406
        inv = self.get_empty_inventory()
407
        dir1 = inventory.InventoryDirectory(u'dirid', 'dir1', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
408
        dir1.revision = b'result'
4526.9.22 by Robert Collins
Check fileids in inventory deltas are not None and are strings.
409
        delta = [(None, u'dir1', dir1.file_id, dir1)]
410
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
411
            inv, delta)
412
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
413
    def test_repeated_file_id(self):
414
        inv = self.get_empty_inventory()
415
        file1 = inventory.InventoryFile('id', 'path1', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
416
        file1.revision = b'result'
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
417
        file1.text_size = 0
418
        file1.text_sha1 = ""
5847.4.10 by John Arbash Meinel
A few more bug fixes.
419
        file2 = file1.copy()
420
        file2.name = 'path2'
4505.5.7 by Robert Collins
Handle unicode parents correctly in dirstate parent checking.
421
        delta = [(None, u'path1', 'id', file1), (None, u'path2', 'id', file2)]
4505.5.3 by Robert Collins
Test infrastructure for testing all inventory delta applications and fix CHK inventories to reject repeated file ids in deltas.
422
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
423
            inv, delta)
963 by Martin Pool
- add the start of a test for inventory file-id matching
424
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
425
    def test_repeated_new_path(self):
426
        inv = self.get_empty_inventory()
427
        file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
428
        file1.revision = b'result'
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
429
        file1.text_size = 0
430
        file1.text_sha1 = ""
5847.4.10 by John Arbash Meinel
A few more bug fixes.
431
        file2 = file1.copy()
432
        file2.file_id = 'id2'
4505.5.7 by Robert Collins
Handle unicode parents correctly in dirstate parent checking.
433
        delta = [(None, u'path', 'id1', file1), (None, u'path', 'id2', file2)]
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
434
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
435
            inv, delta)
436
437
    def test_repeated_old_path(self):
438
        inv = self.get_empty_inventory()
439
        file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
440
        file1.revision = b'result'
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
441
        file1.text_size = 0
442
        file1.text_sha1 = ""
443
        # We can't *create* a source inventory with the same path, but
444
        # a badly generated partial delta might claim the same source twice.
445
        # This would be buggy in two ways: the path is repeated in the delta,
446
        # And the path for one of the file ids doesn't match the source
447
        # location. Alternatively, we could have a repeated fileid, but that
448
        # is separately checked for.
449
        file2 = inventory.InventoryFile('id2', 'path2', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
450
        file2.revision = b'result'
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
451
        file2.text_size = 0
452
        file2.text_sha1 = ""
453
        inv.add(file1)
454
        inv.add(file2)
4505.5.7 by Robert Collins
Handle unicode parents correctly in dirstate parent checking.
455
        delta = [(u'path', None, 'id1', None), (u'path', None, 'id2', None)]
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
456
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
457
            inv, delta)
458
459
    def test_mismatched_id_entry_id(self):
460
        inv = self.get_empty_inventory()
461
        file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
462
        file1.revision = b'result'
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
463
        file1.text_size = 0
464
        file1.text_sha1 = ""
4505.5.7 by Robert Collins
Handle unicode parents correctly in dirstate parent checking.
465
        delta = [(None, u'path', 'id', file1)]
4505.5.4 by Robert Collins
Repeated path/id corruption detected.
466
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
467
            inv, delta)
468
4526.9.4 by Robert Collins
Look for trivial issues with new_path and entry being out of sync in deltas.
469
    def test_mismatched_new_path_entry_None(self):
470
        inv = self.get_empty_inventory()
471
        delta = [(None, u'path', 'id', None)]
472
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
473
            inv, delta)
474
475
    def test_mismatched_new_path_None_entry(self):
476
        inv = self.get_empty_inventory()
477
        file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
478
        file1.revision = b'result'
4526.9.4 by Robert Collins
Look for trivial issues with new_path and entry being out of sync in deltas.
479
        file1.text_size = 0
480
        file1.text_sha1 = ""
481
        delta = [(u"path", None, 'id1', file1)]
482
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
483
            inv, delta)
484
4505.5.5 by Robert Collins
Parents used in a delta must be directories.
485
    def test_parent_is_not_directory(self):
486
        inv = self.get_empty_inventory()
487
        file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
488
        file1.revision = b'result'
4505.5.5 by Robert Collins
Parents used in a delta must be directories.
489
        file1.text_size = 0
490
        file1.text_sha1 = ""
491
        file2 = inventory.InventoryFile('id2', 'path2', 'id1')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
492
        file2.revision = b'result'
4505.5.5 by Robert Collins
Parents used in a delta must be directories.
493
        file2.text_size = 0
494
        file2.text_sha1 = ""
495
        inv.add(file1)
4505.5.7 by Robert Collins
Handle unicode parents correctly in dirstate parent checking.
496
        delta = [(None, u'path/path2', 'id2', file2)]
4505.5.5 by Robert Collins
Parents used in a delta must be directories.
497
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
498
            inv, delta)
499
4505.5.6 by Robert Collins
Check for missing parents in deltas.
500
    def test_parent_is_missing(self):
501
        inv = self.get_empty_inventory()
502
        file2 = inventory.InventoryFile('id2', 'path2', 'missingparent')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
503
        file2.revision = b'result'
4505.5.6 by Robert Collins
Check for missing parents in deltas.
504
        file2.text_size = 0
505
        file2.text_sha1 = ""
4505.5.7 by Robert Collins
Handle unicode parents correctly in dirstate parent checking.
506
        delta = [(None, u'path/path2', 'id2', file2)]
4505.5.6 by Robert Collins
Check for missing parents in deltas.
507
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
508
            inv, delta)
509
4526.9.2 by Robert Collins
Handle deltas with new paths not matching the actual path.
510
    def test_new_parent_path_has_wrong_id(self):
511
        inv = self.get_empty_inventory()
512
        parent1 = inventory.InventoryDirectory('p-1', 'dir', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
513
        parent1.revision = b'result'
4526.9.2 by Robert Collins
Handle deltas with new paths not matching the actual path.
514
        parent2 = inventory.InventoryDirectory('p-2', 'dir2', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
515
        parent2.revision = b'result'
4526.9.2 by Robert Collins
Handle deltas with new paths not matching the actual path.
516
        file1 = inventory.InventoryFile('id', 'path', 'p-2')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
517
        file1.revision = b'result'
4526.9.2 by Robert Collins
Handle deltas with new paths not matching the actual path.
518
        file1.text_size = 0
519
        file1.text_sha1 = ""
520
        inv.add(parent1)
521
        inv.add(parent2)
522
        # This delta claims that file1 is at dir/path, but actually its at
523
        # dir2/path if you follow the inventory parent structure.
524
        delta = [(None, u'dir/path', 'id', file1)]
525
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
526
            inv, delta)
527
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
528
    def test_old_parent_path_is_wrong(self):
529
        inv = self.get_empty_inventory()
530
        parent1 = inventory.InventoryDirectory('p-1', 'dir', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
531
        parent1.revision = b'result'
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
532
        parent2 = inventory.InventoryDirectory('p-2', 'dir2', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
533
        parent2.revision = b'result'
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
534
        file1 = inventory.InventoryFile('id', 'path', 'p-2')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
535
        file1.revision = b'result'
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
536
        file1.text_size = 0
537
        file1.text_sha1 = ""
538
        inv.add(parent1)
539
        inv.add(parent2)
540
        inv.add(file1)
541
        # This delta claims that file1 was at dir/path, but actually it was at
542
        # dir2/path if you follow the inventory parent structure.
543
        delta = [(u'dir/path', None, 'id', None)]
544
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
545
            inv, delta)
546
547
    def test_old_parent_path_is_for_other_id(self):
548
        inv = self.get_empty_inventory()
549
        parent1 = inventory.InventoryDirectory('p-1', 'dir', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
550
        parent1.revision = b'result'
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
551
        parent2 = inventory.InventoryDirectory('p-2', 'dir2', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
552
        parent2.revision = b'result'
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
553
        file1 = inventory.InventoryFile('id', 'path', 'p-2')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
554
        file1.revision = b'result'
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
555
        file1.text_size = 0
556
        file1.text_sha1 = ""
557
        file2 = inventory.InventoryFile('id2', 'path', 'p-1')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
558
        file2.revision = b'result'
4526.9.3 by Robert Collins
Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.
559
        file2.text_size = 0
560
        file2.text_sha1 = ""
561
        inv.add(parent1)
562
        inv.add(parent2)
563
        inv.add(file1)
564
        inv.add(file2)
565
        # This delta claims that file1 was at dir/path, but actually it was at
566
        # dir2/path if you follow the inventory parent structure. At dir/path
567
        # is another entry we should not delete.
568
        delta = [(u'dir/path', None, 'id', None)]
569
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
570
            inv, delta)
571
4526.9.5 by Robert Collins
Require that added ids in inventory deltas be new.
572
    def test_add_existing_id_new_path(self):
573
        inv = self.get_empty_inventory()
574
        parent1 = inventory.InventoryDirectory('p-1', 'dir1', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
575
        parent1.revision = b'result'
4526.9.5 by Robert Collins
Require that added ids in inventory deltas be new.
576
        parent2 = inventory.InventoryDirectory('p-1', 'dir2', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
577
        parent2.revision = b'result'
4526.9.5 by Robert Collins
Require that added ids in inventory deltas be new.
578
        inv.add(parent1)
579
        delta = [(None, u'dir2', 'p-1', parent2)]
580
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
581
            inv, delta)
582
4526.9.8 by Robert Collins
Check that the paths deltas put entries into are not in use already.
583
    def test_add_new_id_existing_path(self):
584
        inv = self.get_empty_inventory()
585
        parent1 = inventory.InventoryDirectory('p-1', 'dir1', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
586
        parent1.revision = b'result'
4526.9.8 by Robert Collins
Check that the paths deltas put entries into are not in use already.
587
        parent2 = inventory.InventoryDirectory('p-2', 'dir1', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
588
        parent2.revision = b'result'
4526.9.8 by Robert Collins
Check that the paths deltas put entries into are not in use already.
589
        inv.add(parent1)
590
        delta = [(None, u'dir1', 'p-2', parent2)]
591
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
592
            inv, delta)
593
4526.9.9 by Robert Collins
Add interface tests for dangling children in inventory deltas.
594
    def test_remove_dir_leaving_dangling_child(self):
595
        inv = self.get_empty_inventory()
596
        dir1 = inventory.InventoryDirectory('p-1', 'dir1', inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
597
        dir1.revision = b'result'
4526.9.9 by Robert Collins
Add interface tests for dangling children in inventory deltas.
598
        dir2 = inventory.InventoryDirectory('p-2', 'child1', 'p-1')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
599
        dir2.revision = b'result'
4526.9.9 by Robert Collins
Add interface tests for dangling children in inventory deltas.
600
        dir3 = inventory.InventoryDirectory('p-3', 'child2', 'p-1')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
601
        dir3.revision = b'result'
4526.9.9 by Robert Collins
Add interface tests for dangling children in inventory deltas.
602
        inv.add(dir1)
603
        inv.add(dir2)
604
        inv.add(dir3)
605
        delta = [(u'dir1', None, 'p-1', None),
606
            (u'dir1/child2', None, 'p-3', None)]
607
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
608
            inv, delta)
609
5876.1.1 by John Arbash Meinel
Fix bug #781168, and allow WT.update_basis_by_delta
610
    def test_add_file(self):
611
        inv = self.get_empty_inventory()
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
612
        file1 = inventory.InventoryFile(b'file-id', 'path', inv.root.file_id)
613
        file1.revision = b'result'
5876.1.1 by John Arbash Meinel
Fix bug #781168, and allow WT.update_basis_by_delta
614
        file1.text_size = 0
615
        file1.text_sha1 = ''
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
616
        delta = [(None, u'path', b'file-id', file1)]
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
617
        res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
6855.4.10 by Jelmer Vernooij
merge trunk
618
        self.assertEqual(b'file-id', res_inv.get_entry(b'file-id').file_id)
5876.1.1 by John Arbash Meinel
Fix bug #781168, and allow WT.update_basis_by_delta
619
620
    def test_remove_file(self):
621
        inv = self.get_empty_inventory()
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
622
        file1 = inventory.InventoryFile(b'file-id', 'path', inv.root.file_id)
623
        file1.revision = b'result'
5876.1.1 by John Arbash Meinel
Fix bug #781168, and allow WT.update_basis_by_delta
624
        file1.text_size = 0
625
        file1.text_sha1 = ''
626
        inv.add(file1)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
627
        delta = [(u'path', None, b'file-id', None)]
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
628
        res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
6856 by Jelmer Vernooij
Merge lp:~jelmer/brz/is-versioned.
629
        self.assertEqual(None, res_inv.path2id('path'))
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
630
        self.assertRaises(errors.NoSuchId, res_inv.id2path, b'file-id')
5876.1.1 by John Arbash Meinel
Fix bug #781168, and allow WT.update_basis_by_delta
631
632
    def test_rename_file(self):
633
        inv = self.get_empty_inventory()
5847.4.10 by John Arbash Meinel
A few more bug fixes.
634
        file1 = self.make_file_ie(name='path', parent_id=inv.root.file_id)
5876.1.1 by John Arbash Meinel
Fix bug #781168, and allow WT.update_basis_by_delta
635
        inv.add(file1)
5847.4.10 by John Arbash Meinel
A few more bug fixes.
636
        file2 = self.make_file_ie(name='path2', parent_id=inv.root.file_id)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
637
        delta = [(u'path', 'path2', b'file-id', file2)]
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
638
        res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
6856 by Jelmer Vernooij
Merge lp:~jelmer/brz/is-versioned.
639
        self.assertEqual(None, res_inv.path2id('path'))
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
640
        self.assertEqual(b'file-id', res_inv.path2id('path2'))
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
641
5847.4.10 by John Arbash Meinel
A few more bug fixes.
642
    def test_replaced_at_new_path(self):
643
        inv = self.get_empty_inventory()
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
644
        file1 = self.make_file_ie(file_id=b'id1', parent_id=inv.root.file_id)
5847.4.10 by John Arbash Meinel
A few more bug fixes.
645
        inv.add(file1)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
646
        file2 = self.make_file_ie(file_id=b'id2', parent_id=inv.root.file_id)
647
        delta = [(u'name', None, b'id1', None),
648
                 (None, u'name', b'id2', file2)]
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
649
        res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
650
        self.assertEqual(b'id2', res_inv.path2id('name'))
5847.4.10 by John Arbash Meinel
A few more bug fixes.
651
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
652
    def test_rename_dir(self):
653
        inv = self.get_empty_inventory()
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
654
        dir1 = inventory.InventoryDirectory(b'dir-id', 'dir1', inv.root.file_id)
655
        dir1.revision = b'basis'
656
        file1 = self.make_file_ie(parent_id=b'dir-id')
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
657
        inv.add(dir1)
658
        inv.add(file1)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
659
        dir2 = inventory.InventoryDirectory(b'dir-id', 'dir2', inv.root.file_id)
660
        dir2.revision = b'result'
661
        delta = [('dir1', 'dir2', b'dir-id', dir2)]
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
662
        res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
663
        # The file should be accessible under the new path
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
664
        self.assertEqual(b'file-id', res_inv.path2id('dir2/name'))
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
665
666
    def test_renamed_dir_with_renamed_child(self):
667
        inv = self.get_empty_inventory()
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
668
        dir1 = inventory.InventoryDirectory(b'dir-id', 'dir1', inv.root.file_id)
669
        dir1.revision = b'basis'
670
        file1 = self.make_file_ie(b'file-id-1', 'name1', parent_id=b'dir-id')
671
        file2 = self.make_file_ie(b'file-id-2', 'name2', parent_id=b'dir-id')
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
672
        inv.add(dir1)
673
        inv.add(file1)
674
        inv.add(file2)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
675
        dir2 = inventory.InventoryDirectory(b'dir-id', 'dir2', inv.root.file_id)
676
        dir2.revision = b'result'
677
        file2b = self.make_file_ie(b'file-id-2', 'name2', inv.root.file_id)
678
        delta = [('dir1', 'dir2', b'dir-id', dir2),
679
                 ('dir1/name2', 'name2', b'file-id-2', file2b)]
5847.4.35 by John Arbash Meinel
Rename 'expect_fail' to 'invalid_delta' as suggested by Jelmer
680
        res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
681
        # The file should be accessible under the new path
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
682
        self.assertEqual(b'file-id-1', res_inv.path2id('dir2/name1'))
6856 by Jelmer Vernooij
Merge lp:~jelmer/brz/is-versioned.
683
        self.assertEqual(None, res_inv.path2id('dir2/name2'))
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
684
        self.assertEqual(b'file-id-2', res_inv.path2id('name2'))
5847.4.13 by John Arbash Meinel
Mostly more test cases, some small progress in getting
685
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
686
    def test_is_root(self):
687
        """Ensure our root-checking code is accurate."""
688
        inv = inventory.Inventory('TREE_ROOT')
689
        self.assertTrue(inv.is_root('TREE_ROOT'))
690
        self.assertFalse(inv.is_root('booga'))
691
        inv.root.file_id = 'booga'
692
        self.assertFalse(inv.is_root('TREE_ROOT'))
693
        self.assertTrue(inv.is_root('booga'))
694
        # works properly even if no root is set
695
        inv.root = None
696
        self.assertFalse(inv.is_root('TREE_ROOT'))
697
        self.assertFalse(inv.is_root('booga'))
698
5410.1.2 by Daniel Knittl-Frank
Add a test case for `entries()` on empty inventory
699
    def test_entries_for_empty_inventory(self):
700
        """Test that entries() will not fail for an empty inventory"""
5410.1.3 by Daniel Knittl-Frank
fix whitespace (only use spaces)
701
        inv = Inventory(root_id=None)
702
        self.assertEqual([], inv.entries())
5410.1.2 by Daniel Knittl-Frank
Add a test case for `entries()` on empty inventory
703
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
704
1407 by Robert Collins
define some expected behaviour for inventory_entry.snapshot
705
class TestInventoryEntry(TestCase):
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
706
6478.3.3 by Jelmer Vernooij
Support backslash filenames in Inventory.
707
    def test_file_invalid_entry_name(self):
708
        self.assertRaises(errors.InvalidEntryName, inventory.InventoryFile,
709
            '123', 'a/hello.c', ROOT_ID)
710
711
    def test_file_backslash(self):
712
        file = inventory.InventoryFile('123', 'h\\ello.c', ROOT_ID)
713
        self.assertEquals(file.name, 'h\\ello.c')
714
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
715
    def test_file_kind_character(self):
1399.1.9 by Robert Collins
factor out file related logic from InventoryEntry to InventoryFile
716
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
717
        self.assertEqual(file.kind_character(), '')
718
719
    def test_dir_kind_character(self):
1399.1.8 by Robert Collins
factor out inventory directory logic into 'InventoryDirectory' class
720
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
721
        self.assertEqual(dir.kind_character(), '/')
722
723
    def test_link_kind_character(self):
1399.1.10 by Robert Collins
remove kind from the InventoryEntry constructor - only child classes should be created now
724
        dir = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
725
        self.assertEqual(dir.kind_character(), '')
1399.1.3 by Robert Collins
move change detection for text and metadata from delta to entry.detect_changes
726
727
    def test_dir_detect_changes(self):
1399.1.8 by Robert Collins
factor out inventory directory logic into 'InventoryDirectory' class
728
        left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
729
        right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
1399.1.3 by Robert Collins
move change detection for text and metadata from delta to entry.detect_changes
730
        self.assertEqual((False, False), left.detect_changes(right))
731
        self.assertEqual((False, False), right.detect_changes(left))
732
733
    def test_file_detect_changes(self):
1399.1.9 by Robert Collins
factor out file related logic from InventoryEntry to InventoryFile
734
        left = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
1399.1.3 by Robert Collins
move change detection for text and metadata from delta to entry.detect_changes
735
        left.text_sha1 = 123
1399.1.9 by Robert Collins
factor out file related logic from InventoryEntry to InventoryFile
736
        right = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
1399.1.3 by Robert Collins
move change detection for text and metadata from delta to entry.detect_changes
737
        right.text_sha1 = 123
738
        self.assertEqual((False, False), left.detect_changes(right))
739
        self.assertEqual((False, False), right.detect_changes(left))
740
        left.executable = True
741
        self.assertEqual((False, True), left.detect_changes(right))
742
        self.assertEqual((False, True), right.detect_changes(left))
743
        right.text_sha1 = 321
744
        self.assertEqual((True, True), left.detect_changes(right))
745
        self.assertEqual((True, True), right.detect_changes(left))
746
747
    def test_symlink_detect_changes(self):
1399.1.10 by Robert Collins
remove kind from the InventoryEntry constructor - only child classes should be created now
748
        left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
1399.1.3 by Robert Collins
move change detection for text and metadata from delta to entry.detect_changes
749
        left.symlink_target='foo'
1399.1.10 by Robert Collins
remove kind from the InventoryEntry constructor - only child classes should be created now
750
        right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
1399.1.3 by Robert Collins
move change detection for text and metadata from delta to entry.detect_changes
751
        right.symlink_target='foo'
752
        self.assertEqual((False, False), left.detect_changes(right))
753
        self.assertEqual((False, False), right.detect_changes(left))
754
        left.symlink_target = 'different'
755
        self.assertEqual((True, False), left.detect_changes(right))
756
        self.assertEqual((True, False), right.detect_changes(left))
1399.1.4 by Robert Collins
move diff and symlink conditionals into inventory.py from diff.py
757
1399.1.5 by Robert Collins
move checking whether an entry stores text into inventory.py from fetch,py
758
    def test_file_has_text(self):
1399.1.9 by Robert Collins
factor out file related logic from InventoryEntry to InventoryFile
759
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
760
        self.assertTrue(file.has_text())
1399.1.5 by Robert Collins
move checking whether an entry stores text into inventory.py from fetch,py
761
762
    def test_directory_has_text(self):
1399.1.8 by Robert Collins
factor out inventory directory logic into 'InventoryDirectory' class
763
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
764
        self.assertFalse(dir.has_text())
1399.1.5 by Robert Collins
move checking whether an entry stores text into inventory.py from fetch,py
765
766
    def test_link_has_text(self):
1399.1.10 by Robert Collins
remove kind from the InventoryEntry constructor - only child classes should be created now
767
        link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
768
        self.assertFalse(link.has_text())
1399.1.5 by Robert Collins
move checking whether an entry stores text into inventory.py from fetch,py
769
1713.1.11 by Robert Collins
refactor smart_add to pass around the parent inventory entry and use that, resulting in another 100bzrlib/inventory.py performance improvement, and making inventory writing the dominating factory in add. (Robert Collins)
770
    def test_make_entry(self):
771
        self.assertIsInstance(inventory.make_entry("file", "name", ROOT_ID),
772
            inventory.InventoryFile)
773
        self.assertIsInstance(inventory.make_entry("symlink", "name", ROOT_ID),
774
            inventory.InventoryLink)
775
        self.assertIsInstance(inventory.make_entry("directory", "name", ROOT_ID),
776
            inventory.InventoryDirectory)
1399.1.4 by Robert Collins
move diff and symlink conditionals into inventory.py from diff.py
777
1830.3.5 by John Arbash Meinel
make_entry refuses to create non-normalized entries.
778
    def test_make_entry_non_normalized(self):
779
        orig_normalized_filename = osutils.normalized_filename
780
781
        try:
782
            osutils.normalized_filename = osutils._accessible_normalized_filename
783
            entry = inventory.make_entry("file", u'a\u030a', ROOT_ID)
784
            self.assertEqual(u'\xe5', entry.name)
785
            self.assertIsInstance(entry, inventory.InventoryFile)
786
787
            osutils.normalized_filename = osutils._inaccessible_normalized_filename
788
            self.assertRaises(errors.InvalidNormalization,
789
                    inventory.make_entry, 'file', u'a\u030a', ROOT_ID)
790
        finally:
791
            osutils.normalized_filename = orig_normalized_filename
792
793
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
794
class TestDescribeChanges(TestCase):
795
796
    def test_describe_change(self):
797
        # we need to test the following change combinations:
798
        # rename
799
        # reparent
800
        # modify
801
        # gone
802
        # added
803
        # renamed/reparented and modified
804
        # change kind (perhaps can't be done yet?)
805
        # also, merged in combination with all of these?
806
        old_a = InventoryFile('a-id', 'a_file', ROOT_ID)
807
        old_a.text_sha1 = '123132'
808
        old_a.text_size = 0
809
        new_a = InventoryFile('a-id', 'a_file', ROOT_ID)
810
        new_a.text_sha1 = '123132'
811
        new_a.text_size = 0
812
813
        self.assertChangeDescription('unchanged', old_a, new_a)
814
815
        new_a.text_size = 10
816
        new_a.text_sha1 = 'abcabc'
817
        self.assertChangeDescription('modified', old_a, new_a)
818
819
        self.assertChangeDescription('added', None, new_a)
820
        self.assertChangeDescription('removed', old_a, None)
821
        # perhaps a bit questionable but seems like the most reasonable thing...
822
        self.assertChangeDescription('unchanged', None, None)
823
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
824
        # in this case it's both renamed and modified; show a rename and
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
825
        # modification:
826
        new_a.name = 'newfilename'
827
        self.assertChangeDescription('modified and renamed', old_a, new_a)
828
829
        # reparenting is 'renaming'
830
        new_a.name = old_a.name
831
        new_a.parent_id = 'somedir-id'
832
        self.assertChangeDescription('modified and renamed', old_a, new_a)
833
834
        # reset the content values so its not modified
835
        new_a.text_size = old_a.text_size
836
        new_a.text_sha1 = old_a.text_sha1
837
        new_a.name = old_a.name
838
839
        new_a.name = 'newfilename'
840
        self.assertChangeDescription('renamed', old_a, new_a)
841
842
        # reparenting is 'renaming'
843
        new_a.name = old_a.name
844
        new_a.parent_id = 'somedir-id'
845
        self.assertChangeDescription('renamed', old_a, new_a)
846
847
    def assertChangeDescription(self, expected_change, old_ie, new_ie):
848
        change = InventoryEntry.describe_change(old_ie, new_ie)
849
        self.assertEqual(expected_change, change)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
850
851
4634.51.1 by John Arbash Meinel
Switch away from creating a whole repository just to get a VF.
852
class TestCHKInventory(tests.TestCaseWithMemoryTransport):
3735.2.99 by John Arbash Meinel
Merge bzr.dev 4034. Whitespace cleanup
853
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
854
    def get_chk_bytes(self):
4634.51.1 by John Arbash Meinel
Switch away from creating a whole repository just to get a VF.
855
        factory = groupcompress.make_pack_factory(True, True, 1)
856
        trans = self.get_transport('')
857
        return factory(trans)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
858
859
    def read_bytes(self, chk_bytes, key):
860
        stream = chk_bytes.get_record_stream([key], 'unordered', True)
861
        return stream.next().get_bytes_as("fulltext")
862
863
    def test_deserialise_gives_CHKInventory(self):
864
        inv = Inventory()
865
        inv.revision_id = "revid"
866
        inv.root.revision = "rootrev"
867
        chk_bytes = self.get_chk_bytes()
868
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
869
        bytes = ''.join(chk_inv.to_lines())
870
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
871
        self.assertEqual("revid", new_inv.revision_id)
872
        self.assertEqual("directory", new_inv.root.kind)
873
        self.assertEqual(inv.root.file_id, new_inv.root.file_id)
874
        self.assertEqual(inv.root.parent_id, new_inv.root.parent_id)
875
        self.assertEqual(inv.root.name, new_inv.root.name)
876
        self.assertEqual("rootrev", new_inv.root.revision)
3735.16.7 by John Arbash Meinel
Start parameterizing CHKInventory and CHKSerializer so that we can
877
        self.assertEqual('plain', new_inv._search_key_name)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
878
879
    def test_deserialise_wrong_revid(self):
880
        inv = Inventory()
881
        inv.revision_id = "revid"
882
        inv.root.revision = "rootrev"
883
        chk_bytes = self.get_chk_bytes()
884
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
885
        bytes = ''.join(chk_inv.to_lines())
886
        self.assertRaises(ValueError, CHKInventory.deserialise, chk_bytes,
887
            bytes, ("revid2",))
888
889
    def test_captures_rev_root_byid(self):
890
        inv = Inventory()
891
        inv.revision_id = "foo"
892
        inv.root.revision = "bar"
893
        chk_bytes = self.get_chk_bytes()
894
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
3735.16.7 by John Arbash Meinel
Start parameterizing CHKInventory and CHKSerializer so that we can
895
        lines = chk_inv.to_lines()
896
        self.assertEqual([
897
            'chkinventory:\n',
898
            'revision_id: foo\n',
899
            'root_id: TREE_ROOT\n',
3735.2.132 by John Arbash Meinel
Remove references to parent_id_basename_index, now that we know we want it.
900
            'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
3735.17.11 by John Arbash Meinel
Actually format the inventories using line-based separation.
901
            'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
3735.16.7 by John Arbash Meinel
Start parameterizing CHKInventory and CHKSerializer so that we can
902
            ], lines)
903
        chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
904
        self.assertEqual('plain', chk_inv._search_key_name)
905
906
    def test_captures_parent_id_basename_index(self):
907
        inv = Inventory()
908
        inv.revision_id = "foo"
909
        inv.root.revision = "bar"
910
        chk_bytes = self.get_chk_bytes()
3735.2.132 by John Arbash Meinel
Remove references to parent_id_basename_index, now that we know we want it.
911
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
3735.16.7 by John Arbash Meinel
Start parameterizing CHKInventory and CHKSerializer so that we can
912
        lines = chk_inv.to_lines()
913
        self.assertEqual([
914
            'chkinventory:\n',
915
            'revision_id: foo\n',
916
            'root_id: TREE_ROOT\n',
3735.17.8 by John Arbash Meinel
Most direct tests are now passing.
917
            'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
3735.17.11 by John Arbash Meinel
Actually format the inventories using line-based separation.
918
            'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
3735.16.7 by John Arbash Meinel
Start parameterizing CHKInventory and CHKSerializer so that we can
919
            ], lines)
920
        chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
921
        self.assertEqual('plain', chk_inv._search_key_name)
922
923
    def test_captures_search_key_name(self):
924
        inv = Inventory()
925
        inv.revision_id = "foo"
926
        inv.root.revision = "bar"
927
        chk_bytes = self.get_chk_bytes()
928
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv,
929
                                              search_key_name='hash-16-way')
930
        lines = chk_inv.to_lines()
931
        self.assertEqual([
932
            'chkinventory:\n',
933
            'search_key_name: hash-16-way\n',
3735.24.2 by John Arbash Meinel
Add a bit more strictness to the formatting, update the test case.
934
            'root_id: TREE_ROOT\n',
3735.17.8 by John Arbash Meinel
Most direct tests are now passing.
935
            'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
3735.24.2 by John Arbash Meinel
Add a bit more strictness to the formatting, update the test case.
936
            'revision_id: foo\n',
3735.17.11 by John Arbash Meinel
Actually format the inventories using line-based separation.
937
            'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
3735.16.7 by John Arbash Meinel
Start parameterizing CHKInventory and CHKSerializer so that we can
938
            ], lines)
939
        chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
940
        self.assertEqual('hash-16-way', chk_inv._search_key_name)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
941
942
    def test_directory_children_on_demand(self):
943
        inv = Inventory()
944
        inv.revision_id = "revid"
945
        inv.root.revision = "rootrev"
946
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
947
        inv.get_entry("fileid").revision = "filerev"
948
        inv.get_entry("fileid").executable = True
949
        inv.get_entry("fileid").text_sha1 = "ffff"
950
        inv.get_entry("fileid").text_size = 1
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
951
        chk_bytes = self.get_chk_bytes()
952
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
953
        bytes = ''.join(chk_inv.to_lines())
954
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
955
        root_entry = new_inv.get_entry(inv.root.file_id)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
956
        self.assertEqual(None, root_entry._children)
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
957
        self.assertEqual({'file'}, set(root_entry.children))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
958
        file_direct = new_inv.get_entry("fileid")
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
959
        file_found = root_entry.children['file']
960
        self.assertEqual(file_direct.kind, file_found.kind)
961
        self.assertEqual(file_direct.file_id, file_found.file_id)
962
        self.assertEqual(file_direct.parent_id, file_found.parent_id)
963
        self.assertEqual(file_direct.name, file_found.name)
964
        self.assertEqual(file_direct.revision, file_found.revision)
965
        self.assertEqual(file_direct.text_sha1, file_found.text_sha1)
966
        self.assertEqual(file_direct.text_size, file_found.text_size)
967
        self.assertEqual(file_direct.executable, file_found.executable)
968
3735.2.27 by Robert Collins
Use 4K pages for development3 repositories.
969
    def test_from_inventory_maximum_size(self):
970
        # from_inventory supports the maximum_size parameter.
971
        inv = Inventory()
972
        inv.revision_id = "revid"
973
        inv.root.revision = "rootrev"
974
        chk_bytes = self.get_chk_bytes()
975
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv, 120)
4413.5.10 by John Arbash Meinel
Clean upt the test_inv tests that assumed _root_node was real and not just a key.
976
        chk_inv.id_to_entry._ensure_root()
3735.2.27 by Robert Collins
Use 4K pages for development3 repositories.
977
        self.assertEqual(120, chk_inv.id_to_entry._root_node.maximum_size)
4413.5.10 by John Arbash Meinel
Clean upt the test_inv tests that assumed _root_node was real and not just a key.
978
        self.assertEqual(1, chk_inv.id_to_entry._root_node._key_width)
979
        p_id_basename = chk_inv.parent_id_basename_to_file_id
980
        p_id_basename._ensure_root()
981
        self.assertEqual(120, p_id_basename._root_node.maximum_size)
982
        self.assertEqual(2, p_id_basename._root_node._key_width)
3735.2.27 by Robert Collins
Use 4K pages for development3 repositories.
983
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
984
    def test_iter_all_ids(self):
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
985
        inv = Inventory()
986
        inv.revision_id = "revid"
987
        inv.root.revision = "rootrev"
988
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
989
        inv.get_entry("fileid").revision = "filerev"
990
        inv.get_entry("fileid").executable = True
991
        inv.get_entry("fileid").text_sha1 = "ffff"
992
        inv.get_entry("fileid").text_size = 1
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
993
        chk_bytes = self.get_chk_bytes()
994
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
995
        bytes = ''.join(chk_inv.to_lines())
996
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
997
        fileids = sorted(new_inv.iter_all_ids())
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
998
        self.assertEqual([inv.root.file_id, "fileid"], fileids)
999
1000
    def test__len__(self):
1001
        inv = Inventory()
1002
        inv.revision_id = "revid"
1003
        inv.root.revision = "rootrev"
1004
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1005
        inv.get_entry("fileid").revision = "filerev"
1006
        inv.get_entry("fileid").executable = True
1007
        inv.get_entry("fileid").text_sha1 = "ffff"
1008
        inv.get_entry("fileid").text_size = 1
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1009
        chk_bytes = self.get_chk_bytes()
1010
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1011
        self.assertEqual(2, len(chk_inv))
1012
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1013
    def test_get_entry(self):
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1014
        inv = Inventory()
6684.1.4 by Martin
Start making inventory tests pass on Python 3
1015
        inv.revision_id = b"revid"
1016
        inv.root.revision = b"rootrev"
1017
        inv.add(InventoryFile(b"fileid", u"file", inv.root.file_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1018
        inv.get_entry(b"fileid").revision = b"filerev"
1019
        inv.get_entry(b"fileid").executable = True
1020
        inv.get_entry(b"fileid").text_sha1 = b"ffff"
1021
        inv.get_entry(b"fileid").text_size = 1
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1022
        chk_bytes = self.get_chk_bytes()
1023
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
6684.1.4 by Martin
Start making inventory tests pass on Python 3
1024
        data = b''.join(chk_inv.to_lines())
1025
        new_inv = CHKInventory.deserialise(chk_bytes, data, (b"revid",))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1026
        root_entry = new_inv.get_entry(inv.root.file_id)
1027
        file_entry = new_inv.get_entry(b"fileid")
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1028
        self.assertEqual("directory", root_entry.kind)
1029
        self.assertEqual(inv.root.file_id, root_entry.file_id)
1030
        self.assertEqual(inv.root.parent_id, root_entry.parent_id)
1031
        self.assertEqual(inv.root.name, root_entry.name)
6684.1.4 by Martin
Start making inventory tests pass on Python 3
1032
        self.assertEqual(b"rootrev", root_entry.revision)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1033
        self.assertEqual("file", file_entry.kind)
6684.1.4 by Martin
Start making inventory tests pass on Python 3
1034
        self.assertEqual(b"fileid", file_entry.file_id)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1035
        self.assertEqual(inv.root.file_id, file_entry.parent_id)
6684.1.4 by Martin
Start making inventory tests pass on Python 3
1036
        self.assertEqual(u"file", file_entry.name)
1037
        self.assertEqual(b"filerev", file_entry.revision)
1038
        self.assertEqual(b"ffff", file_entry.text_sha1)
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1039
        self.assertEqual(1, file_entry.text_size)
1040
        self.assertEqual(True, file_entry.executable)
6915.4.4 by Jelmer Vernooij
Fix test.
1041
        self.assertRaises(errors.NoSuchId, new_inv.get_entry, 'missing')
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1042
1043
    def test_has_id_true(self):
1044
        inv = Inventory()
6855.4.1 by Jelmer Vernooij
Yet more bees.
1045
        inv.revision_id = b"revid"
1046
        inv.root.revision = b"rootrev"
1047
        inv.add(InventoryFile(b"fileid", "file", inv.root.file_id))
6855.4.10 by Jelmer Vernooij
merge trunk
1048
        inv.get_entry(b"fileid").revision = b"filerev"
1049
        inv.get_entry(b"fileid").executable = True
1050
        inv.get_entry(b"fileid").text_sha1 = "ffff"
1051
        inv.get_entry(b"fileid").text_size = 1
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1052
        chk_bytes = self.get_chk_bytes()
1053
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1054
        self.assertTrue(chk_inv.has_id(b'fileid'))
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1055
        self.assertTrue(chk_inv.has_id(inv.root.file_id))
1056
1057
    def test_has_id_not(self):
1058
        inv = Inventory()
6855.4.1 by Jelmer Vernooij
Yet more bees.
1059
        inv.revision_id = b"revid"
1060
        inv.root.revision = b"rootrev"
3735.2.9 by Robert Collins
Get a working chk_map using inventory implementation bootstrapped.
1061
        chk_bytes = self.get_chk_bytes()
1062
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1063
        self.assertFalse(chk_inv.has_id(b'fileid'))
3735.2.10 by Robert Collins
Teach CHKInventory how to make a new inventory from an inventory delta.
1064
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1065
    def test_id2path(self):
1066
        inv = Inventory()
6855.4.1 by Jelmer Vernooij
Yet more bees.
1067
        inv.revision_id = b"revid"
1068
        inv.root.revision = b"rootrev"
1069
        direntry = InventoryDirectory(b"dirid", "dir", inv.root.file_id)
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1070
        fileentry = InventoryFile("fileid", "file", "dirid")
1071
        inv.add(direntry)
1072
        inv.add(fileentry)
6855.4.10 by Jelmer Vernooij
merge trunk
1073
        inv.get_entry(b"fileid").revision = b"filerev"
1074
        inv.get_entry(b"fileid").executable = True
1075
        inv.get_entry(b"fileid").text_sha1 = "ffff"
1076
        inv.get_entry(b"fileid").text_size = 1
1077
        inv.get_entry(b"dirid").revision = b"filerev"
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1078
        chk_bytes = self.get_chk_bytes()
1079
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1080
        bytes = ''.join(chk_inv.to_lines())
6855.4.1 by Jelmer Vernooij
Yet more bees.
1081
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, (b"revid",))
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1082
        self.assertEqual('', new_inv.id2path(inv.root.file_id))
6855.4.1 by Jelmer Vernooij
Yet more bees.
1083
        self.assertEqual('dir', new_inv.id2path(b'dirid'))
1084
        self.assertEqual('dir/file', new_inv.id2path(b'fileid'))
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1085
1086
    def test_path2id(self):
1087
        inv = Inventory()
6855.4.10 by Jelmer Vernooij
merge trunk
1088
        inv.revision_id = b"revid"
1089
        inv.root.revision = b"rootrev"
1090
        direntry = InventoryDirectory(b"dirid", "dir", inv.root.file_id)
1091
        fileentry = InventoryFile(b"fileid", "file", b"dirid")
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1092
        inv.add(direntry)
1093
        inv.add(fileentry)
6855.4.10 by Jelmer Vernooij
merge trunk
1094
        inv.get_entry(b"fileid").revision = b"filerev"
1095
        inv.get_entry(b"fileid").executable = True
1096
        inv.get_entry(b"fileid").text_sha1 = "ffff"
1097
        inv.get_entry(b"fileid").text_size = 1
1098
        inv.get_entry(b"dirid").revision = b"filerev"
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1099
        chk_bytes = self.get_chk_bytes()
1100
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1101
        bytes = ''.join(chk_inv.to_lines())
6855.4.10 by Jelmer Vernooij
merge trunk
1102
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, (b"revid",))
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1103
        self.assertEqual(inv.root.file_id, new_inv.path2id(''))
6855.4.10 by Jelmer Vernooij
merge trunk
1104
        self.assertEqual(b'dirid', new_inv.path2id('dir'))
1105
        self.assertEqual(b'fileid', new_inv.path2id('dir/file'))
3735.2.12 by Robert Collins
Implement commit-via-deltas for split inventory repositories.
1106
3735.2.57 by Jelmer Vernooij
Make sure CHKInventory._entry_cache gets initialized in create_by_apply_delta.
1107
    def test_create_by_apply_delta_sets_root(self):
1108
        inv = Inventory()
1109
        inv.revision_id = "revid"
1110
        chk_bytes = self.get_chk_bytes()
1111
        base_inv = CHKInventory.from_inventory(chk_bytes, inv)
1112
        inv.add_path("", "directory", "myrootid", None)
1113
        inv.revision_id = "expectedid"
1114
        reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
4526.9.15 by Robert Collins
Fix broken CHK inventory test that was applying an inconsistend delta.
1115
        delta = [("", None, base_inv.root.file_id, None),
1116
            (None, "",  "myrootid", inv.root)]
3735.2.57 by Jelmer Vernooij
Make sure CHKInventory._entry_cache gets initialized in create_by_apply_delta.
1117
        new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1118
        self.assertEqual(reference_inv.root, new_inv.root)
3735.2.57 by Jelmer Vernooij
Make sure CHKInventory._entry_cache gets initialized in create_by_apply_delta.
1119
3735.2.10 by Robert Collins
Teach CHKInventory how to make a new inventory from an inventory delta.
1120
    def test_create_by_apply_delta_empty_add_child(self):
1121
        inv = Inventory()
1122
        inv.revision_id = "revid"
1123
        inv.root.revision = "rootrev"
1124
        chk_bytes = self.get_chk_bytes()
1125
        base_inv = CHKInventory.from_inventory(chk_bytes, inv)
1126
        a_entry = InventoryFile("A-id", "A", inv.root.file_id)
1127
        a_entry.revision = "filerev"
1128
        a_entry.executable = True
1129
        a_entry.text_sha1 = "ffff"
1130
        a_entry.text_size = 1
1131
        inv.add(a_entry)
1132
        inv.revision_id = "expectedid"
1133
        reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
1134
        delta = [(None, "A",  "A-id", a_entry)]
1135
        new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
1136
        # new_inv should be the same as reference_inv.
1137
        self.assertEqual(reference_inv.revision_id, new_inv.revision_id)
1138
        self.assertEqual(reference_inv.root_id, new_inv.root_id)
4413.5.10 by John Arbash Meinel
Clean upt the test_inv tests that assumed _root_node was real and not just a key.
1139
        reference_inv.id_to_entry._ensure_root()
1140
        new_inv.id_to_entry._ensure_root()
3735.2.10 by Robert Collins
Teach CHKInventory how to make a new inventory from an inventory delta.
1141
        self.assertEqual(reference_inv.id_to_entry._root_node._key,
1142
            new_inv.id_to_entry._root_node._key)
3735.2.33 by Robert Collins
Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.
1143
3735.2.41 by Robert Collins
Make the parent_id_basename index be updated during CHKInventory.apply_delta.
1144
    def test_create_by_apply_delta_empty_add_child_updates_parent_id(self):
1145
        inv = Inventory()
1146
        inv.revision_id = "revid"
1147
        inv.root.revision = "rootrev"
1148
        chk_bytes = self.get_chk_bytes()
3735.2.132 by John Arbash Meinel
Remove references to parent_id_basename_index, now that we know we want it.
1149
        base_inv = CHKInventory.from_inventory(chk_bytes, inv)
3735.2.41 by Robert Collins
Make the parent_id_basename index be updated during CHKInventory.apply_delta.
1150
        a_entry = InventoryFile("A-id", "A", inv.root.file_id)
1151
        a_entry.revision = "filerev"
1152
        a_entry.executable = True
1153
        a_entry.text_sha1 = "ffff"
1154
        a_entry.text_size = 1
1155
        inv.add(a_entry)
1156
        inv.revision_id = "expectedid"
3735.2.132 by John Arbash Meinel
Remove references to parent_id_basename_index, now that we know we want it.
1157
        reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
3735.2.41 by Robert Collins
Make the parent_id_basename index be updated during CHKInventory.apply_delta.
1158
        delta = [(None, "A",  "A-id", a_entry)]
1159
        new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
4413.5.10 by John Arbash Meinel
Clean upt the test_inv tests that assumed _root_node was real and not just a key.
1160
        reference_inv.id_to_entry._ensure_root()
1161
        reference_inv.parent_id_basename_to_file_id._ensure_root()
1162
        new_inv.id_to_entry._ensure_root()
1163
        new_inv.parent_id_basename_to_file_id._ensure_root()
3735.2.41 by Robert Collins
Make the parent_id_basename index be updated during CHKInventory.apply_delta.
1164
        # new_inv should be the same as reference_inv.
1165
        self.assertEqual(reference_inv.revision_id, new_inv.revision_id)
1166
        self.assertEqual(reference_inv.root_id, new_inv.root_id)
1167
        self.assertEqual(reference_inv.id_to_entry._root_node._key,
1168
            new_inv.id_to_entry._root_node._key)
1169
        self.assertEqual(reference_inv.parent_id_basename_to_file_id._root_node._key,
1170
            new_inv.parent_id_basename_to_file_id._root_node._key)
1171
3735.2.33 by Robert Collins
Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.
1172
    def test_iter_changes(self):
1173
        # Low level bootstrapping smoke test; comprehensive generic tests via
1174
        # InterTree are coming.
1175
        inv = Inventory()
1176
        inv.revision_id = "revid"
1177
        inv.root.revision = "rootrev"
1178
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1179
        inv.get_entry("fileid").revision = "filerev"
1180
        inv.get_entry("fileid").executable = True
1181
        inv.get_entry("fileid").text_sha1 = "ffff"
1182
        inv.get_entry("fileid").text_size = 1
3735.2.33 by Robert Collins
Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.
1183
        inv2 = Inventory()
1184
        inv2.revision_id = "revid2"
1185
        inv2.root.revision = "rootrev"
1186
        inv2.add(InventoryFile("fileid", "file", inv.root.file_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1187
        inv2.get_entry("fileid").revision = "filerev2"
1188
        inv2.get_entry("fileid").executable = False
1189
        inv2.get_entry("fileid").text_sha1 = "bbbb"
1190
        inv2.get_entry("fileid").text_size = 2
3735.2.33 by Robert Collins
Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.
1191
        # get fresh objects.
1192
        chk_bytes = self.get_chk_bytes()
1193
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1194
        bytes = ''.join(chk_inv.to_lines())
1195
        inv_1 = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1196
        chk_inv2 = CHKInventory.from_inventory(chk_bytes, inv2)
1197
        bytes = ''.join(chk_inv2.to_lines())
1198
        inv_2 = CHKInventory.deserialise(chk_bytes, bytes, ("revid2",))
1199
        self.assertEqual([('fileid', (u'file', u'file'), True, (True, True),
1200
            ('TREE_ROOT', 'TREE_ROOT'), (u'file', u'file'), ('file', 'file'),
1201
            (False, True))],
1202
            list(inv_1.iter_changes(inv_2)))
3735.2.40 by Robert Collins
Add development4 which has a parent_id to basename index on CHKInventory objects.
1203
3735.2.41 by Robert Collins
Make the parent_id_basename index be updated during CHKInventory.apply_delta.
1204
    def test_parent_id_basename_to_file_id_index_enabled(self):
3735.2.40 by Robert Collins
Add development4 which has a parent_id to basename index on CHKInventory objects.
1205
        inv = Inventory()
1206
        inv.revision_id = "revid"
1207
        inv.root.revision = "rootrev"
1208
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1209
        inv.get_entry("fileid").revision = "filerev"
1210
        inv.get_entry("fileid").executable = True
1211
        inv.get_entry("fileid").text_sha1 = "ffff"
1212
        inv.get_entry("fileid").text_size = 1
3735.2.40 by Robert Collins
Add development4 which has a parent_id to basename index on CHKInventory objects.
1213
        # get fresh objects.
1214
        chk_bytes = self.get_chk_bytes()
3735.2.132 by John Arbash Meinel
Remove references to parent_id_basename_index, now that we know we want it.
1215
        tmp_inv = CHKInventory.from_inventory(chk_bytes, inv)
3735.2.40 by Robert Collins
Add development4 which has a parent_id to basename index on CHKInventory objects.
1216
        bytes = ''.join(tmp_inv.to_lines())
1217
        chk_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
3735.2.41 by Robert Collins
Make the parent_id_basename index be updated during CHKInventory.apply_delta.
1218
        self.assertIsInstance(chk_inv.parent_id_basename_to_file_id, chk_map.CHKMap)
3735.2.40 by Robert Collins
Add development4 which has a parent_id to basename index on CHKInventory objects.
1219
        self.assertEqual(
1220
            {('', ''): 'TREE_ROOT', ('TREE_ROOT', 'file'): 'fileid'},
3735.2.41 by Robert Collins
Make the parent_id_basename index be updated during CHKInventory.apply_delta.
1221
            dict(chk_inv.parent_id_basename_to_file_id.iteritems()))
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1222
1223
    def test_file_entry_to_bytes(self):
1224
        inv = CHKInventory(None)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1225
        ie = inventory.InventoryFile(b'file-id', 'filename', 'parent-id')
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1226
        ie.executable = True
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1227
        ie.revision = b'file-rev-id'
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1228
        ie.text_sha1 = 'abcdefgh'
1229
        ie.text_size = 100
1230
        bytes = inv._entry_to_bytes(ie)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1231
        self.assertEqual(b'file: file-id\nparent-id\nfilename\n'
1232
                         b'file-rev-id\nabcdefgh\n100\nY', bytes)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1233
        ie2 = inv._bytes_to_entry(bytes)
1234
        self.assertEqual(ie, ie2)
6973.6.2 by Jelmer Vernooij
Fix more tests.
1235
        self.assertIsInstance(ie2.name, text_type)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1236
        self.assertEqual(('filename', b'file-id', b'file-rev-id'),
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1237
                         inv._bytes_to_utf8name_key(bytes))
1238
1239
    def test_file2_entry_to_bytes(self):
1240
        inv = CHKInventory(None)
1241
        # \u30a9 == 'omega'
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1242
        ie = inventory.InventoryFile(b'file-id', u'\u03a9name', b'parent-id')
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1243
        ie.executable = False
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1244
        ie.revision = b'file-rev-id'
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1245
        ie.text_sha1 = '123456'
1246
        ie.text_size = 25
1247
        bytes = inv._entry_to_bytes(ie)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1248
        self.assertEqual(b'file: file-id\nparent-id\n\xce\xa9name\n'
1249
                         b'file-rev-id\n123456\n25\nN', bytes)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1250
        ie2 = inv._bytes_to_entry(bytes)
1251
        self.assertEqual(ie, ie2)
6973.6.2 by Jelmer Vernooij
Fix more tests.
1252
        self.assertIsInstance(ie2.name, text_type)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1253
        self.assertEqual((b'\xce\xa9name', b'file-id', b'file-rev-id'),
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1254
                         inv._bytes_to_utf8name_key(bytes))
1255
1256
    def test_dir_entry_to_bytes(self):
1257
        inv = CHKInventory(None)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1258
        ie = inventory.InventoryDirectory(b'dir-id', 'dirname', b'parent-id')
1259
        ie.revision = b'dir-rev-id'
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1260
        bytes = inv._entry_to_bytes(ie)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1261
        self.assertEqual(b'dir: dir-id\nparent-id\ndirname\ndir-rev-id', bytes)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1262
        ie2 = inv._bytes_to_entry(bytes)
1263
        self.assertEqual(ie, ie2)
6973.6.2 by Jelmer Vernooij
Fix more tests.
1264
        self.assertIsInstance(ie2.name, text_type)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1265
        self.assertEqual(('dirname', b'dir-id', b'dir-rev-id'),
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1266
                         inv._bytes_to_utf8name_key(bytes))
1267
1268
    def test_dir2_entry_to_bytes(self):
1269
        inv = CHKInventory(None)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1270
        ie = inventory.InventoryDirectory(b'dir-id', u'dir\u03a9name',
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1271
                                          None)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1272
        ie.revision = b'dir-rev-id'
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1273
        bytes = inv._entry_to_bytes(ie)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1274
        self.assertEqual(b'dir: dir-id\n\ndir\xce\xa9name\n'
1275
                         b'dir-rev-id', bytes)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1276
        ie2 = inv._bytes_to_entry(bytes)
1277
        self.assertEqual(ie, ie2)
6973.6.2 by Jelmer Vernooij
Fix more tests.
1278
        self.assertIsInstance(ie2.name, text_type)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1279
        self.assertIs(ie2.parent_id, None)
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1280
        self.assertEqual(('dir\xce\xa9name', b'dir-id', b'dir-rev-id'),
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1281
                         inv._bytes_to_utf8name_key(bytes))
1282
1283
    def test_symlink_entry_to_bytes(self):
1284
        inv = CHKInventory(None)
1285
        ie = inventory.InventoryLink('link-id', 'linkname', 'parent-id')
1286
        ie.revision = 'link-rev-id'
1287
        ie.symlink_target = u'target/path'
1288
        bytes = inv._entry_to_bytes(ie)
1289
        self.assertEqual('symlink: link-id\nparent-id\nlinkname\n'
1290
                         'link-rev-id\ntarget/path', bytes)
1291
        ie2 = inv._bytes_to_entry(bytes)
1292
        self.assertEqual(ie, ie2)
6973.6.2 by Jelmer Vernooij
Fix more tests.
1293
        self.assertIsInstance(ie2.name, text_type)
1294
        self.assertIsInstance(ie2.symlink_target, text_type)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1295
        self.assertEqual(('linkname', 'link-id', 'link-rev-id'),
1296
                         inv._bytes_to_utf8name_key(bytes))
1297
1298
    def test_symlink2_entry_to_bytes(self):
1299
        inv = CHKInventory(None)
1300
        ie = inventory.InventoryLink('link-id', u'link\u03a9name', 'parent-id')
1301
        ie.revision = 'link-rev-id'
1302
        ie.symlink_target = u'target/\u03a9path'
1303
        bytes = inv._entry_to_bytes(ie)
1304
        self.assertEqual('symlink: link-id\nparent-id\nlink\xce\xa9name\n'
1305
                         'link-rev-id\ntarget/\xce\xa9path', bytes)
1306
        ie2 = inv._bytes_to_entry(bytes)
1307
        self.assertEqual(ie, ie2)
6973.6.2 by Jelmer Vernooij
Fix more tests.
1308
        self.assertIsInstance(ie2.name, text_type)
1309
        self.assertIsInstance(ie2.symlink_target, text_type)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1310
        self.assertEqual(('link\xce\xa9name', 'link-id', 'link-rev-id'),
1311
                         inv._bytes_to_utf8name_key(bytes))
1312
1313
    def test_tree_reference_entry_to_bytes(self):
1314
        inv = CHKInventory(None)
1315
        ie = inventory.TreeReference('tree-root-id', u'tree\u03a9name',
1316
                                     'parent-id')
1317
        ie.revision = 'tree-rev-id'
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
1318
        ie.reference_revision = b'ref-rev-id'
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1319
        bytes = inv._entry_to_bytes(ie)
1320
        self.assertEqual('tree: tree-root-id\nparent-id\ntree\xce\xa9name\n'
1321
                         'tree-rev-id\nref-rev-id', bytes)
1322
        ie2 = inv._bytes_to_entry(bytes)
1323
        self.assertEqual(ie, ie2)
6973.6.2 by Jelmer Vernooij
Fix more tests.
1324
        self.assertIsInstance(ie2.name, text_type)
3735.36.12 by John Arbash Meinel
Add some direct tests for CHKInventory._entry_to_bytes
1325
        self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
1326
                         inv._bytes_to_utf8name_key(bytes))
5726.2.3 by John Arbash Meinel
Properly decode basename. In the map it is always stored as UTF-8, but
1327
5726.2.4 by John Arbash Meinel
_preload should also handle when some entries have already been expanded.
1328
    def make_basic_utf8_inventory(self):
5726.2.3 by John Arbash Meinel
Properly decode basename. In the map it is always stored as UTF-8, but
1329
        inv = Inventory()
1330
        inv.revision_id = "revid"
1331
        inv.root.revision = "rootrev"
1332
        root_id = inv.root.file_id
1333
        inv.add(InventoryFile("fileid", u'f\xefle', root_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1334
        inv.get_entry("fileid").revision = "filerev"
1335
        inv.get_entry("fileid").text_sha1 = "ffff"
1336
        inv.get_entry("fileid").text_size = 0
5726.2.3 by John Arbash Meinel
Properly decode basename. In the map it is always stored as UTF-8, but
1337
        inv.add(InventoryDirectory("dirid", u'dir-\N{EURO SIGN}', root_id))
1338
        inv.add(InventoryFile("childid", u'ch\xefld', "dirid"))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1339
        inv.get_entry("childid").revision = "filerev"
1340
        inv.get_entry("childid").text_sha1 = "ffff"
1341
        inv.get_entry("childid").text_size = 0
5726.2.3 by John Arbash Meinel
Properly decode basename. In the map it is always stored as UTF-8, but
1342
        chk_bytes = self.get_chk_bytes()
1343
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1344
        bytes = ''.join(chk_inv.to_lines())
5726.2.4 by John Arbash Meinel
_preload should also handle when some entries have already been expanded.
1345
        return CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1346
1347
    def test__preload_handles_utf8(self):
1348
        new_inv = self.make_basic_utf8_inventory()
5726.2.3 by John Arbash Meinel
Properly decode basename. In the map it is always stored as UTF-8, but
1349
        self.assertEqual({}, new_inv._fileid_to_entry_cache)
1350
        self.assertFalse(new_inv._fully_cached)
1351
        new_inv._preload_cache()
1352
        self.assertEqual(
5726.2.4 by John Arbash Meinel
_preload should also handle when some entries have already been expanded.
1353
            sorted([new_inv.root_id, "fileid", "dirid", "childid"]),
5726.2.3 by John Arbash Meinel
Properly decode basename. In the map it is always stored as UTF-8, but
1354
            sorted(new_inv._fileid_to_entry_cache.keys()))
5726.2.4 by John Arbash Meinel
_preload should also handle when some entries have already been expanded.
1355
        ie_root = new_inv._fileid_to_entry_cache[new_inv.root_id]
5726.2.3 by John Arbash Meinel
Properly decode basename. In the map it is always stored as UTF-8, but
1356
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1357
                         sorted(ie_root._children.keys()))
1358
        ie_dir = new_inv._fileid_to_entry_cache['dirid']
1359
        self.assertEqual([u'ch\xefld'], sorted(ie_dir._children.keys()))
1360
5726.2.1 by John Arbash Meinel
Fix bug #737234. Preload all entries for iter_entries_by_dir().
1361
    def test__preload_populates_cache(self):
1362
        inv = Inventory()
1363
        inv.revision_id = "revid"
1364
        inv.root.revision = "rootrev"
1365
        root_id = inv.root.file_id
1366
        inv.add(InventoryFile("fileid", "file", root_id))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1367
        inv.get_entry("fileid").revision = "filerev"
1368
        inv.get_entry("fileid").executable = True
1369
        inv.get_entry("fileid").text_sha1 = "ffff"
1370
        inv.get_entry("fileid").text_size = 1
5726.2.1 by John Arbash Meinel
Fix bug #737234. Preload all entries for iter_entries_by_dir().
1371
        inv.add(InventoryDirectory("dirid", "dir", root_id))
1372
        inv.add(InventoryFile("childid", "child", "dirid"))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1373
        inv.get_entry("childid").revision = "filerev"
1374
        inv.get_entry("childid").executable = False
1375
        inv.get_entry("childid").text_sha1 = "dddd"
1376
        inv.get_entry("childid").text_size = 1
5726.2.1 by John Arbash Meinel
Fix bug #737234. Preload all entries for iter_entries_by_dir().
1377
        chk_bytes = self.get_chk_bytes()
1378
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1379
        bytes = ''.join(chk_inv.to_lines())
1380
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1381
        self.assertEqual({}, new_inv._fileid_to_entry_cache)
1382
        self.assertFalse(new_inv._fully_cached)
1383
        new_inv._preload_cache()
1384
        self.assertEqual(
1385
            sorted([root_id, "fileid", "dirid", "childid"]),
1386
            sorted(new_inv._fileid_to_entry_cache.keys()))
1387
        self.assertTrue(new_inv._fully_cached)
1388
        ie_root = new_inv._fileid_to_entry_cache[root_id]
1389
        self.assertEqual(['dir', 'file'], sorted(ie_root._children.keys()))
1390
        ie_dir = new_inv._fileid_to_entry_cache['dirid']
1391
        self.assertEqual(['child'], sorted(ie_dir._children.keys()))
5609.27.1 by John Arbash Meinel
Backport the fix for bug #737234 to the 2.3 series.
1392
5726.2.4 by John Arbash Meinel
_preload should also handle when some entries have already been expanded.
1393
    def test__preload_handles_partially_evaluated_inventory(self):
1394
        new_inv = self.make_basic_utf8_inventory()
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1395
        ie = new_inv.get_entry(new_inv.root_id)
5726.2.4 by John Arbash Meinel
_preload should also handle when some entries have already been expanded.
1396
        self.assertIs(None, ie._children)
1397
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1398
                         sorted(ie.children.keys()))
1399
        # Accessing .children loads _children
1400
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1401
                         sorted(ie._children.keys()))
1402
        new_inv._preload_cache()
1403
        # No change
1404
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1405
                         sorted(ie._children.keys()))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1406
        ie_dir = new_inv.get_entry("dirid")
5726.2.4 by John Arbash Meinel
_preload should also handle when some entries have already been expanded.
1407
        self.assertEqual([u'ch\xefld'],
1408
                         sorted(ie_dir._children.keys()))
1409
6024.2.1 by Bastian Bowe
Test to prove error in CHKInventory.filter method
1410
    def test_filter_change_in_renamed_subfolder(self):
1411
        inv = Inventory('tree-root')
1412
        src_ie = inv.add_path('src', 'directory', 'src-id')
1413
        inv.add_path('src/sub/', 'directory', 'sub-id')
1414
        a_ie = inv.add_path('src/sub/a', 'file', 'a-id')
1415
        a_ie.text_sha1 = osutils.sha_string('content\n')
1416
        a_ie.text_size = len('content\n')
1417
        chk_bytes = self.get_chk_bytes()
1418
        inv = CHKInventory.from_inventory(chk_bytes, inv)
1419
        inv = inv.create_by_apply_delta([
1420
            ("src/sub/a", "src/sub/a", "a-id", a_ie),
1421
            ("src", "src2", "src-id", src_ie),
1422
            ], 'new-rev-2')
1423
        new_inv = inv.filter(['a-id', 'src-id'])
1424
        self.assertEqual([
1425
            ('', 'tree-root'),
1426
            ('src', 'src-id'),
1427
            ('src/sub', 'sub-id'),
1428
            ('src/sub/a', 'a-id'),
1429
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
4634.51.2 by John Arbash Meinel
Start laying the groundwork for testing the expansion code
1430
1431
class TestCHKInventoryExpand(tests.TestCaseWithMemoryTransport):
1432
1433
    def get_chk_bytes(self):
1434
        factory = groupcompress.make_pack_factory(True, True, 1)
1435
        trans = self.get_transport('')
1436
        return factory(trans)
1437
1438
    def make_dir(self, inv, name, parent_id):
6855.4.1 by Jelmer Vernooij
Yet more bees.
1439
        inv.add(inv.make_entry('directory', name, parent_id, name.encode('utf-8') + b'-id'))
4634.51.2 by John Arbash Meinel
Start laying the groundwork for testing the expansion code
1440
1441
    def make_file(self, inv, name, parent_id, content='content\n'):
4634.51.3 by John Arbash Meinel
We have iteration to parents working, need to find children now.
1442
        ie = inv.make_entry('file', name, parent_id, name + '-id')
4634.51.2 by John Arbash Meinel
Start laying the groundwork for testing the expansion code
1443
        ie.text_sha1 = osutils.sha_string(content)
1444
        ie.text_size = len(content)
1445
        inv.add(ie)
1446
1447
    def make_simple_inventory(self):
1448
        inv = Inventory('TREE_ROOT')
1449
        inv.revision_id = "revid"
1450
        inv.root.revision = "rootrev"
1451
        # /                 TREE_ROOT
1452
        # dir1/             dir1-id
1453
        #   sub-file1       sub-file1-id
1454
        #   sub-file2       sub-file2-id
1455
        #   sub-dir1/       sub-dir1-id
1456
        #     subsub-file1  subsub-file1-id
1457
        # dir2/             dir2-id
1458
        #   sub2-file1      sub2-file1-id
1459
        # top               top-id
1460
        self.make_dir(inv, 'dir1', 'TREE_ROOT')
1461
        self.make_dir(inv, 'dir2', 'TREE_ROOT')
1462
        self.make_dir(inv, 'sub-dir1', 'dir1-id')
1463
        self.make_file(inv, 'top', 'TREE_ROOT')
1464
        self.make_file(inv, 'sub-file1', 'dir1-id')
1465
        self.make_file(inv, 'sub-file2', 'dir1-id')
1466
        self.make_file(inv, 'subsub-file1', 'sub-dir1-id')
1467
        self.make_file(inv, 'sub2-file1', 'dir2-id')
1468
        chk_bytes = self.get_chk_bytes()
4634.51.8 by John Arbash Meinel
Catch a corner case that we were missing.
1469
        #  use a small maximum_size to force internal paging structures
1470
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv,
1471
                        maximum_size=100,
6963.1.1 by Jelmer Vernooij
Fix a bunch of tests on python3.
1472
                        search_key_name=b'hash-255-way')
1473
        bytes = b''.join(chk_inv.to_lines())
1474
        return CHKInventory.deserialise(chk_bytes, bytes, (b"revid",))
4634.51.3 by John Arbash Meinel
We have iteration to parents working, need to find children now.
1475
1476
    def assert_Getitems(self, expected_fileids, inv, file_ids):
1477
        self.assertEqual(sorted(expected_fileids),
1478
                         sorted([ie.file_id for ie in inv._getitems(file_ids)]))
1479
4634.51.5 by John Arbash Meinel
Change the api a bit.
1480
    def assertExpand(self, all_ids, inv, file_ids):
1481
        (val_all_ids,
1482
         val_children) = inv._expand_fileids_to_parents_and_children(file_ids)
1483
        self.assertEqual(set(all_ids), val_all_ids)
1484
        entries = inv._getitems(val_all_ids)
1485
        expected_children = {}
1486
        for entry in entries:
1487
            s = expected_children.setdefault(entry.parent_id, [])
1488
            s.append(entry.file_id)
1489
        val_children = dict((k, sorted(v)) for k, v
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
1490
                            in val_children.items())
4634.51.5 by John Arbash Meinel
Change the api a bit.
1491
        expected_children = dict((k, sorted(v)) for k, v
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
1492
                            in expected_children.items())
4634.51.5 by John Arbash Meinel
Change the api a bit.
1493
        self.assertEqual(expected_children, val_children)
4634.51.3 by John Arbash Meinel
We have iteration to parents working, need to find children now.
1494
1495
    def test_make_simple_inventory(self):
4634.51.2 by John Arbash Meinel
Start laying the groundwork for testing the expansion code
1496
        inv = self.make_simple_inventory()
1497
        layout = []
1498
        for path, entry in inv.iter_entries_by_dir():
1499
            layout.append((path, entry.file_id))
1500
        self.assertEqual([
1501
            ('', 'TREE_ROOT'),
1502
            ('dir1', 'dir1-id'),
1503
            ('dir2', 'dir2-id'),
1504
            ('top', 'top-id'),
1505
            ('dir1/sub-dir1', 'sub-dir1-id'),
1506
            ('dir1/sub-file1', 'sub-file1-id'),
1507
            ('dir1/sub-file2', 'sub-file2-id'),
1508
            ('dir1/sub-dir1/subsub-file1', 'subsub-file1-id'),
1509
            ('dir2/sub2-file1', 'sub2-file1-id'),
1510
            ], layout)
4634.51.3 by John Arbash Meinel
We have iteration to parents working, need to find children now.
1511
1512
    def test__getitems(self):
1513
        inv = self.make_simple_inventory()
1514
        # Reading from disk
1515
        self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
1516
        self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
1517
        self.assertFalse('sub-file2-id' in inv._fileid_to_entry_cache)
1518
        # From cache
1519
        self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
1520
        # Mixed
1521
        self.assert_Getitems(['dir1-id', 'sub-file2-id'], inv,
1522
                             ['dir1-id', 'sub-file2-id'])
1523
        self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
1524
        self.assertTrue('sub-file2-id' in inv._fileid_to_entry_cache)
1525
1526
    def test_single_file(self):
1527
        inv = self.make_simple_inventory()
4634.51.5 by John Arbash Meinel
Change the api a bit.
1528
        self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
4634.51.3 by John Arbash Meinel
We have iteration to parents working, need to find children now.
1529
1530
    def test_get_all_parents(self):
1531
        inv = self.make_simple_inventory()
4634.51.5 by John Arbash Meinel
Change the api a bit.
1532
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1533
                           'subsub-file1-id',
1534
                          ], inv, ['subsub-file1-id'])
4634.51.4 by John Arbash Meinel
Implement an expansion function that works directly on the chk maps.
1535
1536
    def test_get_children(self):
1537
        inv = self.make_simple_inventory()
4634.51.5 by John Arbash Meinel
Change the api a bit.
1538
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1539
                           'sub-file1-id', 'sub-file2-id', 'subsub-file1-id',
4634.51.4 by John Arbash Meinel
Implement an expansion function that works directly on the chk maps.
1540
                          ], inv, ['dir1-id'])
4634.51.8 by John Arbash Meinel
Catch a corner case that we were missing.
1541
1542
    def test_from_root(self):
1543
        inv = self.make_simple_inventory()
1544
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'dir2-id', 'sub-dir1-id',
1545
                           'sub-file1-id', 'sub-file2-id', 'sub2-file1-id',
1546
                           'subsub-file1-id', 'top-id'], inv, ['TREE_ROOT'])
1547
1548
    def test_top_level_file(self):
1549
        inv = self.make_simple_inventory()
1550
        self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
1551
1552
    def test_subsub_file(self):
1553
        inv = self.make_simple_inventory()
1554
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1555
                           'subsub-file1-id'], inv, ['subsub-file1-id'])
1556
1557
    def test_sub_and_root(self):
1558
        inv = self.make_simple_inventory()
1559
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id', 'top-id',
1560
                           'subsub-file1-id'], inv, ['top-id', 'subsub-file1-id'])
5802.1.2 by Jelmer Vernooij
Add test for mutable_inventory_from_tree.
1561
1562
1563
class TestMutableInventoryFromTree(TestCaseWithTransport):
1564
1565
    def test_empty(self):
1566
        repository = self.make_repository('.')
1567
        tree = repository.revision_tree(revision.NULL_REVISION)
1568
        inv = mutable_inventory_from_tree(tree)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1569
        self.assertEqual(revision.NULL_REVISION, inv.revision_id)
1570
        self.assertEqual(0, len(inv))
5802.1.2 by Jelmer Vernooij
Add test for mutable_inventory_from_tree.
1571
1572
    def test_some_files(self):
1573
        wt = self.make_branch_and_tree('.')
1574
        self.build_tree(['a'])
1575
        wt.add(['a'], ['thefileid'])
1576
        revid = wt.commit("commit")
1577
        tree = wt.branch.repository.revision_tree(revid)
1578
        inv = mutable_inventory_from_tree(tree)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1579
        self.assertEqual(revid, inv.revision_id)
1580
        self.assertEqual(2, len(inv))
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1581
        self.assertEqual("a", inv.get_entry('thefileid').name)
5802.1.2 by Jelmer Vernooij
Add test for mutable_inventory_from_tree.
1582
        # The inventory should be mutable and independent of
1583
        # the original tree
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
1584
        self.assertFalse(tree.root_inventory.get_entry('thefileid').executable)
1585
        inv.get_entry('thefileid').executable = True
1586
        self.assertFalse(tree.root_inventory.get_entry('thefileid').executable)