PageRenderTime 42ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/Lib/test/test_asyncio/test_subprocess.py

https://bitbucket.org/ctheune/cpython
Python | 184 lines | 136 code | 36 blank | 12 comment | 9 complexity | ce334b94a0c2714ac8cfa9e18796dd91 MD5 | raw file
Possible License(s): 0BSD
  1. from asyncio import subprocess
  2. import asyncio
  3. import signal
  4. import sys
  5. import unittest
  6. from test import support
  7. if sys.platform != 'win32':
  8. from asyncio import unix_events
  9. # Program blocking
  10. PROGRAM_BLOCKED = [sys.executable, '-c', 'import time; time.sleep(3600)']
  11. # Program sleeping during 1 second
  12. PROGRAM_SLEEP_1SEC = [sys.executable, '-c', 'import time; time.sleep(1)']
  13. # Program copying input to output
  14. PROGRAM_CAT = [
  15. sys.executable, '-c',
  16. ';'.join(('import sys',
  17. 'data = sys.stdin.buffer.read()',
  18. 'sys.stdout.buffer.write(data)'))]
  19. class SubprocessMixin:
  20. def test_stdin_stdout(self):
  21. args = PROGRAM_CAT
  22. @asyncio.coroutine
  23. def run(data):
  24. proc = yield from asyncio.create_subprocess_exec(
  25. *args,
  26. stdin=subprocess.PIPE,
  27. stdout=subprocess.PIPE,
  28. loop=self.loop)
  29. # feed data
  30. proc.stdin.write(data)
  31. yield from proc.stdin.drain()
  32. proc.stdin.close()
  33. # get output and exitcode
  34. data = yield from proc.stdout.read()
  35. exitcode = yield from proc.wait()
  36. return (exitcode, data)
  37. task = run(b'some data')
  38. task = asyncio.wait_for(task, 10.0, loop=self.loop)
  39. exitcode, stdout = self.loop.run_until_complete(task)
  40. self.assertEqual(exitcode, 0)
  41. self.assertEqual(stdout, b'some data')
  42. def test_communicate(self):
  43. args = PROGRAM_CAT
  44. @asyncio.coroutine
  45. def run(data):
  46. proc = yield from asyncio.create_subprocess_exec(
  47. *args,
  48. stdin=subprocess.PIPE,
  49. stdout=subprocess.PIPE,
  50. loop=self.loop)
  51. stdout, stderr = yield from proc.communicate(data)
  52. return proc.returncode, stdout
  53. task = run(b'some data')
  54. task = asyncio.wait_for(task, 10.0, loop=self.loop)
  55. exitcode, stdout = self.loop.run_until_complete(task)
  56. self.assertEqual(exitcode, 0)
  57. self.assertEqual(stdout, b'some data')
  58. def test_shell(self):
  59. create = asyncio.create_subprocess_shell('exit 7',
  60. loop=self.loop)
  61. proc = self.loop.run_until_complete(create)
  62. exitcode = self.loop.run_until_complete(proc.wait())
  63. self.assertEqual(exitcode, 7)
  64. def test_start_new_session(self):
  65. # start the new process in a new session
  66. create = asyncio.create_subprocess_shell('exit 8',
  67. start_new_session=True,
  68. loop=self.loop)
  69. proc = self.loop.run_until_complete(create)
  70. exitcode = self.loop.run_until_complete(proc.wait())
  71. self.assertEqual(exitcode, 8)
  72. def test_kill(self):
  73. args = PROGRAM_BLOCKED
  74. create = asyncio.create_subprocess_exec(*args, loop=self.loop)
  75. proc = self.loop.run_until_complete(create)
  76. proc.kill()
  77. returncode = self.loop.run_until_complete(proc.wait())
  78. if sys.platform == 'win32':
  79. self.assertIsInstance(returncode, int)
  80. # expect 1 but sometimes get 0
  81. else:
  82. self.assertEqual(-signal.SIGKILL, returncode)
  83. def test_terminate(self):
  84. args = PROGRAM_BLOCKED
  85. create = asyncio.create_subprocess_exec(*args, loop=self.loop)
  86. proc = self.loop.run_until_complete(create)
  87. proc.terminate()
  88. returncode = self.loop.run_until_complete(proc.wait())
  89. if sys.platform == 'win32':
  90. self.assertIsInstance(returncode, int)
  91. # expect 1 but sometimes get 0
  92. else:
  93. self.assertEqual(-signal.SIGTERM, returncode)
  94. @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP")
  95. def test_send_signal(self):
  96. args = PROGRAM_BLOCKED
  97. create = asyncio.create_subprocess_exec(*args, loop=self.loop)
  98. proc = self.loop.run_until_complete(create)
  99. proc.send_signal(signal.SIGHUP)
  100. returncode = self.loop.run_until_complete(proc.wait())
  101. self.assertEqual(-signal.SIGHUP, returncode)
  102. def test_broken_pipe(self):
  103. large_data = b'x' * support.PIPE_MAX_SIZE
  104. create = asyncio.create_subprocess_exec(
  105. *PROGRAM_SLEEP_1SEC,
  106. stdin=subprocess.PIPE,
  107. loop=self.loop)
  108. proc = self.loop.run_until_complete(create)
  109. with self.assertRaises(BrokenPipeError):
  110. self.loop.run_until_complete(proc.communicate(large_data))
  111. self.loop.run_until_complete(proc.wait())
  112. if sys.platform != 'win32':
  113. # Unix
  114. class SubprocessWatcherMixin(SubprocessMixin):
  115. Watcher = None
  116. def setUp(self):
  117. policy = asyncio.get_event_loop_policy()
  118. self.loop = policy.new_event_loop()
  119. # ensure that the event loop is passed explicitly in the code
  120. policy.set_event_loop(None)
  121. watcher = self.Watcher()
  122. watcher.attach_loop(self.loop)
  123. policy.set_child_watcher(watcher)
  124. def tearDown(self):
  125. policy = asyncio.get_event_loop_policy()
  126. policy.set_child_watcher(None)
  127. self.loop.close()
  128. policy.set_event_loop(None)
  129. class SubprocessSafeWatcherTests(SubprocessWatcherMixin,
  130. unittest.TestCase):
  131. Watcher = unix_events.SafeChildWatcher
  132. class SubprocessFastWatcherTests(SubprocessWatcherMixin,
  133. unittest.TestCase):
  134. Watcher = unix_events.FastChildWatcher
  135. else:
  136. # Windows
  137. class SubprocessProactorTests(SubprocessMixin, unittest.TestCase):
  138. def setUp(self):
  139. policy = asyncio.get_event_loop_policy()
  140. self.loop = asyncio.ProactorEventLoop()
  141. # ensure that the event loop is passed explicitly in the code
  142. policy.set_event_loop(None)
  143. def tearDown(self):
  144. policy = asyncio.get_event_loop_policy()
  145. self.loop.close()
  146. policy.set_event_loop(None)
  147. if __name__ == '__main__':
  148. unittest.main()