183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#!/usr/bin/env python
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test import test_support
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport socket
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport urllib
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport time
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehmimetools = test_support.import_module("mimetools", deprecated=True)
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _open_with_retry(func, host, *args, **kwargs):
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Connecting to remote hosts is flaky.  Make it more robust
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # by retrying the connection several times.
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for i in range(3):
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return func(host, *args, **kwargs)
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except IOError, last_exc:
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            continue
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except:
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    raise last_exc
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass URLTimeoutTest(unittest.TestCase):
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    TIMEOUT = 10.0
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        socket.setdefaulttimeout(self.TIMEOUT)
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        socket.setdefaulttimeout(None)
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testURLread(self):
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = _open_with_retry(urllib.urlopen, "http://www.python.org/")
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        x = f.read()
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass urlopenNetworkTests(unittest.TestCase):
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """Tests urllib.urlopen using the network.
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    These tests are not exhaustive.  Assuming that testing using files does a
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    good job overall of some of the basic interface features.  There are no
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    tests exercising the optional 'data' and 'proxies' arguments.  No tests
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for transparent redirection have been written.
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    setUp is not used for always constructing a connection to
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    http://www.python.org/ since there a few tests that don't use that address
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    and making a connection is expensive enough to warrant minimizing unneeded
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    connections.
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def urlopen(self, *args):
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return _open_with_retry(urllib.urlopen, *args)
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_basic(self):
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Simple test expected to pass.
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open_url = self.urlopen("http://www.python.org/")
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for attr in ("read", "readline", "readlines", "fileno", "close",
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                     "info", "geturl"):
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertTrue(hasattr(open_url, attr), "object returned from "
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                            "urlopen lacks the %s attribute" % attr)
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertTrue(open_url.read(), "calling 'read' failed")
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            open_url.close()
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_readlines(self):
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test both readline and readlines.
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open_url = self.urlopen("http://www.python.org/")
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertIsInstance(open_url.readline(), basestring,
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  "readline did not return a string")
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertIsInstance(open_url.readlines(), list,
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  "readlines did not return a list")
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            open_url.close()
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_info(self):
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test 'info'.
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open_url = self.urlopen("http://www.python.org/")
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            info_obj = open_url.info()
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            open_url.close()
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertIsInstance(info_obj, mimetools.Message,
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  "object returned by 'info' is not an "
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  "instance of mimetools.Message")
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(info_obj.getsubtype(), "html")
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_geturl(self):
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Make sure same URL as opened is returned by geturl.
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        URL = "http://www.python.org/"
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open_url = self.urlopen(URL)
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            gotten_url = open_url.geturl()
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            open_url.close()
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(gotten_url, URL)
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_getcode(self):
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test getcode() with the fancy opener to get 404 error codes
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        URL = "http://www.python.org/XXXinvalidXXX"
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open_url = urllib.FancyURLopener().open(URL)
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            code = open_url.getcode()
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            open_url.close()
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(code, 404)
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_fileno(self):
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if (sys.platform in ('win32',) or
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                not hasattr(os, 'fdopen')):
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # On Windows, socket handles are not file descriptors; this
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # test can't pass on Windows.
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Make sure fd returned by fileno is valid.
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open_url = self.urlopen("http://www.python.org/")
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        fd = open_url.fileno()
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        FILE = os.fdopen(fd)
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertTrue(FILE.read(), "reading from file created using fd "
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                      "returned by fileno failed")
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            FILE.close()
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_bad_address(self):
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Make sure proper exception is raised when connecting to a bogus
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # address.
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        bogus_domain = "sadflkjsasf.i.nvali.d"
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            socket.gethostbyname(bogus_domain)
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except socket.gaierror:
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # This happens with some overzealous DNS providers such as OpenDNS
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.skipTest("%r should not resolve for test to work" % bogus_domain)
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(IOError,
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          # SF patch 809915:  In Sep 2003, VeriSign started
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          # highjacking invalid .com and .net addresses to
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          # boost traffic to their own site.  This test
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          # started failing then.  One hopes the .invalid
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          # domain will be spared to serve its defined
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          # purpose.
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          # urllib.urlopen, "http://www.sadflkjsasadf.com/")
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          urllib.urlopen, "http://sadflkjsasf.i.nvali.d/")
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass urlretrieveNetworkTests(unittest.TestCase):
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """Tests urllib.urlretrieve using the network."""
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def urlretrieve(self, *args):
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return _open_with_retry(urllib.urlretrieve, *args)
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_basic(self):
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test basic functionality.
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        file_location,info = self.urlretrieve("http://www.python.org/")
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(os.path.exists(file_location), "file location returned by"
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        " urlretrieve is not a valid path")
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        FILE = file(file_location)
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertTrue(FILE.read(), "reading from the file location returned"
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         " by urlretrieve failed")
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            FILE.close()
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.unlink(file_location)
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_specified_path(self):
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Make sure that specifying the location of the file to write to works.
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        file_location,info = self.urlretrieve("http://www.python.org/",
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                              test_support.TESTFN)
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(file_location, test_support.TESTFN)
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(os.path.exists(file_location))
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        FILE = file(file_location)
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertTrue(FILE.read(), "reading from temporary file failed")
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            FILE.close()
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.unlink(file_location)
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_header(self):
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Make sure header returned as 2nd value from urlretrieve is good.
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        file_location, header = self.urlretrieve("http://www.python.org/")
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.unlink(file_location)
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertIsInstance(header, mimetools.Message,
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              "header is not an instance of mimetools.Message")
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_data_header(self):
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        logo = "http://www.python.org/community/logos/python-logo-master-v3-TM.png"
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        file_location, fileheaders = self.urlretrieve(logo)
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.unlink(file_location)
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        datevalue = fileheaders.getheader('Date')
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        dateformat = '%a, %d %b %Y %H:%M:%S GMT'
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            time.strptime(datevalue, dateformat)
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except ValueError:
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail('Date value not in %r format', dateformat)
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main():
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_support.requires('network')
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    with test_support.check_py3k_warnings(
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ("urllib.urlopen.. has been removed", DeprecationWarning)):
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        test_support.run_unittest(URLTimeoutTest,
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  urlopenNetworkTests,
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  urlretrieveNetworkTests)
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == "__main__":
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_main()
214