PageRenderTime 77ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_asyncio/test_tasks.py

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