~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_versionedfile.py

  • Committer: Aaron Bentley
  • Date: 2006-03-31 02:39:09 UTC
  • mfrom: (1558.7.10 bzr.ab.integration)
  • mto: This revision was merged to the branch mainline in revision 1634.
  • Revision ID: aaron.bentley@utoronto.ca-20060331023909-957277c1233c6aff
Merge from bzr.ab.integration

Show diffs side-by-side

added added

removed removed

Lines of Context:
66
66
        f = self.reopen_file()
67
67
        verify_file(f)
68
68
 
 
69
    def test_adds_with_parent_texts(self):
 
70
        f = self.get_file()
 
71
        parent_texts = {}
 
72
        parent_texts['r0'] = f.add_lines('r0', [], ['a\n', 'b\n'])
 
73
        try:
 
74
            parent_texts['r1'] = f.add_lines_with_ghosts('r1',
 
75
                                                         ['r0', 'ghost'], 
 
76
                                                         ['b\n', 'c\n'],
 
77
                                                         parent_texts=parent_texts)
 
78
        except NotImplementedError:
 
79
            # if the format doesn't support ghosts, just add normally.
 
80
            parent_texts['r1'] = f.add_lines('r1',
 
81
                                             ['r0'], 
 
82
                                             ['b\n', 'c\n'],
 
83
                                             parent_texts=parent_texts)
 
84
        f.add_lines('r2', ['r1'], ['c\n', 'd\n'], parent_texts=parent_texts)
 
85
        self.assertNotEqual(None, parent_texts['r0'])
 
86
        self.assertNotEqual(None, parent_texts['r1'])
 
87
        def verify_file(f):
 
88
            versions = f.versions()
 
89
            self.assertTrue('r0' in versions)
 
90
            self.assertTrue('r1' in versions)
 
91
            self.assertTrue('r2' in versions)
 
92
            self.assertEquals(f.get_lines('r0'), ['a\n', 'b\n'])
 
93
            self.assertEquals(f.get_lines('r1'), ['b\n', 'c\n'])
 
94
            self.assertEquals(f.get_lines('r2'), ['c\n', 'd\n'])
 
95
            self.assertEqual(3, f.num_versions())
 
96
            origins = f.annotate('r1')
 
97
            self.assertEquals(origins[0][0], 'r0')
 
98
            self.assertEquals(origins[1][0], 'r1')
 
99
            origins = f.annotate('r2')
 
100
            self.assertEquals(origins[0][0], 'r1')
 
101
            self.assertEquals(origins[1][0], 'r2')
 
102
 
 
103
        verify_file(f)
 
104
        f = self.reopen_file()
 
105
        verify_file(f)
 
106
 
 
107
    def test_get_delta(self):
 
108
        f = self.get_file()
 
109
        sha1s = self._setup_for_deltas(f)
 
110
        expected_delta = (None, '6bfa09d82ce3e898ad4641ae13dd4fdb9cf0d76b', False, 
 
111
                          [(0, 0, 1, [('base', 'line\n')])])
 
112
        self.assertEqual(expected_delta, f.get_delta('base'))
 
113
        next_parent = 'base'
 
114
        text_name = 'chain1-'
 
115
        for depth in range(26):
 
116
            new_version = text_name + '%s' % depth
 
117
            expected_delta = (next_parent, sha1s[depth], 
 
118
                              False,
 
119
                              [(depth + 1, depth + 1, 1, [(new_version, 'line\n')])])
 
120
            self.assertEqual(expected_delta, f.get_delta(new_version))
 
121
            next_parent = new_version
 
122
        next_parent = 'base'
 
123
        text_name = 'chain2-'
 
124
        for depth in range(26):
 
125
            new_version = text_name + '%s' % depth
 
126
            expected_delta = (next_parent, sha1s[depth], False,
 
127
                              [(depth + 1, depth + 1, 1, [(new_version, 'line\n')])])
 
128
            self.assertEqual(expected_delta, f.get_delta(new_version))
 
129
            next_parent = new_version
 
130
        # smoke test for eol support
 
131
        expected_delta = ('base', '264f39cab871e4cfd65b3a002f7255888bb5ed97', True, [])
 
132
        self.assertEqual(['line'], f.get_lines('noeol'))
 
133
        self.assertEqual(expected_delta, f.get_delta('noeol'))
 
134
 
 
135
    def test_get_deltas(self):
 
136
        f = self.get_file()
 
137
        sha1s = self._setup_for_deltas(f)
 
138
        deltas = f.get_deltas(f.versions())
 
139
        expected_delta = (None, '6bfa09d82ce3e898ad4641ae13dd4fdb9cf0d76b', False, 
 
140
                          [(0, 0, 1, [('base', 'line\n')])])
 
141
        self.assertEqual(expected_delta, deltas['base'])
 
142
        next_parent = 'base'
 
143
        text_name = 'chain1-'
 
144
        for depth in range(26):
 
145
            new_version = text_name + '%s' % depth
 
146
            expected_delta = (next_parent, sha1s[depth], 
 
147
                              False,
 
148
                              [(depth + 1, depth + 1, 1, [(new_version, 'line\n')])])
 
149
            self.assertEqual(expected_delta, deltas[new_version])
 
150
            next_parent = new_version
 
151
        next_parent = 'base'
 
152
        text_name = 'chain2-'
 
153
        for depth in range(26):
 
154
            new_version = text_name + '%s' % depth
 
155
            expected_delta = (next_parent, sha1s[depth], False,
 
156
                              [(depth + 1, depth + 1, 1, [(new_version, 'line\n')])])
 
157
            self.assertEqual(expected_delta, deltas[new_version])
 
158
            next_parent = new_version
 
159
        # smoke tests for eol support
 
160
        expected_delta = ('base', '264f39cab871e4cfd65b3a002f7255888bb5ed97', True, [])
 
161
        self.assertEqual(['line'], f.get_lines('noeol'))
 
162
        self.assertEqual(expected_delta, deltas['noeol'])
 
163
        # smoke tests for eol support - two noeol in a row same content
 
164
        expected_deltas = (('noeol', '3ad7ee82dbd8f29ecba073f96e43e414b3f70a4d', True, 
 
165
                          [(0, 1, 2, [(u'noeolsecond', 'line\n'), (u'noeolsecond', 'line\n')])]),
 
166
                          ('noeol', '3ad7ee82dbd8f29ecba073f96e43e414b3f70a4d', True, 
 
167
                           [(0, 0, 1, [('noeolsecond', 'line\n')]), (1, 1, 0, [])]))
 
168
        self.assertEqual(['line\n', 'line'], f.get_lines('noeolsecond'))
 
169
        self.assertTrue(deltas['noeolsecond'] in expected_deltas)
 
170
        # two no-eol in a row, different content
 
171
        expected_delta = ('noeolsecond', '8bb553a84e019ef1149db082d65f3133b195223b', True, 
 
172
                          [(1, 2, 1, [(u'noeolnotshared', 'phone\n')])])
 
173
        self.assertEqual(['line\n', 'phone'], f.get_lines('noeolnotshared'))
 
174
        self.assertEqual(expected_delta, deltas['noeolnotshared'])
 
175
        # eol folling a no-eol with content change
 
176
        expected_delta = ('noeol', 'a61f6fb6cfc4596e8d88c34a308d1e724caf8977', False, 
 
177
                          [(0, 1, 1, [(u'eol', 'phone\n')])])
 
178
        self.assertEqual(['phone\n'], f.get_lines('eol'))
 
179
        self.assertEqual(expected_delta, deltas['eol'])
 
180
        # eol folling a no-eol with content change
 
181
        expected_delta = ('noeol', '6bfa09d82ce3e898ad4641ae13dd4fdb9cf0d76b', False, 
 
182
                          [(0, 1, 1, [(u'eolline', 'line\n')])])
 
183
        self.assertEqual(['line\n'], f.get_lines('eolline'))
 
184
        self.assertEqual(expected_delta, deltas['eolline'])
 
185
        # eol with no parents
 
186
        expected_delta = (None, '264f39cab871e4cfd65b3a002f7255888bb5ed97', True, 
 
187
                          [(0, 0, 1, [(u'noeolbase', 'line\n')])])
 
188
        self.assertEqual(['line'], f.get_lines('noeolbase'))
 
189
        self.assertEqual(expected_delta, deltas['noeolbase'])
 
190
        # eol with two parents, in inverse insertion order
 
191
        expected_deltas = (('noeolbase', '264f39cab871e4cfd65b3a002f7255888bb5ed97', True,
 
192
                            [(0, 1, 1, [(u'eolbeforefirstparent', 'line\n')])]),
 
193
                           ('noeolbase', '264f39cab871e4cfd65b3a002f7255888bb5ed97', True,
 
194
                            [(0, 1, 1, [(u'eolbeforefirstparent', 'line\n')])]))
 
195
        self.assertEqual(['line'], f.get_lines('eolbeforefirstparent'))
 
196
        #self.assertTrue(deltas['eolbeforefirstparent'] in expected_deltas)
 
197
 
 
198
    def _setup_for_deltas(self, f):
 
199
        self.assertRaises(errors.RevisionNotPresent, f.get_delta, 'base')
 
200
        # add texts that should trip the knit maximum delta chain threshold
 
201
        # as well as doing parallel chains of data in knits.
 
202
        # this is done by two chains of 25 insertions
 
203
        f.add_lines('base', [], ['line\n'])
 
204
        f.add_lines('noeol', ['base'], ['line'])
 
205
        # detailed eol tests:
 
206
        # shared last line with parent no-eol
 
207
        f.add_lines('noeolsecond', ['noeol'], ['line\n', 'line'])
 
208
        # differing last line with parent, both no-eol
 
209
        f.add_lines('noeolnotshared', ['noeolsecond'], ['line\n', 'phone'])
 
210
        # add eol following a noneol parent, change content
 
211
        f.add_lines('eol', ['noeol'], ['phone\n'])
 
212
        # add eol following a noneol parent, no change content
 
213
        f.add_lines('eolline', ['noeol'], ['line\n'])
 
214
        # noeol with no parents:
 
215
        f.add_lines('noeolbase', [], ['line'])
 
216
        # noeol preceeding its leftmost parent in the output:
 
217
        # this is done by making it a merge of two parents with no common
 
218
        # anestry: noeolbase and noeol with the 
 
219
        # later-inserted parent the leftmost.
 
220
        f.add_lines('eolbeforefirstparent', ['noeolbase', 'noeol'], ['line'])
 
221
        # two identical eol texts
 
222
        f.add_lines('noeoldup', ['noeol'], ['line'])
 
223
        next_parent = 'base'
 
224
        text_name = 'chain1-'
 
225
        text = ['line\n']
 
226
        sha1s = {0 :'da6d3141cb4a5e6f464bf6e0518042ddc7bfd079',
 
227
                 1 :'45e21ea146a81ea44a821737acdb4f9791c8abe7',
 
228
                 2 :'e1f11570edf3e2a070052366c582837a4fe4e9fa',
 
229
                 3 :'26b4b8626da827088c514b8f9bbe4ebf181edda1',
 
230
                 4 :'e28a5510be25ba84d31121cff00956f9970ae6f6',
 
231
                 5 :'d63ec0ce22e11dcf65a931b69255d3ac747a318d',
 
232
                 6 :'2c2888d288cb5e1d98009d822fedfe6019c6a4ea',
 
233
                 7 :'95c14da9cafbf828e3e74a6f016d87926ba234ab',
 
234
                 8 :'779e9a0b28f9f832528d4b21e17e168c67697272',
 
235
                 9 :'1f8ff4e5c6ff78ac106fcfe6b1e8cb8740ff9a8f',
 
236
                 10:'131a2ae712cf51ed62f143e3fbac3d4206c25a05',
 
237
                 11:'c5a9d6f520d2515e1ec401a8f8a67e6c3c89f199',
 
238
                 12:'31a2286267f24d8bedaa43355f8ad7129509ea85',
 
239
                 13:'dc2a7fe80e8ec5cae920973973a8ee28b2da5e0a',
 
240
                 14:'2c4b1736566b8ca6051e668de68650686a3922f2',
 
241
                 15:'5912e4ecd9b0c07be4d013e7e2bdcf9323276cde',
 
242
                 16:'b0d2e18d3559a00580f6b49804c23fea500feab3',
 
243
                 17:'8e1d43ad72f7562d7cb8f57ee584e20eb1a69fc7',
 
244
                 18:'5cf64a3459ae28efa60239e44b20312d25b253f3',
 
245
                 19:'1ebed371807ba5935958ad0884595126e8c4e823',
 
246
                 20:'2aa62a8b06fb3b3b892a3292a068ade69d5ee0d3',
 
247
                 21:'01edc447978004f6e4e962b417a4ae1955b6fe5d',
 
248
                 22:'d8d8dc49c4bf0bab401e0298bb5ad827768618bb',
 
249
                 23:'c21f62b1c482862983a8ffb2b0c64b3451876e3f',
 
250
                 24:'c0593fe795e00dff6b3c0fe857a074364d5f04fc',
 
251
                 25:'dd1a1cf2ba9cc225c3aff729953e6364bf1d1855',
 
252
                 }
 
253
        for depth in range(26):
 
254
            new_version = text_name + '%s' % depth
 
255
            text = text + ['line\n']
 
256
            f.add_lines(new_version, [next_parent], text)
 
257
            next_parent = new_version
 
258
        next_parent = 'base'
 
259
        text_name = 'chain2-'
 
260
        text = ['line\n']
 
261
        for depth in range(26):
 
262
            new_version = text_name + '%s' % depth
 
263
            text = text + ['line\n']
 
264
            f.add_lines(new_version, [next_parent], text)
 
265
            next_parent = new_version
 
266
        return sha1s
 
267
 
 
268
    def test_add_delta(self):
 
269
        # tests for the add-delta facility.
 
270
        # at this point, optimising for speed, we assume no checks when deltas are inserted.
 
271
        # this may need to be revisited.
 
272
        source = self.get_file('source')
 
273
        source.add_lines('base', [], ['line\n'])
 
274
        next_parent = 'base'
 
275
        text_name = 'chain1-'
 
276
        text = ['line\n']
 
277
        for depth in range(26):
 
278
            new_version = text_name + '%s' % depth
 
279
            text = text + ['line\n']
 
280
            source.add_lines(new_version, [next_parent], text)
 
281
            next_parent = new_version
 
282
        next_parent = 'base'
 
283
        text_name = 'chain2-'
 
284
        text = ['line\n']
 
285
        for depth in range(26):
 
286
            new_version = text_name + '%s' % depth
 
287
            text = text + ['line\n']
 
288
            source.add_lines(new_version, [next_parent], text)
 
289
            next_parent = new_version
 
290
        source.add_lines('noeol', ['base'], ['line'])
 
291
        
 
292
        target = self.get_file('target')
 
293
        for version in source.versions():
 
294
            parent, sha1, noeol, delta = source.get_delta(version)
 
295
            target.add_delta(version,
 
296
                             source.get_parents(version),
 
297
                             parent,
 
298
                             sha1,
 
299
                             noeol,
 
300
                             delta)
 
301
        self.assertRaises(RevisionAlreadyPresent,
 
302
                          target.add_delta, 'base', [], None, '', False, [])
 
303
        for version in source.versions():
 
304
            self.assertEqual(source.get_lines(version),
 
305
                             target.get_lines(version))
 
306
 
69
307
    def test_ancestry(self):
70
308
        f = self.get_file()
71
309
        self.assertEqual([], f.get_ancestry([]))
97
335
    def test_mutate_after_finish(self):
98
336
        f = self.get_file()
99
337
        f.transaction_finished()
 
338
        self.assertRaises(errors.OutSideTransaction, f.add_delta, '', [], '', '', False, [])
100
339
        self.assertRaises(errors.OutSideTransaction, f.add_lines, '', [], [])
101
340
        self.assertRaises(errors.OutSideTransaction, f.add_lines_with_ghosts, '', [], [])
102
341
        self.assertRaises(errors.OutSideTransaction, f.fix_parents, '', [])
387
626
        factory = self.get_factory()
388
627
        vf = factory('id', transport, 0777, create=True, access_mode='w')
389
628
        vf = factory('id', transport, access_mode='r')
 
629
        self.assertRaises(errors.ReadOnlyError, vf.add_delta, '', [], '', '', False, [])
390
630
        self.assertRaises(errors.ReadOnlyError, vf.add_lines, 'base', [], [])
391
631
        self.assertRaises(errors.ReadOnlyError,
392
632
                          vf.add_lines_with_ghosts,