~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_repository.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-06-25 10:36:36 UTC
  • mfrom: (3350.6.12 versionedfiles)
  • Revision ID: pqm@pqm.ubuntu.com-20080625103636-6kxh4e1gmyn82f50
(mbp for robertc) VersionedFiles refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
171
171
                          control.transport.get,
172
172
                          'ancestry.weave')
173
173
 
174
 
    def test_exposed_versioned_files_are_marked_dirty(self):
175
 
        control = bzrdir.BzrDirFormat6().initialize(self.get_url())
176
 
        repo = weaverepo.RepositoryFormat6().initialize(control)
177
 
        repo.lock_write()
178
 
        inv = repo.get_inventory_weave()
179
 
        repo.unlock()
180
 
        self.assertRaises(errors.OutSideTransaction,
181
 
            inv.add_lines, 'foo', [], [])
182
 
 
183
174
    def test_supports_external_lookups(self):
184
175
        control = bzrdir.BzrDirFormat6().initialize(self.get_url())
185
176
        repo = weaverepo.RepositoryFormat6().initialize(control)
209
200
                             'w\n'
210
201
                             'W\n',
211
202
                             t.get('inventory.weave').read())
 
203
        # Creating a file with id Foo:Bar results in a non-escaped file name on
 
204
        # disk.
 
205
        control.create_branch()
 
206
        tree = control.create_workingtree()
 
207
        tree.add(['foo'], ['Foo:Bar'], ['file'])
 
208
        tree.put_file_bytes_non_atomic('Foo:Bar', 'content\n')
 
209
        tree.commit('first post', rev_id='first')
 
210
        self.assertEqualDiff(
 
211
            '# bzr weave file v5\n'
 
212
            'i\n'
 
213
            '1 7fe70820e08a1aac0ef224d9c66ab66831cc4ab1\n'
 
214
            'n first\n'
 
215
            '\n'
 
216
            'w\n'
 
217
            '{ 0\n'
 
218
            '. content\n'
 
219
            '}\n'
 
220
            'W\n',
 
221
            t.get('weaves/74/Foo%3ABar.weave').read())
212
222
 
213
223
    def test_shared_disk_layout(self):
214
224
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
289
299
                             'W\n',
290
300
                             t.get('inventory.weave').read())
291
301
 
292
 
    def test_exposed_versioned_files_are_marked_dirty(self):
293
 
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
294
 
        repo = weaverepo.RepositoryFormat7().initialize(control)
295
 
        repo.lock_write()
296
 
        inv = repo.get_inventory_weave()
297
 
        repo.unlock()
298
 
        self.assertRaises(errors.OutSideTransaction,
299
 
            inv.add_lines, 'foo', [], [])
300
 
 
301
302
    def test_supports_external_lookups(self):
302
303
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
303
304
        repo = weaverepo.RepositoryFormat7().initialize(control)
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  :')
328
337
 
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())
333
 
        # no default content
334
 
        self.assertTrue(t.has(knit_name + '.knit'))
335
342
 
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)
383
390
 
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)
388
 
        repo.lock_write()
389
 
        inv = repo.get_inventory_weave()
390
 
        repo.unlock()
391
 
        self.assertRaises(errors.OutSideTransaction,
392
 
            inv.add_lines, 'foo', [], [])
393
 
 
394
391
    def test_deserialise_sets_root_revision(self):
395
392
        """We must have a inventory.root.revision
396
393
 
424
421
        self.assertFalse(repo._format.supports_external_lookups)
425
422
 
426
423
 
427
 
class KnitRepositoryStreamTests(test_knit.KnitTests):
428
 
    """Tests for knitrepo._get_stream_as_bytes."""
429
 
 
430
 
    def test_get_stream_as_bytes(self):
431
 
        # Make a simple knit
432
 
        k1 = self.make_test_knit()
433
 
        k1.add_lines('text-a', [], test_knit.split_lines(test_knit.TEXT_1))
434
 
        
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])
442
 
 
443
 
    def test_get_stream_as_bytes_all(self):
444
 
        """Get a serialised data stream for all the records in a knit.
445
 
 
446
 
        Much like test_get_stream_all, except for get_stream_as_bytes.
447
 
        """
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).
451
 
        test_data = [
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),
457
 
           ]
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)
460
 
        # behaviour.
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']),
468
 
            ]
469
 
        for version_id, parents, lines in test_data:
470
 
            k1.add_lines(version_id, parents, test_knit.split_lines(lines))
471
 
 
472
 
        bytes = knitrepo._get_stream_as_bytes(
473
 
            k1, ['text-a', 'text-b', 'text-m', 'text-c', 'text-d', ])
474
 
 
475
 
        data = bencode.bdecode(bytes)
476
 
        format = data.pop(0)
477
 
        self.assertEqual('knit-plain', format)
478
 
 
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)
488
 
 
489
 
 
490
424
class DummyRepository(object):
491
425
    """A dummy repository for testing."""
492
426
 
597
531
                                                        repo_b).__class__)
598
532
 
599
533
 
600
 
class TestInterRemoteToOther(TestCaseWithTransport):
601
 
 
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()
607
 
        smart_server.setUp()
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()
612
 
        return remote_repo
613
 
 
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
620
 
        self.assertTrue(
621
 
            is_compatible(remote_repo, local_repo),
622
 
            "InterRemoteToOther(%r, %r) is false" % (remote_repo, local_repo))
623
 
          
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
628
 
        self.assertFalse(
629
 
            is_compatible(remote_repo, local_repo),
630
 
            "InterRemoteToOther(%r, %r) is true" % (local_repo, remote_repo))
631
 
 
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
637
 
        self.assertFalse(
638
 
            is_compatible(remote_repo_a, remote_repo_b),
639
 
            "InterRemoteToOther(%r, %r) is true"
640
 
            % (remote_repo_a, remote_repo_b))
641
 
 
642
 
 
643
534
class TestRepositoryConverter(TestCaseWithTransport):
644
535
 
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()
 
569
        try:
 
570
            self.assertRaises(errors.NoSuchFile, revision_tree.get_file_lines,
 
571
                revision_tree.inventory.root.file_id)
 
572
        finally:
 
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()
 
580
        try:
 
581
            revision_tree.get_file_lines(revision_tree.inventory.root.file_id)
 
582
        finally:
 
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)
688
589
 
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)
693
 
        repo.lock_write()
694
 
        inv = repo.get_inventory_weave()
695
 
        repo.unlock()
696
 
        self.assertRaises(errors.OutSideTransaction,
697
 
            inv.add_lines, 'foo', [], [])
698
 
 
699
590
    def test_supports_external_lookups(self):
700
591
        format = bzrdir.BzrDirMetaFormat1()
701
592
        format.repository_format = knitrepo.RepositoryFormatKnit3()
773
664
        entry.revision = revision
774
665
        entry.text_size = 0
775
666
        inv.add(entry)
776
 
        vf = repo.weave_store.get_weave_or_empty(file_id,
777
 
                                                 repo.get_transaction())
778
 
        vf.add_lines(revision, parents, ['line\n'])
 
667
        text_key = (file_id, revision)
 
668
        parent_keys = [(file_id, parent) for parent in parents]
 
669
        repo.texts.add_lines(text_key, parent_keys, ['line\n'])
779
670
 
780
671
    def test_insert_from_broken_repo(self):
781
672
        """Inserting a data stream from a broken repository won't silently
783
674
        """
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()
794
 
        try:
795
 
            self.assertRaises(
796
 
                errors.KnitCorrupt, empty_repo.insert_data_stream, stream)
797
 
        finally:
798
 
            empty_repo.abort_write_group()
 
677
        self.assertRaises(errors.RevisionNotPresent, empty_repo.fetch, broken_repo)
799
678
 
800
679
 
801
680
class TestKnitPackNoSubtrees(TestCaseWithTransport):
820
699
            "Bazaar pack repository format 1 (needs bzr 0.92)\n",
821
700
                             t.get('format').read())
822
701
 
823
 
    def assertHasKndx(self, t, knit_name):
824
 
        """Assert that knit_name exists on t."""
825
 
        self.assertEqualDiff('# bzr knit index 8\n',
826
 
                             t.get(knit_name + '.kndx').read())
827
 
 
828
702
    def assertHasNoKndx(self, t, knit_name):
829
703
        """Assert that knit_name has no index on t."""
830
704
        self.assertFalse(t.has(knit_name + '.kndx'))
1010
884
 
1011
885
    def _add_text(self, repo, fileid):
1012
886
        """Add a text to the repository within a write group."""
1013
 
        vf =repo.weave_store.get_weave(fileid, repo.get_transaction())
1014
 
        vf.add_lines('samplerev+' + fileid, [], [])
 
887
        repo.texts.add_lines((fileid, 'samplerev+'+fileid), [], [])
1015
888
 
1016
889
    def test_concurrent_writers_merge_new_packs(self):
1017
890
        format = self.get_format()
1188
1061
            inv.root.revision = revision_id
1189
1062
            root_id = inv.root.file_id
1190
1063
            sha1 = repo.add_inventory(revision_id, inv, [])
1191
 
            vf = repo.weave_store.get_weave_or_empty(root_id,
1192
 
                repo.get_transaction())
1193
 
            vf.add_lines(revision_id, [], [])
 
1064
            repo.texts.add_lines((root_id, revision_id), [], [])
1194
1065
            rev = bzrlib.revision.Revision(timestamp=0,
1195
1066
                                           timezone=None,
1196
1067
                                           committer="Foo Bar <foo@example.com>",
1211
1082
        inv = missing_ghost.get_inventory('tip')
1212
1083
        self.assertRaises(errors.NoSuchRevision,
1213
1084
            missing_ghost.get_revision, 'ghost')
1214
 
        self.assertRaises(errors.RevisionNotPresent,
 
1085
        self.assertRaises(errors.NoSuchRevision,
1215
1086
            missing_ghost.get_inventory, 'ghost')
1216
1087
 
1217
1088
    def test_supports_external_lookups(self):