~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bundle.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-05-11 15:04:23 UTC
  • mfrom: (5848.1.1 2.4-cython-first)
  • Revision ID: pqm@pqm.ubuntu.com-20110511150423-tpm1ablukqalkvim
(jameinel) Default to using Cython for compiling code,
 rather than Pyrex. (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2013, 2016 Canonical Ltd
 
1
# Copyright (C) 2005-2011 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
16
16
 
17
17
from cStringIO import StringIO
18
18
import os
19
 
import SocketServer
 
19
import socket
20
20
import sys
 
21
import threading
21
22
 
22
23
from bzrlib import (
23
24
    bzrdir,
27
28
    merge,
28
29
    osutils,
29
30
    revision as _mod_revision,
 
31
    symbol_versioning,
30
32
    tests,
31
33
    treebuilder,
32
34
    )
40
42
from bzrlib.bundle.serializer.v4 import BundleSerializerV4
41
43
from bzrlib.repofmt import knitrepo
42
44
from bzrlib.tests import (
43
 
    features,
 
45
    test_read_bundle,
44
46
    test_commit,
45
 
    test_read_bundle,
46
 
    test_server,
47
47
    )
48
48
from bzrlib.transform import TreeTransform
49
49
 
75
75
        self.root = InventoryDirectory(ROOT_ID, '', None)
76
76
 
77
77
    inventory = property(lambda x:x)
78
 
    root_inventory = property(lambda x:x)
79
 
 
80
 
    def get_root_id(self):
81
 
        return self.root.file_id
82
78
 
83
79
    def all_file_ids(self):
84
80
        return set(self.paths.keys())
85
81
 
86
 
    def is_executable(self, file_id):
87
 
        # Not all the files are executable.
88
 
        return False
89
 
 
90
82
    def __getitem__(self, file_id):
91
83
        if file_id == self.root.file_id:
92
84
            return self.root
103
95
        for path, file_id in self.ids.iteritems():
104
96
            yield path, self[file_id]
105
97
 
106
 
    def kind(self, file_id):
 
98
    def get_file_kind(self, file_id):
107
99
        if file_id in self.contents:
108
100
            kind = 'file'
109
101
        else:
111
103
        return kind
112
104
 
113
105
    def make_entry(self, file_id, path):
114
 
        from bzrlib.inventory import (InventoryFile , InventoryDirectory,
115
 
            InventoryLink)
 
106
        from bzrlib.inventory import (InventoryEntry, InventoryFile
 
107
                                    , InventoryDirectory, InventoryLink)
116
108
        name = os.path.basename(path)
117
 
        kind = self.kind(file_id)
 
109
        kind = self.get_file_kind(file_id)
118
110
        parent_id = self.parent_id(file_id)
119
111
        text_sha_1, text_size = self.contents_stats(file_id)
120
112
        if kind == 'directory':
155
147
    def get_file_revision(self, file_id):
156
148
        return self.inventory[file_id].revision
157
149
 
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
 
 
164
150
    def contents_stats(self, file_id):
165
151
        if file_id not in self.contents:
166
152
            return None, None
329
315
        self.assertTrue(btree.path2id("grandparent/parent/file") is None)
330
316
 
331
317
    def sorted_ids(self, tree):
332
 
        ids = list(tree.all_file_ids())
 
318
        ids = list(tree)
333
319
        ids.sort()
334
320
        return ids
335
321
 
521
507
                new.unlock()
522
508
                old.unlock()
523
509
        if not _mod_revision.is_null(rev_id):
524
 
            tree.branch.generate_revision_history(rev_id)
 
510
            rh = self.b1.revision_history()
 
511
            self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
 
512
                tree.branch.set_revision_history, rh[:rh.index(rev_id)+1])
525
513
            tree.update()
526
514
            delta = tree.changes_from(self.b1.repository.revision_tree(rev_id))
527
515
            self.assertFalse(delta.has_changed(),
545
533
        original_parents = to_tree.get_parent_ids()
546
534
        self.assertIs(repository.has_revision(base_rev_id), True)
547
535
        for rev in info.real_revisions:
548
 
            self.assertTrue(not repository.has_revision(rev.revision_id),
549
 
                            'Revision {%s} present before applying bundle'
550
 
                            % rev.revision_id)
 
536
            self.assert_(not repository.has_revision(rev.revision_id),
 
537
                'Revision {%s} present before applying bundle'
 
538
                % rev.revision_id)
551
539
        merge_bundle(info, to_tree, True, merge.Merge3Merger, False, False)
552
540
 
553
541
        for rev in info.real_revisions:
554
 
            self.assertTrue(repository.has_revision(rev.revision_id),
555
 
                            'Missing revision {%s} after applying bundle'
556
 
                            % rev.revision_id)
 
542
            self.assert_(repository.has_revision(rev.revision_id),
 
543
                'Missing revision {%s} after applying bundle'
 
544
                % rev.revision_id)
557
545
 
558
 
        self.assertTrue(to_tree.branch.repository.has_revision(info.target))
 
546
        self.assert_(to_tree.branch.repository.has_revision(info.target))
559
547
        # Do we also want to verify that all the texts have been added?
560
548
 
561
549
        self.assertEqual(original_parents + [info.target],
562
 
                         to_tree.get_parent_ids())
 
550
            to_tree.get_parent_ids())
563
551
 
564
552
        rev = info.real_revisions[-1]
565
553
        base_tree = self.b1.repository.revision_tree(rev.revision_id)
663
651
        bundle = self.get_valid_bundle('null:', 'a@cset-0-4')
664
652
 
665
653
        # Modified files
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(
 
654
        open('b1/sub/dir/WithCaps.txt', 'ab').write('\nAdding some text\n')
 
655
        open('b1/sub/dir/ pre space', 'ab').write(
668
656
             '\r\nAdding some\r\nDOS format lines\r\n')
669
 
        with open('b1/sub/dir/nolastnewline.txt', 'ab') as f: f.write('\n')
 
657
        open('b1/sub/dir/nolastnewline.txt', 'ab').write('\n')
670
658
        self.tree1.rename_one('sub/dir/ pre space',
671
659
                              'sub/ start space')
672
660
        self.tree1.commit('Modified files', rev_id='a@cset-0-5')
694
682
    def _test_symlink_bundle(self, link_name, link_target, new_link_target):
695
683
        link_id = 'link-1'
696
684
 
697
 
        self.requireFeature(features.SymlinkFeature)
 
685
        self.requireFeature(tests.SymlinkFeature)
698
686
        self.tree1 = self.make_branch_and_tree('b1')
699
687
        self.b1 = self.tree1.branch
700
688
 
741
729
        self._test_symlink_bundle('link', 'bar/foo', 'mars')
742
730
 
743
731
    def test_unicode_symlink_bundle(self):
744
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
732
        self.requireFeature(tests.UnicodeFilenameFeature)
745
733
        self._test_symlink_bundle(u'\N{Euro Sign}link',
746
734
                                  u'bar/\N{Euro Sign}foo',
747
735
                                  u'mars\N{Euro Sign}')
821
809
        self.tree1 = self.make_branch_and_tree('b1')
822
810
        self.b1 = self.tree1.branch
823
811
 
824
 
        with open('b1/one', 'wb') as f: f.write('one\n')
 
812
        open('b1/one', 'wb').write('one\n')
825
813
        self.tree1.add('one')
826
814
        self.tree1.commit('add file', rev_id='a@cset-0-1')
827
 
        with open('b1/one', 'wb') as f: f.write('two\n')
 
815
        open('b1/one', 'wb').write('two\n')
828
816
        self.tree1.commit('modify', rev_id='a@cset-0-2')
829
 
        with open('b1/one', 'wb') as f: f.write('three\n')
 
817
        open('b1/one', 'wb').write('three\n')
830
818
        self.tree1.commit('modify', rev_id='a@cset-0-3')
831
819
        bundle_file = StringIO()
832
820
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
848
836
        return bundle_file.getvalue()
849
837
 
850
838
    def test_unicode_bundle(self):
851
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
839
        self.requireFeature(tests.UnicodeFilenameFeature)
852
840
        # Handle international characters
853
841
        os.mkdir('b1')
854
842
        f = open(u'b1/with Dod\N{Euro Sign}', 'wb')
911
899
        bundle = self.get_valid_bundle('null:', 'white-1')
912
900
 
913
901
        # Modified
914
 
        with open('b1/trailing space ', 'ab') as f: f.write('add some text\n')
 
902
        open('b1/trailing space ', 'ab').write('add some text\n')
915
903
        self.tree1.commit('add text', rev_id='white-2')
916
904
 
917
905
        bundle = self.get_valid_bundle('white-1', 'white-2')
959
947
        self.tree1.commit('message', rev_id='revid1')
960
948
        bundle = self.get_valid_bundle('null:', 'revid1')
961
949
        tree = self.get_bundle_tree(bundle, 'revid1')
962
 
        root_revision = tree.get_file_revision(tree.get_root_id())
963
 
        self.assertEqual('revid1', root_revision)
 
950
        self.assertEqual('revid1', tree.inventory.root.revision)
964
951
 
965
952
    def test_install_revisions(self):
966
953
        self.tree1 = self.make_branch_and_tree('b1')
1433
1420
            from bzrlib.testament import Testament
1434
1421
            # monkey patch gpg signing mechanism
1435
1422
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
1436
 
            new_config = test_commit.MustSignConfig()
1437
 
            commit.Commit(config_stack=new_config).commit(message="base",
 
1423
            new_config = test_commit.MustSignConfig(branch)
 
1424
            commit.Commit(config=new_config).commit(message="base",
1438
1425
                                                    allow_pointless=True,
1439
1426
                                                    rev_id='B',
1440
1427
                                                    working_tree=tree_a)
1849
1836
        bundle, then the ConnectionReset error should be propagated.
1850
1837
        """
1851
1838
        # Instantiate a server that will provoke a ConnectionReset
1852
 
        sock_server = DisconnectingServer()
 
1839
        sock_server = _DisconnectingTCPServer()
1853
1840
        self.start_server(sock_server)
1854
1841
        # We don't really care what the url is since the server will close the
1855
1842
        # connection without interpreting it
1857
1844
        self.assertRaises(errors.ConnectionReset, read_mergeable_from_url, url)
1858
1845
 
1859
1846
 
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)
 
1847
class _DisconnectingTCPServer(object):
 
1848
    """A TCP server that immediately closes any connection made to it."""
 
1849
 
 
1850
    def start_server(self):
 
1851
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
1852
        self.sock.bind(('127.0.0.1', 0))
 
1853
        self.sock.listen(1)
 
1854
        self.port = self.sock.getsockname()[1]
 
1855
        self.thread = threading.Thread(
 
1856
            name='%s (port %d)' % (self.__class__.__name__, self.port),
 
1857
            target=self.accept_and_close)
 
1858
        self.thread.start()
 
1859
 
 
1860
    def accept_and_close(self):
 
1861
        conn, addr = self.sock.accept()
 
1862
        conn.shutdown(socket.SHUT_RDWR)
 
1863
        conn.close()
1874
1864
 
1875
1865
    def get_url(self):
1876
 
        """Return the url of the server"""
1877
 
        return "bzr://%s:%d/" % self.server.server_address
 
1866
        return 'bzr://127.0.0.1:%d/' % (self.port,)
 
1867
 
 
1868
    def stop_server(self):
 
1869
        try:
 
1870
            # make sure the thread dies by connecting to the listening socket,
 
1871
            # just in case the test failed to do so.
 
1872
            conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
1873
            conn.connect(self.sock.getsockname())
 
1874
            conn.close()
 
1875
        except socket.error:
 
1876
            pass
 
1877
        self.sock.close()
 
1878
        self.thread.join()