PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_asyncio/test_tasks.py

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