~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_versionedfile.py

  • Committer: Aaron Bentley
  • Date: 2008-04-24 04:58:42 UTC
  • mfrom: (3377 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3380.
  • Revision ID: aaron@aaronbentley.com-20080424045842-0cajl9v6s4u52kaw
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
    progress,
31
31
    )
32
32
from bzrlib.errors import (
33
 
                           RevisionNotPresent, 
 
33
                           RevisionNotPresent,
34
34
                           RevisionAlreadyPresent,
35
35
                           WeaveParentMismatch
36
36
                           )
37
37
from bzrlib.knit import (
38
 
    KnitVersionedFile,
 
38
    make_file_knit,
39
39
    KnitAnnotateFactory,
40
40
    KnitPlainFactory,
41
41
    )
59
59
    they are strictly controlled by their owning repositories.
60
60
    """
61
61
 
 
62
    def get_transaction(self):
 
63
        if not hasattr(self, '_transaction'):
 
64
            self._transaction = None
 
65
        return self._transaction
 
66
 
62
67
    def test_add(self):
63
68
        f = self.get_file()
64
69
        f.add_lines('r0', [], ['a\n', 'b\n'])
242
247
        for version in multiparent.topo_iter(vf):
243
248
            mpdiff = vf.make_mpdiffs([version])[0]
244
249
            new_vf.add_mpdiffs([(version, vf.get_parent_map([version])[version],
245
 
                                 vf.get_sha1(version), mpdiff)])
 
250
                                 vf.get_sha1s([version])[0], mpdiff)])
246
251
            self.assertEqualDiff(vf.get_text(version),
247
252
                                 new_vf.get_text(version))
248
253
 
348
353
            set(f.get_ancestry('rM', topo_sorted=False)))
349
354
 
350
355
    def test_mutate_after_finish(self):
 
356
        self._transaction = 'before'
351
357
        f = self.get_file()
352
 
        f.transaction_finished()
 
358
        self._transaction = 'after'
353
359
        self.assertRaises(errors.OutSideTransaction, f.add_lines, '', [], [])
354
360
        self.assertRaises(errors.OutSideTransaction, f.add_lines_with_ghosts, '', [], [])
355
361
        self.assertRaises(errors.OutSideTransaction, f.join, '')
356
 
        self.assertRaises(errors.OutSideTransaction, f.clone_text, 'base', 'bar', ['foo'])
357
362
        
358
 
    def test_clear_cache(self):
359
 
        f = self.get_file()
360
 
        # on a new file it should not error
361
 
        f.clear_cache()
362
 
        # and after adding content, doing a clear_cache and a get should work.
363
 
        f.add_lines('0', [], ['a'])
364
 
        f.clear_cache()
365
 
        self.assertEqual(['a'], f.get_lines('0'))
366
 
 
367
363
    def test_clone_text(self):
368
364
        f = self.get_file()
369
365
        f.add_lines('r0', [], ['a\n', 'b\n'])
370
 
        f.clone_text('r1', 'r0', ['r0'])
 
366
        self.applyDeprecated(one_four, f.clone_text, 'r1', 'r0', ['r0'])
371
367
        def verify_file(f):
372
368
            self.assertEquals(f.get_lines('r1'), f.get_lines('r0'))
373
369
            self.assertEquals(f.get_lines('r1'), ['a\n', 'b\n'])
374
370
            self.assertEqual({'r1':('r0',)}, f.get_parent_map(['r1']))
375
371
            self.assertRaises(RevisionNotPresent,
376
 
                f.clone_text, 'r2', 'rX', [])
 
372
                self.applyDeprecated, one_four, f.clone_text, 'r2', 'rX', [])
377
373
            self.assertRaises(RevisionAlreadyPresent,
378
 
                f.clone_text, 'r1', 'r0', [])
 
374
                self.applyDeprecated, one_four, f.clone_text, 'r1', 'r0', [])
379
375
        verify_file(f)
380
376
        verify_file(self.reopen_file())
381
377
 
384
380
        f.add_lines('0', [], ['a\n'])
385
381
        t = MemoryTransport()
386
382
        f.copy_to('foo', t)
387
 
        for suffix in f.__class__.get_suffixes():
 
383
        for suffix in self.get_factory().get_suffixes():
388
384
            self.assertTrue(t.has('foo' + suffix))
389
385
 
390
386
    def test_get_suffixes(self):
391
387
        f = self.get_file()
392
 
        # should be the same
393
 
        self.assertEqual(f.__class__.get_suffixes(), f.__class__.get_suffixes())
394
388
        # and should be a list
395
 
        self.assertTrue(isinstance(f.__class__.get_suffixes(), list))
 
389
        self.assertTrue(isinstance(self.get_factory().get_suffixes(), list))
396
390
 
397
391
    def build_graph(self, file, graph):
398
392
        for node in topo_sort(graph.items()):
405
399
            'v2': ('v1', ),
406
400
            'v3': ('v2', )}
407
401
        self.build_graph(f, graph)
408
 
        self.assertEqual(graph, f.get_graph())
 
402
        self.assertEqual(graph, self.applyDeprecated(one_four, f.get_graph))
409
403
    
410
404
    def test_get_graph_partial(self):
411
405
        f = self.get_file()
432
426
        simple_b_gam.update(simple_gam)
433
427
        simple_b_gam.update(simple_b)
434
428
        self.build_graph(f, complex_graph)
435
 
        self.assertEqual(simple_a, f.get_graph(['a']))
436
 
        self.assertEqual(simple_b, f.get_graph(['b']))
437
 
        self.assertEqual(simple_gam, f.get_graph(['gam']))
438
 
        self.assertEqual(simple_b_gam, f.get_graph(['b', 'gam']))
 
429
        self.assertEqual(simple_a, self.applyDeprecated(one_four, f.get_graph,
 
430
            ['a']))
 
431
        self.assertEqual(simple_b, self.applyDeprecated(one_four, f.get_graph,
 
432
            ['b']))
 
433
        self.assertEqual(simple_gam, self.applyDeprecated(one_four,
 
434
            f.get_graph, ['gam']))
 
435
        self.assertEqual(simple_b_gam, self.applyDeprecated(one_four,
 
436
            f.get_graph, ['b', 'gam']))
439
437
 
440
438
    def test_get_parents(self):
441
439
        f = self.get_file()
525
523
        # XXX TODO a ghost
526
524
        # cases: each sample data individually:
527
525
        self.assertEqual(set([('r0', ())]),
528
 
            set(f.iter_parents(['r0'])))
 
526
            set(self.applyDeprecated(one_four, f.iter_parents, ['r0'])))
529
527
        self.assertEqual(set([('r1', ('r0', ))]),
530
 
            set(f.iter_parents(['r1'])))
 
528
            set(self.applyDeprecated(one_four, f.iter_parents, ['r1'])))
531
529
        self.assertEqual(set([('r2', ('r1', 'r0'))]),
532
 
            set(f.iter_parents(['r2'])))
 
530
            set(self.applyDeprecated(one_four, f.iter_parents, ['r2'])))
533
531
        # no nodes returned for a missing node
534
532
        self.assertEqual(set(),
535
 
            set(f.iter_parents(['missing'])))
 
533
            set(self.applyDeprecated(one_four, f.iter_parents, ['missing'])))
536
534
        # 1 node returned with missing nodes skipped
537
535
        self.assertEqual(set([('r1', ('r0', ))]),
538
 
            set(f.iter_parents(['ghost1', 'r1', 'ghost'])))
 
536
            set(self.applyDeprecated(one_four, f.iter_parents, ['ghost1', 'r1',
 
537
                'ghost'])))
539
538
        # 2 nodes returned
540
539
        self.assertEqual(set([('r0', ()), ('r1', ('r0', ))]),
541
 
            set(f.iter_parents(['r0', 'r1'])))
 
540
            set(self.applyDeprecated(one_four, f.iter_parents, ['r0', 'r1'])))
542
541
        # 2 nodes returned, missing skipped
543
542
        self.assertEqual(set([('r0', ()), ('r1', ('r0', ))]),
544
 
            set(f.iter_parents(['a', 'r0', 'b', 'r1', 'c'])))
 
543
            set(self.applyDeprecated(one_four, f.iter_parents,
 
544
                ['a', 'r0', 'b', 'r1', 'c'])))
545
545
 
546
546
    def test_iter_lines_added_or_present_in_versions(self):
547
547
        # test that we get at least an equalset of the lines added by
631
631
        self.assertEqual(['notbxbfse'], vf.get_ancestry('notbxbfse'))
632
632
        self.assertEqual([],
633
633
            self.applyDeprecated(one_four, vf.get_parents, 'notbxbfse'))
634
 
        self.assertEqual({'notbxbfse':()}, vf.get_graph())
 
634
        self.assertEqual({'notbxbfse':()}, self.applyDeprecated(one_four,
 
635
            vf.get_graph))
635
636
        self.assertFalse(vf.has_version(parent_id_utf8))
636
637
        # we have _with_ghost apis to give us ghost information.
637
638
        self.assertEqual([parent_id_utf8, 'notbxbfse'], vf.get_ancestry_with_ghosts(['notbxbfse']))
649
650
        self.assertEqual({parent_id_utf8:(),
650
651
                          'notbxbfse':(parent_id_utf8, ),
651
652
                          },
652
 
                         vf.get_graph())
 
653
                         self.applyDeprecated(one_four, vf.get_graph))
653
654
        self.assertTrue(vf.has_version(parent_id_utf8))
654
655
        # we have _with_ghost apis to give us ghost information.
655
656
        self.assertEqual([parent_id_utf8, 'notbxbfse'],
693
694
                          [],
694
695
                          [])
695
696
        self.assertRaises(errors.ReadOnlyError, vf.join, 'base')
696
 
        self.assertRaises(errors.ReadOnlyError, vf.clone_text, 'base', 'bar', ['foo'])
697
697
    
698
 
    def test_get_sha1(self):
 
698
    def test_get_sha1s(self):
699
699
        # check the sha1 data is available
700
700
        vf = self.get_file()
701
701
        # a simple file
704
704
        vf.add_lines('b', ['a'], ['a\n'])
705
705
        # a file differing only in last newline.
706
706
        vf.add_lines('c', [], ['a'])
707
 
        self.assertEqual(
708
 
            '3f786850e387550fdab836ed7e6dc881de23001b', vf.get_sha1('a'))
709
 
        self.assertEqual(
710
 
            '3f786850e387550fdab836ed7e6dc881de23001b', vf.get_sha1('b'))
711
 
        self.assertEqual(
712
 
            '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', vf.get_sha1('c'))
713
 
 
 
707
        # Deprecasted single-version API.
 
708
        self.assertEqual(
 
709
            '3f786850e387550fdab836ed7e6dc881de23001b',
 
710
            self.applyDeprecated(one_four, vf.get_sha1, 'a'))
 
711
        self.assertEqual(
 
712
            '3f786850e387550fdab836ed7e6dc881de23001b',
 
713
            self.applyDeprecated(one_four, vf.get_sha1, 'b'))
 
714
        self.assertEqual(
 
715
            '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8',
 
716
            self.applyDeprecated(one_four, vf.get_sha1, 'c'))
714
717
        self.assertEqual(['3f786850e387550fdab836ed7e6dc881de23001b',
715
718
                          '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8',
716
719
                          '3f786850e387550fdab836ed7e6dc881de23001b'],
720
723
class TestWeave(TestCaseWithMemoryTransport, VersionedFileTestMixIn):
721
724
 
722
725
    def get_file(self, name='foo'):
723
 
        return WeaveFile(name, get_transport(self.get_url('.')), create=True)
 
726
        return WeaveFile(name, get_transport(self.get_url('.')), create=True,
 
727
            get_scope=self.get_transaction)
724
728
 
725
729
    def get_file_corrupted_text(self):
726
 
        w = WeaveFile('foo', get_transport(self.get_url('.')), create=True)
 
730
        w = WeaveFile('foo', get_transport(self.get_url('.')), create=True,
 
731
            get_scope=self.get_transaction)
727
732
        w.add_lines('v1', [], ['hello\n'])
728
733
        w.add_lines('v2', ['v1'], ['hello\n', 'there\n'])
729
734
        
757
762
        return w
758
763
 
759
764
    def reopen_file(self, name='foo', create=False):
760
 
        return WeaveFile(name, get_transport(self.get_url('.')), create=create)
 
765
        return WeaveFile(name, get_transport(self.get_url('.')), create=create,
 
766
            get_scope=self.get_transaction)
761
767
 
762
768
    def test_no_implicit_create(self):
763
769
        self.assertRaises(errors.NoSuchFile,
764
770
                          WeaveFile,
765
771
                          'foo',
766
 
                          get_transport(self.get_url('.')))
 
772
                          get_transport(self.get_url('.')),
 
773
                          get_scope=self.get_transaction)
767
774
 
768
775
    def get_factory(self):
769
776
        return WeaveFile
773
780
 
774
781
    def get_file(self, name='foo'):
775
782
        return self.get_factory()(name, get_transport(self.get_url('.')),
776
 
                                  delta=True, create=True)
 
783
            delta=True, create=True, get_scope=self.get_transaction)
777
784
 
778
785
    def get_factory(self):
779
 
        return KnitVersionedFile
 
786
        return make_file_knit
780
787
 
781
788
    def get_file_corrupted_text(self):
782
789
        knit = self.get_file()
794
801
        knit.check()
795
802
 
796
803
    def test_no_implicit_create(self):
797
 
        self.assertRaises(errors.NoSuchFile,
798
 
                          KnitVersionedFile,
799
 
                          'foo',
800
 
                          get_transport(self.get_url('.')))
 
804
        self.assertRaises(errors.NoSuchFile, self.get_factory(), 'foo',
 
805
            get_transport(self.get_url('.')))
801
806
 
802
807
 
803
808
class TestPlaintextKnit(TestKnit):
804
809
    """Test a knit with no cached annotations"""
805
810
 
806
 
    def _factory(self, name, transport, file_mode=None, access_mode=None,
807
 
                 delta=True, create=False):
808
 
        return KnitVersionedFile(name, transport, file_mode, access_mode,
809
 
                                 KnitPlainFactory(), delta=delta,
810
 
                                 create=create)
811
 
 
812
811
    def get_factory(self):
813
 
        return self._factory
 
812
        return make_file_knit
814
813
 
815
814
 
816
815
class TestPlanMergeVersionedFile(TestCaseWithMemoryTransport):
817
816
 
818
817
    def setUp(self):
819
818
        TestCaseWithMemoryTransport.setUp(self)
820
 
        self.vf1 = KnitVersionedFile('root', self.get_transport(), create=True)
821
 
        self.vf2 = KnitVersionedFile('root', self.get_transport(), create=True)
 
819
        self.vf1 = make_file_knit('root', self.get_transport(), create=True)
 
820
        self.vf2 = make_file_knit('root', self.get_transport(), create=True)
822
821
        self.plan_merge_vf = versionedfile._PlanMergeVersionedFile('root',
823
822
            [self.vf1, self.vf2])
824
823
 
946
945
 
947
946
class TestReadonlyHttpMixin(object):
948
947
 
 
948
    def get_transaction(self):
 
949
        return 1
 
950
 
949
951
    def test_readonly_http_works(self):
950
952
        # we should be able to read from http with a versioned file.
951
953
        vf = self.get_file()
964
966
class TestWeaveHTTP(TestCaseWithWebserver, TestReadonlyHttpMixin):
965
967
 
966
968
    def get_file(self):
967
 
        return WeaveFile('foo', get_transport(self.get_url('.')), create=True)
 
969
        return WeaveFile('foo', get_transport(self.get_url('.')), create=True,
 
970
            get_scope=self.get_transaction)
968
971
 
969
972
    def get_factory(self):
970
973
        return WeaveFile
973
976
class TestKnitHTTP(TestCaseWithWebserver, TestReadonlyHttpMixin):
974
977
 
975
978
    def get_file(self):
976
 
        return KnitVersionedFile('foo', get_transport(self.get_url('.')),
977
 
                                 delta=True, create=True)
 
979
        return make_file_knit('foo', get_transport(self.get_url('.')),
 
980
            delta=True, create=True, get_scope=self.get_transaction)
978
981
 
979
982
    def get_factory(self):
980
 
        return KnitVersionedFile
 
983
        return make_file_knit
981
984
 
982
985
 
983
986
class MergeCasesMixin(object):
1220
1223
class TestKnitMerge(TestCaseWithMemoryTransport, MergeCasesMixin):
1221
1224
 
1222
1225
    def get_file(self, name='foo'):
1223
 
        return KnitVersionedFile(name, get_transport(self.get_url('.')),
 
1226
        return make_file_knit(name, get_transport(self.get_url('.')),
1224
1227
                                 delta=True, create=True)
1225
1228
 
1226
1229
    def log_contents(self, w):
1240
1243
 
1241
1244
    overlappedInsertExpected = ['aaa', '<<<<<<< ', 'xxx', 'yyy', '=======', 
1242
1245
                                'xxx', '>>>>>>> ', 'bbb']
1243
 
 
1244
 
 
1245
 
class TestFormatSignatures(TestCaseWithMemoryTransport):
1246
 
 
1247
 
    def get_knit_file(self, name, annotated):
1248
 
        if annotated:
1249
 
            factory = KnitAnnotateFactory()
1250
 
        else:
1251
 
            factory = KnitPlainFactory()
1252
 
        return KnitVersionedFile(
1253
 
            name, get_transport(self.get_url('.')), create=True,
1254
 
            factory=factory)
1255
 
 
1256
 
    def test_knit_format_signatures(self):
1257
 
        """Different formats of knit have different signature strings."""
1258
 
        knit = self.get_knit_file('a', True)
1259
 
        self.assertEqual('knit-annotated', knit.get_format_signature())
1260
 
        knit = self.get_knit_file('p', False)
1261
 
        self.assertEqual('knit-plain', knit.get_format_signature())
1262