325
326
# self.assertEqualDiff('', t.get('lock').read())
326
327
self.assertTrue(S_ISDIR(t.stat('knits').st_mode))
327
328
self.check_knits(t)
329
# Check per-file knits.
330
branch = control.create_branch()
331
tree = control.create_workingtree()
332
tree.add(['foo'], ['Nasty-IdC:'], ['file'])
333
tree.put_file_bytes_non_atomic('Nasty-IdC:', '')
334
tree.commit('1st post', rev_id='foo')
335
self.assertHasKnit(t, 'knits/e8/%254easty-%2549d%2543%253a',
336
'\nfoo fulltext 0 81 :')
329
def assertHasKnit(self, t, knit_name):
338
def assertHasKnit(self, t, knit_name, extra_content=''):
330
339
"""Assert that knit_name exists on t."""
331
self.assertEqualDiff('# bzr knit index 8\n',
340
self.assertEqualDiff('# bzr knit index 8\n' + extra_content,
332
341
t.get(knit_name + '.kndx').read())
334
self.assertTrue(t.has(knit_name + '.knit'))
336
343
def check_knits(self, t):
337
344
"""check knit content for a repository."""
381
388
self.assertTrue(S_ISDIR(t.stat('knits').st_mode))
382
389
self.check_knits(t)
384
def test_exposed_versioned_files_are_marked_dirty(self):
385
format = bzrdir.BzrDirMetaFormat1()
386
format.repository_format = knitrepo.RepositoryFormatKnit1()
387
repo = self.make_repository('.', format=format)
389
inv = repo.get_inventory_weave()
391
self.assertRaises(errors.OutSideTransaction,
392
inv.add_lines, 'foo', [], [])
394
391
def test_deserialise_sets_root_revision(self):
395
392
"""We must have a inventory.root.revision
424
421
self.assertFalse(repo._format.supports_external_lookups)
427
class KnitRepositoryStreamTests(test_knit.KnitTests):
428
"""Tests for knitrepo._get_stream_as_bytes."""
430
def test_get_stream_as_bytes(self):
432
k1 = self.make_test_knit()
433
k1.add_lines('text-a', [], test_knit.split_lines(test_knit.TEXT_1))
435
# Serialise it, check the output.
436
bytes = knitrepo._get_stream_as_bytes(k1, ['text-a'])
437
data = bencode.bdecode(bytes)
438
format, record = data
439
self.assertEqual('knit-plain', format)
440
self.assertEqual(['text-a', ['fulltext'], []], record[:3])
441
self.assertRecordContentEqual(k1, 'text-a', record[3])
443
def test_get_stream_as_bytes_all(self):
444
"""Get a serialised data stream for all the records in a knit.
446
Much like test_get_stream_all, except for get_stream_as_bytes.
448
k1 = self.make_test_knit()
449
# Insert the same data as BasicKnitTests.test_knit_join, as they seem
450
# to cover a range of cases (no parents, one parent, multiple parents).
452
('text-a', [], test_knit.TEXT_1),
453
('text-b', ['text-a'], test_knit.TEXT_1),
454
('text-c', [], test_knit.TEXT_1),
455
('text-d', ['text-c'], test_knit.TEXT_1),
456
('text-m', ['text-b', 'text-d'], test_knit.TEXT_1),
458
# This test is actually a bit strict as the order in which they're
459
# returned is not defined. This matches the current (deterministic)
461
expected_data_list = [
462
# version, options, parents
463
('text-a', ['fulltext'], []),
464
('text-b', ['line-delta'], ['text-a']),
465
('text-m', ['line-delta'], ['text-b', 'text-d']),
466
('text-c', ['fulltext'], []),
467
('text-d', ['line-delta'], ['text-c']),
469
for version_id, parents, lines in test_data:
470
k1.add_lines(version_id, parents, test_knit.split_lines(lines))
472
bytes = knitrepo._get_stream_as_bytes(
473
k1, ['text-a', 'text-b', 'text-m', 'text-c', 'text-d', ])
475
data = bencode.bdecode(bytes)
477
self.assertEqual('knit-plain', format)
479
for expected, actual in zip(expected_data_list, data):
480
expected_version = expected[0]
481
expected_options = expected[1]
482
expected_parents = expected[2]
483
version, options, parents, bytes = actual
484
self.assertEqual(expected_version, version)
485
self.assertEqual(expected_options, options)
486
self.assertEqual(expected_parents, parents)
487
self.assertRecordContentEqual(k1, version, bytes)
490
424
class DummyRepository(object):
491
425
"""A dummy repository for testing."""
597
531
repo_b).__class__)
600
class TestInterRemoteToOther(TestCaseWithTransport):
602
def make_remote_repository(self, path, backing_format=None):
603
"""Make a RemoteRepository object backed by a real repository that will
604
be created at the given path."""
605
self.make_repository(path, format=backing_format)
606
smart_server = server.SmartTCPServer_for_testing()
608
remote_transport = get_transport(smart_server.get_url()).clone(path)
609
self.addCleanup(smart_server.tearDown)
610
remote_bzrdir = bzrdir.BzrDir.open_from_transport(remote_transport)
611
remote_repo = remote_bzrdir.open_repository()
614
def test_is_compatible_same_format(self):
615
"""InterRemoteToOther is compatible with a remote repository and a
616
second repository that have the same format."""
617
local_repo = self.make_repository('local')
618
remote_repo = self.make_remote_repository('remote')
619
is_compatible = repository.InterRemoteToOther.is_compatible
621
is_compatible(remote_repo, local_repo),
622
"InterRemoteToOther(%r, %r) is false" % (remote_repo, local_repo))
624
def test_is_incompatible_different_format(self):
625
local_repo = self.make_repository('local', 'dirstate')
626
remote_repo = self.make_remote_repository('a', 'dirstate-with-subtree')
627
is_compatible = repository.InterRemoteToOther.is_compatible
629
is_compatible(remote_repo, local_repo),
630
"InterRemoteToOther(%r, %r) is true" % (local_repo, remote_repo))
632
def test_is_incompatible_different_format_both_remote(self):
633
remote_repo_a = self.make_remote_repository(
634
'a', 'dirstate-with-subtree')
635
remote_repo_b = self.make_remote_repository('b', 'dirstate')
636
is_compatible = repository.InterRemoteToOther.is_compatible
638
is_compatible(remote_repo_a, remote_repo_b),
639
"InterRemoteToOther(%r, %r) is true"
640
% (remote_repo_a, remote_repo_b))
643
534
class TestRepositoryConverter(TestCaseWithTransport):
645
536
def test_convert_empty(self):
674
565
tree = self.make_branch_and_tree('.', format)
675
566
tree.commit("Dull commit", rev_id="dull")
676
567
revision_tree = tree.branch.repository.revision_tree('dull')
677
self.assertRaises(errors.NoSuchFile, revision_tree.get_file_lines,
678
revision_tree.inventory.root.file_id)
568
revision_tree.lock_read()
570
self.assertRaises(errors.NoSuchFile, revision_tree.get_file_lines,
571
revision_tree.inventory.root.file_id)
573
revision_tree.unlock()
679
574
format = bzrdir.BzrDirMetaFormat1()
680
575
format.repository_format = knitrepo.RepositoryFormatKnit3()
681
576
upgrade.Convert('.', format)
682
577
tree = workingtree.WorkingTree.open('.')
683
578
revision_tree = tree.branch.repository.revision_tree('dull')
684
revision_tree.get_file_lines(revision_tree.inventory.root.file_id)
579
revision_tree.lock_read()
581
revision_tree.get_file_lines(revision_tree.inventory.root.file_id)
583
revision_tree.unlock()
685
584
tree.commit("Another dull commit", rev_id='dull2')
686
585
revision_tree = tree.branch.repository.revision_tree('dull2')
586
revision_tree.lock_read()
587
self.addCleanup(revision_tree.unlock)
687
588
self.assertEqual('dull', revision_tree.inventory.root.revision)
689
def test_exposed_versioned_files_are_marked_dirty(self):
690
format = bzrdir.BzrDirMetaFormat1()
691
format.repository_format = knitrepo.RepositoryFormatKnit3()
692
repo = self.make_repository('.', format=format)
694
inv = repo.get_inventory_weave()
696
self.assertRaises(errors.OutSideTransaction,
697
inv.add_lines, 'foo', [], [])
699
590
def test_supports_external_lookups(self):
700
591
format = bzrdir.BzrDirMetaFormat1()
701
592
format.repository_format = knitrepo.RepositoryFormatKnit3()
784
675
broken_repo = self.make_broken_repository()
785
676
empty_repo = self.make_repository('empty-repo')
786
search = graph.SearchResult(set(['rev1a', 'rev2', 'rev3']),
787
set(), 3, ['rev1a', 'rev2', 'rev3'])
788
broken_repo.lock_read()
789
self.addCleanup(broken_repo.unlock)
790
stream = broken_repo.get_data_stream_for_search(search)
791
empty_repo.lock_write()
792
self.addCleanup(empty_repo.unlock)
793
empty_repo.start_write_group()
796
errors.KnitCorrupt, empty_repo.insert_data_stream, stream)
798
empty_repo.abort_write_group()
677
self.assertRaises(errors.RevisionNotPresent, empty_repo.fetch, broken_repo)
801
680
class TestKnitPackNoSubtrees(TestCaseWithTransport):