~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bundle.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
from cStringIO import StringIO
18
18
import os
19
 
import socket
 
19
import SocketServer
20
20
import sys
21
 
import threading
22
21
 
23
22
from bzrlib import (
24
23
    bzrdir,
28
27
    merge,
29
28
    osutils,
30
29
    revision as _mod_revision,
31
 
    symbol_versioning,
32
30
    tests,
33
31
    treebuilder,
34
32
    )
42
40
from bzrlib.bundle.serializer.v4 import BundleSerializerV4
43
41
from bzrlib.repofmt import knitrepo
44
42
from bzrlib.tests import (
 
43
    features,
 
44
    test_commit,
45
45
    test_read_bundle,
46
 
    test_commit,
 
46
    test_server,
47
47
    )
48
48
from bzrlib.transform import TreeTransform
49
49
 
65
65
 
66
66
 
67
67
class MockTree(object):
 
68
 
68
69
    def __init__(self):
69
70
        from bzrlib.inventory import InventoryDirectory, ROOT_ID
70
71
        object.__init__(self)
74
75
        self.root = InventoryDirectory(ROOT_ID, '', None)
75
76
 
76
77
    inventory = property(lambda x:x)
77
 
 
78
 
    def __iter__(self):
79
 
        return self.paths.iterkeys()
 
78
    root_inventory = property(lambda x:x)
 
79
 
 
80
    def get_root_id(self):
 
81
        return self.root.file_id
 
82
 
 
83
    def all_file_ids(self):
 
84
        return set(self.paths.keys())
 
85
 
 
86
    def is_executable(self, file_id):
 
87
        # Not all the files are executable.
 
88
        return False
80
89
 
81
90
    def __getitem__(self, file_id):
82
91
        if file_id == self.root.file_id:
94
103
        for path, file_id in self.ids.iteritems():
95
104
            yield path, self[file_id]
96
105
 
97
 
    def get_file_kind(self, file_id):
 
106
    def kind(self, file_id):
98
107
        if file_id in self.contents:
99
108
            kind = 'file'
100
109
        else:
102
111
        return kind
103
112
 
104
113
    def make_entry(self, file_id, path):
105
 
        from bzrlib.inventory import (InventoryEntry, InventoryFile
106
 
                                    , InventoryDirectory, InventoryLink)
 
114
        from bzrlib.inventory import (InventoryFile , InventoryDirectory,
 
115
            InventoryLink)
107
116
        name = os.path.basename(path)
108
 
        kind = self.get_file_kind(file_id)
 
117
        kind = self.kind(file_id)
109
118
        parent_id = self.parent_id(file_id)
110
119
        text_sha_1, text_size = self.contents_stats(file_id)
111
120
        if kind == 'directory':
146
155
    def get_file_revision(self, file_id):
147
156
        return self.inventory[file_id].revision
148
157
 
 
158
    def get_file_size(self, file_id):
 
159
        return self.inventory[file_id].text_size
 
160
 
 
161
    def get_file_sha1(self, file_id):
 
162
        return self.inventory[file_id].text_sha1
 
163
 
149
164
    def contents_stats(self, file_id):
150
165
        if file_id not in self.contents:
151
166
            return None, None
314
329
        self.assertTrue(btree.path2id("grandparent/parent/file") is None)
315
330
 
316
331
    def sorted_ids(self, tree):
317
 
        ids = list(tree)
 
332
        ids = list(tree.all_file_ids())
318
333
        ids.sort()
319
334
        return ids
320
335
 
493
508
                                 % (ancestor,))
494
509
 
495
510
                # Now check that the file contents are all correct
496
 
                for inventory_id in old:
 
511
                for inventory_id in old.all_file_ids():
497
512
                    try:
498
513
                        old_file = old.get_file(inventory_id)
499
514
                    except errors.NoSuchFile:
506
521
                new.unlock()
507
522
                old.unlock()
508
523
        if not _mod_revision.is_null(rev_id):
509
 
            rh = self.b1.revision_history()
510
 
            self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
511
 
                tree.branch.set_revision_history, rh[:rh.index(rev_id)+1])
 
524
            tree.branch.generate_revision_history(rev_id)
512
525
            tree.update()
513
526
            delta = tree.changes_from(self.b1.repository.revision_tree(rev_id))
514
527
            self.assertFalse(delta.has_changed(),
650
663
        bundle = self.get_valid_bundle('null:', 'a@cset-0-4')
651
664
 
652
665
        # Modified files
653
 
        open('b1/sub/dir/WithCaps.txt', 'ab').write('\nAdding some text\n')
654
 
        open('b1/sub/dir/ pre space', 'ab').write(
 
666
        with open('b1/sub/dir/WithCaps.txt', 'ab') as f: f.write('\nAdding some text\n')
 
667
        with open('b1/sub/dir/ pre space', 'ab') as f: f.write(
655
668
             '\r\nAdding some\r\nDOS format lines\r\n')
656
 
        open('b1/sub/dir/nolastnewline.txt', 'ab').write('\n')
 
669
        with open('b1/sub/dir/nolastnewline.txt', 'ab') as f: f.write('\n')
657
670
        self.tree1.rename_one('sub/dir/ pre space',
658
671
                              'sub/ start space')
659
672
        self.tree1.commit('Modified files', rev_id='a@cset-0-5')
681
694
    def _test_symlink_bundle(self, link_name, link_target, new_link_target):
682
695
        link_id = 'link-1'
683
696
 
684
 
        self.requireFeature(tests.SymlinkFeature)
 
697
        self.requireFeature(features.SymlinkFeature)
685
698
        self.tree1 = self.make_branch_and_tree('b1')
686
699
        self.b1 = self.tree1.branch
687
700
 
728
741
        self._test_symlink_bundle('link', 'bar/foo', 'mars')
729
742
 
730
743
    def test_unicode_symlink_bundle(self):
731
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
744
        self.requireFeature(features.UnicodeFilenameFeature)
732
745
        self._test_symlink_bundle(u'\N{Euro Sign}link',
733
746
                                  u'bar/\N{Euro Sign}foo',
734
747
                                  u'mars\N{Euro Sign}')
808
821
        self.tree1 = self.make_branch_and_tree('b1')
809
822
        self.b1 = self.tree1.branch
810
823
 
811
 
        open('b1/one', 'wb').write('one\n')
 
824
        with open('b1/one', 'wb') as f: f.write('one\n')
812
825
        self.tree1.add('one')
813
826
        self.tree1.commit('add file', rev_id='a@cset-0-1')
814
 
        open('b1/one', 'wb').write('two\n')
 
827
        with open('b1/one', 'wb') as f: f.write('two\n')
815
828
        self.tree1.commit('modify', rev_id='a@cset-0-2')
816
 
        open('b1/one', 'wb').write('three\n')
 
829
        with open('b1/one', 'wb') as f: f.write('three\n')
817
830
        self.tree1.commit('modify', rev_id='a@cset-0-3')
818
831
        bundle_file = StringIO()
819
832
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
835
848
        return bundle_file.getvalue()
836
849
 
837
850
    def test_unicode_bundle(self):
838
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
851
        self.requireFeature(features.UnicodeFilenameFeature)
839
852
        # Handle international characters
840
853
        os.mkdir('b1')
841
854
        f = open(u'b1/with Dod\N{Euro Sign}', 'wb')
898
911
        bundle = self.get_valid_bundle('null:', 'white-1')
899
912
 
900
913
        # Modified
901
 
        open('b1/trailing space ', 'ab').write('add some text\n')
 
914
        with open('b1/trailing space ', 'ab') as f: f.write('add some text\n')
902
915
        self.tree1.commit('add text', rev_id='white-2')
903
916
 
904
917
        bundle = self.get_valid_bundle('white-1', 'white-2')
946
959
        self.tree1.commit('message', rev_id='revid1')
947
960
        bundle = self.get_valid_bundle('null:', 'revid1')
948
961
        tree = self.get_bundle_tree(bundle, 'revid1')
949
 
        self.assertEqual('revid1', tree.inventory.root.revision)
 
962
        root_revision = tree.get_file_revision(tree.get_root_id())
 
963
        self.assertEqual('revid1', root_revision)
950
964
 
951
965
    def test_install_revisions(self):
952
966
        self.tree1 = self.make_branch_and_tree('b1')
1419
1433
            from bzrlib.testament import Testament
1420
1434
            # monkey patch gpg signing mechanism
1421
1435
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
1422
 
            new_config = test_commit.MustSignConfig(branch)
1423
 
            commit.Commit(config=new_config).commit(message="base",
 
1436
            new_config = test_commit.MustSignConfig()
 
1437
            commit.Commit(config_stack=new_config).commit(message="base",
1424
1438
                                                    allow_pointless=True,
1425
1439
                                                    rev_id='B',
1426
1440
                                                    working_tree=tree_a)
1835
1849
        bundle, then the ConnectionReset error should be propagated.
1836
1850
        """
1837
1851
        # Instantiate a server that will provoke a ConnectionReset
1838
 
        sock_server = _DisconnectingTCPServer()
 
1852
        sock_server = DisconnectingServer()
1839
1853
        self.start_server(sock_server)
1840
1854
        # We don't really care what the url is since the server will close the
1841
1855
        # connection without interpreting it
1843
1857
        self.assertRaises(errors.ConnectionReset, read_mergeable_from_url, url)
1844
1858
 
1845
1859
 
1846
 
class _DisconnectingTCPServer(object):
1847
 
    """A TCP server that immediately closes any connection made to it."""
1848
 
 
1849
 
    def start_server(self):
1850
 
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1851
 
        self.sock.bind(('127.0.0.1', 0))
1852
 
        self.sock.listen(1)
1853
 
        self.port = self.sock.getsockname()[1]
1854
 
        self.thread = threading.Thread(
1855
 
            name='%s (port %d)' % (self.__class__.__name__, self.port),
1856
 
            target=self.accept_and_close)
1857
 
        self.thread.start()
1858
 
 
1859
 
    def accept_and_close(self):
1860
 
        conn, addr = self.sock.accept()
1861
 
        conn.shutdown(socket.SHUT_RDWR)
1862
 
        conn.close()
 
1860
class DisconnectingHandler(SocketServer.BaseRequestHandler):
 
1861
    """A request handler that immediately closes any connection made to it."""
 
1862
 
 
1863
    def handle(self):
 
1864
        self.request.close()
 
1865
 
 
1866
 
 
1867
class DisconnectingServer(test_server.TestingTCPServerInAThread):
 
1868
 
 
1869
    def __init__(self):
 
1870
        super(DisconnectingServer, self).__init__(
 
1871
            ('127.0.0.1', 0),
 
1872
            test_server.TestingTCPServer,
 
1873
            DisconnectingHandler)
1863
1874
 
1864
1875
    def get_url(self):
1865
 
        return 'bzr://127.0.0.1:%d/' % (self.port,)
1866
 
 
1867
 
    def stop_server(self):
1868
 
        try:
1869
 
            # make sure the thread dies by connecting to the listening socket,
1870
 
            # just in case the test failed to do so.
1871
 
            conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1872
 
            conn.connect(self.sock.getsockname())
1873
 
            conn.close()
1874
 
        except socket.error:
1875
 
            pass
1876
 
        self.sock.close()
1877
 
        self.thread.join()
 
1876
        """Return the url of the server"""
 
1877
        return "bzr://%s:%d/" % self.server.server_address