215
214
(other.start, other.length, other.ranges))
217
class LateReadError(object):
218
"""A helper for transports which pretends to be a readable file.
220
When read() is called, errors.ReadError is raised.
223
def __init__(self, path):
227
"""a no-op - do nothing."""
230
"""Raise ReadError."""
231
raise errors.ReadError(self._path)
236
def read(self, count=-1):
218
243
class Transport(object):
219
244
"""This class encapsulates methods for retrieving or putting a file
220
245
from/to a storage location.
320
def external_url(self):
321
"""Return a URL for self that can be given to an external process.
323
There is no guarantee that the URL can be accessed from a different
324
machine - e.g. file:/// urls are only usable on the local machine,
325
sftp:/// urls when the server is only bound to localhost are only
326
usable from localhost etc.
328
NOTE: This method may remove security wrappers (e.g. on chroot
329
transports) and thus should *only* be used when the result will not
330
be used to obtain a new transport within bzrlib. Ideally chroot
331
transports would know enough to cause the external url to be the exact
332
one used that caused the chrooting in the first place, but that is not
335
:return: A URL that can be given to another process.
336
:raises InProcessTransport: If the transport is one that cannot be
337
accessed out of the current process (e.g. a MemoryTransport)
338
then InProcessTransport is raised.
340
raise NotImplementedError(self.external_url)
295
342
def should_cache(self):
296
343
"""Return True if the data pulled across should be cached locally.
473
520
def get(self, relpath):
474
521
"""Get the file at the given relative path.
523
This may fail in a number of ways:
524
- HTTP servers may return content for a directory. (unexpected
526
- FTP servers may indicate NoSuchFile for a directory.
527
- SFTP servers may give a file handle for a directory that will
530
For correct use of the interface, be sure to catch errors.PathError
531
when calling it and catch errors.ReadError when reading from the
476
534
:param relpath: The relative path to the file
477
535
:rtype: File-like object.
575
633
:param fudge_factor: All transports have some level of 'it is
576
634
better to read some more data and throw it away rather
577
635
than seek', so collapse if we are 'close enough'
578
:return: yield _CoalescedOffset objects, which have members for wher
636
:return: yield _CoalescedOffset objects, which have members for where
579
637
to start, how much to read, and how to split those
1177
1235
raise NotImplementedError
1180
class TransportTestProviderAdapter(object):
1181
"""A tool to generate a suite testing all transports for a single test.
1183
This is done by copying the test once for each transport and injecting
1184
the transport_class and transport_server classes into each copy. Each copy
1185
is also given a new id() to make it easy to identify.
1188
def adapt(self, test):
1189
result = unittest.TestSuite()
1190
for klass, server_factory in self._test_permutations():
1191
new_test = deepcopy(test)
1192
new_test.transport_class = klass
1193
new_test.transport_server = server_factory
1194
def make_new_test_id():
1195
new_id = "%s(%s)" % (new_test.id(), server_factory.__name__)
1196
return lambda: new_id
1197
new_test.id = make_new_test_id()
1198
result.addTest(new_test)
1201
def get_transport_test_permutations(self, module):
1202
"""Get the permutations module wants to have tested."""
1203
if getattr(module, 'get_test_permutations', None) is None:
1204
warning("transport module %s doesn't provide get_test_permutations()"
1207
return module.get_test_permutations()
1209
def _test_permutations(self):
1210
"""Return a list of the klass, server_factory pairs to test."""
1212
for module in _get_transport_modules():
1214
result.extend(self.get_transport_test_permutations(reduce(getattr,
1215
(module).split('.')[1:],
1216
__import__(module))))
1217
except errors.DependencyNotPresent, e:
1218
# Continue even if a dependency prevents us
1219
# from running this test
1224
1238
class TransportLogger(object):
1225
1239
"""Adapt a transport to get clear logging data on api calls.
1302
1316
# help="This modifier converts any transport to be readonly."
1304
1318
register_lazy_transport('readonly+', 'bzrlib.transport.readonly', 'ReadonlyTransportDecorator')
1305
1320
register_transport_proto('fakenfs+')
1306
1321
register_lazy_transport('fakenfs+', 'bzrlib.transport.fakenfs', 'FakeNFSTransportDecorator')
1323
register_transport_proto('brokenrename+')
1324
register_lazy_transport('brokenrename+', 'bzrlib.transport.brokenrename',
1325
'BrokenRenameTransportDecorator')
1307
1327
register_transport_proto('vfat+')
1308
1328
register_lazy_transport('vfat+',
1309
1329
'bzrlib.transport.fakevfat',