(self)
| 407 | self.assertEqual(server.wfile_fileno, server.request_fileno) |
| 408 | |
| 409 | def test_write(self): |
| 410 | # Test that wfile.write() sends data immediately, and that it does |
| 411 | # not truncate sends when interrupted by a Unix signal |
| 412 | pthread_kill = test.support.get_attribute(signal, 'pthread_kill') |
| 413 | |
| 414 | class Handler(socketserver.StreamRequestHandler): |
| 415 | def handle(self): |
| 416 | self.server.sent1 = self.wfile.write(b'write data\n') |
| 417 | # Should be sent immediately, without requiring flush() |
| 418 | self.server.received = self.rfile.readline() |
| 419 | big_chunk = b'\0' * test.support.SOCK_MAX_SIZE |
| 420 | self.server.sent2 = self.wfile.write(big_chunk) |
| 421 | |
| 422 | server = socketserver.TCPServer((HOST, 0), Handler) |
| 423 | self.addCleanup(server.server_close) |
| 424 | interrupted = threading.Event() |
| 425 | |
| 426 | def signal_handler(signum, frame): |
| 427 | interrupted.set() |
| 428 | |
| 429 | original = signal.signal(signal.SIGUSR1, signal_handler) |
| 430 | self.addCleanup(signal.signal, signal.SIGUSR1, original) |
| 431 | response1 = None |
| 432 | received2 = None |
| 433 | main_thread = threading.get_ident() |
| 434 | |
| 435 | def run_client(): |
| 436 | s = socket.socket(server.address_family, socket.SOCK_STREAM, |
| 437 | socket.IPPROTO_TCP) |
| 438 | with s, s.makefile('rb') as reader: |
| 439 | s.connect(server.server_address) |
| 440 | nonlocal response1 |
| 441 | response1 = reader.readline() |
| 442 | s.sendall(b'client response\n') |
| 443 | |
| 444 | reader.read(100) |
| 445 | # The main thread should now be blocking in a send() syscall. |
| 446 | # But in theory, it could get interrupted by other signals, |
| 447 | # and then retried. So keep sending the signal in a loop, in |
| 448 | # case an earlier signal happens to be delivered at an |
| 449 | # inconvenient moment. |
| 450 | while True: |
| 451 | pthread_kill(main_thread, signal.SIGUSR1) |
| 452 | if interrupted.wait(timeout=float(1)): |
| 453 | break |
| 454 | nonlocal received2 |
| 455 | received2 = len(reader.read()) |
| 456 | |
| 457 | background = threading.Thread(target=run_client) |
| 458 | background.start() |
| 459 | server.handle_request() |
| 460 | background.join() |
| 461 | self.assertEqual(server.sent1, len(response1)) |
| 462 | self.assertEqual(response1, b'write data\n') |
| 463 | self.assertEqual(server.received, b'client response\n') |
| 464 | self.assertEqual(server.sent2, test.support.SOCK_MAX_SIZE) |
| 465 | self.assertEqual(received2, test.support.SOCK_MAX_SIZE - 100) |
| 466 |
nothing calls this directly
no test coverage detected