'Generic buffered read method test harness to verify 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 signal was handled,
writing a final newline char and closing the infile pipe.
read_and_verify_code: Single "line" of code to read from a file
object named \'infile\' and validate the result.  This will be
executed as part of a python subprocess fed data_to_write.
method_name: The name of the read method being tested, for use in
an error message on failure.
universal_newlines: If True, infile will be opened in universal
newline mode in the child process.'

def _test_reading(self, data_to_write, read_and_verify_code, method_name, universal_newlines=False):

    if universal_newlines:
        data_to_write = data_to_write.replace('\n', '\r\n')
        infile_setup_code = 'infile    =    os.fdopen(sys.stdin.fileno(),    "rU")'
    else:
        infile_setup_code = 'infile    =    sys.stdin'
    assert (len(data_to_write) < 512), 'data_to_write    must    fit    in    pipe    buf.'
    child_code = (((('import    os,    signal,    sys    ;signal.signal(signal.SIGINT,    lambda    s,    f:    sys.stderr.write("$\\n"))    ;' + infile_setup_code) + '    ;') + 'assert    isinstance(infile,    file)    ;sys.stderr.write("Go.\\n")    ;') + read_and_verify_code)
    reader_process = subprocess.Popen([sys.executable, '-c', child_code], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    go = reader_process.stderr.read(4)
    if (go != 'Go.\n'):
        reader_process.kill()
        self.fail(('Error    from    %s    process    while    awaiting    "Go":\n%s' % (method_name, (go + reader_process.stderr.read()))))
    reader_process.stdin.write(data_to_write)
    signals_sent = 0
    rlist = []
    while (not rlist):
        (rlist, _, _) = select.select([reader_process.stderr], (), (), 0.05)
        reader_process.send_signal(signal.SIGINT)
        time.sleep(0.1)
        signals_sent += 1
        if (signals_sent > 200):
            reader_process.kill()
            self.fail(('failed    to    handle    signal    during    %s.' % method_name))
    signal_line = reader_process.stderr.readline()
    if (signal_line != '$\n'):
        reader_process.kill()
        self.fail(('Error    from    %s    process    while    awaiting    signal:\n%s' % (method_name, (signal_line + reader_process.stderr.read()))))
    (stdout, stderr) = reader_process.communicate(input='\n')
    if (reader_process.returncode != 0):
        self.fail(('%s()    process    exited    rc=%d.\nSTDOUT:\n%s\nSTDERR:\n%s' % (method_name, reader_process.returncode, stdout, stderr)))
