MCPcopy Index your code
hub / github.com/python/cpython / _test_reading

Method _test_reading

Lib/test/test_file_eintr.py:75–144  ·  view source on GitHub ↗

Generic buffered read method test harness to validate EINTR behavior. Also validates that Python signal handlers are run during the read. Args: data_to_write: String to write to the child process for reading before sending it a signal, confirming the sig

(self, data_to_write, read_and_verify_code)

Source from the content-addressed store, hash-verified

73 (why, stdout.decode(), stderr.decode()))
74
75 def _test_reading(self, data_to_write, read_and_verify_code):
76 """Generic buffered read method test harness to validate EINTR behavior.
77
78 Also validates that Python signal handlers are run during the read.
79
80 Args:
81 data_to_write: String to write to the child process for reading
82 before sending it a signal, confirming the signal was handled,
83 writing a final newline and closing the infile pipe.
84 read_and_verify_code: Single "line" of code to read from a file
85 object named 'infile' and validate the result. This will be
86 executed as part of a python subprocess fed data_to_write.
87 """
88 infile_setup_code = self._generate_infile_setup_code()
89 # Total pipe IO in this function is smaller than the minimum posix OS
90 # pipe buffer size of 512 bytes. No writer should block.
91 assert len(data_to_write) < 512, 'data_to_write must fit in pipe buf.'
92
93 # Start a subprocess to call our read method while handling a signal.
94 self._process = subprocess.Popen(
95 [sys.executable, '-u', '-c',
96 'import signal, sys ;'
97 'signal.signal(signal.SIGINT, '
98 'lambda s, f: sys.stderr.write("$\\n")) ;'
99 + infile_setup_code + ' ;' +
100 'sys.stderr.write("Worm Sign!\\n") ;'
101 + read_and_verify_code + ' ;' +
102 'infile.close()'
103 ],
104 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
105 stderr=subprocess.PIPE)
106
107 # Wait for the signal handler to be installed.
108 worm_sign = self._process.stderr.read(len(b'Worm Sign!\n'))
109 if worm_sign != b'Worm Sign!\n': # See also, Dune by Frank Herbert.
110 self.fail_with_process_info('while awaiting a sign',
111 stderr=worm_sign)
112 self._process.stdin.write(data_to_write)
113
114 signals_sent = 0
115 rlist = []
116 # We don't know when the read_and_verify_code in our child is actually
117 # executing within the read system call we want to interrupt. This
118 # loop waits for a bit before sending the first signal to increase
119 # the likelihood of that. Implementations without correct EINTR
120 # and signal handling usually fail this test.
121 while not rlist:
122 rlist, _, _ = select.select([self._process.stderr], (), (), 0.05)
123 self._process.send_signal(signal.SIGINT)
124 signals_sent += 1
125 if signals_sent > 200:
126 self._process.kill()
127 self.fail('reader process failed to handle our signals.')
128 # This assumes anything unexpected that writes to stderr will also
129 # write a newline. That is true of the traceback printing code.
130 signal_line = self._process.stderr.readline()
131 if signal_line != b'$\n':
132 self.fail_with_process_info('while awaiting signal',

Callers 7

test_readlineMethod · 0.95
test_readlinesMethod · 0.95
test_readallMethod · 0.95
test_readallMethod · 0.80
test_readlineMethod · 0.80
test_readlinesMethod · 0.80
test_readallMethod · 0.80

Calls 10

readMethod · 0.45
writeMethod · 0.45
selectMethod · 0.45
send_signalMethod · 0.45
killMethod · 0.45
failMethod · 0.45
readlineMethod · 0.45
communicateMethod · 0.45

Tested by

no test coverage detected