41
41
K = 4
42
42
_RAISE_NETWORK_ERROR_DEFAULT = False
43
43
44
+
44
45
def rands (n ):
45
46
choices = string .ascii_letters + string .digits
46
47
return '' .join (random .choice (choices ) for _ in xrange (n ))
@@ -675,22 +676,26 @@ def optional_args(decorator):
675
676
def function(): pass
676
677
677
678
Calls decorator with decorator(f, *args, **kwargs)"""
679
+
678
680
@wraps (decorator )
679
681
def wrapper (* args , ** kwargs ):
680
682
def dec (f ):
681
683
return decorator (f , * args , ** kwargs )
684
+
682
685
is_decorating = not kwargs and len (args ) == 1 and callable (args [0 ])
683
686
if is_decorating :
684
687
f = args [0 ]
685
688
args = []
686
689
return dec (f )
687
690
else :
688
691
return dec
692
+
689
693
return wrapper
690
694
695
+
691
696
@optional_args
692
697
def network (t , raise_on_error = _RAISE_NETWORK_ERROR_DEFAULT ,
693
- error_classes = (IOError ,)):
698
+ error_classes = (IOError ,)):
694
699
"""
695
700
Label a test as requiring network connection and skip test if it encounters a ``URLError``.
696
701
@@ -751,6 +756,7 @@ def network(t, raise_on_error=_RAISE_NETWORK_ERROR_DEFAULT,
751
756
``pandas/util/testing.py`` sets the default behavior (currently False).
752
757
"""
753
758
t .network = True
759
+
754
760
@wraps (t )
755
761
def network_wrapper (* args , ** kwargs ):
756
762
if raise_on_error :
@@ -760,8 +766,98 @@ def network_wrapper(*args, **kwargs):
760
766
return t (* args , ** kwargs )
761
767
except error_classes as e :
762
768
raise nose .SkipTest ("Skipping test %s" % e )
769
+
763
770
return network_wrapper
764
771
772
+
773
+ def can_connect (url ):
774
+ """tries to connect to the given url. True if succeeds, False if IOError raised"""
775
+ try :
776
+ urllib2 .urlopen (url )
777
+ except IOError :
778
+ return False
779
+ else :
780
+ return True
781
+
782
+
783
+ @optional_args
784
+ def with_connectivity_check (t , url = "http://www.google.com" ,
785
+ raise_on_error = _RAISE_NETWORK_ERROR_DEFAULT , check_before_test = False ,
786
+ error_classes = IOError ):
787
+ """
788
+ Label a test as requiring network connection and, if an error is
789
+ encountered, only raise if it does not find a network connection.
790
+
791
+ In comparison to ``network``, this assumes an added contract to your test:
792
+ you must assert that, under normal conditions, your test will ONLY fail if
793
+ it does not have network connectivity.
794
+
795
+ You can call this in 3 ways: as a standard decorator, with keyword
796
+ arguments, or with a positional argument that is the url to check.
797
+
798
+ Parameters
799
+ ----------
800
+ t : callable
801
+ The test requiring network connectivity.
802
+ url : path
803
+ The url to test via ``urllib2.urlopen`` to check for connectivity.
804
+ Defaults to 'http://www.google.com'.
805
+ raise_on_error : bool
806
+ If True, never catches errors.
807
+ check_before_test : bool
808
+ If True, checks connectivity before running the test case.
809
+ error_classes : tuple or Exception
810
+ error classes to ignore. If not in ``error_classes``, raises the error.
811
+ defaults to IOError. Be careful about changing the error classes here.
812
+
813
+ NOTE: ``raise_on_error`` supercedes ``check_before_test``
814
+ Returns
815
+ -------
816
+ t : callable
817
+ The decorated test ``t``, with checks for connectivity errors.
818
+
819
+ Example
820
+ -------
821
+
822
+ In this example, you see how it will raise the error if it can connect to
823
+ the url::
824
+ >>> @with_connectivity_check("http://www.yahoo.com")
825
+ ... def test_something_with_yahoo():
826
+ ... raise IOError("Failure Message")
827
+ >>> test_something_with_yahoo()
828
+ Traceback (most recent call last):
829
+ ...
830
+ IOError: Failure Message
831
+
832
+ I you set check_before_test, it will check the url first and not run the test on failure::
833
+ >>> @with_connectivity_check("failing://url.blaher", check_before_test=True)
834
+ ... def test_something():
835
+ ... print("I ran!")
836
+ ... raise ValueError("Failure")
837
+ >>> test_something()
838
+ Traceback (most recent call last):
839
+ ...
840
+ SkipTest
841
+ """
842
+ t .network = True
843
+
844
+ @wraps (t )
845
+ def wrapper (* args , ** kwargs ):
846
+ if check_before_test and not raise_on_error :
847
+ if not can_connect (url ):
848
+ raise nose .SkipTest
849
+ try :
850
+ return t (* args , ** kwargs )
851
+ except error_classes as e :
852
+ if raise_on_error or can_connect (url ):
853
+ raise
854
+ else :
855
+ raise nose .SkipTest ("Skipping test due to lack of connectivity"
856
+ " and error %s" % e )
857
+
858
+ return wrapper
859
+
860
+
765
861
class SimpleMock (object ):
766
862
"""
767
863
Poor man's mocking object
@@ -806,11 +902,13 @@ def stdin_encoding(encoding=None):
806
902
807
903
"""
808
904
import sys
905
+
809
906
_stdin = sys .stdin
810
907
sys .stdin = SimpleMock (sys .stdin , "encoding" , encoding )
811
908
yield
812
909
sys .stdin = _stdin
813
910
911
+
814
912
def assertRaisesRegexp (exception , regexp , callable , * args , ** kwargs ):
815
913
""" Port of assertRaisesRegexp from unittest in Python 2.7 - used in with statement.
816
914
@@ -842,6 +940,7 @@ def assertRaisesRegexp(exception, regexp, callable, *args, **kwargs):
842
940
"""
843
941
844
942
import re
943
+
845
944
try :
846
945
callable (* args , ** kwargs )
847
946
except Exception as e :
@@ -855,7 +954,7 @@ def assertRaisesRegexp(exception, regexp, callable, *args, **kwargs):
855
954
expected_regexp = re .compile (regexp )
856
955
if not expected_regexp .search (str (e )):
857
956
raise AssertionError ('"%s" does not match "%s"' %
858
- (expected_regexp .pattern , str (e )))
957
+ (expected_regexp .pattern , str (e )))
859
958
else :
860
959
# Apparently some exceptions don't have a __name__ attribute? Just aping unittest library here
861
960
name = getattr (exception , "__name__" , str (exception ))
0 commit comments