/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_weave.py

  • Committer: Martin Pool
  • Date: 2007-10-03 08:06:44 UTC
  • mto: This revision was merged to the branch mainline in revision 2901.
  • Revision ID: mbp@sourcefrog.net-20071003080644-oivy0gkg98sex0ed
Avoid internal error tracebacks on failure to lock on readonly transport (#129701).

Add new LockFailed, which doesn't imply that we failed to get it because of
contention.  Raise this if we fail to create the pending or lock directories
because of Transport errors.

UnlockableTransport is not an internal error.

ReadOnlyLockError has a message which didn't match its name or usage; it's now
deprecated and callers are updated to use LockFailed which is more appropriate.

Add zero_ninetytwo deprecation symbol.

Unify assertMatchesRe with TestCase.assertContainsRe.

When the constructor is deprecated, just say that the class is deprecated, not
the __init__ method - this works better with applyDeprecated in tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
18
# TODO: tests regarding version names
19
 
# TODO: rbc 20050108 test that join does not leave an inconsistent weave
 
19
# TODO: rbc 20050108 test that join does not leave an inconsistent weave 
20
20
#       if it fails.
21
21
 
22
22
"""test suite for weave algorithm"""
65
65
class WeaveContains(TestBase):
66
66
    """Weave __contains__ operator"""
67
67
    def runTest(self):
68
 
        k = Weave(get_scope=lambda:None)
 
68
        k = Weave()
69
69
        self.assertFalse('foo' in k)
70
70
        k.add_lines('foo', [], TEXT_1)
71
71
        self.assertTrue('foo' in k)
84
84
                         [('text0', TEXT_0[0])])
85
85
 
86
86
 
 
87
class GetSha1(TestBase):
 
88
    def test_get_sha1(self):
 
89
        k = Weave()
 
90
        k.add_lines('text0', [], 'text0')
 
91
        self.assertEqual('34dc0e430c642a26c3dd1c2beb7a8b4f4445eb79',
 
92
                         k.get_sha1('text0'))
 
93
        self.assertRaises(errors.RevisionNotPresent,
 
94
                          k.get_sha1, 0)
 
95
        self.assertRaises(errors.RevisionNotPresent,
 
96
                          k.get_sha1, 'text1')
 
97
                        
 
98
 
87
99
class InvalidAdd(TestBase):
88
100
    """Try to use invalid version number during add."""
89
101
    def runTest(self):
121
133
                          'text0',
122
134
                          ['basis'],         # not the right parents
123
135
                          TEXT_0)
124
 
 
 
136
        
125
137
 
126
138
class InsertLines(TestBase):
127
139
    """Store a revision that adds one line to the original.
170
182
              ['text0', 'text1', 'text3'],
171
183
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
172
184
 
173
 
        self.assertEqual(k.annotate('text4'),
 
185
        self.assertEqual(k.annotate('text4'), 
174
186
                         [('text0', 'line 1'),
175
187
                          ('text4', 'aaa'),
176
188
                          ('text3', 'middle line'),
189
201
        base_text = ['one', 'two', 'three', 'four']
190
202
 
191
203
        k.add_lines('text0', [], base_text)
192
 
 
 
204
        
193
205
        texts = [['one', 'two', 'three'],
194
206
                 ['two', 'three', 'four'],
195
207
                 ['one', 'four'],
226
238
                ]
227
239
        ################################### SKIPPED
228
240
        # Weave.get doesn't trap this anymore
229
 
        return
 
241
        return 
230
242
 
231
243
        self.assertRaises(WeaveFormatError,
232
244
                          k.get_lines,
233
 
                          0)
 
245
                          0)        
234
246
 
235
247
 
236
248
class CannedDelete(TestBase):
278
290
                'line to be deleted',
279
291
                (']', 1),
280
292
                ('{', 1),
281
 
                'replacement line',
 
293
                'replacement line',                
282
294
                ('}', 1),
283
295
                'last line',
284
296
                ('}', 0),
321
333
 
322
334
        ################################### SKIPPED
323
335
        # Weave.get doesn't trap this anymore
324
 
        return
 
336
        return 
325
337
 
326
338
 
327
339
        self.assertRaises(WeaveFormatError,
399
411
                          '  added in version 1',
400
412
                          '  also from v1',
401
413
                          '}'])
402
 
 
 
414
                       
403
415
        self.assertEqual(k.get_lines(2),
404
416
                         ['foo {',
405
417
                          '  added in v2',
411
423
                          '  added in v2',
412
424
                          '  also from v1',
413
425
                          '}'])
414
 
 
 
426
                         
415
427
 
416
428
class DeleteLines2(TestBase):
417
429
    """Test recording revisions that delete lines.
493
505
                ('}', 1),
494
506
                ('{', 2),
495
507
                "alternative second line",
496
 
                ('}', 2),
 
508
                ('}', 2),                
497
509
                ]
498
510
 
499
511
        k._sha1s = [sha_string('first line')
521
533
 
522
534
        text0 = ['cheddar', 'stilton', 'gruyere']
523
535
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
524
 
 
 
536
        
525
537
        k.add_lines('text0', [], text0)
526
538
        k.add_lines('text1', ['text0'], text1)
527
539
 
609
621
            A Jug of Wine, a Loaf of Bread, -- and Thou
610
622
            Beside me singing in the Wilderness --
611
623
            Oh, Wilderness were Paradise enow!""",
612
 
 
 
624
            
613
625
            """A Book of Verses underneath the Bough,
614
626
            A Jug of Wine, a Loaf of Bread, -- and Thou
615
627
            Beside me singing in the Wilderness --
657
669
        self.weave1.add_lines('v1', [], self.lines1)
658
670
        self.weave1.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
659
671
        self.weave1.add_lines('v3', ['v2'], self.lines3)
 
672
        
 
673
    def test_join_empty(self):
 
674
        """Join two empty weaves."""
 
675
        eq = self.assertEqual
 
676
        w1 = Weave()
 
677
        w2 = Weave()
 
678
        w1.join(w2)
 
679
        eq(len(w1), 0)
 
680
        
 
681
    def test_join_empty_to_nonempty(self):
 
682
        """Join empty weave onto nonempty."""
 
683
        self.weave1.join(Weave())
 
684
        self.assertEqual(len(self.weave1), 3)
 
685
 
 
686
    def test_join_unrelated(self):
 
687
        """Join two weaves with no history in common."""
 
688
        wb = Weave()
 
689
        wb.add_lines('b1', [], ['line from b\n'])
 
690
        w1 = self.weave1
 
691
        w1.join(wb)
 
692
        eq = self.assertEqual
 
693
        eq(len(w1), 4)
 
694
        eq(sorted(w1.versions()),
 
695
           ['b1', 'v1', 'v2', 'v3'])
 
696
 
 
697
    def test_join_related(self):
 
698
        wa = self.weave1.copy()
 
699
        wb = self.weave1.copy()
 
700
        wa.add_lines('a1', ['v3'], ['hello\n', 'sweet\n', 'world\n'])
 
701
        wb.add_lines('b1', ['v3'], ['hello\n', 'pale blue\n', 'world\n'])
 
702
        eq = self.assertEquals
 
703
        eq(len(wa), 4)
 
704
        eq(len(wb), 4)
 
705
        wa.join(wb)
 
706
        eq(len(wa), 5)
 
707
        eq(wa.get_lines('b1'),
 
708
           ['hello\n', 'pale blue\n', 'world\n'])
 
709
 
 
710
    def test_join_text_disagreement(self):
 
711
        """Cannot join weaves with different texts for a version."""
 
712
        wa = Weave()
 
713
        wb = Weave()
 
714
        wa.add_lines('v1', [], ['hello\n'])
 
715
        wb.add_lines('v1', [], ['not\n', 'hello\n'])
 
716
        self.assertRaises(WeaveError,
 
717
                          wa.join, wb)
 
718
 
 
719
    def test_join_unordered(self):
 
720
        """Join weaves where indexes differ.
 
721
        
 
722
        The source weave contains a different version at index 0."""
 
723
        wa = self.weave1.copy()
 
724
        wb = Weave()
 
725
        wb.add_lines('x1', [], ['line from x1\n'])
 
726
        wb.add_lines('v1', [], ['hello\n'])
 
727
        wb.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
 
728
        wa.join(wb)
 
729
        eq = self.assertEquals
 
730
        eq(sorted(wa.versions()), ['v1', 'v2', 'v3', 'x1',])
 
731
        eq(wa.get_text('x1'), 'line from x1\n')
660
732
 
661
733
    def test_written_detection(self):
662
734
        # Test detection of weave file corruption.
707
779
        self.assertRaises(errors.WeaveInvalidChecksum, w.check)
708
780
 
709
781
 
710
 
class TestWeave(TestCase):
711
 
 
712
 
    def test_allow_reserved_false(self):
713
 
        w = Weave('name', allow_reserved=False)
714
 
        # Add lines is checked at the WeaveFile level, not at the Weave level
715
 
        w.add_lines('name:', [], TEXT_1)
716
 
        # But get_lines is checked at this level
717
 
        self.assertRaises(errors.ReservedId, w.get_lines, 'name:')
718
 
 
719
 
    def test_allow_reserved_true(self):
720
 
        w = Weave('name', allow_reserved=True)
721
 
        w.add_lines('name:', [], TEXT_1)
722
 
        self.assertEqual(TEXT_1, w.get_lines('name:'))
723
 
 
724
 
 
725
782
class InstrumentedWeave(Weave):
726
783
    """Keep track of how many times functions are called."""
727
 
 
 
784
    
728
785
    def __init__(self, weave_name=None):
729
786
        self._extract_count = 0
730
787
        Weave.__init__(self, weave_name=weave_name)
734
791
        return Weave._extract(self, versions)
735
792
 
736
793
 
 
794
class JoinOptimization(TestCase):
 
795
    """Test that Weave.join() doesn't extract all texts, only what must be done."""
 
796
 
 
797
    def test_join(self):
 
798
        w1 = InstrumentedWeave()
 
799
        w2 = InstrumentedWeave()
 
800
 
 
801
        txt0 = ['a\n']
 
802
        txt1 = ['a\n', 'b\n']
 
803
        txt2 = ['a\n', 'c\n']
 
804
        txt3 = ['a\n', 'b\n', 'c\n']
 
805
 
 
806
        w1.add_lines('txt0', [], txt0) # extract 1a
 
807
        w2.add_lines('txt0', [], txt0) # extract 1b
 
808
        w1.add_lines('txt1', ['txt0'], txt1)# extract 2a
 
809
        w2.add_lines('txt2', ['txt0'], txt2)# extract 2b
 
810
        w1.join(w2) # extract 3a to add txt2 
 
811
        w2.join(w1) # extract 3b to add txt1 
 
812
 
 
813
        w1.add_lines('txt3', ['txt1', 'txt2'], txt3) # extract 4a 
 
814
        w2.add_lines('txt3', ['txt2', 'txt1'], txt3) # extract 4b
 
815
        # These secretly have inverted parents
 
816
 
 
817
        # This should not have to do any extractions
 
818
        w1.join(w2) # NO extract, texts already present with same parents
 
819
        w2.join(w1) # NO extract, texts already present with same parents
 
820
 
 
821
        self.assertEqual(4, w1._extract_count)
 
822
        self.assertEqual(4, w2._extract_count)
 
823
 
 
824
    def test_double_parent(self):
 
825
        # It should not be considered illegal to add
 
826
        # a revision with the same parent twice
 
827
        w1 = InstrumentedWeave()
 
828
        w2 = InstrumentedWeave()
 
829
 
 
830
        txt0 = ['a\n']
 
831
        txt1 = ['a\n', 'b\n']
 
832
        txt2 = ['a\n', 'c\n']
 
833
        txt3 = ['a\n', 'b\n', 'c\n']
 
834
 
 
835
        w1.add_lines('txt0', [], txt0)
 
836
        w2.add_lines('txt0', [], txt0)
 
837
        w1.add_lines('txt1', ['txt0'], txt1)
 
838
        w2.add_lines('txt1', ['txt0', 'txt0'], txt1)
 
839
        # Same text, effectively the same, because the
 
840
        # parent is only repeated
 
841
        w1.join(w2) # extract 3a to add txt2 
 
842
        w2.join(w1) # extract 3b to add txt1 
 
843
 
 
844
 
737
845
class TestNeedsReweave(TestCase):
738
846
    """Internal corner cases for when reweave is needed."""
739
847
 
753
861
 
754
862
 
755
863
class TestWeaveFile(TestCaseInTempDir):
756
 
 
 
864
    
757
865
    def test_empty_file(self):
758
866
        f = open('empty.weave', 'wb+')
759
867
        try: