89
def apply_inventory_WT(self, basis, delta):
90
"""Apply delta to basis and return the result.
92
This sets the tree state to be basis, and then calls apply_inventory_delta.
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.
98
control = self.make_bzrdir('tree', format=self.format._matchingbzrdir)
99
control.create_repository()
100
control.create_branch()
101
tree = self.format.initialize(control)
104
tree._write_inventory(basis)
107
# Fresh object, reads disk again.
108
tree = tree.bzrdir.open_workingtree()
111
tree.apply_inventory_delta(delta)
114
# reload tree - ensure we get what was written.
115
tree = tree.bzrdir.open_workingtree()
117
self.addCleanup(tree.unlock)
118
# One could add 'tree._validate' here but that would cause 'early' failues
119
# as far as higher level code is concerned. Possibly adding an
120
# expect_fail parameter to this function and if that is False then do a
122
return tree.inventory
125
74
def apply_inventory_WT_basis(self, basis, delta):
126
75
"""Apply delta to basis and return the result.
259
208
return repo.get_inventory('result')
262
class TestInventoryUpdates(TestCase):
264
def test_creation_from_root_id(self):
265
# iff a root id is passed to the constructor, a root directory is made
266
inv = inventory.Inventory(root_id='tree-root')
267
self.assertNotEqual(None, inv.root)
268
self.assertEqual('tree-root', inv.root.file_id)
270
def test_add_path_of_root(self):
271
# if no root id is given at creation time, there is no root directory
272
inv = inventory.Inventory(root_id=None)
273
self.assertIs(None, inv.root)
274
# add a root entry by adding its path
275
ie = inv.add_path("", "directory", "my-root")
276
ie.revision = 'test-rev'
277
self.assertEqual("my-root", ie.file_id)
278
self.assertIs(ie, inv.root)
280
def test_add_path(self):
281
inv = inventory.Inventory(root_id='tree_root')
282
ie = inv.add_path('hello', 'file', 'hello-id')
283
self.assertEqual('hello-id', ie.file_id)
284
self.assertEqual('file', ie.kind)
287
"""Make sure copy() works and creates a deep copy."""
288
inv = inventory.Inventory(root_id='some-tree-root')
289
ie = inv.add_path('hello', 'file', 'hello-id')
291
inv.root.file_id = 'some-new-root'
293
self.assertEqual('some-tree-root', inv2.root.file_id)
294
self.assertEqual('hello', inv2['hello-id'].name)
296
def test_copy_empty(self):
297
"""Make sure an empty inventory can be copied."""
298
inv = inventory.Inventory(root_id=None)
300
self.assertIs(None, inv2.root)
302
def test_copy_copies_root_revision(self):
303
"""Make sure the revision of the root gets copied."""
304
inv = inventory.Inventory(root_id='someroot')
305
inv.root.revision = 'therev'
307
self.assertEquals('someroot', inv2.root.file_id)
308
self.assertEquals('therev', inv2.root.revision)
310
def test_create_tree_reference(self):
311
inv = inventory.Inventory('tree-root-123')
312
inv.add(TreeReference('nested-id', 'nested', parent_id='tree-root-123',
313
revision='rev', reference_revision='rev2'))
315
def test_error_encoding(self):
316
inv = inventory.Inventory('tree-root')
317
inv.add(InventoryFile('a-id', u'\u1234', 'tree-root'))
318
e = self.assertRaises(errors.InconsistentDelta, inv.add,
319
InventoryFile('b-id', u'\u1234', 'tree-root'))
320
self.assertContainsRe(str(e), r'\\u1234')
322
def test_add_recursive(self):
323
parent = InventoryDirectory('src-id', 'src', 'tree-root')
324
child = InventoryFile('hello-id', 'hello.c', 'src-id')
325
parent.children[child.file_id] = child
326
inv = inventory.Inventory('tree-root')
328
self.assertEqual('src/hello.c', inv.id2path('hello-id'))
332
211
class TestDeltaApplication(TestCaseWithTransport):
334
213
def get_empty_inventory(self, reference_inv=None):
474
321
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
477
def test_new_parent_path_has_wrong_id(self):
478
inv = self.get_empty_inventory()
479
parent1 = inventory.InventoryDirectory('p-1', 'dir', inv.root.file_id)
480
parent1.revision = 'result'
481
parent2 = inventory.InventoryDirectory('p-2', 'dir2', inv.root.file_id)
482
parent2.revision = 'result'
483
file1 = inventory.InventoryFile('id', 'path', 'p-2')
484
file1.revision = 'result'
489
# This delta claims that file1 is at dir/path, but actually its at
490
# dir2/path if you follow the inventory parent structure.
491
delta = [(None, u'dir/path', 'id', file1)]
492
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
495
def test_old_parent_path_is_wrong(self):
496
inv = self.get_empty_inventory()
497
parent1 = inventory.InventoryDirectory('p-1', 'dir', inv.root.file_id)
498
parent1.revision = 'result'
499
parent2 = inventory.InventoryDirectory('p-2', 'dir2', inv.root.file_id)
500
parent2.revision = 'result'
501
file1 = inventory.InventoryFile('id', 'path', 'p-2')
502
file1.revision = 'result'
508
# This delta claims that file1 was at dir/path, but actually it was at
509
# dir2/path if you follow the inventory parent structure.
510
delta = [(u'dir/path', None, 'id', None)]
511
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
514
def test_old_parent_path_is_for_other_id(self):
515
inv = self.get_empty_inventory()
516
parent1 = inventory.InventoryDirectory('p-1', 'dir', inv.root.file_id)
517
parent1.revision = 'result'
518
parent2 = inventory.InventoryDirectory('p-2', 'dir2', inv.root.file_id)
519
parent2.revision = 'result'
520
file1 = inventory.InventoryFile('id', 'path', 'p-2')
521
file1.revision = 'result'
524
file2 = inventory.InventoryFile('id2', 'path', 'p-1')
525
file2.revision = 'result'
532
# This delta claims that file1 was at dir/path, but actually it was at
533
# dir2/path if you follow the inventory parent structure. At dir/path
534
# is another entry we should not delete.
535
delta = [(u'dir/path', None, 'id', None)]
536
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
539
def test_add_existing_id_new_path(self):
540
inv = self.get_empty_inventory()
541
parent1 = inventory.InventoryDirectory('p-1', 'dir1', inv.root.file_id)
542
parent1.revision = 'result'
543
parent2 = inventory.InventoryDirectory('p-1', 'dir2', inv.root.file_id)
544
parent2.revision = 'result'
546
delta = [(None, u'dir2', 'p-1', parent2)]
547
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
550
def test_add_new_id_existing_path(self):
551
inv = self.get_empty_inventory()
552
parent1 = inventory.InventoryDirectory('p-1', 'dir1', inv.root.file_id)
553
parent1.revision = 'result'
554
parent2 = inventory.InventoryDirectory('p-2', 'dir1', inv.root.file_id)
555
parent2.revision = 'result'
557
delta = [(None, u'dir1', 'p-2', parent2)]
558
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
561
def test_remove_dir_leaving_dangling_child(self):
562
inv = self.get_empty_inventory()
563
dir1 = inventory.InventoryDirectory('p-1', 'dir1', inv.root.file_id)
564
dir1.revision = 'result'
565
dir2 = inventory.InventoryDirectory('p-2', 'child1', 'p-1')
566
dir2.revision = 'result'
567
dir3 = inventory.InventoryDirectory('p-3', 'child2', 'p-1')
568
dir3.revision = 'result'
572
delta = [(u'dir1', None, 'p-1', None),
573
(u'dir1/child2', None, 'p-3', None)]
574
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
578
class TestInventory(TestCase):
580
def test_is_root(self):
581
"""Ensure our root-checking code is accurate."""
582
inv = inventory.Inventory('TREE_ROOT')
583
self.assertTrue(inv.is_root('TREE_ROOT'))
584
self.assertFalse(inv.is_root('booga'))
585
inv.root.file_id = 'booga'
586
self.assertFalse(inv.is_root('TREE_ROOT'))
587
self.assertTrue(inv.is_root('booga'))
588
# works properly even if no root is set
590
self.assertFalse(inv.is_root('TREE_ROOT'))
591
self.assertFalse(inv.is_root('booga'))
594
325
class TestInventoryEntry(TestCase):
1214
949
self.assertIsInstance(ie2.name, unicode)
1215
950
self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
1216
951
inv._bytes_to_utf8name_key(bytes))
1219
class TestCHKInventoryExpand(tests.TestCaseWithMemoryTransport):
1221
def get_chk_bytes(self):
1222
factory = groupcompress.make_pack_factory(True, True, 1)
1223
trans = self.get_transport('')
1224
return factory(trans)
1226
def make_dir(self, inv, name, parent_id):
1227
inv.add(inv.make_entry('directory', name, parent_id, name + '-id'))
1229
def make_file(self, inv, name, parent_id, content='content\n'):
1230
ie = inv.make_entry('file', name, parent_id, name + '-id')
1231
ie.text_sha1 = osutils.sha_string(content)
1232
ie.text_size = len(content)
1235
def make_simple_inventory(self):
1236
inv = Inventory('TREE_ROOT')
1237
inv.revision_id = "revid"
1238
inv.root.revision = "rootrev"
1241
# sub-file1 sub-file1-id
1242
# sub-file2 sub-file2-id
1243
# sub-dir1/ sub-dir1-id
1244
# subsub-file1 subsub-file1-id
1246
# sub2-file1 sub2-file1-id
1248
self.make_dir(inv, 'dir1', 'TREE_ROOT')
1249
self.make_dir(inv, 'dir2', 'TREE_ROOT')
1250
self.make_dir(inv, 'sub-dir1', 'dir1-id')
1251
self.make_file(inv, 'top', 'TREE_ROOT')
1252
self.make_file(inv, 'sub-file1', 'dir1-id')
1253
self.make_file(inv, 'sub-file2', 'dir1-id')
1254
self.make_file(inv, 'subsub-file1', 'sub-dir1-id')
1255
self.make_file(inv, 'sub2-file1', 'dir2-id')
1256
chk_bytes = self.get_chk_bytes()
1257
# use a small maximum_size to force internal paging structures
1258
chk_inv = CHKInventory.from_inventory(chk_bytes, inv,
1260
search_key_name='hash-255-way')
1261
bytes = ''.join(chk_inv.to_lines())
1262
return CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1264
def assert_Getitems(self, expected_fileids, inv, file_ids):
1265
self.assertEqual(sorted(expected_fileids),
1266
sorted([ie.file_id for ie in inv._getitems(file_ids)]))
1268
def assertExpand(self, all_ids, inv, file_ids):
1270
val_children) = inv._expand_fileids_to_parents_and_children(file_ids)
1271
self.assertEqual(set(all_ids), val_all_ids)
1272
entries = inv._getitems(val_all_ids)
1273
expected_children = {}
1274
for entry in entries:
1275
s = expected_children.setdefault(entry.parent_id, [])
1276
s.append(entry.file_id)
1277
val_children = dict((k, sorted(v)) for k, v
1278
in val_children.iteritems())
1279
expected_children = dict((k, sorted(v)) for k, v
1280
in expected_children.iteritems())
1281
self.assertEqual(expected_children, val_children)
1283
def test_make_simple_inventory(self):
1284
inv = self.make_simple_inventory()
1286
for path, entry in inv.iter_entries_by_dir():
1287
layout.append((path, entry.file_id))
1290
('dir1', 'dir1-id'),
1291
('dir2', 'dir2-id'),
1293
('dir1/sub-dir1', 'sub-dir1-id'),
1294
('dir1/sub-file1', 'sub-file1-id'),
1295
('dir1/sub-file2', 'sub-file2-id'),
1296
('dir1/sub-dir1/subsub-file1', 'subsub-file1-id'),
1297
('dir2/sub2-file1', 'sub2-file1-id'),
1300
def test__getitems(self):
1301
inv = self.make_simple_inventory()
1303
self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
1304
self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
1305
self.assertFalse('sub-file2-id' in inv._fileid_to_entry_cache)
1307
self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
1309
self.assert_Getitems(['dir1-id', 'sub-file2-id'], inv,
1310
['dir1-id', 'sub-file2-id'])
1311
self.assertTrue('dir1-id' in inv._fileid_to_entry_cache)
1312
self.assertTrue('sub-file2-id' in inv._fileid_to_entry_cache)
1314
def test_single_file(self):
1315
inv = self.make_simple_inventory()
1316
self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
1318
def test_get_all_parents(self):
1319
inv = self.make_simple_inventory()
1320
self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1322
], inv, ['subsub-file1-id'])
1324
def test_get_children(self):
1325
inv = self.make_simple_inventory()
1326
self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1327
'sub-file1-id', 'sub-file2-id', 'subsub-file1-id',
1328
], inv, ['dir1-id'])
1330
def test_from_root(self):
1331
inv = self.make_simple_inventory()
1332
self.assertExpand(['TREE_ROOT', 'dir1-id', 'dir2-id', 'sub-dir1-id',
1333
'sub-file1-id', 'sub-file2-id', 'sub2-file1-id',
1334
'subsub-file1-id', 'top-id'], inv, ['TREE_ROOT'])
1336
def test_top_level_file(self):
1337
inv = self.make_simple_inventory()
1338
self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
1340
def test_subsub_file(self):
1341
inv = self.make_simple_inventory()
1342
self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1343
'subsub-file1-id'], inv, ['subsub-file1-id'])
1345
def test_sub_and_root(self):
1346
inv = self.make_simple_inventory()
1347
self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id', 'top-id',
1348
'subsub-file1-id'], inv, ['top-id', 'subsub-file1-id'])