~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Rework test_script a little bit.


Don't allow someone to request a stdin request to echo.
Echo never reads from stdin, it just echos its arguments.
You use 'cat' if you want to read from stdin.

A few other fixes because the tests were using filenames
that are actually illegal on Windows, rather than just
nonexistant.


Change the exception handling for commands so that
unknown errors don't get silently squashed and then
turn into hard-to-debug errors later.

test_script now passes on Windows.

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
 
36
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
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):
 
92
    def __init__(self, transport, format, _client=None, _force_probe=False):
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
102
103
        # 1-shot cache for the call pattern 'create_branch; open_branch' - see
103
104
        # create_branch for details.
104
105
        self._next_open_branch_result = None
108
109
            self._client = client._SmartClient(medium)
109
110
        else:
110
111
            self._client = _client
111
 
            return
112
 
 
 
112
            if not _force_probe:
 
113
                return
 
114
 
 
115
        self._probe_bzrdir()
 
116
 
 
117
    def _probe_bzrdir(self):
 
118
        medium = self._client._medium
113
119
        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):
114
145
        response = self._call('BzrDir.open', path)
115
146
        if response not in [('yes',), ('no',)]:
116
147
            raise errors.UnexpectedSmartServerResponse(response)
117
148
        if response == ('no',):
118
 
            raise errors.NotBranchError(path=transport.base)
 
149
            raise errors.NotBranchError(path=self.root_transport.base)
119
150
 
120
151
    def _ensure_real(self):
121
152
        """Ensure that there is a _real_bzrdir set.
355
386
        else:
356
387
            raise errors.NoRepositoryPresent(self)
357
388
 
 
389
    def has_workingtree(self):
 
390
        if self._has_working_tree is None:
 
391
            self._ensure_real()
 
392
            self._has_working_tree = self._real_bzrdir.has_workingtree()
 
393
        return self._has_working_tree
 
394
 
358
395
    def open_workingtree(self, recommend_upgrade=True):
359
 
        self._ensure_real()
360
 
        if self._real_bzrdir.has_workingtree():
 
396
        if self.has_workingtree():
361
397
            raise errors.NotLocalUrl(self.root_transport)
362
398
        else:
363
399
            raise errors.NoWorkingTree(self.root_transport.base)
583
619
        return self._custom_format._serializer
584
620
 
585
621
 
586
 
class RemoteRepository(_RpcHelper):
 
622
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
587
623
    """Repository accessed over rpc.
588
624
 
589
625
    For the moment most operations are performed using local transport-backed
913
949
    def lock_read(self):
914
950
        # wrong eventually - want a local lock cache context
915
951
        if not self._lock_mode:
 
952
            self._note_lock('r')
916
953
            self._lock_mode = 'r'
917
954
            self._lock_count = 1
918
955
            self._unstacked_provider.enable_cache(cache_misses=True)
938
975
 
939
976
    def lock_write(self, token=None, _skip_rpc=False):
940
977
        if not self._lock_mode:
 
978
            self._note_lock('w')
941
979
            if _skip_rpc:
942
980
                if self._lock_token is not None:
943
981
                    if token != self._lock_token:
1046
1084
        else:
1047
1085
            raise errors.UnexpectedSmartServerResponse(response)
1048
1086
 
 
1087
    @only_raises(errors.LockNotHeld, errors.LockBroken)
1049
1088
    def unlock(self):
1050
1089
        if not self._lock_count:
1051
1090
            return lock.cant_unlock_not_held(self)
2045
2084
        return self._custom_format.supports_set_append_revisions_only()
2046
2085
 
2047
2086
 
2048
 
class RemoteBranch(branch.Branch, _RpcHelper):
 
2087
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
2049
2088
    """Branch stored on a server accessed by HPSS RPC.
2050
2089
 
2051
2090
    At the moment most operations are mapped down to simple file operations.
2282
2321
    def lock_read(self):
2283
2322
        self.repository.lock_read()
2284
2323
        if not self._lock_mode:
 
2324
            self._note_lock('r')
2285
2325
            self._lock_mode = 'r'
2286
2326
            self._lock_count = 1
2287
2327
            if self._real_branch is not None:
2307
2347
 
2308
2348
    def lock_write(self, token=None):
2309
2349
        if not self._lock_mode:
 
2350
            self._note_lock('w')
2310
2351
            # Lock the branch and repo in one remote call.
2311
2352
            remote_tokens = self._remote_lock_write(token)
2312
2353
            self._lock_token, self._repo_lock_token = remote_tokens
2347
2388
            return
2348
2389
        raise errors.UnexpectedSmartServerResponse(response)
2349
2390
 
 
2391
    @only_raises(errors.LockNotHeld, errors.LockBroken)
2350
2392
    def unlock(self):
2351
2393
        try:
2352
2394
            self._lock_count -= 1