/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: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2018-11-16 18:59:44 UTC
  • mfrom: (7143.15.15 more-cleanups)
  • Revision ID: breezy.the.bot@gmail.com-20181116185944-biefv1sub37qfybm
Sprinkle some PEP8iness.

Merged from https://code.launchpad.net/~jelmer/brz/more-cleanups/+merge/358611

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