LEFT | RIGHT |
1 import base64 | 1 import base64 |
2 import datetime | 2 import datetime |
3 import sys | 3 import sys |
4 import time | 4 import time |
5 import unittest | 5 import unittest |
| 6 from unittest import mock |
6 import xmlrpc.client as xmlrpclib | 7 import xmlrpc.client as xmlrpclib |
7 import xmlrpc.server | 8 import xmlrpc.server |
8 import http.client | 9 import http.client |
9 import socket | 10 import socket |
10 import os | 11 import os |
11 import re | 12 import re |
12 import io | 13 import io |
13 import contextlib | 14 import contextlib |
14 from test import support | 15 from test import support |
15 | 16 |
| 17 try: |
| 18 import gzip |
| 19 except ImportError: |
| 20 gzip = None |
16 try: | 21 try: |
17 import threading | 22 import threading |
18 except ImportError: | 23 except ImportError: |
19 threading = None | 24 threading = None |
20 | 25 |
21 alist = [{'astring': 'foo@bar.baz.spam', | 26 alist = [{'astring': 'foo@bar.baz.spam', |
22 'afloat': 7283.43, | 27 'afloat': 7283.43, |
23 'anint': 2**20, | 28 'anint': 2**20, |
24 'ashortlong': 2, | 29 'ashortlong': 2, |
25 'anotherlist': ['.zyx.41'], | 30 'anotherlist': ['.zyx.41'], |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 | 247 |
243 def test_dotted_attribute(self): | 248 def test_dotted_attribute(self): |
244 # this will raise AttributeError because code don't want us to use | 249 # this will raise AttributeError because code don't want us to use |
245 # private methods | 250 # private methods |
246 self.assertRaises(AttributeError, | 251 self.assertRaises(AttributeError, |
247 xmlrpc.server.resolve_dotted_attribute, str, '__add') | 252 xmlrpc.server.resolve_dotted_attribute, str, '__add') |
248 self.assertTrue(xmlrpc.server.resolve_dotted_attribute(str, 'title')) | 253 self.assertTrue(xmlrpc.server.resolve_dotted_attribute(str, 'title')) |
249 | 254 |
250 class DateTimeTestCase(unittest.TestCase): | 255 class DateTimeTestCase(unittest.TestCase): |
251 def test_default(self): | 256 def test_default(self): |
252 t = xmlrpclib.DateTime() | 257 with mock.patch('time.localtime') as localtime_mock: |
| 258 time_struct = time.struct_time( |
| 259 [2013, 7, 15, 0, 24, 49, 0, 196, 0]) |
| 260 localtime_mock.return_value = time_struct |
| 261 localtime = time.localtime() |
| 262 t = xmlrpclib.DateTime() |
| 263 self.assertEqual(str(t), |
| 264 time.strftime("%Y%m%dT%H:%M:%S", localtime)) |
253 | 265 |
254 def test_time(self): | 266 def test_time(self): |
255 d = 1181399930.036952 | 267 d = 1181399930.036952 |
256 t = xmlrpclib.DateTime(d) | 268 t = xmlrpclib.DateTime(d) |
257 self.assertEqual(str(t), | 269 self.assertEqual(str(t), |
258 time.strftime("%Y%m%dT%H:%M:%S", time.localtime(d))) | 270 time.strftime("%Y%m%dT%H:%M:%S", time.localtime(d))) |
259 | 271 |
260 def test_time_tuple(self): | 272 def test_time_tuple(self): |
261 d = (2007,6,9,10,38,50,5,160,0) | 273 d = (2007,6,9,10,38,50,5,160,0) |
262 t = xmlrpclib.DateTime(d) | 274 t = xmlrpclib.DateTime(d) |
(...skipping 16 matching lines...) Expand all Loading... |
279 self.assertEqual(repr(t), val) | 291 self.assertEqual(repr(t), val) |
280 | 292 |
281 def test_decode(self): | 293 def test_decode(self): |
282 d = ' 20070908T07:11:13 ' | 294 d = ' 20070908T07:11:13 ' |
283 t1 = xmlrpclib.DateTime() | 295 t1 = xmlrpclib.DateTime() |
284 t1.decode(d) | 296 t1.decode(d) |
285 tref = xmlrpclib.DateTime(datetime.datetime(2007,9,8,7,11,13)) | 297 tref = xmlrpclib.DateTime(datetime.datetime(2007,9,8,7,11,13)) |
286 self.assertEqual(t1, tref) | 298 self.assertEqual(t1, tref) |
287 | 299 |
288 t2 = xmlrpclib._datetime(d) | 300 t2 = xmlrpclib._datetime(d) |
289 self.assertEqual(t1, tref) | 301 self.assertEqual(t2, tref) |
290 | 302 |
291 def test_comparison(self): | 303 def test_comparison(self): |
292 now = datetime.datetime.now() | 304 now = datetime.datetime.now() |
293 dtime = xmlrpclib.DateTime(now.timetuple()) | 305 dtime = xmlrpclib.DateTime(now.timetuple()) |
294 | 306 |
295 # datetime vs. DateTime | 307 # datetime vs. DateTime |
296 self.assertTrue(dtime == now) | 308 self.assertTrue(dtime == now) |
297 self.assertTrue(now == dtime) | 309 self.assertTrue(now == dtime) |
298 then = now + datetime.timedelta(seconds=4) | 310 then = now + datetime.timedelta(seconds=4) |
299 self.assertTrue(then >= dtime) | 311 self.assertTrue(then >= dtime) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 # the event after it has been set the first time to catch the second set. | 373 # the event after it has been set the first time to catch the second set. |
362 def http_server(evt, numrequests, requestHandler=None): | 374 def http_server(evt, numrequests, requestHandler=None): |
363 class TestInstanceClass: | 375 class TestInstanceClass: |
364 def div(self, x, y): | 376 def div(self, x, y): |
365 return x // y | 377 return x // y |
366 | 378 |
367 def _methodHelp(self, name): | 379 def _methodHelp(self, name): |
368 if name == 'div': | 380 if name == 'div': |
369 return 'This is the div function' | 381 return 'This is the div function' |
370 | 382 |
| 383 class Fixture: |
| 384 @staticmethod |
| 385 def getData(): |
| 386 return '42' |
| 387 |
371 def my_function(): | 388 def my_function(): |
372 '''This is my function''' | 389 '''This is my function''' |
373 return True | 390 return True |
374 | 391 |
375 class MyXMLRPCServer(xmlrpc.server.SimpleXMLRPCServer): | 392 class MyXMLRPCServer(xmlrpc.server.SimpleXMLRPCServer): |
376 def get_request(self): | 393 def get_request(self): |
377 # Ensure the socket is always non-blocking. On Linux, socket | 394 # Ensure the socket is always non-blocking. On Linux, socket |
378 # attributes are not inherited like they are on *BSD and Windows. | 395 # attributes are not inherited like they are on *BSD and Windows. |
379 s, port = self.socket.accept() | 396 s, port = self.socket.accept() |
380 s.setblocking(True) | 397 s.setblocking(True) |
(...skipping 11 matching lines...) Expand all Loading... |
392 #trying to connect to "localhost" using all address families, which | 409 #trying to connect to "localhost" using all address families, which |
393 #causes slowdown e.g. on vista which supports AF_INET6. The server list
ens | 410 #causes slowdown e.g. on vista which supports AF_INET6. The server list
ens |
394 #on AF_INET only. | 411 #on AF_INET only. |
395 URL = "http://%s:%d"%(ADDR, PORT) | 412 URL = "http://%s:%d"%(ADDR, PORT) |
396 serv.server_activate() | 413 serv.server_activate() |
397 serv.register_introspection_functions() | 414 serv.register_introspection_functions() |
398 serv.register_multicall_functions() | 415 serv.register_multicall_functions() |
399 serv.register_function(pow) | 416 serv.register_function(pow) |
400 serv.register_function(lambda x,y: x+y, 'add') | 417 serv.register_function(lambda x,y: x+y, 'add') |
401 serv.register_function(my_function) | 418 serv.register_function(my_function) |
402 serv.register_instance(TestInstanceClass()) | 419 testInstance = TestInstanceClass() |
| 420 serv.register_instance(testInstance, allow_dotted_names=True) |
403 evt.set() | 421 evt.set() |
404 | 422 |
405 # handle up to 'numrequests' requests | 423 # handle up to 'numrequests' requests |
406 while numrequests > 0: | 424 while numrequests > 0: |
407 serv.handle_request() | 425 serv.handle_request() |
408 numrequests -= 1 | 426 numrequests -= 1 |
409 | 427 |
410 except socket.timeout: | 428 except socket.timeout: |
411 pass | 429 pass |
412 finally: | 430 finally: |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 conn.request('POST', '/this-is-not-valid') | 590 conn.request('POST', '/this-is-not-valid') |
573 response = conn.getresponse() | 591 response = conn.getresponse() |
574 conn.close() | 592 conn.close() |
575 | 593 |
576 self.assertEqual(response.status, 404) | 594 self.assertEqual(response.status, 404) |
577 self.assertEqual(response.reason, 'Not Found') | 595 self.assertEqual(response.reason, 'Not Found') |
578 | 596 |
579 def test_introspection1(self): | 597 def test_introspection1(self): |
580 expected_methods = set(['pow', 'div', 'my_function', 'add', | 598 expected_methods = set(['pow', 'div', 'my_function', 'add', |
581 'system.listMethods', 'system.methodHelp', | 599 'system.listMethods', 'system.methodHelp', |
582 'system.methodSignature', 'system.multicall']) | 600 'system.methodSignature', 'system.multicall', |
| 601 'Fixture']) |
583 try: | 602 try: |
584 p = xmlrpclib.ServerProxy(URL) | 603 p = xmlrpclib.ServerProxy(URL) |
585 meth = p.system.listMethods() | 604 meth = p.system.listMethods() |
586 self.assertEqual(set(meth), expected_methods) | 605 self.assertEqual(set(meth), expected_methods) |
587 except (xmlrpclib.ProtocolError, OSError) as e: | 606 except (xmlrpclib.ProtocolError, OSError) as e: |
588 # ignore failures due to non-blocking socket 'unavailable' errors | 607 # ignore failures due to non-blocking socket 'unavailable' errors |
589 if not is_unavailable_exception(e): | 608 if not is_unavailable_exception(e): |
590 # protocol error; provide additional information in test output | 609 # protocol error; provide additional information in test output |
591 self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) | 610 self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) |
592 | 611 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 | 689 |
671 def test_dotted_attribute(self): | 690 def test_dotted_attribute(self): |
672 # Raises an AttributeError because private methods are not allowed. | 691 # Raises an AttributeError because private methods are not allowed. |
673 self.assertRaises(AttributeError, | 692 self.assertRaises(AttributeError, |
674 xmlrpc.server.resolve_dotted_attribute, str, '__add') | 693 xmlrpc.server.resolve_dotted_attribute, str, '__add') |
675 | 694 |
676 self.assertTrue(xmlrpc.server.resolve_dotted_attribute(str, 'title')) | 695 self.assertTrue(xmlrpc.server.resolve_dotted_attribute(str, 'title')) |
677 # Get the test to run faster by sending a request with test_simple1. | 696 # Get the test to run faster by sending a request with test_simple1. |
678 # This avoids waiting for the socket timeout. | 697 # This avoids waiting for the socket timeout. |
679 self.test_simple1() | 698 self.test_simple1() |
| 699 |
| 700 def test_allow_dotted_names_true(self): |
| 701 # XXX also need allow_dotted_names_false test. |
| 702 server = xmlrpclib.ServerProxy("http://%s:%d/RPC2" % (ADDR, PORT)) |
| 703 data = server.Fixture.getData() |
| 704 self.assertEqual(data, '42') |
680 | 705 |
681 def test_unicode_host(self): | 706 def test_unicode_host(self): |
682 server = xmlrpclib.ServerProxy("http://%s:%d/RPC2" % (ADDR, PORT)) | 707 server = xmlrpclib.ServerProxy("http://%s:%d/RPC2" % (ADDR, PORT)) |
683 self.assertEqual(server.add("a", "\xe9"), "a\xe9") | 708 self.assertEqual(server.add("a", "\xe9"), "a\xe9") |
684 | 709 |
685 def test_partial_post(self): | 710 def test_partial_post(self): |
686 # Check that a partial POST doesn't make the server loop: issue #14001. | 711 # Check that a partial POST doesn't make the server loop: issue #14001. |
687 conn = http.client.HTTPConnection(ADDR, PORT) | 712 conn = http.client.HTTPConnection(ADDR, PORT) |
688 conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye') | 713 conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye') |
689 conn.close() | 714 conn.close() |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 p = xmlrpclib.ServerProxy(URL) | 803 p = xmlrpclib.ServerProxy(URL) |
779 #do some requests with close. | 804 #do some requests with close. |
780 self.assertEqual(p.pow(6,8), 6**8) | 805 self.assertEqual(p.pow(6,8), 6**8) |
781 p("transport").close() #same as above, really. | 806 p("transport").close() #same as above, really. |
782 self.assertEqual(p.pow(6,8), 6**8) | 807 self.assertEqual(p.pow(6,8), 6**8) |
783 p("close")() | 808 p("close")() |
784 self.assertEqual(len(self.RequestHandler.myRequests), 2) | 809 self.assertEqual(len(self.RequestHandler.myRequests), 2) |
785 | 810 |
786 #A test case that verifies that gzip encoding works in both directions | 811 #A test case that verifies that gzip encoding works in both directions |
787 #(for a request and the response) | 812 #(for a request and the response) |
| 813 @unittest.skipIf(gzip is None, 'requires gzip') |
788 class GzipServerTestCase(BaseServerTestCase): | 814 class GzipServerTestCase(BaseServerTestCase): |
789 #a request handler that supports keep-alive and logs requests into a | 815 #a request handler that supports keep-alive and logs requests into a |
790 #class variable | 816 #class variable |
791 class RequestHandler(xmlrpc.server.SimpleXMLRPCRequestHandler): | 817 class RequestHandler(xmlrpc.server.SimpleXMLRPCRequestHandler): |
792 parentClass = xmlrpc.server.SimpleXMLRPCRequestHandler | 818 parentClass = xmlrpc.server.SimpleXMLRPCRequestHandler |
793 protocol_version = 'HTTP/1.1' | 819 protocol_version = 'HTTP/1.1' |
794 | 820 |
795 def do_POST(self): | 821 def do_POST(self): |
796 #store content of last request in class | 822 #store content of last request in class |
797 self.__class__.content_length = int(self.headers["content-length"]) | 823 self.__class__.content_length = int(self.headers["content-length"]) |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 | 1095 |
1070 def test_xmlrpcserver_has_use_builtin_types_flag(self): | 1096 def test_xmlrpcserver_has_use_builtin_types_flag(self): |
1071 server = xmlrpc.server.SimpleXMLRPCServer(("localhost", 0), | 1097 server = xmlrpc.server.SimpleXMLRPCServer(("localhost", 0), |
1072 use_builtin_types=True) | 1098 use_builtin_types=True) |
1073 server.server_close() | 1099 server.server_close() |
1074 self.assertTrue(server.use_builtin_types) | 1100 self.assertTrue(server.use_builtin_types) |
1075 | 1101 |
1076 | 1102 |
1077 @support.reap_threads | 1103 @support.reap_threads |
1078 def test_main(): | 1104 def test_main(): |
1079 xmlrpc_tests = [XMLRPCTestCase, HelperTestCase, DateTimeTestCase, | 1105 support.run_unittest(XMLRPCTestCase, HelperTestCase, DateTimeTestCase, |
1080 BinaryTestCase, FaultTestCase] | 1106 BinaryTestCase, FaultTestCase, UseBuiltinTypesTestCase, |
1081 xmlrpc_tests.append(UseBuiltinTypesTestCase) | 1107 SimpleServerTestCase, KeepaliveServerTestCase1, |
1082 xmlrpc_tests.append(SimpleServerTestCase) | 1108 KeepaliveServerTestCase2, GzipServerTestCase, |
1083 xmlrpc_tests.append(KeepaliveServerTestCase1) | 1109 MultiPathServerTestCase, ServerProxyTestCase, FailingServerTestCase, |
1084 xmlrpc_tests.append(KeepaliveServerTestCase2) | 1110 CGIHandlerTestCase) |
1085 try: | 1111 |
1086 import gzip | |
1087 xmlrpc_tests.append(GzipServerTestCase) | |
1088 except ImportError: | |
1089 pass #gzip not supported in this build | |
1090 xmlrpc_tests.append(MultiPathServerTestCase) | |
1091 xmlrpc_tests.append(ServerProxyTestCase) | |
1092 xmlrpc_tests.append(FailingServerTestCase) | |
1093 xmlrpc_tests.append(CGIHandlerTestCase) | |
1094 | |
1095 support.run_unittest(*xmlrpc_tests) | |
1096 | 1112 |
1097 if __name__ == "__main__": | 1113 if __name__ == "__main__": |
1098 test_main() | 1114 test_main() |
LEFT | RIGHT |