PageRenderTime 70ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_asyncio/test_tasks.py

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