~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bundle.py

  • Committer: Robert Collins
  • Date: 2007-07-04 08:08:13 UTC
  • mfrom: (2572 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2587.
  • Revision ID: robertc@robertcollins.net-20070704080813-wzebx0r88fvwj5rq
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004-2006 by Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
import tempfile
21
21
 
22
22
from bzrlib import (
23
 
    bzrdir, 
24
 
    errors, 
25
 
    inventory, 
26
 
    repository, 
 
23
    bzrdir,
 
24
    errors,
 
25
    inventory,
 
26
    repository,
27
27
    treebuilder,
28
28
    )
29
 
from bzrlib.builtins import merge
 
29
from bzrlib.builtins import _merge_helper
30
30
from bzrlib.bzrdir import BzrDir
31
31
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
32
32
from bzrlib.bundle.bundle_data import BundleTree
38
38
from bzrlib.errors import (BzrError, TestamentMismatch, NotABundle, BadBundle, 
39
39
                           NoSuchFile,)
40
40
from bzrlib.merge import Merge3Merger
 
41
from bzrlib.repofmt import knitrepo
41
42
from bzrlib.osutils import has_symlinks, sha_file
42
43
from bzrlib.tests import (TestCaseInTempDir, TestCaseWithTransport,
43
44
                          TestCase, TestSkipped)
313
314
 
314
315
    def test_mismatched_bundle(self):
315
316
        format = bzrdir.BzrDirMetaFormat1()
316
 
        format.repository_format = repository.RepositoryFormatKnit2()
 
317
        format.repository_format = knitrepo.RepositoryFormatKnit3()
317
318
        serializer = BundleSerializerV08('0.8')
318
319
        b = self.make_branch('.', format=format)
319
 
        self.assertRaises(errors.IncompatibleFormat, serializer.write, 
 
320
        self.assertRaises(errors.IncompatibleBundleFormat, serializer.write, 
320
321
                          b.repository, [], {}, StringIO())
321
322
 
322
323
    def test_matched_bundle(self):
323
 
        """Don't raise IncompatibleFormat for knit2 and bundle0.9"""
 
324
        """Don't raise IncompatibleBundleFormat for knit2 and bundle0.9"""
324
325
        format = bzrdir.BzrDirMetaFormat1()
325
 
        format.repository_format = repository.RepositoryFormatKnit2()
 
326
        format.repository_format = knitrepo.RepositoryFormatKnit3()
326
327
        serializer = BundleSerializerV09('0.9')
327
328
        b = self.make_branch('.', format=format)
328
329
        serializer.write(b.repository, [], {}, StringIO())
330
331
    def test_mismatched_model(self):
331
332
        """Try copying a bundle from knit2 to knit1"""
332
333
        format = bzrdir.BzrDirMetaFormat1()
333
 
        format.repository_format = repository.RepositoryFormatKnit2()
 
334
        format.repository_format = knitrepo.RepositoryFormatKnit3()
334
335
        source = self.make_branch_and_tree('source', format=format)
335
336
        source.commit('one', rev_id='one-id')
336
337
        source.commit('two', rev_id='two-id')
340
341
        text.seek(0)
341
342
 
342
343
        format = bzrdir.BzrDirMetaFormat1()
343
 
        format.repository_format = repository.RepositoryFormatKnit1()
 
344
        format.repository_format = knitrepo.RepositoryFormatKnit1()
344
345
        target = self.make_branch('target', format=format)
345
346
        self.assertRaises(errors.IncompatibleRevision, install_bundle, 
346
347
                          target.repository, read_bundle(text))
352
353
 
353
354
    def bzrdir_format(self):
354
355
        format = bzrdir.BzrDirMetaFormat1()
355
 
        format.repository_format = repository.RepositoryFormatKnit1()
 
356
        format.repository_format = knitrepo.RepositoryFormatKnit1()
356
357
        return format
357
358
 
358
359
    def make_branch_and_tree(self, path, format=None):
487
488
            tree.update()
488
489
            delta = tree.changes_from(self.b1.repository.revision_tree(rev_id))
489
490
            self.assertFalse(delta.has_changed(),
490
 
                             'Working tree has modifications')
 
491
                             'Working tree has modifications: %s' % delta)
491
492
        return tree
492
493
 
493
494
    def valid_apply_bundle(self, base_rev_id, info, checkout_dir=None):
640
641
        self.assertEqualDiff(tree1_inv, tree2_inv)
641
642
        other.rename_one('sub/dir/nolastnewline.txt', 'sub/nolastnewline.txt')
642
643
        other.commit('rename file', rev_id='a@cset-0-6b')
643
 
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
 
644
        _merge_helper([other.basedir, -1], [None, None],
 
645
                      this_dir=self.tree1.basedir)
644
646
        self.tree1.commit(u'Merge', rev_id='a@cset-0-7',
645
647
                          verbose=False)
646
648
        bundle = self.get_valid_bundle('a@cset-0-6', 'a@cset-0-7')
741
743
        tt.create_file('file2', trans_id)
742
744
        tt.apply()
743
745
        other.commit('modify text in another tree', rev_id='a@lmod-0-2b')
744
 
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
 
746
        _merge_helper([other.basedir, -1], [None, None],
 
747
                      this_dir=self.tree1.basedir)
745
748
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-3',
746
749
                          verbose=False)
747
750
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-4')
761
764
        bundle_file = StringIO()
762
765
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
763
766
                               'a@cset-0-1', bundle_file, format=self.format)
764
 
        self.assertNotContainsRe(bundle_file.getvalue(), 'two')
 
767
        self.assertNotContainsRe(bundle_file.getvalue(), '\btwo\b')
765
768
        self.assertContainsRe(bundle_file.getvalue(), 'one')
766
769
        self.assertContainsRe(bundle_file.getvalue(), 'three')
767
770
 
781
784
            u'William Dod\xe9\n').encode('utf-8'))
782
785
        f.close()
783
786
 
784
 
        self.tree1.add([u'with Dod\xe9'])
785
 
        self.tree1.commit(u'i18n commit from William Dod\xe9', 
 
787
        self.tree1.add([u'with Dod\xe9'], ['withdod-id'])
 
788
        self.tree1.commit(u'i18n commit from William Dod\xe9',
786
789
                          rev_id='i18n-1', committer=u'William Dod\xe9')
787
790
 
 
791
        if sys.platform == 'darwin':
 
792
            # On Mac the '\xe9' gets changed to 'e\u0301'
 
793
            self.assertEqual([u'.bzr', u'with Dode\u0301'],
 
794
                             sorted(os.listdir(u'b1')))
 
795
            delta = self.tree1.changes_from(self.tree1.basis_tree())
 
796
            self.assertEqual([(u'with Dod\xe9', 'withdod-id', 'file')],
 
797
                             delta.removed)
 
798
            self.knownFailure("Mac OSX doesn't preserve unicode"
 
799
                              " combining characters.")
 
800
 
788
801
        # Add
789
802
        bundle = self.get_valid_bundle(None, 'i18n-1')
790
803
 
881
894
        tree = bundle.revision_tree(self.b1.repository, 'revid1')
882
895
        self.assertEqual('revid1', tree.inventory.root.revision)
883
896
 
 
897
    def test_install_revisions(self):
 
898
        self.tree1 = self.make_branch_and_tree('b1')
 
899
        self.b1 = self.tree1.branch
 
900
        self.tree1.commit('message', rev_id='rev2a')
 
901
        bundle = self.get_valid_bundle(None, 'rev2a')
 
902
        branch2 = self.make_branch('b2')
 
903
        self.assertFalse(branch2.repository.has_revision('rev2a'))
 
904
        target_revision = bundle.install_revisions(branch2.repository)
 
905
        self.assertTrue(branch2.repository.has_revision('rev2a'))
 
906
        self.assertEqual('rev2a', target_revision)
 
907
 
 
908
    def test_bundle_empty_property(self):
 
909
        """Test serializing revision properties with an empty value."""
 
910
        tree = self.make_branch_and_memory_tree('tree')
 
911
        tree.lock_write()
 
912
        self.addCleanup(tree.unlock)
 
913
        tree.add([''], ['TREE_ROOT'])
 
914
        tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
 
915
        self.b1 = tree.branch
 
916
        bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
 
917
        self.assertContainsRe(bundle_sio.getvalue(),
 
918
                              '# properties:\n'
 
919
                              '#   branch-nick: tree\n'
 
920
                              '#   empty: \n'
 
921
                              '#   one: two\n'
 
922
                             )
 
923
        bundle = read_bundle(bundle_sio)
 
924
        revision_info = bundle.revisions[0]
 
925
        self.assertEqual('rev1', revision_info.revision_id)
 
926
        rev = revision_info.as_revision()
 
927
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
 
928
                         rev.properties)
 
929
 
 
930
    def test_bundle_empty_property_alt(self):
 
931
        """Test serializing revision properties with an empty value.
 
932
 
 
933
        Older readers had a bug when reading an empty property.
 
934
        They assumed that all keys ended in ': \n'. However they would write an
 
935
        empty value as ':\n'. This tests make sure that all newer bzr versions
 
936
        can handle th second form.
 
937
        """
 
938
        tree = self.make_branch_and_memory_tree('tree')
 
939
        tree.lock_write()
 
940
        self.addCleanup(tree.unlock)
 
941
        tree.add([''], ['TREE_ROOT'])
 
942
        tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
 
943
        self.b1 = tree.branch
 
944
        bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
 
945
        txt = bundle_sio.getvalue()
 
946
        loc = txt.find('#   empty: ') + len('#   empty:')
 
947
        # Create a new bundle, which strips the trailing space after empty
 
948
        bundle_sio = StringIO(txt[:loc] + txt[loc+1:])
 
949
 
 
950
        self.assertContainsRe(bundle_sio.getvalue(),
 
951
                              '# properties:\n'
 
952
                              '#   branch-nick: tree\n'
 
953
                              '#   empty:\n'
 
954
                              '#   one: two\n'
 
955
                             )
 
956
        bundle = read_bundle(bundle_sio)
 
957
        revision_info = bundle.revisions[0]
 
958
        self.assertEqual('rev1', revision_info.revision_id)
 
959
        rev = revision_info.as_revision()
 
960
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
 
961
                         rev.properties)
 
962
 
 
963
    def test_bundle_sorted_properties(self):
 
964
        """For stability the writer should write properties in sorted order."""
 
965
        tree = self.make_branch_and_memory_tree('tree')
 
966
        tree.lock_write()
 
967
        self.addCleanup(tree.unlock)
 
968
 
 
969
        tree.add([''], ['TREE_ROOT'])
 
970
        tree.commit('One', rev_id='rev1',
 
971
                    revprops={'a':'4', 'b':'3', 'c':'2', 'd':'1'})
 
972
        self.b1 = tree.branch
 
973
        bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
 
974
        self.assertContainsRe(bundle_sio.getvalue(),
 
975
                              '# properties:\n'
 
976
                              '#   a: 4\n'
 
977
                              '#   b: 3\n'
 
978
                              '#   branch-nick: tree\n'
 
979
                              '#   c: 2\n'
 
980
                              '#   d: 1\n'
 
981
                             )
 
982
        bundle = read_bundle(bundle_sio)
 
983
        revision_info = bundle.revisions[0]
 
984
        self.assertEqual('rev1', revision_info.revision_id)
 
985
        rev = revision_info.as_revision()
 
986
        self.assertEqual({'branch-nick':'tree', 'a':'4', 'b':'3', 'c':'2',
 
987
                          'd':'1'}, rev.properties)
 
988
 
 
989
    def test_bundle_unicode_properties(self):
 
990
        """We should be able to round trip a non-ascii property."""
 
991
        tree = self.make_branch_and_memory_tree('tree')
 
992
        tree.lock_write()
 
993
        self.addCleanup(tree.unlock)
 
994
 
 
995
        tree.add([''], ['TREE_ROOT'])
 
996
        # Revisions themselves do not require anything about revision property
 
997
        # keys, other than that they are a basestring, and do not contain
 
998
        # whitespace.
 
999
        # However, Testaments assert than they are str(), and thus should not
 
1000
        # be Unicode.
 
1001
        tree.commit('One', rev_id='rev1',
 
1002
                    revprops={'omega':u'\u03a9', 'alpha':u'\u03b1'})
 
1003
        self.b1 = tree.branch
 
1004
        bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
 
1005
        self.assertContainsRe(bundle_sio.getvalue(),
 
1006
                              '# properties:\n'
 
1007
                              '#   alpha: \xce\xb1\n'
 
1008
                              '#   branch-nick: tree\n'
 
1009
                              '#   omega: \xce\xa9\n'
 
1010
                             )
 
1011
        bundle = read_bundle(bundle_sio)
 
1012
        revision_info = bundle.revisions[0]
 
1013
        self.assertEqual('rev1', revision_info.revision_id)
 
1014
        rev = revision_info.as_revision()
 
1015
        self.assertEqual({'branch-nick':'tree', 'omega':u'\u03a9',
 
1016
                          'alpha':u'\u03b1'}, rev.properties)
 
1017
 
884
1018
 
885
1019
class V09BundleKnit2Tester(V08BundleTester):
886
1020
 
888
1022
 
889
1023
    def bzrdir_format(self):
890
1024
        format = bzrdir.BzrDirMetaFormat1()
891
 
        format.repository_format = repository.RepositoryFormatKnit2()
 
1025
        format.repository_format = knitrepo.RepositoryFormatKnit3()
892
1026
        return format
893
1027
 
894
1028
 
898
1032
 
899
1033
    def bzrdir_format(self):
900
1034
        format = bzrdir.BzrDirMetaFormat1()
901
 
        format.repository_format = repository.RepositoryFormatKnit1()
 
1035
        format.repository_format = knitrepo.RepositoryFormatKnit1()
902
1036
        return format
903
1037
 
904
1038