/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-05-18 01:55:17 UTC
  • mfrom: (5881.1.1 trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20110518015517-en7p3zst2mdprrqx
(vila) Merge 2.3 into trunk (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
from bzrlib import (
19
19
    chk_map,
20
20
    groupcompress,
21
 
    bzrdir,
22
21
    errors,
23
22
    inventory,
24
23
    osutils,
25
24
    repository,
26
25
    revision,
27
26
    tests,
28
 
    )
29
 
from bzrlib.inventory import (CHKInventory, Inventory, ROOT_ID, InventoryFile,
30
 
    InventoryDirectory, InventoryEntry, TreeReference)
 
27
    workingtree,
 
28
    )
 
29
from bzrlib.inventory import (
 
30
    CHKInventory,
 
31
    Inventory,
 
32
    ROOT_ID,
 
33
    InventoryFile,
 
34
    InventoryDirectory,
 
35
    InventoryEntry,
 
36
    TreeReference,
 
37
    mutable_inventory_from_tree,
 
38
    )
31
39
from bzrlib.tests import (
32
40
    TestCase,
33
41
    TestCaseWithTransport,
34
 
    condition_isinstance,
35
 
    multiply_tests,
36
 
    split_suite_by_condition,
37
42
    )
38
 
from bzrlib.tests.per_workingtree import workingtree_formats
39
 
 
40
 
 
41
 
def load_tests(standard_tests, module, loader):
42
 
    """Parameterise some inventory tests."""
43
 
    to_adapt, result = split_suite_by_condition(standard_tests,
44
 
        condition_isinstance(TestDeltaApplication))
 
43
from bzrlib.tests.scenarios import load_tests_apply_scenarios
 
44
 
 
45
 
 
46
load_tests = load_tests_apply_scenarios
 
47
 
 
48
 
 
49
def delta_application_scenarios():
45
50
    scenarios = [
46
51
        ('Inventory', {'apply_delta':apply_inventory_Inventory}),
47
52
        ]
52
57
    # just creating trees.
53
58
    formats = set()
54
59
    for _, format in repository.format_registry.iteritems():
55
 
        scenarios.append((str(format.__name__), {
56
 
            'apply_delta':apply_inventory_Repository_add_inventory_by_delta,
57
 
            'format':format}))
58
 
    for format in workingtree_formats():
 
60
        if format.supports_full_versioned_files:
 
61
            scenarios.append((str(format.__name__), {
 
62
                'apply_delta':apply_inventory_Repository_add_inventory_by_delta,
 
63
                'format':format}))
 
64
    for format in workingtree.format_registry._get_all():
 
65
        repo_fmt = format._matchingbzrdir.repository_format
 
66
        if not repo_fmt.supports_full_versioned_files:
 
67
            continue
59
68
        scenarios.append(
60
69
            (str(format.__class__.__name__) + ".update_basis_by_delta", {
61
70
            'apply_delta':apply_inventory_WT_basis,
64
73
            (str(format.__class__.__name__) + ".apply_inventory_delta", {
65
74
            'apply_delta':apply_inventory_WT,
66
75
            'format':format}))
67
 
    return multiply_tests(to_adapt, scenarios, result)
 
76
    return scenarios
68
77
 
69
78
 
70
79
def create_texts_for_inv(repo, inv):
74
83
        else:
75
84
            lines = []
76
85
        repo.texts.add_lines((ie.file_id, ie.revision), [], lines)
77
 
    
 
86
 
 
87
 
78
88
def apply_inventory_Inventory(self, basis, delta):
79
89
    """Apply delta to basis and return the result.
80
90
    
166
176
        # This reads basis from the repo and puts it into the tree's local
167
177
        # cache, if it has one.
168
178
        tree.set_parent_ids(['basis'])
169
 
        paths = {}
170
 
        parents = set()
171
 
        for old, new, id, entry in delta:
172
 
            if None in (new, entry):
173
 
                continue
174
 
            paths[new] = (entry.file_id, entry.kind)
175
 
            parents.add(osutils.dirname(new))
176
 
        parents = osutils.minimum_path_selection(parents)
177
 
        parents.discard('')
178
 
        # Put place holders in the tree to permit adding the other entries.
179
 
        for pos, parent in enumerate(parents):
180
 
            if not tree.path2id(parent):
181
 
                # add a synthetic directory in the tree so we can can put the
182
 
                # tree0 entries in place for dirstate.
183
 
                tree.add([parent], ["id%d" % pos], ["directory"])
184
 
        if paths:
185
 
            # Many deltas may cause this mini-apply to fail, but we want to see what
186
 
            # the delta application code says, not the prep that we do to deal with 
187
 
            # limitations of dirstate's update_basis code.
188
 
            for path, (file_id, kind) in sorted(paths.items()):
189
 
                try:
190
 
                    tree.add([path], [file_id], [kind])
191
 
                except (KeyboardInterrupt, SystemExit):
192
 
                    raise
193
 
                except:
194
 
                    pass
195
179
    finally:
196
180
        tree.unlock()
197
181
    # Fresh lock, reads disk again.
330
314
 
331
315
 
332
316
class TestDeltaApplication(TestCaseWithTransport):
 
317
 
 
318
    scenarios = delta_application_scenarios()
333
319
 
334
320
    def get_empty_inventory(self, reference_inv=None):
335
321
        """Get an empty inventory.
574
560
        self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
575
561
            inv, delta)
576
562
 
577
 
 
578
 
class TestInventory(TestCase):
 
563
    def test_add_file(self):
 
564
        inv = self.get_empty_inventory()
 
565
        file1 = inventory.InventoryFile('file-id', 'path', inv.root.file_id)
 
566
        file1.revision = 'result'
 
567
        file1.text_size = 0
 
568
        file1.text_sha1 = ''
 
569
        delta = [(None, u'path', 'file-id', file1)]
 
570
        res_inv = self.apply_delta(self, inv, delta)
 
571
        self.assertEqual('file-id', res_inv['file-id'].file_id)
 
572
 
 
573
    def test_remove_file(self):
 
574
        inv = self.get_empty_inventory()
 
575
        file1 = inventory.InventoryFile('file-id', 'path', inv.root.file_id)
 
576
        file1.revision = 'result'
 
577
        file1.text_size = 0
 
578
        file1.text_sha1 = ''
 
579
        inv.add(file1)
 
580
        delta = [(u'path', None, 'file-id', None)]
 
581
        res_inv = self.apply_delta(self, inv, delta)
 
582
        self.assertEqual(None, res_inv.path2id('path'))
 
583
        self.assertRaises(errors.NoSuchId, res_inv.id2path, 'file-id')
 
584
 
 
585
    def test_rename_file(self):
 
586
        inv = self.get_empty_inventory()
 
587
        file1 = inventory.InventoryFile('file-id', 'path', inv.root.file_id)
 
588
        file1.revision = 'result'
 
589
        file1.text_size = 0
 
590
        file1.text_sha1 = ''
 
591
        inv.add(file1)
 
592
        file2 = file1.copy()
 
593
        file2.name = 'path2'
 
594
        delta = [(u'path', 'path2', 'file-id', file2)]
 
595
        res_inv = self.apply_delta(self, inv, delta)
 
596
        self.assertEqual(None, res_inv.path2id('path'))
 
597
        self.assertEqual('file-id', res_inv.path2id('path2'))
579
598
 
580
599
    def test_is_root(self):
581
600
        """Ensure our root-checking code is accurate."""
590
609
        self.assertFalse(inv.is_root('TREE_ROOT'))
591
610
        self.assertFalse(inv.is_root('booga'))
592
611
 
 
612
    def test_entries_for_empty_inventory(self):
 
613
        """Test that entries() will not fail for an empty inventory"""
 
614
        inv = Inventory(root_id=None)
 
615
        self.assertEqual([], inv.entries())
 
616
 
593
617
 
594
618
class TestInventoryEntry(TestCase):
595
619
 
607
631
 
608
632
    def test_dir_detect_changes(self):
609
633
        left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
610
 
        left.text_sha1 = 123
611
 
        left.executable = True
612
 
        left.symlink_target='foo'
613
634
        right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
614
 
        right.text_sha1 = 321
615
 
        right.symlink_target='bar'
616
635
        self.assertEqual((False, False), left.detect_changes(right))
617
636
        self.assertEqual((False, False), right.detect_changes(left))
618
637
 
632
651
 
633
652
    def test_symlink_detect_changes(self):
634
653
        left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
635
 
        left.text_sha1 = 123
636
 
        left.executable = True
637
654
        left.symlink_target='foo'
638
655
        right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
639
 
        right.text_sha1 = 321
640
656
        right.symlink_target='foo'
641
657
        self.assertEqual((False, False), left.detect_changes(right))
642
658
        self.assertEqual((False, False), right.detect_changes(left))
646
662
 
647
663
    def test_file_has_text(self):
648
664
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
649
 
        self.failUnless(file.has_text())
 
665
        self.assertTrue(file.has_text())
650
666
 
651
667
    def test_directory_has_text(self):
652
668
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
653
 
        self.failIf(dir.has_text())
 
669
        self.assertFalse(dir.has_text())
654
670
 
655
671
    def test_link_has_text(self):
656
672
        link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
657
 
        self.failIf(link.has_text())
 
673
        self.assertFalse(link.has_text())
658
674
 
659
675
    def test_make_entry(self):
660
676
        self.assertIsInstance(inventory.make_entry("file", "name", ROOT_ID),
1215
1231
        self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
1216
1232
                         inv._bytes_to_utf8name_key(bytes))
1217
1233
 
 
1234
    def make_basic_utf8_inventory(self):
 
1235
        inv = Inventory()
 
1236
        inv.revision_id = "revid"
 
1237
        inv.root.revision = "rootrev"
 
1238
        root_id = inv.root.file_id
 
1239
        inv.add(InventoryFile("fileid", u'f\xefle', root_id))
 
1240
        inv["fileid"].revision = "filerev"
 
1241
        inv["fileid"].text_sha1 = "ffff"
 
1242
        inv["fileid"].text_size = 0
 
1243
        inv.add(InventoryDirectory("dirid", u'dir-\N{EURO SIGN}', root_id))
 
1244
        inv.add(InventoryFile("childid", u'ch\xefld', "dirid"))
 
1245
        inv["childid"].revision = "filerev"
 
1246
        inv["childid"].text_sha1 = "ffff"
 
1247
        inv["childid"].text_size = 0
 
1248
        chk_bytes = self.get_chk_bytes()
 
1249
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
1250
        bytes = ''.join(chk_inv.to_lines())
 
1251
        return CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
1252
 
 
1253
    def test__preload_handles_utf8(self):
 
1254
        new_inv = self.make_basic_utf8_inventory()
 
1255
        self.assertEqual({}, new_inv._fileid_to_entry_cache)
 
1256
        self.assertFalse(new_inv._fully_cached)
 
1257
        new_inv._preload_cache()
 
1258
        self.assertEqual(
 
1259
            sorted([new_inv.root_id, "fileid", "dirid", "childid"]),
 
1260
            sorted(new_inv._fileid_to_entry_cache.keys()))
 
1261
        ie_root = new_inv._fileid_to_entry_cache[new_inv.root_id]
 
1262
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
 
1263
                         sorted(ie_root._children.keys()))
 
1264
        ie_dir = new_inv._fileid_to_entry_cache['dirid']
 
1265
        self.assertEqual([u'ch\xefld'], sorted(ie_dir._children.keys()))
 
1266
 
 
1267
    def test__preload_populates_cache(self):
 
1268
        inv = Inventory()
 
1269
        inv.revision_id = "revid"
 
1270
        inv.root.revision = "rootrev"
 
1271
        root_id = inv.root.file_id
 
1272
        inv.add(InventoryFile("fileid", "file", root_id))
 
1273
        inv["fileid"].revision = "filerev"
 
1274
        inv["fileid"].executable = True
 
1275
        inv["fileid"].text_sha1 = "ffff"
 
1276
        inv["fileid"].text_size = 1
 
1277
        inv.add(InventoryDirectory("dirid", "dir", root_id))
 
1278
        inv.add(InventoryFile("childid", "child", "dirid"))
 
1279
        inv["childid"].revision = "filerev"
 
1280
        inv["childid"].executable = False
 
1281
        inv["childid"].text_sha1 = "dddd"
 
1282
        inv["childid"].text_size = 1
 
1283
        chk_bytes = self.get_chk_bytes()
 
1284
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
1285
        bytes = ''.join(chk_inv.to_lines())
 
1286
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
1287
        self.assertEqual({}, new_inv._fileid_to_entry_cache)
 
1288
        self.assertFalse(new_inv._fully_cached)
 
1289
        new_inv._preload_cache()
 
1290
        self.assertEqual(
 
1291
            sorted([root_id, "fileid", "dirid", "childid"]),
 
1292
            sorted(new_inv._fileid_to_entry_cache.keys()))
 
1293
        self.assertTrue(new_inv._fully_cached)
 
1294
        ie_root = new_inv._fileid_to_entry_cache[root_id]
 
1295
        self.assertEqual(['dir', 'file'], sorted(ie_root._children.keys()))
 
1296
        ie_dir = new_inv._fileid_to_entry_cache['dirid']
 
1297
        self.assertEqual(['child'], sorted(ie_dir._children.keys()))
 
1298
 
 
1299
    def test__preload_handles_partially_evaluated_inventory(self):
 
1300
        new_inv = self.make_basic_utf8_inventory()
 
1301
        ie = new_inv[new_inv.root_id]
 
1302
        self.assertIs(None, ie._children)
 
1303
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
 
1304
                         sorted(ie.children.keys()))
 
1305
        # Accessing .children loads _children
 
1306
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
 
1307
                         sorted(ie._children.keys()))
 
1308
        new_inv._preload_cache()
 
1309
        # No change
 
1310
        self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
 
1311
                         sorted(ie._children.keys()))
 
1312
        ie_dir = new_inv["dirid"]
 
1313
        self.assertEqual([u'ch\xefld'],
 
1314
                         sorted(ie_dir._children.keys()))
 
1315
 
1218
1316
 
1219
1317
class TestCHKInventoryExpand(tests.TestCaseWithMemoryTransport):
1220
1318
 
1346
1444
        inv = self.make_simple_inventory()
1347
1445
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id', 'top-id',
1348
1446
                           'subsub-file1-id'], inv, ['top-id', 'subsub-file1-id'])
 
1447
 
 
1448
 
 
1449
class TestMutableInventoryFromTree(TestCaseWithTransport):
 
1450
 
 
1451
    def test_empty(self):
 
1452
        repository = self.make_repository('.')
 
1453
        tree = repository.revision_tree(revision.NULL_REVISION)
 
1454
        inv = mutable_inventory_from_tree(tree)
 
1455
        self.assertEquals(revision.NULL_REVISION, inv.revision_id)
 
1456
        self.assertEquals(0, len(inv))
 
1457
 
 
1458
    def test_some_files(self):
 
1459
        wt = self.make_branch_and_tree('.')
 
1460
        self.build_tree(['a'])
 
1461
        wt.add(['a'], ['thefileid'])
 
1462
        revid = wt.commit("commit")
 
1463
        tree = wt.branch.repository.revision_tree(revid)
 
1464
        inv = mutable_inventory_from_tree(tree)
 
1465
        self.assertEquals(revid, inv.revision_id)
 
1466
        self.assertEquals(2, len(inv))
 
1467
        self.assertEquals("a", inv['thefileid'].name)
 
1468
        # The inventory should be mutable and independent of
 
1469
        # the original tree
 
1470
        self.assertFalse(tree.inventory['thefileid'].executable)
 
1471
        inv['thefileid'].executable = True
 
1472
        self.assertFalse(tree.inventory['thefileid'].executable)