summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-09-07 20:42:19 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-09-07 20:42:19 (GMT)
commita88c83cbabb925d55714ffcfb67bd4e82dcf3547 (patch)
tree65f5bf3f1ceb977761528500695f3778008c7e80
parentf015b3f5f6ccaa848bdb96306d2f4120bdbc46c7 (diff)
downloadcpython-a88c83cbabb925d55714ffcfb67bd4e82dcf3547.zip
cpython-a88c83cbabb925d55714ffcfb67bd4e82dcf3547.tar.gz
cpython-a88c83cbabb925d55714ffcfb67bd4e82dcf3547.tar.bz2
Issue #8574: better implementation of test.support.transient_internet().
Original patch by Victor.
-rw-r--r--Lib/test/support.py38
-rw-r--r--Lib/test/test_ssl.py8
2 files changed, 35 insertions, 11 deletions
diff --git a/Lib/test/support.py b/Lib/test/support.py
index 814d061..64c9a86 100644
--- a/Lib/test/support.py
+++ b/Lib/test/support.py
@@ -35,7 +35,7 @@ __all__ = [
"check_warnings", "CleanImport", "EnvironmentVarGuard",
"TransientResource", "captured_output", "captured_stdout",
"time_out", "socket_peer_reset", "ioerror_peer_reset",
- "run_with_locale", 'temp_umask',
+ "run_with_locale", 'temp_umask', "transient_internet",
"set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner",
"run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
"reap_children", "cpython_only", "check_impl_detail", "get_attribute",
@@ -775,23 +775,47 @@ class TransientResource(object):
else:
raise ResourceDenied("an optional resource is not available")
-
# Context managers that raise ResourceDenied when various issues
# with the Internet connection manifest themselves as exceptions.
+# XXX deprecate these and use transient_internet() instead
time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
@contextlib.contextmanager
-def transient_internet():
+def transient_internet(resource_name, *, timeout=30.0, errnos=()):
"""Return a context manager that raises ResourceDenied when various issues
with the Internet connection manifest themselves as exceptions."""
- time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
- socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
- ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
- with time_out, socket_peer_reset, ioerror_peer_reset:
+ denied = ResourceDenied("Resource '%s' is not available" % resource_name)
+ captured_errnos = errnos or (errno.ETIMEDOUT, errno.ECONNRESET)
+
+ def filter_error(err):
+ if (isinstance(err, socket.timeout) or
+ getattr(err, 'errno', None) in captured_errnos):
+ if not verbose:
+ sys.stderr.write(denied.args[0] + "\n")
+ raise denied from err
+
+ old_timeout = socket.getdefaulttimeout()
+ try:
+ if timeout is not None:
+ socket.setdefaulttimeout(timeout)
yield
+ except IOError as err:
+ # socket.error inherits IOError
+ filter_error(err)
+ # urllib.request wraps the original socket.error with IOerror:
+ #
+ # except socket.error as msg:
+ # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
+ if len(err.args) >= 2 and isinstance(err.args[1], socket.error):
+ filter_error(err.args[1])
+ raise
+ # XXX should we catch generic exceptions and look for their
+ # __cause__ or __context__?
+ finally:
+ socket.setdefaulttimeout(old_timeout)
@contextlib.contextmanager
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 8e38ae0..9ee4db1 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -477,10 +477,10 @@ class NetworkedTests(unittest.TestCase):
# NOTE: https://sha256.tbs-internet.com is another possible test host
remote = ("sha2.hboeck.de", 443)
sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=sha256_cert,)
- with support.transient_internet():
+ with support.transient_internet("sha2.hboeck.de"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=sha256_cert,)
try:
s.connect(remote)
if support.verbose: