/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 breezy/tests/per_versionedfile.py

  • Committer: Jelmer Vernooij
  • Date: 2019-03-05 07:32:38 UTC
  • mto: (7290.1.21 work)
  • mto: This revision was merged to the branch mainline in revision 7311.
  • Revision ID: jelmer@jelmer.uk-20190305073238-zlqn981opwnqsmzi
Add appveyor configuration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
# considered typical and check that it can be detected/corrected.
23
23
 
24
24
from gzip import GzipFile
25
 
from io import BytesIO
26
25
import itertools
27
26
 
28
 
from ... import (
 
27
from .. import (
29
28
    errors,
30
29
    graph as _mod_graph,
31
30
    osutils,
33
32
    transport,
34
33
    ui,
35
34
    )
36
 
from .. import (
 
35
from ..bzr import (
37
36
    groupcompress,
38
37
    knit as _mod_knit,
39
38
    )
40
 
from ...errors import (
 
39
from ..errors import (
41
40
    RevisionNotPresent,
42
41
    RevisionAlreadyPresent,
43
42
    )
44
 
from ..knit import (
 
43
from ..bzr.knit import (
45
44
    cleanup_pack_knit,
46
45
    make_file_factory,
47
46
    make_pack_factory,
48
47
    )
49
 
from ...tests import (
 
48
from ..sixish import (
 
49
    BytesIO,
 
50
    zip,
 
51
    )
 
52
from . import (
50
53
    TestCase,
51
54
    TestCaseWithMemoryTransport,
52
55
    TestNotApplicable,
53
56
    TestSkipped,
54
57
    )
55
 
from ...tests.http_utils import TestCaseWithWebserver
56
 
from ...transport.memory import MemoryTransport
57
 
from .. import versionedfile as versionedfile
58
 
from ..versionedfile import (
59
 
    ChunkedContentFactory,
 
58
from .http_utils import TestCaseWithWebserver
 
59
from ..transport.memory import MemoryTransport
 
60
from ..bzr import versionedfile as versionedfile
 
61
from ..bzr.versionedfile import (
60
62
    ConstantMapper,
61
 
    ExistingContent,
62
63
    HashEscapedPrefixMapper,
63
64
    PrefixMapper,
64
 
    UnavailableRepresentation,
65
65
    VirtualVersionedFiles,
66
66
    make_versioned_files_factory,
67
67
    )
68
 
from ..weave import (
 
68
from ..bzr.weave import (
69
69
    WeaveFile,
70
70
    WeaveInvalidChecksum,
71
71
    )
72
 
from ..weavefile import write_weave
73
 
from ...tests.scenarios import load_tests_apply_scenarios
 
72
from ..bzr.weavefile import write_weave
 
73
from .scenarios import load_tests_apply_scenarios
74
74
 
75
75
 
76
76
load_tests = load_tests_apply_scenarios
305
305
        # we now have a copy of all the lines in the vf.
306
306
        for sha, (version, lines) in zip(
307
307
                shas, (empty_text, sample_text_nl, sample_text_no_nl)):
308
 
            self.assertRaises(ExistingContent,
 
308
            self.assertRaises(errors.ExistingContent,
309
309
                              vf.add_lines, version + b"2", [], lines,
310
310
                              nostore_sha=sha)
311
311
            # and no new version should have been added.
330
330
            raise TestSkipped("add_lines_with_ghosts is optional")
331
331
        for sha, (version, lines) in zip(
332
332
                shas, (empty_text, sample_text_nl, sample_text_no_nl)):
333
 
            self.assertRaises(ExistingContent,
 
333
            self.assertRaises(errors.ExistingContent,
334
334
                              vf.add_lines_with_ghosts, version + b"2", [], lines,
335
335
                              nostore_sha=sha)
336
336
            # and no new version should have been added.
534
534
 
535
535
    def test_ancestry(self):
536
536
        f = self.get_file()
537
 
        self.assertEqual(set(), f.get_ancestry([]))
 
537
        self.assertEqual([], f.get_ancestry([]))
538
538
        f.add_lines(b'r0', [], [b'a\n', b'b\n'])
539
539
        f.add_lines(b'r1', [b'r0'], [b'b\n', b'c\n'])
540
540
        f.add_lines(b'r2', [b'r0'], [b'b\n', b'c\n'])
541
541
        f.add_lines(b'r3', [b'r2'], [b'b\n', b'c\n'])
542
542
        f.add_lines(b'rM', [b'r1', b'r2'], [b'b\n', b'c\n'])
543
 
        self.assertEqual(set(), f.get_ancestry([]))
 
543
        self.assertEqual([], f.get_ancestry([]))
544
544
        versions = f.get_ancestry([b'rM'])
 
545
        # there are some possibilities:
 
546
        # r0 r1 r2 rM r3
 
547
        # r0 r1 r2 r3 rM
 
548
        # etc
 
549
        # so we check indexes
 
550
        r0 = versions.index(b'r0')
 
551
        r1 = versions.index(b'r1')
 
552
        r2 = versions.index(b'r2')
 
553
        self.assertFalse(b'r3' in versions)
 
554
        rM = versions.index(b'rM')
 
555
        self.assertTrue(r0 < r1)
 
556
        self.assertTrue(r0 < r2)
 
557
        self.assertTrue(r1 < rM)
 
558
        self.assertTrue(r2 < rM)
545
559
 
546
560
        self.assertRaises(RevisionNotPresent,
547
561
                          f.get_ancestry, [b'rM', b'rX'])
548
562
 
549
563
        self.assertEqual(set(f.get_ancestry(b'rM')),
550
 
                         set(f.get_ancestry(b'rM')))
 
564
                         set(f.get_ancestry(b'rM', topo_sorted=False)))
551
565
 
552
566
    def test_mutate_after_finish(self):
553
567
        self._transaction = 'before'
720
734
        # test key graph related apis: getncestry, _graph, get_parents
721
735
        # has_version
722
736
        # - these are ghost unaware and must not be reflect ghosts
723
 
        self.assertEqual(set([b'notbxbfse']), vf.get_ancestry(b'notbxbfse'))
 
737
        self.assertEqual([b'notbxbfse'], vf.get_ancestry(b'notbxbfse'))
724
738
        self.assertFalse(vf.has_version(parent_id_utf8))
725
739
        # we have _with_ghost apis to give us ghost information.
726
 
        self.assertEqual(set([parent_id_utf8, b'notbxbfse']),
 
740
        self.assertEqual([parent_id_utf8, b'notbxbfse'],
727
741
                         vf.get_ancestry_with_ghosts([b'notbxbfse']))
728
742
        self.assertEqual([parent_id_utf8],
729
743
                         vf.get_parents_with_ghosts(b'notbxbfse'))
730
744
        # if we add something that is a ghost of another, it should correct the
731
745
        # results of the prior apis
732
746
        vf.add_lines(parent_id_utf8, [], [])
733
 
        self.assertEqual(set([parent_id_utf8, b'notbxbfse']),
 
747
        self.assertEqual([parent_id_utf8, b'notbxbfse'],
734
748
                         vf.get_ancestry([b'notbxbfse']))
735
749
        self.assertEqual({b'notbxbfse': (parent_id_utf8,)},
736
750
                         vf.get_parent_map([b'notbxbfse']))
737
751
        self.assertTrue(vf.has_version(parent_id_utf8))
738
752
        # we have _with_ghost apis to give us ghost information.
739
 
        self.assertEqual(set([parent_id_utf8, b'notbxbfse']),
 
753
        self.assertEqual([parent_id_utf8, b'notbxbfse'],
740
754
                         vf.get_ancestry_with_ghosts([b'notbxbfse']))
741
755
        self.assertEqual([parent_id_utf8],
742
756
                         vf.get_parents_with_ghosts(b'notbxbfse'))
895
909
            return next(self.plan_merge_vf.get_record_stream(
896
910
                [(b'root', suffix)], 'unordered', True))
897
911
        self.assertEqual(b'a', get_record(b'A').get_bytes_as('fulltext'))
898
 
        self.assertEqual(b'a', b''.join(get_record(b'A').iter_bytes_as('chunked')))
899
912
        self.assertEqual(b'c', get_record(b'C').get_bytes_as('fulltext'))
900
913
        self.assertEqual(b'e', get_record(b'E:').get_bytes_as('fulltext'))
901
914
        self.assertEqual('absent', get_record('F').storage_kind)
1201
1214
        # Each is source_kind, requested_kind, adapter class
1202
1215
        scenarios = [
1203
1216
            ('knit-delta-gz', 'fulltext', _mod_knit.DeltaPlainToFullText),
1204
 
            ('knit-delta-gz', 'lines', _mod_knit.DeltaPlainToFullText),
1205
 
            ('knit-delta-gz', 'chunked', _mod_knit.DeltaPlainToFullText),
1206
1217
            ('knit-ft-gz', 'fulltext', _mod_knit.FTPlainToFullText),
1207
 
            ('knit-ft-gz', 'lines', _mod_knit.FTPlainToFullText),
1208
 
            ('knit-ft-gz', 'chunked', _mod_knit.FTPlainToFullText),
1209
1218
            ('knit-annotated-delta-gz', 'knit-delta-gz',
1210
1219
                _mod_knit.DeltaAnnotatedToUnannotated),
1211
1220
            ('knit-annotated-delta-gz', 'fulltext',
1214
1223
                _mod_knit.FTAnnotatedToUnannotated),
1215
1224
            ('knit-annotated-ft-gz', 'fulltext',
1216
1225
                _mod_knit.FTAnnotatedToFullText),
1217
 
            ('knit-annotated-ft-gz', 'lines',
1218
 
                _mod_knit.FTAnnotatedToFullText),
1219
 
            ('knit-annotated-ft-gz', 'chunked',
1220
 
                _mod_knit.FTAnnotatedToFullText),
1221
1226
            ]
1222
1227
        for source, requested, klass in scenarios:
1223
1228
            adapter_factory = versionedfile.adapter_registry.get(
1230
1235
        transport = self.get_transport()
1231
1236
        return make_file_factory(annotated, mapper)(transport)
1232
1237
 
1233
 
    def helpGetBytes(self, f, ft_name, ft_adapter, delta_name, delta_adapter):
 
1238
    def helpGetBytes(self, f, ft_adapter, delta_adapter):
1234
1239
        """Grab the interested adapted texts for tests."""
1235
1240
        # origin is a fulltext
1236
1241
        entries = f.get_record_stream([(b'origin',)], 'unordered', False)
1237
1242
        base = next(entries)
1238
 
        ft_data = ft_adapter.get_bytes(base, ft_name)
 
1243
        ft_data = ft_adapter.get_bytes(base)
1239
1244
        # merged is both a delta and multiple parents.
1240
1245
        entries = f.get_record_stream([(b'merged',)], 'unordered', False)
1241
1246
        merged = next(entries)
1242
 
        delta_data = delta_adapter.get_bytes(merged, delta_name)
 
1247
        delta_data = delta_adapter.get_bytes(merged)
1243
1248
        return ft_data, delta_data
1244
1249
 
1245
1250
    def test_deannotation_noeol(self):
1247
1252
        # we need a full text, and a delta
1248
1253
        f = self.get_knit()
1249
1254
        get_diamond_files(f, 1, trailing_eol=False)
1250
 
        ft_data, delta_data = self.helpGetBytes(
1251
 
            f, 'knit-ft-gz', _mod_knit.FTAnnotatedToUnannotated(None),
1252
 
            'knit-delta-gz', _mod_knit.DeltaAnnotatedToUnannotated(None))
 
1255
        ft_data, delta_data = self.helpGetBytes(f,
 
1256
                                                _mod_knit.FTAnnotatedToUnannotated(
 
1257
                                                    None),
 
1258
                                                _mod_knit.DeltaAnnotatedToUnannotated(None))
1253
1259
        self.assertEqual(
1254
1260
            b'version origin 1 b284f94827db1fa2970d9e2014f080413b547a7e\n'
1255
1261
            b'origin\n'
1265
1271
        # we need a full text, and a delta
1266
1272
        f = self.get_knit()
1267
1273
        get_diamond_files(f, 1)
1268
 
        ft_data, delta_data = self.helpGetBytes(
1269
 
            f, 'knit-ft-gz', _mod_knit.FTAnnotatedToUnannotated(None),
1270
 
            'knit-delta-gz', _mod_knit.DeltaAnnotatedToUnannotated(None))
 
1274
        ft_data, delta_data = self.helpGetBytes(f,
 
1275
                                                _mod_knit.FTAnnotatedToUnannotated(
 
1276
                                                    None),
 
1277
                                                _mod_knit.DeltaAnnotatedToUnannotated(None))
1271
1278
        self.assertEqual(
1272
1279
            b'version origin 1 00e364d235126be43292ab09cb4686cf703ddc17\n'
1273
1280
            b'origin\n'
1286
1293
        # Reconstructing a full text requires a backing versioned file, and it
1287
1294
        # must have the base lines requested from it.
1288
1295
        logged_vf = versionedfile.RecordingVersionedFilesDecorator(f)
1289
 
        ft_data, delta_data = self.helpGetBytes(
1290
 
            f, 'fulltext', _mod_knit.FTAnnotatedToFullText(None),
1291
 
            'fulltext', _mod_knit.DeltaAnnotatedToFullText(logged_vf))
 
1296
        ft_data, delta_data = self.helpGetBytes(f,
 
1297
                                                _mod_knit.FTAnnotatedToFullText(
 
1298
                                                    None),
 
1299
                                                _mod_knit.DeltaAnnotatedToFullText(logged_vf))
1292
1300
        self.assertEqual(b'origin', ft_data)
1293
1301
        self.assertEqual(b'base\nleft\nright\nmerged', delta_data)
1294
1302
        self.assertEqual([('get_record_stream', [(b'left',)], 'unordered',
1302
1310
        # Reconstructing a full text requires a backing versioned file, and it
1303
1311
        # must have the base lines requested from it.
1304
1312
        logged_vf = versionedfile.RecordingVersionedFilesDecorator(f)
1305
 
        ft_data, delta_data = self.helpGetBytes(
1306
 
            f, 'fulltext', _mod_knit.FTAnnotatedToFullText(None),
1307
 
            'fulltext', _mod_knit.DeltaAnnotatedToFullText(logged_vf))
 
1313
        ft_data, delta_data = self.helpGetBytes(f,
 
1314
                                                _mod_knit.FTAnnotatedToFullText(
 
1315
                                                    None),
 
1316
                                                _mod_knit.DeltaAnnotatedToFullText(logged_vf))
1308
1317
        self.assertEqual(b'origin\n', ft_data)
1309
1318
        self.assertEqual(b'base\nleft\nright\nmerged\n', delta_data)
1310
1319
        self.assertEqual([('get_record_stream', [(b'left',)], 'unordered',
1321
1330
        # Reconstructing a full text requires a backing versioned file, and it
1322
1331
        # must have the base lines requested from it.
1323
1332
        logged_vf = versionedfile.RecordingVersionedFilesDecorator(f)
1324
 
        ft_data, delta_data = self.helpGetBytes(
1325
 
            f, 'fulltext', _mod_knit.FTPlainToFullText(None),
1326
 
            'fulltext', _mod_knit.DeltaPlainToFullText(logged_vf))
 
1333
        ft_data, delta_data = self.helpGetBytes(f,
 
1334
                                                _mod_knit.FTPlainToFullText(
 
1335
                                                    None),
 
1336
                                                _mod_knit.DeltaPlainToFullText(logged_vf))
1327
1337
        self.assertEqual(b'origin\n', ft_data)
1328
1338
        self.assertEqual(b'base\nleft\nright\nmerged\n', delta_data)
1329
1339
        self.assertEqual([('get_record_stream', [(b'left',)], 'unordered',
1340
1350
        # Reconstructing a full text requires a backing versioned file, and it
1341
1351
        # must have the base lines requested from it.
1342
1352
        logged_vf = versionedfile.RecordingVersionedFilesDecorator(f)
1343
 
        ft_data, delta_data = self.helpGetBytes(
1344
 
            f, 'fulltext', _mod_knit.FTPlainToFullText(None),
1345
 
            'fulltext', _mod_knit.DeltaPlainToFullText(logged_vf))
 
1353
        ft_data, delta_data = self.helpGetBytes(f,
 
1354
                                                _mod_knit.FTPlainToFullText(
 
1355
                                                    None),
 
1356
                                                _mod_knit.DeltaPlainToFullText(logged_vf))
1346
1357
        self.assertEqual(b'origin', ft_data)
1347
1358
        self.assertEqual(b'base\nleft\nright\nmerged', delta_data)
1348
1359
        self.assertEqual([('get_record_stream', [(b'left',)], 'unordered',
1527
1538
        records.sort()
1528
1539
        self.assertEqual([(key0, b'a\nb\n'), (key1, b'b\nc\n')], records)
1529
1540
 
1530
 
    def test_add_chunks(self):
1531
 
        f = self.get_versionedfiles()
1532
 
        key0 = self.get_simple_key(b'r0')
1533
 
        key1 = self.get_simple_key(b'r1')
1534
 
        key2 = self.get_simple_key(b'r2')
1535
 
        keyf = self.get_simple_key(b'foo')
1536
 
        def add_chunks(key, parents, chunks):
1537
 
            factory = ChunkedContentFactory(
1538
 
                key, parents, osutils.sha_strings(chunks), chunks)
1539
 
            return f.add_content(factory)
1540
 
 
1541
 
        add_chunks(key0, [], [b'a', b'\nb\n'])
1542
 
        if self.graph:
1543
 
            add_chunks(key1, [key0], [b'b', b'\n', b'c\n'])
1544
 
        else:
1545
 
            add_chunks(key1, [], [b'b\n', b'c\n'])
1546
 
        keys = f.keys()
1547
 
        self.assertIn(key0, keys)
1548
 
        self.assertIn(key1, keys)
1549
 
        records = []
1550
 
        for record in f.get_record_stream([key0, key1], 'unordered', True):
1551
 
            records.append((record.key, record.get_bytes_as('fulltext')))
1552
 
        records.sort()
1553
 
        self.assertEqual([(key0, b'a\nb\n'), (key1, b'b\nc\n')], records)
1554
 
 
1555
1541
    def test_annotate(self):
1556
1542
        files = self.get_versionedfiles()
1557
1543
        self.get_diamond_files(files)
1646
1632
        for sha, (version, lines) in zip(
1647
1633
                shas, (empty_text, sample_text_nl, sample_text_no_nl)):
1648
1634
            new_key = self.get_simple_key(version + b"2")
1649
 
            self.assertRaises(ExistingContent,
 
1635
            self.assertRaises(errors.ExistingContent,
1650
1636
                              vf.add_lines, new_key, [], lines,
1651
1637
                              nostore_sha=sha)
1652
 
            self.assertRaises(ExistingContent,
 
1638
            self.assertRaises(errors.ExistingContent,
1653
1639
                              vf.add_lines, new_key, [], lines,
1654
1640
                              nostore_sha=sha)
1655
1641
            # and no new version should have been added.
1927
1913
            self.assertIsInstance(ft_bytes, bytes)
1928
1914
            chunked_bytes = factory.get_bytes_as('chunked')
1929
1915
            self.assertEqualDiff(ft_bytes, b''.join(chunked_bytes))
1930
 
            chunked_bytes = factory.iter_bytes_as('chunked')
1931
 
            self.assertEqualDiff(ft_bytes, b''.join(chunked_bytes))
1932
1916
 
1933
1917
        self.assertStreamOrder(sort_order, seen, keys)
1934
1918
 
1984
1968
                                 factory.sha1)
1985
1969
            self.assertEqual(parent_map[factory.key], factory.parents)
1986
1970
            # currently no stream emits mpdiff
1987
 
            self.assertRaises(UnavailableRepresentation,
 
1971
            self.assertRaises(errors.UnavailableRepresentation,
1988
1972
                              factory.get_bytes_as, 'mpdiff')
1989
1973
            self.assertIsInstance(factory.get_bytes_as(factory.storage_kind),
1990
1974
                                  bytes)