blob: 39d3130c8a0f40d83e22eef2326d6a3a510b2cfc [file] [log] [blame]
Guido van Rossum24e4af82002-06-12 19:18:08 +00001#!/usr/bin/env python
Barry Warsawcf3d4b51997-01-03 20:03:32 +00002
Guido van Rossum24e4af82002-06-12 19:18:08 +00003import unittest
4import test_support
Barry Warsawcf3d4b51997-01-03 20:03:32 +00005
Barry Warsawcf3d4b51997-01-03 20:03:32 +00006import socket
Guido van Rossum24e4af82002-06-12 19:18:08 +00007import select
Barry Warsawcf3d4b51997-01-03 20:03:32 +00008import time
Guido van Rossum24e4af82002-06-12 19:18:08 +00009import thread, threading
10import Queue
Barry Warsawcf3d4b51997-01-03 20:03:32 +000011
Guido van Rossum24e4af82002-06-12 19:18:08 +000012PORT = 50007
13HOST = 'localhost'
14MSG = 'Michael Gilfix was here\n'
Barry Warsawcf3d4b51997-01-03 20:03:32 +000015
Guido van Rossum24e4af82002-06-12 19:18:08 +000016class SocketTCPTest(unittest.TestCase):
Barry Warsawcf3d4b51997-01-03 20:03:32 +000017
Guido van Rossum24e4af82002-06-12 19:18:08 +000018 def setUp(self):
19 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
20 self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
21 self.serv.bind((HOST, PORT))
22 self.serv.listen(1)
Barry Warsawcf3d4b51997-01-03 20:03:32 +000023
Guido van Rossum24e4af82002-06-12 19:18:08 +000024 def tearDown(self):
25 self.serv.close()
26 self.serv = None
Barry Warsawcf3d4b51997-01-03 20:03:32 +000027
Guido van Rossum24e4af82002-06-12 19:18:08 +000028class SocketUDPTest(unittest.TestCase):
29
30 def setUp(self):
31 self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
32 self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
33 self.serv.bind((HOST, PORT))
34
35 def tearDown(self):
36 self.serv.close()
37 self.serv = None
38
39class ThreadableTest:
40
41 def __init__(self):
42 # Swap the true setup function
43 self.__setUp = self.setUp
44 self.__tearDown = self.tearDown
45 self.setUp = self._setUp
46 self.tearDown = self._tearDown
47
48 def _setUp(self):
49 self.ready = threading.Event()
50 self.done = threading.Event()
51 self.queue = Queue.Queue(1)
52
53 # Do some munging to start the client test.
54 test_method = getattr(self, ''.join(('_', self._TestCase__testMethodName)))
55 self.client_thread = thread.start_new_thread(self.clientRun, (test_method, ))
56
57 self.__setUp()
58 self.ready.wait()
59
60 def _tearDown(self):
61 self.__tearDown()
62 self.done.wait()
63
64 if not self.queue.empty():
65 msg = self.queue.get()
66 self.fail(msg)
67
68 def clientRun(self, test_func):
69 self.ready.set()
70 self.clientSetUp()
71 if not callable(test_func):
72 raise TypeError, "test_func must be a callable function"
73 try:
74 test_func()
75 except Exception, strerror:
76 self.queue.put(strerror)
77 self.clientTearDown()
78
79 def clientSetUp(self):
80 raise NotImplementedError, "clientSetUp must be implemented."
81
82 def clientTearDown(self):
83 self.done.set()
84 thread.exit()
85
86class ThreadedTCPSocketTest(SocketTCPTest, ThreadableTest):
87
88 def __init__(self, methodName='runTest'):
89 SocketTCPTest.__init__(self, methodName=methodName)
90 ThreadableTest.__init__(self)
91
92 def clientSetUp(self):
93 self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
94
95 def clientTearDown(self):
96 self.cli.close()
97 self.cli = None
98 ThreadableTest.clientTearDown(self)
99
100class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest):
101
102 def __init__(self, methodName='runTest'):
103 SocketUDPTest.__init__(self, methodName=methodName)
104 ThreadableTest.__init__(self)
105
106 def clientSetUp(self):
107 self.cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
108
109class SocketConnectedTest(ThreadedTCPSocketTest):
110
111 def __init__(self, methodName='runTest'):
112 ThreadedTCPSocketTest.__init__(self, methodName=methodName)
113
114 def setUp(self):
115 ThreadedTCPSocketTest.setUp(self)
116 conn, addr = self.serv.accept()
117 self.cli_conn = conn
118
119 def tearDown(self):
120 self.cli_conn.close()
121 self.cli_conn = None
122 ThreadedTCPSocketTest.tearDown(self)
123
124 def clientSetUp(self):
125 ThreadedTCPSocketTest.clientSetUp(self)
126 self.cli.connect((HOST, PORT))
127 self.serv_conn = self.cli
128
129 def clientTearDown(self):
130 self.serv_conn.close()
131 self.serv_conn = None
132 ThreadedTCPSocketTest.clientTearDown(self)
133
134#######################################################################
135## Begin Tests
136
137class GeneralModuleTests(unittest.TestCase):
138
139 def testSocketError(self):
140 """Testing that socket module exceptions."""
141 def raise_error(*args, **kwargs):
142 raise socket.error
143 def raise_herror(*args, **kwargs):
144 raise socket.herror
145 def raise_gaierror(*args, **kwargs):
146 raise socket.gaierror
147 self.failUnlessRaises(socket.error, raise_error,
148 "Error raising socket exception.")
149 self.failUnlessRaises(socket.error, raise_herror,
150 "Error raising socket exception.")
151 self.failUnlessRaises(socket.error, raise_gaierror,
152 "Error raising socket exception.")
153
154 def testCrucialConstants(self):
155 """Testing for mission critical constants."""
156 socket.AF_INET
157 socket.SOCK_STREAM
158 socket.SOCK_DGRAM
159 socket.SOCK_RAW
160 socket.SOCK_RDM
161 socket.SOCK_SEQPACKET
162 socket.SOL_SOCKET
163 socket.SO_REUSEADDR
164
165 def testNonCrucialConstants(self):
166 """Testing for existance of non-crucial constants."""
167 for const in (
168 "AF_UNIX",
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000169
Guido van Rossum41360a41998-03-26 19:42:58 +0000170 "SO_DEBUG", "SO_ACCEPTCONN", "SO_REUSEADDR", "SO_KEEPALIVE",
171 "SO_DONTROUTE", "SO_BROADCAST", "SO_USELOOPBACK", "SO_LINGER",
172 "SO_OOBINLINE", "SO_REUSEPORT", "SO_SNDBUF", "SO_RCVBUF",
173 "SO_SNDLOWAT", "SO_RCVLOWAT", "SO_SNDTIMEO", "SO_RCVTIMEO",
174 "SO_ERROR", "SO_TYPE", "SOMAXCONN",
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000175
Guido van Rossum41360a41998-03-26 19:42:58 +0000176 "MSG_OOB", "MSG_PEEK", "MSG_DONTROUTE", "MSG_EOR",
177 "MSG_TRUNC", "MSG_CTRUNC", "MSG_WAITALL", "MSG_BTAG",
178 "MSG_ETAG",
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000179
Guido van Rossum41360a41998-03-26 19:42:58 +0000180 "SOL_SOCKET",
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000181
Guido van Rossum41360a41998-03-26 19:42:58 +0000182 "IPPROTO_IP", "IPPROTO_ICMP", "IPPROTO_IGMP",
183 "IPPROTO_GGP", "IPPROTO_TCP", "IPPROTO_EGP",
184 "IPPROTO_PUP", "IPPROTO_UDP", "IPPROTO_IDP",
185 "IPPROTO_HELLO", "IPPROTO_ND", "IPPROTO_TP",
186 "IPPROTO_XTP", "IPPROTO_EON", "IPPROTO_BIP",
187 "IPPROTO_RAW", "IPPROTO_MAX",
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000188
Guido van Rossum41360a41998-03-26 19:42:58 +0000189 "IPPORT_RESERVED", "IPPORT_USERRESERVED",
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000190
Guido van Rossum41360a41998-03-26 19:42:58 +0000191 "INADDR_ANY", "INADDR_BROADCAST", "INADDR_LOOPBACK",
192 "INADDR_UNSPEC_GROUP", "INADDR_ALLHOSTS_GROUP",
193 "INADDR_MAX_LOCAL_GROUP", "INADDR_NONE",
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000194
Guido van Rossum41360a41998-03-26 19:42:58 +0000195 "IP_OPTIONS", "IP_HDRINCL", "IP_TOS", "IP_TTL",
196 "IP_RECVOPTS", "IP_RECVRETOPTS", "IP_RECVDSTADDR",
197 "IP_RETOPTS", "IP_MULTICAST_IF", "IP_MULTICAST_TTL",
198 "IP_MULTICAST_LOOP", "IP_ADD_MEMBERSHIP",
199 "IP_DROP_MEMBERSHIP",
Guido van Rossum24e4af82002-06-12 19:18:08 +0000200 ):
201 try:
202 getattr(socket, const)
203 except AttributeError:
204 pass
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000205
Guido van Rossum24e4af82002-06-12 19:18:08 +0000206 def testHostnameRes(self):
207 """Testing hostname resolution mechanisms."""
208 hostname = socket.gethostname()
209 ip = socket.gethostbyname(hostname)
210 self.assert_(ip.find('.') >= 0, "Error resolving host to ip.")
211 hname, aliases, ipaddrs = socket.gethostbyaddr(ip)
212 all_host_names = [hname] + aliases
213 fqhn = socket.getfqdn()
214 if not fqhn in all_host_names:
215 self.fail("Error testing host resolution mechanisms.")
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000216
Guido van Rossum24e4af82002-06-12 19:18:08 +0000217 def testJavaRef(self):
218 """Testing reference count for getnameinfo."""
219 import sys
220 if not sys.platform.startswith('java'):
221 try:
222 # On some versions, this loses a reference
223 orig = sys.getrefcount(__name__)
224 socket.getnameinfo(__name__,0)
225 except SystemError:
226 if sys.getrefcount(__name__) <> orig:
227 self.fail("socket.getnameinfo loses a reference")
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000228
Guido van Rossum24e4af82002-06-12 19:18:08 +0000229 def testInterpreterCrash(self):
230 """Making sure getnameinfo doesn't crash the interpreter."""
231 try:
232 # On some versions, this crashes the interpreter.
233 socket.getnameinfo(('x', 0, 0, 0), 0)
234 except socket.error:
235 pass
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000236
Guido van Rossum24e4af82002-06-12 19:18:08 +0000237 def testGetServByName(self):
238 """Testing getservbyname."""
239 if hasattr(socket, 'getservbyname'):
240 socket.getservbyname('telnet', 'tcp')
241 try:
242 socket.getservbyname('telnet', 'udp')
243 except socket.error:
244 pass
245
246 def testSockName(self):
247 """Testing getsockname()."""
248 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
249 name = sock.getsockname()
250
251 def testGetSockOpt(self):
252 """Testing getsockopt()."""
253 # We know a socket should start without reuse==0
254 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
255 reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
Guido van Rossum733632a2002-06-12 20:46:49 +0000256 self.failIf(reuse != 0, "initial mode is reuse")
Guido van Rossum24e4af82002-06-12 19:18:08 +0000257
258 def testSetSockOpt(self):
259 """Testing setsockopt()."""
260 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
261 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
262 reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
Guido van Rossum733632a2002-06-12 20:46:49 +0000263 self.failIf(reuse == 0, "failed to set reuse mode")
Guido van Rossum24e4af82002-06-12 19:18:08 +0000264
265class BasicTCPTest(SocketConnectedTest):
266
267 def __init__(self, methodName='runTest'):
268 SocketConnectedTest.__init__(self, methodName=methodName)
269
270 def testRecv(self):
271 """Testing large receive over TCP."""
272 msg = self.cli_conn.recv(1024)
Guido van Rossum76489682002-06-12 20:38:30 +0000273 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000274
275 def _testRecv(self):
276 self.serv_conn.send(MSG)
277
278 def testOverFlowRecv(self):
279 """Testing receive in chunks over TCP."""
280 seg1 = self.cli_conn.recv(len(MSG) - 3)
281 seg2 = self.cli_conn.recv(1024)
282 msg = ''.join ((seg1, seg2))
Guido van Rossum76489682002-06-12 20:38:30 +0000283 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000284
285 def _testOverFlowRecv(self):
286 self.serv_conn.send(MSG)
287
288 def testRecvFrom(self):
289 """Testing large recvfrom() over TCP."""
290 msg, addr = self.cli_conn.recvfrom(1024)
291 hostname, port = addr
Guido van Rossum76489682002-06-12 20:38:30 +0000292 self.assertEqual(hostname, socket.gethostbyname('localhost'))
293 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000294
295 def _testRecvFrom(self):
296 self.serv_conn.send(MSG)
297
298 def testOverFlowRecvFrom(self):
299 """Testing recvfrom() in chunks over TCP."""
300 seg1, addr = self.cli_conn.recvfrom(len(MSG)-3)
301 seg2, addr = self.cli_conn.recvfrom(1024)
302 msg = ''.join((seg1, seg2))
303 hostname, port = addr
Guido van Rossum76489682002-06-12 20:38:30 +0000304 self.assertEqual(hostname, socket.gethostbyname('localhost'))
305 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000306
307 def _testOverFlowRecvFrom(self):
308 self.serv_conn.send(MSG)
309
310 def testSendAll(self):
311 """Testing sendall() with a 2048 byte string over TCP."""
312 while 1:
313 read = self.cli_conn.recv(1024)
314 if not read:
315 break
316 self.assert_(len(read) == 1024, "Error performing sendall.")
317 read = filter(lambda x: x == 'f', read)
318 self.assert_(len(read) == 1024, "Error performing sendall.")
319
320 def _testSendAll(self):
321 big_chunk = ''.join([ 'f' ] * 2048)
322 self.serv_conn.sendall(big_chunk)
323
324 def testFromFd(self):
325 """Testing fromfd()."""
Guido van Rossum6fb3d5e2002-06-12 20:48:59 +0000326 if not hasattr(socket, fromfd):
327 return # On Windows, this doesn't exist
Guido van Rossum24e4af82002-06-12 19:18:08 +0000328 fd = self.cli_conn.fileno()
329 sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
330 msg = sock.recv(1024)
Guido van Rossum76489682002-06-12 20:38:30 +0000331 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000332
333 def _testFromFd(self):
334 self.serv_conn.send(MSG)
335
336 def testShutdown(self):
337 """Testing shutdown()."""
338 msg = self.cli_conn.recv(1024)
Guido van Rossum76489682002-06-12 20:38:30 +0000339 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000340
341 def _testShutdown(self):
342 self.serv_conn.send(MSG)
343 self.serv_conn.shutdown(2)
344
345class BasicUDPTest(ThreadedUDPSocketTest):
346
347 def __init__(self, methodName='runTest'):
348 ThreadedUDPSocketTest.__init__(self, methodName=methodName)
349
350 def testSendtoAndRecv(self):
351 """Testing sendto() and Recv() over UDP."""
352 msg = self.serv.recv(len(MSG))
Guido van Rossum76489682002-06-12 20:38:30 +0000353 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000354
355 def _testSendtoAndRecv(self):
356 self.cli.sendto(MSG, 0, (HOST, PORT))
357
358 def testRecvfrom(self):
359 """Testing recfrom() over UDP."""
360 msg, addr = self.serv.recvfrom(len(MSG))
361 hostname, port = addr
Guido van Rossum76489682002-06-12 20:38:30 +0000362 self.assertEqual(hostname, socket.gethostbyname('localhost'))
363 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000364
365 def _testRecvfrom(self):
366 self.cli.sendto(MSG, 0, (HOST, PORT))
367
368class NonBlockingTCPTests(ThreadedTCPSocketTest):
369
370 def __init__(self, methodName='runTest'):
371 ThreadedTCPSocketTest.__init__(self, methodName=methodName)
372
373 def testSetBlocking(self):
374 """Testing whether set blocking works."""
375 self.serv.setblocking(0)
376 start = time.time()
377 try:
378 self.serv.accept()
379 except socket.error:
380 pass
381 end = time.time()
382 self.assert_((end - start) < 1.0, "Error setting non-blocking mode.")
383
384 def _testSetBlocking(self):
Barry Warsaw6870bba2001-03-23 17:40:16 +0000385 pass
Barry Warsawcf3d4b51997-01-03 20:03:32 +0000386
Guido van Rossum24e4af82002-06-12 19:18:08 +0000387 def testAccept(self):
388 """Testing non-blocking accept."""
389 self.serv.setblocking(0)
Guido van Rossum41360a41998-03-26 19:42:58 +0000390 try:
Guido van Rossum24e4af82002-06-12 19:18:08 +0000391 conn, addr = self.serv.accept()
392 except socket.error:
393 pass
394 else:
395 self.fail("Error trying to do non-blocking accept.")
396 read, write, err = select.select([self.serv], [], [])
397 if self.serv in read:
398 conn, addr = self.serv.accept()
399 else:
400 self.fail("Error trying to do accept after select.")
Guido van Rossum67f7a382002-06-06 21:08:16 +0000401
Guido van Rossum24e4af82002-06-12 19:18:08 +0000402 def _testAccept(self):
403 time.sleep(1)
404 self.cli.connect((HOST, PORT))
405
406 def testConnect(self):
407 """Testing non-blocking connect."""
408 time.sleep(1)
409 conn, addr = self.serv.accept()
410
411 def _testConnect(self):
412 self.cli.setblocking(0)
413 try:
414 self.cli.connect((HOST, PORT))
415 except socket.error:
416 pass
417 else:
418 self.fail("Error trying to do non-blocking connect.")
419 read, write, err = select.select([self.cli], [], [])
420 if self.cli in read:
421 self.cli.connect((HOST, PORT))
422 else:
423 self.fail("Error trying to do connect after select.")
424
425 def testRecv(self):
426 """Testing non-blocking recv."""
427 conn, addr = self.serv.accept()
428 conn.setblocking(0)
429 try:
430 msg = conn.recv(len(MSG))
431 except socket.error:
432 pass
433 else:
434 self.fail("Error trying to do non-blocking recv.")
435 read, write, err = select.select([conn], [], [])
436 if conn in read:
437 msg = conn.recv(len(MSG))
Guido van Rossum76489682002-06-12 20:38:30 +0000438 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000439 else:
440 self.fail("Error during select call to non-blocking socket.")
441
442 def _testRecv(self):
443 self.cli.connect((HOST, PORT))
444 time.sleep(1)
445 self.cli.send(MSG)
446
447class FileObjectClassTestCase(SocketConnectedTest):
448
449 def __init__(self, methodName='runTest'):
450 SocketConnectedTest.__init__(self, methodName=methodName)
451
452 def setUp(self):
453 SocketConnectedTest.setUp(self)
454 self.serv_file = socket._fileobject(self.cli_conn, 'rb', 8192)
455
456 def tearDown(self):
457 self.serv_file.close()
458 self.serv_file = None
459 SocketConnectedTest.tearDown(self)
460
461 def clientSetUp(self):
462 SocketConnectedTest.clientSetUp(self)
463 self.cli_file = socket._fileobject(self.serv_conn, 'rb', 8192)
464
465 def clientTearDown(self):
466 self.cli_file.close()
467 self.cli_file = None
468 SocketConnectedTest.clientTearDown(self)
469
470 def testSmallRead(self):
471 """Performing small file read test."""
472 first_seg = self.serv_file.read(len(MSG)-3)
473 second_seg = self.serv_file.read(3)
474 msg = ''.join((first_seg, second_seg))
Guido van Rossum76489682002-06-12 20:38:30 +0000475 self.assertEqual(msg, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000476
477 def _testSmallRead(self):
478 self.cli_file.write(MSG)
479 self.cli_file.flush()
480
481 def testUnbufferedRead(self):
482 """Performing unbuffered file read test."""
483 buf = ''
484 while 1:
485 char = self.serv_file.read(1)
Guido van Rossum76489682002-06-12 20:38:30 +0000486 self.failIf(not char)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000487 buf += char
488 if buf == MSG:
489 break
490
491 def _testUnbufferedRead(self):
492 self.cli_file.write(MSG)
493 self.cli_file.flush()
494
495 def testReadline(self):
496 """Performing file readline test."""
497 line = self.serv_file.readline()
Guido van Rossum76489682002-06-12 20:38:30 +0000498 self.assertEqual(line, MSG)
Guido van Rossum24e4af82002-06-12 19:18:08 +0000499
500 def _testReadline(self):
501 self.cli_file.write(MSG)
502 self.cli_file.flush()
503
504def test_main():
505 suite = unittest.TestSuite()
506 suite.addTest(unittest.makeSuite(GeneralModuleTests))
507 suite.addTest(unittest.makeSuite(BasicTCPTest))
508 suite.addTest(unittest.makeSuite(BasicUDPTest))
509 suite.addTest(unittest.makeSuite(NonBlockingTCPTests))
510 suite.addTest(unittest.makeSuite(FileObjectClassTestCase))
511 test_support.run_suite(suite)
512
513if __name__ == "__main__":
514 test_main()