130
194
allow safety checks made by the WT to succeed, and finally ensures that all
131
195
items in the delta with a new path are present in the WT before calling
132
196
update_basis_by_delta.
134
198
:param basis: An inventory to be used as the basis.
135
199
:param delta: The inventory delta to apply:
136
200
:return: An inventory resulting from the application.
138
control = self.make_bzrdir('tree', format=self.format._matchingbzrdir)
202
control = test.make_controldir(
203
'tree', format=test.format._matchingcontroldir)
139
204
control.create_repository()
140
205
control.create_branch()
141
tree = self.format.initialize(control)
206
tree = test.format.initialize(control)
142
207
tree.lock_write()
144
repo = tree.branch.repository
145
repo.start_write_group()
147
rev = revision.Revision('basis', timestamp=0, timezone=None,
148
message="", committer="foo@example.com")
149
basis.revision_id = 'basis'
150
create_texts_for_inv(tree.branch.repository, basis)
151
repo.add_revision('basis', rev, basis)
152
# Add a revision for the result, with the basis content -
153
# update_basis_by_delta doesn't check that the delta results in
154
# result, and we want inconsistent deltas to get called on the
155
# tree, or else the code isn't actually checked.
156
rev = revision.Revision('result', timestamp=0, timezone=None,
157
message="", committer="foo@example.com")
158
basis.revision_id = 'result'
159
repo.add_revision('result', rev, basis)
160
repo.commit_write_group()
162
repo.abort_write_group()
209
target_entries = _create_repo_revisions(tree.branch.repository, basis,
210
delta, invalid_delta)
164
211
# Set the basis state as the trees current state
165
212
tree._write_inventory(basis)
166
213
# This reads basis from the repo and puts it into the tree's local
167
214
# cache, if it has one.
168
tree.set_parent_ids(['basis'])
171
for old, new, id, entry in delta:
172
if None in (new, entry):
174
paths[new] = (entry.file_id, entry.kind)
175
parents.add(osutils.dirname(new))
176
parents = osutils.minimum_path_selection(parents)
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"])
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()):
190
tree.add([path], [file_id], [kind])
191
except (KeyboardInterrupt, SystemExit):
215
tree.set_parent_ids([b'basis'])
197
218
# Fresh lock, reads disk again.
200
tree.update_basis_by_delta('result', delta)
219
with tree.lock_write():
220
tree.update_basis_by_delta(b'result', delta)
221
if not invalid_delta:
203
223
# reload tree - ensure we get what was written.
204
tree = tree.bzrdir.open_workingtree()
224
tree = tree.controldir.open_workingtree()
205
225
basis_tree = tree.basis_tree()
206
226
basis_tree.lock_read()
207
self.addCleanup(basis_tree.unlock)
208
# Note, that if the tree does not have a local cache, the trick above of
209
# setting the result as the basis, will come back to bite us. That said,
210
# all the implementations in bzr do have a local cache.
211
return basis_tree.inventory
214
def apply_inventory_Repository_add_inventory_by_delta(self, basis, delta):
227
test.addCleanup(basis_tree.unlock)
228
basis_inv = basis_tree.root_inventory
230
basis_entries = list(basis_inv.iter_entries_by_dir())
231
test.assertEqual(target_entries, basis_entries)
235
def apply_inventory_Repository_add_inventory_by_delta(self, basis, delta,
215
237
"""Apply delta to basis and return the result.
217
239
This inserts basis as a whole inventory and then uses
218
240
add_inventory_by_delta to add delta.
222
244
:return: An inventory resulting from the application.
224
246
format = self.format()
225
control = self.make_bzrdir('tree', format=format._matchingbzrdir)
247
control = self.make_controldir('tree', format=format._matchingcontroldir)
226
248
repo = format.initialize(control)
229
repo.start_write_group()
231
rev = revision.Revision('basis', timestamp=0, timezone=None,
232
message="", committer="foo@example.com")
233
basis.revision_id = 'basis'
234
create_texts_for_inv(repo, basis)
235
repo.add_revision('basis', rev, basis)
236
repo.commit_write_group()
238
repo.abort_write_group()
244
repo.start_write_group()
246
inv_sha1 = repo.add_inventory_by_delta('basis', delta,
249
repo.abort_write_group()
252
repo.commit_write_group()
249
with repo.lock_write(), repository.WriteGroup(repo):
250
rev = revision.Revision(
251
b'basis', timestamp=0, timezone=None, message="",
252
committer="foo@example.com")
253
basis.revision_id = b'basis'
254
create_texts_for_inv(repo, basis)
255
repo.add_revision(b'basis', rev, basis)
256
with repo.lock_write(), repository.WriteGroup(repo):
257
inv_sha1 = repo.add_inventory_by_delta(
258
b'basis', delta, b'result', [b'basis'])
255
259
# Fresh lock, reads disk again.
256
repo = repo.bzrdir.open_repository()
260
repo = repo.controldir.open_repository()
258
262
self.addCleanup(repo.unlock)
259
return repo.get_inventory('result')
263
return repo.get_inventory(b'result')
262
266
class TestInventoryUpdates(TestCase):
264
268
def test_creation_from_root_id(self):
265
269
# iff a root id is passed to the constructor, a root directory is made
266
inv = inventory.Inventory(root_id='tree-root')
270
inv = inventory.Inventory(root_id=b'tree-root')
267
271
self.assertNotEqual(None, inv.root)
268
self.assertEqual('tree-root', inv.root.file_id)
272
self.assertEqual(b'tree-root', inv.root.file_id)
270
274
def test_add_path_of_root(self):
271
275
# if no root id is given at creation time, there is no root directory
272
276
inv = inventory.Inventory(root_id=None)
273
277
self.assertIs(None, inv.root)
274
278
# 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)
279
ie = inv.add_path(u"", "directory", b"my-root")
280
ie.revision = b'test-rev'
281
self.assertEqual(b"my-root", ie.file_id)
278
282
self.assertIs(ie, inv.root)
280
284
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)
285
inv = inventory.Inventory(root_id=b'tree_root')
286
ie = inv.add_path(u'hello', 'file', b'hello-id')
287
self.assertEqual(b'hello-id', ie.file_id)
284
288
self.assertEqual('file', ie.kind)
286
290
def test_copy(self):
287
291
"""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')
292
inv = inventory.Inventory(root_id=b'some-tree-root')
293
ie = inv.add_path(u'hello', 'file', b'hello-id')
290
294
inv2 = inv.copy()
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)
295
inv.root.file_id = b'some-new-root'
297
self.assertEqual(b'some-tree-root', inv2.root.file_id)
298
self.assertEqual(u'hello', inv2.get_entry(b'hello-id').name)
296
300
def test_copy_empty(self):
297
301
"""Make sure an empty inventory can be copied."""
360
373
def test_None_file_id(self):
361
374
inv = self.get_empty_inventory()
362
dir1 = inventory.InventoryDirectory(None, 'dir1', inv.root.file_id)
363
dir1.revision = 'result'
375
dir1 = inventory.InventoryDirectory(b'dirid', 'dir1', inv.root.file_id)
377
dir1.revision = b'result'
364
378
delta = [(None, u'dir1', None, dir1)]
365
379
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
368
382
def test_unicode_file_id(self):
369
383
inv = self.get_empty_inventory()
370
dir1 = inventory.InventoryDirectory(u'dirid', 'dir1', inv.root.file_id)
371
dir1.revision = 'result'
384
dir1 = inventory.InventoryDirectory(b'dirid', 'dir1', inv.root.file_id)
385
dir1.file_id = u'dirid'
386
dir1.revision = b'result'
372
387
delta = [(None, u'dir1', dir1.file_id, dir1)]
373
388
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
376
391
def test_repeated_file_id(self):
377
392
inv = self.get_empty_inventory()
378
file1 = inventory.InventoryFile('id', 'path1', inv.root.file_id)
379
file1.revision = 'result'
393
file1 = inventory.InventoryFile(b'id', 'path1', inv.root.file_id)
394
file1.revision = b'result'
380
395
file1.text_size = 0
382
file2 = inventory.InventoryFile('id', 'path2', inv.root.file_id)
383
file2.revision = 'result'
386
delta = [(None, u'path1', 'id', file1), (None, u'path2', 'id', file2)]
396
file1.text_sha1 = b""
399
delta = [(None, u'path1', b'id', file1),
400
(None, u'path2', b'id', file2)]
387
401
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
390
404
def test_repeated_new_path(self):
391
405
inv = self.get_empty_inventory()
392
file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
393
file1.revision = 'result'
406
file1 = inventory.InventoryFile(b'id1', 'path', inv.root.file_id)
407
file1.revision = b'result'
394
408
file1.text_size = 0
396
file2 = inventory.InventoryFile('id2', 'path', inv.root.file_id)
397
file2.revision = 'result'
400
delta = [(None, u'path', 'id1', file1), (None, u'path', 'id2', file2)]
409
file1.text_sha1 = b""
411
file2.file_id = b'id2'
412
delta = [(None, u'path', b'id1', file1),
413
(None, u'path', b'id2', file2)]
401
414
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
404
417
def test_repeated_old_path(self):
405
418
inv = self.get_empty_inventory()
406
file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
407
file1.revision = 'result'
419
file1 = inventory.InventoryFile(b'id1', 'path', inv.root.file_id)
420
file1.revision = b'result'
408
421
file1.text_size = 0
422
file1.text_sha1 = b""
410
423
# We can't *create* a source inventory with the same path, but
411
424
# a badly generated partial delta might claim the same source twice.
412
425
# This would be buggy in two ways: the path is repeated in the delta,
413
426
# And the path for one of the file ids doesn't match the source
414
427
# location. Alternatively, we could have a repeated fileid, but that
415
428
# is separately checked for.
416
file2 = inventory.InventoryFile('id2', 'path2', inv.root.file_id)
417
file2.revision = 'result'
429
file2 = inventory.InventoryFile(b'id2', 'path2', inv.root.file_id)
430
file2.revision = b'result'
418
431
file2.text_size = 0
432
file2.text_sha1 = b""
422
delta = [(u'path', None, 'id1', None), (u'path', None, 'id2', None)]
435
delta = [(u'path', None, b'id1', None), (u'path', None, b'id2', None)]
423
436
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
426
439
def test_mismatched_id_entry_id(self):
427
440
inv = self.get_empty_inventory()
428
file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
429
file1.revision = 'result'
441
file1 = inventory.InventoryFile(b'id1', 'path', inv.root.file_id)
442
file1.revision = b'result'
430
443
file1.text_size = 0
432
delta = [(None, u'path', 'id', file1)]
444
file1.text_sha1 = b""
445
delta = [(None, u'path', b'id', file1)]
433
446
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
436
449
def test_mismatched_new_path_entry_None(self):
437
450
inv = self.get_empty_inventory()
438
delta = [(None, u'path', 'id', None)]
451
delta = [(None, u'path', b'id', None)]
439
452
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
442
455
def test_mismatched_new_path_None_entry(self):
443
456
inv = self.get_empty_inventory()
444
file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
445
file1.revision = 'result'
457
file1 = inventory.InventoryFile(b'id1', 'path', inv.root.file_id)
458
file1.revision = b'result'
446
459
file1.text_size = 0
448
delta = [(u"path", None, 'id1', file1)]
460
file1.text_sha1 = b""
461
delta = [(u"path", None, b'id1', file1)]
449
462
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
452
465
def test_parent_is_not_directory(self):
453
466
inv = self.get_empty_inventory()
454
file1 = inventory.InventoryFile('id1', 'path', inv.root.file_id)
455
file1.revision = 'result'
467
file1 = inventory.InventoryFile(b'id1', 'path', inv.root.file_id)
468
file1.revision = b'result'
456
469
file1.text_size = 0
458
file2 = inventory.InventoryFile('id2', 'path2', 'id1')
459
file2.revision = 'result'
470
file1.text_sha1 = b""
471
file2 = inventory.InventoryFile(b'id2', 'path2', b'id1')
472
file2.revision = b'result'
460
473
file2.text_size = 0
474
file2.text_sha1 = b""
463
delta = [(None, u'path/path2', 'id2', file2)]
476
delta = [(None, u'path/path2', b'id2', file2)]
464
477
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
467
480
def test_parent_is_missing(self):
468
481
inv = self.get_empty_inventory()
469
file2 = inventory.InventoryFile('id2', 'path2', 'missingparent')
470
file2.revision = 'result'
482
file2 = inventory.InventoryFile(b'id2', 'path2', b'missingparent')
483
file2.revision = b'result'
471
484
file2.text_size = 0
473
delta = [(None, u'path/path2', 'id2', file2)]
485
file2.text_sha1 = b""
486
delta = [(None, u'path/path2', b'id2', file2)]
474
487
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
477
490
def test_new_parent_path_has_wrong_id(self):
478
491
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'
492
parent1 = inventory.InventoryDirectory(b'p-1', 'dir', inv.root.file_id)
493
parent1.revision = b'result'
494
parent2 = inventory.InventoryDirectory(
495
b'p-2', 'dir2', inv.root.file_id)
496
parent2.revision = b'result'
497
file1 = inventory.InventoryFile(b'id', 'path', b'p-2')
498
file1.revision = b'result'
485
499
file1.text_size = 0
500
file1.text_sha1 = b""
489
503
# This delta claims that file1 is at dir/path, but actually its at
490
504
# dir2/path if you follow the inventory parent structure.
491
delta = [(None, u'dir/path', 'id', file1)]
505
delta = [(None, u'dir/path', b'id', file1)]
492
506
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
495
509
def test_old_parent_path_is_wrong(self):
496
510
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'
511
parent1 = inventory.InventoryDirectory(b'p-1', 'dir', inv.root.file_id)
512
parent1.revision = b'result'
513
parent2 = inventory.InventoryDirectory(
514
b'p-2', 'dir2', inv.root.file_id)
515
parent2.revision = b'result'
516
file1 = inventory.InventoryFile(b'id', 'path', b'p-2')
517
file1.revision = b'result'
503
518
file1.text_size = 0
519
file1.text_sha1 = b""
508
523
# This delta claims that file1 was at dir/path, but actually it was at
509
524
# dir2/path if you follow the inventory parent structure.
510
delta = [(u'dir/path', None, 'id', None)]
525
delta = [(u'dir/path', None, b'id', None)]
511
526
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
514
529
def test_old_parent_path_is_for_other_id(self):
515
530
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'
531
parent1 = inventory.InventoryDirectory(b'p-1', 'dir', inv.root.file_id)
532
parent1.revision = b'result'
533
parent2 = inventory.InventoryDirectory(
534
b'p-2', 'dir2', inv.root.file_id)
535
parent2.revision = b'result'
536
file1 = inventory.InventoryFile(b'id', 'path', b'p-2')
537
file1.revision = b'result'
522
538
file1.text_size = 0
524
file2 = inventory.InventoryFile('id2', 'path', 'p-1')
525
file2.revision = 'result'
539
file1.text_sha1 = b""
540
file2 = inventory.InventoryFile(b'id2', 'path', b'p-1')
541
file2.revision = b'result'
526
542
file2.text_size = 0
543
file2.text_sha1 = b""
532
548
# This delta claims that file1 was at dir/path, but actually it was at
533
549
# dir2/path if you follow the inventory parent structure. At dir/path
534
550
# is another entry we should not delete.
535
delta = [(u'dir/path', None, 'id', None)]
551
delta = [(u'dir/path', None, b'id', None)]
536
552
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
539
555
def test_add_existing_id_new_path(self):
540
556
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'
557
parent1 = inventory.InventoryDirectory(
558
b'p-1', 'dir1', inv.root.file_id)
559
parent1.revision = b'result'
560
parent2 = inventory.InventoryDirectory(
561
b'p-1', 'dir2', inv.root.file_id)
562
parent2.revision = b'result'
546
delta = [(None, u'dir2', 'p-1', parent2)]
564
delta = [(None, u'dir2', b'p-1', parent2)]
547
565
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
550
568
def test_add_new_id_existing_path(self):
551
569
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'
570
parent1 = inventory.InventoryDirectory(
571
b'p-1', 'dir1', inv.root.file_id)
572
parent1.revision = b'result'
573
parent2 = inventory.InventoryDirectory(
574
b'p-2', 'dir1', inv.root.file_id)
575
parent2.revision = b'result'
557
delta = [(None, u'dir1', 'p-2', parent2)]
577
delta = [(None, u'dir1', b'p-2', parent2)]
558
578
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
561
581
def test_remove_dir_leaving_dangling_child(self):
562
582
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'
583
dir1 = inventory.InventoryDirectory(b'p-1', 'dir1', inv.root.file_id)
584
dir1.revision = b'result'
585
dir2 = inventory.InventoryDirectory(b'p-2', 'child1', b'p-1')
586
dir2.revision = b'result'
587
dir3 = inventory.InventoryDirectory(b'p-3', 'child2', b'p-1')
588
dir3.revision = b'result'
572
delta = [(u'dir1', None, 'p-1', None),
573
(u'dir1/child2', None, 'p-3', None)]
592
delta = [(u'dir1', None, b'p-1', None),
593
(u'dir1/child2', None, b'p-3', None)]
574
594
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
578
class TestInventory(TestCase):
597
def test_add_file(self):
598
inv = self.get_empty_inventory()
599
file1 = inventory.InventoryFile(b'file-id', 'path', inv.root.file_id)
600
file1.revision = b'result'
602
file1.text_sha1 = b''
603
delta = [(None, u'path', b'file-id', file1)]
604
res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
605
self.assertEqual(b'file-id', res_inv.get_entry(b'file-id').file_id)
607
def test_remove_file(self):
608
inv = self.get_empty_inventory()
609
file1 = inventory.InventoryFile(b'file-id', 'path', inv.root.file_id)
610
file1.revision = b'result'
612
file1.text_sha1 = b''
614
delta = [(u'path', None, b'file-id', None)]
615
res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
616
self.assertEqual(None, res_inv.path2id('path'))
617
self.assertRaises(errors.NoSuchId, res_inv.id2path, b'file-id')
619
def test_rename_file(self):
620
inv = self.get_empty_inventory()
621
file1 = self.make_file_ie(name='path', parent_id=inv.root.file_id)
623
file2 = self.make_file_ie(name='path2', parent_id=inv.root.file_id)
624
delta = [(u'path', 'path2', b'file-id', file2)]
625
res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
626
self.assertEqual(None, res_inv.path2id('path'))
627
self.assertEqual(b'file-id', res_inv.path2id('path2'))
629
def test_replaced_at_new_path(self):
630
inv = self.get_empty_inventory()
631
file1 = self.make_file_ie(file_id=b'id1', parent_id=inv.root.file_id)
633
file2 = self.make_file_ie(file_id=b'id2', parent_id=inv.root.file_id)
634
delta = [(u'name', None, b'id1', None),
635
(None, u'name', b'id2', file2)]
636
res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
637
self.assertEqual(b'id2', res_inv.path2id('name'))
639
def test_rename_dir(self):
640
inv = self.get_empty_inventory()
641
dir1 = inventory.InventoryDirectory(
642
b'dir-id', 'dir1', inv.root.file_id)
643
dir1.revision = b'basis'
644
file1 = self.make_file_ie(parent_id=b'dir-id')
647
dir2 = inventory.InventoryDirectory(
648
b'dir-id', 'dir2', inv.root.file_id)
649
dir2.revision = b'result'
650
delta = [('dir1', 'dir2', b'dir-id', dir2)]
651
res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
652
# The file should be accessible under the new path
653
self.assertEqual(b'file-id', res_inv.path2id('dir2/name'))
655
def test_renamed_dir_with_renamed_child(self):
656
inv = self.get_empty_inventory()
657
dir1 = inventory.InventoryDirectory(
658
b'dir-id', 'dir1', inv.root.file_id)
659
dir1.revision = b'basis'
660
file1 = self.make_file_ie(b'file-id-1', 'name1', parent_id=b'dir-id')
661
file2 = self.make_file_ie(b'file-id-2', 'name2', parent_id=b'dir-id')
665
dir2 = inventory.InventoryDirectory(
666
b'dir-id', 'dir2', inv.root.file_id)
667
dir2.revision = b'result'
668
file2b = self.make_file_ie(b'file-id-2', 'name2', inv.root.file_id)
669
delta = [('dir1', 'dir2', b'dir-id', dir2),
670
('dir1/name2', 'name2', b'file-id-2', file2b)]
671
res_inv = self.apply_delta(self, inv, delta, invalid_delta=False)
672
# The file should be accessible under the new path
673
self.assertEqual(b'file-id-1', res_inv.path2id('dir2/name1'))
674
self.assertEqual(None, res_inv.path2id('dir2/name2'))
675
self.assertEqual(b'file-id-2', res_inv.path2id('name2'))
580
677
def test_is_root(self):
581
678
"""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'))
679
inv = inventory.Inventory(b'TREE_ROOT')
680
self.assertTrue(inv.is_root(b'TREE_ROOT'))
681
self.assertFalse(inv.is_root(b'booga'))
682
inv.root.file_id = b'booga'
683
self.assertFalse(inv.is_root(b'TREE_ROOT'))
684
self.assertTrue(inv.is_root(b'booga'))
588
685
# works properly even if no root is set
590
self.assertFalse(inv.is_root('TREE_ROOT'))
591
self.assertFalse(inv.is_root('booga'))
687
self.assertFalse(inv.is_root(b'TREE_ROOT'))
688
self.assertFalse(inv.is_root(b'booga'))
690
def test_entries_for_empty_inventory(self):
691
"""Test that entries() will not fail for an empty inventory"""
692
inv = Inventory(root_id=None)
693
self.assertEqual([], inv.entries())
594
696
class TestInventoryEntry(TestCase):
698
def test_file_invalid_entry_name(self):
699
self.assertRaises(errors.InvalidEntryName, inventory.InventoryFile,
700
b'123', 'a/hello.c', ROOT_ID)
702
def test_file_backslash(self):
703
file = inventory.InventoryFile(b'123', 'h\\ello.c', ROOT_ID)
704
self.assertEquals(file.name, 'h\\ello.c')
596
706
def test_file_kind_character(self):
597
file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
707
file = inventory.InventoryFile(b'123', 'hello.c', ROOT_ID)
598
708
self.assertEqual(file.kind_character(), '')
600
710
def test_dir_kind_character(self):
601
dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
711
dir = inventory.InventoryDirectory(b'123', 'hello.c', ROOT_ID)
602
712
self.assertEqual(dir.kind_character(), '/')
604
714
def test_link_kind_character(self):
605
dir = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
715
dir = inventory.InventoryLink(b'123', 'hello.c', ROOT_ID)
606
716
self.assertEqual(dir.kind_character(), '')
718
def test_link_kind_character(self):
719
dir = TreeReference(b'123', 'hello.c', ROOT_ID)
720
self.assertEqual(dir.kind_character(), '+')
608
722
def test_dir_detect_changes(self):
609
left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
611
left.executable = True
612
left.symlink_target='foo'
613
right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
614
right.text_sha1 = 321
615
right.symlink_target='bar'
723
left = inventory.InventoryDirectory(b'123', 'hello.c', ROOT_ID)
724
right = inventory.InventoryDirectory(b'123', 'hello.c', ROOT_ID)
616
725
self.assertEqual((False, False), left.detect_changes(right))
617
726
self.assertEqual((False, False), right.detect_changes(left))
619
728
def test_file_detect_changes(self):
620
left = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
729
left = inventory.InventoryFile(b'123', 'hello.c', ROOT_ID)
621
730
left.text_sha1 = 123
622
right = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
731
right = inventory.InventoryFile(b'123', 'hello.c', ROOT_ID)
623
732
right.text_sha1 = 123
624
733
self.assertEqual((False, False), left.detect_changes(right))
625
734
self.assertEqual((False, False), right.detect_changes(left))
748
854
def read_bytes(self, chk_bytes, key):
749
855
stream = chk_bytes.get_record_stream([key], 'unordered', True)
750
return stream.next().get_bytes_as("fulltext")
856
return next(stream).get_bytes_as("fulltext")
752
858
def test_deserialise_gives_CHKInventory(self):
753
859
inv = Inventory()
754
inv.revision_id = "revid"
755
inv.root.revision = "rootrev"
860
inv.revision_id = b"revid"
861
inv.root.revision = b"rootrev"
756
862
chk_bytes = self.get_chk_bytes()
757
863
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
758
bytes = ''.join(chk_inv.to_lines())
759
new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
760
self.assertEqual("revid", new_inv.revision_id)
864
lines = chk_inv.to_lines()
865
new_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
866
self.assertEqual(b"revid", new_inv.revision_id)
761
867
self.assertEqual("directory", new_inv.root.kind)
762
868
self.assertEqual(inv.root.file_id, new_inv.root.file_id)
763
869
self.assertEqual(inv.root.parent_id, new_inv.root.parent_id)
764
870
self.assertEqual(inv.root.name, new_inv.root.name)
765
self.assertEqual("rootrev", new_inv.root.revision)
766
self.assertEqual('plain', new_inv._search_key_name)
871
self.assertEqual(b"rootrev", new_inv.root.revision)
872
self.assertEqual(b'plain', new_inv._search_key_name)
768
874
def test_deserialise_wrong_revid(self):
769
875
inv = Inventory()
770
inv.revision_id = "revid"
771
inv.root.revision = "rootrev"
876
inv.revision_id = b"revid"
877
inv.root.revision = b"rootrev"
772
878
chk_bytes = self.get_chk_bytes()
773
879
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
774
bytes = ''.join(chk_inv.to_lines())
880
lines = chk_inv.to_lines()
775
881
self.assertRaises(ValueError, CHKInventory.deserialise, chk_bytes,
778
884
def test_captures_rev_root_byid(self):
779
885
inv = Inventory()
780
inv.revision_id = "foo"
781
inv.root.revision = "bar"
886
inv.revision_id = b"foo"
887
inv.root.revision = b"bar"
782
888
chk_bytes = self.get_chk_bytes()
783
889
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
784
890
lines = chk_inv.to_lines()
785
891
self.assertEqual([
787
'revision_id: foo\n',
788
'root_id: TREE_ROOT\n',
789
'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
790
'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
893
b'revision_id: foo\n',
894
b'root_id: TREE_ROOT\n',
895
b'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
896
b'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
792
chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
793
self.assertEqual('plain', chk_inv._search_key_name)
898
chk_inv = CHKInventory.deserialise(
899
chk_bytes, lines, (b'foo',))
900
self.assertEqual(b'plain', chk_inv._search_key_name)
795
902
def test_captures_parent_id_basename_index(self):
796
903
inv = Inventory()
797
inv.revision_id = "foo"
798
inv.root.revision = "bar"
904
inv.revision_id = b"foo"
905
inv.root.revision = b"bar"
799
906
chk_bytes = self.get_chk_bytes()
800
907
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
801
908
lines = chk_inv.to_lines()
802
909
self.assertEqual([
804
'revision_id: foo\n',
805
'root_id: TREE_ROOT\n',
806
'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
807
'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
911
b'revision_id: foo\n',
912
b'root_id: TREE_ROOT\n',
913
b'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
914
b'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
809
chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
810
self.assertEqual('plain', chk_inv._search_key_name)
916
chk_inv = CHKInventory.deserialise(
917
chk_bytes, lines, (b'foo',))
918
self.assertEqual(b'plain', chk_inv._search_key_name)
812
920
def test_captures_search_key_name(self):
813
921
inv = Inventory()
814
inv.revision_id = "foo"
815
inv.root.revision = "bar"
922
inv.revision_id = b"foo"
923
inv.root.revision = b"bar"
816
924
chk_bytes = self.get_chk_bytes()
817
925
chk_inv = CHKInventory.from_inventory(chk_bytes, inv,
818
search_key_name='hash-16-way')
926
search_key_name=b'hash-16-way')
819
927
lines = chk_inv.to_lines()
820
928
self.assertEqual([
822
'search_key_name: hash-16-way\n',
823
'root_id: TREE_ROOT\n',
824
'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
825
'revision_id: foo\n',
826
'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
930
b'search_key_name: hash-16-way\n',
931
b'root_id: TREE_ROOT\n',
932
b'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
933
b'revision_id: foo\n',
934
b'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
828
chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
829
self.assertEqual('hash-16-way', chk_inv._search_key_name)
936
chk_inv = CHKInventory.deserialise(
937
chk_bytes, lines, (b'foo',))
938
self.assertEqual(b'hash-16-way', chk_inv._search_key_name)
831
940
def test_directory_children_on_demand(self):
832
941
inv = Inventory()
833
inv.revision_id = "revid"
834
inv.root.revision = "rootrev"
835
inv.add(InventoryFile("fileid", "file", inv.root.file_id))
836
inv["fileid"].revision = "filerev"
837
inv["fileid"].executable = True
838
inv["fileid"].text_sha1 = "ffff"
839
inv["fileid"].text_size = 1
942
inv.revision_id = b"revid"
943
inv.root.revision = b"rootrev"
944
inv.add(InventoryFile(b"fileid", "file", inv.root.file_id))
945
inv.get_entry(b"fileid").revision = b"filerev"
946
inv.get_entry(b"fileid").executable = True
947
inv.get_entry(b"fileid").text_sha1 = b"ffff"
948
inv.get_entry(b"fileid").text_size = 1
840
949
chk_bytes = self.get_chk_bytes()
841
950
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
842
bytes = ''.join(chk_inv.to_lines())
843
new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
844
root_entry = new_inv[inv.root.file_id]
951
lines = chk_inv.to_lines()
952
new_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
953
root_entry = new_inv.get_entry(inv.root.file_id)
845
954
self.assertEqual(None, root_entry._children)
846
self.assertEqual(['file'], root_entry.children.keys())
847
file_direct = new_inv["fileid"]
955
self.assertEqual({'file'}, set(root_entry.children))
956
file_direct = new_inv.get_entry(b"fileid")
848
957
file_found = root_entry.children['file']
849
958
self.assertEqual(file_direct.kind, file_found.kind)
850
959
self.assertEqual(file_direct.file_id, file_found.file_id)
870
979
self.assertEqual(120, p_id_basename._root_node.maximum_size)
871
980
self.assertEqual(2, p_id_basename._root_node._key_width)
873
def test___iter__(self):
982
def test_iter_all_ids(self):
874
983
inv = Inventory()
875
inv.revision_id = "revid"
876
inv.root.revision = "rootrev"
877
inv.add(InventoryFile("fileid", "file", inv.root.file_id))
878
inv["fileid"].revision = "filerev"
879
inv["fileid"].executable = True
880
inv["fileid"].text_sha1 = "ffff"
881
inv["fileid"].text_size = 1
984
inv.revision_id = b"revid"
985
inv.root.revision = b"rootrev"
986
inv.add(InventoryFile(b"fileid", "file", inv.root.file_id))
987
inv.get_entry(b"fileid").revision = b"filerev"
988
inv.get_entry(b"fileid").executable = True
989
inv.get_entry(b"fileid").text_sha1 = b"ffff"
990
inv.get_entry(b"fileid").text_size = 1
882
991
chk_bytes = self.get_chk_bytes()
883
992
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
884
bytes = ''.join(chk_inv.to_lines())
885
new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
886
fileids = list(new_inv.__iter__())
888
self.assertEqual([inv.root.file_id, "fileid"], fileids)
993
lines = chk_inv.to_lines()
994
new_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
995
fileids = sorted(new_inv.iter_all_ids())
996
self.assertEqual([inv.root.file_id, b"fileid"], fileids)
890
998
def test__len__(self):
891
999
inv = Inventory()
892
inv.revision_id = "revid"
893
inv.root.revision = "rootrev"
894
inv.add(InventoryFile("fileid", "file", inv.root.file_id))
895
inv["fileid"].revision = "filerev"
896
inv["fileid"].executable = True
897
inv["fileid"].text_sha1 = "ffff"
898
inv["fileid"].text_size = 1
1000
inv.revision_id = b"revid"
1001
inv.root.revision = b"rootrev"
1002
inv.add(InventoryFile(b"fileid", "file", inv.root.file_id))
1003
inv.get_entry(b"fileid").revision = b"filerev"
1004
inv.get_entry(b"fileid").executable = True
1005
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1006
inv.get_entry(b"fileid").text_size = 1
899
1007
chk_bytes = self.get_chk_bytes()
900
1008
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
901
1009
self.assertEqual(2, len(chk_inv))
903
def test___getitem__(self):
1011
def test_get_entry(self):
904
1012
inv = Inventory()
905
inv.revision_id = "revid"
906
inv.root.revision = "rootrev"
907
inv.add(InventoryFile("fileid", "file", inv.root.file_id))
908
inv["fileid"].revision = "filerev"
909
inv["fileid"].executable = True
910
inv["fileid"].text_sha1 = "ffff"
911
inv["fileid"].text_size = 1
1013
inv.revision_id = b"revid"
1014
inv.root.revision = b"rootrev"
1015
inv.add(InventoryFile(b"fileid", u"file", inv.root.file_id))
1016
inv.get_entry(b"fileid").revision = b"filerev"
1017
inv.get_entry(b"fileid").executable = True
1018
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1019
inv.get_entry(b"fileid").text_size = 1
912
1020
chk_bytes = self.get_chk_bytes()
913
1021
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
914
bytes = ''.join(chk_inv.to_lines())
915
new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
916
root_entry = new_inv[inv.root.file_id]
917
file_entry = new_inv["fileid"]
1022
lines = chk_inv.to_lines()
1023
new_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
1024
root_entry = new_inv.get_entry(inv.root.file_id)
1025
file_entry = new_inv.get_entry(b"fileid")
918
1026
self.assertEqual("directory", root_entry.kind)
919
1027
self.assertEqual(inv.root.file_id, root_entry.file_id)
920
1028
self.assertEqual(inv.root.parent_id, root_entry.parent_id)
921
1029
self.assertEqual(inv.root.name, root_entry.name)
922
self.assertEqual("rootrev", root_entry.revision)
1030
self.assertEqual(b"rootrev", root_entry.revision)
923
1031
self.assertEqual("file", file_entry.kind)
924
self.assertEqual("fileid", file_entry.file_id)
1032
self.assertEqual(b"fileid", file_entry.file_id)
925
1033
self.assertEqual(inv.root.file_id, file_entry.parent_id)
926
self.assertEqual("file", file_entry.name)
927
self.assertEqual("filerev", file_entry.revision)
928
self.assertEqual("ffff", file_entry.text_sha1)
1034
self.assertEqual(u"file", file_entry.name)
1035
self.assertEqual(b"filerev", file_entry.revision)
1036
self.assertEqual(b"ffff", file_entry.text_sha1)
929
1037
self.assertEqual(1, file_entry.text_size)
930
1038
self.assertEqual(True, file_entry.executable)
931
self.assertRaises(errors.NoSuchId, new_inv.__getitem__, 'missing')
1039
self.assertRaises(errors.NoSuchId, new_inv.get_entry, 'missing')
933
1041
def test_has_id_true(self):
934
1042
inv = Inventory()
935
inv.revision_id = "revid"
936
inv.root.revision = "rootrev"
937
inv.add(InventoryFile("fileid", "file", inv.root.file_id))
938
inv["fileid"].revision = "filerev"
939
inv["fileid"].executable = True
940
inv["fileid"].text_sha1 = "ffff"
941
inv["fileid"].text_size = 1
1043
inv.revision_id = b"revid"
1044
inv.root.revision = b"rootrev"
1045
inv.add(InventoryFile(b"fileid", "file", inv.root.file_id))
1046
inv.get_entry(b"fileid").revision = b"filerev"
1047
inv.get_entry(b"fileid").executable = True
1048
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1049
inv.get_entry(b"fileid").text_size = 1
942
1050
chk_bytes = self.get_chk_bytes()
943
1051
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
944
self.assertTrue(chk_inv.has_id('fileid'))
1052
self.assertTrue(chk_inv.has_id(b'fileid'))
945
1053
self.assertTrue(chk_inv.has_id(inv.root.file_id))
947
1055
def test_has_id_not(self):
948
1056
inv = Inventory()
949
inv.revision_id = "revid"
950
inv.root.revision = "rootrev"
1057
inv.revision_id = b"revid"
1058
inv.root.revision = b"rootrev"
951
1059
chk_bytes = self.get_chk_bytes()
952
1060
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
953
self.assertFalse(chk_inv.has_id('fileid'))
1061
self.assertFalse(chk_inv.has_id(b'fileid'))
955
1063
def test_id2path(self):
956
1064
inv = Inventory()
957
inv.revision_id = "revid"
958
inv.root.revision = "rootrev"
959
direntry = InventoryDirectory("dirid", "dir", inv.root.file_id)
960
fileentry = InventoryFile("fileid", "file", "dirid")
1065
inv.revision_id = b"revid"
1066
inv.root.revision = b"rootrev"
1067
direntry = InventoryDirectory(b"dirid", "dir", inv.root.file_id)
1068
fileentry = InventoryFile(b"fileid", "file", b"dirid")
961
1069
inv.add(direntry)
962
1070
inv.add(fileentry)
963
inv["fileid"].revision = "filerev"
964
inv["fileid"].executable = True
965
inv["fileid"].text_sha1 = "ffff"
966
inv["fileid"].text_size = 1
967
inv["dirid"].revision = "filerev"
1071
inv.get_entry(b"fileid").revision = b"filerev"
1072
inv.get_entry(b"fileid").executable = True
1073
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1074
inv.get_entry(b"fileid").text_size = 1
1075
inv.get_entry(b"dirid").revision = b"filerev"
968
1076
chk_bytes = self.get_chk_bytes()
969
1077
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
970
bytes = ''.join(chk_inv.to_lines())
971
new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1078
lines = chk_inv.to_lines()
1079
new_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
972
1080
self.assertEqual('', new_inv.id2path(inv.root.file_id))
973
self.assertEqual('dir', new_inv.id2path('dirid'))
974
self.assertEqual('dir/file', new_inv.id2path('fileid'))
1081
self.assertEqual('dir', new_inv.id2path(b'dirid'))
1082
self.assertEqual('dir/file', new_inv.id2path(b'fileid'))
976
1084
def test_path2id(self):
977
1085
inv = Inventory()
978
inv.revision_id = "revid"
979
inv.root.revision = "rootrev"
980
direntry = InventoryDirectory("dirid", "dir", inv.root.file_id)
981
fileentry = InventoryFile("fileid", "file", "dirid")
1086
inv.revision_id = b"revid"
1087
inv.root.revision = b"rootrev"
1088
direntry = InventoryDirectory(b"dirid", "dir", inv.root.file_id)
1089
fileentry = InventoryFile(b"fileid", "file", b"dirid")
982
1090
inv.add(direntry)
983
1091
inv.add(fileentry)
984
inv["fileid"].revision = "filerev"
985
inv["fileid"].executable = True
986
inv["fileid"].text_sha1 = "ffff"
987
inv["fileid"].text_size = 1
988
inv["dirid"].revision = "filerev"
1092
inv.get_entry(b"fileid").revision = b"filerev"
1093
inv.get_entry(b"fileid").executable = True
1094
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1095
inv.get_entry(b"fileid").text_size = 1
1096
inv.get_entry(b"dirid").revision = b"filerev"
989
1097
chk_bytes = self.get_chk_bytes()
990
1098
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
991
bytes = ''.join(chk_inv.to_lines())
992
new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1099
lines = chk_inv.to_lines()
1100
new_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
993
1101
self.assertEqual(inv.root.file_id, new_inv.path2id(''))
994
self.assertEqual('dirid', new_inv.path2id('dir'))
995
self.assertEqual('fileid', new_inv.path2id('dir/file'))
1102
self.assertEqual(b'dirid', new_inv.path2id('dir'))
1103
self.assertEqual(b'fileid', new_inv.path2id('dir/file'))
997
1105
def test_create_by_apply_delta_sets_root(self):
998
1106
inv = Inventory()
999
inv.revision_id = "revid"
1107
inv.root.revision = b"myrootrev"
1108
inv.revision_id = b"revid"
1000
1109
chk_bytes = self.get_chk_bytes()
1001
1110
base_inv = CHKInventory.from_inventory(chk_bytes, inv)
1002
inv.add_path("", "directory", "myrootid", None)
1003
inv.revision_id = "expectedid"
1111
inv.add_path("", "directory", b"myrootid", None)
1112
inv.revision_id = b"expectedid"
1113
inv.root.revision = b"myrootrev"
1004
1114
reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
1005
1115
delta = [("", None, base_inv.root.file_id, None),
1006
(None, "", "myrootid", inv.root)]
1007
new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
1008
self.assertEquals(reference_inv.root, new_inv.root)
1116
(None, "", b"myrootid", inv.root)]
1117
new_inv = base_inv.create_by_apply_delta(delta, b"expectedid")
1118
self.assertEqual(reference_inv.root, new_inv.root)
1010
1120
def test_create_by_apply_delta_empty_add_child(self):
1011
1121
inv = Inventory()
1012
inv.revision_id = "revid"
1013
inv.root.revision = "rootrev"
1122
inv.revision_id = b"revid"
1123
inv.root.revision = b"rootrev"
1014
1124
chk_bytes = self.get_chk_bytes()
1015
1125
base_inv = CHKInventory.from_inventory(chk_bytes, inv)
1016
a_entry = InventoryFile("A-id", "A", inv.root.file_id)
1017
a_entry.revision = "filerev"
1126
a_entry = InventoryFile(b"A-id", "A", inv.root.file_id)
1127
a_entry.revision = b"filerev"
1018
1128
a_entry.executable = True
1019
a_entry.text_sha1 = "ffff"
1129
a_entry.text_sha1 = b"ffff"
1020
1130
a_entry.text_size = 1
1021
1131
inv.add(a_entry)
1022
inv.revision_id = "expectedid"
1132
inv.revision_id = b"expectedid"
1023
1133
reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
1024
delta = [(None, "A", "A-id", a_entry)]
1025
new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
1134
delta = [(None, "A", b"A-id", a_entry)]
1135
new_inv = base_inv.create_by_apply_delta(delta, b"expectedid")
1026
1136
# new_inv should be the same as reference_inv.
1027
1137
self.assertEqual(reference_inv.revision_id, new_inv.revision_id)
1028
1138
self.assertEqual(reference_inv.root_id, new_inv.root_id)
1029
1139
reference_inv.id_to_entry._ensure_root()
1030
1140
new_inv.id_to_entry._ensure_root()
1031
1141
self.assertEqual(reference_inv.id_to_entry._root_node._key,
1032
new_inv.id_to_entry._root_node._key)
1142
new_inv.id_to_entry._root_node._key)
1034
1144
def test_create_by_apply_delta_empty_add_child_updates_parent_id(self):
1035
1145
inv = Inventory()
1036
inv.revision_id = "revid"
1037
inv.root.revision = "rootrev"
1146
inv.revision_id = b"revid"
1147
inv.root.revision = b"rootrev"
1038
1148
chk_bytes = self.get_chk_bytes()
1039
1149
base_inv = CHKInventory.from_inventory(chk_bytes, inv)
1040
a_entry = InventoryFile("A-id", "A", inv.root.file_id)
1041
a_entry.revision = "filerev"
1150
a_entry = InventoryFile(b"A-id", "A", inv.root.file_id)
1151
a_entry.revision = b"filerev"
1042
1152
a_entry.executable = True
1043
a_entry.text_sha1 = "ffff"
1153
a_entry.text_sha1 = b"ffff"
1044
1154
a_entry.text_size = 1
1045
1155
inv.add(a_entry)
1046
inv.revision_id = "expectedid"
1156
inv.revision_id = b"expectedid"
1047
1157
reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
1048
delta = [(None, "A", "A-id", a_entry)]
1049
new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
1158
delta = [(None, "A", b"A-id", a_entry)]
1159
new_inv = base_inv.create_by_apply_delta(delta, b"expectedid")
1050
1160
reference_inv.id_to_entry._ensure_root()
1051
1161
reference_inv.parent_id_basename_to_file_id._ensure_root()
1052
1162
new_inv.id_to_entry._ensure_root()
1055
1165
self.assertEqual(reference_inv.revision_id, new_inv.revision_id)
1056
1166
self.assertEqual(reference_inv.root_id, new_inv.root_id)
1057
1167
self.assertEqual(reference_inv.id_to_entry._root_node._key,
1058
new_inv.id_to_entry._root_node._key)
1168
new_inv.id_to_entry._root_node._key)
1059
1169
self.assertEqual(reference_inv.parent_id_basename_to_file_id._root_node._key,
1060
new_inv.parent_id_basename_to_file_id._root_node._key)
1170
new_inv.parent_id_basename_to_file_id._root_node._key)
1062
1172
def test_iter_changes(self):
1063
1173
# Low level bootstrapping smoke test; comprehensive generic tests via
1064
1174
# InterTree are coming.
1065
1175
inv = Inventory()
1066
inv.revision_id = "revid"
1067
inv.root.revision = "rootrev"
1068
inv.add(InventoryFile("fileid", "file", inv.root.file_id))
1069
inv["fileid"].revision = "filerev"
1070
inv["fileid"].executable = True
1071
inv["fileid"].text_sha1 = "ffff"
1072
inv["fileid"].text_size = 1
1176
inv.revision_id = b"revid"
1177
inv.root.revision = b"rootrev"
1178
inv.add(InventoryFile(b"fileid", "file", inv.root.file_id))
1179
inv.get_entry(b"fileid").revision = b"filerev"
1180
inv.get_entry(b"fileid").executable = True
1181
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1182
inv.get_entry(b"fileid").text_size = 1
1073
1183
inv2 = Inventory()
1074
inv2.revision_id = "revid2"
1075
inv2.root.revision = "rootrev"
1076
inv2.add(InventoryFile("fileid", "file", inv.root.file_id))
1077
inv2["fileid"].revision = "filerev2"
1078
inv2["fileid"].executable = False
1079
inv2["fileid"].text_sha1 = "bbbb"
1080
inv2["fileid"].text_size = 2
1184
inv2.revision_id = b"revid2"
1185
inv2.root.revision = b"rootrev"
1186
inv2.add(InventoryFile(b"fileid", "file", inv.root.file_id))
1187
inv2.get_entry(b"fileid").revision = b"filerev2"
1188
inv2.get_entry(b"fileid").executable = False
1189
inv2.get_entry(b"fileid").text_sha1 = b"bbbb"
1190
inv2.get_entry(b"fileid").text_size = 2
1081
1191
# get fresh objects.
1082
1192
chk_bytes = self.get_chk_bytes()
1083
1193
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1084
bytes = ''.join(chk_inv.to_lines())
1085
inv_1 = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1194
lines = chk_inv.to_lines()
1195
inv_1 = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
1086
1196
chk_inv2 = CHKInventory.from_inventory(chk_bytes, inv2)
1087
bytes = ''.join(chk_inv2.to_lines())
1088
inv_2 = CHKInventory.deserialise(chk_bytes, bytes, ("revid2",))
1089
self.assertEqual([('fileid', (u'file', u'file'), True, (True, True),
1090
('TREE_ROOT', 'TREE_ROOT'), (u'file', u'file'), ('file', 'file'),
1092
list(inv_1.iter_changes(inv_2)))
1197
lines = chk_inv2.to_lines()
1198
inv_2 = CHKInventory.deserialise(chk_bytes, lines, (b"revid2",))
1199
self.assertEqual([(b'fileid', (u'file', u'file'), True, (True, True),
1200
(b'TREE_ROOT', b'TREE_ROOT'), (u'file',
1201
u'file'), ('file', 'file'),
1203
list(inv_1.iter_changes(inv_2)))
1094
1205
def test_parent_id_basename_to_file_id_index_enabled(self):
1095
1206
inv = Inventory()
1096
inv.revision_id = "revid"
1097
inv.root.revision = "rootrev"
1098
inv.add(InventoryFile("fileid", "file", inv.root.file_id))
1099
inv["fileid"].revision = "filerev"
1100
inv["fileid"].executable = True
1101
inv["fileid"].text_sha1 = "ffff"
1102
inv["fileid"].text_size = 1
1207
inv.revision_id = b"revid"
1208
inv.root.revision = b"rootrev"
1209
inv.add(InventoryFile(b"fileid", "file", inv.root.file_id))
1210
inv.get_entry(b"fileid").revision = b"filerev"
1211
inv.get_entry(b"fileid").executable = True
1212
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1213
inv.get_entry(b"fileid").text_size = 1
1103
1214
# get fresh objects.
1104
1215
chk_bytes = self.get_chk_bytes()
1105
1216
tmp_inv = CHKInventory.from_inventory(chk_bytes, inv)
1106
bytes = ''.join(tmp_inv.to_lines())
1107
chk_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1108
self.assertIsInstance(chk_inv.parent_id_basename_to_file_id, chk_map.CHKMap)
1217
lines = tmp_inv.to_lines()
1218
chk_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
1219
self.assertIsInstance(
1220
chk_inv.parent_id_basename_to_file_id, chk_map.CHKMap)
1109
1221
self.assertEqual(
1110
{('', ''): 'TREE_ROOT', ('TREE_ROOT', 'file'): 'fileid'},
1222
{(b'', b''): b'TREE_ROOT', (b'TREE_ROOT', b'file'): b'fileid'},
1111
1223
dict(chk_inv.parent_id_basename_to_file_id.iteritems()))
1113
1225
def test_file_entry_to_bytes(self):
1114
1226
inv = CHKInventory(None)
1115
ie = inventory.InventoryFile('file-id', 'filename', 'parent-id')
1227
ie = inventory.InventoryFile(b'file-id', 'filename', b'parent-id')
1116
1228
ie.executable = True
1117
ie.revision = 'file-rev-id'
1118
ie.text_sha1 = 'abcdefgh'
1229
ie.revision = b'file-rev-id'
1230
ie.text_sha1 = b'abcdefgh'
1119
1231
ie.text_size = 100
1120
1232
bytes = inv._entry_to_bytes(ie)
1121
self.assertEqual('file: file-id\nparent-id\nfilename\n'
1122
'file-rev-id\nabcdefgh\n100\nY', bytes)
1233
self.assertEqual(b'file: file-id\nparent-id\nfilename\n'
1234
b'file-rev-id\nabcdefgh\n100\nY', bytes)
1123
1235
ie2 = inv._bytes_to_entry(bytes)
1124
1236
self.assertEqual(ie, ie2)
1125
self.assertIsInstance(ie2.name, unicode)
1126
self.assertEqual(('filename', 'file-id', 'file-rev-id'),
1237
self.assertIsInstance(ie2.name, text_type)
1238
self.assertEqual((b'filename', b'file-id', b'file-rev-id'),
1127
1239
inv._bytes_to_utf8name_key(bytes))
1129
1241
def test_file2_entry_to_bytes(self):
1130
1242
inv = CHKInventory(None)
1131
1243
# \u30a9 == 'omega'
1132
ie = inventory.InventoryFile('file-id', u'\u03a9name', 'parent-id')
1244
ie = inventory.InventoryFile(b'file-id', u'\u03a9name', b'parent-id')
1133
1245
ie.executable = False
1134
ie.revision = 'file-rev-id'
1135
ie.text_sha1 = '123456'
1246
ie.revision = b'file-rev-id'
1247
ie.text_sha1 = b'123456'
1136
1248
ie.text_size = 25
1137
1249
bytes = inv._entry_to_bytes(ie)
1138
self.assertEqual('file: file-id\nparent-id\n\xce\xa9name\n'
1139
'file-rev-id\n123456\n25\nN', bytes)
1250
self.assertEqual(b'file: file-id\nparent-id\n\xce\xa9name\n'
1251
b'file-rev-id\n123456\n25\nN', bytes)
1140
1252
ie2 = inv._bytes_to_entry(bytes)
1141
1253
self.assertEqual(ie, ie2)
1142
self.assertIsInstance(ie2.name, unicode)
1143
self.assertEqual(('\xce\xa9name', 'file-id', 'file-rev-id'),
1254
self.assertIsInstance(ie2.name, text_type)
1255
self.assertEqual((b'\xce\xa9name', b'file-id', b'file-rev-id'),
1144
1256
inv._bytes_to_utf8name_key(bytes))
1146
1258
def test_dir_entry_to_bytes(self):
1147
1259
inv = CHKInventory(None)
1148
ie = inventory.InventoryDirectory('dir-id', 'dirname', 'parent-id')
1149
ie.revision = 'dir-rev-id'
1260
ie = inventory.InventoryDirectory(b'dir-id', 'dirname', b'parent-id')
1261
ie.revision = b'dir-rev-id'
1150
1262
bytes = inv._entry_to_bytes(ie)
1151
self.assertEqual('dir: dir-id\nparent-id\ndirname\ndir-rev-id', bytes)
1263
self.assertEqual(b'dir: dir-id\nparent-id\ndirname\ndir-rev-id', bytes)
1152
1264
ie2 = inv._bytes_to_entry(bytes)
1153
1265
self.assertEqual(ie, ie2)
1154
self.assertIsInstance(ie2.name, unicode)
1155
self.assertEqual(('dirname', 'dir-id', 'dir-rev-id'),
1266
self.assertIsInstance(ie2.name, text_type)
1267
self.assertEqual((b'dirname', b'dir-id', b'dir-rev-id'),
1156
1268
inv._bytes_to_utf8name_key(bytes))
1158
1270
def test_dir2_entry_to_bytes(self):
1159
1271
inv = CHKInventory(None)
1160
ie = inventory.InventoryDirectory('dir-id', u'dir\u03a9name',
1272
ie = inventory.InventoryDirectory(b'dir-id', u'dir\u03a9name',
1162
ie.revision = 'dir-rev-id'
1274
ie.revision = b'dir-rev-id'
1163
1275
bytes = inv._entry_to_bytes(ie)
1164
self.assertEqual('dir: dir-id\n\ndir\xce\xa9name\n'
1165
'dir-rev-id', bytes)
1276
self.assertEqual(b'dir: dir-id\n\ndir\xce\xa9name\n'
1277
b'dir-rev-id', bytes)
1166
1278
ie2 = inv._bytes_to_entry(bytes)
1167
1279
self.assertEqual(ie, ie2)
1168
self.assertIsInstance(ie2.name, unicode)
1280
self.assertIsInstance(ie2.name, text_type)
1169
1281
self.assertIs(ie2.parent_id, None)
1170
self.assertEqual(('dir\xce\xa9name', 'dir-id', 'dir-rev-id'),
1282
self.assertEqual((b'dir\xce\xa9name', b'dir-id', b'dir-rev-id'),
1171
1283
inv._bytes_to_utf8name_key(bytes))
1173
1285
def test_symlink_entry_to_bytes(self):
1174
1286
inv = CHKInventory(None)
1175
ie = inventory.InventoryLink('link-id', 'linkname', 'parent-id')
1176
ie.revision = 'link-rev-id'
1287
ie = inventory.InventoryLink(b'link-id', 'linkname', b'parent-id')
1288
ie.revision = b'link-rev-id'
1177
1289
ie.symlink_target = u'target/path'
1178
1290
bytes = inv._entry_to_bytes(ie)
1179
self.assertEqual('symlink: link-id\nparent-id\nlinkname\n'
1180
'link-rev-id\ntarget/path', bytes)
1291
self.assertEqual(b'symlink: link-id\nparent-id\nlinkname\n'
1292
b'link-rev-id\ntarget/path', bytes)
1181
1293
ie2 = inv._bytes_to_entry(bytes)
1182
1294
self.assertEqual(ie, ie2)
1183
self.assertIsInstance(ie2.name, unicode)
1184
self.assertIsInstance(ie2.symlink_target, unicode)
1185
self.assertEqual(('linkname', 'link-id', 'link-rev-id'),
1295
self.assertIsInstance(ie2.name, text_type)
1296
self.assertIsInstance(ie2.symlink_target, text_type)
1297
self.assertEqual((b'linkname', b'link-id', b'link-rev-id'),
1186
1298
inv._bytes_to_utf8name_key(bytes))
1188
1300
def test_symlink2_entry_to_bytes(self):
1189
1301
inv = CHKInventory(None)
1190
ie = inventory.InventoryLink('link-id', u'link\u03a9name', 'parent-id')
1191
ie.revision = 'link-rev-id'
1302
ie = inventory.InventoryLink(
1303
b'link-id', u'link\u03a9name', b'parent-id')
1304
ie.revision = b'link-rev-id'
1192
1305
ie.symlink_target = u'target/\u03a9path'
1193
1306
bytes = inv._entry_to_bytes(ie)
1194
self.assertEqual('symlink: link-id\nparent-id\nlink\xce\xa9name\n'
1195
'link-rev-id\ntarget/\xce\xa9path', bytes)
1307
self.assertEqual(b'symlink: link-id\nparent-id\nlink\xce\xa9name\n'
1308
b'link-rev-id\ntarget/\xce\xa9path', bytes)
1196
1309
ie2 = inv._bytes_to_entry(bytes)
1197
1310
self.assertEqual(ie, ie2)
1198
self.assertIsInstance(ie2.name, unicode)
1199
self.assertIsInstance(ie2.symlink_target, unicode)
1200
self.assertEqual(('link\xce\xa9name', 'link-id', 'link-rev-id'),
1311
self.assertIsInstance(ie2.name, text_type)
1312
self.assertIsInstance(ie2.symlink_target, text_type)
1313
self.assertEqual((b'link\xce\xa9name', b'link-id', b'link-rev-id'),
1201
1314
inv._bytes_to_utf8name_key(bytes))
1203
1316
def test_tree_reference_entry_to_bytes(self):
1204
1317
inv = CHKInventory(None)
1205
ie = inventory.TreeReference('tree-root-id', u'tree\u03a9name',
1207
ie.revision = 'tree-rev-id'
1208
ie.reference_revision = 'ref-rev-id'
1318
ie = inventory.TreeReference(b'tree-root-id', u'tree\u03a9name',
1320
ie.revision = b'tree-rev-id'
1321
ie.reference_revision = b'ref-rev-id'
1209
1322
bytes = inv._entry_to_bytes(ie)
1210
self.assertEqual('tree: tree-root-id\nparent-id\ntree\xce\xa9name\n'
1211
'tree-rev-id\nref-rev-id', bytes)
1323
self.assertEqual(b'tree: tree-root-id\nparent-id\ntree\xce\xa9name\n'
1324
b'tree-rev-id\nref-rev-id', bytes)
1212
1325
ie2 = inv._bytes_to_entry(bytes)
1213
1326
self.assertEqual(ie, ie2)
1214
self.assertIsInstance(ie2.name, unicode)
1215
self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
1327
self.assertIsInstance(ie2.name, text_type)
1328
self.assertEqual((b'tree\xce\xa9name', b'tree-root-id', b'tree-rev-id'),
1216
1329
inv._bytes_to_utf8name_key(bytes))
1331
def make_basic_utf8_inventory(self):
1333
inv.revision_id = b"revid"
1334
inv.root.revision = b"rootrev"
1335
root_id = inv.root.file_id
1336
inv.add(InventoryFile(b"fileid", u'f\xefle', root_id))
1337
inv.get_entry(b"fileid").revision = b"filerev"
1338
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1339
inv.get_entry(b"fileid").text_size = 0
1340
inv.add(InventoryDirectory(b"dirid", u'dir-\N{EURO SIGN}', root_id))
1341
inv.get_entry(b"dirid").revision = b"dirrev"
1342
inv.add(InventoryFile(b"childid", u'ch\xefld', b"dirid"))
1343
inv.get_entry(b"childid").revision = b"filerev"
1344
inv.get_entry(b"childid").text_sha1 = b"ffff"
1345
inv.get_entry(b"childid").text_size = 0
1346
chk_bytes = self.get_chk_bytes()
1347
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1348
lines = chk_inv.to_lines()
1349
return CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
1351
def test__preload_handles_utf8(self):
1352
new_inv = self.make_basic_utf8_inventory()
1353
self.assertEqual({}, new_inv._fileid_to_entry_cache)
1354
self.assertFalse(new_inv._fully_cached)
1355
new_inv._preload_cache()
1357
sorted([new_inv.root_id, b"fileid", b"dirid", b"childid"]),
1358
sorted(new_inv._fileid_to_entry_cache.keys()))
1359
ie_root = new_inv._fileid_to_entry_cache[new_inv.root_id]
1360
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1361
sorted(ie_root._children.keys()))
1362
ie_dir = new_inv._fileid_to_entry_cache[b'dirid']
1363
self.assertEqual([u'ch\xefld'], sorted(ie_dir._children.keys()))
1365
def test__preload_populates_cache(self):
1367
inv.revision_id = b"revid"
1368
inv.root.revision = b"rootrev"
1369
root_id = inv.root.file_id
1370
inv.add(InventoryFile(b"fileid", "file", root_id))
1371
inv.get_entry(b"fileid").revision = b"filerev"
1372
inv.get_entry(b"fileid").executable = True
1373
inv.get_entry(b"fileid").text_sha1 = b"ffff"
1374
inv.get_entry(b"fileid").text_size = 1
1375
inv.add(InventoryDirectory(b"dirid", "dir", root_id))
1376
inv.get_entry(b"dirid").revision = b"dirrev"
1377
inv.add(InventoryFile(b"childid", "child", b"dirid"))
1378
inv.get_entry(b"childid").revision = b"filerev"
1379
inv.get_entry(b"childid").executable = False
1380
inv.get_entry(b"childid").text_sha1 = b"dddd"
1381
inv.get_entry(b"childid").text_size = 1
1382
chk_bytes = self.get_chk_bytes()
1383
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1384
lines = chk_inv.to_lines()
1385
new_inv = CHKInventory.deserialise(chk_bytes, lines, (b"revid",))
1386
self.assertEqual({}, new_inv._fileid_to_entry_cache)
1387
self.assertFalse(new_inv._fully_cached)
1388
new_inv._preload_cache()
1390
sorted([root_id, b"fileid", b"dirid", b"childid"]),
1391
sorted(new_inv._fileid_to_entry_cache.keys()))
1392
self.assertTrue(new_inv._fully_cached)
1393
ie_root = new_inv._fileid_to_entry_cache[root_id]
1394
self.assertEqual(['dir', 'file'], sorted(ie_root._children.keys()))
1395
ie_dir = new_inv._fileid_to_entry_cache[b'dirid']
1396
self.assertEqual(['child'], sorted(ie_dir._children.keys()))
1398
def test__preload_handles_partially_evaluated_inventory(self):
1399
new_inv = self.make_basic_utf8_inventory()
1400
ie = new_inv.get_entry(new_inv.root_id)
1401
self.assertIs(None, ie._children)
1402
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1403
sorted(ie.children.keys()))
1404
# Accessing .children loads _children
1405
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1406
sorted(ie._children.keys()))
1407
new_inv._preload_cache()
1409
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1410
sorted(ie._children.keys()))
1411
ie_dir = new_inv.get_entry(b"dirid")
1412
self.assertEqual([u'ch\xefld'],
1413
sorted(ie_dir._children.keys()))
1415
def test_filter_change_in_renamed_subfolder(self):
1416
inv = Inventory(b'tree-root')
1417
inv.root.revision = b'rootrev'
1418
src_ie = inv.add_path('src', 'directory', b'src-id')
1419
src_ie.revision = b'srcrev'
1420
sub_ie = inv.add_path('src/sub/', 'directory', b'sub-id')
1421
sub_ie.revision = b'subrev'
1422
a_ie = inv.add_path('src/sub/a', 'file', b'a-id')
1423
a_ie.revision = b'filerev'
1424
a_ie.text_sha1 = osutils.sha_string(b'content\n')
1425
a_ie.text_size = len(b'content\n')
1426
chk_bytes = self.get_chk_bytes()
1427
inv = CHKInventory.from_inventory(chk_bytes, inv)
1428
inv = inv.create_by_apply_delta([
1429
("src/sub/a", "src/sub/a", b"a-id", a_ie),
1430
("src", "src2", b"src-id", src_ie),
1432
new_inv = inv.filter([b'a-id', b'src-id'])
1436
('src/sub', b'sub-id'),
1437
('src/sub/a', b'a-id'),
1438
], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
1219
1441
class TestCHKInventoryExpand(tests.TestCaseWithMemoryTransport):
1286
1513
for path, entry in inv.iter_entries_by_dir():
1287
1514
layout.append((path, entry.file_id))
1288
1515
self.assertEqual([
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'),
1517
('dir1', b'dir1-id'),
1518
('dir2', b'dir2-id'),
1520
('dir1/sub-dir1', b'sub-dir1-id'),
1521
('dir1/sub-file1', b'sub-file1-id'),
1522
('dir1/sub-file2', b'sub-file2-id'),
1523
('dir1/sub-dir1/subsub-file1', b'subsub-file1-id'),
1524
('dir2/sub2-file1', b'sub2-file1-id'),
1300
1527
def test__getitems(self):
1301
1528
inv = self.make_simple_inventory()
1302
1529
# Reading from disk
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)
1530
self.assert_Getitems([b'dir1-id'], inv, [b'dir1-id'])
1531
self.assertTrue(b'dir1-id' in inv._fileid_to_entry_cache)
1532
self.assertFalse(b'sub-file2-id' in inv._fileid_to_entry_cache)
1307
self.assert_Getitems(['dir1-id'], inv, ['dir1-id'])
1534
self.assert_Getitems([b'dir1-id'], inv, [b'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)
1536
self.assert_Getitems([b'dir1-id', b'sub-file2-id'], inv,
1537
[b'dir1-id', b'sub-file2-id'])
1538
self.assertTrue(b'dir1-id' in inv._fileid_to_entry_cache)
1539
self.assertTrue(b'sub-file2-id' in inv._fileid_to_entry_cache)
1314
1541
def test_single_file(self):
1315
1542
inv = self.make_simple_inventory()
1316
self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
1543
self.assertExpand([b'TREE_ROOT', b'top-id'], inv, [b'top-id'])
1318
1545
def test_get_all_parents(self):
1319
1546
inv = self.make_simple_inventory()
1320
self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1322
], inv, ['subsub-file1-id'])
1547
self.assertExpand([b'TREE_ROOT', b'dir1-id', b'sub-dir1-id',
1549
], inv, [b'subsub-file1-id'])
1324
1551
def test_get_children(self):
1325
1552
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'])
1553
self.assertExpand([b'TREE_ROOT', b'dir1-id', b'sub-dir1-id',
1554
b'sub-file1-id', b'sub-file2-id', b'subsub-file1-id',
1555
], inv, [b'dir1-id'])
1330
1557
def test_from_root(self):
1331
1558
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'])
1559
self.assertExpand([b'TREE_ROOT', b'dir1-id', b'dir2-id', b'sub-dir1-id',
1560
b'sub-file1-id', b'sub-file2-id', b'sub2-file1-id',
1561
b'subsub-file1-id', b'top-id'], inv, [b'TREE_ROOT'])
1336
1563
def test_top_level_file(self):
1337
1564
inv = self.make_simple_inventory()
1338
self.assertExpand(['TREE_ROOT', 'top-id'], inv, ['top-id'])
1565
self.assertExpand([b'TREE_ROOT', b'top-id'], inv, [b'top-id'])
1340
1567
def test_subsub_file(self):
1341
1568
inv = self.make_simple_inventory()
1342
self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id',
1343
'subsub-file1-id'], inv, ['subsub-file1-id'])
1569
self.assertExpand([b'TREE_ROOT', b'dir1-id', b'sub-dir1-id',
1570
b'subsub-file1-id'], inv, [b'subsub-file1-id'])
1345
1572
def test_sub_and_root(self):
1346
1573
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'])
1574
self.assertExpand([b'TREE_ROOT', b'dir1-id', b'sub-dir1-id', b'top-id',
1575
b'subsub-file1-id'], inv, [b'top-id', b'subsub-file1-id'])
1578
class TestMutableInventoryFromTree(TestCaseWithTransport):
1580
def test_empty(self):
1581
repository = self.make_repository('.')
1582
tree = repository.revision_tree(revision.NULL_REVISION)
1583
inv = mutable_inventory_from_tree(tree)
1584
self.assertEqual(revision.NULL_REVISION, inv.revision_id)
1585
self.assertEqual(0, len(inv))
1587
def test_some_files(self):
1588
wt = self.make_branch_and_tree('.')
1589
self.build_tree(['a'])
1590
wt.add(['a'], [b'thefileid'])
1591
revid = wt.commit("commit")
1592
tree = wt.branch.repository.revision_tree(revid)
1593
inv = mutable_inventory_from_tree(tree)
1594
self.assertEqual(revid, inv.revision_id)
1595
self.assertEqual(2, len(inv))
1596
self.assertEqual("a", inv.get_entry(b'thefileid').name)
1597
# The inventory should be mutable and independent of
1599
self.assertFalse(tree.root_inventory.get_entry(
1600
b'thefileid').executable)
1601
inv.get_entry(b'thefileid').executable = True
1602
self.assertFalse(tree.root_inventory.get_entry(
1603
b'thefileid').executable)