~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-01 08:02:42 UTC
  • mfrom: (5390.3.3 faster-revert-593560)
  • Revision ID: pqm@pqm.ubuntu.com-20100901080242-esg62ody4frwmy66
(spiv) Avoid repeatedly calling self.target.all_file_ids() in
 InterTree.iter_changes. (Andrew Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
17
17
 
18
18
from bzrlib import (
19
19
    chk_map,
20
 
    bzrdir,
 
20
    groupcompress,
21
21
    errors,
22
22
    inventory,
23
23
    osutils,
24
24
    repository,
25
25
    revision,
 
26
    tests,
26
27
    )
27
28
from bzrlib.inventory import (CHKInventory, Inventory, ROOT_ID, InventoryFile,
28
29
    InventoryDirectory, InventoryEntry, TreeReference)
65
66
    return multiply_tests(to_adapt, scenarios, result)
66
67
 
67
68
 
 
69
def create_texts_for_inv(repo, inv):
 
70
    for path, ie in inv.iter_entries():
 
71
        if ie.text_size:
 
72
            lines = ['a' * ie.text_size]
 
73
        else:
 
74
            lines = []
 
75
        repo.texts.add_lines((ie.file_id, ie.revision), [], lines)
 
76
    
68
77
def apply_inventory_Inventory(self, basis, delta):
69
78
    """Apply delta to basis and return the result.
70
79
    
137
146
            rev = revision.Revision('basis', timestamp=0, timezone=None,
138
147
                message="", committer="foo@example.com")
139
148
            basis.revision_id = 'basis'
 
149
            create_texts_for_inv(tree.branch.repository, basis)
140
150
            repo.add_revision('basis', rev, basis)
141
151
            # Add a revision for the result, with the basis content - 
142
152
            # update_basis_by_delta doesn't check that the delta results in
146
156
                message="", committer="foo@example.com")
147
157
            basis.revision_id = 'result'
148
158
            repo.add_revision('result', rev, basis)
 
159
            repo.commit_write_group()
149
160
        except:
150
161
            repo.abort_write_group()
151
162
            raise
152
 
        else:
153
 
            repo.commit_write_group()
154
163
        # Set the basis state as the trees current state
155
164
        tree._write_inventory(basis)
156
165
        # This reads basis from the repo and puts it into the tree's local
221
230
            rev = revision.Revision('basis', timestamp=0, timezone=None,
222
231
                message="", committer="foo@example.com")
223
232
            basis.revision_id = 'basis'
 
233
            create_texts_for_inv(repo, basis)
224
234
            repo.add_revision('basis', rev, basis)
 
235
            repo.commit_write_group()
225
236
        except:
226
237
            repo.abort_write_group()
227
238
            raise
228
 
        else:
229
 
            repo.commit_write_group()
230
239
    finally:
231
240
        repo.unlock()
232
241
    repo.lock_write()
249
258
    return repo.get_inventory('result')
250
259
 
251
260
 
 
261
class TestInventoryUpdates(TestCase):
 
262
 
 
263
    def test_creation_from_root_id(self):
 
264
        # iff a root id is passed to the constructor, a root directory is made
 
265
        inv = inventory.Inventory(root_id='tree-root')
 
266
        self.assertNotEqual(None, inv.root)
 
267
        self.assertEqual('tree-root', inv.root.file_id)
 
268
 
 
269
    def test_add_path_of_root(self):
 
270
        # if no root id is given at creation time, there is no root directory
 
271
        inv = inventory.Inventory(root_id=None)
 
272
        self.assertIs(None, inv.root)
 
273
        # add a root entry by adding its path
 
274
        ie = inv.add_path("", "directory", "my-root")
 
275
        ie.revision = 'test-rev'
 
276
        self.assertEqual("my-root", ie.file_id)
 
277
        self.assertIs(ie, inv.root)
 
278
 
 
279
    def test_add_path(self):
 
280
        inv = inventory.Inventory(root_id='tree_root')
 
281
        ie = inv.add_path('hello', 'file', 'hello-id')
 
282
        self.assertEqual('hello-id', ie.file_id)
 
283
        self.assertEqual('file', ie.kind)
 
284
 
 
285
    def test_copy(self):
 
286
        """Make sure copy() works and creates a deep copy."""
 
287
        inv = inventory.Inventory(root_id='some-tree-root')
 
288
        ie = inv.add_path('hello', 'file', 'hello-id')
 
289
        inv2 = inv.copy()
 
290
        inv.root.file_id = 'some-new-root'
 
291
        ie.name = 'file2'
 
292
        self.assertEqual('some-tree-root', inv2.root.file_id)
 
293
        self.assertEqual('hello', inv2['hello-id'].name)
 
294
 
 
295
    def test_copy_empty(self):
 
296
        """Make sure an empty inventory can be copied."""
 
297
        inv = inventory.Inventory(root_id=None)
 
298
        inv2 = inv.copy()
 
299
        self.assertIs(None, inv2.root)
 
300
 
 
301
    def test_copy_copies_root_revision(self):
 
302
        """Make sure the revision of the root gets copied."""
 
303
        inv = inventory.Inventory(root_id='someroot')
 
304
        inv.root.revision = 'therev'
 
305
        inv2 = inv.copy()
 
306
        self.assertEquals('someroot', inv2.root.file_id)
 
307
        self.assertEquals('therev', inv2.root.revision)
 
308
 
 
309
    def test_create_tree_reference(self):
 
310
        inv = inventory.Inventory('tree-root-123')
 
311
        inv.add(TreeReference('nested-id', 'nested', parent_id='tree-root-123',
 
312
                              revision='rev', reference_revision='rev2'))
 
313
 
 
314
    def test_error_encoding(self):
 
315
        inv = inventory.Inventory('tree-root')
 
316
        inv.add(InventoryFile('a-id', u'\u1234', 'tree-root'))
 
317
        e = self.assertRaises(errors.InconsistentDelta, inv.add,
 
318
            InventoryFile('b-id', u'\u1234', 'tree-root'))
 
319
        self.assertContainsRe(str(e), r'\\u1234')
 
320
 
 
321
    def test_add_recursive(self):
 
322
        parent = InventoryDirectory('src-id', 'src', 'tree-root')
 
323
        child = InventoryFile('hello-id', 'hello.c', 'src-id')
 
324
        parent.children[child.file_id] = child
 
325
        inv = inventory.Inventory('tree-root')
 
326
        inv.add(parent)
 
327
        self.assertEqual('src/hello.c', inv.id2path('hello-id'))
 
328
 
 
329
 
 
330
 
252
331
class TestDeltaApplication(TestCaseWithTransport):
253
332
 
254
333
    def get_empty_inventory(self, reference_inv=None):
495
574
            inv, delta)
496
575
 
497
576
 
 
577
class TestInventory(TestCase):
 
578
 
 
579
    def test_is_root(self):
 
580
        """Ensure our root-checking code is accurate."""
 
581
        inv = inventory.Inventory('TREE_ROOT')
 
582
        self.assertTrue(inv.is_root('TREE_ROOT'))
 
583
        self.assertFalse(inv.is_root('booga'))
 
584
        inv.root.file_id = 'booga'
 
585
        self.assertFalse(inv.is_root('TREE_ROOT'))
 
586
        self.assertTrue(inv.is_root('booga'))
 
587
        # works properly even if no root is set
 
588
        inv.root = None
 
589
        self.assertFalse(inv.is_root('TREE_ROOT'))
 
590
        self.assertFalse(inv.is_root('booga'))
 
591
 
 
592
 
498
593
class TestInventoryEntry(TestCase):
499
594
 
500
595
    def test_file_kind_character(self):
511
606
 
512
607
    def test_dir_detect_changes(self):
513
608
        left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
514
 
        left.text_sha1 = 123
515
 
        left.executable = True
516
 
        left.symlink_target='foo'
517
609
        right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
518
 
        right.text_sha1 = 321
519
 
        right.symlink_target='bar'
520
610
        self.assertEqual((False, False), left.detect_changes(right))
521
611
        self.assertEqual((False, False), right.detect_changes(left))
522
612
 
536
626
 
537
627
    def test_symlink_detect_changes(self):
538
628
        left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
539
 
        left.text_sha1 = 123
540
 
        left.executable = True
541
629
        left.symlink_target='foo'
542
630
        right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
543
 
        right.text_sha1 = 321
544
631
        right.symlink_target='foo'
545
632
        self.assertEqual((False, False), left.detect_changes(right))
546
633
        self.assertEqual((False, False), right.detect_changes(left))
642
729
        self.assertEqual(expected_change, change)
643
730
 
644
731
 
645
 
class TestCHKInventory(TestCaseWithTransport):
 
732
class TestCHKInventory(tests.TestCaseWithMemoryTransport):
646
733
 
647
734
    def get_chk_bytes(self):
648
 
        # The easiest way to get a CHK store is a development6 repository and
649
 
        # then work with the chk_bytes attribute directly.
650
 
        repo = self.make_repository(".", format="development6-rich-root")
651
 
        repo.lock_write()
652
 
        self.addCleanup(repo.unlock)
653
 
        repo.start_write_group()
654
 
        self.addCleanup(repo.abort_write_group)
655
 
        return repo.chk_bytes
 
735
        factory = groupcompress.make_pack_factory(True, True, 1)
 
736
        trans = self.get_transport('')
 
737
        return factory(trans)
656
738
 
657
739
    def read_bytes(self, chk_bytes, key):
658
740
        stream = chk_bytes.get_record_stream([key], 'unordered', True)
1123
1205
        self.assertIsInstance(ie2.name, unicode)
1124
1206
        self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
1125
1207
                         inv._bytes_to_utf8name_key(bytes))
 
1208
 
 
1209
 
 
1210
class TestCHKInventoryExpand(tests.TestCaseWithMemoryTransport):
 
1211
 
 
1212
    def get_chk_bytes(self):
 
1213
        factory = groupcompress.make_pack_factory(True, True, 1)
 
1214
        trans = self.get_transport('')
 
1215
        return factory(trans)
 
1216
 
 
1217
    def make_dir(self, inv, name, parent_id):
 
1218
        inv.add(inv.make_entry('directory', name, parent_id, name + '-id'))
 
1219
 
 
1220
    def make_file(self, inv, name, parent_id, content='content\n'):
 
1221
        ie = inv.make_entry('file', name, parent_id, name + '-id')
 
1222
        ie.text_sha1 = osutils.sha_string(content)
 
1223
        ie.text_size = len(content)
 
1224
        inv.add(ie)
 
1225
 
 
1226
    def make_simple_inventory(self):
 
1227
        inv = Inventory('TREE_ROOT')
 
1228
        inv.revision_id = "revid"
 
1229
        inv.root.revision = "rootrev"
 
1230
        # /                 TREE_ROOT
 
1231
        # dir1/             dir1-id
 
1232
        #   sub-file1       sub-file1-id
 
1233
        #   sub-file2       sub-file2-id
 
1234
        #   sub-dir1/       sub-dir1-id
 
1235
        #     subsub-file1  subsub-file1-id
 
1236
        # dir2/             dir2-id
 
1237
        #   sub2-file1      sub2-file1-id
 
1238
        # top               top-id
 
1239
        self.make_dir(inv, 'dir1', 'TREE_ROOT')
 
1240
        self.make_dir(inv, 'dir2', 'TREE_ROOT')
 
1241
        self.make_dir(inv, 'sub-dir1', 'dir1-id')
 
1242
        self.make_file(inv, 'top', 'TREE_ROOT')
 
1243
        self.make_file(inv, 'sub-file1', 'dir1-id')
 
1244
        self.make_file(inv, 'sub-file2', 'dir1-id')
 
1245
        self.make_file(inv, 'subsub-file1', 'sub-dir1-id')
 
1246
        self.make_file(inv, 'sub2-file1', 'dir2-id')
 
1247
        chk_bytes = self.get_chk_bytes()
 
1248
        #  use a small maximum_size to force internal paging structures
 
1249
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv,
 
1250
                        maximum_size=100,
 
1251
                        search_key_name='hash-255-way')
 
1252
        bytes = ''.join(chk_inv.to_lines())
 
1253
        return CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
1254
 
 
1255
    def assert_Getitems(self, expected_fileids, inv, file_ids):
 
1256
        self.assertEqual(sorted(expected_fileids),
 
1257
                         sorted([ie.file_id for ie in inv._getitems(file_ids)]))
 
1258
 
 
1259
    def assertExpand(self, all_ids, inv, file_ids):
 
1260
        (val_all_ids,
 
1261
         val_children) = inv._expand_fileids_to_parents_and_children(file_ids)
 
1262
        self.assertEqual(set(all_ids), val_all_ids)
 
1263
        entries = inv._getitems(val_all_ids)
 
1264
        expected_children = {}
 
1265
        for entry in entries:
 
1266
            s = expected_children.setdefault(entry.parent_id, [])
 
1267
            s.append(entry.file_id)
 
1268
        val_children = dict((k, sorted(v)) for k, v
 
1269
                            in val_children.iteritems())
 
1270
        expected_children = dict((k, sorted(v)) for k, v
 
1271
                            in expected_children.iteritems())
 
1272
        self.assertEqual(expected_children, val_children)
 
1273
 
 
1274
    def test_make_simple_inventory(self):
 
1275
        inv = self.make_simple_inventory()
 
1276
        layout = []
 
1277
        for path, entry in inv.iter_entries_by_dir():
 
1278
            layout.append((path, entry.file_id))
 
1279
        self.assertEqual([
 
1280
            ('', 'TREE_ROOT'),
 
1281
            ('dir1', 'dir1-id'),
 
1282
            ('dir2', 'dir2-id'),
 
1283
            ('top', 'top-id'),
 
1284
            ('dir1/sub-dir1', 'sub-dir1-id'),
 
1285
            ('dir1/sub-file1', 'sub-file1-id'),
 
1286
            ('dir1/sub-file2', 'sub-file2-id'),
 
1287
            ('dir1/sub-dir1/subsub-file1', 'subsub-file1-id'),
 
1288
            ('dir2/sub2-file1', 'sub2-file1-id'),
 
1289
            ], layout)
 
1290
 
 
1291
    def test__getitems(self):
 
1292
        inv = self.make_simple_inventory()
 
1293
        # Reading from disk
 
1294
        self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
 
1295
        self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
 
1296
        self.assertFalse('sub-file2-id' in inv._fileid_to_entry_cache)
 
1297
        # From cache
 
1298
        self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
 
1299
        # Mixed
 
1300
        self.assert_Getitems(['dir1-id', 'sub-file2-id'], inv,
 
1301
                             ['dir1-id', 'sub-file2-id'])
 
1302
        self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
 
1303
        self.assertTrue('sub-file2-id' in inv._fileid_to_entry_cache)
 
1304
 
 
1305
    def test_single_file(self):
 
1306
        inv = self.make_simple_inventory()
 
1307
        self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
 
1308
 
 
1309
    def test_get_all_parents(self):
 
1310
        inv = self.make_simple_inventory()
 
1311
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
 
1312
                           'subsub-file1-id',
 
1313
                          ], inv, ['subsub-file1-id'])
 
1314
 
 
1315
    def test_get_children(self):
 
1316
        inv = self.make_simple_inventory()
 
1317
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
 
1318
                           'sub-file1-id', 'sub-file2-id', 'subsub-file1-id',
 
1319
                          ], inv, ['dir1-id'])
 
1320
 
 
1321
    def test_from_root(self):
 
1322
        inv = self.make_simple_inventory()
 
1323
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'dir2-id', 'sub-dir1-id',
 
1324
                           'sub-file1-id', 'sub-file2-id', 'sub2-file1-id',
 
1325
                           'subsub-file1-id', 'top-id'], inv, ['TREE_ROOT'])
 
1326
 
 
1327
    def test_top_level_file(self):
 
1328
        inv = self.make_simple_inventory()
 
1329
        self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
 
1330
 
 
1331
    def test_subsub_file(self):
 
1332
        inv = self.make_simple_inventory()
 
1333
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
 
1334
                           'subsub-file1-id'], inv, ['subsub-file1-id'])
 
1335
 
 
1336
    def test_sub_and_root(self):
 
1337
        inv = self.make_simple_inventory()
 
1338
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id', 'top-id',
 
1339
                           'subsub-file1-id'], inv, ['top-id', 'subsub-file1-id'])