11 from test
import test_support
12 from test
.test_support
import TESTFN
, run_unittest
, unlink
13 from StringIO
import StringIO
20 HOST
= test_support
.HOST
34 self
.socket
= dummysocket()
43 def handle_read_event(self
):
44 raise asyncore
.ExitNow()
46 handle_write_event
= handle_read_event
47 handle_close
= handle_read_event
48 handle_expt_event
= handle_read_event
52 self
.error_handled
= False
54 def handle_read_event(self
):
57 handle_write_event
= handle_read_event
58 handle_close
= handle_read_event
59 handle_expt_event
= handle_read_event
61 def handle_error(self
):
62 self
.error_handled
= True
64 # used when testing senders; just collects what it gets until newline is sent
65 def capture_server(evt
, buf
, serv
):
68 conn
, addr
= serv
.accept()
69 except socket
.timeout
:
74 r
, w
, e
= select
.select([conn
], [], [])
77 # keep everything except for the newline terminator
78 buf
.write(data
.replace('\n', ''))
90 class HelperFunctionTests(unittest
.TestCase
):
91 def test_readwriteexc(self
):
92 # Check exception handling behavior of read, write and _exception
94 # check that ExitNow exceptions in the object handler method
95 # bubbles all the way up through asyncore read/write/_exception calls
97 self
.assertRaises(asyncore
.ExitNow
, asyncore
.read
, tr1
)
98 self
.assertRaises(asyncore
.ExitNow
, asyncore
.write
, tr1
)
99 self
.assertRaises(asyncore
.ExitNow
, asyncore
._exception
, tr1
)
101 # check that an exception other than ExitNow in the object handler
102 # method causes the handle_error method to get called
103 tr2
= crashingdummy()
105 self
.assertEqual(tr2
.error_handled
, True)
107 tr2
= crashingdummy()
109 self
.assertEqual(tr2
.error_handled
, True)
111 tr2
= crashingdummy()
112 asyncore
._exception
(tr2
)
113 self
.assertEqual(tr2
.error_handled
, True)
115 # asyncore.readwrite uses constants in the select module that
116 # are not present in Windows systems (see this thread:
117 # http://mail.python.org/pipermail/python-list/2001-October/109973.html)
118 # These constants should be present as long as poll is available
120 @unittest.skipUnless(hasattr(select
, 'poll'), 'select.poll required')
121 def test_readwrite(self
):
122 # Check that correct methods are called by readwrite()
124 attributes
= ('read', 'expt', 'write', 'closed', 'error_handled')
127 (select
.POLLIN
, 'read'),
128 (select
.POLLPRI
, 'expt'),
129 (select
.POLLOUT
, 'write'),
130 (select
.POLLERR
, 'closed'),
131 (select
.POLLHUP
, 'closed'),
132 (select
.POLLNVAL
, 'closed'),
141 self
.error_handled
= False
143 def handle_read_event(self
):
146 def handle_write_event(self
):
149 def handle_close(self
):
152 def handle_expt_event(self
):
155 def handle_error(self
):
156 self
.error_handled
= True
158 for flag
, expectedattr
in expected
:
160 self
.assertEqual(getattr(tobj
, expectedattr
), False)
161 asyncore
.readwrite(tobj
, flag
)
163 # Only the attribute modified by the routine we expect to be
164 # called should be True.
165 for attr
in attributes
:
166 self
.assertEqual(getattr(tobj
, attr
), attr
==expectedattr
)
168 # check that ExitNow exceptions in the object handler method
169 # bubbles all the way up through asyncore readwrite call
171 self
.assertRaises(asyncore
.ExitNow
, asyncore
.readwrite
, tr1
, flag
)
173 # check that an exception other than ExitNow in the object handler
174 # method causes the handle_error method to get called
175 tr2
= crashingdummy()
176 self
.assertEqual(tr2
.error_handled
, False)
177 asyncore
.readwrite(tr2
, flag
)
178 self
.assertEqual(tr2
.error_handled
, True)
180 def test_closeall(self
):
181 self
.closeall_check(False)
183 def test_closeall_default(self
):
184 self
.closeall_check(True)
186 def closeall_check(self
, usedefault
):
187 # Check that close_all() closes everything in a given map
194 self
.assertEqual(c
.socket
.closed
, False)
198 socketmap
= asyncore
.socket_map
200 asyncore
.socket_map
= testmap
203 testmap
, asyncore
.socket_map
= asyncore
.socket_map
, socketmap
205 asyncore
.close_all(testmap
)
207 self
.assertEqual(len(testmap
), 0)
210 self
.assertEqual(c
.socket
.closed
, True)
212 def test_compact_traceback(self
):
214 raise Exception("I don't like spam!")
216 real_t
, real_v
, real_tb
= sys
.exc_info()
217 r
= asyncore
.compact_traceback()
219 self
.fail("Expected exception")
221 (f
, function
, line
), t
, v
, info
= r
222 self
.assertEqual(os
.path
.split(f
)[-1], 'test_asyncore.py')
223 self
.assertEqual(function
, 'test_compact_traceback')
224 self
.assertEqual(t
, real_t
)
225 self
.assertEqual(v
, real_v
)
226 self
.assertEqual(info
, '[%s|%s|%s]' % (f
, function
, line
))
229 class DispatcherTests(unittest
.TestCase
):
236 def test_basic(self
):
237 d
= asyncore
.dispatcher()
238 self
.assertEqual(d
.readable(), True)
239 self
.assertEqual(d
.writable(), True)
242 d
= asyncore
.dispatcher()
243 self
.assertEqual(repr(d
), '<asyncore.dispatcher at %#x>' % id(d
))
246 d
= asyncore
.dispatcher()
248 # capture output of dispatcher.log() (to stderr)
251 l1
= "Lovely spam! Wonderful spam!"
252 l2
= "I don't like spam!"
260 lines
= fp
.getvalue().splitlines()
261 self
.assertEqual(lines
, ['log: %s' % l1
, 'log: %s' % l2
])
263 def test_log_info(self
):
264 d
= asyncore
.dispatcher()
266 # capture output of dispatcher.log_info() (to stdout via print)
269 l1
= "Have you got anything without spam?"
270 l2
= "Why can't she have egg bacon spam and sausage?"
271 l3
= "THAT'S got spam in it!"
274 d
.log_info(l1
, 'EGGS')
276 d
.log_info(l3
, 'SPAM')
280 lines
= fp
.getvalue().splitlines()
281 expected
= ['EGGS: %s' % l1
, 'info: %s' % l2
, 'SPAM: %s' % l3
]
283 self
.assertEqual(lines
, expected
)
285 def test_unhandled(self
):
286 d
= asyncore
.dispatcher()
287 d
.ignore_log_types
= ()
289 # capture output of dispatcher.log_info() (to stdout via print)
302 lines
= fp
.getvalue().splitlines()
303 expected
= ['warning: unhandled incoming priority event',
304 'warning: unhandled read event',
305 'warning: unhandled write event',
306 'warning: unhandled connect event',
307 'warning: unhandled accept event']
308 self
.assertEqual(lines
, expected
)
310 def test_issue_8594(self
):
311 # XXX - this test is supposed to be removed in next major Python
313 d
= asyncore
.dispatcher(socket
.socket())
314 # make sure the error message no longer refers to the socket
315 # object but the dispatcher instance instead
316 self
.assertRaisesRegexp(AttributeError, 'dispatcher instance',
318 # cheap inheritance with the underlying socket is supposed
319 # to still work but a DeprecationWarning is expected
320 with warnings
.catch_warnings(record
=True) as w
:
321 warnings
.simplefilter("always")
323 self
.assertEqual(family
, socket
.AF_INET
)
324 self
.assertEqual(len(w
), 1)
325 self
.assertTrue(issubclass(w
[0].category
, DeprecationWarning))
327 def test_strerror(self
):
328 # refers to bug #8573
329 err
= asyncore
._strerror
(errno
.EPERM
)
330 if hasattr(os
, 'strerror'):
331 self
.assertEqual(err
, os
.strerror(errno
.EPERM
))
332 err
= asyncore
._strerror
(-1)
333 self
.assertTrue(err
!= "")
336 class dispatcherwithsend_noread(asyncore
.dispatcher_with_send
):
340 def handle_connect(self
):
343 class DispatcherWithSendTests(unittest
.TestCase
):
352 @unittest.skipUnless(threading
, 'Threading required for this test.')
353 @test_support.reap_threads
355 evt
= threading
.Event()
356 sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
358 port
= test_support
.bind_port(sock
)
361 args
= (evt
, cap
, sock
)
362 t
= threading
.Thread(target
=capture_server
, args
=args
)
365 # wait a little longer for the server to initialize (it sometimes
366 # refuses connections on slow machines without this wait)
369 data
= "Suppose there isn't a 16-ton weight?"
370 d
= dispatcherwithsend_noread()
371 d
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
372 d
.connect((HOST
, port
))
374 # give time for socket to connect
382 while d
.out_buffer
and n
> 0:
388 self
.assertEqual(cap
.getvalue(), data
*2)
393 class DispatcherWithSendTests_UsePoll(DispatcherWithSendTests
):
396 @unittest.skipUnless(hasattr(asyncore
, 'file_wrapper'),
397 'asyncore.file_wrapper required')
398 class FileWrapperTest(unittest
.TestCase
):
400 self
.d
= "It's not dead, it's sleeping!"
401 with
file(TESTFN
, 'w') as h
:
408 fd
= os
.open(TESTFN
, os
.O_RDONLY
)
409 w
= asyncore
.file_wrapper(fd
)
412 self
.assertNotEqual(w
.fd
, fd
)
413 self
.assertNotEqual(w
.fileno(), fd
)
414 self
.assertEqual(w
.recv(13), "It's not dead")
415 self
.assertEqual(w
.read(6), ", it's")
417 self
.assertRaises(OSError, w
.read
, 1)
422 d2
= "I want to buy some cheese."
423 fd
= os
.open(TESTFN
, os
.O_WRONLY | os
.O_APPEND
)
424 w
= asyncore
.file_wrapper(fd
)
430 self
.assertEqual(file(TESTFN
).read(), self
.d
+ d1
+ d2
)
432 @unittest.skipUnless(hasattr(asyncore
, 'file_dispatcher'),
433 'asyncore.file_dispatcher required')
434 def test_dispatcher(self
):
435 fd
= os
.open(TESTFN
, os
.O_RDONLY
)
437 class FileDispatcher(asyncore
.file_dispatcher
):
438 def handle_read(self
):
439 data
.append(self
.recv(29))
440 s
= FileDispatcher(fd
)
442 asyncore
.loop(timeout
=0.01, use_poll
=True, count
=2)
443 self
.assertEqual(b
"".join(data
), self
.d
)
446 class BaseTestHandler(asyncore
.dispatcher
):
448 def __init__(self
, sock
=None):
449 asyncore
.dispatcher
.__init
__(self
, sock
)
452 def handle_accept(self
):
453 raise Exception("handle_accept not supposed to be called")
455 def handle_connect(self
):
456 raise Exception("handle_connect not supposed to be called")
458 def handle_expt(self
):
459 raise Exception("handle_expt not supposed to be called")
461 def handle_close(self
):
462 raise Exception("handle_close not supposed to be called")
464 def handle_error(self
):
468 class TCPServer(asyncore
.dispatcher
):
469 """A server which listens on an address and dispatches the
470 connection to a handler.
473 def __init__(self
, handler
=BaseTestHandler
, host
=HOST
, port
=0):
474 asyncore
.dispatcher
.__init
__(self
)
475 self
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
476 self
.set_reuse_addr()
477 self
.bind((host
, port
))
479 self
.handler
= handler
483 return self
.socket
.getsockname()[:2]
485 def handle_accept(self
):
486 sock
, addr
= self
.accept()
489 def handle_error(self
):
493 class BaseClient(BaseTestHandler
):
495 def __init__(self
, address
):
496 BaseTestHandler
.__init
__(self
)
497 self
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
498 self
.connect(address
)
500 def handle_connect(self
):
504 class BaseTestAPI(unittest
.TestCase
):
509 def loop_waiting_for_flag(self
, instance
, timeout
=5):
510 timeout
= float(timeout
) / 100
512 while asyncore
.socket_map
and count
> 0:
513 asyncore
.loop(timeout
=0.01, count
=1, use_poll
=self
.use_poll
)
518 self
.fail("flag not set")
520 def test_handle_connect(self
):
521 # make sure handle_connect is called on connect()
523 class TestClient(BaseClient
):
524 def handle_connect(self
):
528 client
= TestClient(server
.address
)
529 self
.loop_waiting_for_flag(client
)
531 def test_handle_accept(self
):
532 # make sure handle_accept() is called when a client connects
534 class TestListener(BaseTestHandler
):
537 BaseTestHandler
.__init
__(self
)
538 self
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
541 self
.address
= self
.socket
.getsockname()[:2]
543 def handle_accept(self
):
546 server
= TestListener()
547 client
= BaseClient(server
.address
)
548 self
.loop_waiting_for_flag(server
)
550 def test_handle_read(self
):
551 # make sure handle_read is called on data received
553 class TestClient(BaseClient
):
554 def handle_read(self
):
557 class TestHandler(BaseTestHandler
):
558 def __init__(self
, conn
):
559 BaseTestHandler
.__init
__(self
, conn
)
560 self
.send('x' * 1024)
562 server
= TCPServer(TestHandler
)
563 client
= TestClient(server
.address
)
564 self
.loop_waiting_for_flag(client
)
566 def test_handle_write(self
):
567 # make sure handle_write is called
569 class TestClient(BaseClient
):
570 def handle_write(self
):
574 client
= TestClient(server
.address
)
575 self
.loop_waiting_for_flag(client
)
577 def test_handle_close(self
):
578 # make sure handle_close is called when the other end closes
581 class TestClient(BaseClient
):
583 def handle_read(self
):
584 # in order to make handle_close be called we are supposed
585 # to make at least one recv() call
588 def handle_close(self
):
592 class TestHandler(BaseTestHandler
):
593 def __init__(self
, conn
):
594 BaseTestHandler
.__init
__(self
, conn
)
597 server
= TCPServer(TestHandler
)
598 client
= TestClient(server
.address
)
599 self
.loop_waiting_for_flag(client
)
601 @unittest.skipIf(sys
.platform
.startswith("sunos"),
602 "OOB support is broken on Solaris")
603 def test_handle_expt(self
):
604 # Make sure handle_expt is called on OOB data received.
605 # Note: this might fail on some platforms as OOB data is
606 # tenuously supported and rarely used.
608 class TestClient(BaseClient
):
609 def handle_expt(self
):
612 class TestHandler(BaseTestHandler
):
613 def __init__(self
, conn
):
614 BaseTestHandler
.__init
__(self
, conn
)
615 self
.socket
.send(chr(244), socket
.MSG_OOB
)
617 server
= TCPServer(TestHandler
)
618 client
= TestClient(server
.address
)
619 self
.loop_waiting_for_flag(client
)
621 def test_handle_error(self
):
623 class TestClient(BaseClient
):
624 def handle_write(self
):
626 def handle_error(self
):
630 except ZeroDivisionError:
633 raise Exception("exception not raised")
636 client
= TestClient(server
.address
)
637 self
.loop_waiting_for_flag(client
)
639 def test_connection_attributes(self
):
641 client
= BaseClient(server
.address
)
643 # we start disconnected
644 self
.assertFalse(server
.connected
)
645 self
.assertTrue(server
.accepting
)
646 # this can't be taken for granted across all platforms
647 #self.assertFalse(client.connected)
648 self
.assertFalse(client
.accepting
)
650 # execute some loops so that client connects to server
651 asyncore
.loop(timeout
=0.01, use_poll
=self
.use_poll
, count
=100)
652 self
.assertFalse(server
.connected
)
653 self
.assertTrue(server
.accepting
)
654 self
.assertTrue(client
.connected
)
655 self
.assertFalse(client
.accepting
)
657 # disconnect the client
659 self
.assertFalse(server
.connected
)
660 self
.assertTrue(server
.accepting
)
661 self
.assertFalse(client
.connected
)
662 self
.assertFalse(client
.accepting
)
666 self
.assertFalse(server
.connected
)
667 self
.assertFalse(server
.accepting
)
669 def test_create_socket(self
):
670 s
= asyncore
.dispatcher()
671 s
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
672 self
.assertEqual(s
.socket
.family
, socket
.AF_INET
)
673 self
.assertEqual(s
.socket
.type, socket
.SOCK_STREAM
)
676 s1
= asyncore
.dispatcher()
677 s1
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
680 port
= s1
.socket
.getsockname()[1]
682 s2
= asyncore
.dispatcher()
683 s2
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
684 # EADDRINUSE indicates the socket was correctly bound
685 self
.assertRaises(socket
.error
, s2
.bind
, (HOST
, port
))
687 def test_set_reuse_addr(self
):
688 sock
= socket
.socket()
690 sock
.setsockopt(socket
.SOL_SOCKET
, socket
.SO_REUSEADDR
, 1)
692 unittest
.skip("SO_REUSEADDR not supported on this platform")
694 # if SO_REUSEADDR succeeded for sock we expect asyncore
696 s
= asyncore
.dispatcher(socket
.socket())
697 self
.assertFalse(s
.socket
.getsockopt(socket
.SOL_SOCKET
,
698 socket
.SO_REUSEADDR
))
699 s
.create_socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
701 self
.assertTrue(s
.socket
.getsockopt(socket
.SOL_SOCKET
,
702 socket
.SO_REUSEADDR
))
707 class TestAPI_UseSelect(BaseTestAPI
):
710 @unittest.skipUnless(hasattr(select
, 'poll'), 'select.poll required')
711 class TestAPI_UsePoll(BaseTestAPI
):
716 tests
= [HelperFunctionTests
, DispatcherTests
, DispatcherWithSendTests
,
717 DispatcherWithSendTests_UsePoll
, TestAPI_UseSelect
,
718 TestAPI_UsePoll
, FileWrapperTest
]
721 if __name__
== "__main__":