(self)
| 237 | out.splitlines()) |
| 238 | |
| 239 | def test_interrupted_write(self): |
| 240 | # BaseHandler._write() and _flush() have to write all data, even if |
| 241 | # it takes multiple send() calls. Test this by interrupting a send() |
| 242 | # call with a Unix signal. |
| 243 | pthread_kill = support.get_attribute(signal, "pthread_kill") |
| 244 | |
| 245 | def app(environ, start_response): |
| 246 | start_response("200 OK", []) |
| 247 | return [b'\0' * support.SOCK_MAX_SIZE] |
| 248 | |
| 249 | class WsgiHandler(NoLogRequestHandler, WSGIRequestHandler): |
| 250 | pass |
| 251 | |
| 252 | server = make_server(socket_helper.HOST, 0, app, handler_class=WsgiHandler) |
| 253 | self.addCleanup(server.server_close) |
| 254 | interrupted = threading.Event() |
| 255 | |
| 256 | def signal_handler(signum, frame): |
| 257 | interrupted.set() |
| 258 | |
| 259 | original = signal.signal(signal.SIGUSR1, signal_handler) |
| 260 | self.addCleanup(signal.signal, signal.SIGUSR1, original) |
| 261 | received = None |
| 262 | main_thread = threading.get_ident() |
| 263 | |
| 264 | def run_client(): |
| 265 | http = HTTPConnection(*server.server_address) |
| 266 | http.request("GET", "/") |
| 267 | with http.getresponse() as response: |
| 268 | response.read(100) |
| 269 | # The main thread should now be blocking in a send() system |
| 270 | # call. But in theory, it could get interrupted by other |
| 271 | # signals, and then retried. So keep sending the signal in a |
| 272 | # loop, in case an earlier signal happens to be delivered at |
| 273 | # an inconvenient moment. |
| 274 | while True: |
| 275 | pthread_kill(main_thread, signal.SIGUSR1) |
| 276 | if interrupted.wait(timeout=float(1)): |
| 277 | break |
| 278 | nonlocal received |
| 279 | received = len(response.read()) |
| 280 | http.close() |
| 281 | |
| 282 | background = threading.Thread(target=run_client) |
| 283 | background.start() |
| 284 | server.handle_request() |
| 285 | background.join() |
| 286 | self.assertEqual(received, support.SOCK_MAX_SIZE - 100) |
| 287 | |
| 288 | |
| 289 | class UtilityTests(TestCase): |
nothing calls this directly
no test coverage detected