Home | History | Annotate | Download | only in test
      1 import unittest
      2 from test import test_support
      3 
      4 import socket
      5 import urllib
      6 import sys
      7 import os
      8 import time
      9 
     10 try:
     11     import ssl
     12 except ImportError:
     13     ssl = None
     14 
     15 here = os.path.dirname(__file__)
     16 # Self-signed cert file for self-signed.pythontest.net
     17 CERT_selfsigned_pythontestdotnet = os.path.join(here, 'selfsigned_pythontestdotnet.pem')
     18 
     19 mimetools = test_support.import_module("mimetools", deprecated=True)
     20 
     21 
     22 def _open_with_retry(func, host, *args, **kwargs):
     23     # Connecting to remote hosts is flaky.  Make it more robust
     24     # by retrying the connection several times.
     25     for i in range(3):
     26         try:
     27             return func(host, *args, **kwargs)
     28         except IOError, last_exc:
     29             continue
     30         except:
     31             raise
     32     raise last_exc
     33 
     34 
     35 class URLTimeoutTest(unittest.TestCase):
     36 
     37     TIMEOUT = 10.0
     38 
     39     def setUp(self):
     40         socket.setdefaulttimeout(self.TIMEOUT)
     41 
     42     def tearDown(self):
     43         socket.setdefaulttimeout(None)
     44 
     45     def testURLread(self):
     46         f = _open_with_retry(urllib.urlopen, "http://www.example.com/")
     47         x = f.read()
     48 
     49 class urlopenNetworkTests(unittest.TestCase):
     50     """Tests urllib.urlopen using the network.
     51 
     52     These tests are not exhaustive.  Assuming that testing using files does a
     53     good job overall of some of the basic interface features.  There are no
     54     tests exercising the optional 'data' and 'proxies' arguments.  No tests
     55     for transparent redirection have been written.
     56 
     57     setUp is not used for always constructing a connection to
     58     http://www.example.com/ since there a few tests that don't use that address
     59     and making a connection is expensive enough to warrant minimizing unneeded
     60     connections.
     61 
     62     """
     63 
     64     def urlopen(self, *args):
     65         return _open_with_retry(urllib.urlopen, *args)
     66 
     67     def test_basic(self):
     68         # Simple test expected to pass.
     69         open_url = self.urlopen("http://www.example.com/")
     70         for attr in ("read", "readline", "readlines", "fileno", "close",
     71                      "info", "geturl"):
     72             self.assertTrue(hasattr(open_url, attr), "object returned from "
     73                             "urlopen lacks the %s attribute" % attr)
     74         try:
     75             self.assertTrue(open_url.read(), "calling 'read' failed")
     76         finally:
     77             open_url.close()
     78 
     79     def test_readlines(self):
     80         # Test both readline and readlines.
     81         open_url = self.urlopen("http://www.example.com/")
     82         try:
     83             self.assertIsInstance(open_url.readline(), basestring,
     84                                   "readline did not return a string")
     85             self.assertIsInstance(open_url.readlines(), list,
     86                                   "readlines did not return a list")
     87         finally:
     88             open_url.close()
     89 
     90     def test_info(self):
     91         # Test 'info'.
     92         open_url = self.urlopen("http://www.example.com/")
     93         try:
     94             info_obj = open_url.info()
     95         finally:
     96             open_url.close()
     97             self.assertIsInstance(info_obj, mimetools.Message,
     98                                   "object returned by 'info' is not an "
     99                                   "instance of mimetools.Message")
    100             self.assertEqual(info_obj.getsubtype(), "html")
    101 
    102     def test_geturl(self):
    103         # Make sure same URL as opened is returned by geturl.
    104         URL = "http://www.example.com/"
    105         open_url = self.urlopen(URL)
    106         try:
    107             gotten_url = open_url.geturl()
    108         finally:
    109             open_url.close()
    110         self.assertEqual(gotten_url, URL)
    111 
    112     def test_getcode(self):
    113         # test getcode() with the fancy opener to get 404 error codes
    114         URL = "http://www.pythontest.net/XXXinvalidXXX"
    115         open_url = urllib.FancyURLopener().open(URL)
    116         try:
    117             code = open_url.getcode()
    118         finally:
    119             open_url.close()
    120         self.assertEqual(code, 404)
    121 
    122     @unittest.skipIf(sys.platform in ('win32',), 'not appropriate for Windows')
    123     @unittest.skipUnless(hasattr(os, 'fdopen'), 'os.fdopen not available')
    124     def test_fileno(self):
    125         # Make sure fd returned by fileno is valid.
    126         open_url = self.urlopen("http://www.example.com/")
    127         fd = open_url.fileno()
    128         FILE = os.fdopen(fd)
    129         try:
    130             self.assertTrue(FILE.read(), "reading from file created using fd "
    131                                       "returned by fileno failed")
    132         finally:
    133             FILE.close()
    134 
    135     def test_bad_address(self):
    136         # Make sure proper exception is raised when connecting to a bogus
    137         # address.
    138         bogus_domain = "sadflkjsasf.i.nvali.d"
    139         try:
    140             socket.gethostbyname(bogus_domain)
    141         except socket.gaierror:
    142             pass
    143         else:
    144             # This happens with some overzealous DNS providers such as OpenDNS
    145             self.skipTest("%r should not resolve for test to work" % bogus_domain)
    146         self.assertRaises(IOError,
    147                           # SF patch 809915:  In Sep 2003, VeriSign started
    148                           # highjacking invalid .com and .net addresses to
    149                           # boost traffic to their own site.  This test
    150                           # started failing then.  One hopes the .invalid
    151                           # domain will be spared to serve its defined
    152                           # purpose.
    153                           # urllib.urlopen, "http://www.sadflkjsasadf.com/")
    154                           urllib.urlopen, "http://sadflkjsasf.i.nvali.d/")
    155 
    156 class urlretrieveNetworkTests(unittest.TestCase):
    157     """Tests urllib.urlretrieve using the network."""
    158 
    159     def urlretrieve(self, *args):
    160         return _open_with_retry(urllib.urlretrieve, *args)
    161 
    162     def test_basic(self):
    163         # Test basic functionality.
    164         file_location,info = self.urlretrieve("http://www.example.com/")
    165         self.assertTrue(os.path.exists(file_location), "file location returned by"
    166                         " urlretrieve is not a valid path")
    167         FILE = file(file_location)
    168         try:
    169             self.assertTrue(FILE.read(), "reading from the file location returned"
    170                          " by urlretrieve failed")
    171         finally:
    172             FILE.close()
    173             os.unlink(file_location)
    174 
    175     def test_specified_path(self):
    176         # Make sure that specifying the location of the file to write to works.
    177         file_location,info = self.urlretrieve("http://www.example.com/",
    178                                               test_support.TESTFN)
    179         self.assertEqual(file_location, test_support.TESTFN)
    180         self.assertTrue(os.path.exists(file_location))
    181         FILE = file(file_location)
    182         try:
    183             self.assertTrue(FILE.read(), "reading from temporary file failed")
    184         finally:
    185             FILE.close()
    186             os.unlink(file_location)
    187 
    188     def test_header(self):
    189         # Make sure header returned as 2nd value from urlretrieve is good.
    190         file_location, header = self.urlretrieve("http://www.example.com/")
    191         os.unlink(file_location)
    192         self.assertIsInstance(header, mimetools.Message,
    193                               "header is not an instance of mimetools.Message")
    194 
    195     def test_data_header(self):
    196         logo = "http://www.example.com/"
    197         file_location, fileheaders = self.urlretrieve(logo)
    198         os.unlink(file_location)
    199         datevalue = fileheaders.getheader('Date')
    200         dateformat = '%a, %d %b %Y %H:%M:%S GMT'
    201         try:
    202             time.strptime(datevalue, dateformat)
    203         except ValueError:
    204             self.fail('Date value not in %r format', dateformat)
    205 
    206 
    207 @unittest.skipIf(ssl is None, "requires ssl")
    208 class urlopen_HttpsTests(unittest.TestCase):
    209 
    210     def test_context_argument(self):
    211         context = ssl.create_default_context(cafile=CERT_selfsigned_pythontestdotnet)
    212         response = urllib.urlopen("https://self-signed.pythontest.net", context=context)
    213         self.assertIn("Python", response.read())
    214 
    215 
    216 def test_main():
    217     test_support.requires('network')
    218     with test_support.check_py3k_warnings(
    219             ("urllib.urlopen.. has been removed", DeprecationWarning)):
    220         test_support.run_unittest(URLTimeoutTest,
    221                                   urlopenNetworkTests,
    222                                   urlretrieveNetworkTests,
    223                                   urlopen_HttpsTests)
    224 
    225 if __name__ == "__main__":
    226     test_main()
    227