PageRenderTime 56ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/Lib/test/test_asyncio/test_tasks.py

https://bitbucket.org/ncoghlan/cpython_sandbox
Python | 2451 lines | 1904 code | 448 blank | 99 comment | 128 complexity | 8e87dbc01358e48a10fa9822375037fe MD5 | raw file
Possible License(s): BSD-3-Clause, Unlicense, CC-BY-SA-3.0, 0BSD
  1. """Tests for tasks.py."""
  2. import contextlib
  3. import functools
  4. import io
  5. import os
  6. import re
  7. import sys
  8. import time
  9. import types
  10. import unittest
  11. import weakref
  12. from unittest import mock
  13. import asyncio
  14. from asyncio import coroutines
  15. from asyncio import test_utils
  16. try:
  17. from test import support
  18. except ImportError:
  19. from asyncio import test_support as support
  20. try:
  21. from test.support.script_helper import assert_python_ok
  22. except ImportError:
  23. try:
  24. from test.script_helper import assert_python_ok
  25. except ImportError:
  26. from asyncio.test_support import assert_python_ok
  27. PY34 = (sys.version_info >= (3, 4))
  28. PY35 = (sys.version_info >= (3, 5))
  29. @asyncio.coroutine
  30. def coroutine_function():
  31. pass
  32. @contextlib.contextmanager
  33. def set_coroutine_debug(enabled):
  34. coroutines = asyncio.coroutines
  35. old_debug = coroutines._DEBUG
  36. try:
  37. coroutines._DEBUG = enabled
  38. yield
  39. finally:
  40. coroutines._DEBUG = old_debug
  41. def format_coroutine(qualname, state, src, source_traceback, generator=False):
  42. if generator:
  43. state = '%s' % state
  44. else:
  45. state = '%s, defined' % state
  46. if source_traceback is not None:
  47. frame = source_traceback[-1]
  48. return ('coro=<%s() %s at %s> created at %s:%s'
  49. % (qualname, state, src, frame[0], frame[1]))
  50. else:
  51. return 'coro=<%s() %s at %s>' % (qualname, state, src)
  52. class Dummy:
  53. def __repr__(self):
  54. return '<Dummy>'
  55. def __call__(self, *args):
  56. pass
  57. class TaskTests(test_utils.TestCase):
  58. def setUp(self):
  59. self.loop = self.new_test_loop()
  60. def test_other_loop_future(self):
  61. other_loop = asyncio.new_event_loop()
  62. fut = asyncio.Future(loop=other_loop)
  63. @asyncio.coroutine
  64. def run(fut):
  65. yield from fut
  66. try:
  67. with self.assertRaisesRegex(RuntimeError,
  68. r'Task .* got Future .* attached'):
  69. self.loop.run_until_complete(run(fut))
  70. finally:
  71. other_loop.close()
  72. def test_task_class(self):
  73. @asyncio.coroutine
  74. def notmuch():
  75. return 'ok'
  76. t = asyncio.Task(notmuch(), loop=self.loop)
  77. self.loop.run_until_complete(t)
  78. self.assertTrue(t.done())
  79. self.assertEqual(t.result(), 'ok')
  80. self.assertIs(t._loop, self.loop)
  81. loop = asyncio.new_event_loop()
  82. self.set_event_loop(loop)
  83. t = asyncio.Task(notmuch(), loop=loop)
  84. self.assertIs(t._loop, loop)
  85. loop.run_until_complete(t)
  86. loop.close()
  87. def test_ensure_future_coroutine(self):
  88. @asyncio.coroutine
  89. def notmuch():
  90. return 'ok'
  91. t = asyncio.ensure_future(notmuch(), loop=self.loop)
  92. self.loop.run_until_complete(t)
  93. self.assertTrue(t.done())
  94. self.assertEqual(t.result(), 'ok')
  95. self.assertIs(t._loop, self.loop)
  96. loop = asyncio.new_event_loop()
  97. self.set_event_loop(loop)
  98. t = asyncio.ensure_future(notmuch(), loop=loop)
  99. self.assertIs(t._loop, loop)
  100. loop.run_until_complete(t)
  101. loop.close()
  102. def test_ensure_future_future(self):
  103. f_orig = asyncio.Future(loop=self.loop)
  104. f_orig.set_result('ko')
  105. f = asyncio.ensure_future(f_orig)
  106. self.loop.run_until_complete(f)
  107. self.assertTrue(f.done())
  108. self.assertEqual(f.result(), 'ko')
  109. self.assertIs(f, f_orig)
  110. loop = asyncio.new_event_loop()
  111. self.set_event_loop(loop)
  112. with self.assertRaises(ValueError):
  113. f = asyncio.ensure_future(f_orig, loop=loop)
  114. loop.close()
  115. f = asyncio.ensure_future(f_orig, loop=self.loop)
  116. self.assertIs(f, f_orig)
  117. def test_ensure_future_task(self):
  118. @asyncio.coroutine
  119. def notmuch():
  120. return 'ok'
  121. t_orig = asyncio.Task(notmuch(), loop=self.loop)
  122. t = asyncio.ensure_future(t_orig)
  123. self.loop.run_until_complete(t)
  124. self.assertTrue(t.done())
  125. self.assertEqual(t.result(), 'ok')
  126. self.assertIs(t, t_orig)
  127. loop = asyncio.new_event_loop()
  128. self.set_event_loop(loop)
  129. with self.assertRaises(ValueError):
  130. t = asyncio.ensure_future(t_orig, loop=loop)
  131. loop.close()
  132. t = asyncio.ensure_future(t_orig, loop=self.loop)
  133. self.assertIs(t, t_orig)
  134. @unittest.skipUnless(PY35, 'need python 3.5 or later')
  135. def test_ensure_future_awaitable(self):
  136. class Aw:
  137. def __init__(self, coro):
  138. self.coro = coro
  139. def __await__(self):
  140. return (yield from self.coro)
  141. @asyncio.coroutine
  142. def coro():
  143. return 'ok'
  144. loop = asyncio.new_event_loop()
  145. self.set_event_loop(loop)
  146. fut = asyncio.ensure_future(Aw(coro()), loop=loop)
  147. loop.run_until_complete(fut)
  148. assert fut.result() == 'ok'
  149. def test_ensure_future_neither(self):
  150. with self.assertRaises(TypeError):
  151. asyncio.ensure_future('ok')
  152. def test_async_warning(self):
  153. f = asyncio.Future(loop=self.loop)
  154. with self.assertWarnsRegex(DeprecationWarning,
  155. 'function is deprecated, use ensure_'):
  156. self.assertIs(f, asyncio.async(f))
  157. def test_get_stack(self):
  158. T = None
  159. @asyncio.coroutine
  160. def foo():
  161. yield from bar()
  162. @asyncio.coroutine
  163. def bar():
  164. # test get_stack()
  165. f = T.get_stack(limit=1)
  166. try:
  167. self.assertEqual(f[0].f_code.co_name, 'foo')
  168. finally:
  169. f = None
  170. # test print_stack()
  171. file = io.StringIO()
  172. T.print_stack(limit=1, file=file)
  173. file.seek(0)
  174. tb = file.read()
  175. self.assertRegex(tb, r'foo\(\) running')
  176. @asyncio.coroutine
  177. def runner():
  178. nonlocal T
  179. T = asyncio.ensure_future(foo(), loop=self.loop)
  180. yield from T
  181. self.loop.run_until_complete(runner())
  182. def test_task_repr(self):
  183. self.loop.set_debug(False)
  184. @asyncio.coroutine
  185. def notmuch():
  186. yield from []
  187. return 'abc'
  188. # test coroutine function
  189. self.assertEqual(notmuch.__name__, 'notmuch')
  190. if PY35:
  191. self.assertEqual(notmuch.__qualname__,
  192. 'TaskTests.test_task_repr.<locals>.notmuch')
  193. self.assertEqual(notmuch.__module__, __name__)
  194. filename, lineno = test_utils.get_function_source(notmuch)
  195. src = "%s:%s" % (filename, lineno)
  196. # test coroutine object
  197. gen = notmuch()
  198. if coroutines._DEBUG or PY35:
  199. coro_qualname = 'TaskTests.test_task_repr.<locals>.notmuch'
  200. else:
  201. coro_qualname = 'notmuch'
  202. self.assertEqual(gen.__name__, 'notmuch')
  203. if PY35:
  204. self.assertEqual(gen.__qualname__,
  205. coro_qualname)
  206. # test pending Task
  207. t = asyncio.Task(gen, loop=self.loop)
  208. t.add_done_callback(Dummy())
  209. coro = format_coroutine(coro_qualname, 'running', src,
  210. t._source_traceback, generator=True)
  211. self.assertEqual(repr(t),
  212. '<Task pending %s cb=[<Dummy>()]>' % coro)
  213. # test cancelling Task
  214. t.cancel() # Does not take immediate effect!
  215. self.assertEqual(repr(t),
  216. '<Task cancelling %s cb=[<Dummy>()]>' % coro)
  217. # test cancelled Task
  218. self.assertRaises(asyncio.CancelledError,
  219. self.loop.run_until_complete, t)
  220. coro = format_coroutine(coro_qualname, 'done', src,
  221. t._source_traceback)
  222. self.assertEqual(repr(t),
  223. '<Task cancelled %s>' % coro)
  224. # test finished Task
  225. t = asyncio.Task(notmuch(), loop=self.loop)
  226. self.loop.run_until_complete(t)
  227. coro = format_coroutine(coro_qualname, 'done', src,
  228. t._source_traceback)
  229. self.assertEqual(repr(t),
  230. "<Task finished %s result='abc'>" % coro)
  231. def test_task_repr_coro_decorator(self):
  232. self.loop.set_debug(False)
  233. @asyncio.coroutine
  234. def notmuch():
  235. # notmuch() function doesn't use yield from: it will be wrapped by
  236. # @coroutine decorator
  237. return 123
  238. # test coroutine function
  239. self.assertEqual(notmuch.__name__, 'notmuch')
  240. if PY35:
  241. self.assertEqual(notmuch.__qualname__,
  242. 'TaskTests.test_task_repr_coro_decorator'
  243. '.<locals>.notmuch')
  244. self.assertEqual(notmuch.__module__, __name__)
  245. # test coroutine object
  246. gen = notmuch()
  247. if coroutines._DEBUG or PY35:
  248. # On Python >= 3.5, generators now inherit the name of the
  249. # function, as expected, and have a qualified name (__qualname__
  250. # attribute).
  251. coro_name = 'notmuch'
  252. coro_qualname = ('TaskTests.test_task_repr_coro_decorator'
  253. '.<locals>.notmuch')
  254. else:
  255. # On Python < 3.5, generators inherit the name of the code, not of
  256. # the function. See: http://bugs.python.org/issue21205
  257. coro_name = coro_qualname = 'coro'
  258. self.assertEqual(gen.__name__, coro_name)
  259. if PY35:
  260. self.assertEqual(gen.__qualname__, coro_qualname)
  261. # test repr(CoroWrapper)
  262. if coroutines._DEBUG:
  263. # format the coroutine object
  264. if coroutines._DEBUG:
  265. filename, lineno = test_utils.get_function_source(notmuch)
  266. frame = gen._source_traceback[-1]
  267. coro = ('%s() running, defined at %s:%s, created at %s:%s'
  268. % (coro_qualname, filename, lineno,
  269. frame[0], frame[1]))
  270. else:
  271. code = gen.gi_code
  272. coro = ('%s() running at %s:%s'
  273. % (coro_qualname, code.co_filename,
  274. code.co_firstlineno))
  275. self.assertEqual(repr(gen), '<CoroWrapper %s>' % coro)
  276. # test pending Task
  277. t = asyncio.Task(gen, loop=self.loop)
  278. t.add_done_callback(Dummy())
  279. # format the coroutine object
  280. if coroutines._DEBUG:
  281. src = '%s:%s' % test_utils.get_function_source(notmuch)
  282. else:
  283. code = gen.gi_code
  284. src = '%s:%s' % (code.co_filename, code.co_firstlineno)
  285. coro = format_coroutine(coro_qualname, 'running', src,
  286. t._source_traceback,
  287. generator=not coroutines._DEBUG)
  288. self.assertEqual(repr(t),
  289. '<Task pending %s cb=[<Dummy>()]>' % coro)
  290. self.loop.run_until_complete(t)
  291. def test_task_repr_wait_for(self):
  292. self.loop.set_debug(False)
  293. @asyncio.coroutine
  294. def wait_for(fut):
  295. return (yield from fut)
  296. fut = asyncio.Future(loop=self.loop)
  297. task = asyncio.Task(wait_for(fut), loop=self.loop)
  298. test_utils.run_briefly(self.loop)
  299. self.assertRegex(repr(task),
  300. '<Task .* wait_for=%s>' % re.escape(repr(fut)))
  301. fut.set_result(None)
  302. self.loop.run_until_complete(task)
  303. def test_task_repr_partial_corowrapper(self):
  304. # Issue #222: repr(CoroWrapper) must not fail in debug mode if the
  305. # coroutine is a partial function
  306. with set_coroutine_debug(True):
  307. self.loop.set_debug(True)
  308. @asyncio.coroutine
  309. def func(x, y):
  310. yield from asyncio.sleep(0)
  311. partial_func = asyncio.coroutine(functools.partial(func, 1))
  312. task = self.loop.create_task(partial_func(2))
  313. # make warnings quiet
  314. task._log_destroy_pending = False
  315. self.addCleanup(task._coro.close)
  316. coro_repr = repr(task._coro)
  317. expected = ('<CoroWrapper TaskTests.test_task_repr_partial_corowrapper'
  318. '.<locals>.func(1)() running, ')
  319. self.assertTrue(coro_repr.startswith(expected),
  320. coro_repr)
  321. def test_task_basics(self):
  322. @asyncio.coroutine
  323. def outer():
  324. a = yield from inner1()
  325. b = yield from inner2()
  326. return a+b
  327. @asyncio.coroutine
  328. def inner1():
  329. return 42
  330. @asyncio.coroutine
  331. def inner2():
  332. return 1000
  333. t = outer()
  334. self.assertEqual(self.loop.run_until_complete(t), 1042)
  335. def test_cancel(self):
  336. def gen():
  337. when = yield
  338. self.assertAlmostEqual(10.0, when)
  339. yield 0
  340. loop = self.new_test_loop(gen)
  341. @asyncio.coroutine
  342. def task():
  343. yield from asyncio.sleep(10.0, loop=loop)
  344. return 12
  345. t = asyncio.Task(task(), loop=loop)
  346. loop.call_soon(t.cancel)
  347. with self.assertRaises(asyncio.CancelledError):
  348. loop.run_until_complete(t)
  349. self.assertTrue(t.done())
  350. self.assertTrue(t.cancelled())
  351. self.assertFalse(t.cancel())
  352. def test_cancel_yield(self):
  353. @asyncio.coroutine
  354. def task():
  355. yield
  356. yield
  357. return 12
  358. t = asyncio.Task(task(), loop=self.loop)
  359. test_utils.run_briefly(self.loop) # start coro
  360. t.cancel()
  361. self.assertRaises(
  362. asyncio.CancelledError, self.loop.run_until_complete, t)
  363. self.assertTrue(t.done())
  364. self.assertTrue(t.cancelled())
  365. self.assertFalse(t.cancel())
  366. def test_cancel_inner_future(self):
  367. f = asyncio.Future(loop=self.loop)
  368. @asyncio.coroutine
  369. def task():
  370. yield from f
  371. return 12
  372. t = asyncio.Task(task(), loop=self.loop)
  373. test_utils.run_briefly(self.loop) # start task
  374. f.cancel()
  375. with self.assertRaises(asyncio.CancelledError):
  376. self.loop.run_until_complete(t)
  377. self.assertTrue(f.cancelled())
  378. self.assertTrue(t.cancelled())
  379. def test_cancel_both_task_and_inner_future(self):
  380. f = asyncio.Future(loop=self.loop)
  381. @asyncio.coroutine
  382. def task():
  383. yield from f
  384. return 12
  385. t = asyncio.Task(task(), loop=self.loop)
  386. test_utils.run_briefly(self.loop)
  387. f.cancel()
  388. t.cancel()
  389. with self.assertRaises(asyncio.CancelledError):
  390. self.loop.run_until_complete(t)
  391. self.assertTrue(t.done())
  392. self.assertTrue(f.cancelled())
  393. self.assertTrue(t.cancelled())
  394. def test_cancel_task_catching(self):
  395. fut1 = asyncio.Future(loop=self.loop)
  396. fut2 = asyncio.Future(loop=self.loop)
  397. @asyncio.coroutine
  398. def task():
  399. yield from fut1
  400. try:
  401. yield from fut2
  402. except asyncio.CancelledError:
  403. return 42
  404. t = asyncio.Task(task(), loop=self.loop)
  405. test_utils.run_briefly(self.loop)
  406. self.assertIs(t._fut_waiter, fut1) # White-box test.
  407. fut1.set_result(None)
  408. test_utils.run_briefly(self.loop)
  409. self.assertIs(t._fut_waiter, fut2) # White-box test.
  410. t.cancel()
  411. self.assertTrue(fut2.cancelled())
  412. res = self.loop.run_until_complete(t)
  413. self.assertEqual(res, 42)
  414. self.assertFalse(t.cancelled())
  415. def test_cancel_task_ignoring(self):
  416. fut1 = asyncio.Future(loop=self.loop)
  417. fut2 = asyncio.Future(loop=self.loop)
  418. fut3 = asyncio.Future(loop=self.loop)
  419. @asyncio.coroutine
  420. def task():
  421. yield from fut1
  422. try:
  423. yield from fut2
  424. except asyncio.CancelledError:
  425. pass
  426. res = yield from fut3
  427. return res
  428. t = asyncio.Task(task(), loop=self.loop)
  429. test_utils.run_briefly(self.loop)
  430. self.assertIs(t._fut_waiter, fut1) # White-box test.
  431. fut1.set_result(None)
  432. test_utils.run_briefly(self.loop)
  433. self.assertIs(t._fut_waiter, fut2) # White-box test.
  434. t.cancel()
  435. self.assertTrue(fut2.cancelled())
  436. test_utils.run_briefly(self.loop)
  437. self.assertIs(t._fut_waiter, fut3) # White-box test.
  438. fut3.set_result(42)
  439. res = self.loop.run_until_complete(t)
  440. self.assertEqual(res, 42)
  441. self.assertFalse(fut3.cancelled())
  442. self.assertFalse(t.cancelled())
  443. def test_cancel_current_task(self):
  444. loop = asyncio.new_event_loop()
  445. self.set_event_loop(loop)
  446. @asyncio.coroutine
  447. def task():
  448. t.cancel()
  449. self.assertTrue(t._must_cancel) # White-box test.
  450. # The sleep should be cancelled immediately.
  451. yield from asyncio.sleep(100, loop=loop)
  452. return 12
  453. t = asyncio.Task(task(), loop=loop)
  454. self.assertRaises(
  455. asyncio.CancelledError, loop.run_until_complete, t)
  456. self.assertTrue(t.done())
  457. self.assertFalse(t._must_cancel) # White-box test.
  458. self.assertFalse(t.cancel())
  459. def test_stop_while_run_in_complete(self):
  460. def gen():
  461. when = yield
  462. self.assertAlmostEqual(0.1, when)
  463. when = yield 0.1
  464. self.assertAlmostEqual(0.2, when)
  465. when = yield 0.1
  466. self.assertAlmostEqual(0.3, when)
  467. yield 0.1
  468. loop = self.new_test_loop(gen)
  469. x = 0
  470. waiters = []
  471. @asyncio.coroutine
  472. def task():
  473. nonlocal x
  474. while x < 10:
  475. waiters.append(asyncio.sleep(0.1, loop=loop))
  476. yield from waiters[-1]
  477. x += 1
  478. if x == 2:
  479. loop.stop()
  480. t = asyncio.Task(task(), loop=loop)
  481. with self.assertRaises(RuntimeError) as cm:
  482. loop.run_until_complete(t)
  483. self.assertEqual(str(cm.exception),
  484. 'Event loop stopped before Future completed.')
  485. self.assertFalse(t.done())
  486. self.assertEqual(x, 2)
  487. self.assertAlmostEqual(0.3, loop.time())
  488. # close generators
  489. for w in waiters:
  490. w.close()
  491. t.cancel()
  492. self.assertRaises(asyncio.CancelledError, loop.run_until_complete, t)
  493. def test_wait_for(self):
  494. def gen():
  495. when = yield
  496. self.assertAlmostEqual(0.2, when)
  497. when = yield 0
  498. self.assertAlmostEqual(0.1, when)
  499. when = yield 0.1
  500. loop = self.new_test_loop(gen)
  501. foo_running = None
  502. @asyncio.coroutine
  503. def foo():
  504. nonlocal foo_running
  505. foo_running = True
  506. try:
  507. yield from asyncio.sleep(0.2, loop=loop)
  508. finally:
  509. foo_running = False
  510. return 'done'
  511. fut = asyncio.Task(foo(), loop=loop)
  512. with self.assertRaises(asyncio.TimeoutError):
  513. loop.run_until_complete(asyncio.wait_for(fut, 0.1, loop=loop))
  514. self.assertTrue(fut.done())
  515. # it should have been cancelled due to the timeout
  516. self.assertTrue(fut.cancelled())
  517. self.assertAlmostEqual(0.1, loop.time())
  518. self.assertEqual(foo_running, False)
  519. def test_wait_for_blocking(self):
  520. loop = self.new_test_loop()
  521. @asyncio.coroutine
  522. def coro():
  523. return 'done'
  524. res = loop.run_until_complete(asyncio.wait_for(coro(),
  525. timeout=None,
  526. loop=loop))
  527. self.assertEqual(res, 'done')
  528. def test_wait_for_with_global_loop(self):
  529. def gen():
  530. when = yield
  531. self.assertAlmostEqual(0.2, when)
  532. when = yield 0
  533. self.assertAlmostEqual(0.01, when)
  534. yield 0.01
  535. loop = self.new_test_loop(gen)
  536. @asyncio.coroutine
  537. def foo():
  538. yield from asyncio.sleep(0.2, loop=loop)
  539. return 'done'
  540. asyncio.set_event_loop(loop)
  541. try:
  542. fut = asyncio.Task(foo(), loop=loop)
  543. with self.assertRaises(asyncio.TimeoutError):
  544. loop.run_until_complete(asyncio.wait_for(fut, 0.01))
  545. finally:
  546. asyncio.set_event_loop(None)
  547. self.assertAlmostEqual(0.01, loop.time())
  548. self.assertTrue(fut.done())
  549. self.assertTrue(fut.cancelled())
  550. def test_wait_for_race_condition(self):
  551. def gen():
  552. yield 0.1
  553. yield 0.1
  554. yield 0.1
  555. loop = self.new_test_loop(gen)
  556. fut = asyncio.Future(loop=loop)
  557. task = asyncio.wait_for(fut, timeout=0.2, loop=loop)
  558. loop.call_later(0.1, fut.set_result, "ok")
  559. res = loop.run_until_complete(task)
  560. self.assertEqual(res, "ok")
  561. def test_wait(self):
  562. def gen():
  563. when = yield
  564. self.assertAlmostEqual(0.1, when)
  565. when = yield 0
  566. self.assertAlmostEqual(0.15, when)
  567. yield 0.15
  568. loop = self.new_test_loop(gen)
  569. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  570. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  571. @asyncio.coroutine
  572. def foo():
  573. done, pending = yield from asyncio.wait([b, a], loop=loop)
  574. self.assertEqual(done, set([a, b]))
  575. self.assertEqual(pending, set())
  576. return 42
  577. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  578. self.assertEqual(res, 42)
  579. self.assertAlmostEqual(0.15, loop.time())
  580. # Doing it again should take no time and exercise a different path.
  581. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  582. self.assertAlmostEqual(0.15, loop.time())
  583. self.assertEqual(res, 42)
  584. def test_wait_with_global_loop(self):
  585. def gen():
  586. when = yield
  587. self.assertAlmostEqual(0.01, when)
  588. when = yield 0
  589. self.assertAlmostEqual(0.015, when)
  590. yield 0.015
  591. loop = self.new_test_loop(gen)
  592. a = asyncio.Task(asyncio.sleep(0.01, loop=loop), loop=loop)
  593. b = asyncio.Task(asyncio.sleep(0.015, loop=loop), loop=loop)
  594. @asyncio.coroutine
  595. def foo():
  596. done, pending = yield from asyncio.wait([b, a])
  597. self.assertEqual(done, set([a, b]))
  598. self.assertEqual(pending, set())
  599. return 42
  600. asyncio.set_event_loop(loop)
  601. res = loop.run_until_complete(
  602. asyncio.Task(foo(), loop=loop))
  603. self.assertEqual(res, 42)
  604. def test_wait_duplicate_coroutines(self):
  605. @asyncio.coroutine
  606. def coro(s):
  607. return s
  608. c = coro('test')
  609. task = asyncio.Task(
  610. asyncio.wait([c, c, coro('spam')], loop=self.loop),
  611. loop=self.loop)
  612. done, pending = self.loop.run_until_complete(task)
  613. self.assertFalse(pending)
  614. self.assertEqual(set(f.result() for f in done), {'test', 'spam'})
  615. def test_wait_errors(self):
  616. self.assertRaises(
  617. ValueError, self.loop.run_until_complete,
  618. asyncio.wait(set(), loop=self.loop))
  619. # -1 is an invalid return_when value
  620. sleep_coro = asyncio.sleep(10.0, loop=self.loop)
  621. wait_coro = asyncio.wait([sleep_coro], return_when=-1, loop=self.loop)
  622. self.assertRaises(ValueError,
  623. self.loop.run_until_complete, wait_coro)
  624. sleep_coro.close()
  625. def test_wait_first_completed(self):
  626. def gen():
  627. when = yield
  628. self.assertAlmostEqual(10.0, when)
  629. when = yield 0
  630. self.assertAlmostEqual(0.1, when)
  631. yield 0.1
  632. loop = self.new_test_loop(gen)
  633. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  634. b = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  635. task = asyncio.Task(
  636. asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
  637. loop=loop),
  638. loop=loop)
  639. done, pending = loop.run_until_complete(task)
  640. self.assertEqual({b}, done)
  641. self.assertEqual({a}, pending)
  642. self.assertFalse(a.done())
  643. self.assertTrue(b.done())
  644. self.assertIsNone(b.result())
  645. self.assertAlmostEqual(0.1, loop.time())
  646. # move forward to close generator
  647. loop.advance_time(10)
  648. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  649. def test_wait_really_done(self):
  650. # there is possibility that some tasks in the pending list
  651. # became done but their callbacks haven't all been called yet
  652. @asyncio.coroutine
  653. def coro1():
  654. yield
  655. @asyncio.coroutine
  656. def coro2():
  657. yield
  658. yield
  659. a = asyncio.Task(coro1(), loop=self.loop)
  660. b = asyncio.Task(coro2(), loop=self.loop)
  661. task = asyncio.Task(
  662. asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
  663. loop=self.loop),
  664. loop=self.loop)
  665. done, pending = self.loop.run_until_complete(task)
  666. self.assertEqual({a, b}, done)
  667. self.assertTrue(a.done())
  668. self.assertIsNone(a.result())
  669. self.assertTrue(b.done())
  670. self.assertIsNone(b.result())
  671. def test_wait_first_exception(self):
  672. def gen():
  673. when = yield
  674. self.assertAlmostEqual(10.0, when)
  675. yield 0
  676. loop = self.new_test_loop(gen)
  677. # first_exception, task already has exception
  678. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  679. @asyncio.coroutine
  680. def exc():
  681. raise ZeroDivisionError('err')
  682. b = asyncio.Task(exc(), loop=loop)
  683. task = asyncio.Task(
  684. asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
  685. loop=loop),
  686. loop=loop)
  687. done, pending = loop.run_until_complete(task)
  688. self.assertEqual({b}, done)
  689. self.assertEqual({a}, pending)
  690. self.assertAlmostEqual(0, loop.time())
  691. # move forward to close generator
  692. loop.advance_time(10)
  693. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  694. def test_wait_first_exception_in_wait(self):
  695. def gen():
  696. when = yield
  697. self.assertAlmostEqual(10.0, when)
  698. when = yield 0
  699. self.assertAlmostEqual(0.01, when)
  700. yield 0.01
  701. loop = self.new_test_loop(gen)
  702. # first_exception, exception during waiting
  703. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  704. @asyncio.coroutine
  705. def exc():
  706. yield from asyncio.sleep(0.01, loop=loop)
  707. raise ZeroDivisionError('err')
  708. b = asyncio.Task(exc(), loop=loop)
  709. task = asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
  710. loop=loop)
  711. done, pending = loop.run_until_complete(task)
  712. self.assertEqual({b}, done)
  713. self.assertEqual({a}, pending)
  714. self.assertAlmostEqual(0.01, loop.time())
  715. # move forward to close generator
  716. loop.advance_time(10)
  717. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  718. def test_wait_with_exception(self):
  719. def gen():
  720. when = yield
  721. self.assertAlmostEqual(0.1, when)
  722. when = yield 0
  723. self.assertAlmostEqual(0.15, when)
  724. yield 0.15
  725. loop = self.new_test_loop(gen)
  726. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  727. @asyncio.coroutine
  728. def sleeper():
  729. yield from asyncio.sleep(0.15, loop=loop)
  730. raise ZeroDivisionError('really')
  731. b = asyncio.Task(sleeper(), loop=loop)
  732. @asyncio.coroutine
  733. def foo():
  734. done, pending = yield from asyncio.wait([b, a], loop=loop)
  735. self.assertEqual(len(done), 2)
  736. self.assertEqual(pending, set())
  737. errors = set(f for f in done if f.exception() is not None)
  738. self.assertEqual(len(errors), 1)
  739. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  740. self.assertAlmostEqual(0.15, loop.time())
  741. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  742. self.assertAlmostEqual(0.15, loop.time())
  743. def test_wait_with_timeout(self):
  744. def gen():
  745. when = yield
  746. self.assertAlmostEqual(0.1, when)
  747. when = yield 0
  748. self.assertAlmostEqual(0.15, when)
  749. when = yield 0
  750. self.assertAlmostEqual(0.11, when)
  751. yield 0.11
  752. loop = self.new_test_loop(gen)
  753. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  754. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  755. @asyncio.coroutine
  756. def foo():
  757. done, pending = yield from asyncio.wait([b, a], timeout=0.11,
  758. loop=loop)
  759. self.assertEqual(done, set([a]))
  760. self.assertEqual(pending, set([b]))
  761. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  762. self.assertAlmostEqual(0.11, loop.time())
  763. # move forward to close generator
  764. loop.advance_time(10)
  765. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  766. def test_wait_concurrent_complete(self):
  767. def gen():
  768. when = yield
  769. self.assertAlmostEqual(0.1, when)
  770. when = yield 0
  771. self.assertAlmostEqual(0.15, when)
  772. when = yield 0
  773. self.assertAlmostEqual(0.1, when)
  774. yield 0.1
  775. loop = self.new_test_loop(gen)
  776. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  777. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  778. done, pending = loop.run_until_complete(
  779. asyncio.wait([b, a], timeout=0.1, loop=loop))
  780. self.assertEqual(done, set([a]))
  781. self.assertEqual(pending, set([b]))
  782. self.assertAlmostEqual(0.1, loop.time())
  783. # move forward to close generator
  784. loop.advance_time(10)
  785. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  786. def test_as_completed(self):
  787. def gen():
  788. yield 0
  789. yield 0
  790. yield 0.01
  791. yield 0
  792. loop = self.new_test_loop(gen)
  793. # disable "slow callback" warning
  794. loop.slow_callback_duration = 1.0
  795. completed = set()
  796. time_shifted = False
  797. @asyncio.coroutine
  798. def sleeper(dt, x):
  799. nonlocal time_shifted
  800. yield from asyncio.sleep(dt, loop=loop)
  801. completed.add(x)
  802. if not time_shifted and 'a' in completed and 'b' in completed:
  803. time_shifted = True
  804. loop.advance_time(0.14)
  805. return x
  806. a = sleeper(0.01, 'a')
  807. b = sleeper(0.01, 'b')
  808. c = sleeper(0.15, 'c')
  809. @asyncio.coroutine
  810. def foo():
  811. values = []
  812. for f in asyncio.as_completed([b, c, a], loop=loop):
  813. values.append((yield from f))
  814. return values
  815. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  816. self.assertAlmostEqual(0.15, loop.time())
  817. self.assertTrue('a' in res[:2])
  818. self.assertTrue('b' in res[:2])
  819. self.assertEqual(res[2], 'c')
  820. # Doing it again should take no time and exercise a different path.
  821. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  822. self.assertAlmostEqual(0.15, loop.time())
  823. def test_as_completed_with_timeout(self):
  824. def gen():
  825. yield
  826. yield 0
  827. yield 0
  828. yield 0.1
  829. loop = self.new_test_loop(gen)
  830. a = asyncio.sleep(0.1, 'a', loop=loop)
  831. b = asyncio.sleep(0.15, 'b', loop=loop)
  832. @asyncio.coroutine
  833. def foo():
  834. values = []
  835. for f in asyncio.as_completed([a, b], timeout=0.12, loop=loop):
  836. if values:
  837. loop.advance_time(0.02)
  838. try:
  839. v = yield from f
  840. values.append((1, v))
  841. except asyncio.TimeoutError as exc:
  842. values.append((2, exc))
  843. return values
  844. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  845. self.assertEqual(len(res), 2, res)
  846. self.assertEqual(res[0], (1, 'a'))
  847. self.assertEqual(res[1][0], 2)
  848. self.assertIsInstance(res[1][1], asyncio.TimeoutError)
  849. self.assertAlmostEqual(0.12, loop.time())
  850. # move forward to close generator
  851. loop.advance_time(10)
  852. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  853. def test_as_completed_with_unused_timeout(self):
  854. def gen():
  855. yield
  856. yield 0
  857. yield 0.01
  858. loop = self.new_test_loop(gen)
  859. a = asyncio.sleep(0.01, 'a', loop=loop)
  860. @asyncio.coroutine
  861. def foo():
  862. for f in asyncio.as_completed([a], timeout=1, loop=loop):
  863. v = yield from f
  864. self.assertEqual(v, 'a')
  865. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  866. def test_as_completed_reverse_wait(self):
  867. def gen():
  868. yield 0
  869. yield 0.05
  870. yield 0
  871. loop = self.new_test_loop(gen)
  872. a = asyncio.sleep(0.05, 'a', loop=loop)
  873. b = asyncio.sleep(0.10, 'b', loop=loop)
  874. fs = {a, b}
  875. futs = list(asyncio.as_completed(fs, loop=loop))
  876. self.assertEqual(len(futs), 2)
  877. x = loop.run_until_complete(futs[1])
  878. self.assertEqual(x, 'a')
  879. self.assertAlmostEqual(0.05, loop.time())
  880. loop.advance_time(0.05)
  881. y = loop.run_until_complete(futs[0])
  882. self.assertEqual(y, 'b')
  883. self.assertAlmostEqual(0.10, loop.time())
  884. def test_as_completed_concurrent(self):
  885. def gen():
  886. when = yield
  887. self.assertAlmostEqual(0.05, when)
  888. when = yield 0
  889. self.assertAlmostEqual(0.05, when)
  890. yield 0.05
  891. loop = self.new_test_loop(gen)
  892. a = asyncio.sleep(0.05, 'a', loop=loop)
  893. b = asyncio.sleep(0.05, 'b', loop=loop)
  894. fs = {a, b}
  895. futs = list(asyncio.as_completed(fs, loop=loop))
  896. self.assertEqual(len(futs), 2)
  897. waiter = asyncio.wait(futs, loop=loop)
  898. done, pending = loop.run_until_complete(waiter)
  899. self.assertEqual(set(f.result() for f in done), {'a', 'b'})
  900. def test_as_completed_duplicate_coroutines(self):
  901. @asyncio.coroutine
  902. def coro(s):
  903. return s
  904. @asyncio.coroutine
  905. def runner():
  906. result = []
  907. c = coro('ham')
  908. for f in asyncio.as_completed([c, c, coro('spam')],
  909. loop=self.loop):
  910. result.append((yield from f))
  911. return result
  912. fut = asyncio.Task(runner(), loop=self.loop)
  913. self.loop.run_until_complete(fut)
  914. result = fut.result()
  915. self.assertEqual(set(result), {'ham', 'spam'})
  916. self.assertEqual(len(result), 2)
  917. def test_sleep(self):
  918. def gen():
  919. when = yield
  920. self.assertAlmostEqual(0.05, when)
  921. when = yield 0.05
  922. self.assertAlmostEqual(0.1, when)
  923. yield 0.05
  924. loop = self.new_test_loop(gen)
  925. @asyncio.coroutine
  926. def sleeper(dt, arg):
  927. yield from asyncio.sleep(dt/2, loop=loop)
  928. res = yield from asyncio.sleep(dt/2, arg, loop=loop)
  929. return res
  930. t = asyncio.Task(sleeper(0.1, 'yeah'), loop=loop)
  931. loop.run_until_complete(t)
  932. self.assertTrue(t.done())
  933. self.assertEqual(t.result(), 'yeah')
  934. self.assertAlmostEqual(0.1, loop.time())
  935. def test_sleep_cancel(self):
  936. def gen():
  937. when = yield
  938. self.assertAlmostEqual(10.0, when)
  939. yield 0
  940. loop = self.new_test_loop(gen)
  941. t = asyncio.Task(asyncio.sleep(10.0, 'yeah', loop=loop),
  942. loop=loop)
  943. handle = None
  944. orig_call_later = loop.call_later
  945. def call_later(delay, callback, *args):
  946. nonlocal handle
  947. handle = orig_call_later(delay, callback, *args)
  948. return handle
  949. loop.call_later = call_later
  950. test_utils.run_briefly(loop)
  951. self.assertFalse(handle._cancelled)
  952. t.cancel()
  953. test_utils.run_briefly(loop)
  954. self.assertTrue(handle._cancelled)
  955. def test_task_cancel_sleeping_task(self):
  956. def gen():
  957. when = yield
  958. self.assertAlmostEqual(0.1, when)
  959. when = yield 0
  960. self.assertAlmostEqual(5000, when)
  961. yield 0.1
  962. loop = self.new_test_loop(gen)
  963. @asyncio.coroutine
  964. def sleep(dt):
  965. yield from asyncio.sleep(dt, loop=loop)
  966. @asyncio.coroutine
  967. def doit():
  968. sleeper = asyncio.Task(sleep(5000), loop=loop)
  969. loop.call_later(0.1, sleeper.cancel)
  970. try:
  971. yield from sleeper
  972. except asyncio.CancelledError:
  973. return 'cancelled'
  974. else:
  975. return 'slept in'
  976. doer = doit()
  977. self.assertEqual(loop.run_until_complete(doer), 'cancelled')
  978. self.assertAlmostEqual(0.1, loop.time())
  979. def test_task_cancel_waiter_future(self):
  980. fut = asyncio.Future(loop=self.loop)
  981. @asyncio.coroutine
  982. def coro():
  983. yield from fut
  984. task = asyncio.Task(coro(), loop=self.loop)
  985. test_utils.run_briefly(self.loop)
  986. self.assertIs(task._fut_waiter, fut)
  987. task.cancel()
  988. test_utils.run_briefly(self.loop)
  989. self.assertRaises(
  990. asyncio.CancelledError, self.loop.run_until_complete, task)
  991. self.assertIsNone(task._fut_waiter)
  992. self.assertTrue(fut.cancelled())
  993. def test_step_in_completed_task(self):
  994. @asyncio.coroutine
  995. def notmuch():
  996. return 'ko'
  997. gen = notmuch()
  998. task = asyncio.Task(gen, loop=self.loop)
  999. task.set_result('ok')
  1000. self.assertRaises(AssertionError, task._step)
  1001. gen.close()
  1002. def test_step_result(self):
  1003. @asyncio.coroutine
  1004. def notmuch():
  1005. yield None
  1006. yield 1
  1007. return 'ko'
  1008. self.assertRaises(
  1009. RuntimeError, self.loop.run_until_complete, notmuch())
  1010. def test_step_result_future(self):
  1011. # If coroutine returns future, task waits on this future.
  1012. class Fut(asyncio.Future):
  1013. def __init__(self, *args, **kwds):
  1014. self.cb_added = False
  1015. super().__init__(*args, **kwds)
  1016. def add_done_callback(self, fn):
  1017. self.cb_added = True
  1018. super().add_done_callback(fn)
  1019. fut = Fut(loop=self.loop)
  1020. result = None
  1021. @asyncio.coroutine
  1022. def wait_for_future():
  1023. nonlocal result
  1024. result = yield from fut
  1025. t = asyncio.Task(wait_for_future(), loop=self.loop)
  1026. test_utils.run_briefly(self.loop)
  1027. self.assertTrue(fut.cb_added)
  1028. res = object()
  1029. fut.set_result(res)
  1030. test_utils.run_briefly(self.loop)
  1031. self.assertIs(res, result)
  1032. self.assertTrue(t.done())
  1033. self.assertIsNone(t.result())
  1034. def test_step_with_baseexception(self):
  1035. @asyncio.coroutine
  1036. def notmutch():
  1037. raise BaseException()
  1038. task = asyncio.Task(notmutch(), loop=self.loop)
  1039. self.assertRaises(BaseException, task._step)
  1040. self.assertTrue(task.done())
  1041. self.assertIsInstance(task.exception(), BaseException)
  1042. def test_baseexception_during_cancel(self):
  1043. def gen():
  1044. when = yield
  1045. self.assertAlmostEqual(10.0, when)
  1046. yield 0
  1047. loop = self.new_test_loop(gen)
  1048. @asyncio.coroutine
  1049. def sleeper():
  1050. yield from asyncio.sleep(10, loop=loop)
  1051. base_exc = BaseException()
  1052. @asyncio.coroutine
  1053. def notmutch():
  1054. try:
  1055. yield from sleeper()
  1056. except asyncio.CancelledError:
  1057. raise base_exc
  1058. task = asyncio.Task(notmutch(), loop=loop)
  1059. test_utils.run_briefly(loop)
  1060. task.cancel()
  1061. self.assertFalse(task.done())
  1062. self.assertRaises(BaseException, test_utils.run_briefly, loop)
  1063. self.assertTrue(task.done())
  1064. self.assertFalse(task.cancelled())
  1065. self.assertIs(task.exception(), base_exc)
  1066. def test_iscoroutinefunction(self):
  1067. def fn():
  1068. pass
  1069. self.assertFalse(asyncio.iscoroutinefunction(fn))
  1070. def fn1():
  1071. yield
  1072. self.assertFalse(asyncio.iscoroutinefunction(fn1))
  1073. @asyncio.coroutine
  1074. def fn2():
  1075. yield
  1076. self.assertTrue(asyncio.iscoroutinefunction(fn2))
  1077. def test_yield_vs_yield_from(self):
  1078. fut = asyncio.Future(loop=self.loop)
  1079. @asyncio.coroutine
  1080. def wait_for_future():
  1081. yield fut
  1082. task = wait_for_future()
  1083. with self.assertRaises(RuntimeError):
  1084. self.loop.run_until_complete(task)
  1085. self.assertFalse(fut.done())
  1086. def test_yield_vs_yield_from_generator(self):
  1087. @asyncio.coroutine
  1088. def coro():
  1089. yield
  1090. @asyncio.coroutine
  1091. def wait_for_future():
  1092. gen = coro()
  1093. try:
  1094. yield gen
  1095. finally:
  1096. gen.close()
  1097. task = wait_for_future()
  1098. self.assertRaises(
  1099. RuntimeError,
  1100. self.loop.run_until_complete, task)
  1101. def test_coroutine_non_gen_function(self):
  1102. @asyncio.coroutine
  1103. def func():
  1104. return 'test'
  1105. self.assertTrue(asyncio.iscoroutinefunction(func))
  1106. coro = func()
  1107. self.assertTrue(asyncio.iscoroutine(coro))
  1108. res = self.loop.run_until_complete(coro)
  1109. self.assertEqual(res, 'test')
  1110. def test_coroutine_non_gen_function_return_future(self):
  1111. fut = asyncio.Future(loop=self.loop)
  1112. @asyncio.coroutine
  1113. def func():
  1114. return fut
  1115. @asyncio.coroutine
  1116. def coro():
  1117. fut.set_result('test')
  1118. t1 = asyncio.Task(func(), loop=self.loop)
  1119. t2 = asyncio.Task(coro(), loop=self.loop)
  1120. res = self.loop.run_until_complete(t1)
  1121. self.assertEqual(res, 'test')
  1122. self.assertIsNone(t2.result())
  1123. def test_current_task(self):
  1124. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1125. @asyncio.coroutine
  1126. def coro(loop):
  1127. self.assertTrue(asyncio.Task.current_task(loop=loop) is task)
  1128. task = asyncio.Task(coro(self.loop), loop=self.loop)
  1129. self.loop.run_until_complete(task)
  1130. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1131. def test_current_task_with_interleaving_tasks(self):
  1132. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1133. fut1 = asyncio.Future(loop=self.loop)
  1134. fut2 = asyncio.Future(loop=self.loop)
  1135. @asyncio.coroutine
  1136. def coro1(loop):
  1137. self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
  1138. yield from fut1
  1139. self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
  1140. fut2.set_result(True)
  1141. @asyncio.coroutine
  1142. def coro2(loop):
  1143. self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
  1144. fut1.set_result(True)
  1145. yield from fut2
  1146. self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
  1147. task1 = asyncio.Task(coro1(self.loop), loop=self.loop)
  1148. task2 = asyncio.Task(coro2(self.loop), loop=self.loop)
  1149. self.loop.run_until_complete(asyncio.wait((task1, task2),
  1150. loop=self.loop))
  1151. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1152. # Some thorough tests for cancellation propagation through
  1153. # coroutines, tasks and wait().
  1154. def test_yield_future_passes_cancel(self):
  1155. # Cancelling outer() cancels inner() cancels waiter.
  1156. proof = 0
  1157. waiter = asyncio.Future(loop=self.loop)
  1158. @asyncio.coroutine
  1159. def inner():
  1160. nonlocal proof
  1161. try:
  1162. yield from waiter
  1163. except asyncio.CancelledError:
  1164. proof += 1
  1165. raise
  1166. else:
  1167. self.fail('got past sleep() in inner()')
  1168. @asyncio.coroutine
  1169. def outer():
  1170. nonlocal proof
  1171. try:
  1172. yield from inner()
  1173. except asyncio.CancelledError:
  1174. proof += 100 # Expect this path.
  1175. else:
  1176. proof += 10
  1177. f = asyncio.ensure_future(outer(), loop=self.loop)
  1178. test_utils.run_briefly(self.loop)
  1179. f.cancel()
  1180. self.loop.run_until_complete(f)
  1181. self.assertEqual(proof, 101)
  1182. self.assertTrue(waiter.cancelled())
  1183. def test_yield_wait_does_not_shield_cancel(self):
  1184. # Cancelling outer() makes wait() return early, leaves inner()
  1185. # running.
  1186. proof = 0
  1187. waiter = asyncio.Future(loop=self.loop)
  1188. @asyncio.coroutine
  1189. def inner():
  1190. nonlocal proof
  1191. yield from waiter
  1192. proof += 1
  1193. @asyncio.coroutine
  1194. def outer():
  1195. nonlocal proof
  1196. d, p = yield from asyncio.wait([inner()], loop=self.loop)
  1197. proof += 100
  1198. f = asyncio.ensure_future(outer(), loop=self.loop)
  1199. test_utils.run_briefly(self.loop)
  1200. f.cancel()
  1201. self.assertRaises(
  1202. asyncio.CancelledError, self.loop.run_until_complete, f)
  1203. waiter.set_result(None)
  1204. test_utils.run_briefly(self.loop)
  1205. self.assertEqual(proof, 1)
  1206. def test_shield_result(self):
  1207. inner = asyncio.Future(loop=self.loop)
  1208. outer = asyncio.shield(inner)
  1209. inner.set_result(42)
  1210. res = self.loop.run_until_complete(outer)
  1211. self.assertEqual(res, 42)
  1212. def test_shield_exception(self):
  1213. inner = asyncio.Future(loop=self.loop)
  1214. outer = asyncio.shield(inner)
  1215. test_utils.run_briefly(self.loop)
  1216. exc = RuntimeError('expected')
  1217. inner.set_exception(exc)
  1218. test_utils.run_briefly(self.loop)
  1219. self.assertIs(outer.exception(), exc)
  1220. def test_shield_cancel(self):
  1221. inner = asyncio.Future(loop=self.loop)
  1222. outer = asyncio.shield(inner)
  1223. test_utils.run_briefly(self.loop)
  1224. inner.cancel()
  1225. test_utils.run_briefly(self.loop)
  1226. self.assertTrue(outer.cancelled())
  1227. def test_shield_shortcut(self):
  1228. fut = asyncio.Future(loop=self.loop)
  1229. fut.set_result(42)
  1230. res = self.loop.run_until_complete(asyncio.shield(fut))
  1231. self.assertEqual(res, 42)
  1232. def test_shield_effect(self):
  1233. # Cancelling outer() does not affect inner().
  1234. proof = 0
  1235. waiter = asyncio.Future(loop=self.loop)
  1236. @asyncio.coroutine
  1237. def inner():
  1238. nonlocal proof
  1239. yield from waiter
  1240. proof += 1
  1241. @asyncio.coroutine
  1242. def outer():
  1243. nonlocal proof
  1244. yield from asyncio.shield(inner(), loop=self.loop)
  1245. proof += 100
  1246. f = asyncio.ensure_future(outer(), loop=self.loop)
  1247. test_utils.run_briefly(self.loop)
  1248. f.cancel()
  1249. with self.assertRaises(asyncio.CancelledError):
  1250. self.loop.run_until_complete(f)
  1251. waiter.set_result(None)
  1252. test_utils.run_briefly(self.loop)
  1253. self.assertEqual(proof, 1)
  1254. def test_shield_gather(self):
  1255. child1 = asyncio.Future(loop=self.loop)
  1256. child2 = asyncio.Future(loop=self.loop)
  1257. parent = asyncio.gather(child1, child2, loop=self.loop)
  1258. outer = asyncio.shield(parent, loop=self.loop)
  1259. test_utils.run_briefly(self.loop)
  1260. outer.cancel()
  1261. test_utils.run_briefly(self.loop)
  1262. self.assertTrue(outer.cancelled())
  1263. child1.set_result(1)
  1264. child2.set_result(2)
  1265. test_utils.run_briefly(self.loop)
  1266. self.assertEqual(parent.result(), [1, 2])
  1267. def test_gather_shield(self):
  1268. child1 = asyncio.Future(loop=self.loop)
  1269. child2 = asyncio.Future(loop=self.loop)
  1270. inner1 = asyncio.shield(child1, loop=self.loop)
  1271. inner2 = asyncio.shield(child2, loop=self.loop)
  1272. parent = asyncio.gather(inner1, inner2, loop=self.loop)
  1273. test_utils.run_briefly(self.loop)
  1274. parent.cancel()
  1275. # This should cancel inner1 and inner2 but bot child1 and child2.
  1276. test_utils.run_briefly(self.loop)
  1277. self.assertIsInstance(parent.exception(), asyncio.CancelledError)
  1278. self.assertTrue(inner1.cancelled())
  1279. self.assertTrue(inner2.cancelled())
  1280. child1.set_result(1)
  1281. child2.set_result(2)
  1282. test_utils.run_briefly(self.loop)
  1283. def test_as_completed_invalid_args(self):
  1284. fut = asyncio.Future(loop=self.loop)
  1285. # as_completed() expects a list of futures, not a future instance
  1286. self.assertRaises(TypeError, self.loop.run_until_complete,
  1287. asyncio.as_completed(fut, loop=self.loop))
  1288. coro = coroutine_function()
  1289. self.assertRaises(TypeError, self.loop.run_until_complete,
  1290. asyncio.as_completed(coro, loop=self.loop))
  1291. coro.close()
  1292. def test_wait_invalid_args(self):
  1293. fut = asyncio.Future(loop=self.loop)
  1294. # wait() expects a list of futures, not a future instance
  1295. self.assertRaises(TypeError, self.loop.run_until_complete,
  1296. asyncio.wait(fut, loop=self.loop))
  1297. coro = coroutine_function()
  1298. self.assertRaises(TypeError, self.loop.run_until_complete,
  1299. asyncio.wait(coro, loop=self.loop))
  1300. coro.close()
  1301. # wait() expects at least a future
  1302. self.assertRaises(ValueError, self.loop.run_until_complete,
  1303. asyncio.wait([], loop=self.loop))
  1304. def test_corowrapper_mocks_generator(self):
  1305. def check():
  1306. # A function that asserts various things.
  1307. # Called twice, with different debug flag values.
  1308. @asyncio.coroutine
  1309. def coro():
  1310. # The actual coroutine.
  1311. self.assertTrue(gen.gi_running)
  1312. yield from fut
  1313. # A completed Future used to run the coroutine.
  1314. fut = asyncio.Future(loop=self.loop)
  1315. fut.set_result(None)
  1316. # Call the coroutine.
  1317. gen = coro()
  1318. # Check some properties.
  1319. self.assertTrue(asyncio.iscoroutine(gen))
  1320. self.assertIsInstance(gen.gi_frame, types.FrameType)
  1321. self.assertFalse(gen.gi_running)
  1322. self.assertIsInstance(gen.gi_code, types.CodeType)
  1323. # Run it.
  1324. self.loop.run_until_complete(gen)
  1325. # The frame should have changed.
  1326. self.assertIsNone(gen.gi_frame)
  1327. # Test with debug flag cleared.
  1328. with set_coroutine_debug(False):
  1329. check()
  1330. # Test with debug flag set.
  1331. with set_coroutine_debug(True):
  1332. check()
  1333. def test_yield_from_corowrapper(self):
  1334. with set_coroutine_debug(True):
  1335. @asyncio.coroutine
  1336. def t1():
  1337. return (yield from t2())
  1338. @asyncio.coroutine
  1339. def t2():
  1340. f = asyncio.Future(loop=self.loop)
  1341. asyncio.Task(t3(f), loop=self.loop)
  1342. return (yield from f)
  1343. @asyncio.coroutine
  1344. def t3(f):
  1345. f.set_result((1, 2, 3))
  1346. task = asyncio.Task(t1(), loop=self.loop)
  1347. val = self.loop.run_until_complete(task)
  1348. self.assertEqual(val, (1, 2, 3))
  1349. def test_yield_from_corowrapper_send(self):
  1350. def foo():
  1351. a = yield
  1352. return a
  1353. def call(arg):
  1354. cw = asyncio.coroutines.CoroWrapper(foo())
  1355. cw.send(None)
  1356. try:
  1357. cw.send(arg)
  1358. except StopIteration as ex:
  1359. return ex.args[0]
  1360. else:
  1361. raise AssertionError('StopIteration was expected')
  1362. self.assertEqual(call((1, 2)), (1, 2))
  1363. self.assertEqual(call('spam'), 'spam')
  1364. def test_corowrapper_weakref(self):
  1365. wd = weakref.WeakValueDictionary()
  1366. def foo(): yield from []
  1367. cw = asyncio.coroutines.CoroWrapper(foo())
  1368. wd['cw'] = cw # Would fail without __weakref__ slot.
  1369. cw.gen = None # Suppress warning from __del__.
  1370. @unittest.skipUnless(PY34,
  1371. 'need python 3.4 or later')
  1372. def test_log_destroyed_pending_task(self):
  1373. @asyncio.coroutine
  1374. def kill_me(loop):
  1375. future = asyncio.Future(loop=loop)
  1376. yield from future
  1377. # at this point, the only reference to kill_me() task is
  1378. # the Task._wakeup() method in future._callbacks
  1379. raise Exception("code never reached")
  1380. mock_handler = mock.Mock()
  1381. self.loop.set_debug(True)
  1382. self.loop.set_exception_handler(mock_handler)
  1383. # schedule the task
  1384. coro = kill_me(self.loop)
  1385. task = asyncio.ensure_future(coro, loop=self.loop)
  1386. self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), {task})
  1387. # execute the task so it waits for future
  1388. self.loop._run_once()
  1389. self.assertEqual(len(self.loop._ready), 0)
  1390. # remove the future used in kill_me(), and references to the task
  1391. del coro.gi_frame.f_locals['future']
  1392. coro = None
  1393. source_traceback = task._source_traceback
  1394. task = None
  1395. # no more reference to kill_me() task: the task is destroyed by the GC
  1396. support.gc_collect()
  1397. self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), set())
  1398. mock_handler.assert_called_with(self.loop, {
  1399. 'message': 'Task was destroyed but it is pending!',
  1400. 'task': mock.ANY,
  1401. 'source_traceback': source_traceback,
  1402. })
  1403. mock_handler.reset_mock()
  1404. @mock.patch('asyncio.coroutines.logger')
  1405. def test_coroutine_never_yielded(self, m_log):
  1406. with set_coroutine_debug(True):
  1407. @asyncio.coroutine
  1408. def coro_noop():
  1409. pass
  1410. tb_filename = __file__
  1411. tb_lineno = sys._getframe().f_lineno + 2
  1412. # create a coroutine object but don't use it
  1413. coro_noop()
  1414. support.gc_collect()
  1415. self.assertTrue(m_log.error.called)
  1416. message = m_log.error.call_args[0][0]
  1417. func_filename, func_lineno = test_utils.get_function_source(coro_noop)
  1418. regex = (r'^<CoroWrapper %s\(?\)? .* at %s:%s, .*> '
  1419. r'was never yielded from\n'
  1420. r'Coroutine object created at \(most recent call last\):\n'
  1421. r'.*\n'
  1422. r' File "%s", line %s, in test_coroutine_never_yielded\n'
  1423. r' coro_noop\(\)$'
  1424. % (re.escape(coro_noop.__qualname__),
  1425. re.escape(func_filename), func_lineno,
  1426. re.escape(tb_filename), tb_lineno))
  1427. self.assertRegex(message, re.compile(regex, re.DOTALL))
  1428. def test_return_coroutine_from_coroutine(self):
  1429. """Return of @asyncio.coroutine()-wrapped function generator object
  1430. from @asyncio.coroutine()-wrapped function should have same effect as
  1431. returning generator object or Future."""
  1432. def check():
  1433. @asyncio.coroutine
  1434. def outer_coro():
  1435. @asyncio.coroutine
  1436. def inner_coro():
  1437. return 1
  1438. return inner_coro()
  1439. result = self.loop.run_until_complete(outer_coro())
  1440. self.assertEqual(result, 1)
  1441. # Test with debug flag cleared.
  1442. with set_coroutine_debug(False):
  1443. check()
  1444. # Test with debug flag set.
  1445. with set_coroutine_debug(True):
  1446. check()
  1447. def test_task_source_traceback(self):
  1448. self.loop.set_debug(True)
  1449. task = asyncio.Task(coroutine_function(), loop=self.loop)
  1450. lineno = sys._getframe().f_lineno - 1
  1451. self.assertIsInstance(task._source_traceback, list)
  1452. self.assertEqual(task._source_traceback[-1][:3],
  1453. (__file__,
  1454. lineno,
  1455. 'test_task_source_traceback'))
  1456. self.loop.run_until_complete(task)
  1457. def _test_cancel_wait_for(self, timeout):
  1458. loop = asyncio.new_event_loop()
  1459. self.addCleanup(loop.close)
  1460. @asyncio.coroutine
  1461. def blocking_coroutine():
  1462. fut = asyncio.Future(loop=loop)
  1463. # Block: fut result is never set
  1464. yield from fut
  1465. task = loop.create_task(blocking_coroutine())
  1466. wait = loop.create_task(asyncio.wait_for(task, timeout, loop=loop))
  1467. loop.call_soon(wait.cancel)
  1468. self.assertRaises(asyncio.CancelledError,
  1469. loop.run_until_complete, wait)
  1470. # Python issue #23219: cancelling the wait must also cancel the task
  1471. self.assertTrue(task.cancelled())
  1472. def test_cancel_blocking_wait_for(self):
  1473. self._test_cancel_wait_for(None)
  1474. def test_cancel_wait_for(self):
  1475. self._test_cancel_wait_for(60.0)
  1476. class GatherTestsBase:
  1477. def setUp(self):
  1478. self.one_loop = self.new_test_loop()
  1479. self.other_loop = self.new_test_loop()
  1480. self.set_event_loop(self.one_loop, cleanup=False)
  1481. def _run_loop(self, loop):
  1482. while loop._ready:
  1483. test_utils.run_briefly(loop)
  1484. def _check_success(self, **kwargs):
  1485. a, b, c = [asyncio.Future(loop=self.one_loop) for i in range(3)]
  1486. fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs)
  1487. cb = test_utils.MockCallback()
  1488. fut.add_done_callback(cb)
  1489. b.set_result(1)
  1490. a.set_result(2)
  1491. self._run_loop(self.one_loop)
  1492. self.assertEqual(cb.called, False)
  1493. self.assertFalse(fut.done())
  1494. c.set_result(3)
  1495. self._run_loop(self.one_loop)
  1496. cb.assert_called_once_with(fut)
  1497. self.assertEqual(fut.result(), [2, 1, 3])
  1498. def test_success(self):
  1499. self._check_success()
  1500. self._check_success(return_exceptions=False)
  1501. def test_result_exception_success(self):
  1502. self._check_success(return_exceptions=True)
  1503. def test_one_exception(self):
  1504. a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
  1505. fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e))
  1506. cb = test_utils.MockCallback()
  1507. fut.add_done_callback(cb)
  1508. exc = ZeroDivisionError()
  1509. a.set_result(1)
  1510. b.set_exception(exc)
  1511. self._run_loop(self.one_loop)
  1512. self.assertTrue(fut.done())
  1513. cb.assert_called_once_with(fut)
  1514. self.assertIs(fut.exception(), exc)
  1515. # Does nothing
  1516. c.set_result(3)
  1517. d.cancel()
  1518. e.set_exception(RuntimeError())
  1519. e.exception()
  1520. def test_return_exceptions(self):
  1521. a, b, c, d = [asyncio.Future(loop=self.one_loop) for i in range(4)]
  1522. fut = asyncio.gather(*self.wrap_futures(a, b, c, d),
  1523. return_exceptions=True)
  1524. cb = test_utils.MockCallback()
  1525. fut.add_done_callback(cb)
  1526. exc = ZeroDivisionError()
  1527. exc2 = RuntimeError()
  1528. b.set_result(1)
  1529. c.set_exception(exc)
  1530. a.set_result(3)
  1531. self._run_loop(self.one_loop)
  1532. self.assertFalse(fut.done())
  1533. d.set_exception(exc2)
  1534. self._run_loop(self.one_loop)
  1535. self.assertTrue(fut.done())
  1536. cb.assert_called_once_with(fut)
  1537. self.assertEqual(fut.result(), [3, 1, exc, exc2])
  1538. def test_env_var_debug(self):
  1539. aio_path = os.path.dirname(os.path.dirname(asyncio.__file__))
  1540. code = '\n'.join((
  1541. 'import asyncio.coroutines',
  1542. 'print(asyncio.coroutines._DEBUG)'))
  1543. # Test with -E to not fail if the unit test was run with
  1544. # PYTHONASYNCIODEBUG set to a non-empty string
  1545. sts, stdout, stderr = assert_python_ok('-E', '-c', code,
  1546. PYTHONPATH=aio_path)
  1547. self.assertEqual(stdout.rstrip(), b'False')
  1548. sts, stdout, stderr = assert_python_ok('-c', code,
  1549. PYTHONASYNCIODEBUG='',
  1550. PYTHONPATH=aio_path)
  1551. self.assertEqual(stdout.rstrip(), b'False')
  1552. sts, stdout, stderr = assert_python_ok('-c', code,
  1553. PYTHONASYNCIODEBUG='1',
  1554. PYTHONPATH=aio_path)
  1555. self.assertEqual(stdout.rstrip(), b'True')
  1556. sts, stdout, stderr = assert_python_ok('-E', '-c', code,
  1557. PYTHONASYNCIODEBUG='1',
  1558. PYTHONPATH=aio_path)
  1559. self.assertEqual(stdout.rstrip(), b'False')
  1560. class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
  1561. def wrap_futures(self, *futures):
  1562. return futures
  1563. def _check_empty_sequence(self, seq_or_iter):
  1564. asyncio.set_event_loop(self.one_loop)
  1565. self.addCleanup(asyncio.set_event_loop, None)
  1566. fut = asyncio.gather(*seq_or_iter)
  1567. self.assertIsInstance(fut, asyncio.Future)
  1568. self.assertIs(fut._loop, self.one_loop)
  1569. self._run_loop(self.one_loop)
  1570. self.assertTrue(fut.done())
  1571. self.assertEqual(fut.result(), [])
  1572. fut = asyncio.gather(*seq_or_iter, loop=self.other_loop)
  1573. self.assertIs(fut._loop, self.other_loop)
  1574. def test_constructor_empty_sequence(self):
  1575. self._check_empty_sequence([])
  1576. self._check_empty_sequence(())
  1577. self._check_empty_sequence(set())
  1578. self._check_empty_sequence(iter(""))
  1579. def test_constructor_heterogenous_futures(self):
  1580. fut1 = asyncio.Future(loop=self.one_loop)
  1581. fut2 = asyncio.Future(loop=self.other_loop)
  1582. with self.assertRaises(ValueError):
  1583. asyncio.gather(fut1, fut2)
  1584. with self.assertRaises(ValueError):
  1585. asyncio.gather(fut1, loop=self.other_loop)
  1586. def test_constructor_homogenous_futures(self):
  1587. children = [asyncio.Future(loop=self.other_loop) for i in range(3)]
  1588. fut = asyncio.gather(*children)
  1589. self.assertIs(fut._loop, self.other_loop)
  1590. self._run_loop(self.other_loop)
  1591. self.assertFalse(fut.done())
  1592. fut = asyncio.gather(*children, loop=self.other_loop)
  1593. self.assertIs(fut._loop, self.other_loop)
  1594. self._run_loop(self.other_loop)
  1595. self.assertFalse(fut.done())
  1596. def test_one_cancellation(self):
  1597. a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
  1598. fut = asyncio.gather(a, b, c, d, e)
  1599. cb = test_utils.MockCallback()
  1600. fut.add_done_callback(cb)
  1601. a.set_result(1)
  1602. b.cancel()
  1603. self._run_loop(self.one_loop)
  1604. self.assertTrue(fut.done())
  1605. cb.assert_called_once_with(fut)
  1606. self.assertFalse(fut.cancelled())
  1607. self.assertIsInstance(fut.exception(), asyncio.CancelledError)
  1608. # Does nothing
  1609. c.set_result(3)
  1610. d.cancel()
  1611. e.set_exception(RuntimeError())
  1612. e.exception()
  1613. def test_result_exception_one_cancellation(self):
  1614. a, b, c, d, e, f = [asyncio.Future(loop=self.one_loop)
  1615. for i in range(6)]
  1616. fut = asyncio.gather(a, b, c, d, e, f, return_exceptions=True)
  1617. cb = test_utils.MockCallback()
  1618. fut.add_done_callback(cb)
  1619. a.set_result(1)
  1620. zde = ZeroDivisionError()
  1621. b.set_exception(zde)
  1622. c.cancel()
  1623. self._run_loop(self.one_loop)
  1624. self.assertFalse(fut.done())
  1625. d.set_result(3)
  1626. e.cancel()
  1627. rte = RuntimeError()
  1628. f.set_exception(rte)
  1629. res = self.one_loop.run_until_complete(fut)
  1630. self.assertIsInstance(res[2], asyncio.CancelledError)
  1631. self.assertIsInstance(res[4], asyncio.CancelledError)
  1632. res[2] = res[4] = None
  1633. self.assertEqual(res, [1, zde, None, 3, None, rte])
  1634. cb.assert_called_once_with(fut)
  1635. class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
  1636. def setUp(self):
  1637. super().setUp()
  1638. asyncio.set_event_loop(self.one_loop)
  1639. def wrap_futures(self, *futures):
  1640. coros = []
  1641. for fut in futures:
  1642. @asyncio.coroutine
  1643. def coro(fut=fut):
  1644. return (yield from fut)
  1645. coros.append(coro())
  1646. return coros
  1647. def test_constructor_loop_selection(self):
  1648. @asyncio.coroutine
  1649. def coro():
  1650. return 'abc'
  1651. gen1 = coro()
  1652. gen2 = coro()
  1653. fut = asyncio.gather(gen1, gen2)
  1654. self.assertIs(fut._loop, self.one_loop)
  1655. self.one_loop.run_until_complete(fut)
  1656. self.set_event_loop(self.other_loop, cleanup=False)
  1657. gen3 = coro()
  1658. gen4 = coro()
  1659. fut2 = asyncio.gather(gen3, gen4, loop=self.other_loop)
  1660. self.assertIs(fut2._loop, self.other_loop)
  1661. self.other_loop.run_until_complete(fut2)
  1662. def test_duplicate_coroutines(self):
  1663. @asyncio.coroutine
  1664. def coro(s):
  1665. return s
  1666. c = coro('abc')
  1667. fut = asyncio.gather(c, c, coro('def'), c, loop=self.one_loop)
  1668. self._run_loop(self.one_loop)
  1669. self.assertEqual(fut.result(), ['abc', 'abc', 'def', 'abc'])
  1670. def test_cancellation_broadcast(self):
  1671. # Cancelling outer() cancels all children.
  1672. proof = 0
  1673. waiter = asyncio.Future(loop=self.one_loop)
  1674. @asyncio.coroutine
  1675. def inner():
  1676. nonlocal proof
  1677. yield from waiter
  1678. proof += 1
  1679. child1 = asyncio.ensure_future(inner(), loop=self.one_loop)
  1680. child2 = asyncio.ensure_future(inner(), loop=self.one_loop)
  1681. gatherer = None
  1682. @asyncio.coroutine
  1683. def outer():
  1684. nonlocal proof, gatherer
  1685. gatherer = asyncio.gather(child1, child2, loop=self.one_loop)
  1686. yield from gatherer
  1687. proof += 100
  1688. f = asyncio.ensure_future(outer(), loop=self.one_loop)
  1689. test_utils.run_briefly(self.one_loop)
  1690. self.assertTrue(f.cancel())
  1691. with self.assertRaises(asyncio.CancelledError):
  1692. self.one_loop.run_until_complete(f)
  1693. self.assertFalse(gatherer.cancel())
  1694. self.assertTrue(waiter.cancelled())
  1695. self.assertTrue(child1.cancelled())
  1696. self.assertTrue(child2.cancelled())
  1697. test_utils.run_briefly(self.one_loop)
  1698. self.assertEqual(proof, 0)
  1699. def test_exception_marking(self):
  1700. # Test for the first line marked "Mark exception retrieved."
  1701. @asyncio.coroutine
  1702. def inner(f):
  1703. yield from f
  1704. raise RuntimeError('should not be ignored')
  1705. a = asyncio.Future(loop=self.one_loop)
  1706. b = asyncio.Future(loop=self.one_loop)
  1707. @asyncio.coroutine
  1708. def outer():
  1709. yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop)
  1710. f = asyncio.ensure_future(outer(), loop=self.one_loop)
  1711. test_utils.run_briefly(self.one_loop)
  1712. a.set_result(None)
  1713. test_utils.run_briefly(self.one_loop)
  1714. b.set_result(None)
  1715. test_utils.run_briefly(self.one_loop)
  1716. self.assertIsInstance(f.exception(), RuntimeError)
  1717. class RunCoroutineThreadsafeTests(test_utils.TestCase):
  1718. """Test case for asyncio.run_coroutine_threadsafe."""
  1719. def setUp(self):
  1720. self.loop = asyncio.new_event_loop()
  1721. self.set_event_loop(self.loop) # Will cleanup properly
  1722. @asyncio.coroutine
  1723. def add(self, a, b, fail=False, cancel=False):
  1724. """Wait 0.05 second and return a + b."""
  1725. yield from asyncio.sleep(0.05, loop=self.loop)
  1726. if fail:
  1727. raise RuntimeError("Fail!")
  1728. if cancel:
  1729. asyncio.tasks.Task.current_task(self.loop).cancel()
  1730. yield
  1731. return a + b
  1732. def target(self, fail=False, cancel=False, timeout=None,
  1733. advance_coro=False):
  1734. """Run add coroutine in the event loop."""
  1735. coro = self.add(1, 2, fail=fail, cancel=cancel)
  1736. future = asyncio.run_coroutine_threadsafe(coro, self.loop)
  1737. if advance_coro:
  1738. # this is for test_run_coroutine_threadsafe_task_factory_exception;
  1739. # otherwise it spills errors and breaks **other** unittests, since
  1740. # 'target' is interacting with threads.
  1741. # With this call, `coro` will be advanced, so that
  1742. # CoroWrapper.__del__ won't do anything when asyncio tests run
  1743. # in debug mode.
  1744. self.loop.call_soon_threadsafe(coro.send, None)
  1745. try:
  1746. return future.result(timeout)
  1747. finally:
  1748. future.done() or future.cancel()
  1749. def test_run_coroutine_threadsafe(self):
  1750. """Test coroutine submission from a thread to an event loop."""
  1751. future = self.loop.run_in_executor(None, self.target)
  1752. result = self.loop.run_until_complete(future)
  1753. self.assertEqual(result, 3)
  1754. def test_run_coroutine_threadsafe_with_exception(self):
  1755. """Test coroutine submission from a thread to an event loop
  1756. when an exception is raised."""
  1757. future = self.loop.run_in_executor(None, self.target, True)
  1758. with self.assertRaises(RuntimeError) as exc_context:
  1759. self.loop.run_until_complete(future)
  1760. self.assertIn("Fail!", exc_context.exception.args)
  1761. def test_run_coroutine_threadsafe_with_timeout(self):
  1762. """Test coroutine submission from a thread to an event loop
  1763. when a timeout is raised."""
  1764. callback = lambda: self.target(timeout=0)
  1765. future = self.loop.run_in_executor(None, callback)
  1766. with self.assertRaises(asyncio.TimeoutError):
  1767. self.loop.run_until_complete(future)
  1768. test_utils.run_briefly(self.loop)
  1769. # Check that there's no pending task (add has been cancelled)
  1770. for task in asyncio.Task.all_tasks(self.loop):
  1771. self.assertTrue(task.done())
  1772. def test_run_coroutine_threadsafe_task_cancelled(self):
  1773. """Test coroutine submission from a tread to an event loop
  1774. when the task is cancelled."""
  1775. callback = lambda: self.target(cancel=True)
  1776. future = self.loop.run_in_executor(None, callback)
  1777. with self.assertRaises(asyncio.CancelledError):
  1778. self.loop.run_until_complete(future)
  1779. def test_run_coroutine_threadsafe_task_factory_exception(self):
  1780. """Test coroutine submission from a tread to an event loop
  1781. when the task factory raise an exception."""
  1782. # Schedule the target
  1783. future = self.loop.run_in_executor(
  1784. None, lambda: self.target(advance_coro=True))
  1785. # Set corrupted task factory
  1786. self.loop.set_task_factory(lambda loop, coro: wrong_name)
  1787. # Set exception handler
  1788. callback = test_utils.MockCallback()
  1789. self.loop.set_exception_handler(callback)
  1790. # Run event loop
  1791. with self.assertRaises(NameError) as exc_context:
  1792. self.loop.run_until_complete(future)
  1793. # Check exceptions
  1794. self.assertIn('wrong_name', exc_context.exception.args[0])
  1795. self.assertEqual(len(callback.call_args_list), 1)
  1796. (loop, context), kwargs = callback.call_args
  1797. self.assertEqual(context['exception'], exc_context.exception)
  1798. class SleepTests(test_utils.TestCase):
  1799. def setUp(self):
  1800. self.loop = asyncio.new_event_loop()
  1801. asyncio.set_event_loop(None)
  1802. def tearDown(self):
  1803. self.loop.close()
  1804. self.loop = None
  1805. def test_sleep_zero(self):
  1806. result = 0
  1807. def inc_result(num):
  1808. nonlocal result
  1809. result += num
  1810. @asyncio.coroutine
  1811. def coro():
  1812. self.loop.call_soon(inc_result, 1)
  1813. self.assertEqual(result, 0)
  1814. num = yield from asyncio.sleep(0, loop=self.loop, result=10)
  1815. self.assertEqual(result, 1) # inc'ed by call_soon
  1816. inc_result(num) # num should be 11
  1817. self.loop.run_until_complete(coro())
  1818. self.assertEqual(result, 11)
  1819. class TimeoutTests(test_utils.TestCase):
  1820. def setUp(self):
  1821. self.loop = asyncio.new_event_loop()
  1822. asyncio.set_event_loop(None)
  1823. def tearDown(self):
  1824. self.loop.close()
  1825. self.loop = None
  1826. def test_timeout(self):
  1827. canceled_raised = [False]
  1828. @asyncio.coroutine
  1829. def long_running_task():
  1830. try:
  1831. yield from asyncio.sleep(10, loop=self.loop)
  1832. except asyncio.CancelledError:
  1833. canceled_raised[0] = True
  1834. raise
  1835. @asyncio.coroutine
  1836. def go():
  1837. with self.assertRaises(asyncio.TimeoutError):
  1838. with asyncio.timeout(0.01, loop=self.loop) as t:
  1839. yield from long_running_task()
  1840. self.assertIs(t._loop, self.loop)
  1841. self.loop.run_until_complete(go())
  1842. self.assertTrue(canceled_raised[0], 'CancelledError was not raised')
  1843. def test_timeout_finish_in_time(self):
  1844. @asyncio.coroutine
  1845. def long_running_task():
  1846. yield from asyncio.sleep(0.01, loop=self.loop)
  1847. return 'done'
  1848. @asyncio.coroutine
  1849. def go():
  1850. with asyncio.timeout(0.1, loop=self.loop):
  1851. resp = yield from long_running_task()
  1852. self.assertEqual(resp, 'done')
  1853. self.loop.run_until_complete(go())
  1854. def test_timeout_gloabal_loop(self):
  1855. asyncio.set_event_loop(self.loop)
  1856. @asyncio.coroutine
  1857. def run():
  1858. with asyncio.timeout(0.1) as t:
  1859. yield from asyncio.sleep(0.01)
  1860. self.assertIs(t._loop, self.loop)
  1861. self.loop.run_until_complete(run())
  1862. def test_timeout_not_relevant_exception(self):
  1863. @asyncio.coroutine
  1864. def go():
  1865. yield from asyncio.sleep(0, loop=self.loop)
  1866. with self.assertRaises(KeyError):
  1867. with asyncio.timeout(0.1, loop=self.loop):
  1868. raise KeyError
  1869. self.loop.run_until_complete(go())
  1870. def test_timeout_canceled_error_is_converted_to_timeout(self):
  1871. @asyncio.coroutine
  1872. def go():
  1873. yield from asyncio.sleep(0, loop=self.loop)
  1874. with self.assertRaises(asyncio.CancelledError):
  1875. with asyncio.timeout(0.001, loop=self.loop):
  1876. raise asyncio.CancelledError
  1877. self.loop.run_until_complete(go())
  1878. def test_timeout_blocking_loop(self):
  1879. @asyncio.coroutine
  1880. def long_running_task():
  1881. time.sleep(0.05)
  1882. return 'done'
  1883. @asyncio.coroutine
  1884. def go():
  1885. with asyncio.timeout(0.01, loop=self.loop):
  1886. result = yield from long_running_task()
  1887. self.assertEqual(result, 'done')
  1888. self.loop.run_until_complete(go())
  1889. def test_for_race_conditions(self):
  1890. fut = asyncio.Future(loop=self.loop)
  1891. self.loop.call_later(0.1, fut.set_result('done'))
  1892. @asyncio.coroutine
  1893. def go():
  1894. with asyncio.timeout(0.2, loop=self.loop):
  1895. resp = yield from fut
  1896. self.assertEqual(resp, 'done')
  1897. self.loop.run_until_complete(go())
  1898. def test_timeout_time(self):
  1899. @asyncio.coroutine
  1900. def go():
  1901. foo_running = None
  1902. start = self.loop.time()
  1903. with self.assertRaises(asyncio.TimeoutError):
  1904. with asyncio.timeout(0.1, loop=self.loop):
  1905. foo_running = True
  1906. try:
  1907. yield from asyncio.sleep(0.2, loop=self.loop)
  1908. finally:
  1909. foo_running = False
  1910. dt = self.loop.time() - start
  1911. # tolerate a small delta for slow delta or unstable clocks
  1912. self.assertTrue(0.09 < dt < 0.12, dt)
  1913. self.assertFalse(foo_running)
  1914. self.loop.run_until_complete(go())
  1915. def test_timeout_disable(self):
  1916. @asyncio.coroutine
  1917. def long_running_task():
  1918. yield from asyncio.sleep(0.1, loop=self.loop)
  1919. return 'done'
  1920. @asyncio.coroutine
  1921. def go():
  1922. t0 = self.loop.time()
  1923. with asyncio.timeout(None, loop=self.loop):
  1924. resp = yield from long_running_task()
  1925. self.assertEqual(resp, 'done')
  1926. dt = self.loop.time() - t0
  1927. # tolerate a time delta for clocks with bad resolution
  1928. # and slow buildbots
  1929. self.assertTrue(0.09 < dt < 0.15, dt)
  1930. self.loop.run_until_complete(go())
  1931. def test_raise_runtimeerror_if_no_task(self):
  1932. with self.assertRaises(RuntimeError):
  1933. with asyncio.timeout(0.1, loop=self.loop):
  1934. pass
  1935. def test_outer_coro_is_not_cancelled(self):
  1936. has_timeout = [False]
  1937. @asyncio.coroutine
  1938. def outer():
  1939. try:
  1940. with asyncio.timeout(0.001, loop=self.loop):
  1941. yield from asyncio.sleep(1, loop=self.loop)
  1942. except asyncio.TimeoutError:
  1943. has_timeout[0] = True
  1944. @asyncio.coroutine
  1945. def go():
  1946. task = asyncio.ensure_future(outer(), loop=self.loop)
  1947. yield from task
  1948. self.assertTrue(has_timeout[0])
  1949. self.assertFalse(task.cancelled())
  1950. self.assertTrue(task.done())
  1951. self.loop.run_until_complete(go())
  1952. def test_cancel_outer_coro(self):
  1953. fut = asyncio.Future(loop=self.loop)
  1954. @asyncio.coroutine
  1955. def outer():
  1956. fut.set_result(None)
  1957. yield from asyncio.sleep(1, loop=self.loop)
  1958. @asyncio.coroutine
  1959. def go():
  1960. task = asyncio.ensure_future(outer(), loop=self.loop)
  1961. yield from fut
  1962. task.cancel()
  1963. with self.assertRaises(asyncio.CancelledError):
  1964. yield from task
  1965. self.assertTrue(task.cancelled())
  1966. self.assertTrue(task.done())
  1967. self.loop.run_until_complete(go())
  1968. if __name__ == '__main__':
  1969. unittest.main()