~pythonregexp2.7/python/issue2636-09-01+10

« back to all changes in this revision

Viewing changes to Lib/test/test_asyncore.py

  • Committer: Jeffrey C. "The TimeHorse" Jacobs
  • Date: 2008-09-22 21:39:45 UTC
  • mfrom: (39055.1.33 Regexp-2.7)
  • Revision ID: darklord@timehorse.com-20080922213945-23717m5eiqpamcyn
Merged in changes from the Single-Loop Engine branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import asyncore
2
 
import unittest
3
 
import select
4
 
import os
5
 
import socket
6
 
import threading
7
 
import sys
8
 
import time
9
 
 
10
 
from test import test_support
11
 
from test.test_support import TESTFN, run_unittest, unlink
12
 
from StringIO import StringIO
13
 
 
14
 
HOST = test_support.HOST
15
 
 
16
 
class dummysocket:
17
 
    def __init__(self):
18
 
        self.closed = False
19
 
 
20
 
    def close(self):
21
 
        self.closed = True
22
 
 
23
 
    def fileno(self):
24
 
        return 42
25
 
 
26
 
class dummychannel:
27
 
    def __init__(self):
28
 
        self.socket = dummysocket()
29
 
 
30
 
class exitingdummy:
31
 
    def __init__(self):
32
 
        pass
33
 
 
34
 
    def handle_read_event(self):
35
 
        raise asyncore.ExitNow()
36
 
 
37
 
    handle_write_event = handle_read_event
38
 
    handle_expt_event = handle_read_event
39
 
 
40
 
class crashingdummy:
41
 
    def __init__(self):
42
 
        self.error_handled = False
43
 
 
44
 
    def handle_read_event(self):
45
 
        raise Exception()
46
 
 
47
 
    handle_write_event = handle_read_event
48
 
    handle_expt_event = handle_read_event
49
 
 
50
 
    def handle_error(self):
51
 
        self.error_handled = True
52
 
 
53
 
# used when testing senders; just collects what it gets until newline is sent
54
 
def capture_server(evt, buf, serv):
55
 
    try:
56
 
        serv.listen(5)
57
 
        conn, addr = serv.accept()
58
 
    except socket.timeout:
59
 
        pass
60
 
    else:
61
 
        n = 200
62
 
        while n > 0:
63
 
            r, w, e = select.select([conn], [], [])
64
 
            if r:
65
 
                data = conn.recv(10)
66
 
                # keep everything except for the newline terminator
67
 
                buf.write(data.replace('\n', ''))
68
 
                if '\n' in data:
69
 
                    break
70
 
            n -= 1
71
 
            time.sleep(0.01)
72
 
 
73
 
        conn.close()
74
 
    finally:
75
 
        serv.close()
76
 
        evt.set()
77
 
 
78
 
 
79
 
class HelperFunctionTests(unittest.TestCase):
80
 
    def test_readwriteexc(self):
81
 
        # Check exception handling behavior of read, write and _exception
82
 
 
83
 
        # check that ExitNow exceptions in the object handler method
84
 
        # bubbles all the way up through asyncore read/write/_exception calls
85
 
        tr1 = exitingdummy()
86
 
        self.assertRaises(asyncore.ExitNow, asyncore.read, tr1)
87
 
        self.assertRaises(asyncore.ExitNow, asyncore.write, tr1)
88
 
        self.assertRaises(asyncore.ExitNow, asyncore._exception, tr1)
89
 
 
90
 
        # check that an exception other than ExitNow in the object handler
91
 
        # method causes the handle_error method to get called
92
 
        tr2 = crashingdummy()
93
 
        asyncore.read(tr2)
94
 
        self.assertEqual(tr2.error_handled, True)
95
 
 
96
 
        tr2 = crashingdummy()
97
 
        asyncore.write(tr2)
98
 
        self.assertEqual(tr2.error_handled, True)
99
 
 
100
 
        tr2 = crashingdummy()
101
 
        asyncore._exception(tr2)
102
 
        self.assertEqual(tr2.error_handled, True)
103
 
 
104
 
    # asyncore.readwrite uses constants in the select module that
105
 
    # are not present in Windows systems (see this thread:
106
 
    # http://mail.python.org/pipermail/python-list/2001-October/109973.html)
107
 
    # These constants should be present as long as poll is available
108
 
 
109
 
    if hasattr(select, 'poll'):
110
 
        def test_readwrite(self):
111
 
            # Check that correct methods are called by readwrite()
112
 
 
113
 
            class testobj:
114
 
                def __init__(self):
115
 
                    self.read = False
116
 
                    self.write = False
117
 
                    self.expt = False
118
 
 
119
 
                def handle_read_event(self):
120
 
                    self.read = True
121
 
 
122
 
                def handle_write_event(self):
123
 
                    self.write = True
124
 
 
125
 
                def handle_expt_event(self):
126
 
                    self.expt = True
127
 
 
128
 
                def handle_error(self):
129
 
                    self.error_handled = True
130
 
 
131
 
            for flag in (select.POLLIN, select.POLLPRI):
132
 
                tobj = testobj()
133
 
                self.assertEqual(tobj.read, False)
134
 
                asyncore.readwrite(tobj, flag)
135
 
                self.assertEqual(tobj.read, True)
136
 
 
137
 
                # check that ExitNow exceptions in the object handler method
138
 
                # bubbles all the way up through asyncore readwrite call
139
 
                tr1 = exitingdummy()
140
 
                self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag)
141
 
 
142
 
                # check that an exception other than ExitNow in the object handler
143
 
                # method causes the handle_error method to get called
144
 
                tr2 = crashingdummy()
145
 
                asyncore.readwrite(tr2, flag)
146
 
                self.assertEqual(tr2.error_handled, True)
147
 
 
148
 
            tobj = testobj()
149
 
            self.assertEqual(tobj.write, False)
150
 
            asyncore.readwrite(tobj, select.POLLOUT)
151
 
            self.assertEqual(tobj.write, True)
152
 
 
153
 
            # check that ExitNow exceptions in the object handler method
154
 
            # bubbles all the way up through asyncore readwrite call
155
 
            tr1 = exitingdummy()
156
 
            self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1,
157
 
                              select.POLLOUT)
158
 
 
159
 
            # check that an exception other than ExitNow in the object handler
160
 
            # method causes the handle_error method to get called
161
 
            tr2 = crashingdummy()
162
 
            asyncore.readwrite(tr2, select.POLLOUT)
163
 
            self.assertEqual(tr2.error_handled, True)
164
 
 
165
 
            for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL):
166
 
                tobj = testobj()
167
 
                self.assertEqual(tobj.expt, False)
168
 
                asyncore.readwrite(tobj, flag)
169
 
                self.assertEqual(tobj.expt, True)
170
 
 
171
 
                # check that ExitNow exceptions in the object handler method
172
 
                # bubbles all the way up through asyncore readwrite calls
173
 
                tr1 = exitingdummy()
174
 
                self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag)
175
 
 
176
 
                # check that an exception other than ExitNow in the object handler
177
 
                # method causes the handle_error method to get called
178
 
                tr2 = crashingdummy()
179
 
                asyncore.readwrite(tr2, flag)
180
 
                self.assertEqual(tr2.error_handled, True)
181
 
 
182
 
    def test_closeall(self):
183
 
        self.closeall_check(False)
184
 
 
185
 
    def test_closeall_default(self):
186
 
        self.closeall_check(True)
187
 
 
188
 
    def closeall_check(self, usedefault):
189
 
        # Check that close_all() closes everything in a given map
190
 
 
191
 
        l = []
192
 
        testmap = {}
193
 
        for i in range(10):
194
 
            c = dummychannel()
195
 
            l.append(c)
196
 
            self.assertEqual(c.socket.closed, False)
197
 
            testmap[i] = c
198
 
 
199
 
        if usedefault:
200
 
            socketmap = asyncore.socket_map
201
 
            try:
202
 
                asyncore.socket_map = testmap
203
 
                asyncore.close_all()
204
 
            finally:
205
 
                testmap, asyncore.socket_map = asyncore.socket_map, socketmap
206
 
        else:
207
 
            asyncore.close_all(testmap)
208
 
 
209
 
        self.assertEqual(len(testmap), 0)
210
 
 
211
 
        for c in l:
212
 
            self.assertEqual(c.socket.closed, True)
213
 
 
214
 
    def test_compact_traceback(self):
215
 
        try:
216
 
            raise Exception("I don't like spam!")
217
 
        except:
218
 
            real_t, real_v, real_tb = sys.exc_info()
219
 
            r = asyncore.compact_traceback()
220
 
        else:
221
 
            self.fail("Expected exception")
222
 
 
223
 
        (f, function, line), t, v, info = r
224
 
        self.assertEqual(os.path.split(f)[-1], 'test_asyncore.py')
225
 
        self.assertEqual(function, 'test_compact_traceback')
226
 
        self.assertEqual(t, real_t)
227
 
        self.assertEqual(v, real_v)
228
 
        self.assertEqual(info, '[%s|%s|%s]' % (f, function, line))
229
 
 
230
 
 
231
 
class DispatcherTests(unittest.TestCase):
232
 
    def setUp(self):
233
 
        pass
234
 
 
235
 
    def tearDown(self):
236
 
        asyncore.close_all()
237
 
 
238
 
    def test_basic(self):
239
 
        d = asyncore.dispatcher()
240
 
        self.assertEqual(d.readable(), True)
241
 
        self.assertEqual(d.writable(), True)
242
 
 
243
 
    def test_repr(self):
244
 
        d = asyncore.dispatcher()
245
 
        self.assertEqual(repr(d), '<asyncore.dispatcher at %#x>' % id(d))
246
 
 
247
 
    def test_log(self):
248
 
        d = asyncore.dispatcher()
249
 
 
250
 
        # capture output of dispatcher.log() (to stderr)
251
 
        fp = StringIO()
252
 
        stderr = sys.stderr
253
 
        l1 = "Lovely spam! Wonderful spam!"
254
 
        l2 = "I don't like spam!"
255
 
        try:
256
 
            sys.stderr = fp
257
 
            d.log(l1)
258
 
            d.log(l2)
259
 
        finally:
260
 
            sys.stderr = stderr
261
 
 
262
 
        lines = fp.getvalue().splitlines()
263
 
        self.assertEquals(lines, ['log: %s' % l1, 'log: %s' % l2])
264
 
 
265
 
    def test_log_info(self):
266
 
        d = asyncore.dispatcher()
267
 
 
268
 
        # capture output of dispatcher.log_info() (to stdout via print)
269
 
        fp = StringIO()
270
 
        stdout = sys.stdout
271
 
        l1 = "Have you got anything without spam?"
272
 
        l2 = "Why can't she have egg bacon spam and sausage?"
273
 
        l3 = "THAT'S got spam in it!"
274
 
        try:
275
 
            sys.stdout = fp
276
 
            d.log_info(l1, 'EGGS')
277
 
            d.log_info(l2)
278
 
            d.log_info(l3, 'SPAM')
279
 
        finally:
280
 
            sys.stdout = stdout
281
 
 
282
 
        lines = fp.getvalue().splitlines()
283
 
        if __debug__:
284
 
            expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3]
285
 
        else:
286
 
            expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3]
287
 
 
288
 
        self.assertEquals(lines, expected)
289
 
 
290
 
    def test_unhandled(self):
291
 
        d = asyncore.dispatcher()
292
 
 
293
 
        # capture output of dispatcher.log_info() (to stdout via print)
294
 
        fp = StringIO()
295
 
        stdout = sys.stdout
296
 
        try:
297
 
            sys.stdout = fp
298
 
            d.handle_expt()
299
 
            d.handle_read()
300
 
            d.handle_write()
301
 
            d.handle_connect()
302
 
            d.handle_accept()
303
 
        finally:
304
 
            sys.stdout = stdout
305
 
 
306
 
        lines = fp.getvalue().splitlines()
307
 
        expected = ['warning: unhandled exception',
308
 
                    'warning: unhandled read event',
309
 
                    'warning: unhandled write event',
310
 
                    'warning: unhandled connect event',
311
 
                    'warning: unhandled accept event']
312
 
        self.assertEquals(lines, expected)
313
 
 
314
 
 
315
 
 
316
 
class dispatcherwithsend_noread(asyncore.dispatcher_with_send):
317
 
    def readable(self):
318
 
        return False
319
 
 
320
 
    def handle_connect(self):
321
 
        pass
322
 
 
323
 
class DispatcherWithSendTests(unittest.TestCase):
324
 
    usepoll = False
325
 
 
326
 
    def setUp(self):
327
 
        pass
328
 
 
329
 
    def tearDown(self):
330
 
        asyncore.close_all()
331
 
 
332
 
    def test_send(self):
333
 
        self.evt = threading.Event()
334
 
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
335
 
        self.sock.settimeout(3)
336
 
        self.port = test_support.bind_port(self.sock)
337
 
 
338
 
        cap = StringIO()
339
 
        args = (self.evt, cap, self.sock)
340
 
        threading.Thread(target=capture_server, args=args).start()
341
 
 
342
 
        # wait a little longer for the server to initialize (it sometimes
343
 
        # refuses connections on slow machines without this wait)
344
 
        time.sleep(0.2)
345
 
 
346
 
        data = "Suppose there isn't a 16-ton weight?"
347
 
        d = dispatcherwithsend_noread()
348
 
        d.create_socket(socket.AF_INET, socket.SOCK_STREAM)
349
 
        d.connect((HOST, self.port))
350
 
 
351
 
        # give time for socket to connect
352
 
        time.sleep(0.1)
353
 
 
354
 
        d.send(data)
355
 
        d.send(data)
356
 
        d.send('\n')
357
 
 
358
 
        n = 1000
359
 
        while d.out_buffer and n > 0:
360
 
            asyncore.poll()
361
 
            n -= 1
362
 
 
363
 
        self.evt.wait()
364
 
 
365
 
        self.assertEqual(cap.getvalue(), data*2)
366
 
 
367
 
 
368
 
class DispatcherWithSendTests_UsePoll(DispatcherWithSendTests):
369
 
    usepoll = True
370
 
 
371
 
if hasattr(asyncore, 'file_wrapper'):
372
 
    class FileWrapperTest(unittest.TestCase):
373
 
        def setUp(self):
374
 
            self.d = "It's not dead, it's sleeping!"
375
 
            file(TESTFN, 'w').write(self.d)
376
 
 
377
 
        def tearDown(self):
378
 
            unlink(TESTFN)
379
 
 
380
 
        def test_recv(self):
381
 
            fd = os.open(TESTFN, os.O_RDONLY)
382
 
            w = asyncore.file_wrapper(fd)
383
 
 
384
 
            self.assertEqual(w.fd, fd)
385
 
            self.assertEqual(w.fileno(), fd)
386
 
            self.assertEqual(w.recv(13), "It's not dead")
387
 
            self.assertEqual(w.read(6), ", it's")
388
 
            w.close()
389
 
            self.assertRaises(OSError, w.read, 1)
390
 
 
391
 
        def test_send(self):
392
 
            d1 = "Come again?"
393
 
            d2 = "I want to buy some cheese."
394
 
            fd = os.open(TESTFN, os.O_WRONLY | os.O_APPEND)
395
 
            w = asyncore.file_wrapper(fd)
396
 
 
397
 
            w.write(d1)
398
 
            w.send(d2)
399
 
            w.close()
400
 
            self.assertEqual(file(TESTFN).read(), self.d + d1 + d2)
401
 
 
402
 
 
403
 
def test_main():
404
 
    tests = [HelperFunctionTests, DispatcherTests, DispatcherWithSendTests,
405
 
             DispatcherWithSendTests_UsePoll]
406
 
    if hasattr(asyncore, 'file_wrapper'):
407
 
        tests.append(FileWrapperTest)
408
 
 
409
 
    run_unittest(*tests)
410
 
 
411
 
if __name__ == "__main__":
412
 
    test_main()
 
1
import asyncore
 
2
import unittest
 
3
import select
 
4
import os
 
5
import socket
 
6
import threading
 
7
import sys
 
8
import time
 
9
 
 
10
from test import test_support
 
11
from test.test_support import TESTFN, run_unittest, unlink
 
12
from StringIO import StringIO
 
13
 
 
14
HOST = test_support.HOST
 
15
 
 
16
class dummysocket:
 
17
    def __init__(self):
 
18
        self.closed = False
 
19
 
 
20
    def close(self):
 
21
        self.closed = True
 
22
 
 
23
    def fileno(self):
 
24
        return 42
 
25
 
 
26
class dummychannel:
 
27
    def __init__(self):
 
28
        self.socket = dummysocket()
 
29
 
 
30
    def close(self):
 
31
        self.socket.close()
 
32
 
 
33
class exitingdummy:
 
34
    def __init__(self):
 
35
        pass
 
36
 
 
37
    def handle_read_event(self):
 
38
        raise asyncore.ExitNow()
 
39
 
 
40
    handle_write_event = handle_read_event
 
41
    handle_close = handle_read_event
 
42
    handle_expt_event = handle_read_event
 
43
 
 
44
class crashingdummy:
 
45
    def __init__(self):
 
46
        self.error_handled = False
 
47
 
 
48
    def handle_read_event(self):
 
49
        raise Exception()
 
50
 
 
51
    handle_write_event = handle_read_event
 
52
    handle_close = handle_read_event
 
53
    handle_expt_event = handle_read_event
 
54
 
 
55
    def handle_error(self):
 
56
        self.error_handled = True
 
57
 
 
58
# used when testing senders; just collects what it gets until newline is sent
 
59
def capture_server(evt, buf, serv):
 
60
    try:
 
61
        serv.listen(5)
 
62
        conn, addr = serv.accept()
 
63
    except socket.timeout:
 
64
        pass
 
65
    else:
 
66
        n = 200
 
67
        while n > 0:
 
68
            r, w, e = select.select([conn], [], [])
 
69
            if r:
 
70
                data = conn.recv(10)
 
71
                # keep everything except for the newline terminator
 
72
                buf.write(data.replace('\n', ''))
 
73
                if '\n' in data:
 
74
                    break
 
75
            n -= 1
 
76
            time.sleep(0.01)
 
77
 
 
78
        conn.close()
 
79
    finally:
 
80
        serv.close()
 
81
        evt.set()
 
82
 
 
83
 
 
84
class HelperFunctionTests(unittest.TestCase):
 
85
    def test_readwriteexc(self):
 
86
        # Check exception handling behavior of read, write and _exception
 
87
 
 
88
        # check that ExitNow exceptions in the object handler method
 
89
        # bubbles all the way up through asyncore read/write/_exception calls
 
90
        tr1 = exitingdummy()
 
91
        self.assertRaises(asyncore.ExitNow, asyncore.read, tr1)
 
92
        self.assertRaises(asyncore.ExitNow, asyncore.write, tr1)
 
93
        self.assertRaises(asyncore.ExitNow, asyncore._exception, tr1)
 
94
 
 
95
        # check that an exception other than ExitNow in the object handler
 
96
        # method causes the handle_error method to get called
 
97
        tr2 = crashingdummy()
 
98
        asyncore.read(tr2)
 
99
        self.assertEqual(tr2.error_handled, True)
 
100
 
 
101
        tr2 = crashingdummy()
 
102
        asyncore.write(tr2)
 
103
        self.assertEqual(tr2.error_handled, True)
 
104
 
 
105
        tr2 = crashingdummy()
 
106
        asyncore._exception(tr2)
 
107
        self.assertEqual(tr2.error_handled, True)
 
108
 
 
109
    # asyncore.readwrite uses constants in the select module that
 
110
    # are not present in Windows systems (see this thread:
 
111
    # http://mail.python.org/pipermail/python-list/2001-October/109973.html)
 
112
    # These constants should be present as long as poll is available
 
113
 
 
114
    if hasattr(select, 'poll'):
 
115
        def test_readwrite(self):
 
116
            # Check that correct methods are called by readwrite()
 
117
 
 
118
            class testobj:
 
119
                def __init__(self):
 
120
                    self.read = False
 
121
                    self.write = False
 
122
                    self.closed = False
 
123
                    self.expt = False
 
124
 
 
125
                def handle_read_event(self):
 
126
                    self.read = True
 
127
 
 
128
                def handle_write_event(self):
 
129
                    self.write = True
 
130
 
 
131
                def handle_close(self):
 
132
                    self.closed = True
 
133
 
 
134
                def handle_expt_event(self):
 
135
                    self.expt = True
 
136
 
 
137
                def handle_error(self):
 
138
                    self.error_handled = True
 
139
 
 
140
            for flag in (select.POLLIN, select.POLLPRI):
 
141
                tobj = testobj()
 
142
                self.assertEqual(tobj.read, False)
 
143
                asyncore.readwrite(tobj, flag)
 
144
                self.assertEqual(tobj.read, True)
 
145
 
 
146
                # check that ExitNow exceptions in the object handler method
 
147
                # bubbles all the way up through asyncore readwrite call
 
148
                tr1 = exitingdummy()
 
149
                self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag)
 
150
 
 
151
                # check that an exception other than ExitNow in the object handler
 
152
                # method causes the handle_error method to get called
 
153
                tr2 = crashingdummy()
 
154
                asyncore.readwrite(tr2, flag)
 
155
                self.assertEqual(tr2.error_handled, True)
 
156
 
 
157
            tobj = testobj()
 
158
            self.assertEqual(tobj.write, False)
 
159
            asyncore.readwrite(tobj, select.POLLOUT)
 
160
            self.assertEqual(tobj.write, True)
 
161
 
 
162
            # check that ExitNow exceptions in the object handler method
 
163
            # bubbles all the way up through asyncore readwrite call
 
164
            tr1 = exitingdummy()
 
165
            self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1,
 
166
                              select.POLLOUT)
 
167
 
 
168
            # check that an exception other than ExitNow in the object handler
 
169
            # method causes the handle_error method to get called
 
170
            tr2 = crashingdummy()
 
171
            asyncore.readwrite(tr2, select.POLLOUT)
 
172
            self.assertEqual(tr2.error_handled, True)
 
173
 
 
174
            for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL):
 
175
                tobj = testobj()
 
176
                self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], False)
 
177
                asyncore.readwrite(tobj, flag)
 
178
                self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], True)
 
179
 
 
180
                # check that ExitNow exceptions in the object handler method
 
181
                # bubbles all the way up through asyncore readwrite calls
 
182
                tr1 = exitingdummy()
 
183
                self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag)
 
184
 
 
185
                # check that an exception other than ExitNow in the object handler
 
186
                # method causes the handle_error method to get called
 
187
                tr2 = crashingdummy()
 
188
                asyncore.readwrite(tr2, flag)
 
189
                self.assertEqual(tr2.error_handled, True)
 
190
 
 
191
    def test_closeall(self):
 
192
        self.closeall_check(False)
 
193
 
 
194
    def test_closeall_default(self):
 
195
        self.closeall_check(True)
 
196
 
 
197
    def closeall_check(self, usedefault):
 
198
        # Check that close_all() closes everything in a given map
 
199
 
 
200
        l = []
 
201
        testmap = {}
 
202
        for i in range(10):
 
203
            c = dummychannel()
 
204
            l.append(c)
 
205
            self.assertEqual(c.socket.closed, False)
 
206
            testmap[i] = c
 
207
 
 
208
        if usedefault:
 
209
            socketmap = asyncore.socket_map
 
210
            try:
 
211
                asyncore.socket_map = testmap
 
212
                asyncore.close_all()
 
213
            finally:
 
214
                testmap, asyncore.socket_map = asyncore.socket_map, socketmap
 
215
        else:
 
216
            asyncore.close_all(testmap)
 
217
 
 
218
        self.assertEqual(len(testmap), 0)
 
219
 
 
220
        for c in l:
 
221
            self.assertEqual(c.socket.closed, True)
 
222
 
 
223
    def test_compact_traceback(self):
 
224
        try:
 
225
            raise Exception("I don't like spam!")
 
226
        except:
 
227
            real_t, real_v, real_tb = sys.exc_info()
 
228
            r = asyncore.compact_traceback()
 
229
        else:
 
230
            self.fail("Expected exception")
 
231
 
 
232
        (f, function, line), t, v, info = r
 
233
        self.assertEqual(os.path.split(f)[-1], 'test_asyncore.py')
 
234
        self.assertEqual(function, 'test_compact_traceback')
 
235
        self.assertEqual(t, real_t)
 
236
        self.assertEqual(v, real_v)
 
237
        self.assertEqual(info, '[%s|%s|%s]' % (f, function, line))
 
238
 
 
239
 
 
240
class DispatcherTests(unittest.TestCase):
 
241
    def setUp(self):
 
242
        pass
 
243
 
 
244
    def tearDown(self):
 
245
        asyncore.close_all()
 
246
 
 
247
    def test_basic(self):
 
248
        d = asyncore.dispatcher()
 
249
        self.assertEqual(d.readable(), True)
 
250
        self.assertEqual(d.writable(), True)
 
251
 
 
252
    def test_repr(self):
 
253
        d = asyncore.dispatcher()
 
254
        self.assertEqual(repr(d), '<asyncore.dispatcher at %#x>' % id(d))
 
255
 
 
256
    def test_log(self):
 
257
        d = asyncore.dispatcher()
 
258
 
 
259
        # capture output of dispatcher.log() (to stderr)
 
260
        fp = StringIO()
 
261
        stderr = sys.stderr
 
262
        l1 = "Lovely spam! Wonderful spam!"
 
263
        l2 = "I don't like spam!"
 
264
        try:
 
265
            sys.stderr = fp
 
266
            d.log(l1)
 
267
            d.log(l2)
 
268
        finally:
 
269
            sys.stderr = stderr
 
270
 
 
271
        lines = fp.getvalue().splitlines()
 
272
        self.assertEquals(lines, ['log: %s' % l1, 'log: %s' % l2])
 
273
 
 
274
    def test_log_info(self):
 
275
        d = asyncore.dispatcher()
 
276
 
 
277
        # capture output of dispatcher.log_info() (to stdout via print)
 
278
        fp = StringIO()
 
279
        stdout = sys.stdout
 
280
        l1 = "Have you got anything without spam?"
 
281
        l2 = "Why can't she have egg bacon spam and sausage?"
 
282
        l3 = "THAT'S got spam in it!"
 
283
        try:
 
284
            sys.stdout = fp
 
285
            d.log_info(l1, 'EGGS')
 
286
            d.log_info(l2)
 
287
            d.log_info(l3, 'SPAM')
 
288
        finally:
 
289
            sys.stdout = stdout
 
290
 
 
291
        lines = fp.getvalue().splitlines()
 
292
        if __debug__:
 
293
            expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3]
 
294
        else:
 
295
            expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3]
 
296
 
 
297
        self.assertEquals(lines, expected)
 
298
 
 
299
    def test_unhandled(self):
 
300
        d = asyncore.dispatcher()
 
301
 
 
302
        # capture output of dispatcher.log_info() (to stdout via print)
 
303
        fp = StringIO()
 
304
        stdout = sys.stdout
 
305
        try:
 
306
            sys.stdout = fp
 
307
            d.handle_expt()
 
308
            d.handle_read()
 
309
            d.handle_write()
 
310
            d.handle_connect()
 
311
            d.handle_accept()
 
312
        finally:
 
313
            sys.stdout = stdout
 
314
 
 
315
        lines = fp.getvalue().splitlines()
 
316
        expected = ['warning: unhandled exception',
 
317
                    'warning: unhandled read event',
 
318
                    'warning: unhandled write event',
 
319
                    'warning: unhandled connect event',
 
320
                    'warning: unhandled accept event']
 
321
        self.assertEquals(lines, expected)
 
322
 
 
323
 
 
324
 
 
325
class dispatcherwithsend_noread(asyncore.dispatcher_with_send):
 
326
    def readable(self):
 
327
        return False
 
328
 
 
329
    def handle_connect(self):
 
330
        pass
 
331
 
 
332
class DispatcherWithSendTests(unittest.TestCase):
 
333
    usepoll = False
 
334
 
 
335
    def setUp(self):
 
336
        pass
 
337
 
 
338
    def tearDown(self):
 
339
        asyncore.close_all()
 
340
 
 
341
    def test_send(self):
 
342
        self.evt = threading.Event()
 
343
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
344
        self.sock.settimeout(3)
 
345
        self.port = test_support.bind_port(self.sock)
 
346
 
 
347
        cap = StringIO()
 
348
        args = (self.evt, cap, self.sock)
 
349
        threading.Thread(target=capture_server, args=args).start()
 
350
 
 
351
        # wait a little longer for the server to initialize (it sometimes
 
352
        # refuses connections on slow machines without this wait)
 
353
        time.sleep(0.2)
 
354
 
 
355
        data = "Suppose there isn't a 16-ton weight?"
 
356
        d = dispatcherwithsend_noread()
 
357
        d.create_socket(socket.AF_INET, socket.SOCK_STREAM)
 
358
        d.connect((HOST, self.port))
 
359
 
 
360
        # give time for socket to connect
 
361
        time.sleep(0.1)
 
362
 
 
363
        d.send(data)
 
364
        d.send(data)
 
365
        d.send('\n')
 
366
 
 
367
        n = 1000
 
368
        while d.out_buffer and n > 0:
 
369
            asyncore.poll()
 
370
            n -= 1
 
371
 
 
372
        self.evt.wait()
 
373
 
 
374
        self.assertEqual(cap.getvalue(), data*2)
 
375
 
 
376
 
 
377
class DispatcherWithSendTests_UsePoll(DispatcherWithSendTests):
 
378
    usepoll = True
 
379
 
 
380
if hasattr(asyncore, 'file_wrapper'):
 
381
    class FileWrapperTest(unittest.TestCase):
 
382
        def setUp(self):
 
383
            self.d = "It's not dead, it's sleeping!"
 
384
            file(TESTFN, 'w').write(self.d)
 
385
 
 
386
        def tearDown(self):
 
387
            unlink(TESTFN)
 
388
 
 
389
        def test_recv(self):
 
390
            fd = os.open(TESTFN, os.O_RDONLY)
 
391
            w = asyncore.file_wrapper(fd)
 
392
            os.close(fd)
 
393
 
 
394
            self.assertNotEqual(w.fd, fd)
 
395
            self.assertNotEqual(w.fileno(), fd)
 
396
            self.assertEqual(w.recv(13), "It's not dead")
 
397
            self.assertEqual(w.read(6), ", it's")
 
398
            w.close()
 
399
            self.assertRaises(OSError, w.read, 1)
 
400
 
 
401
        def test_send(self):
 
402
            d1 = "Come again?"
 
403
            d2 = "I want to buy some cheese."
 
404
            fd = os.open(TESTFN, os.O_WRONLY | os.O_APPEND)
 
405
            w = asyncore.file_wrapper(fd)
 
406
            os.close(fd)
 
407
 
 
408
            w.write(d1)
 
409
            w.send(d2)
 
410
            w.close()
 
411
            self.assertEqual(file(TESTFN).read(), self.d + d1 + d2)
 
412
 
 
413
 
 
414
def test_main():
 
415
    tests = [HelperFunctionTests, DispatcherTests, DispatcherWithSendTests,
 
416
             DispatcherWithSendTests_UsePoll]
 
417
    if hasattr(asyncore, 'file_wrapper'):
 
418
        tests.append(FileWrapperTest)
 
419
 
 
420
    run_unittest(*tests)
 
421
 
 
422
if __name__ == "__main__":
 
423
    test_main()