10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport base64 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport datetime 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport time 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport xmlrpclib 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport SimpleXMLRPCServer 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport mimetools 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport httplib 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport socket 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport StringIO 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport re 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test import test_support 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry: 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import threading 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept ImportError: 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao threading = None 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry: 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao unicode 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept NameError: 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao have_unicode = False 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelse: 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao have_unicode = True 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoalist = [{'astring': 'foo@bar.baz.spam', 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'afloat': 7283.43, 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'anint': 2**20, 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'ashortlong': 2L, 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'anotherlist': ['.zyx.41'], 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'abase64': xmlrpclib.Binary("my dog has fleas"), 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'boolean': xmlrpclib.False, 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'unicode': u'\u4000\u6000\u8000', 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao u'ukey\u4000': 'regular value', 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'datetime1': xmlrpclib.DateTime('20050210T11:41:23'), 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'datetime2': xmlrpclib.DateTime( 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (2005, 02, 10, 11, 41, 23, 0, 1, -1)), 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'datetime3': xmlrpclib.DateTime( 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao datetime.datetime(2005, 02, 10, 11, 41, 23)), 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao }] 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass XMLRPCTestCase(unittest.TestCase): 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_load(self): 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(alist, 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpclib.loads(xmlrpclib.dumps((alist,)))[0][0]) 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_bare_datetime(self): 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # This checks that an unwrapped datetime.date object can be handled 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # by the marshalling code. This can't be done via test_dump_load() 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # since with use_datetime set to 1 the unmarshaller would create 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # datetime objects for the 'datetime[123]' keys as well 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dt = datetime.datetime(2005, 02, 10, 11, 41, 23) 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = xmlrpclib.dumps((dt,)) 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (newdt,), m = xmlrpclib.loads(s, use_datetime=1) 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(newdt, dt) 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(m, None) 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (newdt,), m = xmlrpclib.loads(s, use_datetime=0) 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(newdt, xmlrpclib.DateTime('20050210T11:41:23')) 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_datetime_before_1900(self): 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # same as before but with a date before 1900 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dt = datetime.datetime(1, 02, 10, 11, 41, 23) 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = xmlrpclib.dumps((dt,)) 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (newdt,), m = xmlrpclib.loads(s, use_datetime=1) 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(newdt, dt) 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(m, None) 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (newdt,), m = xmlrpclib.loads(s, use_datetime=0) 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(newdt, xmlrpclib.DateTime('00010210T11:41:23')) 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_cmp_datetime_DateTime(self): 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao now = datetime.datetime.now() 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dt = xmlrpclib.DateTime(now.timetuple()) 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(dt == now) 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(now == dt) 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao then = now + datetime.timedelta(seconds=4) 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(then >= dt) 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(dt < then) 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_bug_1164912 (self): 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = xmlrpclib.DateTime() 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ((new_d,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((d,), 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao methodresponse=True)) 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIsInstance(new_d.value, str) 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Check that the output of dumps() is still an 8-bit string 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = xmlrpclib.dumps((new_d,), methodresponse=True) 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIsInstance(s, str) 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_newstyle_class(self): 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class T(object): 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = T() 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t.x = 100 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t.y = "Hello" 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ((t2,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((t,))) 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(t2, t.__dict__) 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_big_long(self): 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(OverflowError, xmlrpclib.dumps, (2L**99,)) 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_bad_dict(self): 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},)) 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_recursive_seq(self): 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao l = [1,2,3] 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = [3,4,5,l] 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao l.append(t) 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(TypeError, xmlrpclib.dumps, (l,)) 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_recursive_dict(self): 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = {'1':1, '2':1} 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = {'3':3, 'd':d} 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d['t'] = t 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(TypeError, xmlrpclib.dumps, (d,)) 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_big_int(self): 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if sys.maxint > 2L**31-1: 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(OverflowError, xmlrpclib.dumps, 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (int(2L**34),)) 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpclib.dumps((xmlrpclib.MAXINT, xmlrpclib.MININT)) 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MAXINT+1,)) 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MININT-1,)) 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def dummy_write(s): 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao m = xmlrpclib.Marshaller() 1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao m.dump_int(xmlrpclib.MAXINT, dummy_write) 1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao m.dump_int(xmlrpclib.MININT, dummy_write) 1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MAXINT+1, dummy_write) 1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MININT-1, dummy_write) 1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_none(self): 1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao value = alist + [None] 1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao arg1 = (alist + [None],) 1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao strg = xmlrpclib.dumps(arg1, allow_none=True) 1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(value, 1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpclib.loads(strg)[0][0]) 1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,)) 1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_default_encoding_issues(self): 1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # SF bug #1115989: wrong decoding in '_stringify' 1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao utf8 = """<?xml version='1.0' encoding='iso-8859-1'?> 1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <params> 1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <param><value> 1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <string>abc \x95</string> 1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </value></param> 1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <param><value> 1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <struct> 1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <member> 1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <name>def \x96</name> 1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <value><string>ghi \x97</string></value> 1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </member> 1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </struct> 1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </value></param> 1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </params> 1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # sys.setdefaultencoding() normally doesn't exist after site.py is 1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # loaded. Import a temporary fresh copy to get access to it 1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # but then restore the original copy to avoid messing with 1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # other potentially modified sys module attributes 1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao old_encoding = sys.getdefaultencoding() 1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao with test_support.CleanImport('sys'): 1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import sys as temp_sys 1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao temp_sys.setdefaultencoding("iso-8859-1") 1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (s, d), m = xmlrpclib.loads(utf8) 1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao finally: 1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao temp_sys.setdefaultencoding(old_encoding) 1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao items = d.items() 1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if have_unicode: 1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(s, u"abc \x95") 1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIsInstance(s, unicode) 1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(items, [(u"def \x96", u"ghi \x97")]) 1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIsInstance(items[0][0], unicode) 1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIsInstance(items[0][1], unicode) 1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(s, "abc \xc2\x95") 1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(items, [("def \xc2\x96", "ghi \xc2\x97")]) 1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass HelperTestCase(unittest.TestCase): 1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_escape(self): 1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(xmlrpclib.escape("a&b"), "a&b") 1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(xmlrpclib.escape("a<b"), "a<b") 1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(xmlrpclib.escape("a>b"), "a>b") 1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FaultTestCase(unittest.TestCase): 1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_repr(self): 1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = xmlrpclib.Fault(42, 'Test Fault') 2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(repr(f), "<Fault 42: 'Test Fault'>") 2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(repr(f), str(f)) 2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dump_fault(self): 2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = xmlrpclib.Fault(42, 'Test Fault') 2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = xmlrpclib.dumps((f,)) 2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (newf,), m = xmlrpclib.loads(s) 2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(newf, {'faultCode': 42, 'faultString': 'Test Fault'}) 2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(m, None) 2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = xmlrpclib.Marshaller().dumps(f) 2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s) 2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass DateTimeTestCase(unittest.TestCase): 2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_default(self): 2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.DateTime() 2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_time(self): 2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = 1181399930.036952 2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.DateTime(d) 2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t), time.strftime("%Y%m%dT%H:%M:%S", time.localtime(d))) 2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_time_tuple(self): 2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = (2007,6,9,10,38,50,5,160,0) 2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.DateTime(d) 2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t), '20070609T10:38:50') 2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_time_struct(self): 2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = time.localtime(1181399930.036952) 2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.DateTime(d) 2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t), time.strftime("%Y%m%dT%H:%M:%S", d)) 2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_datetime_datetime(self): 2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = datetime.datetime(2007,1,2,3,4,5) 2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.DateTime(d) 2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t), '20070102T03:04:05') 2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_repr(self): 2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = datetime.datetime(2007,1,2,3,4,5) 2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.DateTime(d) 2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao val ="<DateTime '20070102T03:04:05' at %x>" % id(t) 2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(repr(t), val) 2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_decode(self): 2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = ' 20070908T07:11:13 ' 2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t1 = xmlrpclib.DateTime() 2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t1.decode(d) 2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao tref = xmlrpclib.DateTime(datetime.datetime(2007,9,8,7,11,13)) 2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(t1, tref) 2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t2 = xmlrpclib._datetime(d) 2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(t1, tref) 2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass BinaryTestCase(unittest.TestCase): 2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_default(self): 2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.Binary() 2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t), '') 2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_string(self): 2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = '\x01\x02\x03abc123\xff\xfe' 2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.Binary(d) 2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t), d) 2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_decode(self): 2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = '\x01\x02\x03abc123\xff\xfe' 2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao de = base64.encodestring(d) 2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t1 = xmlrpclib.Binary() 2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t1.decode(de) 2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t1), d) 2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t2 = xmlrpclib._binary(de) 2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(str(t2), d) 2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2750a8c90248264a8b26970b4473770bcc3df8515fJosh GaoADDR = PORT = URL = None 2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# The evt is set twice. First when the server is ready to serve. 2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Second when the server has been shutdown. The user must clear 2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# the event after it has been set the first time to catch the second set. 2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef http_server(evt, numrequests, requestHandler=None): 2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class TestInstanceClass: 2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def div(self, x, y): 2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return x // y 2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _methodHelp(self, name): 2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name == 'div': 2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 'This is the div function' 2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def my_function(): 2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '''This is my function''' 2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True 2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class MyXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer): 2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def get_request(self): 2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Ensure the socket is always non-blocking. On Linux, socket 2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # attributes are not inherited like they are on *BSD and Windows. 2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s, port = self.socket.accept() 2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s.setblocking(True) 2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return s, port 3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not requestHandler: 3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao requestHandler = SimpleXMLRPCServer.SimpleXMLRPCRequestHandler 3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv = MyXMLRPCServer(("localhost", 0), requestHandler, 3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao logRequests=False, bind_and_activate=False) 3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.socket.settimeout(3) 3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.server_bind() 3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao global ADDR, PORT, URL 3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ADDR, PORT = serv.socket.getsockname() 3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #connect to IP address directly. This avoids socket.create_connection() 3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #trying to connect to "localhost" using all address families, which 3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #causes slowdown e.g. on vista which supports AF_INET6. The server listens 3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #on AF_INET only. 3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao URL = "http://%s:%d"%(ADDR, PORT) 3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.server_activate() 3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.register_introspection_functions() 3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.register_multicall_functions() 3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.register_function(pow) 3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.register_function(lambda x,y: x+y, 'add') 3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.register_function(my_function) 3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.register_instance(TestInstanceClass()) 3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao evt.set() 3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # handle up to 'numrequests' requests 3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while numrequests > 0: 3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.handle_request() 3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao numrequests -= 1 3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except socket.timeout: 3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao finally: 3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.socket.close() 3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao PORT = None 3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao evt.set() 3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef http_multi_server(evt, numrequests, requestHandler=None): 3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class TestInstanceClass: 3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def div(self, x, y): 3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return x // y 3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _methodHelp(self, name): 3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name == 'div': 3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 'This is the div function' 3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def my_function(): 3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '''This is my function''' 3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True 3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class MyXMLRPCServer(SimpleXMLRPCServer.MultiPathXMLRPCServer): 3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def get_request(self): 3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Ensure the socket is always non-blocking. On Linux, socket 3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # attributes are not inherited like they are on *BSD and Windows. 3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s, port = self.socket.accept() 3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s.setblocking(True) 3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return s, port 3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not requestHandler: 3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao requestHandler = SimpleXMLRPCServer.SimpleXMLRPCRequestHandler 3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class MyRequestHandler(requestHandler): 3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao rpc_paths = [] 3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv = MyXMLRPCServer(("localhost", 0), MyRequestHandler, 3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao logRequests=False, bind_and_activate=False) 3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.socket.settimeout(3) 3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.server_bind() 3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao global ADDR, PORT, URL 3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ADDR, PORT = serv.socket.getsockname() 3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #connect to IP address directly. This avoids socket.create_connection() 3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #trying to connect to "localhost" using all address families, which 3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #causes slowdown e.g. on vista which supports AF_INET6. The server listens 3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #on AF_INET only. 3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao URL = "http://%s:%d"%(ADDR, PORT) 3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.server_activate() 3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao paths = ["/foo", "/foo/bar"] 3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for path in paths: 3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d = serv.add_dispatcher(path, SimpleXMLRPCServer.SimpleXMLRPCDispatcher()) 3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d.register_introspection_functions() 3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao d.register_multicall_functions() 3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.get_dispatcher(paths[0]).register_function(pow) 3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.get_dispatcher(paths[1]).register_function(lambda x,y: x+y, 'add') 3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao evt.set() 3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # handle up to 'numrequests' requests 3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while numrequests > 0: 3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.handle_request() 3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao numrequests -= 1 3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except socket.timeout: 3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao finally: 3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv.socket.close() 3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao PORT = None 3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao evt.set() 3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This function prevents errors like: 3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# <ProtocolError for localhost:57527/RPC2: 500 Internal Server Error> 3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef is_unavailable_exception(e): 3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '''Returns True if the given ProtocolError is the product of a server-side 4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exception caused by the 'temporarily unavailable' response sometimes 4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao given by operations on non-blocking sockets.''' 4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # sometimes we get a -1 error code and/or empty headers 4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if e.errcode == -1 or e.headers is None: 4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True 4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exc_mess = e.headers.get('X-exception') 4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except AttributeError: 4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Ignore socket.errors here. 4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exc_mess = str(e) 4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if exc_mess and 'temporarily unavailable' in exc_mess.lower(): 4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True 4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return False 4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao@unittest.skipUnless(threading, 'Threading required for this test.') 4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass BaseServerTestCase(unittest.TestCase): 4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao requestHandler = None 4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao request_count = 1 4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao threadFunc = staticmethod(http_server) 4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def setUp(self): 4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # enable traceback reporting 4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = True 4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt = threading.Event() 4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # start server thread to handle requests 4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv_args = (self.evt, self.request_count, self.requestHandler) 4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao threading.Thread(target=self.threadFunc, args=serv_args).start() 4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # wait for the server to be ready 4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt.wait(10) 4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt.clear() 4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def tearDown(self): 4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # wait on the server thread to terminate 4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt.wait(10) 4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # disable traceback reporting 4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = False 4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# NOTE: The tests in SimpleServerTestCase will ignore failures caused by 4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# "temporarily unavailable" exceptions raised in SimpleXMLRPCServer. This 4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# condition occurs infrequently on some platforms, frequently on others, and 4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# is apparently caused by using SimpleXMLRPCServer with a non-blocking socket 4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# If the server class is updated at some point in the future to handle this 4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# situation more gracefully, these tests should be modified appropriately. 4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SimpleServerTestCase(BaseServerTestCase): 4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_simple1(self): 4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_nonascii(self): 4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao start_string = 'P\N{LATIN SMALL LETTER Y WITH CIRCUMFLEX}t' 4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao end_string = 'h\N{LATIN SMALL LETTER O WITH HORN}n' 4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.add(start_string, end_string), 4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao start_string + end_string) 4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error) as e: 4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket unavailable errors. 4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_unicode_host(self): 4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao server = xmlrpclib.ServerProxy(u"http://%s:%d/RPC2"%(ADDR, PORT)) 4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(server.add("a", u"\xe9"), u"a\xe9") 4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # [ch] The test 404 is causing lots of false alarms. 4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def XXXtest_404(self): 4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # send POST with httplib, it should return 404 header and 4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # 'Not Found' message. 4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn = httplib.HTTPConnection(ADDR, PORT) 4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.request('POST', '/this-is-not-valid') 4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao response = conn.getresponse() 4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.close() 4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(response.status, 404) 4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(response.reason, 'Not Found') 4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_introspection1(self): 4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao meth = p.system.listMethods() 4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao expected_methods = set(['pow', 'div', 'my_function', 'add', 4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'system.listMethods', 'system.methodHelp', 4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'system.methodSignature', 'system.multicall']) 4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(set(meth), expected_methods) 4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_introspection2(self): 5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # test _methodHelp() 5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao divhelp = p.system.methodHelp('div') 5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(divhelp, 'This is the div function') 5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @unittest.skipIf(sys.flags.optimize >= 2, 5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "Docstrings are omitted with -O2 and above") 5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_introspection3(self): 5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # test native doc 5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao myfunction = p.system.methodHelp('my_function') 5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(myfunction, 'This is my function') 5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_introspection4(self): 5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # the SimpleXMLRPCServer doesn't support signatures, but 5330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # at least check that we can try making the call 5340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 5350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 5360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao divsig = p.system.methodSignature('div') 5370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(divsig, 'signatures not supported') 5380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 5390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 5400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 5410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 5420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 5430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_multicall(self): 5450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 5460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 5470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao multicall = xmlrpclib.MultiCall(p) 5480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao multicall.add(2,3) 5490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao multicall.pow(6,8) 5500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao multicall.div(127,42) 5510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao add_result, pow_result, div_result = multicall() 5520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(add_result, 2+3) 5530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(pow_result, 6**8) 5540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(div_result, 127//42) 5550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 5560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 5570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 5580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 5590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 5600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_non_existing_multicall(self): 5620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 5630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 5640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao multicall = xmlrpclib.MultiCall(p) 5650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao multicall.this_is_not_exists() 5660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = multicall() 5670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # result.results contains; 5690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # [{'faultCode': 1, 'faultString': '<type \'exceptions.Exception\'>:' 5700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # 'method "this_is_not_exists" is not supported'>}] 5710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(result.results[0]['faultCode'], 1) 5730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(result.results[0]['faultString'], 5740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao '<type \'exceptions.Exception\'>:method "this_is_not_exists" ' 5750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'is not supported') 5760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 5770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 5780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 5790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 5800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 5810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_dotted_attribute(self): 5830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Raises an AttributeError because private methods are not allowed. 5840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(AttributeError, 5850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.resolve_dotted_attribute, str, '__add') 5860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(SimpleXMLRPCServer.resolve_dotted_attribute(str, 'title')) 5880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Get the test to run faster by sending a request with test_simple1. 5890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # This avoids waiting for the socket timeout. 5900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.test_simple1() 5910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_partial_post(self): 5930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Check that a partial POST doesn't make the server loop: issue #14001. 5940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn = httplib.HTTPConnection(ADDR, PORT) 5950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye') 5960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.close() 5970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 5980a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass MultiPathServerTestCase(BaseServerTestCase): 5990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao threadFunc = staticmethod(http_multi_server) 6000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao request_count = 2 6010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_path1(self): 6020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL+"/foo") 6030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) 6050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_path2(self): 6060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL+"/foo/bar") 6070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.add(6,8), 6+8) 6080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8) 6090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#A test case that verifies that a server using the HTTP/1.1 keep-alive mechanism 6110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#does indeed serve subsequent requests on the same connection 6120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass BaseKeepaliveServerTestCase(BaseServerTestCase): 6130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #a request handler that supports keep-alive and logs requests into a 6140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #class variable 6150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class RequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): 6160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao parentClass = SimpleXMLRPCServer.SimpleXMLRPCRequestHandler 6170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao protocol_version = 'HTTP/1.1' 6180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao myRequests = [] 6190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def handle(self): 6200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.myRequests.append([]) 6210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.reqidx = len(self.myRequests)-1 6220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.parentClass.handle(self) 6230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def handle_one_request(self): 6240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = self.parentClass.handle_one_request(self) 6250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.myRequests[self.reqidx].append(self.raw_requestline) 6260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return result 6270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao requestHandler = RequestHandler 6290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def setUp(self): 6300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #clear request log 6310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.RequestHandler.myRequests = [] 6320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return BaseServerTestCase.setUp(self) 6330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#A test case that verifies that a server using the HTTP/1.1 keep-alive mechanism 6350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#does indeed serve subsequent requests on the same connection 6360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass KeepaliveServerTestCase1(BaseKeepaliveServerTestCase): 6370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_two(self): 6380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 6390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #do three requests. 6400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #they should have all been handled by a single request handler 6450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(len(self.RequestHandler.myRequests), 1) 6460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #check that we did at least two (the third may be pending append 6480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #due to thread scheduling) 6490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertGreaterEqual(len(self.RequestHandler.myRequests[-1]), 2) 6500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#test special attribute access on the serverproxy, through the __call__ 6520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#function. 6530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass KeepaliveServerTestCase2(BaseKeepaliveServerTestCase): 6540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #ask for two keepalive requests to be handled. 6550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao request_count=2 6560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_close(self): 6580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 6590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #do some requests with close. 6600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p("close")() #this should trigger a new keep-alive request 6640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #they should have all been two request handlers, each having logged at least 6690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #two complete requests 6700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(len(self.RequestHandler.myRequests), 2) 6710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertGreaterEqual(len(self.RequestHandler.myRequests[-1]), 2) 6720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertGreaterEqual(len(self.RequestHandler.myRequests[-2]), 2) 6730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_transport(self): 6750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 6760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #do some requests with close. 6770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p("transport").close() #same as above, really. 6790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 6800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(len(self.RequestHandler.myRequests), 2) 6810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#A test case that verifies that gzip encoding works in both directions 6830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#(for a request and the response) 6840a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass GzipServerTestCase(BaseServerTestCase): 6850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #a request handler that supports keep-alive and logs requests into a 6860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #class variable 6870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class RequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): 6880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao parentClass = SimpleXMLRPCServer.SimpleXMLRPCRequestHandler 6890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao protocol_version = 'HTTP/1.1' 6900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def do_POST(self): 6920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #store content of last request in class 6930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.__class__.content_length = int(self.headers["content-length"]) 6940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.parentClass.do_POST(self) 6950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao requestHandler = RequestHandler 6960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 6970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class Transport(xmlrpclib.Transport): 6980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #custom transport, stores the response length for our perusal 6990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao fake_gzip = False 7000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def parse_response(self, response): 7010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.response_length=int(response.getheader("content-length", 0)) 7020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return xmlrpclib.Transport.parse_response(self, response) 7030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def send_content(self, connection, body): 7050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.fake_gzip: 7060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao #add a lone gzip header to induce decode error remotely 7070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao connection.putheader("Content-Encoding", "gzip") 7080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return xmlrpclib.Transport.send_content(self, connection, body) 7090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def setUp(self): 7110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao BaseServerTestCase.setUp(self) 7120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_gzip_request(self): 7140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = self.Transport() 7150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t.encode_threshold = None 7160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL, transport=t) 7170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 7180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao a = self.RequestHandler.content_length 7190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t.encode_threshold = 0 #turn on request encoding 7200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 7210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao b = self.RequestHandler.content_length 7220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(a>b) 7230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_bad_gzip_request(self): 7250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = self.Transport() 7260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t.encode_threshold = None 7270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t.fake_gzip = True 7280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL, transport=t) 7290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cm = self.assertRaisesRegexp(xmlrpclib.ProtocolError, 7300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao re.compile(r"\b400\b")) 7310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao with cm: 7320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p.pow(6, 8) 7330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_gsip_response(self): 7350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = self.Transport() 7360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL, transport=t) 7370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao old = self.requestHandler.encode_threshold 7380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.requestHandler.encode_threshold = None #no encoding 7390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 7400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao a = t.response_length 7410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.requestHandler.encode_threshold = 0 #always encode 7420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 7430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao b = t.response_length 7440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.requestHandler.encode_threshold = old 7450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(a>b) 7460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#Test special attributes of the ServerProxy object 7480a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass ServerProxyTestCase(unittest.TestCase): 7490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def setUp(self): 7500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao unittest.TestCase.setUp(self) 7510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if threading: 7520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.url = URL 7530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 7540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Without threading, http_server() and http_multi_server() will not 7550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # be executed and URL is still equal to None. 'http://' is a just 7560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # enough to choose the scheme (HTTP) 7570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.url = 'http://' 7580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_close(self): 7600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(self.url) 7610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p('close')(), None) 7620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_transport(self): 7640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao t = xmlrpclib.Transport() 7650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(self.url, transport=t) 7660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p('transport'), t) 7670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This is a contrived way to make a failure occur on the server side 7690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# in order to test the _send_traceback_header flag on the server 7700a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FailingMessageClass(mimetools.Message): 7710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getitem__(self, key): 7720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao key = key.lower() 7730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if key == 'content-length': 7740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 'I am broken' 7750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return mimetools.Message.__getitem__(self, key) 7760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao@unittest.skipUnless(threading, 'Threading required for this test.') 7790a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FailingServerTestCase(unittest.TestCase): 7800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def setUp(self): 7810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt = threading.Event() 7820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # start server thread to handle requests 7830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao serv_args = (self.evt, 1) 7840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao threading.Thread(target=http_server, args=serv_args).start() 7850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # wait for the server to be ready 7870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt.wait() 7880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt.clear() 7890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def tearDown(self): 7910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # wait on the server thread to terminate 7920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.evt.wait() 7930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # reset flag 7940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = False 7950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # reset message class 7960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.MessageClass = mimetools.Message 7970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 7980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_basic(self): 7990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # check that flag is false by default 8000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao flagval = SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header 8010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(flagval, False) 8020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # enable traceback reporting 8040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = True 8050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # test a call that shouldn't fail just as a smoke test 8070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 8080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 8090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(p.pow(6,8), 6**8) 8100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 8110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 8120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e): 8130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # protocol error; provide additional information in test output 8140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) 8150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_fail_no_info(self): 8170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # use the broken message class 8180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.MessageClass = FailingMessageClass 8190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 8210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 8220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p.pow(6,8) 8230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 8240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 8250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e) and hasattr(e, "headers"): 8260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # The two server-side error headers shouldn't be sent back in this case 8270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(e.headers.get("X-exception") is None) 8280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(e.headers.get("X-traceback") is None) 8290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 8300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail('ProtocolError not raised') 8310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_fail_with_info(self): 8330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # use the broken message class 8340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.MessageClass = FailingMessageClass 8350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Check that errors in the server send back exception/traceback 8370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # info when flag is set 8380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = True 8390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 8410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p = xmlrpclib.ServerProxy(URL) 8420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao p.pow(6,8) 8430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (xmlrpclib.ProtocolError, socket.error), e: 8440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # ignore failures due to non-blocking socket 'unavailable' errors 8450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not is_unavailable_exception(e) and hasattr(e, "headers"): 8460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # We should get error info in the response 8470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao expected_err = "invalid literal for int() with base 10: 'I am broken'" 8480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(e.headers.get("x-exception"), expected_err) 8490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertTrue(e.headers.get("x-traceback") is not None) 8500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 8510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fail('ProtocolError not raised') 8520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass CGIHandlerTestCase(unittest.TestCase): 8540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def setUp(self): 8550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.cgi = SimpleXMLRPCServer.CGIXMLRPCRequestHandler() 8560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def tearDown(self): 8580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.cgi = None 8590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_cgi_get(self): 8610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao with test_support.EnvironmentVarGuard() as env: 8620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env['REQUEST_METHOD'] = 'GET' 8630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # if the method is GET and no request_text is given, it runs handle_get 8640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # get sysout output 8650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao with test_support.captured_stdout() as data_out: 8660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.cgi.handle_request() 8670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # parse Status header 8690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data_out.seek(0) 8700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao handle = data_out.read() 8710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = handle.split()[1] 8720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao message = ' '.join(handle.split()[2:4]) 8730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(status, '400') 8750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual(message, 'Bad Request') 8760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_cgi_xmlrpc_response(self): 8790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = """<?xml version='1.0'?> 8800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <methodCall> 8810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <methodName>test_method</methodName> 8820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <params> 8830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <param> 8840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <value><string>foo</string></value> 8850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </param> 8860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <param> 8870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao <value><string>bar</string></value> 8880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </param> 8890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </params> 8900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao </methodCall> 8910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 8920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 8930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao with test_support.EnvironmentVarGuard() as env, \ 8940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao test_support.captured_stdout() as data_out, \ 8950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao test_support.captured_stdin() as data_in: 8960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data_in.write(data) 8970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data_in.seek(0) 8980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao env['CONTENT_LENGTH'] = str(len(data)) 8990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.cgi.handle_request() 9000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data_out.seek(0) 9010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # will respond exception, if so, our goal is achieved ;) 9030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao handle = data_out.read() 9040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # start with 44th char so as not to get http header, we just need only xml 9060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, handle[44:]) 9070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Also test the content-length returned by handle_request 9090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Using the same test method inorder to avoid all the datapassing 9100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # boilerplate code. 9110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Test for bug: http://bugs.python.org/issue5040 9120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao content = handle[handle.find("<?xml"):] 9140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertEqual( 9160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao int(re.search('Content-Length: (\d+)', handle).group(1)), 9170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao len(content)) 9180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FakeSocket: 9210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self): 9230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.data = StringIO.StringIO() 9240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def send(self, buf): 9260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.data.write(buf) 9270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return len(buf) 9280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def sendall(self, buf): 9300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.data.write(buf) 9310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def getvalue(self): 9330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self.data.getvalue() 9340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def makefile(self, x='r', y=-1): 9360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise RuntimeError 9370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def close(self): 9390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 9400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FakeTransport(xmlrpclib.Transport): 9420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """A Transport instance that records instead of sending a request. 9430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao This class replaces the actual socket used by httplib with a 9450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao FakeSocket object that records the request. It doesn't provide a 9460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao response. 9470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 9480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def make_connection(self, host): 9500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn = xmlrpclib.Transport.make_connection(self, host) 9510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.sock = self.fake_socket = FakeSocket() 9520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return conn 9530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9540a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TransportSubclassTestCase(unittest.TestCase): 9550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def issue_request(self, transport_class): 9570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Return an HTTP request made via transport_class.""" 9580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao transport = transport_class() 9590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao proxy = xmlrpclib.ServerProxy("http://example.com/", 9600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao transport=transport) 9610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 9620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao proxy.pow(6, 8) 9630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except RuntimeError: 9640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return transport.fake_socket.getvalue() 9650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return None 9660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_custom_user_agent(self): 9680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class TestTransport(FakeTransport): 9690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def send_user_agent(self, conn): 9710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpclib.Transport.send_user_agent(self, conn) 9720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.putheader("X-Test", "test_custom_user_agent") 9730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao req = self.issue_request(TestTransport) 9750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIn("X-Test: test_custom_user_agent\r\n", req) 9760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_send_host(self): 9780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class TestTransport(FakeTransport): 9790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def send_host(self, conn, host): 9810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpclib.Transport.send_host(self, conn, host) 9820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.putheader("X-Test", "test_send_host") 9830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao req = self.issue_request(TestTransport) 9850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIn("X-Test: test_send_host\r\n", req) 9860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_send_request(self): 9880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class TestTransport(FakeTransport): 9890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def send_request(self, conn, url, body): 9910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpclib.Transport.send_request(self, conn, url, body) 9920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.putheader("X-Test", "test_send_request") 9930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao req = self.issue_request(TestTransport) 9950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIn("X-Test: test_send_request\r\n", req) 9960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 9970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def test_send_content(self): 9980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao class TestTransport(FakeTransport): 9990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def send_content(self, conn, body): 10010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao conn.putheader("X-Test", "test_send_content") 10020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpclib.Transport.send_content(self, conn, body) 10030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao req = self.issue_request(TestTransport) 10050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.assertIn("X-Test: test_send_content\r\n", req) 10060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao@test_support.reap_threads 10080a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main(): 10090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests = [XMLRPCTestCase, HelperTestCase, DateTimeTestCase, 10100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao BinaryTestCase, FaultTestCase, TransportSubclassTestCase] 10110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(SimpleServerTestCase) 10120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(KeepaliveServerTestCase1) 10130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(KeepaliveServerTestCase2) 10140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 10150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import gzip 10160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(GzipServerTestCase) 10170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except ImportError: 10180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass #gzip not supported in this build 10190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(MultiPathServerTestCase) 10200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(ServerProxyTestCase) 10210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(FailingServerTestCase) 10220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao xmlrpc_tests.append(CGIHandlerTestCase) 10230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao test_support.run_unittest(*xmlrpc_tests) 10250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 10260a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == "__main__": 10270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao test_main() 1028