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&amp;b")
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(xmlrpclib.escape("a<b"), "a&lt;b")
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(xmlrpclib.escape("a>b"), "a&gt;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