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