/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/test_bundle.py

  • Committer: Jelmer Vernooij
  • Date: 2018-11-16 23:19:12 UTC
  • mfrom: (7180 work)
  • mto: This revision was merged to the branch mainline in revision 7294.
  • Revision ID: jelmer@jelmer.uk-20181116231912-e043vpq22bdkxa6q
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
        self.contents = {}
78
78
        self.root = InventoryDirectory(ROOT_ID, '', None)
79
79
 
80
 
    inventory = property(lambda x:x)
81
 
    root_inventory = property(lambda x:x)
 
80
    inventory = property(lambda x: x)
 
81
    root_inventory = property(lambda x: x)
82
82
 
83
83
    def get_root_id(self):
84
84
        return self.root.file_id
121
121
 
122
122
    def make_entry(self, file_id, path):
123
123
        from ..bzr.inventory import (InventoryFile, InventoryDirectory,
124
 
            InventoryLink)
 
124
                                     InventoryLink)
125
125
        if not isinstance(file_id, bytes):
126
126
            raise TypeError(file_id)
127
127
        name = os.path.basename(path)
359
359
        """Ensure that iteration through ids works properly"""
360
360
        btree = self.make_tree_1()[0]
361
361
        self.assertEqual(self.sorted_ids(btree),
362
 
            [inventory.ROOT_ID, b'a', b'b', b'c', b'd'])
 
362
                         [inventory.ROOT_ID, b'a', b'b', b'c', b'd'])
363
363
        btree.note_deletion("grandparent/parent/file")
364
364
        btree.note_id(b"e", "grandparent/alt_parent/fool", kind="directory")
365
365
        btree.note_last_changed("grandparent/alt_parent/fool",
366
366
                                "revisionidiguess")
367
367
        self.assertEqual(self.sorted_ids(btree),
368
 
            [inventory.ROOT_ID, b'a', b'b', b'd', b'e'])
 
368
                         [inventory.ROOT_ID, b'a', b'b', b'd', b'e'])
369
369
 
370
370
 
371
371
class BundleTester1(tests.TestCaseWithTransport):
535
535
                    except errors.NoSuchFile:
536
536
                        continue
537
537
                    self.assertEqual(
538
 
                            old_file.read(), new.get_file(path).read())
 
538
                        old_file.read(), new.get_file(path).read())
539
539
            finally:
540
540
                new.unlock()
541
541
                old.unlock()
595
595
 
596
596
        for path, status, kind, fileid, entry in base_files:
597
597
            # Check that the meta information is the same
598
 
            self.assertEqual(base_tree.get_file_size(path),
599
 
                    to_tree.get_file_size(to_tree.id2path(fileid)))
600
 
            self.assertEqual(base_tree.get_file_sha1(path),
601
 
                    to_tree.get_file_sha1(to_tree.id2path(fileid)))
 
598
            self.assertEqual(
 
599
                base_tree.get_file_size(path),
 
600
                to_tree.get_file_size(to_tree.id2path(fileid)))
 
601
            self.assertEqual(
 
602
                base_tree.get_file_sha1(path),
 
603
                to_tree.get_file_sha1(to_tree.id2path(fileid)))
602
604
            # Check that the contents are the same
603
605
            # This is pretty expensive
604
606
            # self.assertEqual(base_tree.get_file(fileid).read(),
618
620
        # Make sure we can handle files with spaces, tabs, other
619
621
        # bogus characters
620
622
        self.build_tree([
621
 
                'b1/with space.txt'
622
 
                , 'b1/dir/'
623
 
                , 'b1/dir/filein subdir.c'
624
 
                , 'b1/dir/WithCaps.txt'
625
 
                , 'b1/dir/ pre space'
626
 
                , 'b1/sub/'
627
 
                , 'b1/sub/sub/'
628
 
                , 'b1/sub/sub/nonempty.txt'
629
 
                ])
 
623
            'b1/with space.txt', 'b1/dir/', 'b1/dir/filein subdir.c', 'b1/dir/WithCaps.txt', 'b1/dir/ pre space', 'b1/sub/', 'b1/sub/sub/', 'b1/sub/sub/nonempty.txt'
 
624
            ])
630
625
        self.build_tree_contents([('b1/sub/sub/emptyfile.txt', b''),
631
626
                                  ('b1/dir/nolastnewline.txt', b'bloop')])
632
627
        tt = TreeTransform(self.tree1)
636
631
        # a (length-prefixed) record containing it later.
637
632
        self.tree1.add('with space.txt', b'withspace-id')
638
633
        self.tree1.add([
639
 
                  'dir'
640
 
                , 'dir/filein subdir.c'
641
 
                , 'dir/WithCaps.txt'
642
 
                , 'dir/ pre space'
643
 
                , 'dir/nolastnewline.txt'
644
 
                , 'sub'
645
 
                , 'sub/sub'
646
 
                , 'sub/sub/nonempty.txt'
647
 
                , 'sub/sub/emptyfile.txt'
648
 
                ])
 
634
            'dir', 'dir/filein subdir.c', 'dir/WithCaps.txt', 'dir/ pre space', 'dir/nolastnewline.txt', 'sub', 'sub/sub', 'sub/sub/nonempty.txt', 'sub/sub/emptyfile.txt'
 
635
            ])
649
636
        self.tree1.commit('add whitespace', rev_id=b'a@cset-0-2')
650
637
 
651
638
        bundle = self.get_valid_bundle(b'a@cset-0-1', b'a@cset-0-2')
655
642
 
656
643
        # Now delete entries
657
644
        self.tree1.remove(
658
 
                ['sub/sub/nonempty.txt'
659
 
                , 'sub/sub/emptyfile.txt'
660
 
                , 'sub/sub'
661
 
                ])
 
645
            ['sub/sub/nonempty.txt', 'sub/sub/emptyfile.txt', 'sub/sub'
 
646
             ])
662
647
        tt = TreeTransform(self.tree1)
663
648
        trans_id = tt.trans_id_tree_path('executable')
664
649
        tt.set_executability(False, trans_id)
667
652
 
668
653
        bundle = self.get_valid_bundle(b'a@cset-0-2', b'a@cset-0-3')
669
654
        self.assertRaises((errors.TestamentMismatch,
670
 
            errors.VersionedFileInvalidChecksum,
671
 
            errors.BadBundle), self.get_invalid_bundle,
672
 
            b'a@cset-0-2', b'a@cset-0-3')
 
655
                           errors.VersionedFileInvalidChecksum,
 
656
                           errors.BadBundle), self.get_invalid_bundle,
 
657
                          b'a@cset-0-2', b'a@cset-0-3')
673
658
        # Check a rollup bundle
674
659
        bundle = self.get_valid_bundle(b'null:', b'a@cset-0-3')
675
660
 
682
667
        bundle = self.get_valid_bundle(b'null:', b'a@cset-0-4')
683
668
 
684
669
        # Modified files
685
 
        with open('b1/sub/dir/WithCaps.txt', 'ab') as f: f.write(b'\nAdding some text\n')
686
 
        with open('b1/sub/dir/ pre space', 'ab') as f: f.write(
687
 
             b'\r\nAdding some\r\nDOS format lines\r\n')
688
 
        with open('b1/sub/dir/nolastnewline.txt', 'ab') as f: f.write(b'\n')
 
670
        with open('b1/sub/dir/WithCaps.txt', 'ab') as f:
 
671
            f.write(b'\nAdding some text\n')
 
672
        with open('b1/sub/dir/ pre space', 'ab') as f:
 
673
            f.write(
 
674
                b'\r\nAdding some\r\nDOS format lines\r\n')
 
675
        with open('b1/sub/dir/nolastnewline.txt', 'ab') as f:
 
676
            f.write(b'\n')
689
677
        self.tree1.rename_one('sub/dir/ pre space',
690
678
                              'sub/ start space')
691
679
        self.tree1.commit('Modified files', rev_id=b'a@cset-0-5')
725
713
        if getattr(bundle, 'revision_tree', None) is not None:
726
714
            # Not all bundle formats supports revision_tree
727
715
            bund_tree = bundle.revision_tree(self.b1.repository, b'l@cset-0-1')
728
 
            self.assertEqual(link_target, bund_tree.get_symlink_target(link_name))
 
716
            self.assertEqual(
 
717
                link_target, bund_tree.get_symlink_target(link_name))
729
718
 
730
719
        tt = TreeTransform(self.tree1)
731
720
        trans_id = tt.trans_id_tree_path(link_name)
771
760
        tt = TreeTransform(self.tree1)
772
761
 
773
762
        # Add
774
 
        tt.new_file('file', tt.root, [b'\x00\n\x00\r\x01\n\x02\r\xff'], b'binary-1')
 
763
        tt.new_file('file', tt.root, [
 
764
                    b'\x00\n\x00\r\x01\n\x02\r\xff'], b'binary-1')
775
765
        tt.new_file('file2', tt.root, [b'\x01\n\x02\r\x03\n\x04\r\xff'],
776
 
            b'binary-2')
 
766
                    b'binary-2')
777
767
        tt.apply()
778
768
        self.tree1.commit('add binary', rev_id=b'b@cset-0-1')
779
769
        self.get_valid_bundle(b'null:', b'b@cset-0-1')
840
830
        self.tree1 = self.make_branch_and_tree('b1')
841
831
        self.b1 = self.tree1.branch
842
832
 
843
 
        with open('b1/one', 'wb') as f: f.write(b'one\n')
 
833
        with open('b1/one', 'wb') as f:
 
834
            f.write(b'one\n')
844
835
        self.tree1.add('one')
845
836
        self.tree1.commit('add file', rev_id=b'a@cset-0-1')
846
 
        with open('b1/one', 'wb') as f: f.write(b'two\n')
 
837
        with open('b1/one', 'wb') as f:
 
838
            f.write(b'two\n')
847
839
        self.tree1.commit('modify', rev_id=b'a@cset-0-2')
848
 
        with open('b1/one', 'wb') as f: f.write(b'three\n')
 
840
        with open('b1/one', 'wb') as f:
 
841
            f.write(b'three\n')
849
842
        self.tree1.commit('modify', rev_id=b'a@cset-0-3')
850
843
        bundle_file = BytesIO()
851
844
        rev_ids = write_bundle(self.tree1.branch.repository, b'a@cset-0-3',
876
869
        self.b1 = self.tree1.branch
877
870
 
878
871
        f.write((u'A file\n'
879
 
            u'With international man of mystery\n'
880
 
            u'William Dod\xe9\n').encode('utf-8'))
 
872
                 u'With international man of mystery\n'
 
873
                 u'William Dod\xe9\n').encode('utf-8'))
881
874
        f.close()
882
875
 
883
876
        self.tree1.add([u'with Dod\N{Euro Sign}'], [b'withdod-id'])
911
904
        # Rollup
912
905
        bundle = self.get_valid_bundle(b'null:', b'i18n-4')
913
906
 
914
 
 
915
907
    def test_whitespace_bundle(self):
916
908
        if sys.platform in ('win32', 'cygwin'):
917
909
            raise tests.TestSkipped('Windows doesn\'t support filenames'
930
922
        bundle = self.get_valid_bundle(b'null:', b'white-1')
931
923
 
932
924
        # Modified
933
 
        with open('b1/trailing space ', 'ab') as f: f.write(b'add some text\n')
 
925
        with open('b1/trailing space ', 'ab') as f:
 
926
            f.write(b'add some text\n')
934
927
        self.tree1.commit('add text', rev_id=b'white-2')
935
928
 
936
929
        bundle = self.get_valid_bundle(b'white-1', b'white-2')
998
991
        tree.lock_write()
999
992
        self.addCleanup(tree.unlock)
1000
993
        tree.add([''], [b'TREE_ROOT'])
1001
 
        tree.commit('One', revprops={u'one': 'two', u'empty': ''}, rev_id=b'rev1')
 
994
        tree.commit('One', revprops={u'one': 'two',
 
995
                                     u'empty': ''}, rev_id=b'rev1')
1002
996
        self.b1 = tree.branch
1003
997
        bundle_sio, revision_ids = self.create_bundle_text(b'null:', b'rev1')
1004
998
        bundle = read_bundle(bundle_sio)
1005
999
        revision_info = bundle.revisions[0]
1006
1000
        self.assertEqual(b'rev1', revision_info.revision_id)
1007
1001
        rev = revision_info.as_revision()
1008
 
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
 
1002
        self.assertEqual({'branch-nick': 'tree', 'empty': '', 'one': 'two'},
1009
1003
                         rev.properties)
1010
1004
 
1011
1005
    def test_bundle_sorted_properties(self):
1016
1010
 
1017
1011
        tree.add([''], [b'TREE_ROOT'])
1018
1012
        tree.commit('One', rev_id=b'rev1',
1019
 
                    revprops={u'a':'4', u'b':'3', u'c':'2', u'd':'1'})
 
1013
                    revprops={u'a': '4', u'b': '3', u'c': '2', u'd': '1'})
1020
1014
        self.b1 = tree.branch
1021
1015
        bundle_sio, revision_ids = self.create_bundle_text(b'null:', b'rev1')
1022
1016
        bundle = read_bundle(bundle_sio)
1023
1017
        revision_info = bundle.revisions[0]
1024
1018
        self.assertEqual(b'rev1', revision_info.revision_id)
1025
1019
        rev = revision_info.as_revision()
1026
 
        self.assertEqual({'branch-nick':'tree', 'a':'4', 'b':'3', 'c':'2',
1027
 
                          'd':'1'}, rev.properties)
 
1020
        self.assertEqual({'branch-nick': 'tree', 'a': '4', 'b': '3', 'c': '2',
 
1021
                          'd': '1'}, rev.properties)
1028
1022
 
1029
1023
    def test_bundle_unicode_properties(self):
1030
1024
        """We should be able to round trip a non-ascii property."""
1039
1033
        # However, Testaments assert than they are str(), and thus should not
1040
1034
        # be Unicode.
1041
1035
        tree.commit('One', rev_id=b'rev1',
1042
 
                    revprops={u'omega':u'\u03a9', u'alpha':u'\u03b1'})
 
1036
                    revprops={u'omega': u'\u03a9', u'alpha': u'\u03b1'})
1043
1037
        self.b1 = tree.branch
1044
1038
        bundle_sio, revision_ids = self.create_bundle_text(b'null:', b'rev1')
1045
1039
        bundle = read_bundle(bundle_sio)
1046
1040
        revision_info = bundle.revisions[0]
1047
1041
        self.assertEqual(b'rev1', revision_info.revision_id)
1048
1042
        rev = revision_info.as_revision()
1049
 
        self.assertEqual({'branch-nick':'tree', 'omega':u'\u03a9',
1050
 
                          'alpha':u'\u03b1'}, rev.properties)
 
1043
        self.assertEqual({'branch-nick': 'tree', 'omega': u'\u03a9',
 
1044
                          'alpha': u'\u03b1'}, rev.properties)
1051
1045
 
1052
1046
    def test_bundle_with_ghosts(self):
1053
1047
        tree = self.make_branch_and_tree('tree')
1094
1088
        root_id = inv.root.file_id
1095
1089
        repo.lock_read()
1096
1090
        self.addCleanup(repo.unlock)
1097
 
        self.assertEqual({(root_id, b'rev1'):(),
1098
 
            (root_id, b'rev2'):((root_id, b'rev1'),)},
1099
 
            repo.texts.get_parent_map([(root_id, b'rev1'), (root_id, b'rev2')]))
 
1091
        self.assertEqual({(root_id, b'rev1'): (),
 
1092
                          (root_id, b'rev2'): ((root_id, b'rev1'),)},
 
1093
                         repo.texts.get_parent_map([(root_id, b'rev1'), (root_id, b'rev2')]))
1100
1094
 
1101
1095
    def test_inv_hash_across_serializers(self):
1102
1096
        repo = self.make_repo_with_installed_revisions()
1180
1174
        file_ids = set(
1181
1175
            (f, r) for b, m, k, r, f in bundle.get_bundle_reader().iter_records()
1182
1176
            if f is not None)
1183
 
        self.assertEqual({(b'file2-id', b'rev3'), (b'file3-id', rev2)}, file_ids)
 
1177
        self.assertEqual(
 
1178
            {(b'file2-id', b'rev3'), (b'file3-id', rev2)}, file_ids)
1184
1179
        bundle.install_revisions(target.branch.repository)
1185
1180
 
1186
1181
 
1194
1189
        tree.lock_write()
1195
1190
        self.addCleanup(tree.unlock)
1196
1191
        tree.add([''], [b'TREE_ROOT'])
1197
 
        tree.commit('One', revprops={u'one':'two', u'empty':''}, rev_id=b'rev1')
 
1192
        tree.commit('One', revprops={u'one': 'two',
 
1193
                                     u'empty': ''}, rev_id=b'rev1')
1198
1194
        self.b1 = tree.branch
1199
1195
        bundle_sio, revision_ids = self.create_bundle_text(b'null:', b'rev1')
1200
1196
        self.assertContainsRe(bundle_sio.getvalue(),
1202
1198
                              b'#   branch-nick: tree\n'
1203
1199
                              b'#   empty: \n'
1204
1200
                              b'#   one: two\n'
1205
 
                             )
 
1201
                              )
1206
1202
        bundle = read_bundle(bundle_sio)
1207
1203
        revision_info = bundle.revisions[0]
1208
1204
        self.assertEqual(b'rev1', revision_info.revision_id)
1209
1205
        rev = revision_info.as_revision()
1210
 
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
 
1206
        self.assertEqual({'branch-nick': 'tree', 'empty': '', 'one': 'two'},
1211
1207
                         rev.properties)
1212
1208
 
1213
1209
    def get_bundle_tree(self, bundle, revision_id):
1226
1222
        tree.lock_write()
1227
1223
        self.addCleanup(tree.unlock)
1228
1224
        tree.add([''], [b'TREE_ROOT'])
1229
 
        tree.commit('One', revprops={u'one':'two', u'empty':''}, rev_id=b'rev1')
 
1225
        tree.commit('One', revprops={u'one': 'two',
 
1226
                                     u'empty': ''}, rev_id=b'rev1')
1230
1227
        self.b1 = tree.branch
1231
1228
        bundle_sio, revision_ids = self.create_bundle_text(b'null:', b'rev1')
1232
1229
        txt = bundle_sio.getvalue()
1233
1230
        loc = txt.find(b'#   empty: ') + len(b'#   empty:')
1234
1231
        # Create a new bundle, which strips the trailing space after empty
1235
 
        bundle_sio = BytesIO(txt[:loc] + txt[loc+1:])
 
1232
        bundle_sio = BytesIO(txt[:loc] + txt[loc + 1:])
1236
1233
 
1237
1234
        self.assertContainsRe(bundle_sio.getvalue(),
1238
1235
                              b'# properties:\n'
1239
1236
                              b'#   branch-nick: tree\n'
1240
1237
                              b'#   empty:\n'
1241
1238
                              b'#   one: two\n'
1242
 
                             )
 
1239
                              )
1243
1240
        bundle = read_bundle(bundle_sio)
1244
1241
        revision_info = bundle.revisions[0]
1245
1242
        self.assertEqual(b'rev1', revision_info.revision_id)
1246
1243
        rev = revision_info.as_revision()
1247
 
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
 
1244
        self.assertEqual({'branch-nick': 'tree', 'empty': '', 'one': 'two'},
1248
1245
                         rev.properties)
1249
1246
 
1250
1247
    def test_bundle_sorted_properties(self):
1255
1252
 
1256
1253
        tree.add([''], [b'TREE_ROOT'])
1257
1254
        tree.commit('One', rev_id=b'rev1',
1258
 
                    revprops={u'a':'4', u'b':'3', u'c':'2', u'd':'1'})
 
1255
                    revprops={u'a': '4', u'b': '3', u'c': '2', u'd': '1'})
1259
1256
        self.b1 = tree.branch
1260
1257
        bundle_sio, revision_ids = self.create_bundle_text(b'null:', b'rev1')
1261
1258
        self.assertContainsRe(bundle_sio.getvalue(),
1265
1262
                              b'#   branch-nick: tree\n'
1266
1263
                              b'#   c: 2\n'
1267
1264
                              b'#   d: 1\n'
1268
 
                             )
 
1265
                              )
1269
1266
        bundle = read_bundle(bundle_sio)
1270
1267
        revision_info = bundle.revisions[0]
1271
1268
        self.assertEqual(b'rev1', revision_info.revision_id)
1272
1269
        rev = revision_info.as_revision()
1273
 
        self.assertEqual({'branch-nick':'tree', 'a':'4', 'b':'3', 'c':'2',
1274
 
                          'd':'1'}, rev.properties)
 
1270
        self.assertEqual({'branch-nick': 'tree', 'a': '4', 'b': '3', 'c': '2',
 
1271
                          'd': '1'}, rev.properties)
1275
1272
 
1276
1273
    def test_bundle_unicode_properties(self):
1277
1274
        """We should be able to round trip a non-ascii property."""
1286
1283
        # However, Testaments assert than they are str(), and thus should not
1287
1284
        # be Unicode.
1288
1285
        tree.commit('One', rev_id=b'rev1',
1289
 
                    revprops={u'omega':u'\u03a9', u'alpha':u'\u03b1'})
 
1286
                    revprops={u'omega': u'\u03a9', u'alpha': u'\u03b1'})
1290
1287
        self.b1 = tree.branch
1291
1288
        bundle_sio, revision_ids = self.create_bundle_text(b'null:', b'rev1')
1292
1289
        self.assertContainsRe(bundle_sio.getvalue(),
1294
1291
                              b'#   alpha: \xce\xb1\n'
1295
1292
                              b'#   branch-nick: tree\n'
1296
1293
                              b'#   omega: \xce\xa9\n'
1297
 
                             )
 
1294
                              )
1298
1295
        bundle = read_bundle(bundle_sio)
1299
1296
        revision_info = bundle.revisions[0]
1300
1297
        self.assertEqual(b'rev1', revision_info.revision_id)
1301
1298
        rev = revision_info.as_revision()
1302
 
        self.assertEqual({'branch-nick':'tree', 'omega':u'\u03a9',
1303
 
                          'alpha':u'\u03b1'}, rev.properties)
 
1299
        self.assertEqual({'branch-nick': 'tree', 'omega': u'\u03a9',
 
1300
                          'alpha': u'\u03b1'}, rev.properties)
1304
1301
 
1305
1302
 
1306
1303
class V09BundleKnit2Tester(V08BundleTester):
1355
1352
        self.assertEqual(set(rev_ids),
1356
1353
                         {r.revision_id for r in bundle.real_revisions})
1357
1354
        self.valid_apply_bundle(base_rev_id, bundle,
1358
 
                                   checkout_dir=checkout_dir)
 
1355
                                checkout_dir=checkout_dir)
1359
1356
 
1360
1357
        return bundle
1361
1358
 
1407
1404
        s = BytesIO()
1408
1405
        serializer = BundleSerializerV4('1.0')
1409
1406
        with tree.lock_read():
1410
 
            serializer.write_bundle(tree.branch.repository, b'rev2', b'null:', s)
 
1407
            serializer.write_bundle(
 
1408
                tree.branch.repository, b'rev2', b'null:', s)
1411
1409
        s.seek(0)
1412
1410
        tree2 = self.make_branch_and_tree('target')
1413
1411
        target_repo = tree2.branch.repository
1417
1415
        # Turn the 'iterators_of_bytes' back into simple strings for comparison
1418
1416
        repo_texts = dict((i, b''.join(content)) for i, content
1419
1417
                          in target_repo.iter_files_bytes(
1420
 
                                [(b'fileid-2', b'rev1', '1'),
1421
 
                                 (b'fileid-2', b'rev2', '2')]))
1422
 
        self.assertEqual({'1':b'contents1\nstatic\n',
1423
 
                          '2':b'contents2\nstatic\n'},
 
1418
            [(b'fileid-2', b'rev1', '1'),
 
1419
             (b'fileid-2', b'rev2', '2')]))
 
1420
        self.assertEqual({'1': b'contents1\nstatic\n',
 
1421
                          '2': b'contents2\nstatic\n'},
1424
1422
                         repo_texts)
1425
1423
        rtree = target_repo.revision_tree(b'rev2')
1426
1424
        inventory_vf = target_repo.inventories
1454
1452
            breezy.gpg.GPGStrategy = breezy.gpg.LoopbackGPGStrategy
1455
1453
            new_config = test_commit.MustSignConfig()
1456
1454
            commit.Commit(config_stack=new_config).commit(message="base",
1457
 
                                                    allow_pointless=True,
1458
 
                                                    rev_id=b'B',
1459
 
                                                    working_tree=tree_a)
 
1455
                                                          allow_pointless=True,
 
1456
                                                          rev_id=b'B',
 
1457
                                                          working_tree=tree_a)
 
1458
 
1460
1459
            def sign(text):
1461
1460
                return breezy.gpg.LoopbackGPGStrategy(None).sign(text)
1462
1461
            self.assertTrue(repo_a.has_signature_for_revision_id(b'B'))
1467
1466
        s = BytesIO()
1468
1467
        serializer = BundleSerializerV4('4')
1469
1468
        with tree_a.lock_read():
1470
 
            serializer.write_bundle(tree_a.branch.repository, b'B', b'null:', s)
 
1469
            serializer.write_bundle(
 
1470
                tree_a.branch.repository, b'B', b'null:', s)
1471
1471
        s.seek(0)
1472
1472
        install_bundle(repo_b, serializer.read(s))
1473
1473
        self.assertTrue(repo_b.has_signature_for_revision_id(b'B'))
1555
1555
        self.assertEqual({b'parents': [b'a@cset-0-2a', b'a@cset-0-2b'],
1556
1556
                          b'sha1': b'09c53b0c4de0895e11a2aacc34fef60a6e70865c',
1557
1557
                          b'storage_kind': b'mpdiff',
1558
 
                         }, metadata)
 
1558
                          }, metadata)
1559
1559
        # We should have an mpdiff that takes some lines from both parents.
1560
1560
        self.assertEqualDiff(
1561
1561
            b'i 1\n'
1579
1579
        self.assertEqual({b'parents': [],
1580
1580
                          b'sha1': b'a13f42b142d544aac9b085c42595d304150e31a2',
1581
1581
                          b'storage_kind': b'mpdiff',
1582
 
                         }, metadata)
 
1582
                          }, metadata)
1583
1583
        # We should have an mpdiff that takes some lines from both parents.
1584
1584
        self.assertEqualDiff(
1585
1585
            b'i 4\n'
1586
1586
            b'<inventory format="10" revision_id="a@cset-0-1">\n'
1587
1587
            b'<directory file_id="root-id" name=""'
1588
 
                b' revision="a@cset-0-1" />\n'
 
1588
            b' revision="a@cset-0-1" />\n'
1589
1589
            b'<file file_id="file-id" name="file" parent_id="root-id"'
1590
 
                b' revision="a@cset-0-1"'
1591
 
                b' text_sha1="09c2f8647e14e49e922b955c194102070597c2d1"'
1592
 
                b' text_size="17" />\n'
 
1590
            b' revision="a@cset-0-1"'
 
1591
            b' text_sha1="09c2f8647e14e49e922b955c194102070597c2d1"'
 
1592
            b' text_size="17" />\n'
1593
1593
            b'</inventory>\n'
1594
1594
            b'\n', bytes)
1595
1595
 
1596
1596
    def test_multiple_inventories_as_xml(self):
1597
1597
        self.make_merged_branch()
1598
1598
        sio = self.make_bundle_just_inventories(b'a@cset-0-1', b'a@cset-0-3',
1599
 
            [b'a@cset-0-2a', b'a@cset-0-2b', b'a@cset-0-3'])
 
1599
                                                [b'a@cset-0-2a', b'a@cset-0-2b', b'a@cset-0-3'])
1600
1600
        reader = v4.BundleReader(sio, stream_input=False)
1601
1601
        records = list(reader.iter_records())
1602
1602
        self.assertEqual(3, len(records))
1607
1607
        self.assertEqual({b'parents': [b'a@cset-0-1'],
1608
1608
                          b'sha1': b'1e105886d62d510763e22885eec733b66f5f09bf',
1609
1609
                          b'storage_kind': b'mpdiff',
1610
 
                         }, metadata_2a)
 
1610
                          }, metadata_2a)
1611
1611
        metadata_2b = records[1][1]
1612
1612
        self.assertEqual({b'parents': [b'a@cset-0-1'],
1613
1613
                          b'sha1': b'f03f12574bdb5ed2204c28636c98a8547544ccd8',
1614
1614
                          b'storage_kind': b'mpdiff',
1615
 
                         }, metadata_2b)
 
1615
                          }, metadata_2b)
1616
1616
        metadata_3 = records[2][1]
1617
1617
        self.assertEqual({b'parents': [b'a@cset-0-2a', b'a@cset-0-2b'],
1618
1618
                          b'sha1': b'09c53b0c4de0895e11a2aacc34fef60a6e70865c',
1619
1619
                          b'storage_kind': b'mpdiff',
1620
 
                         }, metadata_3)
 
1620
                          }, metadata_3)
1621
1621
        bytes_2a = records[0][0]
1622
1622
        self.assertEqualDiff(
1623
1623
            b'i 1\n'
1626
1626
            b'c 0 1 1 1\n'
1627
1627
            b'i 1\n'
1628
1628
            b'<file file_id="file-id" name="file" parent_id="root-id"'
1629
 
                b' revision="a@cset-0-2a"'
1630
 
                b' text_sha1="50f545ff40e57b6924b1f3174b267ffc4576e9a9"'
1631
 
                b' text_size="12" />\n'
 
1629
            b' revision="a@cset-0-2a"'
 
1630
            b' text_sha1="50f545ff40e57b6924b1f3174b267ffc4576e9a9"'
 
1631
            b' text_size="12" />\n'
1632
1632
            b'\n'
1633
1633
            b'c 0 3 3 1\n', bytes_2a)
1634
1634
        bytes_2b = records[1][0]
1639
1639
            b'c 0 1 1 2\n'
1640
1640
            b'i 1\n'
1641
1641
            b'<file file_id="file2-id" name="other-file" parent_id="root-id"'
1642
 
                b' revision="a@cset-0-2b"'
1643
 
                b' text_sha1="b46c0c8ea1e5ef8e46fc8894bfd4752a88ec939e"'
1644
 
                b' text_size="14" />\n'
 
1642
            b' revision="a@cset-0-2b"'
 
1643
            b' text_sha1="b46c0c8ea1e5ef8e46fc8894bfd4752a88ec939e"'
 
1644
            b' text_size="14" />\n'
1645
1645
            b'\n'
1646
1646
            b'c 0 3 4 1\n', bytes_2b)
1647
1647
        bytes_3 = records[2][0]
1655
1655
    def test_creating_bundle_preserves_chk_pages(self):
1656
1656
        self.make_merged_branch()
1657
1657
        target = self.b1.controldir.sprout('target',
1658
 
                                       revision_id=b'a@cset-0-2a').open_branch()
 
1658
                                           revision_id=b'a@cset-0-2a').open_branch()
1659
1659
        bundle_txt, rev_ids = self.create_bundle_text(b'a@cset-0-2a',
1660
1660
                                                      b'a@cset-0-3')
1661
1661
        self.assertEqual(set([b'a@cset-0-2b', b'a@cset-0-3']), set(rev_ids))
1683
1683
        self.build_tree(['b1/two'])
1684
1684
        wt.add('two')
1685
1685
        wt.commit('add two', rev_id=b'a@cset-0-2',
1686
 
                  revprops={u'branch-nick':'test'})
 
1686
                  revprops={u'branch-nick': 'test'})
1687
1687
 
1688
1688
        bundle_txt = BytesIO()
1689
1689
        rev_ids = write_bundle(wt.branch.repository, b'a@cset-0-2',
1695
1695
    def check_valid(self, bundle):
1696
1696
        """Check that after whatever munging, the final object is valid."""
1697
1697
        self.assertEqual([b'a@cset-0-2'],
1698
 
            [r.revision_id for r in bundle.real_revisions])
 
1698
                         [r.revision_id for r in bundle.real_revisions])
1699
1699
 
1700
1700
    def test_extra_whitespace(self):
1701
1701
        bundle_txt = self.build_test_bundle()
1775
1775
        writer.begin()
1776
1776
        writer.add_info_record({b'foo': b'bar'})
1777
1777
        writer._add_record(b"Record body", {b'parents': [b'1', b'3'],
1778
 
            b'storage_kind': b'fulltext'}, 'file', b'revid', b'fileid')
 
1778
                                            b'storage_kind': b'fulltext'}, 'file', b'revid', b'fileid')
1779
1779
        writer.end()
1780
1780
        fileobj.seek(0)
1781
1781
        reader = v4.BundleReader(fileobj, stream_input=True)
1782
1782
        record_iter = reader.iter_records()
1783
1783
        record = next(record_iter)
1784
1784
        self.assertEqual((None, {b'foo': b'bar', b'storage_kind': b'header'},
1785
 
            'info', None, None), record)
 
1785
                          'info', None, None), record)
1786
1786
        record = next(record_iter)
1787
1787
        self.assertEqual((b"Record body", {b'storage_kind': b'fulltext',
1788
 
                          b'parents': [b'1', b'3']}, 'file', b'revid', b'fileid'),
1789
 
                          record)
 
1788
                                           b'parents': [b'1', b'3']}, 'file', b'revid', b'fileid'),
 
1789
                         record)
1790
1790
 
1791
1791
    def test_roundtrip_record_memory_hungry(self):
1792
1792
        fileobj = BytesIO()
1794
1794
        writer.begin()
1795
1795
        writer.add_info_record({b'foo': b'bar'})
1796
1796
        writer._add_record(b"Record body", {b'parents': [b'1', b'3'],
1797
 
            b'storage_kind': b'fulltext'}, 'file', b'revid', b'fileid')
 
1797
                                            b'storage_kind': b'fulltext'}, 'file', b'revid', b'fileid')
1798
1798
        writer.end()
1799
1799
        fileobj.seek(0)
1800
1800
        reader = v4.BundleReader(fileobj, stream_input=False)
1801
1801
        record_iter = reader.iter_records()
1802
1802
        record = next(record_iter)
1803
1803
        self.assertEqual((None, {b'foo': b'bar', b'storage_kind': b'header'},
1804
 
            'info', None, None), record)
 
1804
                          'info', None, None), record)
1805
1805
        record = next(record_iter)
1806
1806
        self.assertEqual((b"Record body", {b'storage_kind': b'fulltext',
1807
 
                          b'parents': [b'1', b'3']}, 'file', b'revid', b'fileid'),
1808
 
                          record)
 
1807
                                           b'parents': [b'1', b'3']}, 'file', b'revid', b'fileid'),
 
1808
                         record)
1809
1809
 
1810
1810
    def test_encode_name(self):
1811
1811
        self.assertEqual(b'revision/rev1',
1812
 
            v4.BundleWriter.encode_name('revision', b'rev1'))
 
1812
                         v4.BundleWriter.encode_name('revision', b'rev1'))
1813
1813
        self.assertEqual(b'file/rev//1/file-id-1',
1814
 
            v4.BundleWriter.encode_name('file', b'rev/1', b'file-id-1'))
 
1814
                         v4.BundleWriter.encode_name('file', b'rev/1', b'file-id-1'))
1815
1815
        self.assertEqual(b'info',
1816
 
            v4.BundleWriter.encode_name('info', None, None))
 
1816
                         v4.BundleWriter.encode_name('info', None, None))
1817
1817
 
1818
1818
    def test_decode_name(self):
1819
1819
        self.assertEqual(('revision', b'rev1', None),
1820
 
            v4.BundleReader.decode_name(b'revision/rev1'))
 
1820
                         v4.BundleReader.decode_name(b'revision/rev1'))
1821
1821
        self.assertEqual(('file', b'rev/1', b'file-id-1'),
1822
 
            v4.BundleReader.decode_name(b'file/rev//1/file-id-1'))
 
1822
                         v4.BundleReader.decode_name(b'file/rev//1/file-id-1'))
1823
1823
        self.assertEqual(('info', None, None),
1824
1824
                         v4.BundleReader.decode_name(b'info'))
1825
1825
 
1834
1834
        record_iter = v4.BundleReader(fileobj).iter_records()
1835
1835
        record = next(record_iter)
1836
1836
        self.assertEqual((None, {b'foo': b'bar', b'storage_kind': b'header'},
1837
 
            'info', None, None), record)
 
1837
                          'info', None, None), record)
1838
1838
        self.assertRaises(errors.BadBundle, next, record_iter)
1839
1839
 
1840
1840
 
1844
1844
        """A local bundle named like the URL should not be read.
1845
1845
        """
1846
1846
        out, wt = test_read_bundle.create_bundle_file(self)
 
1847
 
1847
1848
        class FooService(object):
1848
1849
            """A directory service that always returns source"""
1849
1850