Introduce test.test_support.TransientResource. It's a context manager to

surround calls to resources that may or may not be available.  Specifying the
expected exception and attributes to be raised if the resource is not available
prevents overly broad catching of exceptions.

This is meant to help suppress spurious failures by raising
test.test_support.ResourceDenied if the exception matches.  It would probably
be good to go through the various network tests and surround the calls to catch
connection timeouts (as done with test_socket_ssl in this commit).
This commit is contained in:
Brett Cannon 2007-03-08 23:58:11 +00:00
parent 9b2a109540
commit a30fcb4dae
4 changed files with 39 additions and 1 deletions

View File

@ -285,6 +285,14 @@ originated from.
The \module{test.test_support} module defines the following classes:
\begin{classdesc}{TransientResource}{exc\optional{, **kwargs}}
Create a context manager that raises \class{ResourceDenied} if the specified
exception type is raised. Any keyword arguments are treated as name/value
pairs to be compared against any exception raised with the \code{with}
statement. Only if all pairs match is \class{ResourceDenied} raised.
\versionadded{2.6}
\end{classdesc}
\begin{classdesc}{EnvironmentVarGuard}{}
Class used to temporarily set or unset environment variables. Instances can be
used as a context manager.

View File

@ -27,7 +27,8 @@ def test_basic():
print "didn't raise TypeError"
socket.RAND_add("this is a random string", 75.0)
f = urllib.urlopen('https://sf.net')
with test_support.TransientResource(IOError, errno=errno.ETIMEDOUT):
f = urllib.urlopen('https://sf.net')
buf = f.read()
f.close()

View File

@ -312,6 +312,31 @@ class EnvironmentVarGuard(object):
for unset in self._unset:
del self._environ[unset]
class TransientResource(object):
"""Raise ResourceDenied if an exception is raised while the context manager
is in effect that matches the specified exception and attributes."""
def __init__(self, exc, **kwargs):
self.exc = exc
self.attrs = kwargs
def __enter__(self):
return self
def __exit__(self, type_=None, value=None, traceback=None):
"""If type_ is a subclass of self.exc and value has attributes matching
self.attrs, raise ResourceDenied. Otherwise let the exception
propagate (if any)."""
if type_ is not None and issubclass(self.exc, type_):
for attr, attr_value in self.attrs.iteritems():
if not hasattr(value, attr):
break
if getattr(value, attr) != attr_value:
break
else:
raise ResourceDenied("an optional resource is not available")
#=======================================================================
# Decorator for running a function in a different locale, correctly resetting

View File

@ -516,6 +516,10 @@ Extension Modules
Tests
-----
- Added test.test_support.TransientResource which is a context manager to
surround calls to resources that are not guaranteed to work even if
test.test_support.requires says that the resource should exist.
- Added a test for slicing of an exception.
- Added test.test_support.EnvironmentVarGuard. It's a class that provides a