PageRenderTime 63ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/Lib/test/test_asyncio/test_tasks.py

https://bitbucket.org/andrea_crotti/cpython
Python | 1555 lines | 1246 code | 284 blank | 25 comment | 50 complexity | 062e46209efc40a9f786637afe1f679f MD5 | raw file
Possible License(s): BSD-3-Clause, 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_with_global_loop(self):
  307. def gen():
  308. when = yield
  309. self.assertAlmostEqual(0.2, when)
  310. when = yield 0
  311. self.assertAlmostEqual(0.01, when)
  312. yield 0.01
  313. loop = test_utils.TestLoop(gen)
  314. self.addCleanup(loop.close)
  315. @asyncio.coroutine
  316. def foo():
  317. yield from asyncio.sleep(0.2, loop=loop)
  318. return 'done'
  319. asyncio.set_event_loop(loop)
  320. try:
  321. fut = asyncio.Task(foo(), loop=loop)
  322. with self.assertRaises(asyncio.TimeoutError):
  323. loop.run_until_complete(asyncio.wait_for(fut, 0.01))
  324. finally:
  325. asyncio.set_event_loop(None)
  326. self.assertAlmostEqual(0.01, loop.time())
  327. self.assertTrue(fut.done())
  328. self.assertTrue(fut.cancelled())
  329. def test_wait(self):
  330. def gen():
  331. when = yield
  332. self.assertAlmostEqual(0.1, when)
  333. when = yield 0
  334. self.assertAlmostEqual(0.15, when)
  335. yield 0.15
  336. loop = test_utils.TestLoop(gen)
  337. self.addCleanup(loop.close)
  338. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  339. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  340. @asyncio.coroutine
  341. def foo():
  342. done, pending = yield from asyncio.wait([b, a], loop=loop)
  343. self.assertEqual(done, set([a, b]))
  344. self.assertEqual(pending, set())
  345. return 42
  346. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  347. self.assertEqual(res, 42)
  348. self.assertAlmostEqual(0.15, loop.time())
  349. # Doing it again should take no time and exercise a different path.
  350. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  351. self.assertAlmostEqual(0.15, loop.time())
  352. self.assertEqual(res, 42)
  353. def test_wait_with_global_loop(self):
  354. def gen():
  355. when = yield
  356. self.assertAlmostEqual(0.01, when)
  357. when = yield 0
  358. self.assertAlmostEqual(0.015, when)
  359. yield 0.015
  360. loop = test_utils.TestLoop(gen)
  361. self.addCleanup(loop.close)
  362. a = asyncio.Task(asyncio.sleep(0.01, loop=loop), loop=loop)
  363. b = asyncio.Task(asyncio.sleep(0.015, loop=loop), loop=loop)
  364. @asyncio.coroutine
  365. def foo():
  366. done, pending = yield from asyncio.wait([b, a])
  367. self.assertEqual(done, set([a, b]))
  368. self.assertEqual(pending, set())
  369. return 42
  370. asyncio.set_event_loop(loop)
  371. try:
  372. res = loop.run_until_complete(
  373. asyncio.Task(foo(), loop=loop))
  374. finally:
  375. asyncio.set_event_loop(None)
  376. self.assertEqual(res, 42)
  377. def test_wait_errors(self):
  378. self.assertRaises(
  379. ValueError, self.loop.run_until_complete,
  380. asyncio.wait(set(), loop=self.loop))
  381. self.assertRaises(
  382. ValueError, self.loop.run_until_complete,
  383. asyncio.wait([asyncio.sleep(10.0, loop=self.loop)],
  384. return_when=-1, loop=self.loop))
  385. def test_wait_first_completed(self):
  386. def gen():
  387. when = yield
  388. self.assertAlmostEqual(10.0, when)
  389. when = yield 0
  390. self.assertAlmostEqual(0.1, when)
  391. yield 0.1
  392. loop = test_utils.TestLoop(gen)
  393. self.addCleanup(loop.close)
  394. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  395. b = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  396. task = asyncio.Task(
  397. asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
  398. loop=loop),
  399. loop=loop)
  400. done, pending = loop.run_until_complete(task)
  401. self.assertEqual({b}, done)
  402. self.assertEqual({a}, pending)
  403. self.assertFalse(a.done())
  404. self.assertTrue(b.done())
  405. self.assertIsNone(b.result())
  406. self.assertAlmostEqual(0.1, loop.time())
  407. # move forward to close generator
  408. loop.advance_time(10)
  409. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  410. def test_wait_really_done(self):
  411. # there is possibility that some tasks in the pending list
  412. # became done but their callbacks haven't all been called yet
  413. @asyncio.coroutine
  414. def coro1():
  415. yield
  416. @asyncio.coroutine
  417. def coro2():
  418. yield
  419. yield
  420. a = asyncio.Task(coro1(), loop=self.loop)
  421. b = asyncio.Task(coro2(), loop=self.loop)
  422. task = asyncio.Task(
  423. asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
  424. loop=self.loop),
  425. loop=self.loop)
  426. done, pending = self.loop.run_until_complete(task)
  427. self.assertEqual({a, b}, done)
  428. self.assertTrue(a.done())
  429. self.assertIsNone(a.result())
  430. self.assertTrue(b.done())
  431. self.assertIsNone(b.result())
  432. def test_wait_first_exception(self):
  433. def gen():
  434. when = yield
  435. self.assertAlmostEqual(10.0, when)
  436. yield 0
  437. loop = test_utils.TestLoop(gen)
  438. self.addCleanup(loop.close)
  439. # first_exception, task already has exception
  440. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  441. @asyncio.coroutine
  442. def exc():
  443. raise ZeroDivisionError('err')
  444. b = asyncio.Task(exc(), loop=loop)
  445. task = asyncio.Task(
  446. asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
  447. loop=loop),
  448. loop=loop)
  449. done, pending = loop.run_until_complete(task)
  450. self.assertEqual({b}, done)
  451. self.assertEqual({a}, pending)
  452. self.assertAlmostEqual(0, loop.time())
  453. # move forward to close generator
  454. loop.advance_time(10)
  455. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  456. def test_wait_first_exception_in_wait(self):
  457. def gen():
  458. when = yield
  459. self.assertAlmostEqual(10.0, when)
  460. when = yield 0
  461. self.assertAlmostEqual(0.01, when)
  462. yield 0.01
  463. loop = test_utils.TestLoop(gen)
  464. self.addCleanup(loop.close)
  465. # first_exception, exception during waiting
  466. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  467. @asyncio.coroutine
  468. def exc():
  469. yield from asyncio.sleep(0.01, loop=loop)
  470. raise ZeroDivisionError('err')
  471. b = asyncio.Task(exc(), loop=loop)
  472. task = asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
  473. loop=loop)
  474. done, pending = loop.run_until_complete(task)
  475. self.assertEqual({b}, done)
  476. self.assertEqual({a}, pending)
  477. self.assertAlmostEqual(0.01, loop.time())
  478. # move forward to close generator
  479. loop.advance_time(10)
  480. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  481. def test_wait_with_exception(self):
  482. def gen():
  483. when = yield
  484. self.assertAlmostEqual(0.1, when)
  485. when = yield 0
  486. self.assertAlmostEqual(0.15, when)
  487. yield 0.15
  488. loop = test_utils.TestLoop(gen)
  489. self.addCleanup(loop.close)
  490. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  491. @asyncio.coroutine
  492. def sleeper():
  493. yield from asyncio.sleep(0.15, loop=loop)
  494. raise ZeroDivisionError('really')
  495. b = asyncio.Task(sleeper(), loop=loop)
  496. @asyncio.coroutine
  497. def foo():
  498. done, pending = yield from asyncio.wait([b, a], loop=loop)
  499. self.assertEqual(len(done), 2)
  500. self.assertEqual(pending, set())
  501. errors = set(f for f in done if f.exception() is not None)
  502. self.assertEqual(len(errors), 1)
  503. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  504. self.assertAlmostEqual(0.15, loop.time())
  505. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  506. self.assertAlmostEqual(0.15, loop.time())
  507. def test_wait_with_timeout(self):
  508. def gen():
  509. when = yield
  510. self.assertAlmostEqual(0.1, when)
  511. when = yield 0
  512. self.assertAlmostEqual(0.15, when)
  513. when = yield 0
  514. self.assertAlmostEqual(0.11, when)
  515. yield 0.11
  516. loop = test_utils.TestLoop(gen)
  517. self.addCleanup(loop.close)
  518. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  519. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  520. @asyncio.coroutine
  521. def foo():
  522. done, pending = yield from asyncio.wait([b, a], timeout=0.11,
  523. loop=loop)
  524. self.assertEqual(done, set([a]))
  525. self.assertEqual(pending, set([b]))
  526. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  527. self.assertAlmostEqual(0.11, loop.time())
  528. # move forward to close generator
  529. loop.advance_time(10)
  530. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  531. def test_wait_concurrent_complete(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.1, when)
  539. yield 0.1
  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. done, pending = loop.run_until_complete(
  545. asyncio.wait([b, a], timeout=0.1, loop=loop))
  546. self.assertEqual(done, set([a]))
  547. self.assertEqual(pending, set([b]))
  548. self.assertAlmostEqual(0.1, loop.time())
  549. # move forward to close generator
  550. loop.advance_time(10)
  551. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  552. def test_as_completed(self):
  553. def gen():
  554. yield 0
  555. yield 0
  556. yield 0.01
  557. yield 0
  558. loop = test_utils.TestLoop(gen)
  559. self.addCleanup(loop.close)
  560. completed = set()
  561. time_shifted = False
  562. @asyncio.coroutine
  563. def sleeper(dt, x):
  564. nonlocal time_shifted
  565. yield from asyncio.sleep(dt, loop=loop)
  566. completed.add(x)
  567. if not time_shifted and 'a' in completed and 'b' in completed:
  568. time_shifted = True
  569. loop.advance_time(0.14)
  570. return x
  571. a = sleeper(0.01, 'a')
  572. b = sleeper(0.01, 'b')
  573. c = sleeper(0.15, 'c')
  574. @asyncio.coroutine
  575. def foo():
  576. values = []
  577. for f in asyncio.as_completed([b, c, a], loop=loop):
  578. values.append((yield from f))
  579. return values
  580. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  581. self.assertAlmostEqual(0.15, loop.time())
  582. self.assertTrue('a' in res[:2])
  583. self.assertTrue('b' in res[:2])
  584. self.assertEqual(res[2], 'c')
  585. # Doing it again should take no time and exercise a different path.
  586. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  587. self.assertAlmostEqual(0.15, loop.time())
  588. def test_as_completed_with_timeout(self):
  589. def gen():
  590. when = yield
  591. self.assertAlmostEqual(0.12, when)
  592. when = yield 0
  593. self.assertAlmostEqual(0.1, when)
  594. when = yield 0
  595. self.assertAlmostEqual(0.15, when)
  596. when = yield 0.1
  597. self.assertAlmostEqual(0.12, when)
  598. yield 0.02
  599. loop = test_utils.TestLoop(gen)
  600. self.addCleanup(loop.close)
  601. a = asyncio.sleep(0.1, 'a', loop=loop)
  602. b = asyncio.sleep(0.15, 'b', loop=loop)
  603. @asyncio.coroutine
  604. def foo():
  605. values = []
  606. for f in asyncio.as_completed([a, b], timeout=0.12, loop=loop):
  607. try:
  608. v = yield from f
  609. values.append((1, v))
  610. except asyncio.TimeoutError as exc:
  611. values.append((2, exc))
  612. return values
  613. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  614. self.assertEqual(len(res), 2, res)
  615. self.assertEqual(res[0], (1, 'a'))
  616. self.assertEqual(res[1][0], 2)
  617. self.assertIsInstance(res[1][1], asyncio.TimeoutError)
  618. self.assertAlmostEqual(0.12, loop.time())
  619. # move forward to close generator
  620. loop.advance_time(10)
  621. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  622. def test_as_completed_reverse_wait(self):
  623. def gen():
  624. yield 0
  625. yield 0.05
  626. yield 0
  627. loop = test_utils.TestLoop(gen)
  628. self.addCleanup(loop.close)
  629. a = asyncio.sleep(0.05, 'a', loop=loop)
  630. b = asyncio.sleep(0.10, 'b', loop=loop)
  631. fs = {a, b}
  632. futs = list(asyncio.as_completed(fs, loop=loop))
  633. self.assertEqual(len(futs), 2)
  634. x = loop.run_until_complete(futs[1])
  635. self.assertEqual(x, 'a')
  636. self.assertAlmostEqual(0.05, loop.time())
  637. loop.advance_time(0.05)
  638. y = loop.run_until_complete(futs[0])
  639. self.assertEqual(y, 'b')
  640. self.assertAlmostEqual(0.10, loop.time())
  641. def test_as_completed_concurrent(self):
  642. def gen():
  643. when = yield
  644. self.assertAlmostEqual(0.05, when)
  645. when = yield 0
  646. self.assertAlmostEqual(0.05, when)
  647. yield 0.05
  648. loop = test_utils.TestLoop(gen)
  649. self.addCleanup(loop.close)
  650. a = asyncio.sleep(0.05, 'a', loop=loop)
  651. b = asyncio.sleep(0.05, 'b', loop=loop)
  652. fs = {a, b}
  653. futs = list(asyncio.as_completed(fs, loop=loop))
  654. self.assertEqual(len(futs), 2)
  655. waiter = asyncio.wait(futs, loop=loop)
  656. done, pending = loop.run_until_complete(waiter)
  657. self.assertEqual(set(f.result() for f in done), {'a', 'b'})
  658. def test_sleep(self):
  659. def gen():
  660. when = yield
  661. self.assertAlmostEqual(0.05, when)
  662. when = yield 0.05
  663. self.assertAlmostEqual(0.1, when)
  664. yield 0.05
  665. loop = test_utils.TestLoop(gen)
  666. self.addCleanup(loop.close)
  667. @asyncio.coroutine
  668. def sleeper(dt, arg):
  669. yield from asyncio.sleep(dt/2, loop=loop)
  670. res = yield from asyncio.sleep(dt/2, arg, loop=loop)
  671. return res
  672. t = asyncio.Task(sleeper(0.1, 'yeah'), loop=loop)
  673. loop.run_until_complete(t)
  674. self.assertTrue(t.done())
  675. self.assertEqual(t.result(), 'yeah')
  676. self.assertAlmostEqual(0.1, loop.time())
  677. def test_sleep_cancel(self):
  678. def gen():
  679. when = yield
  680. self.assertAlmostEqual(10.0, when)
  681. yield 0
  682. loop = test_utils.TestLoop(gen)
  683. self.addCleanup(loop.close)
  684. t = asyncio.Task(asyncio.sleep(10.0, 'yeah', loop=loop),
  685. loop=loop)
  686. handle = None
  687. orig_call_later = loop.call_later
  688. def call_later(self, delay, callback, *args):
  689. nonlocal handle
  690. handle = orig_call_later(self, delay, callback, *args)
  691. return handle
  692. loop.call_later = call_later
  693. test_utils.run_briefly(loop)
  694. self.assertFalse(handle._cancelled)
  695. t.cancel()
  696. test_utils.run_briefly(loop)
  697. self.assertTrue(handle._cancelled)
  698. def test_task_cancel_sleeping_task(self):
  699. def gen():
  700. when = yield
  701. self.assertAlmostEqual(0.1, when)
  702. when = yield 0
  703. self.assertAlmostEqual(5000, when)
  704. yield 0.1
  705. loop = test_utils.TestLoop(gen)
  706. self.addCleanup(loop.close)
  707. sleepfut = None
  708. @asyncio.coroutine
  709. def sleep(dt):
  710. nonlocal sleepfut
  711. sleepfut = asyncio.sleep(dt, loop=loop)
  712. yield from sleepfut
  713. @asyncio.coroutine
  714. def doit():
  715. sleeper = asyncio.Task(sleep(5000), loop=loop)
  716. loop.call_later(0.1, sleeper.cancel)
  717. try:
  718. yield from sleeper
  719. except asyncio.CancelledError:
  720. return 'cancelled'
  721. else:
  722. return 'slept in'
  723. doer = doit()
  724. self.assertEqual(loop.run_until_complete(doer), 'cancelled')
  725. self.assertAlmostEqual(0.1, loop.time())
  726. def test_task_cancel_waiter_future(self):
  727. fut = asyncio.Future(loop=self.loop)
  728. @asyncio.coroutine
  729. def coro():
  730. yield from fut
  731. task = asyncio.Task(coro(), loop=self.loop)
  732. test_utils.run_briefly(self.loop)
  733. self.assertIs(task._fut_waiter, fut)
  734. task.cancel()
  735. test_utils.run_briefly(self.loop)
  736. self.assertRaises(
  737. asyncio.CancelledError, self.loop.run_until_complete, task)
  738. self.assertIsNone(task._fut_waiter)
  739. self.assertTrue(fut.cancelled())
  740. def test_step_in_completed_task(self):
  741. @asyncio.coroutine
  742. def notmuch():
  743. return 'ko'
  744. gen = notmuch()
  745. task = asyncio.Task(gen, loop=self.loop)
  746. task.set_result('ok')
  747. self.assertRaises(AssertionError, task._step)
  748. gen.close()
  749. def test_step_result(self):
  750. @asyncio.coroutine
  751. def notmuch():
  752. yield None
  753. yield 1
  754. return 'ko'
  755. self.assertRaises(
  756. RuntimeError, self.loop.run_until_complete, notmuch())
  757. def test_step_result_future(self):
  758. # If coroutine returns future, task waits on this future.
  759. class Fut(asyncio.Future):
  760. def __init__(self, *args, **kwds):
  761. self.cb_added = False
  762. super().__init__(*args, **kwds)
  763. def add_done_callback(self, fn):
  764. self.cb_added = True
  765. super().add_done_callback(fn)
  766. fut = Fut(loop=self.loop)
  767. result = None
  768. @asyncio.coroutine
  769. def wait_for_future():
  770. nonlocal result
  771. result = yield from fut
  772. t = asyncio.Task(wait_for_future(), loop=self.loop)
  773. test_utils.run_briefly(self.loop)
  774. self.assertTrue(fut.cb_added)
  775. res = object()
  776. fut.set_result(res)
  777. test_utils.run_briefly(self.loop)
  778. self.assertIs(res, result)
  779. self.assertTrue(t.done())
  780. self.assertIsNone(t.result())
  781. def test_step_with_baseexception(self):
  782. @asyncio.coroutine
  783. def notmutch():
  784. raise BaseException()
  785. task = asyncio.Task(notmutch(), loop=self.loop)
  786. self.assertRaises(BaseException, task._step)
  787. self.assertTrue(task.done())
  788. self.assertIsInstance(task.exception(), BaseException)
  789. def test_baseexception_during_cancel(self):
  790. def gen():
  791. when = yield
  792. self.assertAlmostEqual(10.0, when)
  793. yield 0
  794. loop = test_utils.TestLoop(gen)
  795. self.addCleanup(loop.close)
  796. @asyncio.coroutine
  797. def sleeper():
  798. yield from asyncio.sleep(10, loop=loop)
  799. base_exc = BaseException()
  800. @asyncio.coroutine
  801. def notmutch():
  802. try:
  803. yield from sleeper()
  804. except asyncio.CancelledError:
  805. raise base_exc
  806. task = asyncio.Task(notmutch(), loop=loop)
  807. test_utils.run_briefly(loop)
  808. task.cancel()
  809. self.assertFalse(task.done())
  810. self.assertRaises(BaseException, test_utils.run_briefly, loop)
  811. self.assertTrue(task.done())
  812. self.assertFalse(task.cancelled())
  813. self.assertIs(task.exception(), base_exc)
  814. def test_iscoroutinefunction(self):
  815. def fn():
  816. pass
  817. self.assertFalse(asyncio.iscoroutinefunction(fn))
  818. def fn1():
  819. yield
  820. self.assertFalse(asyncio.iscoroutinefunction(fn1))
  821. @asyncio.coroutine
  822. def fn2():
  823. yield
  824. self.assertTrue(asyncio.iscoroutinefunction(fn2))
  825. def test_yield_vs_yield_from(self):
  826. fut = asyncio.Future(loop=self.loop)
  827. @asyncio.coroutine
  828. def wait_for_future():
  829. yield fut
  830. task = wait_for_future()
  831. with self.assertRaises(RuntimeError):
  832. self.loop.run_until_complete(task)
  833. self.assertFalse(fut.done())
  834. def test_yield_vs_yield_from_generator(self):
  835. @asyncio.coroutine
  836. def coro():
  837. yield
  838. @asyncio.coroutine
  839. def wait_for_future():
  840. gen = coro()
  841. try:
  842. yield gen
  843. finally:
  844. gen.close()
  845. task = wait_for_future()
  846. self.assertRaises(
  847. RuntimeError,
  848. self.loop.run_until_complete, task)
  849. def test_coroutine_non_gen_function(self):
  850. @asyncio.coroutine
  851. def func():
  852. return 'test'
  853. self.assertTrue(asyncio.iscoroutinefunction(func))
  854. coro = func()
  855. self.assertTrue(asyncio.iscoroutine(coro))
  856. res = self.loop.run_until_complete(coro)
  857. self.assertEqual(res, 'test')
  858. def test_coroutine_non_gen_function_return_future(self):
  859. fut = asyncio.Future(loop=self.loop)
  860. @asyncio.coroutine
  861. def func():
  862. return fut
  863. @asyncio.coroutine
  864. def coro():
  865. fut.set_result('test')
  866. t1 = asyncio.Task(func(), loop=self.loop)
  867. t2 = asyncio.Task(coro(), loop=self.loop)
  868. res = self.loop.run_until_complete(t1)
  869. self.assertEqual(res, 'test')
  870. self.assertIsNone(t2.result())
  871. def test_current_task(self):
  872. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  873. @asyncio.coroutine
  874. def coro(loop):
  875. self.assertTrue(asyncio.Task.current_task(loop=loop) is task)
  876. task = asyncio.Task(coro(self.loop), loop=self.loop)
  877. self.loop.run_until_complete(task)
  878. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  879. def test_current_task_with_interleaving_tasks(self):
  880. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  881. fut1 = asyncio.Future(loop=self.loop)
  882. fut2 = asyncio.Future(loop=self.loop)
  883. @asyncio.coroutine
  884. def coro1(loop):
  885. self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
  886. yield from fut1
  887. self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
  888. fut2.set_result(True)
  889. @asyncio.coroutine
  890. def coro2(loop):
  891. self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
  892. fut1.set_result(True)
  893. yield from fut2
  894. self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
  895. task1 = asyncio.Task(coro1(self.loop), loop=self.loop)
  896. task2 = asyncio.Task(coro2(self.loop), loop=self.loop)
  897. self.loop.run_until_complete(asyncio.wait((task1, task2),
  898. loop=self.loop))
  899. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  900. # Some thorough tests for cancellation propagation through
  901. # coroutines, tasks and wait().
  902. def test_yield_future_passes_cancel(self):
  903. # Cancelling outer() cancels inner() cancels waiter.
  904. proof = 0
  905. waiter = asyncio.Future(loop=self.loop)
  906. @asyncio.coroutine
  907. def inner():
  908. nonlocal proof
  909. try:
  910. yield from waiter
  911. except asyncio.CancelledError:
  912. proof += 1
  913. raise
  914. else:
  915. self.fail('got past sleep() in inner()')
  916. @asyncio.coroutine
  917. def outer():
  918. nonlocal proof
  919. try:
  920. yield from inner()
  921. except asyncio.CancelledError:
  922. proof += 100 # Expect this path.
  923. else:
  924. proof += 10
  925. f = asyncio.async(outer(), loop=self.loop)
  926. test_utils.run_briefly(self.loop)
  927. f.cancel()
  928. self.loop.run_until_complete(f)
  929. self.assertEqual(proof, 101)
  930. self.assertTrue(waiter.cancelled())
  931. def test_yield_wait_does_not_shield_cancel(self):
  932. # Cancelling outer() makes wait() return early, leaves inner()
  933. # running.
  934. proof = 0
  935. waiter = asyncio.Future(loop=self.loop)
  936. @asyncio.coroutine
  937. def inner():
  938. nonlocal proof
  939. yield from waiter
  940. proof += 1
  941. @asyncio.coroutine
  942. def outer():
  943. nonlocal proof
  944. d, p = yield from asyncio.wait([inner()], loop=self.loop)
  945. proof += 100
  946. f = asyncio.async(outer(), loop=self.loop)
  947. test_utils.run_briefly(self.loop)
  948. f.cancel()
  949. self.assertRaises(
  950. asyncio.CancelledError, self.loop.run_until_complete, f)
  951. waiter.set_result(None)
  952. test_utils.run_briefly(self.loop)
  953. self.assertEqual(proof, 1)
  954. def test_shield_result(self):
  955. inner = asyncio.Future(loop=self.loop)
  956. outer = asyncio.shield(inner)
  957. inner.set_result(42)
  958. res = self.loop.run_until_complete(outer)
  959. self.assertEqual(res, 42)
  960. def test_shield_exception(self):
  961. inner = asyncio.Future(loop=self.loop)
  962. outer = asyncio.shield(inner)
  963. test_utils.run_briefly(self.loop)
  964. exc = RuntimeError('expected')
  965. inner.set_exception(exc)
  966. test_utils.run_briefly(self.loop)
  967. self.assertIs(outer.exception(), exc)
  968. def test_shield_cancel(self):
  969. inner = asyncio.Future(loop=self.loop)
  970. outer = asyncio.shield(inner)
  971. test_utils.run_briefly(self.loop)
  972. inner.cancel()
  973. test_utils.run_briefly(self.loop)
  974. self.assertTrue(outer.cancelled())
  975. def test_shield_shortcut(self):
  976. fut = asyncio.Future(loop=self.loop)
  977. fut.set_result(42)
  978. res = self.loop.run_until_complete(asyncio.shield(fut))
  979. self.assertEqual(res, 42)
  980. def test_shield_effect(self):
  981. # Cancelling outer() does not affect inner().
  982. proof = 0
  983. waiter = asyncio.Future(loop=self.loop)
  984. @asyncio.coroutine
  985. def inner():
  986. nonlocal proof
  987. yield from waiter
  988. proof += 1
  989. @asyncio.coroutine
  990. def outer():
  991. nonlocal proof
  992. yield from asyncio.shield(inner(), loop=self.loop)
  993. proof += 100
  994. f = asyncio.async(outer(), loop=self.loop)
  995. test_utils.run_briefly(self.loop)
  996. f.cancel()
  997. with self.assertRaises(asyncio.CancelledError):
  998. self.loop.run_until_complete(f)
  999. waiter.set_result(None)
  1000. test_utils.run_briefly(self.loop)
  1001. self.assertEqual(proof, 1)
  1002. def test_shield_gather(self):
  1003. child1 = asyncio.Future(loop=self.loop)
  1004. child2 = asyncio.Future(loop=self.loop)
  1005. parent = asyncio.gather(child1, child2, loop=self.loop)
  1006. outer = asyncio.shield(parent, loop=self.loop)
  1007. test_utils.run_briefly(self.loop)
  1008. outer.cancel()
  1009. test_utils.run_briefly(self.loop)
  1010. self.assertTrue(outer.cancelled())
  1011. child1.set_result(1)
  1012. child2.set_result(2)
  1013. test_utils.run_briefly(self.loop)
  1014. self.assertEqual(parent.result(), [1, 2])
  1015. def test_gather_shield(self):
  1016. child1 = asyncio.Future(loop=self.loop)
  1017. child2 = asyncio.Future(loop=self.loop)
  1018. inner1 = asyncio.shield(child1, loop=self.loop)
  1019. inner2 = asyncio.shield(child2, loop=self.loop)
  1020. parent = asyncio.gather(inner1, inner2, loop=self.loop)
  1021. test_utils.run_briefly(self.loop)
  1022. parent.cancel()
  1023. # This should cancel inner1 and inner2 but bot child1 and child2.
  1024. test_utils.run_briefly(self.loop)
  1025. self.assertIsInstance(parent.exception(), asyncio.CancelledError)
  1026. self.assertTrue(inner1.cancelled())
  1027. self.assertTrue(inner2.cancelled())
  1028. child1.set_result(1)
  1029. child2.set_result(2)
  1030. test_utils.run_briefly(self.loop)
  1031. class GatherTestsBase:
  1032. def setUp(self):
  1033. self.one_loop = test_utils.TestLoop()
  1034. self.other_loop = test_utils.TestLoop()
  1035. def tearDown(self):
  1036. self.one_loop.close()
  1037. self.other_loop.close()
  1038. def _run_loop(self, loop):
  1039. while loop._ready:
  1040. test_utils.run_briefly(loop)
  1041. def _check_success(self, **kwargs):
  1042. a, b, c = [asyncio.Future(loop=self.one_loop) for i in range(3)]
  1043. fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs)
  1044. cb = Mock()
  1045. fut.add_done_callback(cb)
  1046. b.set_result(1)
  1047. a.set_result(2)
  1048. self._run_loop(self.one_loop)
  1049. self.assertEqual(cb.called, False)
  1050. self.assertFalse(fut.done())
  1051. c.set_result(3)
  1052. self._run_loop(self.one_loop)
  1053. cb.assert_called_once_with(fut)
  1054. self.assertEqual(fut.result(), [2, 1, 3])
  1055. def test_success(self):
  1056. self._check_success()
  1057. self._check_success(return_exceptions=False)
  1058. def test_result_exception_success(self):
  1059. self._check_success(return_exceptions=True)
  1060. def test_one_exception(self):
  1061. a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
  1062. fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e))
  1063. cb = Mock()
  1064. fut.add_done_callback(cb)
  1065. exc = ZeroDivisionError()
  1066. a.set_result(1)
  1067. b.set_exception(exc)
  1068. self._run_loop(self.one_loop)
  1069. self.assertTrue(fut.done())
  1070. cb.assert_called_once_with(fut)
  1071. self.assertIs(fut.exception(), exc)
  1072. # Does nothing
  1073. c.set_result(3)
  1074. d.cancel()
  1075. e.set_exception(RuntimeError())
  1076. e.exception()
  1077. def test_return_exceptions(self):
  1078. a, b, c, d = [asyncio.Future(loop=self.one_loop) for i in range(4)]
  1079. fut = asyncio.gather(*self.wrap_futures(a, b, c, d),
  1080. return_exceptions=True)
  1081. cb = Mock()
  1082. fut.add_done_callback(cb)
  1083. exc = ZeroDivisionError()
  1084. exc2 = RuntimeError()
  1085. b.set_result(1)
  1086. c.set_exception(exc)
  1087. a.set_result(3)
  1088. self._run_loop(self.one_loop)
  1089. self.assertFalse(fut.done())
  1090. d.set_exception(exc2)
  1091. self._run_loop(self.one_loop)
  1092. self.assertTrue(fut.done())
  1093. cb.assert_called_once_with(fut)
  1094. self.assertEqual(fut.result(), [3, 1, exc, exc2])
  1095. class FutureGatherTests(GatherTestsBase, unittest.TestCase):
  1096. def wrap_futures(self, *futures):
  1097. return futures
  1098. def _check_empty_sequence(self, seq_or_iter):
  1099. asyncio.set_event_loop(self.one_loop)
  1100. self.addCleanup(asyncio.set_event_loop, None)
  1101. fut = asyncio.gather(*seq_or_iter)
  1102. self.assertIsInstance(fut, asyncio.Future)
  1103. self.assertIs(fut._loop, self.one_loop)
  1104. self._run_loop(self.one_loop)
  1105. self.assertTrue(fut.done())
  1106. self.assertEqual(fut.result(), [])
  1107. fut = asyncio.gather(*seq_or_iter, loop=self.other_loop)
  1108. self.assertIs(fut._loop, self.other_loop)
  1109. def test_constructor_empty_sequence(self):
  1110. self._check_empty_sequence([])
  1111. self._check_empty_sequence(())
  1112. self._check_empty_sequence(set())
  1113. self._check_empty_sequence(iter(""))
  1114. def test_constructor_heterogenous_futures(self):
  1115. fut1 = asyncio.Future(loop=self.one_loop)
  1116. fut2 = asyncio.Future(loop=self.other_loop)
  1117. with self.assertRaises(ValueError):
  1118. asyncio.gather(fut1, fut2)
  1119. with self.assertRaises(ValueError):
  1120. asyncio.gather(fut1, loop=self.other_loop)
  1121. def test_constructor_homogenous_futures(self):
  1122. children = [asyncio.Future(loop=self.other_loop) for i in range(3)]
  1123. fut = asyncio.gather(*children)
  1124. self.assertIs(fut._loop, self.other_loop)
  1125. self._run_loop(self.other_loop)
  1126. self.assertFalse(fut.done())
  1127. fut = asyncio.gather(*children, loop=self.other_loop)
  1128. self.assertIs(fut._loop, self.other_loop)
  1129. self._run_loop(self.other_loop)
  1130. self.assertFalse(fut.done())
  1131. def test_one_cancellation(self):
  1132. a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
  1133. fut = asyncio.gather(a, b, c, d, e)
  1134. cb = Mock()
  1135. fut.add_done_callback(cb)
  1136. a.set_result(1)
  1137. b.cancel()
  1138. self._run_loop(self.one_loop)
  1139. self.assertTrue(fut.done())
  1140. cb.assert_called_once_with(fut)
  1141. self.assertFalse(fut.cancelled())
  1142. self.assertIsInstance(fut.exception(), asyncio.CancelledError)
  1143. # Does nothing
  1144. c.set_result(3)
  1145. d.cancel()
  1146. e.set_exception(RuntimeError())
  1147. e.exception()
  1148. def test_result_exception_one_cancellation(self):
  1149. a, b, c, d, e, f = [asyncio.Future(loop=self.one_loop)
  1150. for i in range(6)]
  1151. fut = asyncio.gather(a, b, c, d, e, f, return_exceptions=True)
  1152. cb = Mock()
  1153. fut.add_done_callback(cb)
  1154. a.set_result(1)
  1155. zde = ZeroDivisionError()
  1156. b.set_exception(zde)
  1157. c.cancel()
  1158. self._run_loop(self.one_loop)
  1159. self.assertFalse(fut.done())
  1160. d.set_result(3)
  1161. e.cancel()
  1162. rte = RuntimeError()
  1163. f.set_exception(rte)
  1164. res = self.one_loop.run_until_complete(fut)
  1165. self.assertIsInstance(res[2], asyncio.CancelledError)
  1166. self.assertIsInstance(res[4], asyncio.CancelledError)
  1167. res[2] = res[4] = None
  1168. self.assertEqual(res, [1, zde, None, 3, None, rte])
  1169. cb.assert_called_once_with(fut)
  1170. class CoroutineGatherTests(GatherTestsBase, unittest.TestCase):
  1171. def setUp(self):
  1172. super().setUp()
  1173. asyncio.set_event_loop(self.one_loop)
  1174. def tearDown(self):
  1175. asyncio.set_event_loop(None)
  1176. super().tearDown()
  1177. def wrap_futures(self, *futures):
  1178. coros = []
  1179. for fut in futures:
  1180. @asyncio.coroutine
  1181. def coro(fut=fut):
  1182. return (yield from fut)
  1183. coros.append(coro())
  1184. return coros
  1185. def test_constructor_loop_selection(self):
  1186. @asyncio.coroutine
  1187. def coro():
  1188. return 'abc'
  1189. gen1 = coro()
  1190. gen2 = coro()
  1191. fut = asyncio.gather(gen1, gen2)
  1192. self.assertIs(fut._loop, self.one_loop)
  1193. gen1.close()
  1194. gen2.close()
  1195. gen3 = coro()
  1196. gen4 = coro()
  1197. fut = asyncio.gather(gen3, gen4, loop=self.other_loop)
  1198. self.assertIs(fut._loop, self.other_loop)
  1199. gen3.close()
  1200. gen4.close()
  1201. def test_cancellation_broadcast(self):
  1202. # Cancelling outer() cancels all children.
  1203. proof = 0
  1204. waiter = asyncio.Future(loop=self.one_loop)
  1205. @asyncio.coroutine
  1206. def inner():
  1207. nonlocal proof
  1208. yield from waiter
  1209. proof += 1
  1210. child1 = asyncio.async(inner(), loop=self.one_loop)
  1211. child2 = asyncio.async(inner(), loop=self.one_loop)
  1212. gatherer = None
  1213. @asyncio.coroutine
  1214. def outer():
  1215. nonlocal proof, gatherer
  1216. gatherer = asyncio.gather(child1, child2, loop=self.one_loop)
  1217. yield from gatherer
  1218. proof += 100
  1219. f = asyncio.async(outer(), loop=self.one_loop)
  1220. test_utils.run_briefly(self.one_loop)
  1221. self.assertTrue(f.cancel())
  1222. with self.assertRaises(asyncio.CancelledError):
  1223. self.one_loop.run_until_complete(f)
  1224. self.assertFalse(gatherer.cancel())
  1225. self.assertTrue(waiter.cancelled())
  1226. self.assertTrue(child1.cancelled())
  1227. self.assertTrue(child2.cancelled())
  1228. test_utils.run_briefly(self.one_loop)
  1229. self.assertEqual(proof, 0)
  1230. def test_exception_marking(self):
  1231. # Test for the first line marked "Mark exception retrieved."
  1232. @asyncio.coroutine
  1233. def inner(f):
  1234. yield from f
  1235. raise RuntimeError('should not be ignored')
  1236. a = asyncio.Future(loop=self.one_loop)
  1237. b = asyncio.Future(loop=self.one_loop)
  1238. @asyncio.coroutine
  1239. def outer():
  1240. yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop)
  1241. f = asyncio.async(outer(), loop=self.one_loop)
  1242. test_utils.run_briefly(self.one_loop)
  1243. a.set_result(None)
  1244. test_utils.run_briefly(self.one_loop)
  1245. b.set_result(None)
  1246. test_utils.run_briefly(self.one_loop)
  1247. self.assertIsInstance(f.exception(), RuntimeError)
  1248. if __name__ == '__main__':
  1249. unittest.main()