~ubuntu-branches/ubuntu/quantal/python-gevent/quantal

« back to all changes in this revision

Viewing changes to greentest/test__greenlet.py

  • Committer: Bazaar Package Importer
  • Author(s): Örjan Persson
  • Date: 2011-05-17 16:43:20 UTC
  • mfrom: (6.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110517164320-nwhld2xo6sz58p4m
Tags: 0.13.6-1
New upstream version (Closes: #601863).

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 
31
31
DELAY = 0.01
32
32
 
 
33
 
33
34
class ExpectedError(Exception):
34
35
    pass
35
36
 
49
50
        raise AssertionError('%s not raised, returned %r' % (err, result))
50
51
 
51
52
    def test_link_to_greenlet(self):
52
 
        p = gevent.spawn(lambda : 100)
 
53
        p = gevent.spawn(lambda: 100)
53
54
        receiver = gevent.spawn(sleep, 1)
54
55
        p.link(receiver)
55
56
        self.assertRaises(greenlet.LinkedCompleted, receiver.get)
58
59
        self.assertRaises(greenlet.LinkedCompleted, receiver2.get)
59
60
 
60
61
    def test_link_to_inactive_greenlet(self):
61
 
        p = gevent.spawn(lambda : 100)
 
62
        p = gevent.spawn(lambda: 100)
62
63
        receiver = gevent.spawn_later(10000, sleep, 1)
63
64
        try:
64
65
            p.link(receiver)
65
66
            self.assertRaises(greenlet.LinkedCompleted, receiver.get)
66
67
        finally:
67
 
            receiver.kill(block=True)
 
68
            receiver.kill()
68
69
 
69
70
    def test_link_to_asyncresult(self):
70
 
        p = gevent.spawn(lambda : 100)
 
71
        p = gevent.spawn(lambda: 100)
71
72
        event = AsyncResult()
72
73
        p.link(event)
73
74
        self.assertEqual(event.get(), 100)
79
80
 
80
81
    def test_link_to_asyncresult_exception(self):
81
82
        err = ExpectedError('test_link_to_asyncresult_exception')
82
 
        p = gevent.spawn(lambda : getcurrent().throw(err))
 
83
        p = gevent.spawn(lambda: getcurrent().throw(err))
83
84
        event = AsyncResult()
84
85
        p.link(event)
85
86
        self.assertRaises(err, event.get)
90
91
            self.assertRaises(err, event.get)
91
92
 
92
93
    def test_link_to_queue(self):
93
 
        p = gevent.spawn(lambda : 100)
 
94
        p = gevent.spawn(lambda: 100)
94
95
        q = Queue()
95
96
        p.link(q.put)
96
97
        self.assertEqual(q.get().get(), 100)
100
101
            self.assertEqual(q.get().get(), 100)
101
102
 
102
103
    def test_link_to_channel(self):
103
 
        p1 = gevent.spawn(lambda : 101)
104
 
        p2 = gevent.spawn(lambda : 102)
105
 
        p3 = gevent.spawn(lambda : 103)
 
104
        p1 = gevent.spawn(lambda: 101)
 
105
        p2 = gevent.spawn(lambda: 102)
 
106
        p3 = gevent.spawn(lambda: 103)
106
107
        q = Queue(0)
107
108
        p1.link(q.put)
108
109
        p2.link(q.put)
111
112
        assert sorted(results) == [101, 102, 103], results
112
113
 
113
114
    def test_link_to_current(self):
114
 
        p = gevent.spawn(lambda : 100)
 
115
        p = gevent.spawn(lambda: 100)
115
116
        p.link()
116
117
        self.assertRaises(greenlet.LinkedCompleted, sleep, 0.1)
117
118
        self.assertRaises(greenlet.LinkedCompleted, p.link)
127
128
    def _test_func(self, link):
128
129
        p = self.p
129
130
        link(test_func)
130
 
        assert len(p._links)==1, p._links
 
131
        assert len(p._links) == 1, p._links
131
132
        p.unlink(test_func)
132
133
        assert not p._links, p._links
133
134
 
134
135
        link(self.setUp)
135
 
        assert len(p._links)==1, p._links
 
136
        assert len(p._links) == 1, p._links
136
137
        p.unlink(self.setUp)
137
138
        assert not p._links, p._links
138
139
 
148
149
    def _test_greenlet(self, link):
149
150
        p = self.p
150
151
        link(getcurrent())
151
 
        assert len(p._links)==1, p._links
 
152
        assert len(p._links) == 1, p._links
152
153
        p.unlink(getcurrent())
153
154
        assert not p._links, p._links
154
155
 
155
156
        g = gevent.Greenlet()
156
157
        link(g)
157
 
        assert len(p._links)==1, p._links
 
158
        assert len(p._links) == 1, p._links
158
159
        p.unlink(g)
159
160
        assert not p._links, p._links
160
161
 
173
174
    def link(self, p, listener=None):
174
175
        getattr(p, self.link_method)(listener)
175
176
 
176
 
    def tearDown(self):
177
 
        greentest.TestCase.tearDown(self)
178
 
        self.p.unlink()
 
177
    def receiverf(self, proc_flag):
 
178
        sleep(DELAY)
 
179
        proc_flag.append('finished')
179
180
 
180
181
    def set_links(self, p, first_time, kill_exc_type):
181
182
        event = AsyncResult()
182
183
        self.link(p, event)
183
184
 
184
185
        proc_flag = []
185
 
        def receiver():
186
 
            sleep(DELAY)
187
 
            proc_flag.append('finished')
188
 
        receiver = gevent.spawn(receiver)
 
186
 
 
187
        receiver = gevent.spawn(self.receiverf, proc_flag)
189
188
        self.link(p, receiver)
190
189
 
191
190
        queue = Queue(1)
205
204
        for _ in range(10):
206
205
            self.link(p, AsyncResult())
207
206
            self.link(p, Queue(1).put)
 
207
 
208
208
        return event, receiver, proc_flag, queue, callback_flag
209
209
 
 
210
    def myprocf(self, proc_finished_flag):
 
211
        sleep(10)
 
212
        proc_finished_flag.append('finished')
 
213
        return 555
 
214
 
210
215
    def set_links_timeout(self, link):
211
216
        # stuff that won't be touched
212
217
        event = AsyncResult()
213
218
        link(event)
214
219
 
215
220
        proc_finished_flag = []
216
 
        def myproc():
217
 
            sleep(10)
218
 
            proc_finished_flag.append('finished')
219
 
            return 555
220
 
        myproc = gevent.spawn(myproc)
 
221
        myproc = gevent.spawn(self.myprocf, proc_finished_flag)
221
222
        link(myproc)
222
223
 
223
224
        queue = Queue(0)
229
230
        assert with_timeout(DELAY, queue.get, timeout_value=X) is X, queue.get()
230
231
        assert with_timeout(DELAY, gevent.joinall, [myproc], timeout_value=X) is X
231
232
        assert proc_finished_flag == [], proc_finished_flag
 
233
        myproc.kill()
 
234
 
 
235
 
 
236
def return25():
 
237
    return 25
 
238
 
 
239
 
 
240
def sleep0():
 
241
    return sleep(0)
232
242
 
233
243
 
234
244
class TestReturn_link(LinksTestCase):
235
245
    link_method = 'link'
236
246
 
 
247
    def cleanup(self):
 
248
        while self.p._links:
 
249
            self.p._links.pop()
 
250
 
237
251
    def test_return(self):
238
 
        def return25():
239
 
            return 25
240
 
        p = self.p = gevent.spawn(return25)
241
 
        self._test_return(p, True, 25, greenlet.LinkedCompleted, lambda : sleep(0))
 
252
        self.p = gevent.spawn(return25)
 
253
        self._test_return(self.p, True, 25, greenlet.LinkedCompleted, sleep0)
242
254
        # repeating the same with dead process
243
255
        for _ in xrange(3):
244
 
            self._test_return(p, False, 25, greenlet.LinkedCompleted, lambda : sleep(0))
 
256
            self._test_return(self.p, False, 25, greenlet.LinkedCompleted, sleep0)
 
257
        self.cleanup()
 
258
        self.p.kill()
245
259
 
246
260
    def _test_return(self, p, first_time, result, kill_exc_type, action):
247
261
        event, receiver, proc_flag, queue, callback_flag = self.set_links(p, first_time, kill_exc_type)
250
264
        xxxxx = self.set_links_timeout(p.link_exception)
251
265
 
252
266
        try:
253
 
            sleep(DELAY*2)
 
267
            sleep(DELAY * 2)
254
268
        except kill_exc_type:
255
 
             assert first_time, 'raising here only first time'
 
269
            assert first_time, 'raising here only first time'
256
270
        else:
257
271
            assert not first_time, 'Should not raise LinkedKilled here after first time'
258
272
 
277
291
        try:
278
292
            sleep(DELAY)
279
293
        except kill_exc_type:
280
 
             assert first_time, 'raising here only first time'
 
294
            assert first_time, 'raising here only first time'
281
295
        else:
282
296
            assert not first_time, 'Should not raise LinkedKilled here after first time'
283
297
 
316
330
        try:
317
331
            sleep(DELAY)
318
332
        except kill_exc_type:
319
 
             assert first_time, 'raising here only first time'
 
333
            assert first_time, 'raising here only first time'
320
334
        else:
321
335
            assert not first_time, 'Should not raise LinkedKilled here after first time'
322
336
 
333
347
        self.check_timed_out(*xxxxx)
334
348
 
335
349
    def test_raise(self):
336
 
        p = self.p = gevent.spawn(lambda : getcurrent().throw(ExpectedError('test_raise')))
 
350
        p = self.p = gevent.spawn(lambda: getcurrent().throw(ExpectedError('test_raise')))
337
351
        self._test_raise(p, True, greenlet.LinkedFailed)
338
352
        # repeating the same with dead process
339
353
        for _ in xrange(3):
340
354
            self._test_raise(p, False, greenlet.LinkedFailed)
341
355
 
 
356
 
342
357
class TestRaise_link_exception(TestRaise_link):
343
358
    link_method = 'link_exception'
344
359
 
346
361
class TestStuff(greentest.TestCase):
347
362
 
348
363
    def test_wait_noerrors(self):
349
 
        x = gevent.spawn(lambda : 1)
350
 
        y = gevent.spawn(lambda : 2)
351
 
        z = gevent.spawn(lambda : 3)
 
364
        x = gevent.spawn(lambda: 1)
 
365
        y = gevent.spawn(lambda: 2)
 
366
        z = gevent.spawn(lambda: 3)
352
367
        gevent.joinall([x, y, z], raise_error=True)
353
368
        self.assertEqual([x.value, y.value, z.value], [1, 2, 3])
354
369
        e = AsyncResult()
365
380
            sleep(DELAY)
366
381
            return 1
367
382
        x = gevent.spawn(x)
368
 
        z = gevent.spawn(lambda : 3)
369
 
        y = gevent.spawn(lambda : getcurrent().throw(ExpectedError('test_wait_error')))
 
383
        z = gevent.spawn(lambda: 3)
 
384
        y = gevent.spawn(lambda: getcurrent().throw(ExpectedError('test_wait_error')))
370
385
        y.link(x)
371
386
        x.link(y)
372
387
        y.link(z)
376
391
        self.assertEqual(z.get(), 3)
377
392
        self.assertRaises(ExpectedError, gevent.joinall, [y], raise_error=True)
378
393
 
379
 
    def test_wait_all_exception_order(self):
 
394
    def test_joinall_exception_order(self):
380
395
        # if there're several exceptions raised, the earliest one must be raised by joinall
381
396
        def first():
382
397
            sleep(0.1)
383
398
            raise ExpectedError('first')
384
399
        a = gevent.spawn(first)
385
 
        b = gevent.spawn(lambda : getcurrent().throw(ExpectedError('second')))
 
400
        b = gevent.spawn(lambda: getcurrent().throw(ExpectedError('second')))
386
401
        try:
387
402
            gevent.joinall([a, b], raise_error=True)
388
403
        except ExpectedError, ex:
389
404
            assert 'second' in str(ex), repr(str(ex))
 
405
        gevent.joinall([a, b])
390
406
 
391
407
    def test_multiple_listeners_error(self):
392
408
        # if there was an error while calling a callback
393
409
        # it should not prevent the other listeners from being called
394
410
        # also, all of the errors should be logged, check the output
395
411
        # manually that they are
396
 
        p = gevent.spawn(lambda : 5)
 
412
        p = gevent.spawn(lambda: 5)
397
413
        results = []
 
414
 
398
415
        def listener1(*args):
399
416
            results.append(10)
400
417
            raise ExpectedError('listener1')
 
418
 
401
419
        def listener2(*args):
402
420
            results.append(20)
403
421
            raise ExpectedError('listener2')
 
422
 
404
423
        def listener3(*args):
405
424
            raise ExpectedError('listener3')
 
425
 
406
426
        p.link(listener1)
407
427
        p.link(listener2)
408
428
        p.link(listener3)
409
 
        sleep(DELAY*10)
 
429
        sleep(DELAY * 10)
410
430
        assert results in [[10, 20], [20, 10]], results
411
431
 
412
 
        p = gevent.spawn(lambda : getcurrent().throw(ExpectedError('test_multiple_listeners_error')))
 
432
        p = gevent.spawn(lambda: getcurrent().throw(ExpectedError('test_multiple_listeners_error')))
413
433
        results = []
414
434
        p.link(listener1)
415
435
        p.link(listener2)
416
436
        p.link(listener3)
417
 
        sleep(DELAY*10)
 
437
        sleep(DELAY * 10)
418
438
        assert results in [[10, 20], [20, 10]], results
419
439
 
 
440
    class Results(object):
 
441
 
 
442
        def __init__(self):
 
443
            self.results = []
 
444
 
 
445
        def listener1(self, p):
 
446
            p.unlink(self.listener2)
 
447
            self.results.append(5)
 
448
            raise ExpectedError('listener1')
 
449
 
 
450
        def listener2(self, p):
 
451
            p.unlink(self.listener1)
 
452
            self.results.append(5)
 
453
            raise ExpectedError('listener2')
 
454
 
 
455
        def listener3(self, p):
 
456
            raise ExpectedError('listener3')
 
457
 
420
458
    def _test_multiple_listeners_error_unlink(self, p, link):
421
459
        # notification must not happen after unlink even
422
460
        # though notification process has been already started
423
 
        results = []
424
 
        def listener1(*args):
425
 
            p.unlink(listener2)
426
 
            results.append(5)
427
 
            raise ExpectedError('listener1')
428
 
        def listener2(*args):
429
 
            p.unlink(listener1)
430
 
            results.append(5)
431
 
            raise ExpectedError('listener2')
432
 
        def listener3(*args):
433
 
            raise ExpectedError('listener3')
434
 
        link(listener1)
435
 
        link(listener2)
436
 
        link(listener3)
437
 
        sleep(DELAY*10)
438
 
        assert results == [5], results
 
461
        results = self.Results()
 
462
 
 
463
        link(results.listener1)
 
464
        link(results.listener2)
 
465
        link(results.listener3)
 
466
        sleep(DELAY * 10)
 
467
        assert results.results == [5], results.results
439
468
 
440
469
    def test_multiple_listeners_error_unlink_Greenlet_link(self):
441
 
        p = gevent.spawn(lambda : 5)
 
470
        p = gevent.spawn(lambda: 5)
442
471
        self._test_multiple_listeners_error_unlink(p, p.link)
 
472
        p.kill()
443
473
 
444
474
    def test_multiple_listeners_error_unlink_Greenlet_rawlink(self):
445
 
        p = gevent.spawn(lambda : 5)
 
475
        p = gevent.spawn(lambda: 5)
446
476
        self._test_multiple_listeners_error_unlink(p, p.rawlink)
447
477
 
448
478
    def test_multiple_listeners_error_unlink_AsyncResult_rawlink(self):
452
482
 
453
483
    def test_killing_unlinked(self):
454
484
        e = AsyncResult()
 
485
 
455
486
        def func():
456
487
            try:
457
488
                raise ExpectedError('test_killing_unlinked')
458
489
            except:
459
490
                e.set_exception(sys.exc_info()[1])
 
491
 
460
492
        p = gevent.spawn_link(func)
461
493
        try:
462
494
            try:
464
496
            except ExpectedError:
465
497
                pass
466
498
        finally:
467
 
            p.unlink() # this disables LinkedCompleted that otherwise would be raised by the next line
 
499
            p.unlink()  # this disables LinkedCompleted that otherwise would be raised by the next line
468
500
        sleep(DELAY)
469
501
 
 
502
 
470
503
def test_func(*args):
471
504
    pass
472
505
 
 
506
 
473
507
class A(object):
474
508
 
475
509
    def method(self):
477
511
 
478
512
hexobj = re.compile('-?0x[0123456789abcdef]+L?', re.I)
479
513
 
 
514
 
480
515
class TestStr(greentest.TestCase):
481
516
 
482
517
    def test_function(self):
503
538
class TestJoin(greentest.GenericWaitTestCase):
504
539
 
505
540
    def wait(self, timeout):
506
 
        gevent.spawn(gevent.sleep, 10).join(timeout=timeout)
 
541
        self.g = gevent.spawn(gevent.sleep, 10)
 
542
        return self.g.join(timeout=timeout)
 
543
 
 
544
    def cleanup(self):
 
545
        self.g.kill()
 
546
 
507
547
 
508
548
class TestGet(greentest.GenericGetTestCase):
509
549
 
510
550
    def wait(self, timeout):
511
 
        gevent.spawn(gevent.sleep, 10).get(timeout=timeout)
 
551
        self.g = gevent.spawn(gevent.sleep, 10)
 
552
        return self.g.get(timeout=timeout)
 
553
 
 
554
    def cleanup(self):
 
555
        self.g.kill()
 
556
 
512
557
 
513
558
class TestJoinAll(greentest.GenericWaitTestCase):
514
559
 
515
560
    def wait(self, timeout):
516
 
        gevent.joinall([gevent.spawn(gevent.sleep, 10)], timeout=timeout)
 
561
        self.g = gevent.spawn(gevent.sleep, 10)
 
562
        gevent.joinall([self.g], timeout=timeout)
 
563
 
 
564
    def cleanup(self):
 
565
        self.g.kill()
517
566
 
518
567
 
519
568
class TestBasic(greentest.TestCase):
520
569
 
521
570
    def test_simple_exit(self):
522
571
        link_test = []
 
572
 
523
573
        def func(delay, return_value=4):
524
574
            gevent.sleep(delay)
525
575
            return return_value
 
576
 
526
577
        g = gevent.Greenlet(func, 0.01, return_value=5)
527
578
        g.link(lambda x: link_test.append(x))
528
579
        assert not g
543
594
        assert g.exception is None
544
595
 
545
596
        gevent.sleep(0.001)
546
 
        assert g # changed
 
597
        assert g  # changed
547
598
        assert not g.dead
548
599
        assert g.started
549
600
        assert not g.ready()
559
610
        assert g.ready()
560
611
        assert g.successful()
561
612
        assert g.value == 5
562
 
        assert g.exception is None # not changed
563
 
        assert link_test == [g] # changed
 
613
        assert g.exception is None  # not changed
 
614
        assert link_test == [g]  # changed
564
615
 
565
616
    def test_error_exit(self):
566
617
        link_test = []
 
618
 
567
619
        def func(delay, return_value=4):
568
620
            gevent.sleep(delay)
569
621
            error = ExpectedError('test_error_exit')
570
622
            error.myattr = return_value
571
623
            raise error
 
624
 
572
625
        g = gevent.Greenlet(func, 0.001, return_value=5)
573
626
        g.link(lambda x: link_test.append(x))
574
627
        g.start()
578
631
        assert not g.started
579
632
        assert g.ready()
580
633
        assert not g.successful()
581
 
        assert g.value is None # not changed
 
634
        assert g.value is None  # not changed
582
635
        assert g.exception.myattr == 5
583
636
        assert link_test == [g], link_test
584
637
 
608
661
    def _test_kill_not_started(self, block):
609
662
        link_test = []
610
663
        result = []
611
 
        g = gevent.Greenlet(lambda : result.append(1))
 
664
        g = gevent.Greenlet(lambda: result.append(1))
612
665
        g.link(lambda x: link_test.append(x))
613
666
        self._test_kill(g, block=block)
614
667
        assert not result
623
676
    def _test_kill_just_started(self, block):
624
677
        result = []
625
678
        link_test = []
626
 
        g = gevent.Greenlet(lambda : result.append(1))
 
679
        g = gevent.Greenlet(lambda: result.append(1))
627
680
        g.link(lambda x: link_test.append(x))
628
681
        g.start()
629
682
        self._test_kill(g, block=block)
639
692
    def _test_kill_just_started_later(self, block):
640
693
        result = []
641
694
        link_test = []
642
 
        g = gevent.Greenlet(lambda : result.append(1))
 
695
        g = gevent.Greenlet(lambda: result.append(1))
643
696
        g.link(lambda x: link_test.append(x))
644
697
        g.start_later(1)
645
698
        self._test_kill(g, block=block)
679
732
 
680
733
X = object()
681
734
 
682
 
if __name__=='__main__':
 
735
if __name__ == '__main__':
683
736
    greentest.main()
684