|
4 | 4 | import signal |
5 | 5 | import sys |
6 | 6 | import unittest |
| 7 | +from unittest import mock |
7 | 8 | from test import support |
8 | 9 | if sys.platform != 'win32': |
9 | 10 | from asyncio import unix_events |
@@ -161,6 +162,37 @@ def test_communicate_ignore_broken_pipe(self): |
161 | 162 | self.loop.run_until_complete(proc.communicate(large_data)) |
162 | 163 | self.loop.run_until_complete(proc.wait()) |
163 | 164 |
|
| 165 | + def test_pause_reading(self): |
| 166 | + @asyncio.coroutine |
| 167 | + def test_pause_reading(): |
| 168 | + limit = 100 |
| 169 | + |
| 170 | + code = '\n'.join(( |
| 171 | + 'import sys', |
| 172 | + 'sys.stdout.write("x" * %s)' % (limit * 2 + 1), |
| 173 | + 'sys.stdout.flush()', |
| 174 | + )) |
| 175 | + proc = yield from asyncio.create_subprocess_exec( |
| 176 | + sys.executable, '-c', code, |
| 177 | + stdin=asyncio.subprocess.PIPE, |
| 178 | + stdout=asyncio.subprocess.PIPE, |
| 179 | + limit=limit, |
| 180 | + loop=self.loop) |
| 181 | + stdout_transport = proc._transport.get_pipe_transport(1) |
| 182 | + stdout_transport.pause_reading = mock.Mock() |
| 183 | + |
| 184 | + yield from proc.wait() |
| 185 | + |
| 186 | + # The child process produced more than limit bytes of output, |
| 187 | + # the stream reader transport should pause the protocol to not |
| 188 | + # allocate too much memory. |
| 189 | + return stdout_transport.pause_reading.called |
| 190 | + |
| 191 | + # Issue #22685: Ensure that the stream reader pauses the protocol |
| 192 | + # when the child process produces too much data |
| 193 | + called = self.loop.run_until_complete(test_pause_reading()) |
| 194 | + self.assertTrue(called) |
| 195 | + |
164 | 196 |
|
165 | 197 | if sys.platform != 'win32': |
166 | 198 | # Unix |
|
0 commit comments