~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: Martin Pool
  • Date: 2009-09-14 02:30:23 UTC
  • mto: This revision was merged to the branch mainline in revision 4693.
  • Revision ID: mbp@sourcefrog.net-20090914023023-ros0f3ndo04j3bww
Clearer docs about bzr help.  (Thanks to Naoki)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 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
 
    groupcompress,
 
20
    bzrdir,
21
21
    errors,
22
22
    inventory,
23
23
    osutils,
24
24
    repository,
25
25
    revision,
26
 
    tests,
27
26
    )
28
27
from bzrlib.inventory import (CHKInventory, Inventory, ROOT_ID, InventoryFile,
29
28
    InventoryDirectory, InventoryEntry, TreeReference)
66
65
    return multiply_tests(to_adapt, scenarios, result)
67
66
 
68
67
 
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
 
    
77
68
def apply_inventory_Inventory(self, basis, delta):
78
69
    """Apply delta to basis and return the result.
79
70
    
146
137
            rev = revision.Revision('basis', timestamp=0, timezone=None,
147
138
                message="", committer="foo@example.com")
148
139
            basis.revision_id = 'basis'
149
 
            create_texts_for_inv(tree.branch.repository, basis)
150
140
            repo.add_revision('basis', rev, basis)
151
141
            # Add a revision for the result, with the basis content - 
152
142
            # update_basis_by_delta doesn't check that the delta results in
156
146
                message="", committer="foo@example.com")
157
147
            basis.revision_id = 'result'
158
148
            repo.add_revision('result', rev, basis)
159
 
            repo.commit_write_group()
160
149
        except:
161
150
            repo.abort_write_group()
162
151
            raise
 
152
        else:
 
153
            repo.commit_write_group()
163
154
        # Set the basis state as the trees current state
164
155
        tree._write_inventory(basis)
165
156
        # This reads basis from the repo and puts it into the tree's local
230
221
            rev = revision.Revision('basis', timestamp=0, timezone=None,
231
222
                message="", committer="foo@example.com")
232
223
            basis.revision_id = 'basis'
233
 
            create_texts_for_inv(repo, basis)
234
224
            repo.add_revision('basis', rev, basis)
235
 
            repo.commit_write_group()
236
225
        except:
237
226
            repo.abort_write_group()
238
227
            raise
 
228
        else:
 
229
            repo.commit_write_group()
239
230
    finally:
240
231
        repo.unlock()
241
232
    repo.lock_write()
258
249
    return repo.get_inventory('result')
259
250
 
260
251
 
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
 
 
331
252
class TestDeltaApplication(TestCaseWithTransport):
332
253
 
333
254
    def get_empty_inventory(self, reference_inv=None):
574
495
            inv, delta)
575
496
 
576
497
 
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
 
    def test_entries_for_empty_inventory(self):
593
 
        """Test that entries() will not fail for an empty inventory"""
594
 
        inv = Inventory(root_id=None)
595
 
        self.assertEqual([], inv.entries())
596
 
 
597
 
 
598
498
class TestInventoryEntry(TestCase):
599
499
 
600
500
    def test_file_kind_character(self):
611
511
 
612
512
    def test_dir_detect_changes(self):
613
513
        left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
514
        left.text_sha1 = 123
 
515
        left.executable = True
 
516
        left.symlink_target='foo'
614
517
        right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
518
        right.text_sha1 = 321
 
519
        right.symlink_target='bar'
615
520
        self.assertEqual((False, False), left.detect_changes(right))
616
521
        self.assertEqual((False, False), right.detect_changes(left))
617
522
 
631
536
 
632
537
    def test_symlink_detect_changes(self):
633
538
        left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
539
        left.text_sha1 = 123
 
540
        left.executable = True
634
541
        left.symlink_target='foo'
635
542
        right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
543
        right.text_sha1 = 321
636
544
        right.symlink_target='foo'
637
545
        self.assertEqual((False, False), left.detect_changes(right))
638
546
        self.assertEqual((False, False), right.detect_changes(left))
734
642
        self.assertEqual(expected_change, change)
735
643
 
736
644
 
737
 
class TestCHKInventory(tests.TestCaseWithMemoryTransport):
 
645
class TestCHKInventory(TestCaseWithTransport):
738
646
 
739
647
    def get_chk_bytes(self):
740
 
        factory = groupcompress.make_pack_factory(True, True, 1)
741
 
        trans = self.get_transport('')
742
 
        return factory(trans)
 
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
743
656
 
744
657
    def read_bytes(self, chk_bytes, key):
745
658
        stream = chk_bytes.get_record_stream([key], 'unordered', True)
1210
1123
        self.assertIsInstance(ie2.name, unicode)
1211
1124
        self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
1212
1125
                         inv._bytes_to_utf8name_key(bytes))
1213
 
 
1214
 
 
1215
 
class TestCHKInventoryExpand(tests.TestCaseWithMemoryTransport):
1216
 
 
1217
 
    def get_chk_bytes(self):
1218
 
        factory = groupcompress.make_pack_factory(True, True, 1)
1219
 
        trans = self.get_transport('')
1220
 
        return factory(trans)
1221
 
 
1222
 
    def make_dir(self, inv, name, parent_id):
1223
 
        inv.add(inv.make_entry('directory', name, parent_id, name + '-id'))
1224
 
 
1225
 
    def make_file(self, inv, name, parent_id, content='content\n'):
1226
 
        ie = inv.make_entry('file', name, parent_id, name + '-id')
1227
 
        ie.text_sha1 = osutils.sha_string(content)
1228
 
        ie.text_size = len(content)
1229
 
        inv.add(ie)
1230
 
 
1231
 
    def make_simple_inventory(self):
1232
 
        inv = Inventory('TREE_ROOT')
1233
 
        inv.revision_id = "revid"
1234
 
        inv.root.revision = "rootrev"
1235
 
        # /                 TREE_ROOT
1236
 
        # dir1/             dir1-id
1237
 
        #   sub-file1       sub-file1-id
1238
 
        #   sub-file2       sub-file2-id
1239
 
        #   sub-dir1/       sub-dir1-id
1240
 
        #     subsub-file1  subsub-file1-id
1241
 
        # dir2/             dir2-id
1242
 
        #   sub2-file1      sub2-file1-id
1243
 
        # top               top-id
1244
 
        self.make_dir(inv, 'dir1', 'TREE_ROOT')
1245
 
        self.make_dir(inv, 'dir2', 'TREE_ROOT')
1246
 
        self.make_dir(inv, 'sub-dir1', 'dir1-id')
1247
 
        self.make_file(inv, 'top', 'TREE_ROOT')
1248
 
        self.make_file(inv, 'sub-file1', 'dir1-id')
1249
 
        self.make_file(inv, 'sub-file2', 'dir1-id')
1250
 
        self.make_file(inv, 'subsub-file1', 'sub-dir1-id')
1251
 
        self.make_file(inv, 'sub2-file1', 'dir2-id')
1252
 
        chk_bytes = self.get_chk_bytes()
1253
 
        #  use a small maximum_size to force internal paging structures
1254
 
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv,
1255
 
                        maximum_size=100,
1256
 
                        search_key_name='hash-255-way')
1257
 
        bytes = ''.join(chk_inv.to_lines())
1258
 
        return CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1259
 
 
1260
 
    def assert_Getitems(self, expected_fileids, inv, file_ids):
1261
 
        self.assertEqual(sorted(expected_fileids),
1262
 
                         sorted([ie.file_id for ie in inv._getitems(file_ids)]))
1263
 
 
1264
 
    def assertExpand(self, all_ids, inv, file_ids):
1265
 
        (val_all_ids,
1266
 
         val_children) = inv._expand_fileids_to_parents_and_children(file_ids)
1267
 
        self.assertEqual(set(all_ids), val_all_ids)
1268
 
        entries = inv._getitems(val_all_ids)
1269
 
        expected_children = {}
1270
 
        for entry in entries:
1271
 
            s = expected_children.setdefault(entry.parent_id, [])
1272
 
            s.append(entry.file_id)
1273
 
        val_children = dict((k, sorted(v)) for k, v
1274
 
                            in val_children.iteritems())
1275
 
        expected_children = dict((k, sorted(v)) for k, v
1276
 
                            in expected_children.iteritems())
1277
 
        self.assertEqual(expected_children, val_children)
1278
 
 
1279
 
    def test_make_simple_inventory(self):
1280
 
        inv = self.make_simple_inventory()
1281
 
        layout = []
1282
 
        for path, entry in inv.iter_entries_by_dir():
1283
 
            layout.append((path, entry.file_id))
1284
 
        self.assertEqual([
1285
 
            ('', 'TREE_ROOT'),
1286
 
            ('dir1', 'dir1-id'),
1287
 
            ('dir2', 'dir2-id'),
1288
 
            ('top', 'top-id'),
1289
 
            ('dir1/sub-dir1', 'sub-dir1-id'),
1290
 
            ('dir1/sub-file1', 'sub-file1-id'),
1291
 
            ('dir1/sub-file2', 'sub-file2-id'),
1292
 
            ('dir1/sub-dir1/subsub-file1', 'subsub-file1-id'),
1293
 
            ('dir2/sub2-file1', 'sub2-file1-id'),
1294
 
            ], layout)
1295
 
 
1296
 
    def test__getitems(self):
1297
 
        inv = self.make_simple_inventory()
1298
 
        # Reading from disk
1299
 
        self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
1300
 
        self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
1301
 
        self.assertFalse('sub-file2-id' in inv._fileid_to_entry_cache)
1302
 
        # From cache
1303
 
        self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
1304
 
        # Mixed
1305
 
        self.assert_Getitems(['dir1-id', 'sub-file2-id'], inv,
1306
 
                             ['dir1-id', 'sub-file2-id'])
1307
 
        self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
1308
 
        self.assertTrue('sub-file2-id' in inv._fileid_to_entry_cache)
1309
 
 
1310
 
    def test_single_file(self):
1311
 
        inv = self.make_simple_inventory()
1312
 
        self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
1313
 
 
1314
 
    def test_get_all_parents(self):
1315
 
        inv = self.make_simple_inventory()
1316
 
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1317
 
                           'subsub-file1-id',
1318
 
                          ], inv, ['subsub-file1-id'])
1319
 
 
1320
 
    def test_get_children(self):
1321
 
        inv = self.make_simple_inventory()
1322
 
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1323
 
                           'sub-file1-id', 'sub-file2-id', 'subsub-file1-id',
1324
 
                          ], inv, ['dir1-id'])
1325
 
 
1326
 
    def test_from_root(self):
1327
 
        inv = self.make_simple_inventory()
1328
 
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'dir2-id', 'sub-dir1-id',
1329
 
                           'sub-file1-id', 'sub-file2-id', 'sub2-file1-id',
1330
 
                           'subsub-file1-id', 'top-id'], inv, ['TREE_ROOT'])
1331
 
 
1332
 
    def test_top_level_file(self):
1333
 
        inv = self.make_simple_inventory()
1334
 
        self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
1335
 
 
1336
 
    def test_subsub_file(self):
1337
 
        inv = self.make_simple_inventory()
1338
 
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1339
 
                           'subsub-file1-id'], inv, ['subsub-file1-id'])
1340
 
 
1341
 
    def test_sub_and_root(self):
1342
 
        inv = self.make_simple_inventory()
1343
 
        self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id', 'top-id',
1344
 
                           'subsub-file1-id'], inv, ['top-id', 'subsub-file1-id'])