85 lines
2.4 KiB
Text
85 lines
2.4 KiB
Text
# Copyright (c) Twisted Matrix Laboratories.
|
|
# See LICENSE for details.
|
|
|
|
"""
|
|
Test cases for L{twisted.internet.defer} on Python 3.5 and later.
|
|
|
|
This file is loaded by C{test_defer.py} only when running on an
|
|
interpreter version that supports the C{async} and C{await} keywords.
|
|
"""
|
|
|
|
|
|
import functools
|
|
|
|
|
|
from twisted.internet import defer
|
|
from twisted.trial import unittest
|
|
|
|
|
|
|
|
def ensuringDeferred(f):
|
|
@functools.wraps(f)
|
|
def wrapper(*args, **kwargs):
|
|
result = f(*args, **kwargs)
|
|
return defer.ensureDeferred(result)
|
|
return wrapper
|
|
|
|
|
|
|
|
class DeferredTestsAsync(unittest.TestCase):
|
|
|
|
|
|
@ensuringDeferred
|
|
async def test_asyncWithLock(self):
|
|
"""
|
|
L{defer.DeferredLock} can be used as an asynchronous context manager.
|
|
"""
|
|
lock = defer.DeferredLock()
|
|
async with lock:
|
|
self.assertTrue(lock.locked)
|
|
d = lock.acquire()
|
|
d.addCallback(lambda _: lock.release())
|
|
self.assertTrue(lock.locked)
|
|
self.assertFalse(d.called)
|
|
self.assertTrue(d.called)
|
|
await d
|
|
self.assertFalse(lock.locked)
|
|
|
|
|
|
@ensuringDeferred
|
|
async def test_asyncWithSemaphore(self):
|
|
"""
|
|
L{defer.DeferredSemaphore} can be used as an asynchronous context manager.
|
|
"""
|
|
sem = defer.DeferredSemaphore(3)
|
|
|
|
async with sem:
|
|
self.assertEqual(sem.tokens, 2)
|
|
async with sem:
|
|
self.assertEqual(sem.tokens, 1)
|
|
d1 = sem.acquire()
|
|
d2 = sem.acquire()
|
|
self.assertEqual(sem.tokens, 0)
|
|
self.assertTrue(d1.called)
|
|
self.assertFalse(d2.called)
|
|
self.assertEqual(sem.tokens, 0)
|
|
self.assertTrue(d2.called)
|
|
d1.addCallback(lambda _: sem.release())
|
|
d2.addCallback(lambda _: sem.release())
|
|
await d1
|
|
await d2
|
|
self.assertEqual(sem.tokens, 2)
|
|
self.assertEqual(sem.tokens, 3)
|
|
|
|
@ensuringDeferred
|
|
async def test_asyncWithLockException(self):
|
|
"""
|
|
C{defer.DeferredLock} correctly propagates exceptions when
|
|
used as an asynchronous context manager.
|
|
"""
|
|
lock = defer.DeferredLock()
|
|
with self.assertRaisesRegexp(Exception, 'some specific exception'):
|
|
async with lock:
|
|
self.assertTrue(lock.locked)
|
|
raise Exception('some specific exception')
|
|
self.assertFalse(lock.locked)
|