1"""Regresssion tests for urllib""" 2 3import urllib 4import httplib 5import unittest 6from test import test_support 7import os 8import sys 9import mimetools 10import tempfile 11import StringIO 12 13def hexescape(char): 14 """Escape char as RFC 2396 specifies""" 15 hex_repr = hex(ord(char))[2:].upper() 16 if len(hex_repr) == 1: 17 hex_repr = "0%s" % hex_repr 18 return "%" + hex_repr 19 20class urlopen_FileTests(unittest.TestCase): 21 """Test urlopen() opening a temporary file. 22 23 Try to test as much functionality as possible so as to cut down on reliance 24 on connecting to the Net for testing. 25 26 """ 27 28 def setUp(self): 29 """Setup of a temp file to use for testing""" 30 self.text = "test_urllib: %s\n" % self.__class__.__name__ 31 FILE = file(test_support.TESTFN, 'wb') 32 try: 33 FILE.write(self.text) 34 finally: 35 FILE.close() 36 self.pathname = test_support.TESTFN 37 self.returned_obj = urllib.urlopen("file:%s" % self.pathname) 38 39 def tearDown(self): 40 """Shut down the open object""" 41 self.returned_obj.close() 42 os.remove(test_support.TESTFN) 43 44 def test_interface(self): 45 # Make sure object returned by urlopen() has the specified methods 46 for attr in ("read", "readline", "readlines", "fileno", 47 "close", "info", "geturl", "getcode", "__iter__"): 48 self.assertTrue(hasattr(self.returned_obj, attr), 49 "object returned by urlopen() lacks %s attribute" % 50 attr) 51 52 def test_read(self): 53 self.assertEqual(self.text, self.returned_obj.read()) 54 55 def test_readline(self): 56 self.assertEqual(self.text, self.returned_obj.readline()) 57 self.assertEqual('', self.returned_obj.readline(), 58 "calling readline() after exhausting the file did not" 59 " return an empty string") 60 61 def test_readlines(self): 62 lines_list = self.returned_obj.readlines() 63 self.assertEqual(len(lines_list), 1, 64 "readlines() returned the wrong number of lines") 65 self.assertEqual(lines_list[0], self.text, 66 "readlines() returned improper text") 67 68 def test_fileno(self): 69 file_num = self.returned_obj.fileno() 70 self.assertIsInstance(file_num, int, "fileno() did not return an int") 71 self.assertEqual(os.read(file_num, len(self.text)), self.text, 72 "Reading on the file descriptor returned by fileno() " 73 "did not return the expected text") 74 75 def test_close(self): 76 # Test close() by calling it hear and then having it be called again 77 # by the tearDown() method for the test 78 self.returned_obj.close() 79 80 def test_info(self): 81 self.assertIsInstance(self.returned_obj.info(), mimetools.Message) 82 83 def test_geturl(self): 84 self.assertEqual(self.returned_obj.geturl(), self.pathname) 85 86 def test_getcode(self): 87 self.assertEqual(self.returned_obj.getcode(), None) 88 89 def test_iter(self): 90 # Test iterator 91 # Don't need to count number of iterations since test would fail the 92 # instant it returned anything beyond the first line from the 93 # comparison 94 for line in self.returned_obj.__iter__(): 95 self.assertEqual(line, self.text) 96 97class ProxyTests(unittest.TestCase): 98 99 def setUp(self): 100 # Records changes to env vars 101 self.env = test_support.EnvironmentVarGuard() 102 # Delete all proxy related env vars 103 for k in os.environ.keys(): 104 if 'proxy' in k.lower(): 105 self.env.unset(k) 106 107 def tearDown(self): 108 # Restore all proxy related env vars 109 self.env.__exit__() 110 del self.env 111 112 def test_getproxies_environment_keep_no_proxies(self): 113 self.env.set('NO_PROXY', 'localhost') 114 proxies = urllib.getproxies_environment() 115 # getproxies_environment use lowered case truncated (no '_proxy') keys 116 self.assertEqual('localhost', proxies['no']) 117 118 119class urlopen_HttpTests(unittest.TestCase): 120 """Test urlopen() opening a fake http connection.""" 121 122 def fakehttp(self, fakedata): 123 class FakeSocket(StringIO.StringIO): 124 def sendall(self, str): pass 125 def makefile(self, mode, name): return self 126 def read(self, amt=None): 127 if self.closed: return '' 128 return StringIO.StringIO.read(self, amt) 129 def readline(self, length=None): 130 if self.closed: return '' 131 return StringIO.StringIO.readline(self, length) 132 class FakeHTTPConnection(httplib.HTTPConnection): 133 def connect(self): 134 self.sock = FakeSocket(fakedata) 135 assert httplib.HTTP._connection_class == httplib.HTTPConnection 136 httplib.HTTP._connection_class = FakeHTTPConnection 137 138 def unfakehttp(self): 139 httplib.HTTP._connection_class = httplib.HTTPConnection 140 141 def test_read(self): 142 self.fakehttp('Hello!') 143 try: 144 fp = urllib.urlopen("http://python.org/") 145 self.assertEqual(fp.readline(), 'Hello!') 146 self.assertEqual(fp.readline(), '') 147 self.assertEqual(fp.geturl(), 'http://python.org/') 148 self.assertEqual(fp.getcode(), 200) 149 finally: 150 self.unfakehttp() 151 152 def test_url_fragment(self): 153 # Issue #11703: geturl() omits fragments in the original URL. 154 url = 'http://docs.python.org/library/urllib.html#OK' 155 self.fakehttp('Hello!') 156 try: 157 fp = urllib.urlopen(url) 158 self.assertEqual(fp.geturl(), url) 159 finally: 160 self.unfakehttp() 161 162 def test_read_bogus(self): 163 # urlopen() should raise IOError for many error codes. 164 self.fakehttp('''HTTP/1.1 401 Authentication Required 165Date: Wed, 02 Jan 2008 03:03:54 GMT 166Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e 167Connection: close 168Content-Type: text/html; charset=iso-8859-1 169''') 170 try: 171 self.assertRaises(IOError, urllib.urlopen, "http://python.org/") 172 finally: 173 self.unfakehttp() 174 175 def test_invalid_redirect(self): 176 # urlopen() should raise IOError for many error codes. 177 self.fakehttp("""HTTP/1.1 302 Found 178Date: Wed, 02 Jan 2008 03:03:54 GMT 179Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e 180Location: file:README 181Connection: close 182Content-Type: text/html; charset=iso-8859-1 183""") 184 try: 185 self.assertRaises(IOError, urllib.urlopen, "http://python.org/") 186 finally: 187 self.unfakehttp() 188 189 def test_empty_socket(self): 190 # urlopen() raises IOError if the underlying socket does not send any 191 # data. (#1680230) 192 self.fakehttp('') 193 try: 194 self.assertRaises(IOError, urllib.urlopen, 'http://something') 195 finally: 196 self.unfakehttp() 197 198class urlretrieve_FileTests(unittest.TestCase): 199 """Test urllib.urlretrieve() on local files""" 200 201 def setUp(self): 202 # Create a list of temporary files. Each item in the list is a file 203 # name (absolute path or relative to the current working directory). 204 # All files in this list will be deleted in the tearDown method. Note, 205 # this only helps to makes sure temporary files get deleted, but it 206 # does nothing about trying to close files that may still be open. It 207 # is the responsibility of the developer to properly close files even 208 # when exceptional conditions occur. 209 self.tempFiles = [] 210 211 # Create a temporary file. 212 self.registerFileForCleanUp(test_support.TESTFN) 213 self.text = 'testing urllib.urlretrieve' 214 try: 215 FILE = file(test_support.TESTFN, 'wb') 216 FILE.write(self.text) 217 FILE.close() 218 finally: 219 try: FILE.close() 220 except: pass 221 222 def tearDown(self): 223 # Delete the temporary files. 224 for each in self.tempFiles: 225 try: os.remove(each) 226 except: pass 227 228 def constructLocalFileUrl(self, filePath): 229 return "file://%s" % urllib.pathname2url(os.path.abspath(filePath)) 230 231 def createNewTempFile(self, data=""): 232 """Creates a new temporary file containing the specified data, 233 registers the file for deletion during the test fixture tear down, and 234 returns the absolute path of the file.""" 235 236 newFd, newFilePath = tempfile.mkstemp() 237 try: 238 self.registerFileForCleanUp(newFilePath) 239 newFile = os.fdopen(newFd, "wb") 240 newFile.write(data) 241 newFile.close() 242 finally: 243 try: newFile.close() 244 except: pass 245 return newFilePath 246 247 def registerFileForCleanUp(self, fileName): 248 self.tempFiles.append(fileName) 249 250 def test_basic(self): 251 # Make sure that a local file just gets its own location returned and 252 # a headers value is returned. 253 result = urllib.urlretrieve("file:%s" % test_support.TESTFN) 254 self.assertEqual(result[0], test_support.TESTFN) 255 self.assertIsInstance(result[1], mimetools.Message, 256 "did not get a mimetools.Message instance as " 257 "second returned value") 258 259 def test_copy(self): 260 # Test that setting the filename argument works. 261 second_temp = "%s.2" % test_support.TESTFN 262 self.registerFileForCleanUp(second_temp) 263 result = urllib.urlretrieve(self.constructLocalFileUrl( 264 test_support.TESTFN), second_temp) 265 self.assertEqual(second_temp, result[0]) 266 self.assertTrue(os.path.exists(second_temp), "copy of the file was not " 267 "made") 268 FILE = file(second_temp, 'rb') 269 try: 270 text = FILE.read() 271 FILE.close() 272 finally: 273 try: FILE.close() 274 except: pass 275 self.assertEqual(self.text, text) 276 277 def test_reporthook(self): 278 # Make sure that the reporthook works. 279 def hooktester(count, block_size, total_size, count_holder=[0]): 280 self.assertIsInstance(count, int) 281 self.assertIsInstance(block_size, int) 282 self.assertIsInstance(total_size, int) 283 self.assertEqual(count, count_holder[0]) 284 count_holder[0] = count_holder[0] + 1 285 second_temp = "%s.2" % test_support.TESTFN 286 self.registerFileForCleanUp(second_temp) 287 urllib.urlretrieve(self.constructLocalFileUrl(test_support.TESTFN), 288 second_temp, hooktester) 289 290 def test_reporthook_0_bytes(self): 291 # Test on zero length file. Should call reporthook only 1 time. 292 report = [] 293 def hooktester(count, block_size, total_size, _report=report): 294 _report.append((count, block_size, total_size)) 295 srcFileName = self.createNewTempFile() 296 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName), 297 test_support.TESTFN, hooktester) 298 self.assertEqual(len(report), 1) 299 self.assertEqual(report[0][2], 0) 300 301 def test_reporthook_5_bytes(self): 302 # Test on 5 byte file. Should call reporthook only 2 times (once when 303 # the "network connection" is established and once when the block is 304 # read). Since the block size is 8192 bytes, only one block read is 305 # required to read the entire file. 306 report = [] 307 def hooktester(count, block_size, total_size, _report=report): 308 _report.append((count, block_size, total_size)) 309 srcFileName = self.createNewTempFile("x" * 5) 310 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName), 311 test_support.TESTFN, hooktester) 312 self.assertEqual(len(report), 2) 313 self.assertEqual(report[0][1], 8192) 314 self.assertEqual(report[0][2], 5) 315 316 def test_reporthook_8193_bytes(self): 317 # Test on 8193 byte file. Should call reporthook only 3 times (once 318 # when the "network connection" is established, once for the next 8192 319 # bytes, and once for the last byte). 320 report = [] 321 def hooktester(count, block_size, total_size, _report=report): 322 _report.append((count, block_size, total_size)) 323 srcFileName = self.createNewTempFile("x" * 8193) 324 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName), 325 test_support.TESTFN, hooktester) 326 self.assertEqual(len(report), 3) 327 self.assertEqual(report[0][1], 8192) 328 self.assertEqual(report[0][2], 8193) 329 330class QuotingTests(unittest.TestCase): 331 """Tests for urllib.quote() and urllib.quote_plus() 332 333 According to RFC 2396 ("Uniform Resource Identifiers), to escape a 334 character you write it as '%' + <2 character US-ASCII hex value>. The Python 335 code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly. 336 Case does not matter on the hex letters. 337 338 The various character sets specified are: 339 340 Reserved characters : ";/?:@&=+$," 341 Have special meaning in URIs and must be escaped if not being used for 342 their special meaning 343 Data characters : letters, digits, and "-_.!~*'()" 344 Unreserved and do not need to be escaped; can be, though, if desired 345 Control characters : 0x00 - 0x1F, 0x7F 346 Have no use in URIs so must be escaped 347 space : 0x20 348 Must be escaped 349 Delimiters : '<>#%"' 350 Must be escaped 351 Unwise : "{}|\^[]`" 352 Must be escaped 353 354 """ 355 356 def test_never_quote(self): 357 # Make sure quote() does not quote letters, digits, and "_,.-" 358 do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ", 359 "abcdefghijklmnopqrstuvwxyz", 360 "0123456789", 361 "_.-"]) 362 result = urllib.quote(do_not_quote) 363 self.assertEqual(do_not_quote, result, 364 "using quote(): %s != %s" % (do_not_quote, result)) 365 result = urllib.quote_plus(do_not_quote) 366 self.assertEqual(do_not_quote, result, 367 "using quote_plus(): %s != %s" % (do_not_quote, result)) 368 369 def test_default_safe(self): 370 # Test '/' is default value for 'safe' parameter 371 self.assertEqual(urllib.quote.func_defaults[0], '/') 372 373 def test_safe(self): 374 # Test setting 'safe' parameter does what it should do 375 quote_by_default = "<>" 376 result = urllib.quote(quote_by_default, safe=quote_by_default) 377 self.assertEqual(quote_by_default, result, 378 "using quote(): %s != %s" % (quote_by_default, result)) 379 result = urllib.quote_plus(quote_by_default, safe=quote_by_default) 380 self.assertEqual(quote_by_default, result, 381 "using quote_plus(): %s != %s" % 382 (quote_by_default, result)) 383 384 def test_default_quoting(self): 385 # Make sure all characters that should be quoted are by default sans 386 # space (separate test for that). 387 should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F 388 should_quote.append('<>#%"{}|\^[]`') 389 should_quote.append(chr(127)) # For 0x7F 390 should_quote = ''.join(should_quote) 391 for char in should_quote: 392 result = urllib.quote(char) 393 self.assertEqual(hexescape(char), result, 394 "using quote(): %s should be escaped to %s, not %s" % 395 (char, hexescape(char), result)) 396 result = urllib.quote_plus(char) 397 self.assertEqual(hexescape(char), result, 398 "using quote_plus(): " 399 "%s should be escapes to %s, not %s" % 400 (char, hexescape(char), result)) 401 del should_quote 402 partial_quote = "ab[]cd" 403 expected = "ab%5B%5Dcd" 404 result = urllib.quote(partial_quote) 405 self.assertEqual(expected, result, 406 "using quote(): %s != %s" % (expected, result)) 407 self.assertEqual(expected, result, 408 "using quote_plus(): %s != %s" % (expected, result)) 409 self.assertRaises(TypeError, urllib.quote, None) 410 411 def test_quoting_space(self): 412 # Make sure quote() and quote_plus() handle spaces as specified in 413 # their unique way 414 result = urllib.quote(' ') 415 self.assertEqual(result, hexescape(' '), 416 "using quote(): %s != %s" % (result, hexescape(' '))) 417 result = urllib.quote_plus(' ') 418 self.assertEqual(result, '+', 419 "using quote_plus(): %s != +" % result) 420 given = "a b cd e f" 421 expect = given.replace(' ', hexescape(' ')) 422 result = urllib.quote(given) 423 self.assertEqual(expect, result, 424 "using quote(): %s != %s" % (expect, result)) 425 expect = given.replace(' ', '+') 426 result = urllib.quote_plus(given) 427 self.assertEqual(expect, result, 428 "using quote_plus(): %s != %s" % (expect, result)) 429 430 def test_quoting_plus(self): 431 self.assertEqual(urllib.quote_plus('alpha+beta gamma'), 432 'alpha%2Bbeta+gamma') 433 self.assertEqual(urllib.quote_plus('alpha+beta gamma', '+'), 434 'alpha+beta+gamma') 435 436class UnquotingTests(unittest.TestCase): 437 """Tests for unquote() and unquote_plus() 438 439 See the doc string for quoting_Tests for details on quoting and such. 440 441 """ 442 443 def test_unquoting(self): 444 # Make sure unquoting of all ASCII values works 445 escape_list = [] 446 for num in range(128): 447 given = hexescape(chr(num)) 448 expect = chr(num) 449 result = urllib.unquote(given) 450 self.assertEqual(expect, result, 451 "using unquote(): %s != %s" % (expect, result)) 452 result = urllib.unquote_plus(given) 453 self.assertEqual(expect, result, 454 "using unquote_plus(): %s != %s" % 455 (expect, result)) 456 escape_list.append(given) 457 escape_string = ''.join(escape_list) 458 del escape_list 459 result = urllib.unquote(escape_string) 460 self.assertEqual(result.count('%'), 1, 461 "using quote(): not all characters escaped; %s" % 462 result) 463 result = urllib.unquote(escape_string) 464 self.assertEqual(result.count('%'), 1, 465 "using unquote(): not all characters escaped: " 466 "%s" % result) 467 468 def test_unquoting_badpercent(self): 469 # Test unquoting on bad percent-escapes 470 given = '%xab' 471 expect = given 472 result = urllib.unquote(given) 473 self.assertEqual(expect, result, "using unquote(): %r != %r" 474 % (expect, result)) 475 given = '%x' 476 expect = given 477 result = urllib.unquote(given) 478 self.assertEqual(expect, result, "using unquote(): %r != %r" 479 % (expect, result)) 480 given = '%' 481 expect = given 482 result = urllib.unquote(given) 483 self.assertEqual(expect, result, "using unquote(): %r != %r" 484 % (expect, result)) 485 486 def test_unquoting_mixed_case(self): 487 # Test unquoting on mixed-case hex digits in the percent-escapes 488 given = '%Ab%eA' 489 expect = '\xab\xea' 490 result = urllib.unquote(given) 491 self.assertEqual(expect, result, "using unquote(): %r != %r" 492 % (expect, result)) 493 494 def test_unquoting_parts(self): 495 # Make sure unquoting works when have non-quoted characters 496 # interspersed 497 given = 'ab%sd' % hexescape('c') 498 expect = "abcd" 499 result = urllib.unquote(given) 500 self.assertEqual(expect, result, 501 "using quote(): %s != %s" % (expect, result)) 502 result = urllib.unquote_plus(given) 503 self.assertEqual(expect, result, 504 "using unquote_plus(): %s != %s" % (expect, result)) 505 506 def test_unquoting_plus(self): 507 # Test difference between unquote() and unquote_plus() 508 given = "are+there+spaces..." 509 expect = given 510 result = urllib.unquote(given) 511 self.assertEqual(expect, result, 512 "using unquote(): %s != %s" % (expect, result)) 513 expect = given.replace('+', ' ') 514 result = urllib.unquote_plus(given) 515 self.assertEqual(expect, result, 516 "using unquote_plus(): %s != %s" % (expect, result)) 517 518 def test_unquote_with_unicode(self): 519 r = urllib.unquote(u'br%C3%BCckner_sapporo_20050930.doc') 520 self.assertEqual(r, u'br\xc3\xbcckner_sapporo_20050930.doc') 521 522class urlencode_Tests(unittest.TestCase): 523 """Tests for urlencode()""" 524 525 def help_inputtype(self, given, test_type): 526 """Helper method for testing different input types. 527 528 'given' must lead to only the pairs: 529 * 1st, 1 530 * 2nd, 2 531 * 3rd, 3 532 533 Test cannot assume anything about order. Docs make no guarantee and 534 have possible dictionary input. 535 536 """ 537 expect_somewhere = ["1st=1", "2nd=2", "3rd=3"] 538 result = urllib.urlencode(given) 539 for expected in expect_somewhere: 540 self.assertIn(expected, result, 541 "testing %s: %s not found in %s" % 542 (test_type, expected, result)) 543 self.assertEqual(result.count('&'), 2, 544 "testing %s: expected 2 '&'s; got %s" % 545 (test_type, result.count('&'))) 546 amp_location = result.index('&') 547 on_amp_left = result[amp_location - 1] 548 on_amp_right = result[amp_location + 1] 549 self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(), 550 "testing %s: '&' not located in proper place in %s" % 551 (test_type, result)) 552 self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps 553 "testing %s: " 554 "unexpected number of characters: %s != %s" % 555 (test_type, len(result), (5 * 3) + 2)) 556 557 def test_using_mapping(self): 558 # Test passing in a mapping object as an argument. 559 self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'}, 560 "using dict as input type") 561 562 def test_using_sequence(self): 563 # Test passing in a sequence of two-item sequences as an argument. 564 self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')], 565 "using sequence of two-item tuples as input") 566 567 def test_quoting(self): 568 # Make sure keys and values are quoted using quote_plus() 569 given = {"&":"="} 570 expect = "%s=%s" % (hexescape('&'), hexescape('=')) 571 result = urllib.urlencode(given) 572 self.assertEqual(expect, result) 573 given = {"key name":"A bunch of pluses"} 574 expect = "key+name=A+bunch+of+pluses" 575 result = urllib.urlencode(given) 576 self.assertEqual(expect, result) 577 578 def test_doseq(self): 579 # Test that passing True for 'doseq' parameter works correctly 580 given = {'sequence':['1', '2', '3']} 581 expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3'])) 582 result = urllib.urlencode(given) 583 self.assertEqual(expect, result) 584 result = urllib.urlencode(given, True) 585 for value in given["sequence"]: 586 expect = "sequence=%s" % value 587 self.assertIn(expect, result) 588 self.assertEqual(result.count('&'), 2, 589 "Expected 2 '&'s, got %s" % result.count('&')) 590 591class Pathname_Tests(unittest.TestCase): 592 """Test pathname2url() and url2pathname()""" 593 594 def test_basic(self): 595 # Make sure simple tests pass 596 expected_path = os.path.join("parts", "of", "a", "path") 597 expected_url = "parts/of/a/path" 598 result = urllib.pathname2url(expected_path) 599 self.assertEqual(expected_url, result, 600 "pathname2url() failed; %s != %s" % 601 (result, expected_url)) 602 result = urllib.url2pathname(expected_url) 603 self.assertEqual(expected_path, result, 604 "url2pathame() failed; %s != %s" % 605 (result, expected_path)) 606 607 def test_quoting(self): 608 # Test automatic quoting and unquoting works for pathnam2url() and 609 # url2pathname() respectively 610 given = os.path.join("needs", "quot=ing", "here") 611 expect = "needs/%s/here" % urllib.quote("quot=ing") 612 result = urllib.pathname2url(given) 613 self.assertEqual(expect, result, 614 "pathname2url() failed; %s != %s" % 615 (expect, result)) 616 expect = given 617 result = urllib.url2pathname(result) 618 self.assertEqual(expect, result, 619 "url2pathname() failed; %s != %s" % 620 (expect, result)) 621 given = os.path.join("make sure", "using_quote") 622 expect = "%s/using_quote" % urllib.quote("make sure") 623 result = urllib.pathname2url(given) 624 self.assertEqual(expect, result, 625 "pathname2url() failed; %s != %s" % 626 (expect, result)) 627 given = "make+sure/using_unquote" 628 expect = os.path.join("make+sure", "using_unquote") 629 result = urllib.url2pathname(given) 630 self.assertEqual(expect, result, 631 "url2pathname() failed; %s != %s" % 632 (expect, result)) 633 634 @unittest.skipUnless(sys.platform == 'win32', 635 'test specific to the nturl2path library') 636 def test_ntpath(self): 637 given = ('/C:/', '///C:/', '/C|//') 638 expect = 'C:\\' 639 for url in given: 640 result = urllib.url2pathname(url) 641 self.assertEqual(expect, result, 642 'nturl2path.url2pathname() failed; %s != %s' % 643 (expect, result)) 644 given = '///C|/path' 645 expect = 'C:\\path' 646 result = urllib.url2pathname(given) 647 self.assertEqual(expect, result, 648 'nturl2path.url2pathname() failed; %s != %s' % 649 (expect, result)) 650 651class Utility_Tests(unittest.TestCase): 652 """Testcase to test the various utility functions in the urllib.""" 653 654 def test_splitpasswd(self): 655 """Some of the password examples are not sensible, but it is added to 656 confirming to RFC2617 and addressing issue4675. 657 """ 658 self.assertEqual(('user', 'ab'),urllib.splitpasswd('user:ab')) 659 self.assertEqual(('user', 'a\nb'),urllib.splitpasswd('user:a\nb')) 660 self.assertEqual(('user', 'a\tb'),urllib.splitpasswd('user:a\tb')) 661 self.assertEqual(('user', 'a\rb'),urllib.splitpasswd('user:a\rb')) 662 self.assertEqual(('user', 'a\fb'),urllib.splitpasswd('user:a\fb')) 663 self.assertEqual(('user', 'a\vb'),urllib.splitpasswd('user:a\vb')) 664 self.assertEqual(('user', 'a:b'),urllib.splitpasswd('user:a:b')) 665 666 667class URLopener_Tests(unittest.TestCase): 668 """Testcase to test the open method of URLopener class.""" 669 670 def test_quoted_open(self): 671 class DummyURLopener(urllib.URLopener): 672 def open_spam(self, url): 673 return url 674 675 self.assertEqual(DummyURLopener().open( 676 'spam://example/ /'),'//example/%20/') 677 678 # test the safe characters are not quoted by urlopen 679 self.assertEqual(DummyURLopener().open( 680 "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"), 681 "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/") 682 683 684# Just commented them out. 685# Can't really tell why keep failing in windows and sparc. 686# Everywhere else they work ok, but on those machines, sometimes 687# fail in one of the tests, sometimes in other. I have a linux, and 688# the tests go ok. 689# If anybody has one of the problematic enviroments, please help! 690# . Facundo 691# 692# def server(evt): 693# import socket, time 694# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 695# serv.settimeout(3) 696# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 697# serv.bind(("", 9093)) 698# serv.listen(5) 699# try: 700# conn, addr = serv.accept() 701# conn.send("1 Hola mundo\n") 702# cantdata = 0 703# while cantdata < 13: 704# data = conn.recv(13-cantdata) 705# cantdata += len(data) 706# time.sleep(.3) 707# conn.send("2 No more lines\n") 708# conn.close() 709# except socket.timeout: 710# pass 711# finally: 712# serv.close() 713# evt.set() 714# 715# class FTPWrapperTests(unittest.TestCase): 716# 717# def setUp(self): 718# import ftplib, time, threading 719# ftplib.FTP.port = 9093 720# self.evt = threading.Event() 721# threading.Thread(target=server, args=(self.evt,)).start() 722# time.sleep(.1) 723# 724# def tearDown(self): 725# self.evt.wait() 726# 727# def testBasic(self): 728# # connects 729# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) 730# ftp.close() 731# 732# def testTimeoutNone(self): 733# # global default timeout is ignored 734# import socket 735# self.assertTrue(socket.getdefaulttimeout() is None) 736# socket.setdefaulttimeout(30) 737# try: 738# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) 739# finally: 740# socket.setdefaulttimeout(None) 741# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) 742# ftp.close() 743# 744# def testTimeoutDefault(self): 745# # global default timeout is used 746# import socket 747# self.assertTrue(socket.getdefaulttimeout() is None) 748# socket.setdefaulttimeout(30) 749# try: 750# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) 751# finally: 752# socket.setdefaulttimeout(None) 753# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) 754# ftp.close() 755# 756# def testTimeoutValue(self): 757# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [], 758# timeout=30) 759# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) 760# ftp.close() 761 762 763 764def test_main(): 765 import warnings 766 with warnings.catch_warnings(): 767 warnings.filterwarnings('ignore', ".*urllib\.urlopen.*Python 3.0", 768 DeprecationWarning) 769 test_support.run_unittest( 770 urlopen_FileTests, 771 urlopen_HttpTests, 772 urlretrieve_FileTests, 773 ProxyTests, 774 QuotingTests, 775 UnquotingTests, 776 urlencode_Tests, 777 Pathname_Tests, 778 Utility_Tests, 779 URLopener_Tests, 780 #FTPWrapperTests, 781 ) 782 783 784 785if __name__ == '__main__': 786 test_main() 787