~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: John Arbash Meinel
  • Date: 2009-09-24 19:26:45 UTC
  • mto: (4634.52.3 2.0)
  • mto: This revision was merged to the branch mainline in revision 4716.
  • Revision ID: john@arbash-meinel.com-20090924192645-hyy1ycnnk6u3j5j6
Catch a corner case that we were missing.
The CHKInventory tests were passing, but failed for test_inv because
we were passing None to _getitems(). That only failed for InternalNodes,
but we were using a structure that didn't have internal nodes.
So now the test is parameterized on a small CHKInventory page size
to force those things out into the open.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
)
34
34
from bzrlib.branch import BranchReferenceFormat
35
35
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
36
 
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
 
36
from bzrlib.decorators import needs_read_lock, needs_write_lock
37
37
from bzrlib.errors import (
38
38
    NoSuchRevision,
39
39
    SmartProtocolError,
89
89
class RemoteBzrDir(BzrDir, _RpcHelper):
90
90
    """Control directory on a remote server, accessed via bzr:// or similar."""
91
91
 
92
 
    def __init__(self, transport, format, _client=None, _force_probe=False):
 
92
    def __init__(self, transport, format, _client=None):
93
93
        """Construct a RemoteBzrDir.
94
94
 
95
95
        :param _client: Private parameter for testing. Disables probing and the
99
99
        # this object holds a delegated bzrdir that uses file-level operations
100
100
        # to talk to the other side
101
101
        self._real_bzrdir = None
102
 
        self._has_working_tree = None
103
102
        # 1-shot cache for the call pattern 'create_branch; open_branch' - see
104
103
        # create_branch for details.
105
104
        self._next_open_branch_result = None
109
108
            self._client = client._SmartClient(medium)
110
109
        else:
111
110
            self._client = _client
112
 
            if not _force_probe:
113
 
                return
114
 
 
115
 
        self._probe_bzrdir()
116
 
 
117
 
    def _probe_bzrdir(self):
118
 
        medium = self._client._medium
 
111
            return
 
112
 
119
113
        path = self._path_for_remote_call(self._client)
120
 
        if medium._is_remote_before((2, 1)):
121
 
            self._rpc_open(path)
122
 
            return
123
 
        try:
124
 
            self._rpc_open_2_1(path)
125
 
            return
126
 
        except errors.UnknownSmartMethod:
127
 
            medium._remember_remote_is_before((2, 1))
128
 
            self._rpc_open(path)
129
 
 
130
 
    def _rpc_open_2_1(self, path):
131
 
        response = self._call('BzrDir.open_2.1', path)
132
 
        if response == ('no',):
133
 
            raise errors.NotBranchError(path=self.root_transport.base)
134
 
        elif response[0] == 'yes':
135
 
            if response[1] == 'yes':
136
 
                self._has_working_tree = True
137
 
            elif response[1] == 'no':
138
 
                self._has_working_tree = False
139
 
            else:
140
 
                raise errors.UnexpectedSmartServerResponse(response)
141
 
        else:
142
 
            raise errors.UnexpectedSmartServerResponse(response)
143
 
 
144
 
    def _rpc_open(self, path):
145
114
        response = self._call('BzrDir.open', path)
146
115
        if response not in [('yes',), ('no',)]:
147
116
            raise errors.UnexpectedSmartServerResponse(response)
148
117
        if response == ('no',):
149
 
            raise errors.NotBranchError(path=self.root_transport.base)
 
118
            raise errors.NotBranchError(path=transport.base)
150
119
 
151
120
    def _ensure_real(self):
152
121
        """Ensure that there is a _real_bzrdir set.
154
123
        Used before calls to self._real_bzrdir.
155
124
        """
156
125
        if not self._real_bzrdir:
157
 
            if 'hpssvfs' in debug.debug_flags:
158
 
                import traceback
159
 
                warning('VFS BzrDir access triggered\n%s',
160
 
                    ''.join(traceback.format_stack()))
161
126
            self._real_bzrdir = BzrDir.open_from_transport(
162
127
                self.root_transport, _server_formats=False)
163
128
            self._format._network_name = \
390
355
        else:
391
356
            raise errors.NoRepositoryPresent(self)
392
357
 
393
 
    def has_workingtree(self):
394
 
        if self._has_working_tree is None:
395
 
            self._ensure_real()
396
 
            self._has_working_tree = self._real_bzrdir.has_workingtree()
397
 
        return self._has_working_tree
398
 
 
399
358
    def open_workingtree(self, recommend_upgrade=True):
400
 
        if self.has_workingtree():
 
359
        self._ensure_real()
 
360
        if self._real_bzrdir.has_workingtree():
401
361
            raise errors.NotLocalUrl(self.root_transport)
402
362
        else:
403
363
            raise errors.NoWorkingTree(self.root_transport.base)
601
561
        return self._custom_format._fetch_reconcile
602
562
 
603
563
    def get_format_description(self):
604
 
        self._ensure_real()
605
 
        return 'Remote: ' + self._custom_format.get_format_description()
 
564
        return 'bzr remote repository'
606
565
 
607
566
    def __eq__(self, other):
608
567
        return self.__class__ is other.__class__
624
583
        return self._custom_format._serializer
625
584
 
626
585
 
627
 
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
 
586
class RemoteRepository(_RpcHelper):
628
587
    """Repository accessed over rpc.
629
588
 
630
589
    For the moment most operations are performed using local transport-backed
951
910
    def is_write_locked(self):
952
911
        return self._lock_mode == 'w'
953
912
 
954
 
    def _warn_if_deprecated(self, branch=None):
955
 
        # If we have a real repository, the check will be done there, if we
956
 
        # don't the check will be done remotely.
957
 
        pass
958
 
 
959
913
    def lock_read(self):
960
914
        # wrong eventually - want a local lock cache context
961
915
        if not self._lock_mode:
962
 
            self._note_lock('r')
963
916
            self._lock_mode = 'r'
964
917
            self._lock_count = 1
965
918
            self._unstacked_provider.enable_cache(cache_misses=True)
985
938
 
986
939
    def lock_write(self, token=None, _skip_rpc=False):
987
940
        if not self._lock_mode:
988
 
            self._note_lock('w')
989
941
            if _skip_rpc:
990
942
                if self._lock_token is not None:
991
943
                    if token != self._lock_token:
1094
1046
        else:
1095
1047
            raise errors.UnexpectedSmartServerResponse(response)
1096
1048
 
1097
 
    @only_raises(errors.LockNotHeld, errors.LockBroken)
1098
1049
    def unlock(self):
1099
1050
        if not self._lock_count:
1100
1051
            return lock.cant_unlock_not_held(self)
1936
1887
        :param search: The overall search to satisfy with streams.
1937
1888
        :param sources: A list of Repository objects to query.
1938
1889
        """
1939
 
        self.from_serialiser = self.from_repository._format._serializer
 
1890
        self.serialiser = self.to_format._serializer
1940
1891
        self.seen_revs = set()
1941
1892
        self.referenced_revs = set()
1942
1893
        # If there are heads in the search, or the key count is > 0, we are not
1959
1910
    def missing_parents_rev_handler(self, substream):
1960
1911
        for content in substream:
1961
1912
            revision_bytes = content.get_bytes_as('fulltext')
1962
 
            revision = self.from_serialiser.read_revision_from_string(
1963
 
                revision_bytes)
 
1913
            revision = self.serialiser.read_revision_from_string(revision_bytes)
1964
1914
            self.seen_revs.add(content.key[-1])
1965
1915
            self.referenced_revs.update(revision.parent_ids)
1966
1916
            yield content
2005
1955
                self._network_name)
2006
1956
 
2007
1957
    def get_format_description(self):
2008
 
        self._ensure_real()
2009
 
        return 'Remote: ' + self._custom_format.get_format_description()
 
1958
        return 'Remote BZR Branch'
2010
1959
 
2011
1960
    def network_name(self):
2012
1961
        return self._network_name
2095
2044
        return self._custom_format.supports_set_append_revisions_only()
2096
2045
 
2097
2046
 
2098
 
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
 
2047
class RemoteBranch(branch.Branch, _RpcHelper):
2099
2048
    """Branch stored on a server accessed by HPSS RPC.
2100
2049
 
2101
2050
    At the moment most operations are mapped down to simple file operations.
2332
2281
    def lock_read(self):
2333
2282
        self.repository.lock_read()
2334
2283
        if not self._lock_mode:
2335
 
            self._note_lock('r')
2336
2284
            self._lock_mode = 'r'
2337
2285
            self._lock_count = 1
2338
2286
            if self._real_branch is not None:
2358
2306
 
2359
2307
    def lock_write(self, token=None):
2360
2308
        if not self._lock_mode:
2361
 
            self._note_lock('w')
2362
2309
            # Lock the branch and repo in one remote call.
2363
2310
            remote_tokens = self._remote_lock_write(token)
2364
2311
            self._lock_token, self._repo_lock_token = remote_tokens
2399
2346
            return
2400
2347
        raise errors.UnexpectedSmartServerResponse(response)
2401
2348
 
2402
 
    @only_raises(errors.LockNotHeld, errors.LockBroken)
2403
2349
    def unlock(self):
2404
2350
        try:
2405
2351
            self._lock_count -= 1
2445
2391
            raise NotImplementedError(self.dont_leave_lock_in_place)
2446
2392
        self._leave_lock = False
2447
2393
 
2448
 
    @needs_read_lock
2449
2394
    def get_rev_id(self, revno, history=None):
2450
2395
        if revno == 0:
2451
2396
            return _mod_revision.NULL_REVISION