blob: 4a15de53a55a58f92f91348d172d4de47a2312a6 [file] [log] [blame]
Guido van Rossumb5a755e2007-07-18 18:15:48 +00001import base64
Fred Drakeba613c32005-02-10 18:33:30 +00002import datetime
Skip Montanaro3e7bba92001-10-19 16:06:52 +00003import sys
Guido van Rossumb5a755e2007-07-18 18:15:48 +00004import time
Skip Montanaro419abda2001-10-01 17:47:44 +00005import unittest
6import xmlrpclib
Guido van Rossumaf554a02007-08-16 23:48:43 +00007import SimpleXMLRPCServer
8import threading
Barry Warsaw04f357c2002-07-23 19:04:11 +00009from test import test_support
Skip Montanaro419abda2001-10-01 17:47:44 +000010
11alist = [{'astring': 'foo@bar.baz.spam',
12 'afloat': 7283.43,
Skip Montanaro3e7bba92001-10-19 16:06:52 +000013 'anint': 2**20,
Guido van Rossume2a383d2007-01-15 16:59:06 +000014 'ashortlong': 2,
Skip Montanaro419abda2001-10-01 17:47:44 +000015 'anotherlist': ['.zyx.41'],
16 'abase64': xmlrpclib.Binary("my dog has fleas"),
Guido van Rossume7ba4952007-06-06 23:52:48 +000017 'boolean': False,
Guido van Rossumef87d6e2007-05-02 19:09:54 +000018 'unicode': '\u4000\u6000\u8000',
19 'ukey\u4000': 'regular value',
Fred Drakeba613c32005-02-10 18:33:30 +000020 'datetime1': xmlrpclib.DateTime('20050210T11:41:23'),
21 'datetime2': xmlrpclib.DateTime(
Guido van Rossumcd16bf62007-06-13 18:07:49 +000022 (2005, 2, 10, 11, 41, 23, 0, 1, -1)),
Fred Drakeba613c32005-02-10 18:33:30 +000023 'datetime3': xmlrpclib.DateTime(
Guido van Rossumcd16bf62007-06-13 18:07:49 +000024 datetime.datetime(2005, 2, 10, 11, 41, 23)),
Guido van Rossumb5a755e2007-07-18 18:15:48 +000025 'datetime4': xmlrpclib.DateTime(
26 datetime.date(2005, 2, 10)),
27 'datetime5': xmlrpclib.DateTime(
28 datetime.time(11, 41, 23)),
Skip Montanaro419abda2001-10-01 17:47:44 +000029 }]
30
31class XMLRPCTestCase(unittest.TestCase):
32
33 def test_dump_load(self):
34 self.assertEquals(alist,
35 xmlrpclib.loads(xmlrpclib.dumps((alist,)))[0][0])
36
Fred Drakeba613c32005-02-10 18:33:30 +000037 def test_dump_bare_datetime(self):
Skip Montanaro174dd222005-05-14 20:54:16 +000038 # This checks that an unwrapped datetime.date object can be handled
39 # by the marshalling code. This can't be done via test_dump_load()
40 # since with use_datetime set to 1 the unmarshaller would create
41 # datetime objects for the 'datetime[123]' keys as well
Guido van Rossumcd16bf62007-06-13 18:07:49 +000042 dt = datetime.datetime(2005, 2, 10, 11, 41, 23)
Fred Drakeba613c32005-02-10 18:33:30 +000043 s = xmlrpclib.dumps((dt,))
Skip Montanaro174dd222005-05-14 20:54:16 +000044 (newdt,), m = xmlrpclib.loads(s, use_datetime=1)
45 self.assertEquals(newdt, dt)
Fred Drakeba613c32005-02-10 18:33:30 +000046 self.assertEquals(m, None)
47
Skip Montanaro174dd222005-05-14 20:54:16 +000048 (newdt,), m = xmlrpclib.loads(s, use_datetime=0)
49 self.assertEquals(newdt, xmlrpclib.DateTime('20050210T11:41:23'))
50
51 def test_dump_bare_date(self):
52 # This checks that an unwrapped datetime.date object can be handled
53 # by the marshalling code. This can't be done via test_dump_load()
54 # since the unmarshaller produces a datetime object
Guido van Rossumcd16bf62007-06-13 18:07:49 +000055 d = datetime.datetime(2005, 2, 10, 11, 41, 23).date()
Skip Montanaro174dd222005-05-14 20:54:16 +000056 s = xmlrpclib.dumps((d,))
57 (newd,), m = xmlrpclib.loads(s, use_datetime=1)
58 self.assertEquals(newd.date(), d)
59 self.assertEquals(newd.time(), datetime.time(0, 0, 0))
60 self.assertEquals(m, None)
61
62 (newdt,), m = xmlrpclib.loads(s, use_datetime=0)
63 self.assertEquals(newdt, xmlrpclib.DateTime('20050210T00:00:00'))
64
65 def test_dump_bare_time(self):
66 # This checks that an unwrapped datetime.time object can be handled
67 # by the marshalling code. This can't be done via test_dump_load()
68 # since the unmarshaller produces a datetime object
Guido van Rossumcd16bf62007-06-13 18:07:49 +000069 t = datetime.datetime(2005, 2, 10, 11, 41, 23).time()
Skip Montanaro174dd222005-05-14 20:54:16 +000070 s = xmlrpclib.dumps((t,))
71 (newt,), m = xmlrpclib.loads(s, use_datetime=1)
72 today = datetime.datetime.now().date().strftime("%Y%m%d")
73 self.assertEquals(newt.time(), t)
74 self.assertEquals(newt.date(), datetime.datetime.now().date())
75 self.assertEquals(m, None)
76
77 (newdt,), m = xmlrpclib.loads(s, use_datetime=0)
78 self.assertEquals(newdt, xmlrpclib.DateTime('%sT11:41:23'%today))
79
Andrew M. Kuchlingbdb39012005-12-04 19:11:17 +000080 def test_bug_1164912 (self):
81 d = xmlrpclib.DateTime()
Tim Peters536cf992005-12-25 23:18:31 +000082 ((new_d,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((d,),
Andrew M. Kuchlingbdb39012005-12-04 19:11:17 +000083 methodresponse=True))
84 self.assert_(isinstance(new_d.value, str))
85
86 # Check that the output of dumps() is still an 8-bit string
87 s = xmlrpclib.dumps((new_d,), methodresponse=True)
88 self.assert_(isinstance(s, str))
89
Thomas Wouters89f507f2006-12-13 04:49:30 +000090 def test_newstyle_class(self):
91 class T(object):
92 pass
93 t = T()
94 t.x = 100
95 t.y = "Hello"
96 ((t2,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((t,)))
97 self.assertEquals(t2, t.__dict__)
98
Skip Montanaro3e7bba92001-10-19 16:06:52 +000099 def test_dump_big_long(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000100 self.assertRaises(OverflowError, xmlrpclib.dumps, (2**99,))
Skip Montanaro3e7bba92001-10-19 16:06:52 +0000101
102 def test_dump_bad_dict(self):
103 self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},))
104
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000105 def test_dump_recursive_seq(self):
106 l = [1,2,3]
107 t = [3,4,5,l]
108 l.append(t)
109 self.assertRaises(TypeError, xmlrpclib.dumps, (l,))
110
111 def test_dump_recursive_dict(self):
112 d = {'1':1, '2':1}
113 t = {'3':3, 'd':d}
114 d['t'] = t
115 self.assertRaises(TypeError, xmlrpclib.dumps, (d,))
116
Skip Montanaro3e7bba92001-10-19 16:06:52 +0000117 def test_dump_big_int(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000118 if sys.maxint > 2**31-1:
Skip Montanaro3e7bba92001-10-19 16:06:52 +0000119 self.assertRaises(OverflowError, xmlrpclib.dumps,
Guido van Rossume2a383d2007-01-15 16:59:06 +0000120 (int(2**34),))
Skip Montanaro3e7bba92001-10-19 16:06:52 +0000121
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000122 xmlrpclib.dumps((xmlrpclib.MAXINT, xmlrpclib.MININT))
123 self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MAXINT+1,))
124 self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MININT-1,))
125
126 def dummy_write(s):
127 pass
128
129 m = xmlrpclib.Marshaller()
130 m.dump_int(xmlrpclib.MAXINT, dummy_write)
131 m.dump_int(xmlrpclib.MININT, dummy_write)
132 self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MAXINT+1, dummy_write)
133 self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MININT-1, dummy_write)
134
135
Andrew M. Kuchling0b852032003-04-25 00:27:24 +0000136 def test_dump_none(self):
137 value = alist + [None]
138 arg1 = (alist + [None],)
139 strg = xmlrpclib.dumps(arg1, allow_none=True)
140 self.assertEquals(value,
141 xmlrpclib.loads(strg)[0][0])
142 self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
143
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000144
145class HelperTestCase(unittest.TestCase):
146 def test_escape(self):
147 self.assertEqual(xmlrpclib.escape("a&b"), "a&b")
148 self.assertEqual(xmlrpclib.escape("a<b"), "a&lt;b")
149 self.assertEqual(xmlrpclib.escape("a>b"), "a&gt;b")
150
151class FaultTestCase(unittest.TestCase):
152 def test_repr(self):
153 f = xmlrpclib.Fault(42, 'Test Fault')
154 self.assertEqual(repr(f), "<Fault 42: 'Test Fault'>")
155 self.assertEqual(repr(f), str(f))
156
157 def test_dump_fault(self):
158 f = xmlrpclib.Fault(42, 'Test Fault')
159 s = xmlrpclib.dumps((f,))
160 (newf,), m = xmlrpclib.loads(s)
161 self.assertEquals(newf, {'faultCode': 42, 'faultString': 'Test Fault'})
162 self.assertEquals(m, None)
163
164 s = xmlrpclib.Marshaller().dumps(f)
165 self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s)
166
167
168class DateTimeTestCase(unittest.TestCase):
169 def test_default(self):
170 t = xmlrpclib.DateTime()
171
172 def test_time(self):
173 d = 1181399930.036952
174 t = xmlrpclib.DateTime(d)
175 self.assertEqual(str(t), time.strftime("%Y%m%dT%H:%M:%S", time.localtime(d)))
176
177 def test_time_tuple(self):
178 d = (2007,6,9,10,38,50,5,160,0)
179 t = xmlrpclib.DateTime(d)
180 self.assertEqual(str(t), '20070609T10:38:50')
181
182 def test_time_struct(self):
183 d = time.localtime(1181399930.036952)
184 t = xmlrpclib.DateTime(d)
185 self.assertEqual(str(t), time.strftime("%Y%m%dT%H:%M:%S", d))
186
187 def test_datetime_datetime(self):
188 d = datetime.datetime(2007,1,2,3,4,5)
189 t = xmlrpclib.DateTime(d)
190 self.assertEqual(str(t), '20070102T03:04:05')
191
192 def test_datetime_date(self):
193 d = datetime.date(2007,9,8)
194 t = xmlrpclib.DateTime(d)
195 self.assertEqual(str(t), '20070908T00:00:00')
196
197 def test_datetime_time(self):
198 d = datetime.time(13,17,19)
199 # allow for date rollover by checking today's or tomorrow's dates
200 dd1 = datetime.datetime.now().date()
201 dd2 = dd1 + datetime.timedelta(days=1)
202 vals = (dd1.strftime('%Y%m%dT13:17:19'),
203 dd2.strftime('%Y%m%dT13:17:19'))
204 t = xmlrpclib.DateTime(d)
205 self.assertEqual(str(t) in vals, True)
206
207 def test_repr(self):
208 d = datetime.datetime(2007,1,2,3,4,5)
209 t = xmlrpclib.DateTime(d)
210 val ="<DateTime '20070102T03:04:05' at %x>" % id(t)
211 self.assertEqual(repr(t), val)
212
213 def test_decode(self):
214 d = ' 20070908T07:11:13 '
215 t1 = xmlrpclib.DateTime()
216 t1.decode(d)
217 tref = xmlrpclib.DateTime(datetime.datetime(2007,9,8,7,11,13))
218 self.assertEqual(t1, tref)
219
220 t2 = xmlrpclib._datetime(d)
221 self.assertEqual(t1, tref)
222
223class BinaryTestCase(unittest.TestCase):
224 def test_default(self):
225 t = xmlrpclib.Binary()
226 self.assertEqual(str(t), '')
227
228 def test_string(self):
229 d = '\x01\x02\x03abc123\xff\xfe'
230 t = xmlrpclib.Binary(d)
231 self.assertEqual(str(t), d)
232
233 def test_decode(self):
234 d = '\x01\x02\x03abc123\xff\xfe'
235 de = base64.encodestring(d)
236 t1 = xmlrpclib.Binary()
237 t1.decode(de)
238 self.assertEqual(str(t1), d)
239
240 t2 = xmlrpclib._binary(de)
241 self.assertEqual(str(t2), d)
242
243
Guido van Rossumaf554a02007-08-16 23:48:43 +0000244PORT = None
Skip Montanaro419abda2001-10-01 17:47:44 +0000245
Guido van Rossumaf554a02007-08-16 23:48:43 +0000246def http_server(evt, numrequests):
247 class TestInstanceClass:
248 def div(self, x, y):
249 '''This is the div function'''
250 return x // y
251
252
253 serv = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 0),
254 logRequests=False, bind_and_activate=False)
255
256 try:
257 serv.socket.settimeout(3)
258 serv.server_bind()
259 global PORT
260 PORT = serv.socket.getsockname()[1]
261 serv.server_activate()
262 serv.register_introspection_functions()
263 serv.register_multicall_functions()
264 serv.register_function(pow)
265 serv.register_function(lambda x,y: x+y, 'add')
266 serv.register_instance(TestInstanceClass())
267
268 # handle up to 'numrequests' requests
269 while numrequests > 0:
270 serv.handle_request()
271 numrequests -= 1
272
273 except socket.timeout:
274 pass
275 finally:
276 serv.socket.close()
277 PORT = None
278 evt.set()
279
280
281class HTTPTestCase(unittest.TestCase):
282 def setUp(self):
283 self.evt = threading.Event()
284 # start server thread to handle just one request
285 threading.Thread(target=http_server, args=(self.evt,2)).start()
286
287 # wait for port to be assigned to server
288 n = 1000
289 while n > 0 and PORT is None:
290 time.sleep(0.001)
291 n -= 1
292
293 time.sleep(0.5)
294
295 def tearDown(self):
296 # wait on the server thread to terminate
297 self.evt.wait()
298
299 def test_simple1(self):
300 p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
301 self.assertEqual(p.pow(6,8), 6**8)
302
303 def test_introspection1(self):
304 p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
305 meth = p.system.listMethods()
306 expected_methods = set(['pow', 'div', 'add', 'system.listMethods',
307 'system.methodHelp', 'system.methodSignature', 'system.multicall'])
308 self.assertEqual(set(meth), expected_methods)
309
310 def test_introspection2(self):
311 p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
312 divhelp = p.system.methodHelp('div')
313 self.assertEqual(divhelp, 'This is the div function')
314
315 def test_introspection3(self):
316 # the SimpleXMLRPCServer doesn't support signatures, but
317 # at least check that we can try
318 p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
319 divsig = p.system.methodSignature('div')
320 self.assertEqual(divsig, 'signatures not supported')
321
322 def test_multicall(self):
323 p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
324 multicall = xmlrpclib.MultiCall(p)
325 multicall.add(2,3)
326 multicall.pow(6,8)
327 multicall.div(127,42)
328 add_result, pow_result, div_result = multicall()
329 self.assertEqual(add_result, 2+3)
330 self.assertEqual(pow_result, 6**8)
331 self.assertEqual(div_result, 127//42)
332
333
334def test_main():
335 xmlrpc_tests = [XMLRPCTestCase, HelperTestCase, DateTimeTestCase,
336 BinaryTestCase, FaultTestCase]
337
338 # The test cases against a SimpleXMLRPCServer raise a socket error
339 # 10035 (WSAEWOULDBLOCK) in the server thread handle_request call when
340 # run on Windows. This only happens on the first test to run, but it
341 # fails every time and so these tests are skipped on win32 platforms.
342 if sys.platform != 'win32':
343 xmlrpc_tests.append(HTTPTestCase)
344
345 test_support.run_unittest(*xmlrpc_tests)
Skip Montanaro419abda2001-10-01 17:47:44 +0000346
347if __name__ == "__main__":
348 test_main()