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